StreamingCommunity 2.3.0__py3-none-any.whl → 2.5.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 (92) hide show
  1. StreamingCommunity/run.py +61 -7
  2. {StreamingCommunity-2.3.0.dist-info → StreamingCommunity-2.5.0.dist-info}/METADATA +88 -18
  3. StreamingCommunity-2.5.0.dist-info/RECORD +8 -0
  4. StreamingCommunity/Api/Player/Helper/Vixcloud/js_parser.py +0 -143
  5. StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +0 -136
  6. StreamingCommunity/Api/Player/ddl.py +0 -89
  7. StreamingCommunity/Api/Player/maxstream.py +0 -151
  8. StreamingCommunity/Api/Player/supervideo.py +0 -194
  9. StreamingCommunity/Api/Player/vixcloud.py +0 -273
  10. StreamingCommunity/Api/Site/1337xx/__init__.py +0 -51
  11. StreamingCommunity/Api/Site/1337xx/costant.py +0 -15
  12. StreamingCommunity/Api/Site/1337xx/site.py +0 -89
  13. StreamingCommunity/Api/Site/1337xx/title.py +0 -66
  14. StreamingCommunity/Api/Site/altadefinizione/__init__.py +0 -51
  15. StreamingCommunity/Api/Site/altadefinizione/costant.py +0 -19
  16. StreamingCommunity/Api/Site/altadefinizione/film.py +0 -74
  17. StreamingCommunity/Api/Site/altadefinizione/site.py +0 -95
  18. StreamingCommunity/Api/Site/animeunity/__init__.py +0 -51
  19. StreamingCommunity/Api/Site/animeunity/costant.py +0 -19
  20. StreamingCommunity/Api/Site/animeunity/film_serie.py +0 -135
  21. StreamingCommunity/Api/Site/animeunity/site.py +0 -175
  22. StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +0 -97
  23. StreamingCommunity/Api/Site/cb01new/__init__.py +0 -52
  24. StreamingCommunity/Api/Site/cb01new/costant.py +0 -19
  25. StreamingCommunity/Api/Site/cb01new/film.py +0 -73
  26. StreamingCommunity/Api/Site/cb01new/site.py +0 -83
  27. StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +0 -56
  28. StreamingCommunity/Api/Site/ddlstreamitaly/costant.py +0 -20
  29. StreamingCommunity/Api/Site/ddlstreamitaly/series.py +0 -146
  30. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +0 -99
  31. StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py +0 -85
  32. StreamingCommunity/Api/Site/guardaserie/__init__.py +0 -51
  33. StreamingCommunity/Api/Site/guardaserie/costant.py +0 -19
  34. StreamingCommunity/Api/Site/guardaserie/series.py +0 -198
  35. StreamingCommunity/Api/Site/guardaserie/site.py +0 -90
  36. StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +0 -110
  37. StreamingCommunity/Api/Site/ilcorsaronero/__init__.py +0 -52
  38. StreamingCommunity/Api/Site/ilcorsaronero/costant.py +0 -19
  39. StreamingCommunity/Api/Site/ilcorsaronero/site.py +0 -72
  40. StreamingCommunity/Api/Site/ilcorsaronero/title.py +0 -46
  41. StreamingCommunity/Api/Site/ilcorsaronero/util/ilCorsarScraper.py +0 -149
  42. StreamingCommunity/Api/Site/mostraguarda/__init__.py +0 -49
  43. StreamingCommunity/Api/Site/mostraguarda/costant.py +0 -19
  44. StreamingCommunity/Api/Site/mostraguarda/film.py +0 -101
  45. StreamingCommunity/Api/Site/streamingcommunity/__init__.py +0 -56
  46. StreamingCommunity/Api/Site/streamingcommunity/costant.py +0 -19
  47. StreamingCommunity/Api/Site/streamingcommunity/film.py +0 -75
  48. StreamingCommunity/Api/Site/streamingcommunity/series.py +0 -206
  49. StreamingCommunity/Api/Site/streamingcommunity/site.py +0 -139
  50. StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +0 -123
  51. StreamingCommunity/Api/Template/Class/SearchType.py +0 -101
  52. StreamingCommunity/Api/Template/Util/__init__.py +0 -5
  53. StreamingCommunity/Api/Template/Util/get_domain.py +0 -137
  54. StreamingCommunity/Api/Template/Util/manage_ep.py +0 -179
  55. StreamingCommunity/Api/Template/Util/recall_search.py +0 -37
  56. StreamingCommunity/Api/Template/__init__.py +0 -3
  57. StreamingCommunity/Api/Template/site.py +0 -87
  58. StreamingCommunity/Lib/Downloader/HLS/downloader.py +0 -955
  59. StreamingCommunity/Lib/Downloader/HLS/proxyes.py +0 -110
  60. StreamingCommunity/Lib/Downloader/HLS/segments.py +0 -564
  61. StreamingCommunity/Lib/Downloader/MP4/downloader.py +0 -155
  62. StreamingCommunity/Lib/Downloader/TOR/downloader.py +0 -296
  63. StreamingCommunity/Lib/Downloader/__init__.py +0 -5
  64. StreamingCommunity/Lib/FFmpeg/__init__.py +0 -4
  65. StreamingCommunity/Lib/FFmpeg/capture.py +0 -170
  66. StreamingCommunity/Lib/FFmpeg/command.py +0 -296
  67. StreamingCommunity/Lib/FFmpeg/util.py +0 -249
  68. StreamingCommunity/Lib/M3U8/__init__.py +0 -6
  69. StreamingCommunity/Lib/M3U8/decryptor.py +0 -164
  70. StreamingCommunity/Lib/M3U8/estimator.py +0 -229
  71. StreamingCommunity/Lib/M3U8/parser.py +0 -666
  72. StreamingCommunity/Lib/M3U8/url_fixer.py +0 -52
  73. StreamingCommunity/Lib/TMBD/__init__.py +0 -2
  74. StreamingCommunity/Lib/TMBD/obj_tmbd.py +0 -39
  75. StreamingCommunity/Lib/TMBD/tmdb.py +0 -346
  76. StreamingCommunity/Upload/update.py +0 -67
  77. StreamingCommunity/Upload/version.py +0 -5
  78. StreamingCommunity/Util/_jsonConfig.py +0 -204
  79. StreamingCommunity/Util/call_stack.py +0 -42
  80. StreamingCommunity/Util/color.py +0 -20
  81. StreamingCommunity/Util/console.py +0 -12
  82. StreamingCommunity/Util/ffmpeg_installer.py +0 -351
  83. StreamingCommunity/Util/headers.py +0 -147
  84. StreamingCommunity/Util/logger.py +0 -53
  85. StreamingCommunity/Util/message.py +0 -64
  86. StreamingCommunity/Util/os.py +0 -545
  87. StreamingCommunity/Util/table.py +0 -229
  88. StreamingCommunity-2.3.0.dist-info/RECORD +0 -92
  89. {StreamingCommunity-2.3.0.dist-info → StreamingCommunity-2.5.0.dist-info}/LICENSE +0 -0
  90. {StreamingCommunity-2.3.0.dist-info → StreamingCommunity-2.5.0.dist-info}/WHEEL +0 -0
  91. {StreamingCommunity-2.3.0.dist-info → StreamingCommunity-2.5.0.dist-info}/entry_points.txt +0 -0
  92. {StreamingCommunity-2.3.0.dist-info → StreamingCommunity-2.5.0.dist-info}/top_level.txt +0 -0
@@ -1,137 +0,0 @@
1
- # 18.06.24
2
-
3
- from urllib.parse import urlparse
4
-
5
-
6
- # External libraries
7
- import httpx
8
- from googlesearch import search
9
-
10
-
11
- # Internal utilities
12
- from StreamingCommunity.Util.headers import get_headers
13
- from StreamingCommunity.Util.console import console, msg
14
- from StreamingCommunity.Util._jsonConfig import config_manager
15
-
16
-
17
- def get_base_domain(url_str):
18
- """Extract base domain without protocol, www and path"""
19
- parsed = urlparse(url_str)
20
- domain = parsed.netloc.lower()
21
- if domain.startswith('www.'):
22
- domain = domain[4:]
23
- return domain.split('.')[0]
24
-
25
- def validate_url(url, base_url, max_timeout):
26
- """
27
- Validate if URL is accessible and matches expected base domain
28
- """
29
- console.print(f"\n[cyan]Starting validation for URL[white]: [yellow]{url}")
30
-
31
- def check_response(response, check_num):
32
- if response.status_code == 403:
33
- console.print(f"[red]Check {check_num} failed: Access forbidden (403)")
34
- return False
35
- if response.status_code >= 400:
36
- console.print(f"[red]Check {check_num} failed: HTTP {response.status_code}")
37
- return False
38
- console.print(f"[green]Check {check_num} passed: HTTP {response.status_code}")
39
- return True
40
-
41
- try:
42
-
43
- # Check 1: Initial request without following redirects
44
- console.print("[cyan]Performing initial connection check...")
45
- with httpx.Client(
46
- headers={'User-Agent': get_headers()},
47
- follow_redirects=False,
48
- timeout=max_timeout
49
- ) as client:
50
- response = client.get(url)
51
- if not check_response(response, 1):
52
- return False
53
-
54
- # Check 2: Follow redirects and verify final domain
55
- console.print("[cyan]Checking redirect destination...")
56
- with httpx.Client(
57
- headers={'User-Agent': get_headers()},
58
- follow_redirects=True,
59
- timeout=max_timeout
60
- ) as client:
61
-
62
- response = client.get(url)
63
- if not check_response(response, 2):
64
- return False
65
-
66
- # Compare base domains
67
- original_base = get_base_domain(url)
68
- final_base = get_base_domain(str(response.url))
69
-
70
- console.print(f"[cyan]Comparing domains:")
71
- console.print(f"Original base domain: [yellow]{original_base}")
72
- console.print(f"Final base domain: [yellow]{final_base}")
73
-
74
- if original_base != final_base:
75
- console.print(f"[red]Domain mismatch: Redirected to different base domain")
76
- return False
77
-
78
- # Verify against expected base_url
79
- expected_base = get_base_domain(base_url)
80
- if final_base != expected_base:
81
- console.print(f"[red]Domain mismatch: Final domain does not match expected base URL")
82
- console.print(f"Expected: [yellow]{expected_base}")
83
- return False
84
-
85
- console.print(f"[green]All checks passed: URL is valid and matches expected domain")
86
- return True
87
-
88
- except Exception as e:
89
- console.print(f"[red]Error during validation: {str(e)}")
90
- return False
91
-
92
- def search_domain(site_name: str, base_url: str, get_first: bool = False):
93
- """
94
- Search for valid domain matching site name and base URL.
95
- """
96
- max_timeout = config_manager.get_int("REQUESTS", "timeout")
97
- domain = str(config_manager.get_dict("SITE", site_name)['domain'])
98
- test_url = f"{base_url}.{domain}"
99
-
100
- console.print(f"\n[cyan]Testing initial URL[white]: [yellow]{test_url}")
101
-
102
- try:
103
- if validate_url(test_url, base_url, max_timeout):
104
- parsed_url = urlparse(test_url)
105
- tld = parsed_url.netloc.split('.')[-1]
106
- config_manager.config['SITE'][site_name]['domain'] = tld
107
- config_manager.write_config()
108
- console.print(f"[green]Successfully validated initial URL")
109
- return tld, test_url
110
-
111
- except Exception as e:
112
- console.print(f"[red]Error testing initial URL: {str(e)}")
113
-
114
- # Google search phase
115
- query = base_url.split("/")[-1]
116
- console.print(f"\n[cyan]Performing Google search for[white]: [yellow]{query}")
117
- search_results = list(search(query, num_results=15, lang="it"))
118
-
119
- for idx, result_url in enumerate(search_results, 1):
120
- console.print(f"\n[cyan]Checking Google result {idx}/15[white]: [yellow]{result_url}")
121
-
122
- if validate_url(result_url, base_url, max_timeout):
123
- parsed_result = urlparse(result_url)
124
- new_domain = parsed_result.netloc.split(".")[-1]
125
-
126
- if get_first or msg.ask(
127
- f"\n[cyan]Do you want to update site[white] [red]'{site_name}'[cyan] with domain[white] [red]'{new_domain}'",
128
- choices=["y", "n"],
129
- default="y"
130
- ).lower() == "y":
131
-
132
- config_manager.config['SITE'][site_name]['domain'] = new_domain
133
- config_manager.write_config()
134
- return new_domain, f"{base_url}.{new_domain}"
135
-
136
- console.print("[bold red]No valid URLs found matching the base URL.")
137
- return domain, f"{base_url}.{domain}"
@@ -1,179 +0,0 @@
1
- # 19.06.24
2
-
3
- import logging
4
- from typing import List
5
-
6
-
7
- # Internal utilities
8
- from StreamingCommunity.Util._jsonConfig import config_manager
9
- from StreamingCommunity.Util.os import os_manager
10
-
11
-
12
- # Config
13
- MAP_EPISODE = config_manager.get('DEFAULT', 'map_episode_name')
14
-
15
-
16
- def dynamic_format_number(n: int) -> str:
17
- """
18
- Formats a number by adding a leading zero if it is less than 9.
19
- The width of the resulting string is dynamic, calculated as the number of digits in the number plus one
20
- for numbers less than 9, otherwise the width remains the same.
21
-
22
- Parameters:
23
- - n (int): The number to format.
24
-
25
- Returns:
26
- - str: The formatted number as a string with a leading zero if the number is less than 9.
27
- """
28
- if n < 10:
29
- width = len(str(n)) + 1
30
- else:
31
- width = len(str(n))
32
-
33
- return str(n).zfill(width)
34
-
35
-
36
- def manage_selection(cmd_insert: str, max_count: int) -> List[int]:
37
- """
38
- Manage user selection for seasons or episodes to download.
39
-
40
- Parameters:
41
- - cmd_insert (str): User input for selection.
42
- - max_count (int): Maximum count available.
43
-
44
- Returns:
45
- list_selection (List[int]): List of selected items.
46
- """
47
- list_selection = []
48
- logging.info(f"Command insert: {cmd_insert}, end index: {max_count + 1}")
49
-
50
- # For a single number (e.g., '5')
51
- if cmd_insert.isnumeric():
52
- list_selection.append(int(cmd_insert))
53
-
54
- # For a range (e.g., '5-12')
55
- elif "-" in cmd_insert:
56
- start, end = map(str.strip, cmd_insert.split('-'))
57
- start = int(start)
58
- end = int(end) if end.isnumeric() else max_count
59
-
60
- list_selection = list(range(start, end + 1))
61
-
62
- # For all items ('*')
63
- elif cmd_insert == "*":
64
- list_selection = list(range(1, max_count + 1))
65
-
66
- else:
67
- raise ValueError("Invalid input format")
68
-
69
- logging.info(f"List return: {list_selection}")
70
- return list_selection
71
-
72
-
73
- def map_episode_title(tv_name: str, number_season: int, episode_number: int, episode_name: str) -> str:
74
- """
75
- Maps the episode title to a specific format.
76
-
77
- Parameters:
78
- tv_name (str): The name of the TV show.
79
- number_season (int): The season number.
80
- episode_number (int): The episode number.
81
- episode_name (str): The original name of the episode.
82
-
83
- Returns:
84
- str: The mapped episode title.
85
- """
86
- map_episode_temp = MAP_EPISODE
87
-
88
- if tv_name != None:
89
- map_episode_temp = map_episode_temp.replace("%(tv_name)", os_manager.get_sanitize_file(tv_name))
90
-
91
- if number_season != None:
92
- map_episode_temp = map_episode_temp.replace("%(season)", dynamic_format_number(number_season))
93
- else:
94
- map_episode_temp = map_episode_temp.replace("%(season)", dynamic_format_number(0))
95
-
96
- if episode_number != None:
97
- map_episode_temp = map_episode_temp.replace("%(episode)", dynamic_format_number(episode_number))
98
- else:
99
- map_episode_temp = map_episode_temp.replace("%(episode)", dynamic_format_number(0))
100
-
101
- if episode_name != None:
102
- map_episode_temp = map_episode_temp.replace("%(episode_name)", os_manager.get_sanitize_file(episode_name))
103
-
104
- logging.info(f"Map episode string return: {map_episode_temp}")
105
- return map_episode_temp
106
-
107
-
108
- # --> for season
109
- def validate_selection(list_season_select: List[int], seasons_count: int) -> List[int]:
110
- """
111
- Validates and adjusts the selected seasons based on the available seasons.
112
-
113
- Parameters:
114
- - list_season_select (List[int]): List of seasons selected by the user.
115
- - seasons_count (int): Total number of available seasons.
116
-
117
- Returns:
118
- - List[int]: Adjusted list of valid season numbers.
119
- """
120
- while True:
121
- try:
122
-
123
- # Remove any seasons greater than the available seasons
124
- valid_seasons = [season for season in list_season_select if 1 <= season <= seasons_count]
125
-
126
- # If the list is empty, the input was completely invalid
127
- if not valid_seasons:
128
- logging.error(f"Invalid selection: The selected seasons are outside the available range (1-{seasons_count}). Please try again.")
129
-
130
- # Re-prompt for valid input
131
- input_seasons = input(f"Enter valid season numbers (1-{seasons_count}): ")
132
- list_season_select = list(map(int, input_seasons.split(',')))
133
- continue # Re-prompt the user if the selection is invalid
134
-
135
- return valid_seasons # Return the valid seasons if the input is correct
136
-
137
- except ValueError:
138
- logging.error("Error: Please enter valid integers separated by commas.")
139
-
140
- # Prompt the user for valid input again
141
- input_seasons = input(f"Enter valid season numbers (1-{seasons_count}): ")
142
- list_season_select = list(map(int, input_seasons.split(',')))
143
-
144
-
145
- # --> for episode
146
- def validate_episode_selection(list_episode_select: List[int], episodes_count: int) -> List[int]:
147
- """
148
- Validates and adjusts the selected episodes based on the available episodes.
149
-
150
- Parameters:
151
- - list_episode_select (List[int]): List of episodes selected by the user.
152
- - episodes_count (int): Total number of available episodes in the season.
153
-
154
- Returns:
155
- - List[int]: Adjusted list of valid episode numbers.
156
- """
157
- while True:
158
- try:
159
-
160
- # Remove any episodes greater than the available episodes
161
- valid_episodes = [episode for episode in list_episode_select if 1 <= episode <= episodes_count]
162
-
163
- # If the list is empty, the input was completely invalid
164
- if not valid_episodes:
165
- logging.error(f"Invalid selection: The selected episodes are outside the available range (1-{episodes_count}). Please try again.")
166
-
167
- # Re-prompt for valid input
168
- input_episodes = input(f"Enter valid episode numbers (1-{episodes_count}): ")
169
- list_episode_select = list(map(int, input_episodes.split(',')))
170
- continue # Re-prompt the user if the selection is invalid
171
-
172
- return valid_episodes
173
-
174
- except ValueError:
175
- logging.error("Error: Please enter valid integers separated by commas.")
176
-
177
- # Prompt the user for valid input again
178
- input_episodes = input(f"Enter valid episode numbers (1-{episodes_count}): ")
179
- list_episode_select = list(map(int, input_episodes.split(',')))
@@ -1,37 +0,0 @@
1
- # 19.10.24
2
-
3
- import os
4
- import sys
5
-
6
- def execute_search(info):
7
- """
8
- Dynamically imports and executes a specified function from a module defined in the info dictionary.
9
-
10
- Parameters:
11
- info (dict): A dictionary containing the function name, folder, and module information.
12
- """
13
-
14
- # Define the project path using the folder from the info dictionary
15
- project_path = os.path.dirname(info['folder']) # Get the base path for the project
16
-
17
- # Add the project path to sys.path
18
- if project_path not in sys.path:
19
- sys.path.append(project_path)
20
-
21
- # Attempt to import the specified function from the module
22
- try:
23
- # Construct the import statement dynamically
24
- module_path = f"StreamingCommunity.Api.Site{info['folder_base']}"
25
- exec(f"from {module_path} import {info['function']}")
26
-
27
- # Call the specified function
28
- eval(info['function'])() # Calls the search function
29
-
30
- except ModuleNotFoundError as e:
31
- print(f"ModuleNotFoundError: {e}")
32
-
33
- except ImportError as e:
34
- print(f"ImportError: {e}")
35
-
36
- except Exception as e:
37
- print(f"An error occurred: {e}")
@@ -1,3 +0,0 @@
1
- # 19.06.24
2
-
3
- from .site import get_select_title
@@ -1,87 +0,0 @@
1
- # 19.06.24
2
-
3
- import sys
4
-
5
-
6
- # Internal utilities
7
- from StreamingCommunity.Util.console import console
8
-
9
-
10
- # Variable
11
- available_colors = ['red', 'magenta', 'yellow', 'cyan', 'green', 'blue', 'white']
12
- column_to_hide = ['Slug', 'Sub_ita', 'Last_air_date', 'Seasons_count', 'Url']
13
-
14
-
15
- def get_select_title(table_show_manager, media_search_manager):
16
- """
17
- Display a selection of titles and prompt the user to choose one.
18
-
19
- Returns:
20
- MediaItem: The selected media item.
21
- """
22
-
23
- # Set up table for displaying titles
24
- table_show_manager.set_slice_end(10)
25
-
26
- # Determine column_info dynamically for (search site)
27
- if not media_search_manager.media_list:
28
- console.print("\n[red]No media items available.")
29
- return None
30
-
31
- # Example of available colors for columns
32
- available_colors = ['red', 'magenta', 'yellow', 'cyan', 'green', 'blue', 'white']
33
-
34
- # Retrieve the keys of the first media item as column headers
35
- first_media_item = media_search_manager.media_list[0]
36
- column_info = {"Index": {'color': available_colors[0]}} # Always include Index with a fixed color
37
-
38
- # Assign colors to the remaining keys dynamically
39
- color_index = 1
40
- for key in first_media_item.__dict__.keys():
41
-
42
- if key.capitalize() in column_to_hide:
43
- continue
44
-
45
- if key in ('id', 'type', 'name', 'score'): # Custom prioritization of colors
46
- if key == 'type':
47
- column_info["Type"] = {'color': 'yellow'}
48
- elif key == 'name':
49
- column_info["Name"] = {'color': 'magenta'}
50
- elif key == 'score':
51
- column_info["Score"] = {'color': 'cyan'}
52
-
53
- else:
54
- column_info[key.capitalize()] = {'color': available_colors[color_index % len(available_colors)]}
55
- color_index += 1
56
-
57
- table_show_manager.add_column(column_info)
58
-
59
- # Populate the table with title information
60
- for i, media in enumerate(media_search_manager.media_list):
61
- media_dict = {'Index': str(i)}
62
-
63
- for key in first_media_item.__dict__.keys():
64
- if key.capitalize() in column_to_hide:
65
- continue
66
-
67
- # Ensure all values are strings for rich add table
68
- media_dict[key.capitalize()] = str(getattr(media, key))
69
-
70
- table_show_manager.add_tv_show(media_dict)
71
-
72
- # Run the table and handle user input
73
- last_command = table_show_manager.run(force_int_input=True, max_int_input=len(media_search_manager.media_list))
74
- table_show_manager.clear()
75
-
76
- # Handle user's quit command
77
- if last_command == "q":
78
- console.print("\n[red]Quit [white]...")
79
- sys.exit(0)
80
-
81
- # Check if the selected index is within range
82
- if 0 <= int(last_command) < len(media_search_manager.media_list):
83
- return media_search_manager.get(int(last_command))
84
-
85
- else:
86
- console.print("\n[red]Wrong index")
87
- sys.exit(0)