Unit3DwebUp 0.0.14__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.
Files changed (53) hide show
  1. config/__init__.py +4 -0
  2. config/api_data.py +28 -0
  3. config/constants.py +34 -0
  4. config/host_data.py +47 -0
  5. config/itt.py +154 -0
  6. config/logger.py +37 -0
  7. config/settings.py +212 -0
  8. config/sis.py +137 -0
  9. config/tags.py +395 -0
  10. config/trackers.py +47 -0
  11. external/__init__.py +0 -0
  12. external/async_http_client_service.py +48 -0
  13. external/websocket.py +41 -0
  14. models/__init__.py +0 -0
  15. models/interfaces.py +39 -0
  16. models/keywords.py +13 -0
  17. models/media.py +597 -0
  18. models/media_info.py +142 -0
  19. models/movie.py +287 -0
  20. models/tv.py +266 -0
  21. models/tvdb_search.py +102 -0
  22. models/videos.py +26 -0
  23. repositories/__init__.py +0 -0
  24. repositories/db_online.py +82 -0
  25. repositories/interfaces.py +59 -0
  26. repositories/job_repos.py +166 -0
  27. repositories/media_info_factory.py +28 -0
  28. services/__init__.py +0 -0
  29. services/auto_async_service.py +237 -0
  30. services/create_torrent_service.py +94 -0
  31. services/interfaces.py +72 -0
  32. services/itt_tracker_helper.py +463 -0
  33. services/itt_tracker_service.py +85 -0
  34. services/lifespan_service.py +58 -0
  35. services/media_service.py +114 -0
  36. services/tags_service.py +389 -0
  37. services/tmdb.py +246 -0
  38. services/torrent_client_service.py +92 -0
  39. services/torrent_service.py +107 -0
  40. services/tvdb.py +65 -0
  41. services/utility.py +433 -0
  42. services/video_service.py +356 -0
  43. unit3dwebup-0.0.14.dist-info/METADATA +191 -0
  44. unit3dwebup-0.0.14.dist-info/RECORD +53 -0
  45. unit3dwebup-0.0.14.dist-info/WHEEL +5 -0
  46. unit3dwebup-0.0.14.dist-info/entry_points.txt +2 -0
  47. unit3dwebup-0.0.14.dist-info/top_level.txt +6 -0
  48. use_case/__init__.py +0 -0
  49. use_case/make_torrent_usecase.py +67 -0
  50. use_case/process_all_usecase.py +43 -0
  51. use_case/scan_media_usecase.py +133 -0
  52. use_case/seed_usecase.py +117 -0
  53. use_case/upload_usecase.py +77 -0
config/tags.py ADDED
@@ -0,0 +1,395 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Based on 0.8.21
4
+ # TODO 'Crews and Games ID IGDB' add it later
5
+ crew_patterns = [
6
+ "NOGRP", "LIGHTFORCE", "SUXXORS", "KAOS", "GOG", "TENOKE", "I_KNOW", "RAZOR1911", "RUNE", "FITGIRL",
7
+ "ELAMIGOS", "RAZORDOX", "RAZOR", "SKIDROW", "DINOBYTES", "TINYISO", "FCKDRM", "FLT", "SKIDROW",
8
+ "CPY", "RELOADED", "HIVE", "VACE", "CZW", "PHOENIX", "JAGUAR", "CRIMSON", "TURBO", "DUPLEX", "CODEX"
9
+ ]
10
+
11
+ platform_patterns = ["IOS", "LIN", "MACOS", "NINTENDO", "OCULUS", "PC", "PS4", "PS5", "PSN", "PSVR", "STEAM",
12
+ "STEAMVR", "XBX", "XONE", "NSW"]
13
+
14
+ additions = ["build", "complete", "definitive", "dlc", "edition", "episode", "pack", "patch", "remake", "remaster",
15
+ "season", "update", "ultimate", "version"]
16
+
17
+ ############################################# BAN LIST FOR TITLE GENERATOR #############################################
18
+ BAN_LIST = {
19
+ "dummy" : "banned",
20
+ "video_encoder": "banned"
21
+ }
22
+
23
+ #################################################### TITLE GENERATOR ###################################################
24
+ TAGS_LIST = {
25
+ "REMUX": "remux",
26
+ "WEB-DL": "source",
27
+ "WEBDL": "source",
28
+ "WEB-DLRIP": "source",
29
+ "WEBDLRIP": "source",
30
+ "WEB-DLMUX": "source",
31
+ "WEBDLMUX": "source",
32
+ "WEB-MUX": "source",
33
+ "WEBMUX": "source",
34
+ "WEBRIP": "source",
35
+ "BD-UNTOUCHED": "source",
36
+ "UNTOUCHED": "source",
37
+ "FULL DISC": "source",
38
+ "ENCODE": "source",
39
+ "DLMUX": "source",
40
+ "BDMUX": "source",
41
+ "DVDMUX": "source",
42
+ "CINEMA": "source",
43
+
44
+ "3D": "source",
45
+ "TS": "source",
46
+ "CAM": "source",
47
+ "HDTS": "source",
48
+ "MD": "source",
49
+ "UHDRIP": "source",
50
+ "BLURAY": "source",
51
+ "BRRIP": "source",
52
+ "BDRIP": "source",
53
+ "FHDRIP": "source",
54
+ "PDTV": "source",
55
+ "SATRIP": "source",
56
+ "DVBRIP": "source",
57
+ "DVB-S": "source",
58
+ "DTTRIP": "source",
59
+ "WP": "source",
60
+ "DVDSCR": "source",
61
+ "TVRIP": "source",
62
+ "VHSRIP": "source",
63
+ "DVDRIP": "source",
64
+ "HDTV": "source",
65
+ "DVD5": "source",
66
+ "DVD9": "source",
67
+ "VU": "source",
68
+
69
+ "ATVP": "platform",
70
+ "AMZN": "platform",
71
+ "AMC": "platform",
72
+ "CN": "platform",
73
+ "CR": "platform",
74
+ "DCU": "platform",
75
+ "DSCP": "platform",
76
+ "DSNY": "platform",
77
+ "DSNP": "platform",
78
+ "DPLY": "platform",
79
+ "ESPN": "platform",
80
+ "FOOD": "platform",
81
+ "FOX": "platform",
82
+ "PLAY": "platform",
83
+ "HBO": "platform",
84
+ "HMAX": "platform",
85
+ "HGTV": "platform",
86
+ "HIST": "platform",
87
+ "HULU": "platform",
88
+ "MTOD": "platform",
89
+ "NATG": "platform",
90
+ "NF": "platform",
91
+ "NICK": "platform",
92
+ "NOW": "platform",
93
+ "PMNT": "platform",
94
+ "PMTP": "platform",
95
+ "PCOK": "platform",
96
+ "RKTN": "platform",
97
+ "SHO": "platform",
98
+ "SKST": "platform",
99
+ "STAN": "platform",
100
+ "STRP": "platform",
101
+ "STZ": "platform",
102
+ "TIMV": "platform",
103
+
104
+ "SPECIAL": "version",
105
+ "REPACK": "version",
106
+ "EXTENDED": "version",
107
+ "EDITION": "version",
108
+ "DIRECTOR'S": "version",
109
+ "CUT": "version",
110
+ "RERIP": "version",
111
+
112
+ "COLLECTION": "version",
113
+ "SUBBED": "version",
114
+ "MUX": "version",
115
+ "REMASTERED": "version",
116
+ "READNFO": "version",
117
+ "UNRATED": "version",
118
+ "UNCUT": "version",
119
+ "LIMITED": "version",
120
+ "ANNIVERSARY": "version",
121
+ "4k RESTORATION": "version",
122
+ "IMAX": "version",
123
+ "OPEN MATTE": "version",
124
+ "2IN1": "version",
125
+
126
+ "STV": "version",
127
+ "RECODE": "version",
128
+ "INTERNAL": "version",
129
+ "PROPER": "version",
130
+ "DUAL": "version",
131
+ "COMPLETE": "version",
132
+ "COMPLETA": "version",
133
+
134
+ "X264": "video_encoder",
135
+ "X265": "video_encoder",
136
+ }
137
+
138
+ ###################################################### RELEASERS #######################################################
139
+ SIGNS_LIST = {
140
+ "21APRILE": "releaser",
141
+ "ACCID": "releaser",
142
+ "ADWEB": "releaser",
143
+ "ALE88SERMETE": "releaser",
144
+ "APEX": "releaser",
145
+ "ARMOR": "releaser",
146
+ "ARRANCAR": "releaser",
147
+ "ARTEMIX": "releaser",
148
+ "ARTEMIX MIRCREW": "releaser",
149
+ "ASPIDE MIRCREW": "releaser",
150
+ "ASTOR": "releaser",
151
+ "AV1MERR": "releaser",
152
+ "BADGUY": "releaser",
153
+ "BALTHA": "releaser",
154
+ "BAMAX71": "releaser",
155
+ "BD": "releaser",
156
+ "BEN THE MEN": "releaser",
157
+ "BITSHIFT": "releaser",
158
+ "BLACKBIT": "releaser",
159
+ "BL4CK-B4RT-MIRCREW": "releaser",
160
+ "BLUWORLD": "releaser",
161
+ "BOBDOBBS": "releaser",
162
+ "BONE": "releaser",
163
+ "BULLITT": "releaser",
164
+ "BUMBLEBEE1982": "releaser",
165
+ "BUREK": "releaser",
166
+ "C0P": "releaser",
167
+ "CAPPYO": "releaser",
168
+ "CAVALLONZI": "releaser",
169
+ "CB01HD": "releaser",
170
+ "CHD": "releaser",
171
+ "CHDWEB": "releaser",
172
+ "CIAME": "releaser",
173
+ "CLOCLONE": "releaser",
174
+ "CODEX": "releaser",
175
+ "COMIX21": "releaser",
176
+ "CREW": "releaser",
177
+ "CSS": "releaser",
178
+ "CSS2": "releaser",
179
+ "CSS7896": "releaser",
180
+ "CYBER": "releaser",
181
+ "D3VELOPER": "releaser",
182
+ "DAICHISO": "releaser",
183
+ "DANGUARD": "releaser",
184
+ "DARKCOMPANY": "releaser",
185
+ "DARKPARANOR": "releaser",
186
+ "DAYMON64": "releaser",
187
+ "DB": "releaser",
188
+ "DDN": "releaser",
189
+ "DDNCREW": "releaser",
190
+ "DEDO1911": "releaser",
191
+ "DEMN": "releaser",
192
+ "DMAN": "releaser",
193
+ "DOCH74": "releaser",
194
+ "DR4GON": "releaser",
195
+ "DRIIP": "releaser",
196
+ "DST": "releaser",
197
+ "DYNUX": "releaser",
198
+ "EA": "releaser",
199
+ "EGL": "releaser",
200
+ "ELGHOTO": "releaser",
201
+ "ELISA": "releaser",
202
+ "EMPRESS": "releaser",
203
+ "ENCRYPTED": "releaser",
204
+ "EPSILON": "releaser",
205
+ "EVN": "releaser",
206
+ "EZTV": "releaser",
207
+ "FAINO1310": "releaser",
208
+ "FEDECAS89": "releaser",
209
+ "FGT": "releaser",
210
+ "FHC": "releaser",
211
+ "FLIPU": "releaser",
212
+ "FLT": "releaser",
213
+ "FLORIN993": "releaser",
214
+ "FLUX": "releaser",
215
+ "FOOD": "releaser",
216
+ "FRAMESTOR": "releaser",
217
+ "FREZEEN": "releaser",
218
+ "FW": "releaser",
219
+ "FUSION": "releaser",
220
+ "FXE": "releaser",
221
+ "G66": "releaser",
222
+ "GABIACAS": "releaser",
223
+ "GATTOPOLLO": "releaser",
224
+ "GEGE": "releaser",
225
+ "GFM": "releaser",
226
+ "GIUSEPPETNT": "releaser",
227
+ "GOLDENTORRENT": "releaser",
228
+ "GRYM": "releaser",
229
+ "HAPPITEAM-YNK": "releaser",
230
+ "HASHDEV": "releaser",
231
+ "HDCHINA": "releaser",
232
+ "HDI": "releaser",
233
+ "HHNN": "releaser",
234
+ "HHWEB": "releaser",
235
+ "HENRYDIRTY": "releaser",
236
+ "HMR": "releaser",
237
+ "HONE": "releaser",
238
+ "HYRULE": "releaser",
239
+ "I3AM": "releaser",
240
+ "IBANEZ89": "releaser",
241
+ "IDIB": "releaser",
242
+ "IDN": "releaser",
243
+ "IDN-CREW": "releaser",
244
+ "IGS": "releaser",
245
+ "ILGANZO": "releaser",
246
+ "ILPADRINO": "releaser",
247
+ "ILSAGGIO": "releaser",
248
+ "ILSOMMO": "releaser",
249
+ "IPDR01": "releaser",
250
+ "ITT": "releaser",
251
+ "JEDDAK-MIRCREW": "releaser",
252
+ "JOHNSEED": "releaser",
253
+ "KINGOFROME": "releaser",
254
+ "KIN": "releaser",
255
+ "KISSY": "releaser",
256
+ "KITSUNE": "releaser",
257
+ "KJM": "releaser",
258
+ "KOGI": "releaser",
259
+ "KONTRAST": "releaser",
260
+ "KOVALSKI": "releaser",
261
+ "KRALIMARKO": "releaser",
262
+ "KRIKK": "releaser",
263
+ "KUCHU": "releaser",
264
+ "LAZY-SUBS": "releaser",
265
+ "LATENEVER": "releaser",
266
+ "LDI": "releaser",
267
+ "LEAGUENF": "releaser",
268
+ "LELE753": "releaser",
269
+ "LEPORE": "releaser",
270
+ "LFI": "releaser",
271
+ "LICDOM": "releaser",
272
+ "LOZIO-MIRCREW": "releaser",
273
+ "LULLOZZO": "releaser",
274
+ "LZ": "releaser",
275
+ "LAXII": "releaser",
276
+ "LZ59": "releaser",
277
+ "MADHEX": "releaser",
278
+ "MADSKY": "releaser",
279
+ "MADTIA": "releaser",
280
+ "MAX": "releaser",
281
+ "MAX2014": "releaser",
282
+ "ME7ALH": "releaser",
283
+ "MIK0YAN": "releaser",
284
+ "MIRCREW": "releaser",
285
+ "MISTERNED": "releaser",
286
+ "MORPHEUS": "releaser",
287
+ "MRBLONDE": "releaser",
288
+ "MRROBOT": "releaser",
289
+ "MUETTO": "releaser",
290
+ "MUWATTALI": "releaser",
291
+ "NAHOM": "releaser",
292
+ "NARSETE": "releaser",
293
+ "NEOSTARK": "releaser",
294
+ "NEUROSIS": "releaser",
295
+ "NIMOUEH": "releaser",
296
+ "NOGROUP": "releaser",
297
+ "NOMADS": "releaser",
298
+ "NOVARIP": "releaser",
299
+ "NTB": "releaser",
300
+ "NTROPIC": "releaser",
301
+ "ODS": "releaser",
302
+ "ODINO": "releaser",
303
+ "ONGOIA": "releaser",
304
+ "PASO77": "releaser",
305
+ "PEPPE": "releaser",
306
+ "PENNYWISE": "releaser",
307
+ "PETE321": "releaser",
308
+ "PICOPOCO": "releaser",
309
+ "PING": "releaser",
310
+ "PINKER": "releaser",
311
+ "PIR8": "releaser",
312
+ "PLAYWEB": "releaser",
313
+ "PLUSAM": "releaser",
314
+ "POKE": "releaser",
315
+ "PRIME": "releaser",
316
+ "PROMETHEUS": "releaser",
317
+ "PROSCIUTTO": "releaser",
318
+ "RADESE": "releaser",
319
+ "RAPTA": "releaser",
320
+ "RARBG": "releaser",
321
+ "RAWR": "releaser",
322
+ "REALDMDJ": "releaser",
323
+ "RIDDICKK": "releaser",
324
+ "RMTEAM": "releaser",
325
+ "ROMEO": "releaser",
326
+ "RUNE": "releaser",
327
+ "RYUKXX": "releaser",
328
+ "S-K": "releaser",
329
+ "SAW": "releaser",
330
+ "SANDWORM": "releaser",
331
+ "SBR": "releaser",
332
+ "SEEDBOX": "releaser",
333
+ "SEEDBOX2": "releaser",
334
+ "SERCIUS": "releaser",
335
+ "SID": "releaser",
336
+ "SIMO01": "releaser",
337
+ "SIXTEEN8664": "releaser",
338
+ "SK4TTO": "releaser",
339
+ "SMURF": "releaser",
340
+ "SMURFADMIN": "releaser",
341
+ "SP33DY94-MIRCREW": "releaser",
342
+ "SPWEB": "releaser",
343
+ "SPYRO": "releaser",
344
+ "SPYRO1989": "releaser",
345
+ "STEFRA": "releaser",
346
+ "STEVEJOHNNEE": "releaser",
347
+ "STINGUAJT": "releaser",
348
+ "TAHTAKALECI": "releaser",
349
+ "TASKO": "releaser",
350
+ "TELESTO": "releaser",
351
+ "TEPES": "releaser",
352
+ "TERMINAL": "releaser",
353
+ "THEBLACKKING": "releaser",
354
+ "THEEMOJICREW": "releaser",
355
+ "THUDARA": "releaser",
356
+ "TIGER": "releaser",
357
+ "TIGRE67": "releaser",
358
+ "TBR": "releaser",
359
+ "TBZ": "releaser",
360
+ "T4P3": "releaser",
361
+ "TORRENTER10": "releaser",
362
+ "TOTAL_SHARE88": "releaser",
363
+ "TREE7458": "releaser",
364
+ "TRITON": "releaser",
365
+ "TRL": "releaser",
366
+ "TSUNAMI": "releaser",
367
+ "UBI": "releaser",
368
+ "UH": "releaser",
369
+ "V3SP4EV3R": "releaser",
370
+ "VARYG": "releaser",
371
+ "VIOLENT96": "releaser",
372
+ "VITELLO": "releaser",
373
+ "VOLVIC": "releaser",
374
+ "WAR": "releaser",
375
+ "WATCHABLE": "releaser",
376
+ "WELP": "releaser",
377
+ "WGZ": "releaser",
378
+ "WHEELIE": "releaser",
379
+ "WHITERHINO": "releaser",
380
+ "WIGGAZ": "releaser",
381
+ "WIZARDS2K": "releaser",
382
+ "WRM": "releaser",
383
+ "WRS": "releaser",
384
+ "XFM": "releaser",
385
+ "XVID": "releaser",
386
+ "YIFY": "releaser",
387
+ "YTS": "releaser",
388
+ "YTS.BZ": "releaser",
389
+ "ZIORIP": "releaser",
390
+ "ZK": "releaser",
391
+ "ZODD": "releaser",
392
+ "ZOOEYDES": "releaser",
393
+ "ZTR": "releaser",
394
+ "£ƐGƐND63": "releaser"
395
+ }
config/trackers.py ADDED
@@ -0,0 +1,47 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Same as the old code 0.8.21
3
+
4
+ from dataclasses import dataclass
5
+ from services.utility import ManageTitles
6
+ from config import tracker_list
7
+
8
+ @dataclass
9
+ class TRACKData:
10
+ category: dict[str, int]
11
+ freelech: dict[str, int]
12
+ type_id: dict[str, int]
13
+ resolution: dict[str, int]
14
+ codec: list
15
+
16
+ @classmethod
17
+ def load_from_module(cls, tracker_name: str) -> "TRACKData":
18
+ """
19
+ Load tracker data from module
20
+ """
21
+ tracker_data= tracker_list[tracker_name.upper()]
22
+
23
+ return cls(
24
+ category=tracker_data.get("CATEGORY"),
25
+ freelech=tracker_data.get("FREELECH"),
26
+ type_id=tracker_data.get("TYPE_ID"),
27
+ resolution=tracker_data.get("RESOLUTION"),
28
+ codec=tracker_data.get("CODEC"),
29
+ )
30
+
31
+ def filter_type(self, file_name: str) -> int:
32
+
33
+ file_name = ManageTitles.clean(file_name)
34
+ # >Clean the releaser sign
35
+ file_name = file_name.replace("-", " ")
36
+ word_list = file_name.lower().strip().split(" ")
37
+
38
+ # Caso 1: Cerca un TYPE_ID nel nome del file
39
+ for word in word_list:
40
+ if word in self.type_id:
41
+ return self.type_id[word]
42
+
43
+ # Caso 2: Se non trova un TYPE_ID, cerca un codec e ritorna 'encode'
44
+ for word in word_list:
45
+ if word in self.codec:
46
+ return self.type_id.get("encode", -1)
47
+ return self.type_id.get("altro", -1)
external/__init__.py ADDED
File without changes
@@ -0,0 +1,48 @@
1
+ import aiohttp
2
+
3
+ from config.logger import get_logger
4
+
5
+
6
+ class AsyncHttpClient:
7
+ """
8
+ basic Async HTTP client
9
+ """
10
+
11
+ def __init__(self, session: aiohttp.ClientSession | None = None):
12
+ """
13
+ :param session: aiohttp.ClientSession | None
14
+ """
15
+ self.session = session or aiohttp.ClientSession()
16
+ self.logger = get_logger(self.__class__.__name__)
17
+
18
+ async def __aenter__(self):
19
+ self.session = aiohttp.ClientSession()
20
+ return self
21
+
22
+ async def __aexit__(self, exc_type, exc, tb):
23
+ if self.session:
24
+ await self.session.close()
25
+
26
+ async def close(self):
27
+ if not self.session.closed:
28
+ await self.session.close()
29
+
30
+ async def get(self, url: str, params: dict = None):
31
+ try:
32
+ async with self.session.get(url, params=params, timeout=10) as resp:
33
+ if resp.status == 200:
34
+ return await resp.json()
35
+ return None
36
+ except Exception as e:
37
+ self.logger.error(f"[HTTP ERROR] {e} | URL: {url}")
38
+ return None
39
+
40
+ async def post(self, url: str, data: dict = None):
41
+ try:
42
+ async with self.session.post(url, json=data, timeout=10) as resp:
43
+ if resp.status == 200:
44
+ return await resp.json()
45
+ return None
46
+ except Exception as e:
47
+ self.logger.error(f"[HTTP ERROR] {e} | URL: {url}")
48
+ return None
external/websocket.py ADDED
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from fastapi import WebSocket
4
+ from typing import Set
5
+ import asyncio
6
+
7
+
8
+ class WebSocketManager:
9
+ def __init__(self):
10
+ self._connections: Set[WebSocket] = set()
11
+ self._lock = asyncio.Lock()
12
+
13
+ async def connect(self, ws: WebSocket):
14
+ await ws.accept()
15
+ async with self._lock:
16
+ if ws in self._connections:
17
+ self._connections.remove(ws)
18
+ self._connections.add(ws)
19
+
20
+ async def disconnect(self, ws: WebSocket):
21
+ async with self._lock:
22
+ self._connections.discard(ws)
23
+
24
+ async def broadcast(self, message: dict):
25
+ """
26
+ :param message: message to frontend
27
+ :return:
28
+ """
29
+ async with self._lock:
30
+ dead = []
31
+ for ws in self._connections:
32
+ try:
33
+ await ws.send_json(message)
34
+ except Exception:
35
+ dead.append(ws)
36
+
37
+ for ws in dead:
38
+ self._connections.discard(ws)
39
+
40
+ for ws in dead:
41
+ self._connections.discard(ws)
models/__init__.py ADDED
File without changes
models/interfaces.py ADDED
@@ -0,0 +1,39 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from abc import ABC, abstractmethod
4
+
5
+
6
+ # Tempus fugit
7
+ # Based on the old code unit3dup 0.8.21
8
+ class MediaRepoInterface(ABC):
9
+ """
10
+ interface to get an attribute independently of the repository type (TMDB, TVDB)
11
+ """
12
+
13
+ @abstractmethod
14
+ def get_title(self) -> str:
15
+ pass
16
+
17
+ @abstractmethod
18
+ def get_original(self) -> str:
19
+ pass
20
+
21
+ @abstractmethod
22
+ def get_date(self) -> str:
23
+ pass
24
+
25
+ @abstractmethod
26
+ def get_id(self) -> int:
27
+ pass
28
+
29
+ @abstractmethod
30
+ def get_poster_path(self) -> str:
31
+ pass
32
+
33
+ @abstractmethod
34
+ def get_imdb(self) -> str | None:
35
+ pass
36
+
37
+ @abstractmethod
38
+ def get_translations(self) -> dict[str, str] | None:
39
+ pass
models/keywords.py ADDED
@@ -0,0 +1,13 @@
1
+ # -*- coding: utf-8 -*-
2
+ from dataclasses import dataclass
3
+
4
+
5
+ @dataclass(slots=True)
6
+ class Keyword:
7
+ """
8
+ Dataclass help to manage data from the TMDB ID
9
+ These keywords must be sent to the tracker
10
+ """
11
+
12
+ id: int
13
+ name: str