plexflow 0.0.64__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.
- plexflow/__init__.py +0 -0
- plexflow/__main__.py +15 -0
- plexflow/core/.DS_Store +0 -0
- plexflow/core/__init__.py +0 -0
- plexflow/core/context/__init__.py +0 -0
- plexflow/core/context/metadata/__init__.py +0 -0
- plexflow/core/context/metadata/context.py +32 -0
- plexflow/core/context/metadata/tmdb/__init__.py +0 -0
- plexflow/core/context/metadata/tmdb/context.py +45 -0
- plexflow/core/context/partial_context.py +46 -0
- plexflow/core/context/partials/__init__.py +8 -0
- plexflow/core/context/partials/cache.py +16 -0
- plexflow/core/context/partials/context.py +12 -0
- plexflow/core/context/partials/ids.py +37 -0
- plexflow/core/context/partials/movie.py +115 -0
- plexflow/core/context/partials/tgx_batch.py +33 -0
- plexflow/core/context/partials/tgx_context.py +34 -0
- plexflow/core/context/partials/torrents.py +23 -0
- plexflow/core/context/partials/watchlist.py +35 -0
- plexflow/core/context/plexflow_context.py +29 -0
- plexflow/core/context/plexflow_property.py +36 -0
- plexflow/core/context/root/__init__.py +0 -0
- plexflow/core/context/root/context.py +25 -0
- plexflow/core/context/select/__init__.py +0 -0
- plexflow/core/context/select/context.py +45 -0
- plexflow/core/context/torrent/__init__.py +0 -0
- plexflow/core/context/torrent/context.py +43 -0
- plexflow/core/context/torrent/tpb/__init__.py +0 -0
- plexflow/core/context/torrent/tpb/context.py +45 -0
- plexflow/core/context/torrent/yts/__init__.py +0 -0
- plexflow/core/context/torrent/yts/context.py +45 -0
- plexflow/core/context/watchlist/__init__.py +0 -0
- plexflow/core/context/watchlist/context.py +46 -0
- plexflow/core/downloads/__init__.py +0 -0
- plexflow/core/downloads/candidates/__init__.py +0 -0
- plexflow/core/downloads/candidates/download_candidate.py +210 -0
- plexflow/core/downloads/candidates/filtered.py +51 -0
- plexflow/core/downloads/candidates/utils.py +39 -0
- plexflow/core/env/__init__.py +0 -0
- plexflow/core/env/env.py +31 -0
- plexflow/core/genai/__init__.py +0 -0
- plexflow/core/genai/bot.py +9 -0
- plexflow/core/genai/plexa.py +54 -0
- plexflow/core/genai/torrent/imdb_verify.py +65 -0
- plexflow/core/genai/torrent/movie.py +25 -0
- plexflow/core/genai/utils/__init__.py +0 -0
- plexflow/core/genai/utils/loader.py +5 -0
- plexflow/core/metadata/__init__.py +0 -0
- plexflow/core/metadata/auto/__init__.py +0 -0
- plexflow/core/metadata/auto/auto_meta.py +40 -0
- plexflow/core/metadata/auto/auto_providers/__init__.py +0 -0
- plexflow/core/metadata/auto/auto_providers/auto/__init__.py +0 -0
- plexflow/core/metadata/auto/auto_providers/auto/episode.py +49 -0
- plexflow/core/metadata/auto/auto_providers/auto/item.py +55 -0
- plexflow/core/metadata/auto/auto_providers/auto/movie.py +13 -0
- plexflow/core/metadata/auto/auto_providers/auto/season.py +43 -0
- plexflow/core/metadata/auto/auto_providers/auto/show.py +26 -0
- plexflow/core/metadata/auto/auto_providers/imdb/__init__.py +0 -0
- plexflow/core/metadata/auto/auto_providers/imdb/movie.py +36 -0
- plexflow/core/metadata/auto/auto_providers/imdb/show.py +45 -0
- plexflow/core/metadata/auto/auto_providers/moviemeter/__init__.py +0 -0
- plexflow/core/metadata/auto/auto_providers/moviemeter/movie.py +40 -0
- plexflow/core/metadata/auto/auto_providers/plex/__init__.py +0 -0
- plexflow/core/metadata/auto/auto_providers/plex/movie.py +39 -0
- plexflow/core/metadata/auto/auto_providers/tmdb/__init__.py +0 -0
- plexflow/core/metadata/auto/auto_providers/tmdb/episode.py +30 -0
- plexflow/core/metadata/auto/auto_providers/tmdb/movie.py +36 -0
- plexflow/core/metadata/auto/auto_providers/tmdb/season.py +23 -0
- plexflow/core/metadata/auto/auto_providers/tmdb/show.py +41 -0
- plexflow/core/metadata/auto/auto_providers/tmdb.py +92 -0
- plexflow/core/metadata/auto/auto_providers/tvdb/__init__.py +0 -0
- plexflow/core/metadata/auto/auto_providers/tvdb/episode.py +28 -0
- plexflow/core/metadata/auto/auto_providers/tvdb/movie.py +36 -0
- plexflow/core/metadata/auto/auto_providers/tvdb/season.py +25 -0
- plexflow/core/metadata/auto/auto_providers/tvdb/show.py +41 -0
- plexflow/core/metadata/providers/__init__.py +0 -0
- plexflow/core/metadata/providers/imdb/__init__.py +0 -0
- plexflow/core/metadata/providers/imdb/datatypes.py +53 -0
- plexflow/core/metadata/providers/imdb/imdb.py +112 -0
- plexflow/core/metadata/providers/moviemeter/__init__.py +0 -0
- plexflow/core/metadata/providers/moviemeter/datatypes.py +111 -0
- plexflow/core/metadata/providers/moviemeter/moviemeter.py +42 -0
- plexflow/core/metadata/providers/plex/__init__.py +0 -0
- plexflow/core/metadata/providers/plex/datatypes.py +693 -0
- plexflow/core/metadata/providers/plex/plex.py +167 -0
- plexflow/core/metadata/providers/tmdb/__init__.py +0 -0
- plexflow/core/metadata/providers/tmdb/datatypes.py +460 -0
- plexflow/core/metadata/providers/tmdb/tmdb.py +85 -0
- plexflow/core/metadata/providers/tvdb/__init__.py +0 -0
- plexflow/core/metadata/providers/tvdb/datatypes.py +257 -0
- plexflow/core/metadata/providers/tvdb/tv_datatypes.py +554 -0
- plexflow/core/metadata/providers/tvdb/tvdb.py +65 -0
- plexflow/core/metadata/providers/universal/__init__.py +0 -0
- plexflow/core/metadata/providers/universal/movie.py +130 -0
- plexflow/core/metadata/providers/universal/old.py +192 -0
- plexflow/core/metadata/providers/universal/show.py +107 -0
- plexflow/core/plex/__init__.py +0 -0
- plexflow/core/plex/api/context/authorized.py +15 -0
- plexflow/core/plex/api/context/discover.py +14 -0
- plexflow/core/plex/api/context/library.py +14 -0
- plexflow/core/plex/discover/__init__.py +0 -0
- plexflow/core/plex/discover/activity.py +448 -0
- plexflow/core/plex/discover/comment.py +89 -0
- plexflow/core/plex/discover/feed.py +11 -0
- plexflow/core/plex/hooks/__init__.py +0 -0
- plexflow/core/plex/hooks/plex_authorized.py +60 -0
- plexflow/core/plex/hooks/plexflow_database.py +6 -0
- plexflow/core/plex/library/__init__.py +0 -0
- plexflow/core/plex/library/library.py +103 -0
- plexflow/core/plex/token/__init__.py +0 -0
- plexflow/core/plex/token/auto_token.py +91 -0
- plexflow/core/plex/utils/__init__.py +0 -0
- plexflow/core/plex/utils/paginated.py +39 -0
- plexflow/core/plex/watchlist/__init__.py +0 -0
- plexflow/core/plex/watchlist/datatypes.py +124 -0
- plexflow/core/plex/watchlist/watchlist.py +23 -0
- plexflow/core/storage/__init__.py +0 -0
- plexflow/core/storage/object/__init__.py +0 -0
- plexflow/core/storage/object/plexflow_storage.py +143 -0
- plexflow/core/storage/object/redis_storage.py +169 -0
- plexflow/core/subtitles/__init__.py +0 -0
- plexflow/core/subtitles/providers/__init__.py +0 -0
- plexflow/core/subtitles/providers/auto_subtitles.py +48 -0
- plexflow/core/subtitles/providers/oss/__init__.py +0 -0
- plexflow/core/subtitles/providers/oss/datatypes.py +104 -0
- plexflow/core/subtitles/providers/oss/download.py +48 -0
- plexflow/core/subtitles/providers/oss/old.py +144 -0
- plexflow/core/subtitles/providers/oss/oss.py +400 -0
- plexflow/core/subtitles/providers/oss/oss_subtitle.py +32 -0
- plexflow/core/subtitles/providers/oss/search.py +52 -0
- plexflow/core/subtitles/providers/oss/unlimited_oss.py +231 -0
- plexflow/core/subtitles/providers/oss/utils/__init__.py +0 -0
- plexflow/core/subtitles/providers/oss/utils/config.py +63 -0
- plexflow/core/subtitles/providers/oss/utils/download_client.py +22 -0
- plexflow/core/subtitles/providers/oss/utils/exceptions.py +35 -0
- plexflow/core/subtitles/providers/oss/utils/file_utils.py +83 -0
- plexflow/core/subtitles/providers/oss/utils/languages.py +78 -0
- plexflow/core/subtitles/providers/oss/utils/response_base.py +221 -0
- plexflow/core/subtitles/providers/oss/utils/responses.py +176 -0
- plexflow/core/subtitles/providers/oss/utils/srt.py +561 -0
- plexflow/core/subtitles/results/__init__.py +0 -0
- plexflow/core/subtitles/results/subtitle.py +170 -0
- plexflow/core/torrents/__init__.py +0 -0
- plexflow/core/torrents/analyzers/analyzed_torrent.py +143 -0
- plexflow/core/torrents/analyzers/analyzer.py +45 -0
- plexflow/core/torrents/analyzers/torrentquest/analyzer.py +47 -0
- plexflow/core/torrents/auto/auto_providers/auto/__init__.py +0 -0
- plexflow/core/torrents/auto/auto_providers/auto/torrent.py +64 -0
- plexflow/core/torrents/auto/auto_providers/tpb/torrent.py +62 -0
- plexflow/core/torrents/auto/auto_torrents.py +29 -0
- plexflow/core/torrents/providers/__init__.py +0 -0
- plexflow/core/torrents/providers/ext/__init__.py +0 -0
- plexflow/core/torrents/providers/ext/ext.py +18 -0
- plexflow/core/torrents/providers/ext/utils.py +64 -0
- plexflow/core/torrents/providers/extratorrent/__init__.py +0 -0
- plexflow/core/torrents/providers/extratorrent/extratorrent.py +21 -0
- plexflow/core/torrents/providers/extratorrent/utils.py +66 -0
- plexflow/core/torrents/providers/eztv/__init__.py +0 -0
- plexflow/core/torrents/providers/eztv/eztv.py +47 -0
- plexflow/core/torrents/providers/eztv/utils.py +83 -0
- plexflow/core/torrents/providers/rarbg2/__init__.py +0 -0
- plexflow/core/torrents/providers/rarbg2/rarbg2.py +19 -0
- plexflow/core/torrents/providers/rarbg2/utils.py +76 -0
- plexflow/core/torrents/providers/snowfl/__init__.py +0 -0
- plexflow/core/torrents/providers/snowfl/snowfl.py +36 -0
- plexflow/core/torrents/providers/snowfl/utils.py +59 -0
- plexflow/core/torrents/providers/tgx/__init__.py +0 -0
- plexflow/core/torrents/providers/tgx/context.py +50 -0
- plexflow/core/torrents/providers/tgx/dump.py +40 -0
- plexflow/core/torrents/providers/tgx/tgx.py +22 -0
- plexflow/core/torrents/providers/tgx/utils.py +61 -0
- plexflow/core/torrents/providers/therarbg/__init__.py +0 -0
- plexflow/core/torrents/providers/therarbg/therarbg.py +17 -0
- plexflow/core/torrents/providers/therarbg/utils.py +61 -0
- plexflow/core/torrents/providers/torrentquest/__init__.py +0 -0
- plexflow/core/torrents/providers/torrentquest/torrentquest.py +20 -0
- plexflow/core/torrents/providers/torrentquest/utils.py +70 -0
- plexflow/core/torrents/providers/tpb/__init__.py +0 -0
- plexflow/core/torrents/providers/tpb/tpb.py +17 -0
- plexflow/core/torrents/providers/tpb/utils.py +139 -0
- plexflow/core/torrents/providers/yts/__init__.py +0 -0
- plexflow/core/torrents/providers/yts/utils.py +57 -0
- plexflow/core/torrents/providers/yts/yts.py +31 -0
- plexflow/core/torrents/results/__init__.py +0 -0
- plexflow/core/torrents/results/torrent.py +165 -0
- plexflow/core/torrents/results/universal.py +220 -0
- plexflow/core/torrents/results/utils.py +15 -0
- plexflow/events/__init__.py +0 -0
- plexflow/events/download/__init__.py +0 -0
- plexflow/events/download/torrent_events.py +96 -0
- plexflow/events/publish/__init__.py +0 -0
- plexflow/events/publish/publish.py +34 -0
- plexflow/logging/__init__.py +0 -0
- plexflow/logging/log_setup.py +8 -0
- plexflow/spiders/quiet_logger.py +9 -0
- plexflow/spiders/tgx/pipelines/dump_json_pipeline.py +30 -0
- plexflow/spiders/tgx/pipelines/meta_pipeline.py +13 -0
- plexflow/spiders/tgx/pipelines/publish_pipeline.py +14 -0
- plexflow/spiders/tgx/pipelines/torrent_info_pipeline.py +12 -0
- plexflow/spiders/tgx/pipelines/validation_pipeline.py +17 -0
- plexflow/spiders/tgx/settings.py +36 -0
- plexflow/spiders/tgx/spider.py +72 -0
- plexflow/utils/__init__.py +0 -0
- plexflow/utils/antibot/human_like_requests.py +122 -0
- plexflow/utils/api/__init__.py +0 -0
- plexflow/utils/api/context/http.py +62 -0
- plexflow/utils/api/rest/__init__.py +0 -0
- plexflow/utils/api/rest/antibot_restful.py +68 -0
- plexflow/utils/api/rest/restful.py +49 -0
- plexflow/utils/captcha/__init__.py +0 -0
- plexflow/utils/captcha/bypass/__init__.py +0 -0
- plexflow/utils/captcha/bypass/decode_audio.py +34 -0
- plexflow/utils/download/__init__.py +0 -0
- plexflow/utils/download/gz.py +26 -0
- plexflow/utils/filesystem/__init__.py +0 -0
- plexflow/utils/filesystem/search.py +129 -0
- plexflow/utils/gmail/__init__.py +0 -0
- plexflow/utils/gmail/mails.py +116 -0
- plexflow/utils/hooks/__init__.py +0 -0
- plexflow/utils/hooks/http.py +84 -0
- plexflow/utils/hooks/postgresql.py +93 -0
- plexflow/utils/hooks/redis.py +112 -0
- plexflow/utils/image/storage.py +36 -0
- plexflow/utils/imdb/__init__.py +0 -0
- plexflow/utils/imdb/imdb_codes.py +107 -0
- plexflow/utils/pubsub/consume.py +82 -0
- plexflow/utils/pubsub/produce.py +25 -0
- plexflow/utils/retry/__init__.py +0 -0
- plexflow/utils/retry/utils.py +38 -0
- plexflow/utils/strings/__init__.py +0 -0
- plexflow/utils/strings/filesize.py +55 -0
- plexflow/utils/strings/language.py +14 -0
- plexflow/utils/subtitle/search.py +76 -0
- plexflow/utils/tasks/decorators.py +78 -0
- plexflow/utils/tasks/k8s/task.py +70 -0
- plexflow/utils/thread_safe/safe_list.py +54 -0
- plexflow/utils/thread_safe/safe_set.py +69 -0
- plexflow/utils/torrent/__init__.py +0 -0
- plexflow/utils/torrent/analyze.py +118 -0
- plexflow/utils/torrent/extract/common.py +37 -0
- plexflow/utils/torrent/extract/ext.py +2391 -0
- plexflow/utils/torrent/extract/extratorrent.py +56 -0
- plexflow/utils/torrent/extract/kat.py +1581 -0
- plexflow/utils/torrent/extract/tgx.py +96 -0
- plexflow/utils/torrent/extract/therarbg.py +170 -0
- plexflow/utils/torrent/extract/torrentquest.py +171 -0
- plexflow/utils/torrent/files.py +36 -0
- plexflow/utils/torrent/hash.py +90 -0
- plexflow/utils/transcribe/__init__.py +0 -0
- plexflow/utils/transcribe/speech2text.py +40 -0
- plexflow/utils/video/__init__.py +0 -0
- plexflow/utils/video/subtitle.py +73 -0
- plexflow-0.0.64.dist-info/METADATA +71 -0
- plexflow-0.0.64.dist-info/RECORD +256 -0
- plexflow-0.0.64.dist-info/WHEEL +4 -0
- plexflow-0.0.64.dist-info/entry_points.txt +24 -0
@@ -0,0 +1,554 @@
|
|
1
|
+
from dataclasses import dataclass, field
|
2
|
+
from typing import List, Optional, Dict
|
3
|
+
from dataclasses_json import dataclass_json, Undefined
|
4
|
+
|
5
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
6
|
+
@dataclass
|
7
|
+
class AirsDays:
|
8
|
+
"""
|
9
|
+
Represents the days on which a TV show airs.
|
10
|
+
|
11
|
+
Attributes:
|
12
|
+
friday (Optional[bool]): Indicates if the show airs on Fridays.
|
13
|
+
monday (Optional[bool]): Indicates if the show airs on Mondays.
|
14
|
+
saturday (Optional[bool]): Indicates if the show airs on Saturdays.
|
15
|
+
sunday (Optional[bool]): Indicates if the show airs on Sundays.
|
16
|
+
thursday (Optional[bool]): Indicates if the show airs on Thursdays.
|
17
|
+
tuesday (Optional[bool]): Indicates if the show airs on Tuesdays.
|
18
|
+
wednesday (Optional[bool]): Indicates if the show airs on Wednesdays.
|
19
|
+
_catchall (dict): Catch-all attribute for any additional data not defined in the class.
|
20
|
+
"""
|
21
|
+
friday: Optional[bool] = None
|
22
|
+
monday: Optional[bool] = None
|
23
|
+
saturday: Optional[bool] = None
|
24
|
+
sunday: Optional[bool] = None
|
25
|
+
thursday: Optional[bool] = None
|
26
|
+
tuesday: Optional[bool] = None
|
27
|
+
wednesday: Optional[bool] = None
|
28
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
29
|
+
|
30
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
31
|
+
@dataclass
|
32
|
+
class Alias:
|
33
|
+
"""
|
34
|
+
Represents an alias for a TV show or character.
|
35
|
+
|
36
|
+
Attributes:
|
37
|
+
language (Optional[str]): The language of the alias.
|
38
|
+
name (Optional[str]): The name of the alias.
|
39
|
+
_catchall (dict): A catch-all field for any additional attributes.
|
40
|
+
"""
|
41
|
+
language: Optional[str] = None
|
42
|
+
name: Optional[str] = None
|
43
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
44
|
+
|
45
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
46
|
+
@dataclass
|
47
|
+
class TagOption:
|
48
|
+
"""
|
49
|
+
Represents a tag option for a TV show.
|
50
|
+
|
51
|
+
Attributes:
|
52
|
+
helpText (Optional[str]): The help text for the tag option.
|
53
|
+
id (Optional[int]): The ID of the tag option.
|
54
|
+
name (Optional[str]): The name of the tag option.
|
55
|
+
tag (Optional[int]): The tag of the tag option.
|
56
|
+
tagName (Optional[str]): The tag name of the tag option.
|
57
|
+
_catchall (dict): A catch-all field for any additional attributes not defined in the class.
|
58
|
+
"""
|
59
|
+
helpText: Optional[str] = None
|
60
|
+
id: Optional[int] = None
|
61
|
+
name: Optional[str] = None
|
62
|
+
tag: Optional[int] = None
|
63
|
+
tagName: Optional[str] = None
|
64
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
65
|
+
|
66
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
67
|
+
@dataclass
|
68
|
+
class Status:
|
69
|
+
"""
|
70
|
+
Represents the status of a TV show.
|
71
|
+
|
72
|
+
Attributes:
|
73
|
+
id (Optional[int]): The ID of the status.
|
74
|
+
name (Optional[str]): The name of the status.
|
75
|
+
_catchall (dict): A catch-all dictionary for any additional attributes.
|
76
|
+
"""
|
77
|
+
id: Optional[int] = None
|
78
|
+
name: Optional[str] = None
|
79
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
80
|
+
|
81
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
82
|
+
@dataclass
|
83
|
+
class Artwork:
|
84
|
+
"""
|
85
|
+
Represents artwork associated with a TV show.
|
86
|
+
|
87
|
+
Attributes:
|
88
|
+
episodeId (Optional[int]): The ID of the episode associated with the artwork.
|
89
|
+
height (Optional[int]): The height of the artwork image.
|
90
|
+
id (Optional[int]): The ID of the artwork.
|
91
|
+
image (Optional[str]): The URL or path to the artwork image.
|
92
|
+
includesText (Optional[bool]): Indicates whether the artwork includes text.
|
93
|
+
language (Optional[str]): The language of the artwork.
|
94
|
+
movieId (Optional[int]): The ID of the movie associated with the artwork.
|
95
|
+
networkId (Optional[int]): The ID of the network associated with the artwork.
|
96
|
+
peopleId (Optional[int]): The ID of the people associated with the artwork.
|
97
|
+
score (Optional[int]): The score of the artwork.
|
98
|
+
seasonId (Optional[int]): The ID of the season associated with the artwork.
|
99
|
+
seriesId (Optional[int]): The ID of the series associated with the artwork.
|
100
|
+
seriesPeopleId (Optional[int]): The ID of the series people associated with the artwork.
|
101
|
+
status (Optional[Status]): The status of the artwork.
|
102
|
+
tagOptions (Optional[List[TagOption]]): The tag options associated with the artwork.
|
103
|
+
thumbnail (Optional[str]): The URL or path to the thumbnail image of the artwork.
|
104
|
+
thumbnailHeight (Optional[int]): The height of the thumbnail image.
|
105
|
+
thumbnailWidth (Optional[int]): The width of the thumbnail image.
|
106
|
+
type (Optional[int]): The type of the artwork.
|
107
|
+
updatedAt (Optional[int]): The timestamp of when the artwork was last updated.
|
108
|
+
width (Optional[int]): The width of the artwork image.
|
109
|
+
_catchall (dict): A catch-all field for any additional attributes not defined in the class.
|
110
|
+
"""
|
111
|
+
|
112
|
+
episodeId: Optional[int] = None
|
113
|
+
height: Optional[int] = None
|
114
|
+
id: Optional[int] = None
|
115
|
+
image: Optional[str] = None
|
116
|
+
includesText: Optional[bool] = None
|
117
|
+
language: Optional[str] = None
|
118
|
+
movieId: Optional[int] = None
|
119
|
+
networkId: Optional[int] = None
|
120
|
+
peopleId: Optional[int] = None
|
121
|
+
score: Optional[int] = None
|
122
|
+
seasonId: Optional[int] = None
|
123
|
+
seriesId: Optional[int] = None
|
124
|
+
seriesPeopleId: Optional[int] = None
|
125
|
+
status: Optional[Status] = None
|
126
|
+
tagOptions: Optional[List[TagOption]] = None
|
127
|
+
thumbnail: Optional[str] = None
|
128
|
+
thumbnailHeight: Optional[int] = None
|
129
|
+
thumbnailWidth: Optional[int] = None
|
130
|
+
type: Optional[int] = None
|
131
|
+
updatedAt: Optional[int] = None
|
132
|
+
width: Optional[int] = None
|
133
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
134
|
+
|
135
|
+
def __post_init__(self):
|
136
|
+
self.status = Status(**self.status) if isinstance(self.status, dict) else self.status
|
137
|
+
self.tagOptions = [TagOption(**tagOption) if isinstance(tagOption, dict) else tagOption for tagOption in self.tagOptions] if self.tagOptions else []
|
138
|
+
|
139
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
140
|
+
@dataclass
|
141
|
+
class EpisodeInfo:
|
142
|
+
"""
|
143
|
+
Represents information about an episode of a TV show.
|
144
|
+
|
145
|
+
Attributes:
|
146
|
+
image (Optional[str]): The image associated with the episode.
|
147
|
+
name (Optional[str]): The name of the episode.
|
148
|
+
year (Optional[str]): The year the episode was released.
|
149
|
+
_catchall (dict): A catch-all dictionary for any additional attributes.
|
150
|
+
"""
|
151
|
+
image: Optional[str] = None
|
152
|
+
name: Optional[str] = None
|
153
|
+
year: Optional[str] = None
|
154
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
155
|
+
|
156
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
157
|
+
@dataclass
|
158
|
+
class Character:
|
159
|
+
"""
|
160
|
+
Represents a character in a TV show.
|
161
|
+
|
162
|
+
Attributes:
|
163
|
+
aliases (Optional[List[Alias]]): List of aliases for the character.
|
164
|
+
episode (Optional[EpisodeInfo]): Information about the episode the character appears in.
|
165
|
+
episodeId (Optional[int]): ID of the episode the character appears in.
|
166
|
+
id (Optional[int]): ID of the character.
|
167
|
+
image (Optional[str]): URL of the character's image.
|
168
|
+
isFeatured (Optional[bool]): Indicates if the character is featured.
|
169
|
+
movieId (Optional[int]): ID of the movie the character appears in.
|
170
|
+
movie (Optional[EpisodeInfo]): Information about the movie the character appears in.
|
171
|
+
name (Optional[str]): Name of the character.
|
172
|
+
nameTranslations (Optional[List[str]]): List of translated names for the character.
|
173
|
+
overviewTranslations (Optional[List[str]]): List of translated overviews for the character.
|
174
|
+
peopleId (Optional[int]): ID of the people associated with the character.
|
175
|
+
personImgURL (Optional[str]): URL of the person's image associated with the character.
|
176
|
+
peopleType (Optional[str]): Type of people associated with the character.
|
177
|
+
seriesId (Optional[int]): ID of the TV series the character appears in.
|
178
|
+
series (Optional[EpisodeInfo]): Information about the TV series the character appears in.
|
179
|
+
sort (Optional[int]): Sort order of the character.
|
180
|
+
tagOptions (Optional[List[TagOption]]): List of tag options for the character.
|
181
|
+
type (Optional[int]): Type of the character.
|
182
|
+
url (Optional[str]): URL of the character.
|
183
|
+
personName (Optional[str]): Name of the person associated with the character.
|
184
|
+
_catchall (dict): Catch-all field for any additional attributes not defined in the class.
|
185
|
+
|
186
|
+
Methods:
|
187
|
+
__post_init__(): Initializes the class instance and converts nested dictionaries to objects.
|
188
|
+
"""
|
189
|
+
aliases: Optional[List[Alias]] = None
|
190
|
+
episode: Optional[EpisodeInfo] = None
|
191
|
+
episodeId: Optional[int] = None
|
192
|
+
id: Optional[int] = None
|
193
|
+
image: Optional[str] = None
|
194
|
+
isFeatured: Optional[bool] = None
|
195
|
+
movieId: Optional[int] = None
|
196
|
+
movie: Optional[EpisodeInfo] = None
|
197
|
+
name: Optional[str] = None
|
198
|
+
nameTranslations: Optional[List[str]] = None
|
199
|
+
overviewTranslations: Optional[List[str]] = None
|
200
|
+
peopleId: Optional[int] = None
|
201
|
+
personImgURL: Optional[str] = None
|
202
|
+
peopleType: Optional[str] = None
|
203
|
+
seriesId: Optional[int] = None
|
204
|
+
series: Optional[EpisodeInfo] = None
|
205
|
+
sort: Optional[int] = None
|
206
|
+
tagOptions: Optional[List[TagOption]] = None
|
207
|
+
type: Optional[int] = None
|
208
|
+
url: Optional[str] = None
|
209
|
+
personName: Optional[str] = None
|
210
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
211
|
+
|
212
|
+
def __post_init__(self):
|
213
|
+
self.aliases = [Alias(**alias) if isinstance(alias, dict) else alias for alias in self.aliases] if self.aliases else []
|
214
|
+
self.episode = EpisodeInfo(**self.episode) if isinstance(self.episode, dict) else self.episode
|
215
|
+
self.movie = EpisodeInfo(**self.movie) if isinstance(self.movie, dict) else self.movie
|
216
|
+
self.series = EpisodeInfo(**self.series) if isinstance(self.series, dict) else self.series
|
217
|
+
self.tagOptions = [TagOption(**tagOption) if isinstance(tagOption, dict) else tagOption for tagOption in self.tagOptions] if self.tagOptions else []
|
218
|
+
|
219
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
220
|
+
@dataclass
|
221
|
+
class ContentRating:
|
222
|
+
"""
|
223
|
+
Represents the content rating of a TV show.
|
224
|
+
|
225
|
+
Attributes:
|
226
|
+
id (Optional[int]): The ID of the content rating.
|
227
|
+
name (Optional[str]): The name of the content rating.
|
228
|
+
description (Optional[str]): The description of the content rating.
|
229
|
+
country (Optional[str]): The country of the content rating.
|
230
|
+
contentType (Optional[str]): The type of content the rating applies to.
|
231
|
+
order (Optional[int]): The order of the content rating.
|
232
|
+
fullName (Optional[str]): The full name of the content rating.
|
233
|
+
_catchall (dict): A catch-all field for any additional attributes not defined in the class.
|
234
|
+
"""
|
235
|
+
id: Optional[int] = None
|
236
|
+
name: Optional[str] = None
|
237
|
+
description: Optional[str] = None
|
238
|
+
country: Optional[str] = None
|
239
|
+
contentType: Optional[str] = None
|
240
|
+
order: Optional[int] = None
|
241
|
+
fullName: Optional[str] = None
|
242
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
243
|
+
|
244
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
245
|
+
@dataclass
|
246
|
+
class Company:
|
247
|
+
"""
|
248
|
+
Represents a company associated with a TV show.
|
249
|
+
"""
|
250
|
+
activeDate: Optional[str] = None
|
251
|
+
aliases: Optional[List[Alias]] = None
|
252
|
+
country: Optional[str] = None
|
253
|
+
id: Optional[int] = None
|
254
|
+
inactiveDate: Optional[str] = None
|
255
|
+
name: Optional[str] = None
|
256
|
+
nameTranslations: Optional[List[str]] = None
|
257
|
+
overviewTranslations: Optional[List[str]] = None
|
258
|
+
primaryCompanyType: Optional[int] = None
|
259
|
+
slug: Optional[str] = None
|
260
|
+
parentCompany: Optional[Status] = None
|
261
|
+
tagOptions: Optional[List[TagOption]] = None
|
262
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
263
|
+
|
264
|
+
def __post_init__(self):
|
265
|
+
self.aliases = [Alias(**alias) if isinstance(alias, dict) else alias for alias in self.aliases]
|
266
|
+
self.parentCompany = Status(**self.parentCompany) if isinstance(self.parentCompany, dict) else self.parentCompany
|
267
|
+
self.tagOptions = [TagOption(**tagOption) if isinstance(tagOption, dict) else tagOption for tagOption in self.tagOptions] if self.tagOptions else []
|
268
|
+
|
269
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
270
|
+
@dataclass
|
271
|
+
class Companies:
|
272
|
+
"""
|
273
|
+
Represents the companies associated with a TV show.
|
274
|
+
"""
|
275
|
+
studio: Optional[List[Company]] = None
|
276
|
+
network: Optional[List[Company]] = None
|
277
|
+
production: Optional[List[Company]] = None
|
278
|
+
distributor: Optional[List[Company]] = None
|
279
|
+
special_effects: Optional[List[Company]] = None
|
280
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
281
|
+
|
282
|
+
def __post_init__(self):
|
283
|
+
self.studio = [Company(**company) if isinstance(company, dict) else company for company in self.studio] if self.studio else []
|
284
|
+
self.network = [Company(**company) if isinstance(company, dict) else company for company in self.network] if self.network else []
|
285
|
+
self.production = [Company(**company) if isinstance(company, dict) else company for company in self.production] if self.production else []
|
286
|
+
self.distributor = [Company(**company) if isinstance(company, dict) else company for company in self.distributor] if self.distributor else []
|
287
|
+
self.special_effects = [Company(**company) if isinstance(company, dict) else company for company in self.special_effects] if self.special_effects else []
|
288
|
+
|
289
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
290
|
+
@dataclass
|
291
|
+
class Type:
|
292
|
+
"""
|
293
|
+
Represents the type of a TV show.
|
294
|
+
"""
|
295
|
+
alternateName: Optional[str] = None
|
296
|
+
id: Optional[int] = None
|
297
|
+
name: Optional[str] = None
|
298
|
+
type: Optional[str] = None
|
299
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
300
|
+
|
301
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
302
|
+
@dataclass
|
303
|
+
class Season:
|
304
|
+
"""
|
305
|
+
Represents a season of a TV show.
|
306
|
+
"""
|
307
|
+
id: Optional[int] = None
|
308
|
+
image: Optional[str] = None
|
309
|
+
imageType: Optional[int] = None
|
310
|
+
lastUpdated: Optional[str] = None
|
311
|
+
name: Optional[str] = None
|
312
|
+
nameTranslations: Optional[List[str]] = None
|
313
|
+
number: Optional[int] = None
|
314
|
+
overviewTranslations: Optional[List[str]] = None
|
315
|
+
companies: Optional[Companies] = None
|
316
|
+
seriesId: Optional[int] = None
|
317
|
+
type: Optional[Type] = None
|
318
|
+
year: Optional[str] = None
|
319
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
320
|
+
|
321
|
+
def __post_init__(self):
|
322
|
+
self.companies = Companies(**self.companies) if isinstance(self.companies, dict) else self.companies
|
323
|
+
self.type = Type(**self.type) if isinstance(self.type, dict) else self.type
|
324
|
+
|
325
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
326
|
+
@dataclass
|
327
|
+
class Episode:
|
328
|
+
"""
|
329
|
+
Represents an episode of a TV show.
|
330
|
+
"""
|
331
|
+
aired: Optional[str] = None
|
332
|
+
airsAfterSeason: Optional[int] = None
|
333
|
+
airsBeforeEpisode: Optional[int] = None
|
334
|
+
airsBeforeSeason: Optional[int] = None
|
335
|
+
finaleType: Optional[str] = None
|
336
|
+
id: Optional[int] = None
|
337
|
+
image: Optional[str] = None
|
338
|
+
imageType: Optional[int] = None
|
339
|
+
isMovie: Optional[int] = None
|
340
|
+
lastUpdated: Optional[str] = None
|
341
|
+
linkedMovie: Optional[int] = None
|
342
|
+
name: Optional[str] = None
|
343
|
+
nameTranslations: Optional[List[str]] = None
|
344
|
+
number: Optional[int] = None
|
345
|
+
overview: Optional[str] = None
|
346
|
+
overviewTranslations: Optional[List[str]] = None
|
347
|
+
runtime: Optional[int] = None
|
348
|
+
seasonNumber: Optional[int] = None
|
349
|
+
seasons: Optional[List[Season]] = None
|
350
|
+
seriesId: Optional[int] = None
|
351
|
+
seasonName: Optional[str] = None
|
352
|
+
year: Optional[str] = None
|
353
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
354
|
+
|
355
|
+
def __post_init__(self):
|
356
|
+
self.seasons = [Season(**season) if isinstance(season, dict) else season for season in self.seasons] if self.seasons else []
|
357
|
+
|
358
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
359
|
+
@dataclass
|
360
|
+
class ListAlias:
|
361
|
+
"""
|
362
|
+
Represents an alias for a TV show list.
|
363
|
+
"""
|
364
|
+
language: Optional[str] = None
|
365
|
+
name: Optional[str] = None
|
366
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
367
|
+
|
368
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
369
|
+
@dataclass
|
370
|
+
class RemoteId:
|
371
|
+
"""
|
372
|
+
Represents a remote ID for a TV show.
|
373
|
+
"""
|
374
|
+
id: Optional[str] = None
|
375
|
+
type: Optional[int] = None
|
376
|
+
sourceName: Optional[str] = None
|
377
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
378
|
+
|
379
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
380
|
+
@dataclass
|
381
|
+
class TvdbList:
|
382
|
+
"""
|
383
|
+
Represents a TV show list.
|
384
|
+
"""
|
385
|
+
aliases: Optional[List[ListAlias]] = None
|
386
|
+
id: Optional[int] = None
|
387
|
+
image: Optional[str] = None
|
388
|
+
imageIsFallback: Optional[bool] = None
|
389
|
+
isOfficial: Optional[bool] = None
|
390
|
+
name: Optional[str] = None
|
391
|
+
nameTranslations: Optional[List[str]] = None
|
392
|
+
overview: Optional[str] = None
|
393
|
+
overviewTranslations: Optional[List[str]] = None
|
394
|
+
remoteIds: Optional[List[RemoteId]] = None
|
395
|
+
tags: Optional[List[TagOption]] = None
|
396
|
+
score: Optional[int] = None
|
397
|
+
url: Optional[str] = None
|
398
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
399
|
+
|
400
|
+
def __post_init__(self):
|
401
|
+
self.aliases = [ListAlias(**alias) if isinstance(alias, dict) else alias for alias in self.aliases]
|
402
|
+
self.remoteIds = [RemoteId(**remoteId) if isinstance(remoteId, dict) else remoteId for remoteId in self.remoteIds] if self.remoteIds else []
|
403
|
+
self.tags = [TagOption(**tag) if isinstance(tag, dict) else tag for tag in self.tags] if self.tags else []
|
404
|
+
|
405
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
406
|
+
@dataclass
|
407
|
+
class Genre:
|
408
|
+
id: Optional[int] = None
|
409
|
+
name: Optional[str] = None
|
410
|
+
slug: Optional[str] = None
|
411
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
412
|
+
|
413
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
414
|
+
@dataclass
|
415
|
+
class Translation:
|
416
|
+
aliases: Optional[List[str]] = None
|
417
|
+
isAlias: Optional[bool] = None
|
418
|
+
isPrimary: Optional[bool] = None
|
419
|
+
language: Optional[str] = None
|
420
|
+
name: Optional[str] = None
|
421
|
+
overview: Optional[str] = None
|
422
|
+
tagline: Optional[str] = None
|
423
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
424
|
+
|
425
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
426
|
+
@dataclass
|
427
|
+
class Translations:
|
428
|
+
nameTranslations: Optional[List[Translation]] = None
|
429
|
+
overviewTranslations: Optional[List[Translation]] = None
|
430
|
+
alias: Optional[List[str]] = None
|
431
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
432
|
+
|
433
|
+
def __post_init__(self):
|
434
|
+
self.nameTranslations = [Translation(**translation) if isinstance(translation, dict) else translation for translation in self.nameTranslations]
|
435
|
+
self.overviewTranslations = [Translation(**translation) if isinstance(translation, dict) else translation for translation in self.overviewTranslations]
|
436
|
+
|
437
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
438
|
+
@dataclass
|
439
|
+
class Trailer:
|
440
|
+
id: Optional[int] = None
|
441
|
+
language: Optional[str] = None
|
442
|
+
name: Optional[str] = None
|
443
|
+
url: Optional[str] = None
|
444
|
+
runtime: Optional[int] = None
|
445
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
446
|
+
|
447
|
+
@dataclass_json(undefined=Undefined.EXCLUDE)
|
448
|
+
@dataclass
|
449
|
+
class TvdbShow:
|
450
|
+
"""
|
451
|
+
Represents a TV show retrieved from the TVDB API.
|
452
|
+
|
453
|
+
Attributes:
|
454
|
+
abbreviation (Optional[str]): The abbreviation of the show.
|
455
|
+
airsDays (Optional[AirsDays]): The days on which the show airs.
|
456
|
+
airsTime (Optional[str]): The time at which the show airs.
|
457
|
+
aliases (Optional[List[Alias]]): The aliases of the show.
|
458
|
+
artworks (Optional[List[Artwork]]): The artworks associated with the show.
|
459
|
+
averageRuntime (Optional[int]): The average runtime of the show in minutes.
|
460
|
+
characters (Optional[List[Character]]): The characters in the show.
|
461
|
+
contentRatings (Optional[List[ContentRating]]): The content ratings of the show.
|
462
|
+
country (Optional[str]): The country in which the show is produced.
|
463
|
+
defaultSeasonType (Optional[int]): The default season type of the show.
|
464
|
+
episodes (Optional[List[Episode]]): The episodes of the show.
|
465
|
+
firstAired (Optional[str]): The date on which the show first aired.
|
466
|
+
lists (Optional[List[TvdbList]]): The lists associated with the show.
|
467
|
+
genres (Optional[List[Genre]]): The genres of the show.
|
468
|
+
id (Optional[int]): The ID of the show.
|
469
|
+
image (Optional[str]): The image associated with the show.
|
470
|
+
isOrderRandomized (Optional[bool]): Indicates if the episode order is randomized.
|
471
|
+
lastAired (Optional[str]): The date on which the show last aired.
|
472
|
+
lastUpdated (Optional[str]): The date on which the show was last updated.
|
473
|
+
name (Optional[str]): The name of the show.
|
474
|
+
nameTranslations (Optional[List[str]]): The translations of the show's name.
|
475
|
+
companies (Optional[List[Company]]): The companies associated with the show.
|
476
|
+
nextAired (Optional[str]): The date on which the next episode airs.
|
477
|
+
originalCountry (Optional[str]): The original country of the show.
|
478
|
+
originalLanguage (Optional[str]): The original language of the show.
|
479
|
+
originalNetwork (Optional[Company]): The original network of the show.
|
480
|
+
overview (Optional[str]): The overview of the show.
|
481
|
+
latestNetwork (Optional[Company]): The latest network of the show.
|
482
|
+
overviewTranslations (Optional[List[str]]): The translations of the show's overview.
|
483
|
+
remoteIds (Optional[List[RemoteId]]): The remote IDs associated with the show.
|
484
|
+
score (Optional[int]): The score of the show.
|
485
|
+
seasons (Optional[List[Season]]): The seasons of the show.
|
486
|
+
seasonTypes (Optional[List[Type]]): The types of seasons in the show.
|
487
|
+
slug (Optional[str]): The slug of the show.
|
488
|
+
status (Optional[Status]): The status of the show.
|
489
|
+
tags (Optional[List[TagOption]]): The tags associated with the show.
|
490
|
+
trailers (Optional[List[Trailer]]): The trailers of the show.
|
491
|
+
translations (Optional[Translations]): The translations of the show.
|
492
|
+
year (Optional[str]): The year in which the show was released.
|
493
|
+
_catchall (dict): A catch-all field for any additional attributes.
|
494
|
+
"""
|
495
|
+
abbreviation: Optional[str] = None
|
496
|
+
airsDays: Optional[AirsDays] = None
|
497
|
+
airsTime: Optional[str] = None
|
498
|
+
aliases: Optional[List[Alias]] = None
|
499
|
+
artworks: Optional[List[Artwork]] = None
|
500
|
+
averageRuntime: Optional[int] = None
|
501
|
+
characters: Optional[List[Character]] = None
|
502
|
+
contentRatings: Optional[List[ContentRating]] = None
|
503
|
+
country: Optional[str] = None
|
504
|
+
defaultSeasonType: Optional[int] = None
|
505
|
+
episodes: Optional[List[Episode]] = None
|
506
|
+
firstAired: Optional[str] = None
|
507
|
+
lists: Optional[List[TvdbList]] = None
|
508
|
+
genres: Optional[List[Genre]] = None
|
509
|
+
id: Optional[int] = None
|
510
|
+
image: Optional[str] = None
|
511
|
+
isOrderRandomized: Optional[bool] = None
|
512
|
+
lastAired: Optional[str] = None
|
513
|
+
lastUpdated: Optional[str] = None
|
514
|
+
name: Optional[str] = None
|
515
|
+
nameTranslations: Optional[List[str]] = None
|
516
|
+
companies: Optional[List[Company]] = None
|
517
|
+
nextAired: Optional[str] = None
|
518
|
+
originalCountry: Optional[str] = None
|
519
|
+
originalLanguage: Optional[str] = None
|
520
|
+
originalNetwork: Optional[Company] = None
|
521
|
+
overview: Optional[str] = None
|
522
|
+
latestNetwork: Optional[Company] = None
|
523
|
+
overviewTranslations: Optional[List[str]] = None
|
524
|
+
remoteIds: Optional[List[RemoteId]] = None
|
525
|
+
score: Optional[int] = None
|
526
|
+
seasons: Optional[List[Season]] = None
|
527
|
+
seasonTypes: Optional[List[Type]] = None
|
528
|
+
slug: Optional[str] = None
|
529
|
+
status: Optional[Status] = None
|
530
|
+
tags: Optional[List[TagOption]] = None
|
531
|
+
trailers: Optional[List[Trailer]] = None
|
532
|
+
translations: Optional[Translations] = None
|
533
|
+
year: Optional[str] = None
|
534
|
+
_catchall: dict = field(default_factory=dict, repr=False)
|
535
|
+
|
536
|
+
def __post_init__(self):
|
537
|
+
self.airsDays = AirsDays(**self.airsDays) if isinstance(self.airsDays, dict) else self.airsDays
|
538
|
+
self.aliases = [Alias(**alias) if isinstance(alias, dict) else alias for alias in self.aliases]
|
539
|
+
self.artworks = [Artwork(**artwork) if isinstance(artwork, dict) else artwork for artwork in self.artworks] if self.artworks else []
|
540
|
+
self.characters = [Character(**character) if isinstance(character, dict) else character for character in self.characters] if self.characters else []
|
541
|
+
self.contentRatings = [ContentRating(**contentRating) if isinstance(contentRating, dict) else contentRating for contentRating in self.contentRatings]
|
542
|
+
self.episodes = [Episode(**episode) if isinstance(episode, dict) else episode for episode in self.episodes] if self.episodes else []
|
543
|
+
self.lists = [TvdbList(**list) if isinstance(list, dict) else list for list in self.lists]
|
544
|
+
self.genres = [Genre(**genre) if isinstance(genre, dict) else genre for genre in self.genres]
|
545
|
+
self.companies = [Company(**company) if isinstance(company, dict) else company for company in self.companies]
|
546
|
+
self.originalNetwork = Company(**self.originalNetwork) if isinstance(self.originalNetwork, dict) else self.originalNetwork
|
547
|
+
self.latestNetwork = Company(**self.latestNetwork) if isinstance(self.latestNetwork, dict) else self.latestNetwork
|
548
|
+
self.remoteIds = [RemoteId(**remoteId) if isinstance(remoteId, dict) else remoteId for remoteId in self.remoteIds]
|
549
|
+
self.seasons = [Season(**season) if isinstance(season, dict) else season for season in self.seasons]
|
550
|
+
self.seasonTypes = [Type(**type) if isinstance(type, dict) else type for type in self.seasonTypes]
|
551
|
+
self.status = Status(**self.status) if isinstance(self.status, dict) else self.status
|
552
|
+
self.tags = [TagOption(**tag) if isinstance(tag, dict) else tag for tag in self.tags]
|
553
|
+
self.trailers = [Trailer(**trailer) if isinstance(trailer, dict) else trailer for trailer in self.trailers]
|
554
|
+
self.translations = Translations(**self.translations) if isinstance(self.translations, dict) else self.translations
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import os
|
2
|
+
from tvdb_v4_official import TVDB
|
3
|
+
from typing import Union
|
4
|
+
from plexflow.core.metadata.providers.tvdb.datatypes import TvdbMovie, movie_from_json, show_from_json
|
5
|
+
from plexflow.core.metadata.providers.tvdb.tv_datatypes import TvdbShow
|
6
|
+
import json
|
7
|
+
|
8
|
+
def search_movie_by_imdb(imdb_id: str) -> Union[TvdbMovie, None]:
|
9
|
+
"""
|
10
|
+
Search for a movie in TVDB by IMDB ID.
|
11
|
+
|
12
|
+
Args:
|
13
|
+
imdb_id (str): The IMDB ID of the movie.
|
14
|
+
|
15
|
+
Returns:
|
16
|
+
Union[TvdbMovie, None]: The TvdbMovie object representing the movie if found, None otherwise.
|
17
|
+
"""
|
18
|
+
tvdb = TVDB(os.getenv("TVDB_API_KEY"))
|
19
|
+
try:
|
20
|
+
response = tvdb.search_by_remote_id(imdb_id)
|
21
|
+
if response:
|
22
|
+
movie_id = response[0]["movie"]['id']
|
23
|
+
movie = tvdb.get_movie_extended(movie_id)
|
24
|
+
return movie_from_json(json.dumps(movie))
|
25
|
+
else:
|
26
|
+
raise ValueError(f"No movie found with IMDB ID {imdb_id}")
|
27
|
+
except Exception as e:
|
28
|
+
raise e
|
29
|
+
|
30
|
+
def search_show_by_imdb(imdb_id: str) -> Union[TvdbShow, None]:
|
31
|
+
"""
|
32
|
+
Searches for a TV show in the TVDB database using the IMDB ID.
|
33
|
+
|
34
|
+
Args:
|
35
|
+
imdb_id (str): The IMDB ID of the TV show.
|
36
|
+
|
37
|
+
Returns:
|
38
|
+
Union[TvdbShow, None]: An instance of the TvdbShow class representing the TV show if found,
|
39
|
+
otherwise None.
|
40
|
+
|
41
|
+
Raises:
|
42
|
+
ValueError: If no TV show is found with the given IMDB ID.
|
43
|
+
Exception: If an error occurs during the search.
|
44
|
+
|
45
|
+
"""
|
46
|
+
tvdb = TVDB(os.getenv("TVDB_API_KEY"))
|
47
|
+
try:
|
48
|
+
response = tvdb.search_by_remote_id(imdb_id)
|
49
|
+
if response:
|
50
|
+
show_id = response[0]["series"]['id']
|
51
|
+
show = tvdb.get_series_extended(show_id, meta="episodes", short=True)
|
52
|
+
return TvdbShow.from_dict(show)
|
53
|
+
else:
|
54
|
+
raise ValueError(f"No TV show found with IMDB ID {imdb_id}")
|
55
|
+
except Exception as e:
|
56
|
+
raise e
|
57
|
+
|
58
|
+
|
59
|
+
def get_season(season_id: int) -> dict:
|
60
|
+
tvdb = TVDB(os.getenv("TVDB_API_KEY"))
|
61
|
+
try:
|
62
|
+
response = tvdb.get_season_extended(season_id)
|
63
|
+
return response
|
64
|
+
except Exception as e:
|
65
|
+
raise e
|
File without changes
|