plexflow 0.0.129__py3-none-any.whl → 0.0.131__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.
@@ -158,3 +158,16 @@ class Show(PartialContext):
158
158
  @property
159
159
  def selected_episode(self) -> PlexEpisodeMetadata:
160
160
  return self.get('episodes/selected')
161
+
162
+ def update_episode_imdb_codes(self, season: int, codes: dict):
163
+ self.set(f"episodes/season/{season}/imdb/codes", codes)
164
+
165
+ def episode_imdb_codes(self, season: int) -> dict:
166
+ return self.get(f"episodes/season/{season}/imdb/codes")
167
+
168
+ @property
169
+ def selected_episode_imdb_code(self) -> str:
170
+ episode = self.selected_episode
171
+ season = episode.parentIndex
172
+ codes = self.episode_imdb_codes(season=season)
173
+ return codes.get(episode.index)
@@ -0,0 +1,60 @@
1
+ import requests
2
+ from bs4 import BeautifulSoup
3
+ from typing import Dict, Optional
4
+ from plexflow.utils.imdb.imdb_codes import extract_imdb_code
5
+
6
+ def get_imdb_episode_codes(imdb_title_id: str, season_number: int) -> Dict[int, Optional[str]]:
7
+ """
8
+ Fetches IMDb episode codes for a given title ID and season number.
9
+
10
+ Args:
11
+ imdb_title_id (str): The IMDb title ID (e.g., 'tt3581920').
12
+ season_number (int): The season number to retrieve episodes for.
13
+
14
+ Returns:
15
+ Dict[int, Optional[str]]: A dictionary where keys are episode numbers
16
+ and values are their corresponding IMDb codes.
17
+ Returns an empty dictionary if no episodes are found or
18
+ an error occurs.
19
+ """
20
+ if not imdb_title_id.startswith('tt'):
21
+ print("Warning: IMDb title ID should start with 'tt'.")
22
+ return {}
23
+
24
+ url = f"https://www.imdb.com/title/{imdb_title_id}/episodes/?season={season_number}&ref_=ttep"
25
+ headers = {
26
+ 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.4 Safari/605.1.15',
27
+ }
28
+
29
+ try:
30
+ r = requests.get(url=url, headers=headers, timeout=10) # Added timeout for robustness
31
+ r.raise_for_status() # Raise an exception for HTTP errors (4xx or 5xx)
32
+ except requests.exceptions.RequestException as e:
33
+ print(f"Error fetching URL {url}: {e}")
34
+ return {}
35
+
36
+ soup = BeautifulSoup(r.text, 'html.parser')
37
+
38
+ # Select all <a> tags within elements that have class 'episode-item-wrapper'
39
+ # and whose href attribute starts with '/title/'.
40
+ links = soup.select('.episode-item-wrapper a[href^="/title/"]')
41
+
42
+ episodes: Dict[int, Optional[str]] = {}
43
+ seen_urls = set()
44
+ current_episode_number = 1
45
+
46
+ for link in links:
47
+ href = link['href']
48
+ # IMDb often lists the same episode link multiple times (e.g., image and title link).
49
+ # We only want to process each unique episode URL once.
50
+ if href not in seen_urls:
51
+ seen_urls.add(href)
52
+ # The extract_imdb_code function should return the IMDb code directly,
53
+ # not an iterator, based on common usage. If it returns an iterator,
54
+ # `next(..., None)` is correct.
55
+ episode_imdb_code = next(extract_imdb_code(href), None)
56
+ if episode_imdb_code: # Only add if a valid IMDb code was extracted
57
+ episodes[current_episode_number] = episode_imdb_code
58
+ current_episode_number += 1
59
+
60
+ return episodes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: plexflow
3
- Version: 0.0.129
3
+ Version: 0.0.131
4
4
  Summary: A short description of the package.
5
5
  License: MIT
6
6
  Keywords: keyword1,keyword2,keyword3
@@ -32,7 +32,7 @@ plexflow/core/context/partials/ids.py,sha256=QoQ6FbX1OIWrE-iuz-G6kSzBlTt1_I1jyfl
32
32
  plexflow/core/context/partials/movie.py,sha256=VXQ2SspFgGSRgDefg4VlHrH2fns3KRuKlU72ps6527o,3861
33
33
  plexflow/core/context/partials/movie_assets.py,sha256=qjZTs-lpPfZkQQSKm6CB4aeECX5_YzOom51PxZzmnts,1913
34
34
  plexflow/core/context/partials/reports.py,sha256=0W58RwK3VSsVHbF0rhvMNNlZZr01eutwermyvdeEZIs,810
35
- plexflow/core/context/partials/show.py,sha256=lfjh1mVg49SEFzMSLfseDs4MgLKLx_8_ltHtlWoHbUc,5085
35
+ plexflow/core/context/partials/show.py,sha256=SpNGCRV8TYyqWc3_gZekFndvENJSy9sabDtilW_grKg,5580
36
36
  plexflow/core/context/partials/subtitles.py,sha256=0NhKGkP-sArQswuSyA7puRSjjoobF-3Ah7Pd39QkgTU,535
37
37
  plexflow/core/context/partials/tgx_batch.py,sha256=TduB09oBOQ8CtmPYsHIeNe7AI-ypKw21zQAX-7qktEs,859
38
38
  plexflow/core/context/partials/tgx_context.py,sha256=_FuhOvKsFqi_uynHxgC9_QIR2CfYmz-uJCRFtGFJmXI,1641
@@ -350,7 +350,7 @@ plexflow/core/subtitles/providers/oss/__pycache__/oss.cpython-312.pyc,sha256=XhZ
350
350
  plexflow/core/subtitles/providers/oss/__pycache__/oss_subtitle.cpython-311.pyc,sha256=IfUEII4Khd7b4vs1Ag73irbmoulk1f9uKOX9xI0vtlo,2396
351
351
  plexflow/core/subtitles/providers/oss/__pycache__/oss_subtitle.cpython-312.pyc,sha256=YJjcasSbQna30MtyKApyFrU4VFwNOxh0awY0565RPkE,2576
352
352
  plexflow/core/subtitles/providers/oss/__pycache__/search.cpython-311.pyc,sha256=Hb6ZX9B0wjeOvOMNaw-eZnPBITsINQ3Cs8cYebq-dKs,3038
353
- plexflow/core/subtitles/providers/oss/__pycache__/search.cpython-312.pyc,sha256=QCXsAPqp5G4oo2S-GvRaDmOQF1eVnvlyj4YBgLRSJCI,2662
353
+ plexflow/core/subtitles/providers/oss/__pycache__/search.cpython-312.pyc,sha256=nzKPBAPeNoX7ApIMz3Z-aGAfmnEEg2Bz_7KRUm-nAIw,2662
354
354
  plexflow/core/subtitles/providers/oss/__pycache__/unlimited_oss.cpython-311.pyc,sha256=OUvBlMRcl1mDpT9UnhZl9g9YZgfJj5Y8Gff2oIto1V8,12587
355
355
  plexflow/core/subtitles/providers/oss/__pycache__/unlimited_oss.cpython-312.pyc,sha256=bU2sKm2qYOI-8AO25Xswuwv0AAPRtX04DTdYq3r-K-I,11756
356
356
  plexflow/core/subtitles/providers/oss/datatypes.py,sha256=7YvjS8a3riEJ4yqLKzTRv5g6vftcrcoYKGcBoq0MCLo,3620
@@ -641,6 +641,7 @@ plexflow/utils/imdb/__pycache__/__init__.cpython-311.pyc,sha256=Om33PdqDky-6oW50
641
641
  plexflow/utils/imdb/__pycache__/__init__.cpython-312.pyc,sha256=HB4wxnIqRG2mIgj9A1l6jLVTmlCs7LF2nsnlDEdIh8Q,155
642
642
  plexflow/utils/imdb/__pycache__/imdb_codes.cpython-311.pyc,sha256=pGACYM3C88N41gMgFGz8L0evmhavIoineUeK8XPv3oU,4396
643
643
  plexflow/utils/imdb/__pycache__/imdb_codes.cpython-312.pyc,sha256=PqmomwWgbBJ4HdQHSwg2FIesLrR72Tbs58uoZWrjqQc,4092
644
+ plexflow/utils/imdb/episodes.py,sha256=q5Mcsdr2i-zRX8Ce23gLqTi0G8-XRX9ZHpTFb5Iu2Ps,2602
644
645
  plexflow/utils/imdb/imdb_codes.py,sha256=aIECE9IEFSYbY3A-erONQiFUqy36JrH2hhcM3qWObk0,3028
645
646
  plexflow/utils/llm/mistral.py,sha256=OX_ogd7i3xzh7959O65oGzzfhuGRTFWsUwwmkShH7fs,4521
646
647
  plexflow/utils/pubsub/__pycache__/consume.cpython-312.pyc,sha256=QlvfpCEFCf53lhve-f1QdeNLhiVXRVkqtowp4n8is9w,3780
@@ -713,7 +714,7 @@ plexflow/utils/video/__pycache__/audio.cpython-312.pyc,sha256=kmzGDCHSC1hWyHwRut
713
714
  plexflow/utils/video/__pycache__/subtitle.cpython-312.pyc,sha256=PCjpCLydGXaRsQy6cikhgsEs8WlComfOoYPiLFqfVMA,2515
714
715
  plexflow/utils/video/audio.py,sha256=Pd8OuQHX2QN-lc5iYkB0Vo1OEHmTcvDYH-uKud1f1q4,5262
715
716
  plexflow/utils/video/subtitle.py,sha256=qPvvBjlPj0fynJJvGJgGeKt9ey26R-cF6EoLaYt9iXU,1333
716
- plexflow-0.0.129.dist-info/METADATA,sha256=OtWB_9gAVCtNivzs5zq1g8IAYt1374qQyCHOpOoKsEY,2971
717
- plexflow-0.0.129.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
718
- plexflow-0.0.129.dist-info/entry_points.txt,sha256=9RJC3ikOQORHNOn573EdwJOBUnFU_4EGHbtNUM5pjjY,1557
719
- plexflow-0.0.129.dist-info/RECORD,,
717
+ plexflow-0.0.131.dist-info/METADATA,sha256=TtF9s3LrMhFwP08ejAELCphKk0mA8LTeXzBOM1ROBsE,2971
718
+ plexflow-0.0.131.dist-info/WHEEL,sha256=IYZQI976HJqqOpQU6PHkJ8fb3tMNBFjg-Cn-pwAbaFM,88
719
+ plexflow-0.0.131.dist-info/entry_points.txt,sha256=9RJC3ikOQORHNOn573EdwJOBUnFU_4EGHbtNUM5pjjY,1557
720
+ plexflow-0.0.131.dist-info/RECORD,,