quasarr 1.4.1__py3-none-any.whl → 1.20.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of quasarr might be problematic. Click here for more details.
- quasarr/__init__.py +157 -67
- quasarr/api/__init__.py +126 -43
- quasarr/api/arr/__init__.py +197 -78
- quasarr/api/captcha/__init__.py +885 -39
- quasarr/api/config/__init__.py +23 -0
- quasarr/api/sponsors_helper/__init__.py +84 -22
- quasarr/api/statistics/__init__.py +196 -0
- quasarr/downloads/__init__.py +236 -487
- quasarr/downloads/linkcrypters/al.py +237 -0
- quasarr/downloads/linkcrypters/filecrypt.py +178 -31
- quasarr/downloads/linkcrypters/hide.py +123 -0
- quasarr/downloads/packages/__init__.py +461 -0
- quasarr/downloads/sources/al.py +697 -0
- quasarr/downloads/sources/by.py +106 -0
- quasarr/downloads/sources/dd.py +6 -78
- quasarr/downloads/sources/dj.py +7 -0
- quasarr/downloads/sources/dt.py +1 -1
- quasarr/downloads/sources/dw.py +2 -2
- quasarr/downloads/sources/he.py +112 -0
- quasarr/downloads/sources/mb.py +47 -0
- quasarr/downloads/sources/nk.py +51 -0
- quasarr/downloads/sources/nx.py +36 -81
- quasarr/downloads/sources/sf.py +27 -4
- quasarr/downloads/sources/sj.py +7 -0
- quasarr/downloads/sources/sl.py +90 -0
- quasarr/downloads/sources/wd.py +110 -0
- quasarr/providers/cloudflare.py +204 -0
- quasarr/providers/html_images.py +20 -0
- quasarr/providers/html_templates.py +48 -39
- quasarr/providers/imdb_metadata.py +15 -2
- quasarr/providers/myjd_api.py +34 -5
- quasarr/providers/notifications.py +30 -5
- quasarr/providers/obfuscated.py +35 -0
- quasarr/providers/sessions/__init__.py +0 -0
- quasarr/providers/sessions/al.py +286 -0
- quasarr/providers/sessions/dd.py +78 -0
- quasarr/providers/sessions/nx.py +76 -0
- quasarr/providers/shared_state.py +347 -20
- quasarr/providers/statistics.py +154 -0
- quasarr/providers/version.py +1 -1
- quasarr/search/__init__.py +112 -36
- quasarr/search/sources/al.py +448 -0
- quasarr/search/sources/by.py +203 -0
- quasarr/search/sources/dd.py +17 -6
- quasarr/search/sources/dj.py +213 -0
- quasarr/search/sources/dt.py +37 -7
- quasarr/search/sources/dw.py +27 -47
- quasarr/search/sources/fx.py +27 -29
- quasarr/search/sources/he.py +196 -0
- quasarr/search/sources/mb.py +195 -0
- quasarr/search/sources/nk.py +188 -0
- quasarr/search/sources/nx.py +22 -6
- quasarr/search/sources/sf.py +143 -151
- quasarr/search/sources/sj.py +213 -0
- quasarr/search/sources/sl.py +246 -0
- quasarr/search/sources/wd.py +208 -0
- quasarr/storage/config.py +20 -4
- quasarr/storage/setup.py +216 -51
- quasarr-1.20.4.dist-info/METADATA +304 -0
- quasarr-1.20.4.dist-info/RECORD +72 -0
- {quasarr-1.4.1.dist-info → quasarr-1.20.4.dist-info}/WHEEL +1 -1
- quasarr/providers/tvmaze_metadata.py +0 -23
- quasarr-1.4.1.dist-info/METADATA +0 -174
- quasarr-1.4.1.dist-info/RECORD +0 -43
- {quasarr-1.4.1.dist-info → quasarr-1.20.4.dist-info}/entry_points.txt +0 -0
- {quasarr-1.4.1.dist-info → quasarr-1.20.4.dist-info}/licenses/LICENSE +0 -0
- {quasarr-1.4.1.dist-info → quasarr-1.20.4.dist-info}/top_level.txt +0 -0
|
@@ -2,14 +2,38 @@
|
|
|
2
2
|
# Quasarr
|
|
3
3
|
# Project by https://github.com/rix1337
|
|
4
4
|
|
|
5
|
+
import quasarr.providers.html_images as images
|
|
6
|
+
from quasarr.providers.version import get_version
|
|
7
|
+
|
|
8
|
+
|
|
5
9
|
def render_centered_html(inner_content):
|
|
6
10
|
head = '''
|
|
7
11
|
<head>
|
|
8
12
|
<meta charset="utf-8">
|
|
9
13
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
10
14
|
<title>Quasarr</title>
|
|
11
|
-
<link rel="icon" href="
|
|
15
|
+
<link rel="icon" href="''' + images.logo + '''" type="image/png">
|
|
12
16
|
<style>
|
|
17
|
+
/* Theme variables */
|
|
18
|
+
:root {
|
|
19
|
+
--bg-color: #ffffff;
|
|
20
|
+
--fg-color: #212529;
|
|
21
|
+
--card-bg: #ffffff;
|
|
22
|
+
--card-shadow: rgba(0, 0, 0, 0.1);
|
|
23
|
+
--primary: #0d6efd;
|
|
24
|
+
--secondary: #6c757d;
|
|
25
|
+
--code-bg: #f8f9fa;
|
|
26
|
+
--spacing: 1rem;
|
|
27
|
+
}
|
|
28
|
+
@media (prefers-color-scheme: dark) {
|
|
29
|
+
:root {
|
|
30
|
+
--bg-color: #181a1b;
|
|
31
|
+
--fg-color: #f1f1f1;
|
|
32
|
+
--card-bg: #242526;
|
|
33
|
+
--card-shadow: rgba(0, 0, 0, 0.5);
|
|
34
|
+
--code-bg: #2c2f33;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
13
37
|
/* Logo and heading alignment */
|
|
14
38
|
h1 {
|
|
15
39
|
display: inline-flex;
|
|
@@ -23,7 +47,6 @@ def render_centered_html(inner_content):
|
|
|
23
47
|
height: 48px;
|
|
24
48
|
margin-right: 0.5rem;
|
|
25
49
|
}
|
|
26
|
-
|
|
27
50
|
/* Form labels and inputs */
|
|
28
51
|
label {
|
|
29
52
|
display: block;
|
|
@@ -41,30 +64,10 @@ def render_centered_html(inner_content):
|
|
|
41
64
|
color: var(--fg-color);
|
|
42
65
|
box-sizing: border-box;
|
|
43
66
|
}
|
|
44
|
-
|
|
45
|
-
/* Theme variables */
|
|
46
|
-
:root {
|
|
47
|
-
--bg-color: #ffffff;
|
|
48
|
-
--fg-color: #212529;
|
|
49
|
-
--card-bg: #ffffff;
|
|
50
|
-
--card-shadow: rgba(0, 0, 0, 0.1);
|
|
51
|
-
--primary: #0d6efd;
|
|
52
|
-
--secondary: #6c757d;
|
|
53
|
-
--code-bg: #f8f9fa;
|
|
54
|
-
--spacing: 1rem;
|
|
55
|
-
}
|
|
56
|
-
@media (prefers-color-scheme: dark) {
|
|
57
|
-
:root {
|
|
58
|
-
--bg-color: #181a1b;
|
|
59
|
-
--fg-color: #f1f1f1;
|
|
60
|
-
--card-bg: #242526;
|
|
61
|
-
--card-shadow: rgba(0, 0, 0, 0.5);
|
|
62
|
-
--code-bg: #2c2f33;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
67
|
*, *::before, *::after {
|
|
66
68
|
box-sizing: border-box;
|
|
67
69
|
}
|
|
70
|
+
/* make body a column flex so footer can stick to bottom */
|
|
68
71
|
html, body {
|
|
69
72
|
margin: 0;
|
|
70
73
|
padding: 0;
|
|
@@ -75,12 +78,15 @@ def render_centered_html(inner_content):
|
|
|
75
78
|
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',
|
|
76
79
|
'Noto Sans', Arial, sans-serif;
|
|
77
80
|
line-height: 1.6;
|
|
81
|
+
display: flex;
|
|
82
|
+
flex-direction: column;
|
|
83
|
+
min-height: 100vh;
|
|
78
84
|
}
|
|
79
85
|
.outer {
|
|
86
|
+
flex: 1;
|
|
80
87
|
display: flex;
|
|
81
88
|
justify-content: center;
|
|
82
89
|
align-items: center;
|
|
83
|
-
min-height: 100vh; /* allow container to expand */
|
|
84
90
|
padding: var(--spacing);
|
|
85
91
|
}
|
|
86
92
|
.inner {
|
|
@@ -98,7 +104,6 @@ def render_centered_html(inner_content):
|
|
|
98
104
|
padding-left: 0;
|
|
99
105
|
padding-right: 0;
|
|
100
106
|
}
|
|
101
|
-
|
|
102
107
|
body:has(iframe) .inner {
|
|
103
108
|
padding-left: 0;
|
|
104
109
|
padding-right: 0;
|
|
@@ -118,16 +123,10 @@ def render_centered_html(inner_content):
|
|
|
118
123
|
p {
|
|
119
124
|
margin: 0.5rem 0;
|
|
120
125
|
}
|
|
121
|
-
.
|
|
122
|
-
display: block;
|
|
126
|
+
.copy-input {
|
|
123
127
|
background-color: var(--code-bg);
|
|
124
|
-
padding: 0.5rem;
|
|
125
|
-
border-radius: 0.5rem;
|
|
126
|
-
font-family: monospace;
|
|
127
|
-
word-break: break-all;
|
|
128
|
-
margin: var(--spacing) 0;
|
|
129
128
|
}
|
|
130
|
-
.api-key-wrapper {
|
|
129
|
+
.url-wrapper .api-key-wrapper {
|
|
131
130
|
display: flex;
|
|
132
131
|
gap: 0.5rem;
|
|
133
132
|
flex-wrap: wrap;
|
|
@@ -160,7 +159,14 @@ def render_centered_html(inner_content):
|
|
|
160
159
|
text-decoration: none;
|
|
161
160
|
}
|
|
162
161
|
a:hover {
|
|
163
|
-
|
|
162
|
+
|
|
163
|
+
}
|
|
164
|
+
/* footer styling */
|
|
165
|
+
footer {
|
|
166
|
+
text-align: center;
|
|
167
|
+
font-size: 0.75rem;
|
|
168
|
+
color: var(--secondary);
|
|
169
|
+
padding: 0.5rem 0;
|
|
164
170
|
}
|
|
165
171
|
</style>
|
|
166
172
|
</head>'''
|
|
@@ -173,13 +179,15 @@ def render_centered_html(inner_content):
|
|
|
173
179
|
{inner_content}
|
|
174
180
|
</div>
|
|
175
181
|
</div>
|
|
182
|
+
<footer>
|
|
183
|
+
Quasarr v.{get_version()}
|
|
184
|
+
</footer>
|
|
176
185
|
</body>
|
|
177
186
|
'''
|
|
178
187
|
return f'<html>{body}</html>'
|
|
179
188
|
|
|
180
189
|
|
|
181
190
|
def render_button(text, button_type="primary", attributes=None):
|
|
182
|
-
# Map types to classes
|
|
183
191
|
cls = "btn-primary" if button_type == "primary" else "btn-secondary"
|
|
184
192
|
attr_str = ''
|
|
185
193
|
if attributes:
|
|
@@ -189,7 +197,7 @@ def render_button(text, button_type="primary", attributes=None):
|
|
|
189
197
|
|
|
190
198
|
def render_form(header, form="", script=""):
|
|
191
199
|
content = f'''
|
|
192
|
-
<h1><img src="
|
|
200
|
+
<h1><img src="{images.logo}" type="image/png" alt="Quasarr logo" class="logo"/>Quasarr</h1>
|
|
193
201
|
<h2>{header}</h2>
|
|
194
202
|
{form}
|
|
195
203
|
{script}
|
|
@@ -197,7 +205,7 @@ def render_form(header, form="", script=""):
|
|
|
197
205
|
return render_centered_html(content)
|
|
198
206
|
|
|
199
207
|
|
|
200
|
-
def render_success(message, timeout=10):
|
|
208
|
+
def render_success(message, timeout=10, optional_text=""):
|
|
201
209
|
button_html = render_button(f"Wait time... {timeout}", "secondary", {"id": "nextButton", "disabled": "true"})
|
|
202
210
|
script = f'''
|
|
203
211
|
<script>
|
|
@@ -216,8 +224,9 @@ def render_success(message, timeout=10):
|
|
|
216
224
|
}}, 1000);
|
|
217
225
|
</script>
|
|
218
226
|
'''
|
|
219
|
-
content = f'''<h1><img src="
|
|
227
|
+
content = f'''<h1><img src="{images.logo}" type="image/png" alt="Quasarr logo" class="logo"/>Quasarr</h1>
|
|
220
228
|
<h2>{message}</h2>
|
|
229
|
+
{optional_text}
|
|
221
230
|
{button_html}
|
|
222
231
|
{script}
|
|
223
232
|
'''
|
|
@@ -226,7 +235,7 @@ def render_success(message, timeout=10):
|
|
|
226
235
|
|
|
227
236
|
def render_fail(message):
|
|
228
237
|
button_html = render_button("Back", "secondary", {"onclick": "window.location.href='/'"})
|
|
229
|
-
return render_centered_html(f"""<h1><img src="
|
|
238
|
+
return render_centered_html(f"""<h1><img src="{images.logo}" type="image/png" alt="Quasarr logo" class="logo"/>Quasarr</h1>
|
|
230
239
|
<h2>{message}</h2>
|
|
231
240
|
{button_html}
|
|
232
241
|
""")
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# Quasarr
|
|
3
3
|
# Project by https://github.com/rix1337
|
|
4
4
|
|
|
5
|
+
import html
|
|
5
6
|
import re
|
|
6
7
|
from datetime import datetime, timedelta
|
|
7
8
|
from json import loads
|
|
@@ -61,6 +62,11 @@ def get_localized_title(shared_state, imdb_id, language='de'):
|
|
|
61
62
|
if not localized_title:
|
|
62
63
|
debug(f"Could not get localized title for {imdb_id} in {language} from IMDb")
|
|
63
64
|
|
|
65
|
+
localized_title = html.unescape(localized_title)
|
|
66
|
+
localized_title = re.sub(r"[^a-zA-Z0-9äöüÄÖÜß&-']", ' ', localized_title).strip()
|
|
67
|
+
localized_title = localized_title.replace(" - ", "-")
|
|
68
|
+
localized_title = re.sub(r'\s{2,}', ' ', localized_title)
|
|
69
|
+
|
|
64
70
|
return localized_title
|
|
65
71
|
|
|
66
72
|
|
|
@@ -111,8 +117,15 @@ def get_imdb_id_from_title(shared_state, title, language="de"):
|
|
|
111
117
|
|
|
112
118
|
if len(search_results) > 0:
|
|
113
119
|
for result in search_results:
|
|
114
|
-
|
|
115
|
-
|
|
120
|
+
try:
|
|
121
|
+
found_title = result["listItem"]["titleText"]
|
|
122
|
+
found_id = result["listItem"]["titleId"]
|
|
123
|
+
except KeyError:
|
|
124
|
+
found_title = result["titleNameText"]
|
|
125
|
+
found_id = result['id']
|
|
126
|
+
|
|
127
|
+
if shared_state.search_string_in_sanitized_title(title, found_title):
|
|
128
|
+
imdb_id = found_id
|
|
116
129
|
break
|
|
117
130
|
else:
|
|
118
131
|
debug(f"Request on IMDb failed: {results.status_code}")
|
quasarr/providers/myjd_api.py
CHANGED
|
@@ -39,6 +39,7 @@ import urllib3
|
|
|
39
39
|
from Cryptodome.Cipher import AES
|
|
40
40
|
|
|
41
41
|
from quasarr.providers.log import debug
|
|
42
|
+
from quasarr.providers.version import get_version
|
|
42
43
|
|
|
43
44
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
|
44
45
|
BS = 16
|
|
@@ -399,6 +400,29 @@ class Downloads:
|
|
|
399
400
|
return resp
|
|
400
401
|
|
|
401
402
|
|
|
403
|
+
class Extraction:
|
|
404
|
+
"""
|
|
405
|
+
Class that represents the extraction details of a Device
|
|
406
|
+
"""
|
|
407
|
+
|
|
408
|
+
def __init__(self, device):
|
|
409
|
+
self.device = device
|
|
410
|
+
self.url = "/extraction"
|
|
411
|
+
|
|
412
|
+
def get_archive_info(self, link_ids=[], package_ids=[]):
|
|
413
|
+
"""
|
|
414
|
+
Get ArchiveStatus for links and/or packages.
|
|
415
|
+
|
|
416
|
+
:param package_ids: Package UUID's.
|
|
417
|
+
:type: list of strings.
|
|
418
|
+
:param link_ids: link UUID's.
|
|
419
|
+
:type: list of strings
|
|
420
|
+
"""
|
|
421
|
+
params = [link_ids, package_ids]
|
|
422
|
+
resp = self.device.action(self.url + "/getArchiveInfo", params)
|
|
423
|
+
return resp
|
|
424
|
+
|
|
425
|
+
|
|
402
426
|
class Jddevice:
|
|
403
427
|
"""
|
|
404
428
|
Class that represents a JDownloader device and it's functions
|
|
@@ -417,6 +441,7 @@ class Jddevice:
|
|
|
417
441
|
self.config = Config(self)
|
|
418
442
|
self.linkgrabber = Linkgrabber(self)
|
|
419
443
|
self.downloads = Downloads(self)
|
|
444
|
+
self.extraction = Extraction(self)
|
|
420
445
|
self.downloadcontroller = DownloadController(self)
|
|
421
446
|
self.update = Update(self)
|
|
422
447
|
self.__direct_connection_info = None
|
|
@@ -552,7 +577,7 @@ class Myjdapi:
|
|
|
552
577
|
"""
|
|
553
578
|
self.__request_id = int(time.time() * 1000)
|
|
554
579
|
self.__api_url = "https://api.jdownloader.org"
|
|
555
|
-
self.__app_key = "
|
|
580
|
+
self.__app_key = "quasarr"
|
|
556
581
|
self.__api_version = 1
|
|
557
582
|
self.__devices = None
|
|
558
583
|
self.__login_secret = None
|
|
@@ -795,10 +820,14 @@ class Myjdapi:
|
|
|
795
820
|
query[0] + "&".join(query[1:])))
|
|
796
821
|
]
|
|
797
822
|
query = query[0] + "&".join(query[1:])
|
|
823
|
+
|
|
824
|
+
headers = {
|
|
825
|
+
"User-Agent": f"Quasarr/{get_version()}"
|
|
826
|
+
}
|
|
798
827
|
try:
|
|
799
|
-
encrypted_response = requests.get(api + query, timeout=timeout)
|
|
828
|
+
encrypted_response = requests.get(api + query, timeout=timeout, headers=headers)
|
|
800
829
|
except Exception:
|
|
801
|
-
encrypted_response = requests.get(api + query, timeout=timeout, verify=False)
|
|
830
|
+
encrypted_response = requests.get(api + query, timeout=timeout, headers=headers, verify=False)
|
|
802
831
|
debug("Could not establish secure connection to JDownloader.")
|
|
803
832
|
else:
|
|
804
833
|
params_request = []
|
|
@@ -829,7 +858,7 @@ class Myjdapi:
|
|
|
829
858
|
request_url,
|
|
830
859
|
headers={
|
|
831
860
|
"Content-Type": "application/aesjson-jd; charset=utf-8",
|
|
832
|
-
"User-Agent": "Quasarr"
|
|
861
|
+
"User-Agent": f"Quasarr/{get_version()}"
|
|
833
862
|
},
|
|
834
863
|
data=encrypted_data,
|
|
835
864
|
timeout=timeout
|
|
@@ -840,7 +869,7 @@ class Myjdapi:
|
|
|
840
869
|
request_url,
|
|
841
870
|
headers={
|
|
842
871
|
"Content-Type": "application/aesjson-jd; charset=utf-8",
|
|
843
|
-
"User-Agent": "Quasarr"
|
|
872
|
+
"User-Agent": f"Quasarr/{get_version()}"
|
|
844
873
|
},
|
|
845
874
|
data=encrypted_data,
|
|
846
875
|
timeout=timeout,
|
|
@@ -19,7 +19,7 @@ if os.getenv('SILENT'):
|
|
|
19
19
|
silent = True
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def send_discord_message(shared_state, title, case, imdb_id=None):
|
|
22
|
+
def send_discord_message(shared_state, title, case, imdb_id=None, details=None, source=None):
|
|
23
23
|
"""
|
|
24
24
|
Sends a Discord message to the webhook provided in the shared state, based on the specified case.
|
|
25
25
|
|
|
@@ -27,6 +27,8 @@ def send_discord_message(shared_state, title, case, imdb_id=None):
|
|
|
27
27
|
:param title: Title of the embed to be sent.
|
|
28
28
|
:param case: A string representing the scenario (e.g., 'captcha', 'failed', 'unprotected').
|
|
29
29
|
:param imdb_id: A string starting with "tt" followed by at least 7 digits, representing an object on IMDb
|
|
30
|
+
:param details: A dictionary containing additional details, such as version and link for updates.
|
|
31
|
+
:param source: Optional source of the notification, sent as a field in the embed.
|
|
30
32
|
:return: True if the message was sent successfully, False otherwise.
|
|
31
33
|
"""
|
|
32
34
|
if not shared_state.values.get("discord"):
|
|
@@ -34,7 +36,7 @@ def send_discord_message(shared_state, title, case, imdb_id=None):
|
|
|
34
36
|
|
|
35
37
|
poster_object = None
|
|
36
38
|
if case == "unprotected" or case == "captcha":
|
|
37
|
-
if not imdb_id:
|
|
39
|
+
if not imdb_id and " " not in title: # this should prevent imdb_search for ebooks and magazines
|
|
38
40
|
imdb_id = get_imdb_id_from_title(shared_state, title)
|
|
39
41
|
if imdb_id:
|
|
40
42
|
poster_link = get_poster_link(shared_state, imdb_id)
|
|
@@ -64,8 +66,19 @@ def send_discord_message(shared_state, title, case, imdb_id=None):
|
|
|
64
66
|
if not shared_state.values.get("helper_active"):
|
|
65
67
|
fields.append({
|
|
66
68
|
'name': 'SponsorsHelper',
|
|
67
|
-
'value': f'[
|
|
68
|
-
}
|
|
69
|
+
'value': f'[Sponsors get automated CAPTCHA solutions!](https://github.com/rix1337/Quasarr?tab=readme-ov-file#sponsorshelper)',
|
|
70
|
+
})
|
|
71
|
+
elif case == "quasarr_update":
|
|
72
|
+
description = f'Please update to {details["version"]} as soon as possible!'
|
|
73
|
+
if details:
|
|
74
|
+
fields = [
|
|
75
|
+
{
|
|
76
|
+
'name': 'Release notes at: ',
|
|
77
|
+
'value': f'[GitHub.com: rix1337/Quasarr/{details["version"]}]({details["link"]})',
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
else:
|
|
81
|
+
fields = None
|
|
69
82
|
else:
|
|
70
83
|
info(f"Unknown notification case: {case}")
|
|
71
84
|
return False
|
|
@@ -79,15 +92,27 @@ def send_discord_message(shared_state, title, case, imdb_id=None):
|
|
|
79
92
|
}]
|
|
80
93
|
}
|
|
81
94
|
|
|
95
|
+
if source and source.startswith("http"):
|
|
96
|
+
if not fields:
|
|
97
|
+
fields = []
|
|
98
|
+
fields.append({
|
|
99
|
+
'name': 'Source',
|
|
100
|
+
'value': f'[View release details here]({source})',
|
|
101
|
+
})
|
|
102
|
+
|
|
82
103
|
if fields:
|
|
83
104
|
data['embeds'][0]['fields'] = fields
|
|
84
105
|
|
|
85
106
|
if poster_object:
|
|
86
107
|
data['embeds'][0]['thumbnail'] = poster_object
|
|
87
108
|
data['embeds'][0]['image'] = poster_object
|
|
109
|
+
elif case == "quasarr_update":
|
|
110
|
+
data['embeds'][0]['thumbnail'] = {
|
|
111
|
+
'url': "https://raw.githubusercontent.com/rix1337/Quasarr/main/Quasarr.png"
|
|
112
|
+
}
|
|
88
113
|
|
|
89
114
|
# Apply silent mode: suppress notifications for all cases except 'deleted'
|
|
90
|
-
if silent and case
|
|
115
|
+
if silent and case not in ["failed", "quasarr_update"]:
|
|
91
116
|
data['flags'] = SUPPRESS_NOTIFICATIONS
|
|
92
117
|
|
|
93
118
|
response = requests.post(shared_state.values["discord"], data=json.dumps(data),
|