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,40 @@
|
|
1
|
+
from plexflow.core.metadata.auto.auto_providers.auto.movie import AutoMovie
|
2
|
+
from plexflow.core.metadata.auto.auto_providers.auto.show import AutoShow
|
3
|
+
from plexflow.core.metadata.auto.auto_providers.tmdb.movie import AutoTmdbMovie
|
4
|
+
from plexflow.core.metadata.auto.auto_providers.tvdb.movie import AutoTvdbMovie
|
5
|
+
from plexflow.core.metadata.auto.auto_providers.moviemeter.movie import AutoMovieMeterMovie
|
6
|
+
from plexflow.core.metadata.auto.auto_providers.imdb.movie import AutoImdbMovie
|
7
|
+
from plexflow.core.metadata.auto.auto_providers.tmdb.show import AutoTmdbShow
|
8
|
+
from plexflow.core.metadata.auto.auto_providers.tvdb.show import AutoTvdbShow
|
9
|
+
from plexflow.core.metadata.auto.auto_providers.imdb.show import AutoImdbShow
|
10
|
+
from plexflow.core.metadata.auto.auto_providers.plex.movie import AutoPlexMovie
|
11
|
+
|
12
|
+
class AutoMeta:
|
13
|
+
@staticmethod
|
14
|
+
def movie(imdb_id: str = None, source: str = 'tmdb', rating_key: str = None) -> AutoMovie:
|
15
|
+
if source == 'tmdb':
|
16
|
+
return AutoTmdbMovie(imdb_id)
|
17
|
+
elif source == 'tvdb':
|
18
|
+
return AutoTvdbMovie(imdb_id)
|
19
|
+
elif source =='moviemeter':
|
20
|
+
return AutoMovieMeterMovie(imdb_id)
|
21
|
+
elif source == 'imdb':
|
22
|
+
return AutoImdbMovie(imdb_id)
|
23
|
+
elif source == "plex":
|
24
|
+
if isinstance(rating_key, str):
|
25
|
+
return AutoPlexMovie(rating_key)
|
26
|
+
else:
|
27
|
+
raise ValueError("if source = 'plex', rating_key must be set")
|
28
|
+
else:
|
29
|
+
raise ValueError(f"Invalid source: {source}")
|
30
|
+
|
31
|
+
@staticmethod
|
32
|
+
def show(imdb_id: str, source: str = 'tmdb') -> AutoShow:
|
33
|
+
if source == 'tmdb':
|
34
|
+
return AutoTmdbShow(imdb_id)
|
35
|
+
elif source == 'tvdb':
|
36
|
+
return AutoTvdbShow(imdb_id)
|
37
|
+
elif source == 'imdb':
|
38
|
+
return AutoImdbShow(imdb_id)
|
39
|
+
else:
|
40
|
+
raise ValueError(f"Invalid source: {source}")
|
File without changes
|
File without changes
|
@@ -0,0 +1,49 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
from datetime import datetime
|
3
|
+
|
4
|
+
from plexflow.core.metadata.auto.auto_providers.auto.season import AutoSeason
|
5
|
+
|
6
|
+
class AutoEpisode(ABC):
|
7
|
+
def __init__(self, parent: AutoSeason) -> None:
|
8
|
+
self._parent = parent
|
9
|
+
|
10
|
+
@property
|
11
|
+
def source(self) -> str:
|
12
|
+
return self._parent.source
|
13
|
+
|
14
|
+
@property
|
15
|
+
def season(self) -> AutoSeason:
|
16
|
+
return self._parent
|
17
|
+
|
18
|
+
@property
|
19
|
+
@abstractmethod
|
20
|
+
def runtime(self) -> int:
|
21
|
+
pass
|
22
|
+
|
23
|
+
@property
|
24
|
+
def year(self) -> int:
|
25
|
+
return self.release_date.year
|
26
|
+
|
27
|
+
@property
|
28
|
+
@abstractmethod
|
29
|
+
def episode_number(self) -> int:
|
30
|
+
pass
|
31
|
+
|
32
|
+
@property
|
33
|
+
def season_number(self) -> int:
|
34
|
+
return self._parent.season_number
|
35
|
+
|
36
|
+
@property
|
37
|
+
@abstractmethod
|
38
|
+
def summary(self) -> str:
|
39
|
+
pass
|
40
|
+
|
41
|
+
@property
|
42
|
+
@abstractmethod
|
43
|
+
def title(self) -> str:
|
44
|
+
pass
|
45
|
+
|
46
|
+
@property
|
47
|
+
@abstractmethod
|
48
|
+
def release_date(self) -> datetime:
|
49
|
+
pass
|
@@ -0,0 +1,55 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
from datetime import datetime
|
3
|
+
from typing import Any
|
4
|
+
|
5
|
+
class AutoItem(ABC):
|
6
|
+
def __init__(self, imdb_id: str, source: str) -> None:
|
7
|
+
self._imdb_id = imdb_id
|
8
|
+
self._source = source
|
9
|
+
|
10
|
+
@property
|
11
|
+
@abstractmethod
|
12
|
+
def id(self) -> Any:
|
13
|
+
pass
|
14
|
+
|
15
|
+
@property
|
16
|
+
@abstractmethod
|
17
|
+
def title(self) -> str:
|
18
|
+
pass
|
19
|
+
|
20
|
+
@property
|
21
|
+
@abstractmethod
|
22
|
+
def release_date(self) -> datetime:
|
23
|
+
pass
|
24
|
+
|
25
|
+
@property
|
26
|
+
@abstractmethod
|
27
|
+
def runtime(self) -> int:
|
28
|
+
pass
|
29
|
+
|
30
|
+
@property
|
31
|
+
def year(self) -> int:
|
32
|
+
return self.release_date.year
|
33
|
+
|
34
|
+
@property
|
35
|
+
@abstractmethod
|
36
|
+
def titles(self) -> list:
|
37
|
+
pass
|
38
|
+
|
39
|
+
@property
|
40
|
+
@abstractmethod
|
41
|
+
def summary(self) -> str:
|
42
|
+
pass
|
43
|
+
|
44
|
+
@property
|
45
|
+
@abstractmethod
|
46
|
+
def language(self) -> str:
|
47
|
+
pass
|
48
|
+
|
49
|
+
@property
|
50
|
+
def imdb_id(self) -> str:
|
51
|
+
return self._imdb_id
|
52
|
+
|
53
|
+
@property
|
54
|
+
def source(self) -> str:
|
55
|
+
return self._source
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
from datetime import datetime
|
3
|
+
from plexflow.core.metadata.providers.imdb.imdb import search_movie_by_imdb
|
4
|
+
from plexflow.core.metadata.auto.auto_providers.auto.item import AutoItem
|
5
|
+
|
6
|
+
class AutoMovie(AutoItem):
|
7
|
+
def __init__(self, imdb_id: str, source: str) -> None:
|
8
|
+
super().__init__(imdb_id, source)
|
9
|
+
self._imdb_info = search_movie_by_imdb(self.imdb_id)
|
10
|
+
|
11
|
+
@property
|
12
|
+
def rank(self) -> int:
|
13
|
+
return self._imdb_info.rank
|
@@ -0,0 +1,43 @@
|
|
1
|
+
from typing import TYPE_CHECKING
|
2
|
+
from abc import ABC, abstractmethod
|
3
|
+
from datetime import datetime
|
4
|
+
|
5
|
+
if TYPE_CHECKING:
|
6
|
+
from plexflow.core.metadata.auto.auto_providers.auto.episode import AutoEpisode
|
7
|
+
|
8
|
+
from plexflow.core.metadata.auto.auto_providers.auto.show import AutoShow
|
9
|
+
|
10
|
+
class AutoSeason(ABC):
|
11
|
+
def __init__(self, parent: AutoShow) -> None:
|
12
|
+
self._parent = parent
|
13
|
+
|
14
|
+
@property
|
15
|
+
def show(self) -> AutoShow:
|
16
|
+
return self._parent
|
17
|
+
|
18
|
+
@property
|
19
|
+
def source(self) -> str:
|
20
|
+
return self._parent.source
|
21
|
+
|
22
|
+
@property
|
23
|
+
def total_episodes(self) -> int:
|
24
|
+
return len(self.episodes)
|
25
|
+
|
26
|
+
@property
|
27
|
+
@abstractmethod
|
28
|
+
def season_number(self) -> int:
|
29
|
+
pass
|
30
|
+
|
31
|
+
@property
|
32
|
+
@abstractmethod
|
33
|
+
def episodes(self) -> list['AutoEpisode']:
|
34
|
+
pass
|
35
|
+
|
36
|
+
@property
|
37
|
+
def year(self):
|
38
|
+
return self.release_date.year
|
39
|
+
|
40
|
+
@property
|
41
|
+
@abstractmethod
|
42
|
+
def release_date(self) -> datetime:
|
43
|
+
pass
|
@@ -0,0 +1,26 @@
|
|
1
|
+
from typing import TYPE_CHECKING
|
2
|
+
from abc import abstractmethod
|
3
|
+
|
4
|
+
if TYPE_CHECKING:
|
5
|
+
from plexflow.core.metadata.auto.auto_providers.auto.season import AutoSeason
|
6
|
+
|
7
|
+
from plexflow.core.metadata.providers.imdb.imdb import search_show_by_imdb
|
8
|
+
from plexflow.core.metadata.auto.auto_providers.auto.item import AutoItem
|
9
|
+
|
10
|
+
class AutoShow(AutoItem):
|
11
|
+
def __init__(self, imdb_id: str, source: str) -> None:
|
12
|
+
super().__init__(imdb_id, source)
|
13
|
+
self._imdb_info = search_show_by_imdb(self.imdb_id)
|
14
|
+
|
15
|
+
@property
|
16
|
+
def rank(self) -> int:
|
17
|
+
return self._imdb_info.rank
|
18
|
+
|
19
|
+
@property
|
20
|
+
def total_seasons(self) -> int:
|
21
|
+
return len(self.seasons)
|
22
|
+
|
23
|
+
@property
|
24
|
+
@abstractmethod
|
25
|
+
def seasons(self) -> list['AutoSeason']:
|
26
|
+
pass
|
File without changes
|
@@ -0,0 +1,36 @@
|
|
1
|
+
from plexflow.core.metadata.auto.auto_providers.auto.movie import AutoMovie
|
2
|
+
from plexflow.core.metadata.providers.imdb.imdb import search_movie_by_imdb
|
3
|
+
from datetime import datetime
|
4
|
+
|
5
|
+
class AutoImdbMovie(AutoMovie):
|
6
|
+
def __init__(self, imdb_id: str) -> None:
|
7
|
+
super().__init__(imdb_id, 'imdb')
|
8
|
+
self._movie = search_movie_by_imdb(self.imdb_id)
|
9
|
+
|
10
|
+
@property
|
11
|
+
def id(self) -> str:
|
12
|
+
return self._movie.imdb_id
|
13
|
+
|
14
|
+
@property
|
15
|
+
def title(self) -> str:
|
16
|
+
return self._movie.title
|
17
|
+
|
18
|
+
@property
|
19
|
+
def release_date(self) -> datetime:
|
20
|
+
return self._movie.release_date
|
21
|
+
|
22
|
+
@property
|
23
|
+
def runtime(self) -> int:
|
24
|
+
return round(self._movie.runtime / 60)
|
25
|
+
|
26
|
+
@property
|
27
|
+
def titles(self) -> list:
|
28
|
+
return []
|
29
|
+
|
30
|
+
@property
|
31
|
+
def summary(self) -> str:
|
32
|
+
return None
|
33
|
+
|
34
|
+
@property
|
35
|
+
def language(self) -> str:
|
36
|
+
return None
|
@@ -0,0 +1,45 @@
|
|
1
|
+
from plexflow.core.metadata.auto.auto_providers.auto.show import AutoShow
|
2
|
+
from plexflow.core.metadata.providers.imdb.imdb import search_show_by_imdb
|
3
|
+
from datetime import datetime
|
4
|
+
from plexflow.core.metadata.auto.auto_providers.tmdb.season import AutoTmdbSeason, AutoSeason
|
5
|
+
|
6
|
+
class AutoImdbShow(AutoShow):
|
7
|
+
def __init__(self, imdb_id: str) -> None:
|
8
|
+
super().__init__(imdb_id, 'imdb')
|
9
|
+
self._show = search_show_by_imdb(self.imdb_id)
|
10
|
+
|
11
|
+
@property
|
12
|
+
def id(self) -> int:
|
13
|
+
return self._show.imdb_id
|
14
|
+
|
15
|
+
@property
|
16
|
+
def title(self) -> str:
|
17
|
+
return self._show.title
|
18
|
+
|
19
|
+
@property
|
20
|
+
def release_date(self) -> datetime:
|
21
|
+
return self._show.release_date
|
22
|
+
|
23
|
+
@property
|
24
|
+
def runtime(self) -> int:
|
25
|
+
return round(self._show.runtime / 60)
|
26
|
+
|
27
|
+
@property
|
28
|
+
def titles(self) -> list:
|
29
|
+
return []
|
30
|
+
|
31
|
+
@property
|
32
|
+
def summary(self) -> str:
|
33
|
+
return None
|
34
|
+
|
35
|
+
@property
|
36
|
+
def language(self) -> str:
|
37
|
+
return None
|
38
|
+
|
39
|
+
@property
|
40
|
+
def seasons(self) -> list[AutoSeason]:
|
41
|
+
return []
|
42
|
+
|
43
|
+
@property
|
44
|
+
def total_seasons(self) -> int:
|
45
|
+
return self._show.seasons
|
File without changes
|
@@ -0,0 +1,40 @@
|
|
1
|
+
from plexflow.core.metadata.auto.auto_providers.auto.movie import AutoMovie
|
2
|
+
from plexflow.core.metadata.providers.moviemeter.moviemeter import search_movie_by_imdb
|
3
|
+
from datetime import datetime
|
4
|
+
|
5
|
+
class AutoMovieMeterMovie(AutoMovie):
|
6
|
+
def __init__(self, imdb_id: str) -> None:
|
7
|
+
super().__init__(imdb_id, 'moviemeter')
|
8
|
+
self._movie = search_movie_by_imdb(self.imdb_id)
|
9
|
+
|
10
|
+
@property
|
11
|
+
def id(self) -> int:
|
12
|
+
return self._movie.id
|
13
|
+
|
14
|
+
@property
|
15
|
+
def title(self) -> str:
|
16
|
+
return self._movie.display_title
|
17
|
+
|
18
|
+
@property
|
19
|
+
def release_date(self) -> datetime:
|
20
|
+
return None
|
21
|
+
|
22
|
+
@property
|
23
|
+
def runtime(self) -> int:
|
24
|
+
return self._movie.duration
|
25
|
+
|
26
|
+
@property
|
27
|
+
def titles(self) -> list:
|
28
|
+
return list(filter(lambda x: x, [self._movie.title, self._movie.alternative_title]))
|
29
|
+
|
30
|
+
@property
|
31
|
+
def summary(self) -> str:
|
32
|
+
return self._movie.plot
|
33
|
+
|
34
|
+
@property
|
35
|
+
def year(self) -> int:
|
36
|
+
return self._movie.year
|
37
|
+
|
38
|
+
@property
|
39
|
+
def language(self) -> str:
|
40
|
+
return None
|
File without changes
|
@@ -0,0 +1,39 @@
|
|
1
|
+
from plexflow.core.metadata.auto.auto_providers.auto.movie import AutoMovie
|
2
|
+
from plexflow.core.metadata.providers.plex.plex import search_movie_by_rating_key
|
3
|
+
from datetime import datetime
|
4
|
+
from plexflow.utils.imdb.imdb_codes import extract_imdb_code
|
5
|
+
|
6
|
+
class AutoPlexMovie(AutoMovie):
|
7
|
+
def __init__(self, rating_key: str) -> None:
|
8
|
+
self._movie = search_movie_by_rating_key(rating_key)
|
9
|
+
imdb_id = next((next(extract_imdb_code(g.id), None) for g in self._movie.Guid), None)
|
10
|
+
|
11
|
+
super().__init__(imdb_id, 'plex')
|
12
|
+
|
13
|
+
@property
|
14
|
+
def id(self) -> str:
|
15
|
+
return self._movie.ratingKey
|
16
|
+
|
17
|
+
@property
|
18
|
+
def title(self) -> str:
|
19
|
+
return self._movie.title
|
20
|
+
|
21
|
+
@property
|
22
|
+
def release_date(self) -> datetime:
|
23
|
+
return datetime.strptime(self._movie.originallyAvailableAt, '%Y-%m-%d')
|
24
|
+
|
25
|
+
@property
|
26
|
+
def runtime(self) -> int:
|
27
|
+
return self._movie.duration // 60000 if isinstance(self._movie.duration, int) else None
|
28
|
+
|
29
|
+
@property
|
30
|
+
def titles(self) -> list:
|
31
|
+
return []
|
32
|
+
|
33
|
+
@property
|
34
|
+
def summary(self) -> str:
|
35
|
+
return self._movie.summary
|
36
|
+
|
37
|
+
@property
|
38
|
+
def language(self) -> str:
|
39
|
+
return None
|
File without changes
|
@@ -0,0 +1,30 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
from plexflow.core.metadata.auto.auto_providers.auto.episode import AutoEpisode
|
3
|
+
from plexflow.core.metadata.auto.auto_providers.auto.season import AutoSeason
|
4
|
+
from plexflow.core.metadata.providers.tmdb.tmdb import get_season_by_show_id
|
5
|
+
from plexflow.core.metadata.providers.tmdb.datatypes import SeasonEpisode
|
6
|
+
|
7
|
+
class AutoTmdbEpisode(AutoEpisode):
|
8
|
+
def __init__(self, parent: AutoSeason, episode: SeasonEpisode) -> None:
|
9
|
+
super().__init__(parent=parent)
|
10
|
+
self._episode = episode
|
11
|
+
|
12
|
+
@property
|
13
|
+
def release_date(self) -> datetime:
|
14
|
+
return datetime.strptime(self._episode.air_date, '%Y-%m-%d') if self._episode.air_date else None
|
15
|
+
|
16
|
+
@property
|
17
|
+
def episode_number(self) -> int:
|
18
|
+
return self._episode.episode_number
|
19
|
+
|
20
|
+
@property
|
21
|
+
def title(self) -> str:
|
22
|
+
return self._episode.name
|
23
|
+
|
24
|
+
@property
|
25
|
+
def runtime(self) -> int:
|
26
|
+
return self._episode.runtime
|
27
|
+
|
28
|
+
@property
|
29
|
+
def summary(self) -> str:
|
30
|
+
return self._episode.overview
|
@@ -0,0 +1,36 @@
|
|
1
|
+
from plexflow.core.metadata.auto.auto_providers.auto.movie import AutoMovie
|
2
|
+
from plexflow.core.metadata.providers.tmdb.tmdb import search_movie_by_imdb, search_show_by_imdb, get_all_seasons_by_imdb_id
|
3
|
+
from datetime import datetime
|
4
|
+
|
5
|
+
class AutoTmdbMovie(AutoMovie):
|
6
|
+
def __init__(self, imdb_id: str) -> None:
|
7
|
+
super().__init__(imdb_id, 'tmdb')
|
8
|
+
self._movie = search_movie_by_imdb(self.imdb_id)
|
9
|
+
|
10
|
+
@property
|
11
|
+
def id(self) -> int:
|
12
|
+
return self._movie.id
|
13
|
+
|
14
|
+
@property
|
15
|
+
def title(self) -> str:
|
16
|
+
return self._movie.title
|
17
|
+
|
18
|
+
@property
|
19
|
+
def release_date(self) -> datetime:
|
20
|
+
return datetime.strptime(self._movie.release_date, '%Y-%m-%d')
|
21
|
+
|
22
|
+
@property
|
23
|
+
def runtime(self) -> int:
|
24
|
+
return self._movie.runtime
|
25
|
+
|
26
|
+
@property
|
27
|
+
def titles(self) -> list:
|
28
|
+
return [x.title for x in self._movie.alternative_titles.titles]
|
29
|
+
|
30
|
+
@property
|
31
|
+
def summary(self) -> str:
|
32
|
+
return self._movie.overview
|
33
|
+
|
34
|
+
@property
|
35
|
+
def language(self) -> str:
|
36
|
+
return self._movie.original_language
|
@@ -0,0 +1,23 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
from plexflow.core.metadata.auto.auto_providers.auto.season import AutoSeason
|
3
|
+
from plexflow.core.metadata.auto.auto_providers.auto.show import AutoShow
|
4
|
+
from plexflow.core.metadata.auto.auto_providers.auto.episode import AutoEpisode
|
5
|
+
from plexflow.core.metadata.auto.auto_providers.tmdb.episode import AutoTmdbEpisode
|
6
|
+
from plexflow.core.metadata.providers.tmdb.tmdb import get_season_by_show_id
|
7
|
+
|
8
|
+
class AutoTmdbSeason(AutoSeason):
|
9
|
+
def __init__(self, parent: AutoShow, season_number: int) -> None:
|
10
|
+
super().__init__(parent)
|
11
|
+
self._season = get_season_by_show_id(self._parent.id, season=season_number)
|
12
|
+
|
13
|
+
@property
|
14
|
+
def episodes(self) -> list[AutoEpisode]:
|
15
|
+
return [AutoTmdbEpisode(self, x) for x in self._season.episodes]
|
16
|
+
|
17
|
+
@property
|
18
|
+
def release_date(self) -> datetime:
|
19
|
+
return datetime.strptime(self._season.air_date, '%Y-%m-%d')
|
20
|
+
|
21
|
+
@property
|
22
|
+
def season_number(self) -> int:
|
23
|
+
return self._season.season_number
|
@@ -0,0 +1,41 @@
|
|
1
|
+
from plexflow.core.metadata.auto.auto_providers.auto.show import AutoShow
|
2
|
+
from plexflow.core.metadata.providers.tmdb.tmdb import search_show_by_imdb, get_all_seasons_by_imdb_id
|
3
|
+
from datetime import datetime
|
4
|
+
from plexflow.core.metadata.auto.auto_providers.tmdb.season import AutoTmdbSeason, AutoSeason
|
5
|
+
|
6
|
+
class AutoTmdbShow(AutoShow):
|
7
|
+
def __init__(self, imdb_id: str) -> None:
|
8
|
+
super().__init__(imdb_id, 'tmdb')
|
9
|
+
self._show = search_show_by_imdb(self.imdb_id)
|
10
|
+
|
11
|
+
@property
|
12
|
+
def id(self) -> int:
|
13
|
+
return self._show.id
|
14
|
+
|
15
|
+
@property
|
16
|
+
def title(self) -> str:
|
17
|
+
return self._show.original_name
|
18
|
+
|
19
|
+
@property
|
20
|
+
def release_date(self) -> datetime:
|
21
|
+
return datetime.strptime(self._show.first_air_date, '%Y-%m-%d')
|
22
|
+
|
23
|
+
@property
|
24
|
+
def runtime(self) -> int:
|
25
|
+
return self._show.last_episode_to_air.runtime if self._show.last_episode_to_air else next(iter(self._show.episode_run_time), None)
|
26
|
+
|
27
|
+
@property
|
28
|
+
def titles(self) -> list:
|
29
|
+
return [x.title for x in self._show.alternative_titles.results]
|
30
|
+
|
31
|
+
@property
|
32
|
+
def summary(self) -> str:
|
33
|
+
return self._show.overview
|
34
|
+
|
35
|
+
@property
|
36
|
+
def language(self) -> str:
|
37
|
+
return self._show.original_language
|
38
|
+
|
39
|
+
@property
|
40
|
+
def seasons(self) -> list[AutoSeason]:
|
41
|
+
return [AutoTmdbSeason(self, x.season_number) for x in self._show.seasons]
|
@@ -0,0 +1,92 @@
|
|
1
|
+
from plexflow.core.metadata.providers.tmdb.tmdb import search_movie_by_imdb, search_show_by_imdb, get_all_seasons_by_imdb_id
|
2
|
+
from datetime import datetime
|
3
|
+
|
4
|
+
class AutoTmdbMovie:
|
5
|
+
"""
|
6
|
+
Represents a movie retrieved from the TMDb (The Movie Database) API.
|
7
|
+
|
8
|
+
Attributes:
|
9
|
+
imdb_id (str): The IMDb ID of the movie.
|
10
|
+
|
11
|
+
Properties:
|
12
|
+
title (str): The title of the movie.
|
13
|
+
release_date (datetime): The release date of the movie.
|
14
|
+
runtime (int): The runtime of the movie in minutes.
|
15
|
+
year (int): The year of the movie's release.
|
16
|
+
titles (list): A list of alternative titles for the movie.
|
17
|
+
summary (str): The summary or overview of the movie.
|
18
|
+
language (str): The original language of the movie.
|
19
|
+
"""
|
20
|
+
|
21
|
+
def __init__(self, imdb_id: str) -> None:
|
22
|
+
self.imdb_id = imdb_id
|
23
|
+
self._movie = search_movie_by_imdb(self.imdb_id)
|
24
|
+
|
25
|
+
@property
|
26
|
+
def title(self) -> str:
|
27
|
+
return self._movie.title
|
28
|
+
|
29
|
+
@property
|
30
|
+
def release_date(self) -> datetime:
|
31
|
+
return datetime.strptime(self._movie.release_date, '%Y-%m-%d')
|
32
|
+
|
33
|
+
@property
|
34
|
+
def runtime(self) -> int:
|
35
|
+
return self._movie.runtime
|
36
|
+
|
37
|
+
@property
|
38
|
+
def year(self) -> int:
|
39
|
+
return self.release_date.year
|
40
|
+
|
41
|
+
@property
|
42
|
+
def titles(self) -> list:
|
43
|
+
return [x.title for x in self._movie.alternative_titles]
|
44
|
+
|
45
|
+
@property
|
46
|
+
def summary(self) -> str:
|
47
|
+
return self._movie.overview
|
48
|
+
|
49
|
+
@property
|
50
|
+
def language(self) -> str:
|
51
|
+
return self._movie.original_language
|
52
|
+
|
53
|
+
class AutoTmdbShow:
|
54
|
+
def __init__(self, imdb_id: str) -> None:
|
55
|
+
self.imdb_id = imdb_id
|
56
|
+
self._show = search_show_by_imdb(self.imdb_id)
|
57
|
+
|
58
|
+
@property
|
59
|
+
def title(self) -> str:
|
60
|
+
return self._show.original_name
|
61
|
+
|
62
|
+
@property
|
63
|
+
def release_date(self) -> datetime:
|
64
|
+
return datetime.strptime(self._show.first_air_date, '%Y-%m-%d')
|
65
|
+
|
66
|
+
@property
|
67
|
+
def runtime(self) -> int:
|
68
|
+
return self._show.episode_run_time
|
69
|
+
|
70
|
+
@property
|
71
|
+
def year(self) -> int:
|
72
|
+
return self.release_date.year
|
73
|
+
|
74
|
+
@property
|
75
|
+
def titles(self) -> list:
|
76
|
+
return [x.title for x in self._show.alternative_titles.results]
|
77
|
+
|
78
|
+
@property
|
79
|
+
def summary(self) -> str:
|
80
|
+
return self._show.overview
|
81
|
+
|
82
|
+
@property
|
83
|
+
def language(self) -> str:
|
84
|
+
return self._show.original_language
|
85
|
+
|
86
|
+
@property
|
87
|
+
def total_seasons(self) -> int:
|
88
|
+
return self._show.number_of_seasons
|
89
|
+
|
90
|
+
@property
|
91
|
+
def seasons(self) -> list:
|
92
|
+
return get_all_seasons_by_imdb_id(self.imdb_id)
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
from datetime import datetime
|
2
|
+
from plexflow.core.metadata.auto.auto_providers.auto.episode import AutoEpisode
|
3
|
+
from plexflow.core.metadata.auto.auto_providers.auto.season import AutoSeason
|
4
|
+
|
5
|
+
class AutoTvdbEpisode(AutoEpisode):
|
6
|
+
def __init__(self, parent: AutoSeason, episode: dict) -> None:
|
7
|
+
super().__init__(parent=parent)
|
8
|
+
self._episode = episode
|
9
|
+
|
10
|
+
@property
|
11
|
+
def release_date(self) -> datetime:
|
12
|
+
return datetime.strptime(self._episode.get('aired'), '%Y-%m-%d') if self._episode.get('aired') else None
|
13
|
+
|
14
|
+
@property
|
15
|
+
def episode_number(self) -> int:
|
16
|
+
return self._episode.get('number')
|
17
|
+
|
18
|
+
@property
|
19
|
+
def title(self) -> str:
|
20
|
+
return self._episode.get('name')
|
21
|
+
|
22
|
+
@property
|
23
|
+
def runtime(self) -> int:
|
24
|
+
return self._episode.get('runtime')
|
25
|
+
|
26
|
+
@property
|
27
|
+
def summary(self) -> str:
|
28
|
+
return self._episode.get('overview')
|