StreamingCommunity 3.4.0__py3-none-any.whl → 3.4.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of StreamingCommunity might be problematic. Click here for more details.

Files changed (34) hide show
  1. StreamingCommunity/Api/Site/altadefinizione/film.py +0 -1
  2. StreamingCommunity/Api/Site/altadefinizione/series.py +3 -12
  3. StreamingCommunity/Api/Site/altadefinizione/site.py +0 -2
  4. StreamingCommunity/Api/Site/animeunity/site.py +3 -3
  5. StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +3 -3
  6. StreamingCommunity/Api/Site/crunchyroll/series.py +3 -14
  7. StreamingCommunity/Api/Site/crunchyroll/site.py +2 -4
  8. StreamingCommunity/Api/Site/guardaserie/series.py +3 -14
  9. StreamingCommunity/Api/Site/mediasetinfinity/series.py +3 -13
  10. StreamingCommunity/Api/Site/mediasetinfinity/site.py +14 -22
  11. StreamingCommunity/Api/Site/raiplay/film.py +0 -1
  12. StreamingCommunity/Api/Site/raiplay/series.py +5 -18
  13. StreamingCommunity/Api/Site/raiplay/site.py +42 -36
  14. StreamingCommunity/Api/Site/raiplay/util/ScrapeSerie.py +88 -45
  15. StreamingCommunity/Api/Site/streamingcommunity/series.py +5 -10
  16. StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +0 -1
  17. StreamingCommunity/Api/Site/streamingwatch/series.py +3 -13
  18. StreamingCommunity/Api/Template/Util/__init__.py +4 -2
  19. StreamingCommunity/Api/Template/Util/manage_ep.py +66 -0
  20. StreamingCommunity/Lib/Downloader/DASH/downloader.py +55 -16
  21. StreamingCommunity/Lib/Downloader/DASH/segments.py +45 -16
  22. StreamingCommunity/Lib/Downloader/HLS/downloader.py +71 -34
  23. StreamingCommunity/Lib/Downloader/HLS/segments.py +18 -1
  24. StreamingCommunity/Lib/Downloader/MP4/downloader.py +16 -4
  25. StreamingCommunity/Lib/M3U8/estimator.py +47 -1
  26. StreamingCommunity/Upload/update.py +19 -6
  27. StreamingCommunity/Upload/version.py +1 -1
  28. StreamingCommunity/Util/table.py +50 -8
  29. {streamingcommunity-3.4.0.dist-info → streamingcommunity-3.4.2.dist-info}/METADATA +1 -1
  30. {streamingcommunity-3.4.0.dist-info → streamingcommunity-3.4.2.dist-info}/RECORD +34 -34
  31. {streamingcommunity-3.4.0.dist-info → streamingcommunity-3.4.2.dist-info}/WHEEL +0 -0
  32. {streamingcommunity-3.4.0.dist-info → streamingcommunity-3.4.2.dist-info}/entry_points.txt +0 -0
  33. {streamingcommunity-3.4.0.dist-info → streamingcommunity-3.4.2.dist-info}/licenses/LICENSE +0 -0
  34. {streamingcommunity-3.4.0.dist-info → streamingcommunity-3.4.2.dist-info}/top_level.txt +0 -0
@@ -30,7 +30,6 @@ from StreamingCommunity.Api.Player.supervideo import VideoSource
30
30
 
31
31
  # Variable
32
32
  console = Console()
33
- max_timeout = config_manager.get_int("REQUESTS", "timeout")
34
33
  extension_output = config_manager.get("M3U8_CONVERSION", "extension")
35
34
 
36
35
 
@@ -21,7 +21,8 @@ from StreamingCommunity.Api.Template.Util import (
21
21
  map_episode_title,
22
22
  validate_selection,
23
23
  validate_episode_selection,
24
- display_episodes_list
24
+ display_episodes_list,
25
+ display_seasons_list
25
26
  )
26
27
  from StreamingCommunity.Api.Template.config_loader import site_constant
27
28
  from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
@@ -151,16 +152,11 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
151
152
  - episode_selection (str, optional): Pre-defined episode selection that bypasses manual input
152
153
  """
153
154
  scrape_serie = GetSerieInfo(select_season.url)
154
-
155
- # Get total number of seasons
156
155
  seasons_count = scrape_serie.getNumberSeason()
157
156
 
158
157
  if site_constant.TELEGRAM_BOT:
159
158
  bot = get_bot_instance()
160
159
 
161
- # Prompt user for season selection and download episodes
162
- console.print(f"\n[green]Seasons found: [red]{seasons_count}")
163
-
164
160
  # If season_selection is provided, use it instead of asking for input
165
161
  if season_selection is None:
166
162
  if site_constant.TELEGRAM_BOT:
@@ -180,10 +176,7 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
180
176
  )
181
177
 
182
178
  else:
183
- index_season_selected = msg.ask(
184
- "\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
185
- "[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end"
186
- )
179
+ index_season_selected = display_seasons_list(scrape_serie.seasons_manager)
187
180
  else:
188
181
  index_season_selected = season_selection
189
182
  console.print(f"\n[cyan]Using provided season selection: [yellow]{season_selection}")
@@ -195,10 +188,8 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
195
188
  # Loop through the selected seasons and download episodes
196
189
  for i_season in list_season_select:
197
190
  if len(list_season_select) > 1 or index_season_selected == "*":
198
- # Download all episodes if multiple seasons are selected or if '*' is used
199
191
  download_episode(i_season, scrape_serie, download_all=True)
200
192
  else:
201
- # Otherwise, let the user select specific episodes for the single season
202
193
  download_episode(i_season, scrape_serie, download_all=False, episode_selection=episode_selection)
203
194
 
204
195
  if site_constant.TELEGRAM_BOT:
@@ -7,7 +7,6 @@ from rich.console import Console
7
7
 
8
8
 
9
9
  # Internal utilities
10
- from StreamingCommunity.Util.config_json import config_manager
11
10
  from StreamingCommunity.Util.headers import get_userAgent
12
11
  from StreamingCommunity.Util.http_client import create_client
13
12
  from StreamingCommunity.Util.table import TVShowManager
@@ -23,7 +22,6 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
23
22
  console = Console()
24
23
  media_search_manager = MediaManager()
25
24
  table_show_manager = TVShowManager()
26
- max_timeout = config_manager.get_int("REQUESTS", "timeout")
27
25
 
28
26
 
29
27
  def title_search(query: str) -> int:
@@ -9,7 +9,7 @@ from rich.console import Console
9
9
 
10
10
  # Internal utilities
11
11
  from StreamingCommunity.Util.headers import get_userAgent
12
- from StreamingCommunity.Util.http_client import create_client, create_client_curl
12
+ from StreamingCommunity.Util.http_client import create_client_curl
13
13
  from StreamingCommunity.Util.table import TVShowManager
14
14
  from StreamingCommunity.TelegramHelp.telegram_bot import get_bot_instance
15
15
 
@@ -77,7 +77,7 @@ def title_search(query: str) -> int:
77
77
 
78
78
  # First call: /livesearch
79
79
  try:
80
- response1 = create_client(headers=headers).post(f'{site_constant.FULL_URL}/livesearch', cookies=cookies, json={'title': query})
80
+ response1 = create_client_curl(headers=headers).post(f'{site_constant.FULL_URL}/livesearch', cookies=cookies, data={'title': query})
81
81
  response1.raise_for_status()
82
82
  process_results(response1.json().get('records', []), seen_titles, media_search_manager, choices)
83
83
 
@@ -98,7 +98,7 @@ def title_search(query: str) -> int:
98
98
  'dubbed': False,
99
99
  'season': False
100
100
  }
101
- response2 = create_client(headers=headers).post(f'{site_constant.FULL_URL}/archivio/get-animes', cookies=cookies, json=json_data)
101
+ response2 = create_client_curl(headers=headers).post(f'{site_constant.FULL_URL}/archivio/get-animes', cookies=cookies, data=json_data)
102
102
  response2.raise_for_status()
103
103
  process_results(response2.json().get('records', []), seen_titles, media_search_manager, choices)
104
104
 
@@ -5,7 +5,7 @@ import logging
5
5
 
6
6
  # Internal utilities
7
7
  from StreamingCommunity.Util.headers import get_headers
8
- from StreamingCommunity.Util.http_client import create_client
8
+ from StreamingCommunity.Util.http_client import create_client_curl
9
9
  from StreamingCommunity.Api.Player.Helper.Vixcloud.util import EpisodeManager, Episode
10
10
 
11
11
 
@@ -52,7 +52,7 @@ class ScrapeSerieAnime:
52
52
  """
53
53
  try:
54
54
  # Get initial episode count
55
- response = create_client(headers=self.headers).get(f"{self.url}/info_api/{self.media_id}/")
55
+ response = create_client_curl(headers=self.headers).get(f"{self.url}/info_api/{self.media_id}/")
56
56
  response.raise_for_status()
57
57
  initial_count = response.json()["episodes_count"]
58
58
 
@@ -68,7 +68,7 @@ class ScrapeSerieAnime:
68
68
  "end_range": end_range
69
69
  }
70
70
 
71
- response = create_client(headers=self.headers).get(f"{self.url}/info_api/{self.media_id}/1", params=params)
71
+ response = create_client_curl(headers=self.headers).get(f"{self.url}/info_api/{self.media_id}/1", params=params)
72
72
  response.raise_for_status()
73
73
 
74
74
  chunk_episodes = response.json().get("episodes", [])
@@ -22,7 +22,8 @@ from StreamingCommunity.Api.Template.Util import (
22
22
  map_episode_title,
23
23
  validate_selection,
24
24
  validate_episode_selection,
25
- display_episodes_list
25
+ display_episodes_list,
26
+ display_seasons_list
26
27
  )
27
28
  from StreamingCommunity.Api.Template.config_loader import site_constant
28
29
  from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
@@ -160,20 +161,11 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
160
161
  - episode_selection (str, optional): Pre-defined episode selection that bypasses manual input
161
162
  """
162
163
  scrape_serie = GetSerieInfo(select_season.url.split("/")[-1])
163
-
164
- # Get total number of seasons
165
164
  seasons_count = scrape_serie.getNumberSeason()
166
165
 
167
- # Prompt user for season selection and download episodes
168
- console.print(f"\n[green]Seasons found: [red]{seasons_count}")
169
-
170
166
  # If season_selection is provided, use it instead of asking for input
171
167
  if season_selection is None:
172
- index_season_selected = msg.ask(
173
- "\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
174
- "[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end"
175
- )
176
-
168
+ index_season_selected = display_seasons_list(scrape_serie.seasons_manager)
177
169
  else:
178
170
  index_season_selected = season_selection
179
171
  console.print(f"\n[cyan]Using provided season selection: [yellow]{season_selection}")
@@ -185,9 +177,6 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
185
177
  # Loop through the selected seasons and download episodes
186
178
  for i_season in list_season_select:
187
179
  if len(list_season_select) > 1 or index_season_selected == "*":
188
- # Download all episodes if multiple seasons are selected or if '*' is used
189
180
  download_episode(i_season, scrape_serie, download_all=True)
190
-
191
181
  else:
192
- # Otherwise, let the user select specific episodes for the single season
193
182
  download_episode(i_season, scrape_serie, download_all=False, episode_selection=episode_selection)
@@ -1,7 +1,5 @@
1
1
  # 16.03.25
2
2
 
3
- import sys
4
-
5
3
 
6
4
  # External libraries
7
5
  from rich.console import Console
@@ -42,13 +40,13 @@ def title_search(query: str) -> int:
42
40
  config = config_manager.get_dict("SITE_LOGIN", "crunchyroll")
43
41
  if not config.get('device_id') or not config.get('etp_rt'):
44
42
  console.print("[bold red] device_id or etp_rt is missing or empty in config.json.[/bold red]")
45
- sys.exit(0)
43
+ raise Exception("device_id or etp_rt is missing or empty in config.json.")
46
44
 
47
45
  # Initialize Crunchyroll client
48
46
  client = CrunchyrollClient()
49
47
  if not client.start():
50
48
  console.print("[bold red] Failed to authenticate with Crunchyroll.[/bold red]")
51
- sys.exit(0)
49
+ raise Exception("Failed to authenticate with Crunchyroll.")
52
50
 
53
51
  # Build new Crunchyroll API search URL
54
52
  api_url = "https://www.crunchyroll.com/content/v2/discover/search"
@@ -20,7 +20,8 @@ from StreamingCommunity.Api.Template.Util import (
20
20
  dynamic_format_number,
21
21
  validate_selection,
22
22
  validate_episode_selection,
23
- display_episodes_list
23
+ display_episodes_list,
24
+ display_seasons_list
24
25
  )
25
26
  from StreamingCommunity.Api.Template.config_loader import site_constant
26
27
  from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
@@ -145,19 +146,11 @@ def download_series(dict_serie: MediaItem, season_selection: str = None, episode
145
146
 
146
147
  # Create class
147
148
  scrape_serie = GetSerieInfo(dict_serie)
148
-
149
- # Get season count
150
149
  seasons_count = scrape_serie.get_seasons_number()
151
-
152
- # Prompt user for season selection and download episodes
153
- console.print(f"\n[green]Seasons found: [red]{seasons_count}")
154
150
 
155
151
  # If season_selection is provided, use it instead of asking for input
156
152
  if season_selection is None:
157
- index_season_selected = msg.ask(
158
- "\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
159
- "[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end"
160
- )
153
+ index_season_selected = display_seasons_list(scrape_serie.seasons_manager)
161
154
  else:
162
155
  index_season_selected = season_selection
163
156
  console.print(f"\n[cyan]Using provided season selection: [yellow]{season_selection}")
@@ -169,10 +162,6 @@ def download_series(dict_serie: MediaItem, season_selection: str = None, episode
169
162
  # Loop through the selected seasons and download episodes
170
163
  for i_season in list_season_select:
171
164
  if len(list_season_select) > 1 or index_season_selected == "*":
172
-
173
- # Download all episodes if multiple seasons are selected or if '*' is used
174
165
  download_episode(scrape_serie, i_season, download_all=True)
175
166
  else:
176
-
177
- # Otherwise, let the user select specific episodes for the single season
178
167
  download_episode(scrape_serie, i_season, download_all=False, episode_selection=episode_selection)
@@ -22,7 +22,8 @@ from StreamingCommunity.Api.Template.Util import (
22
22
  map_episode_title,
23
23
  validate_selection,
24
24
  validate_episode_selection,
25
- display_episodes_list
25
+ display_episodes_list,
26
+ display_seasons_list
26
27
  )
27
28
  from StreamingCommunity.Api.Template.config_loader import site_constant
28
29
  from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
@@ -148,20 +149,11 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
148
149
  - episode_selection (str, optional): Pre-defined episode selection that bypasses manual input
149
150
  """
150
151
  scrape_serie = GetSerieInfo(select_season.url)
151
-
152
- # Get total number of seasons
153
152
  seasons_count = scrape_serie.getNumberSeason()
154
153
 
155
- # Prompt user for season selection and download episodes
156
- console.print(f"\n[green]Seasons found: [red]{seasons_count}")
157
-
158
154
  # If season_selection is provided, use it instead of asking for input
159
155
  if season_selection is None:
160
- index_season_selected = msg.ask(
161
- "\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
162
- "[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end"
163
- )
164
-
156
+ index_season_selected = display_seasons_list(scrape_serie.seasons_manager)
165
157
  else:
166
158
  index_season_selected = season_selection
167
159
  console.print(f"\n[cyan]Using provided season selection: [yellow]{season_selection}")
@@ -173,8 +165,6 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
173
165
  # Loop through the selected seasons and download episodes
174
166
  for i_season in list_season_select:
175
167
  if len(list_season_select) > 1 or index_season_selected == "*":
176
- # Download all episodes if multiple seasons are selected or if '*' is used
177
168
  download_episode(i_season, scrape_serie, download_all=True)
178
169
  else:
179
- # Otherwise, let the user select specific episodes for the single season
180
170
  download_episode(i_season, scrape_serie, download_all=False, episode_selection=episode_selection)
@@ -58,33 +58,25 @@ def title_search(query: str) -> int:
58
58
 
59
59
  # Process items
60
60
  for item in items:
61
- item_type = "tv" if item.get("__typename") == "SeriesItem" else "film"
62
-
63
- # Bastava un campo data ma no ...
64
- date = item.get("year")
61
+ is_series = (
62
+ item.get("__typename") == "SeriesItem"
63
+ or item.get("cardLink", {}).get("referenceType") == "series"
64
+ or bool(item.get("seasons"))
65
+ )
66
+ item_type = "tv" if is_series else "film"
67
+
68
+ # Get date
69
+ date = item.get("year") or ''
65
70
  if not date:
66
- updated = item.get("updated")
71
+ updated = item.get("updated") or item.get("r") or ''
67
72
  if updated:
68
73
  try:
69
- date = datetime.fromisoformat(updated.replace("Z", "+00:00")).year
74
+ date = datetime.fromisoformat(str(updated).replace("Z", "+00:00")).year
70
75
  except Exception:
71
- try:
72
- timestamp_ms = int(updated)
73
- date = datetime.fromtimestamp(timestamp_ms / 1000).year
74
- except Exception:
75
- date = ""
76
-
77
- date = item.get('year', '')
78
- if not date and item.get('updated'):
79
- try:
80
-
81
- timestamp_ms = int(item.get('updated', 0))
82
- date = datetime.fromtimestamp(timestamp_ms / 1000).year
83
- except (ValueError, TypeError):
84
- date = ''
76
+ date = ''
85
77
 
86
78
  media_search_manager.add_media({
87
- "url": item.get("cardLink", "").get("value", ""),
79
+ "url": item.get("cardLink", {}).get("value", ""),
88
80
  "id": item.get("guid", ""),
89
81
  "name": item.get("cardTitle", "No Title"),
90
82
  "type": item_type,
@@ -92,4 +84,4 @@ def title_search(query: str) -> int:
92
84
  "date": date,
93
85
  })
94
86
 
95
- return media_search_manager.get_length()
87
+ return media_search_manager.get_length()
@@ -78,7 +78,6 @@ def download_film(select_title: MediaItem) -> Tuple[str, bool]:
78
78
  # Get final output path and status
79
79
  r_proc = dash_process.get_status()
80
80
 
81
-
82
81
  if r_proc['error'] is not None:
83
82
  try:
84
83
  os.remove(r_proc['path'])
@@ -23,7 +23,8 @@ from StreamingCommunity.Api.Template.Util import (
23
23
  map_episode_title,
24
24
  validate_selection,
25
25
  validate_episode_selection,
26
- display_episodes_list
26
+ display_episodes_list,
27
+ display_seasons_list
27
28
  )
28
29
  from StreamingCommunity.Api.Template.config_loader import site_constant
29
30
  from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
@@ -71,17 +72,8 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
71
72
  m3u8_url=master_playlist,
72
73
  output_path=os.path.join(mp4_path, mp4_name)
73
74
  ).start()
74
- # Get streaming URL
75
- master_playlist = VideoSource.extract_m3u8_url(obj_episode.url)
76
75
 
77
- # HLS
78
- if ".mpd" not in master_playlist:
79
- r_proc = HLS_Downloader(
80
- m3u8_url=master_playlist,
81
- output_path=os.path.join(mp4_path, mp4_name)
82
- ).start()
83
-
84
- # MPD
76
+ # MPD (DASH)
85
77
  else:
86
78
  full_license_url = generate_license_url(obj_episode.mpd_id)
87
79
  license_headers = {
@@ -169,15 +161,10 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
169
161
  # Get seasons info
170
162
  scrape_serie.collect_info_title()
171
163
  seasons_count = len(scrape_serie.seasons_manager)
172
- console.print(f"\n[green]Seasons found: [red]{seasons_count}")
173
164
 
174
165
  # If season_selection is provided, use it instead of asking for input
175
166
  if season_selection is None:
176
- index_season_selected = msg.ask(
177
- "\n[cyan]Insert season number [yellow](e.g., 1), [red]* [cyan]to download all seasons, "
178
- "[yellow](e.g., 1-2) [cyan]for a range of seasons, or [yellow](e.g., 3-*) [cyan]to download from a specific season to the end"
179
- )
180
-
167
+ index_season_selected = display_seasons_list(scrape_serie.seasons_manager)
181
168
  else:
182
169
  index_season_selected = season_selection
183
170
  console.print(f"\n[cyan]Using provided season selection: [yellow]{season_selection}")
@@ -191,4 +178,4 @@ def download_series(select_season: MediaItem, season_selection: str = None, epis
191
178
  if len(list_season_select) > 1 or index_season_selected == "*":
192
179
  download_episode(season_number, scrape_serie, download_all=True)
193
180
  else:
194
- download_episode(season_number, scrape_serie, download_all=False, episode_selection=episode_selection)
181
+ download_episode(season_number, scrape_serie, download_all=False, episode_selection=episode_selection)
@@ -12,31 +12,12 @@ from StreamingCommunity.Api.Template.config_loader import site_constant
12
12
  from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
13
13
 
14
14
 
15
- # Logic Import
16
- from .util.ScrapeSerie import GetSerieInfo
17
-
18
-
19
15
  # Variable
20
16
  console = Console()
21
17
  media_search_manager = MediaManager()
22
18
  table_show_manager = TVShowManager()
23
19
 
24
20
 
25
- def determine_media_type(item):
26
- """
27
- Determine if the item is a film or TV series by checking actual seasons count
28
- using GetSerieInfo.
29
- """
30
- try:
31
- scraper = GetSerieInfo(item.get('path_id'))
32
- scraper.collect_info_title()
33
- return scraper.prog_tipology, scraper.prog_description, scraper.prog_year
34
-
35
- except Exception as e:
36
- console.print(f"[red]Error determining media type: {e}[/red]")
37
- return None, None, None
38
-
39
-
40
21
  def title_search(query: str) -> int:
41
22
  """
42
23
  Search for titles based on a search query.
@@ -72,24 +53,49 @@ def title_search(query: str) -> int:
72
53
  console.print(f"[red]Site: {site_constant.SITE_NAME}, request search error: {e}")
73
54
  return 0
74
55
 
75
- # Limit to only 15 results for performance
76
- data = response.json().get('agg').get('titoli').get('cards')[:15]
56
+ try:
57
+ response_data = response.json()
58
+ cards = response_data.get('agg', {}).get('titoli', {}).get('cards', [])
59
+
60
+ # Limit to only 15 results for performance
61
+ data = cards[:15]
62
+ console.print(f"[cyan]Found {len(cards)} results, processing first {len(data)}...[/cyan]")
63
+
64
+ except Exception as e:
65
+ console.print(f"[red]Error parsing search results: {e}[/red]")
66
+ return 0
77
67
 
78
68
  # Process each item and add to media manager
79
- for item in data:
80
- media_type, prog_description, prog_year = determine_media_type(item)
81
- if media_type is None:
69
+ for idx, item in enumerate(data, 1):
70
+ try:
71
+ # Get path_id
72
+ path_id = item.get('path_id', '')
73
+ if not path_id:
74
+ console.print("[yellow]Skipping item due to missing path_id[/yellow]")
75
+ continue
76
+
77
+ # Get image URL - handle both relative and absolute URLs
78
+ image = item.get('immagine', '')
79
+ if image and not image.startswith('http'):
80
+ image = f"https://www.raiplay.it{image}"
81
+
82
+ # Get URL - handle both relative and absolute URLs
83
+ url = item.get('url', '')
84
+ if url and not url.startswith('http'):
85
+ url = f"https://www.raiplay.it{url}"
86
+
87
+ media_search_manager.add_media({
88
+ 'id': item.get('id', ''),
89
+ 'name': item.get('titolo', 'Unknown'),
90
+ 'type': "tv",
91
+ 'path_id': path_id,
92
+ 'url': url,
93
+ 'image': image,
94
+ 'year': image.split("/")[5]
95
+ })
96
+
97
+ except Exception as e:
98
+ console.print(f"[red]Error processing item '{item.get('titolo', 'Unknown')}': {e}[/red]")
82
99
  continue
83
-
84
- media_search_manager.add_media({
85
- 'id': item.get('id', ''),
86
- 'name': item.get('titolo', ''),
87
- 'type': media_type,
88
- 'path_id': item.get('path_id', ''),
89
- 'url': f"https://www.raiplay.it{item.get('url', '')}",
90
- 'image': f"https://www.raiplay.it{item.get('immagine', '')}",
91
- 'desc': prog_description,
92
- 'year': prog_year
93
- })
94
-
100
+
95
101
  return media_search_manager.get_length()