StreamingCommunity 2.2.0__py3-none-any.whl → 2.4.0__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 (56) hide show
  1. StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +15 -24
  2. StreamingCommunity/Api/Site/1337xx/site.py +9 -6
  3. StreamingCommunity/Api/Site/1337xx/title.py +2 -2
  4. StreamingCommunity/Api/Site/altadefinizionegratis/costant.py +19 -0
  5. StreamingCommunity/Api/Site/{altadefinizione → altadefinizionegratis}/film.py +2 -2
  6. StreamingCommunity/Api/Site/{altadefinizione → altadefinizionegratis}/site.py +28 -22
  7. StreamingCommunity/Api/Site/animeunity/__init__.py +1 -1
  8. StreamingCommunity/Api/Site/animeunity/costant.py +6 -2
  9. StreamingCommunity/Api/Site/animeunity/film_serie.py +3 -3
  10. StreamingCommunity/Api/Site/animeunity/site.py +29 -21
  11. StreamingCommunity/Api/Site/cb01new/costant.py +6 -2
  12. StreamingCommunity/Api/Site/cb01new/film.py +2 -2
  13. StreamingCommunity/Api/Site/cb01new/site.py +20 -13
  14. StreamingCommunity/Api/Site/ddlstreamitaly/costant.py +6 -2
  15. StreamingCommunity/Api/Site/ddlstreamitaly/series.py +2 -2
  16. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +9 -5
  17. StreamingCommunity/Api/Site/guardaserie/costant.py +6 -2
  18. StreamingCommunity/Api/Site/guardaserie/series.py +2 -3
  19. StreamingCommunity/Api/Site/guardaserie/site.py +10 -6
  20. StreamingCommunity/Api/Site/ilcorsaronero/costant.py +6 -2
  21. StreamingCommunity/Api/Site/ilcorsaronero/site.py +22 -13
  22. StreamingCommunity/Api/Site/ilcorsaronero/title.py +3 -3
  23. StreamingCommunity/Api/Site/ilcorsaronero/util/ilCorsarScraper.py +1 -1
  24. StreamingCommunity/Api/Site/mostraguarda/costant.py +6 -2
  25. StreamingCommunity/Api/Site/mostraguarda/film.py +2 -2
  26. StreamingCommunity/Api/Site/streamingcommunity/costant.py +7 -3
  27. StreamingCommunity/Api/Site/streamingcommunity/film.py +3 -3
  28. StreamingCommunity/Api/Site/streamingcommunity/series.py +3 -3
  29. StreamingCommunity/Api/Site/streamingcommunity/site.py +30 -26
  30. StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +24 -24
  31. StreamingCommunity/Api/Template/Util/get_domain.py +171 -142
  32. StreamingCommunity/Api/Template/site.py +1 -1
  33. StreamingCommunity/Lib/Downloader/HLS/downloader.py +14 -3
  34. StreamingCommunity/Lib/Downloader/HLS/segments.py +36 -22
  35. StreamingCommunity/Lib/Downloader/TOR/downloader.py +3 -3
  36. StreamingCommunity/Lib/M3U8/decryptor.py +1 -0
  37. StreamingCommunity/Lib/M3U8/estimator.py +2 -2
  38. StreamingCommunity/Lib/M3U8/url_fixer.py +6 -0
  39. StreamingCommunity/Lib/TMBD/tmdb.py +1 -1
  40. StreamingCommunity/Upload/version.py +1 -1
  41. StreamingCommunity/Util/_jsonConfig.py +43 -19
  42. StreamingCommunity/Util/ffmpeg_installer.py +31 -14
  43. StreamingCommunity/Util/headers.py +15 -2
  44. StreamingCommunity/Util/logger.py +9 -0
  45. StreamingCommunity/Util/os.py +100 -138
  46. StreamingCommunity/Util/table.py +6 -6
  47. StreamingCommunity/run.py +61 -7
  48. {StreamingCommunity-2.2.0.dist-info → StreamingCommunity-2.4.0.dist-info}/METADATA +116 -35
  49. StreamingCommunity-2.4.0.dist-info/RECORD +92 -0
  50. StreamingCommunity/Api/Site/altadefinizione/costant.py +0 -15
  51. StreamingCommunity-2.2.0.dist-info/RECORD +0 -92
  52. /StreamingCommunity/Api/Site/{altadefinizione → altadefinizionegratis}/__init__.py +0 -0
  53. {StreamingCommunity-2.2.0.dist-info → StreamingCommunity-2.4.0.dist-info}/LICENSE +0 -0
  54. {StreamingCommunity-2.2.0.dist-info → StreamingCommunity-2.4.0.dist-info}/WHEEL +0 -0
  55. {StreamingCommunity-2.2.0.dist-info → StreamingCommunity-2.4.0.dist-info}/entry_points.txt +0 -0
  56. {StreamingCommunity-2.2.0.dist-info → StreamingCommunity-2.4.0.dist-info}/top_level.txt +0 -0
@@ -2,6 +2,7 @@
2
2
 
3
3
 
4
4
  # Internal utilities
5
+ from StreamingCommunity.Util._jsonConfig import config_manager
5
6
  from StreamingCommunity.Util.table import TVShowManager
6
7
 
7
8
 
@@ -13,9 +14,11 @@ from .util.ilCorsarScraper import IlCorsaroNeroScraper
13
14
 
14
15
 
15
16
  # Variable
16
- from .costant import SITE_NAME
17
+ from .costant import SITE_NAME, DOMAIN_NOW
17
18
  media_search_manager = MediaManager()
18
19
  table_show_manager = TVShowManager()
20
+ max_timeout = config_manager.get_int("REQUESTS", "timeout")
21
+ disable_searchDomain = config_manager.get_bool("DEFAULT", "disable_searchDomain")
19
22
 
20
23
 
21
24
  async def title_search(word_to_search: str) -> int:
@@ -32,25 +35,31 @@ async def title_search(word_to_search: str) -> int:
32
35
  table_show_manager.clear()
33
36
 
34
37
  # Find new domain if prev dont work
35
- domain_to_use, _ = search_domain(SITE_NAME, f"https://{SITE_NAME}")
38
+ domain_to_use = DOMAIN_NOW
39
+
40
+ if not disable_searchDomain:
41
+ domain_to_use, base_url = search_domain(SITE_NAME, f"https://{SITE_NAME}.{DOMAIN_NOW}")
36
42
 
37
43
  # Create scraper and collect result
38
44
  print("\n")
39
45
  scraper = IlCorsaroNeroScraper(f"https://{SITE_NAME}.{domain_to_use}/", 1)
40
46
  results = await scraper.search(word_to_search)
41
47
 
42
- # Add all result to media manager
43
48
  for i, torrent in enumerate(results):
44
- media_search_manager.add_media({
45
- 'name': torrent['name'],
46
- 'type': torrent['type'],
47
- 'seed': torrent['seed'],
48
- 'leech': torrent['leech'],
49
- 'size': torrent['size'],
50
- 'date': torrent['date'],
51
- 'url': torrent['url']
52
- })
53
-
49
+ try:
50
+
51
+ media_search_manager.add_media({
52
+ 'name': torrent['name'],
53
+ 'type': torrent['type'],
54
+ 'seed': torrent['seed'],
55
+ 'leech': torrent['leech'],
56
+ 'size': torrent['size'],
57
+ 'date': torrent['date'],
58
+ 'url': torrent['url']
59
+ })
60
+
61
+ except Exception as e:
62
+ print(f"Error parsing a film entry: {e}")
54
63
 
55
64
  # Return the number of titles found
56
65
  return media_search_manager.get_length()
@@ -15,7 +15,7 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaItem
15
15
 
16
16
 
17
17
  # Config
18
- from .costant import ROOT_PATH, MOVIE_FOLDER
18
+ from .costant import MOVIE_FOLDER
19
19
 
20
20
 
21
21
  def download_title(select_title: MediaItem):
@@ -27,13 +27,13 @@ def download_title(select_title: MediaItem):
27
27
  """
28
28
 
29
29
  start_message()
30
- console.print(f"[yellow]Download: [red]{select_title.name} \n")
30
+ console.print(f"[yellow]Download: [red]{select_title.name} \n")
31
31
  print()
32
32
 
33
33
  # Define output path
34
34
  title_name = os_manager.get_sanitize_file(select_title.name)
35
35
  mp4_path = os_manager.get_sanitize_path(
36
- os.path.join(ROOT_PATH, MOVIE_FOLDER, title_name.replace(".mp4", ""))
36
+ os.path.join(MOVIE_FOLDER, title_name.replace(".mp4", ""))
37
37
  )
38
38
 
39
39
  # Create output folder
@@ -54,7 +54,7 @@ class IlCorsaroNeroScraper:
54
54
  return response.text
55
55
 
56
56
  except Exception as e:
57
- logging.error(f"Error fetching {url}: {e}")
57
+ logging.error(f"Error fetching from {url}: {e}")
58
58
  return None
59
59
 
60
60
  def parse_torrents(self, html: str) -> List[Dict[str, str]]:
@@ -11,5 +11,9 @@ SITE_NAME = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
11
11
  ROOT_PATH = config_manager.get('DEFAULT', 'root_path')
12
12
  DOMAIN_NOW = config_manager.get_dict('SITE', SITE_NAME)['domain']
13
13
 
14
- SERIES_FOLDER = config_manager.get('DEFAULT', 'serie_folder_name')
15
- MOVIE_FOLDER = config_manager.get('DEFAULT', 'movie_folder_name')
14
+ SERIES_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'serie_folder_name'))
15
+ MOVIE_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'movie_folder_name'))
16
+
17
+ if config_manager.get_bool("DEFAULT", "add_siteName"):
18
+ SERIES_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'serie_folder_name'))
19
+ MOVIE_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'movie_folder_name'))
@@ -33,7 +33,7 @@ from StreamingCommunity.Lib.TMBD import Json_film
33
33
 
34
34
 
35
35
  # Config
36
- from .costant import ROOT_PATH, SITE_NAME, DOMAIN_NOW, MOVIE_FOLDER
36
+ from .costant import SITE_NAME, DOMAIN_NOW, MOVIE_FOLDER
37
37
 
38
38
 
39
39
  def download_film(movie_details: Json_film) -> str:
@@ -75,7 +75,7 @@ def download_film(movie_details: Json_film) -> str:
75
75
 
76
76
  # Define output path
77
77
  title_name = os_manager.get_sanitize_file(movie_details.title) + ".mp4"
78
- mp4_path = os.path.join(ROOT_PATH, MOVIE_FOLDER, title_name.replace(".mp4", ""))
78
+ mp4_path = os.path.join(MOVIE_FOLDER, title_name.replace(".mp4", ""))
79
79
 
80
80
  # Get m3u8 master playlist
81
81
  master_playlist = video_source.get_playlist()
@@ -9,7 +9,11 @@ from StreamingCommunity.Util._jsonConfig import config_manager
9
9
 
10
10
  SITE_NAME = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
11
11
  ROOT_PATH = config_manager.get('DEFAULT', 'root_path')
12
- DOMAIN_NOW = config_manager.get('SITE', SITE_NAME)
12
+ DOMAIN_NOW = config_manager.get_dict('SITE', SITE_NAME)['domain']
13
13
 
14
- SERIES_FOLDER = config_manager.get('DEFAULT', 'serie_folder_name')
15
- MOVIE_FOLDER = config_manager.get('DEFAULT', 'movie_folder_name')
14
+ SERIES_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'serie_folder_name'))
15
+ MOVIE_FOLDER = os.path.join(ROOT_PATH, config_manager.get('DEFAULT', 'movie_folder_name'))
16
+
17
+ if config_manager.get_bool("DEFAULT", "add_siteName"):
18
+ SERIES_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'serie_folder_name'))
19
+ MOVIE_FOLDER = os.path.join(ROOT_PATH, SITE_NAME, config_manager.get('DEFAULT', 'movie_folder_name'))
@@ -22,7 +22,7 @@ from StreamingCommunity.Api.Player.vixcloud import VideoSource
22
22
 
23
23
 
24
24
  # Variable
25
- from .costant import ROOT_PATH, SITE_NAME, MOVIE_FOLDER
25
+ from .costant import SITE_NAME, MOVIE_FOLDER
26
26
 
27
27
 
28
28
  def download_film(select_title: MediaItem) -> str:
@@ -51,8 +51,8 @@ def download_film(select_title: MediaItem) -> str:
51
51
  master_playlist = video_source.get_playlist()
52
52
 
53
53
  # Define the filename and path for the downloaded film
54
- title_name = os_manager.get_sanitize_file(select_title.slug) + ".mp4"
55
- mp4_path = os.path.join(ROOT_PATH, MOVIE_FOLDER, select_title.slug)
54
+ title_name = os_manager.get_sanitize_file(select_title.name) + ".mp4"
55
+ mp4_path = os.path.join(MOVIE_FOLDER, select_title.name)
56
56
 
57
57
  # Download the film using the m3u8 playlist, and output filename
58
58
  r_proc = HLS_Downloader(
@@ -24,7 +24,7 @@ from StreamingCommunity.Api.Player.vixcloud import VideoSource
24
24
 
25
25
 
26
26
  # Variable
27
- from .costant import ROOT_PATH, SITE_NAME, SERIES_FOLDER
27
+ from .costant import SITE_NAME, SERIES_FOLDER
28
28
 
29
29
 
30
30
 
@@ -48,7 +48,7 @@ def download_video(index_season_selected: int, index_episode_selected: int, scra
48
48
 
49
49
  # Define filename and path for the downloaded video
50
50
  mp4_name = f"{map_episode_title(scrape_serie.series_name, index_season_selected, index_episode_selected, obj_episode.name)}.mp4"
51
- mp4_path = os.path.join(ROOT_PATH, SERIES_FOLDER, scrape_serie.series_name, f"S{index_season_selected}")
51
+ mp4_path = os.path.join(SERIES_FOLDER, scrape_serie.series_name, f"S{index_season_selected}")
52
52
 
53
53
  # Retrieve scws and if available master playlist
54
54
  video_source.get_iframe(obj_episode.id)
@@ -199,7 +199,7 @@ def display_episodes_list(scrape_serie) -> str:
199
199
  # Run the table and handle user input
200
200
  last_command = table_show_manager.run()
201
201
 
202
- if last_command == "q":
202
+ if last_command == "q" or last_command == "quit":
203
203
  console.print("\n[red]Quit [white]...")
204
204
  sys.exit(0)
205
205
 
@@ -1,6 +1,5 @@
1
1
  # 10.12.23
2
2
 
3
- import sys
4
3
  import json
5
4
  import logging
6
5
  import secrets
@@ -26,30 +25,36 @@ from StreamingCommunity.Api.Template.Class.SearchType import MediaManager
26
25
 
27
26
 
28
27
  # Config
29
- from .costant import SITE_NAME
28
+ from .costant import SITE_NAME, DOMAIN_NOW
30
29
 
31
30
 
32
31
  # Variable
33
32
  media_search_manager = MediaManager()
34
33
  table_show_manager = TVShowManager()
35
34
  max_timeout = config_manager.get_int("REQUESTS", "timeout")
35
+ disable_searchDomain = config_manager.get_bool("DEFAULT", "disable_searchDomain")
36
36
 
37
37
 
38
- def get_version(text: str):
38
+ def get_version(domain: str):
39
39
  """
40
40
  Extracts the version from the HTML text of a webpage.
41
41
 
42
42
  Parameters:
43
- - text (str): The HTML text of the webpage.
43
+ - domain (str): The domain of the site.
44
44
 
45
45
  Returns:
46
46
  str: The version extracted from the webpage.
47
- list: Top 10 titles headlines for today.
48
47
  """
49
48
  try:
49
+ response = httpx.get(
50
+ url=f"https://{SITE_NAME}.{domain}/",
51
+ headers={'User-Agent': get_headers()},
52
+ timeout=max_timeout
53
+ )
54
+ response.raise_for_status()
50
55
 
51
56
  # Parse request to site
52
- soup = BeautifulSoup(text, "html.parser")
57
+ soup = BeautifulSoup(response.text, "html.parser")
53
58
 
54
59
  # Extract version
55
60
  version = json.loads(soup.find("div", {"id": "app"}).get("data-page"))['version']
@@ -72,22 +77,17 @@ def get_version_and_domain():
72
77
  """
73
78
 
74
79
  # Find new domain if prev dont work
75
- domain_to_use, base_url = search_domain(SITE_NAME, f"https://{SITE_NAME}")
80
+ domain_to_use = DOMAIN_NOW
81
+
82
+ if not disable_searchDomain:
83
+ domain_to_use, base_url = search_domain(SITE_NAME, f"https://{SITE_NAME}.{DOMAIN_NOW}")
76
84
 
77
- # Extract version from the response
78
85
  try:
79
- version = get_version(
80
- httpx.get(
81
- url=base_url,
82
- headers={'User-Agent': get_headers()},
83
- timeout=max_timeout
84
- ).text
85
- )
86
-
86
+ version = get_version(domain_to_use)
87
87
  except:
88
88
  console.print("[green]Auto generate version ...")
89
89
  version = secrets.token_hex(32 // 2)
90
-
90
+
91
91
  return version, domain_to_use
92
92
 
93
93
 
@@ -116,16 +116,20 @@ def title_search(title_search: str, domain: str) -> int:
116
116
  except Exception as e:
117
117
  console.print(f"Site: {SITE_NAME}, request search error: {e}")
118
118
 
119
- # Add found titles to media search manager
120
119
  for dict_title in response.json()['data']:
121
- media_search_manager.add_media({
122
- 'id': dict_title.get('id'),
123
- 'slug': dict_title.get('slug'),
124
- 'name': dict_title.get('name'),
125
- 'type': dict_title.get('type'),
126
- 'date': dict_title.get('last_air_date'),
127
- 'score': dict_title.get('score')
128
- })
120
+ try:
121
+
122
+ media_search_manager.add_media({
123
+ 'id': dict_title.get('id'),
124
+ 'slug': dict_title.get('slug'),
125
+ 'name': dict_title.get('name'),
126
+ 'type': dict_title.get('type'),
127
+ 'date': dict_title.get('last_air_date'),
128
+ 'score': dict_title.get('score')
129
+ })
130
+
131
+ except Exception as e:
132
+ print(f"Error parsing a film entry: {e}")
129
133
 
130
134
  # Return the number of titles found
131
135
  return media_search_manager.get_length()
@@ -1,10 +1,12 @@
1
1
  # 01.03.24
2
2
 
3
+ import json
3
4
  import logging
4
5
 
5
6
 
6
7
  # External libraries
7
8
  import httpx
9
+ from bs4 import BeautifulSoup
8
10
 
9
11
 
10
12
  # Internal utilities
@@ -56,33 +58,33 @@ class ScrapeSerie:
56
58
  Raises:
57
59
  Exception: If there's an error fetching season information
58
60
  """
59
- self.headers = {
60
- 'user-agent': get_headers(),
61
- 'x-inertia': 'true',
62
- 'x-inertia-version': self.version,
63
- }
64
-
65
61
  try:
66
-
67
62
  response = httpx.get(
68
- url=f"https://{self.base_name}.{self.domain}/titles/{self.media_id}-{self.series_name}",
69
- headers=self.headers,
63
+ url=f"https://{self.base_name}.{self.domain}/titles/{self.media_id}-{self.series_name}",
64
+ headers=self.headers,
70
65
  timeout=max_timeout
71
66
  )
72
67
  response.raise_for_status()
73
68
 
74
69
  # Extract seasons from JSON response
75
- json_response = response.json().get('props')
70
+ soup = BeautifulSoup(response.text, "html.parser")
71
+ json_response = json.loads(soup.find("div", {"id": "app"}).get("data-page"))
72
+
73
+ """
74
+ response = httpx.post(
75
+ url=f'https://{self.base_name}.{self.domain}/api/titles/preview/{self.media_id}',
76
+ headers={'User-Agent': get_headers()}
77
+ )
78
+ response.raise_for_status()
79
+
80
+
81
+ # Extract seasons from JSON response
82
+ json_response = response.json()
83
+ """
76
84
 
77
85
  # Collect info about season
78
- self.season_manager = Season(json_response.get('title'))
79
- self.season_manager.collect_images(self.base_name, self.domain)
86
+ self.season_manager = Season(json_response.get("props").get("title"))
80
87
 
81
- # Collect first episode info
82
- for i, ep in enumerate(json_response.get('loadedSeason').get('episodes')):
83
- self.season_manager.episodes.add(ep)
84
- self.season_manager.episodes.get(i).collect_image(self.base_name, self.domain)
85
-
86
88
  except Exception as e:
87
89
  logging.error(f"Error collecting season info: {e}")
88
90
  raise
@@ -97,16 +99,14 @@ class ScrapeSerie:
97
99
  Raises:
98
100
  Exception: If there's an error fetching episode information
99
101
  """
100
- self.headers = {
101
- 'user-agent': get_headers(),
102
- 'x-inertia': 'true',
103
- 'x-inertia-version': self.version,
104
- }
105
-
106
102
  try:
107
103
  response = httpx.get(
108
104
  url=f'https://{self.base_name}.{self.domain}/titles/{self.media_id}-{self.series_name}/stagione-{number_season}',
109
- headers=self.headers,
105
+ headers={
106
+ 'User-Agent': get_headers(),
107
+ 'x-inertia': 'true',
108
+ 'x-inertia-version': self.version,
109
+ },
110
110
  timeout=max_timeout
111
111
  )
112
112
  response.raise_for_status()