StreamingCommunity 2.9.4__py3-none-any.whl → 2.9.5__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.
- StreamingCommunity/Api/Site/1337xx/__init__.py +26 -12
- StreamingCommunity/Api/Site/1337xx/site.py +2 -1
- StreamingCommunity/Api/Site/altadefinizione/__init__.py +64 -17
- StreamingCommunity/Api/Site/altadefinizione/film.py +31 -1
- StreamingCommunity/Api/Site/altadefinizione/series.py +53 -8
- StreamingCommunity/Api/Site/altadefinizione/site.py +22 -4
- StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py +2 -2
- StreamingCommunity/Api/Site/animeunity/__init__.py +53 -32
- StreamingCommunity/Api/Site/animeunity/film_serie.py +5 -1
- StreamingCommunity/Api/Site/animeunity/site.py +0 -2
- StreamingCommunity/Api/Site/cb01new/__init__.py +26 -14
- StreamingCommunity/Api/Site/cb01new/site.py +7 -5
- StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +26 -15
- StreamingCommunity/Api/Site/guardaserie/__init__.py +23 -11
- StreamingCommunity/Api/Site/guardaserie/site.py +2 -1
- StreamingCommunity/Api/Site/mostraguarda/__init__.py +27 -7
- StreamingCommunity/Api/Site/streamingcommunity/__init__.py +50 -27
- StreamingCommunity/Api/Site/streamingcommunity/series.py +5 -1
- StreamingCommunity/Api/Site/streamingcommunity/site.py +4 -0
- StreamingCommunity/Lib/Downloader/HLS/segments.py +1 -1
- StreamingCommunity/Lib/Downloader/MP4/downloader.py +7 -6
- StreamingCommunity/Upload/version.py +1 -1
- StreamingCommunity/Util/config_json.py +2 -8
- StreamingCommunity/Util/table.py +12 -2
- StreamingCommunity/global_search.py +315 -0
- StreamingCommunity/run.py +27 -3
- {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.5.dist-info}/METADATA +39 -10
- {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.5.dist-info}/RECORD +32 -31
- {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.5.dist-info}/LICENSE +0 -0
- {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.5.dist-info}/WHEEL +0 -0
- {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.5.dist-info}/entry_points.txt +0 -0
- {streamingcommunity-2.9.4.dist-info → streamingcommunity-2.9.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
# 17.03.25
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import time
|
|
6
|
+
import glob
|
|
7
|
+
import logging
|
|
8
|
+
import importlib
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# External library
|
|
12
|
+
from rich.console import Console
|
|
13
|
+
from rich.prompt import Prompt
|
|
14
|
+
from rich.table import Table
|
|
15
|
+
from rich.progress import Progress
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Internal utilities
|
|
19
|
+
from StreamingCommunity.Util.message import start_message
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
# Variable
|
|
23
|
+
console = Console()
|
|
24
|
+
msg = Prompt()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# !!! DA METTERE IN COMUNE CON QUELLA DI RUN
|
|
28
|
+
def load_search_functions():
|
|
29
|
+
modules = []
|
|
30
|
+
loaded_functions = {}
|
|
31
|
+
excluded_sites = set()
|
|
32
|
+
|
|
33
|
+
# Find api home directory
|
|
34
|
+
if getattr(sys, 'frozen', False): # Modalità PyInstaller
|
|
35
|
+
base_path = os.path.join(sys._MEIPASS, "StreamingCommunity")
|
|
36
|
+
else:
|
|
37
|
+
base_path = os.path.dirname(__file__)
|
|
38
|
+
|
|
39
|
+
api_dir = os.path.join(base_path, 'Api', 'Site')
|
|
40
|
+
init_files = glob.glob(os.path.join(api_dir, '*', '__init__.py'))
|
|
41
|
+
|
|
42
|
+
# Retrieve modules and their indices
|
|
43
|
+
for init_file in init_files:
|
|
44
|
+
|
|
45
|
+
# Get folder name as module name
|
|
46
|
+
module_name = os.path.basename(os.path.dirname(init_file))
|
|
47
|
+
|
|
48
|
+
# Se il modulo è nella lista da escludere, saltalo
|
|
49
|
+
if module_name in excluded_sites:
|
|
50
|
+
continue
|
|
51
|
+
|
|
52
|
+
logging.info(f"Load module name: {module_name}")
|
|
53
|
+
|
|
54
|
+
try:
|
|
55
|
+
# Dynamically import the module
|
|
56
|
+
mod = importlib.import_module(f'StreamingCommunity.Api.Site.{module_name}')
|
|
57
|
+
|
|
58
|
+
# Get 'indice' from the module
|
|
59
|
+
indice = getattr(mod, 'indice', 0)
|
|
60
|
+
is_deprecate = bool(getattr(mod, '_deprecate', True))
|
|
61
|
+
use_for = getattr(mod, '_useFor', 'other')
|
|
62
|
+
|
|
63
|
+
if not is_deprecate:
|
|
64
|
+
modules.append((module_name, indice, use_for))
|
|
65
|
+
|
|
66
|
+
except Exception as e:
|
|
67
|
+
console.print(f"[red]Failed to import module {module_name}: {str(e)}")
|
|
68
|
+
|
|
69
|
+
# Sort modules by 'indice'
|
|
70
|
+
modules.sort(key=lambda x: x[1])
|
|
71
|
+
|
|
72
|
+
# Load search functions in the sorted order
|
|
73
|
+
for module_name, _, use_for in modules:
|
|
74
|
+
|
|
75
|
+
# Construct a unique alias for the module
|
|
76
|
+
module_alias = f'{module_name}_search'
|
|
77
|
+
|
|
78
|
+
try:
|
|
79
|
+
|
|
80
|
+
# Dynamically import the module
|
|
81
|
+
mod = importlib.import_module(f'StreamingCommunity.Api.Site.{module_name}')
|
|
82
|
+
|
|
83
|
+
# Get the search function from the module (assuming the function is named 'search' and defined in __init__.py)
|
|
84
|
+
search_function = getattr(mod, 'search')
|
|
85
|
+
|
|
86
|
+
# Add the function to the loaded functions dictionary
|
|
87
|
+
loaded_functions[module_alias] = (search_function, use_for)
|
|
88
|
+
|
|
89
|
+
except Exception as e:
|
|
90
|
+
console.print(f"[red]Failed to load search function from module {module_name}: {str(e)}")
|
|
91
|
+
|
|
92
|
+
return loaded_functions
|
|
93
|
+
|
|
94
|
+
def global_search(search_terms: str = None, selected_sites: list = None):
|
|
95
|
+
"""
|
|
96
|
+
Perform a search across multiple sites based on selection.
|
|
97
|
+
|
|
98
|
+
Parameters:
|
|
99
|
+
search_terms (str, optional): The terms to search for. If None, will prompt the user.
|
|
100
|
+
selected_sites (list, optional): List of site aliases to search. If None, will search all sites.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
dict: Consolidated search results from all searched sites.
|
|
104
|
+
"""
|
|
105
|
+
search_functions = load_search_functions()
|
|
106
|
+
all_results = {}
|
|
107
|
+
|
|
108
|
+
if search_terms is None:
|
|
109
|
+
search_terms = msg.ask("\n[purple]Enter search terms for global search: ").strip()
|
|
110
|
+
|
|
111
|
+
# Organize sites by category for better display
|
|
112
|
+
sites_by_category = {}
|
|
113
|
+
for alias, (func, category) in search_functions.items():
|
|
114
|
+
if category not in sites_by_category:
|
|
115
|
+
sites_by_category[category] = []
|
|
116
|
+
sites_by_category[category].append((alias, func))
|
|
117
|
+
|
|
118
|
+
# If no sites are specifically selected, prompt the user
|
|
119
|
+
if selected_sites is None:
|
|
120
|
+
console.print("\n[bold green]Select sites to search:[/bold green]")
|
|
121
|
+
console.print("[bold cyan]1.[/bold cyan] Search all sites")
|
|
122
|
+
console.print("[bold cyan]2.[/bold cyan] Search by category")
|
|
123
|
+
console.print("[bold cyan]3.[/bold cyan] Select specific sites")
|
|
124
|
+
|
|
125
|
+
choice = msg.ask("[green]Enter your choice (1-3)", choices=["1", "2", "3"], default="1")
|
|
126
|
+
|
|
127
|
+
if choice == "1":
|
|
128
|
+
# Search all sites
|
|
129
|
+
selected_sites = list(search_functions.keys())
|
|
130
|
+
|
|
131
|
+
elif choice == "2":
|
|
132
|
+
# Search by category
|
|
133
|
+
console.print("\n[bold green]Select categories to search:[/bold green]")
|
|
134
|
+
for i, category in enumerate(sites_by_category.keys(), 1):
|
|
135
|
+
console.print(f"[bold cyan]{i}.[/bold cyan] {category.capitalize()}")
|
|
136
|
+
|
|
137
|
+
category_choices = msg.ask("[green]Enter category numbers separated by commas", default="1")
|
|
138
|
+
selected_categories = [list(sites_by_category.keys())[int(c.strip())-1] for c in category_choices.split(",")]
|
|
139
|
+
|
|
140
|
+
selected_sites = []
|
|
141
|
+
for category in selected_categories:
|
|
142
|
+
for alias, _ in sites_by_category.get(category, []):
|
|
143
|
+
selected_sites.append(alias)
|
|
144
|
+
|
|
145
|
+
else:
|
|
146
|
+
# Select specific sites
|
|
147
|
+
console.print("\n[bold green]Select specific sites to search:[/bold green]")
|
|
148
|
+
|
|
149
|
+
for i, (alias, _) in enumerate(search_functions.items(), 1):
|
|
150
|
+
site_name = alias.split("_")[0].capitalize()
|
|
151
|
+
console.print(f"[bold cyan]{i}.[/bold cyan] {site_name}")
|
|
152
|
+
|
|
153
|
+
site_choices = msg.ask("[green]Enter site numbers separated by commas", default="1")
|
|
154
|
+
selected_indices = [int(c.strip())-1 for c in site_choices.split(",")]
|
|
155
|
+
selected_sites = [list(search_functions.keys())[i] for i in selected_indices if i < len(search_functions)]
|
|
156
|
+
|
|
157
|
+
# Display progress information
|
|
158
|
+
console.print(f"\n[bold green]Searching for:[/bold green] [yellow]{search_terms}[/yellow]")
|
|
159
|
+
console.print(f"[bold green]Searching across:[/bold green] {len(selected_sites)} sites")
|
|
160
|
+
|
|
161
|
+
with Progress() as progress:
|
|
162
|
+
search_task = progress.add_task("[cyan]Searching...", total=len(selected_sites))
|
|
163
|
+
|
|
164
|
+
# Search each selected site
|
|
165
|
+
for alias in selected_sites:
|
|
166
|
+
site_name = alias.split("_")[0].capitalize()
|
|
167
|
+
progress.update(search_task, description=f"[cyan]Searching {site_name}...")
|
|
168
|
+
|
|
169
|
+
func, _ = search_functions[alias]
|
|
170
|
+
try:
|
|
171
|
+
# Call the search function with get_onlyDatabase=True to get database object
|
|
172
|
+
database = func(search_terms, get_onlyDatabase=True)
|
|
173
|
+
|
|
174
|
+
# Check if database has media_list attribute and it's not empty
|
|
175
|
+
if database and hasattr(database, 'media_list') and len(database.media_list) > 0:
|
|
176
|
+
# Store media_list items with additional source information
|
|
177
|
+
all_results[alias] = []
|
|
178
|
+
for element in database.media_list:
|
|
179
|
+
# Convert element to dictionary if it's an object
|
|
180
|
+
if hasattr(element, '__dict__'):
|
|
181
|
+
item_dict = element.__dict__.copy()
|
|
182
|
+
else:
|
|
183
|
+
item_dict = {} # Fallback for non-object items
|
|
184
|
+
|
|
185
|
+
# Add source information
|
|
186
|
+
item_dict['source'] = site_name
|
|
187
|
+
item_dict['source_alias'] = alias
|
|
188
|
+
all_results[alias].append(item_dict)
|
|
189
|
+
|
|
190
|
+
console.print(f"[green]Found {len(database.media_list)} results from {site_name}")
|
|
191
|
+
|
|
192
|
+
except Exception as e:
|
|
193
|
+
console.print(f"[bold red]Error searching {site_name}:[/bold red] {str(e)}")
|
|
194
|
+
|
|
195
|
+
progress.update(search_task, advance=1)
|
|
196
|
+
|
|
197
|
+
# Display the consolidated results
|
|
198
|
+
if all_results:
|
|
199
|
+
all_media_items = []
|
|
200
|
+
for alias, results in all_results.items():
|
|
201
|
+
for item in results:
|
|
202
|
+
all_media_items.append(item)
|
|
203
|
+
|
|
204
|
+
# Display consolidated results
|
|
205
|
+
display_consolidated_results(all_media_items, search_terms)
|
|
206
|
+
|
|
207
|
+
# Allow user to select an item
|
|
208
|
+
selected_item = select_from_consolidated_results(all_media_items)
|
|
209
|
+
if selected_item:
|
|
210
|
+
# Process the selected item - download or further actions
|
|
211
|
+
process_selected_item(selected_item, search_functions)
|
|
212
|
+
|
|
213
|
+
else:
|
|
214
|
+
console.print(f"\n[bold red]No results found for:[/bold red] [yellow]{search_terms}[/yellow]")
|
|
215
|
+
|
|
216
|
+
# Optionally offer to search again or return to main menu
|
|
217
|
+
if msg.ask("[green]Search again? (y/n)", choices=["y", "n"], default="y") == "y":
|
|
218
|
+
global_search()
|
|
219
|
+
|
|
220
|
+
return all_results
|
|
221
|
+
|
|
222
|
+
def display_consolidated_results(all_media_items, search_terms):
|
|
223
|
+
"""
|
|
224
|
+
Display consolidated search results from multiple sites.
|
|
225
|
+
|
|
226
|
+
Parameters:
|
|
227
|
+
all_media_items (list): List of media items from all searched sites.
|
|
228
|
+
search_terms (str): The search terms used.
|
|
229
|
+
"""
|
|
230
|
+
time.sleep(1)
|
|
231
|
+
start_message()
|
|
232
|
+
|
|
233
|
+
console.print(f"\n[bold green]Search results for:[/bold green] [yellow]{search_terms}[/yellow] \n")
|
|
234
|
+
|
|
235
|
+
table = Table(show_header=True, header_style="bold cyan")
|
|
236
|
+
table.add_column("#", style="dim", width=4)
|
|
237
|
+
table.add_column("Title", min_width=20)
|
|
238
|
+
table.add_column("Type", width=15)
|
|
239
|
+
table.add_column("Source", width=25)
|
|
240
|
+
|
|
241
|
+
for i, item in enumerate(all_media_items, 1):
|
|
242
|
+
|
|
243
|
+
# Extract values from item dict, with fallbacks if keys don't exist
|
|
244
|
+
title = item.get('title', item.get('name', 'Unknown'))
|
|
245
|
+
media_type = item.get('type', item.get('media_type', 'Unknown'))
|
|
246
|
+
source = item.get('source', 'Unknown')
|
|
247
|
+
|
|
248
|
+
table.add_row(
|
|
249
|
+
str(i),
|
|
250
|
+
str(title),
|
|
251
|
+
str(media_type),
|
|
252
|
+
str(source),
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
console.print(table)
|
|
256
|
+
|
|
257
|
+
def select_from_consolidated_results(all_media_items):
|
|
258
|
+
"""
|
|
259
|
+
Allow user to select an item from consolidated results.
|
|
260
|
+
|
|
261
|
+
Parameters:
|
|
262
|
+
all_media_items (list): List of media items from all searched sites.
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
dict: The selected media item or None if no selection was made.
|
|
266
|
+
"""
|
|
267
|
+
if not all_media_items:
|
|
268
|
+
return None
|
|
269
|
+
|
|
270
|
+
max_index = len(all_media_items)
|
|
271
|
+
choice = msg.ask(
|
|
272
|
+
f"[green]Select item # (1-{max_index}) or 0 to cancel",
|
|
273
|
+
choices=[str(i) for i in range(max_index + 1)],
|
|
274
|
+
default="1",
|
|
275
|
+
show_choices=False
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
if choice == "0":
|
|
279
|
+
return None
|
|
280
|
+
|
|
281
|
+
return all_media_items[int(choice) - 1]
|
|
282
|
+
|
|
283
|
+
def process_selected_item(selected_item, search_functions):
|
|
284
|
+
"""
|
|
285
|
+
Process the selected item - download the media using the appropriate site API.
|
|
286
|
+
|
|
287
|
+
Parameters:
|
|
288
|
+
selected_item (dict): The selected media item.
|
|
289
|
+
search_functions (dict): Dictionary of search functions by alias.
|
|
290
|
+
"""
|
|
291
|
+
source_alias = selected_item.get('source_alias')
|
|
292
|
+
if not source_alias or source_alias not in search_functions:
|
|
293
|
+
console.print("[bold red]Error: Cannot process this item - source information missing.[/bold red]")
|
|
294
|
+
return
|
|
295
|
+
|
|
296
|
+
# Get the appropriate search function for this source
|
|
297
|
+
func, _ = search_functions[source_alias]
|
|
298
|
+
|
|
299
|
+
console.print(f"\n[bold green]Processing selection from:[/bold green] {selected_item.get('source')}")
|
|
300
|
+
|
|
301
|
+
# Extract necessary information to pass to the site's search function
|
|
302
|
+
item_id = selected_item.get('id', selected_item.get('media_id'))
|
|
303
|
+
item_type = selected_item.get('type', selected_item.get('media_type', 'unknown'))
|
|
304
|
+
item_title = selected_item.get('title', selected_item.get('name', 'Unknown'))
|
|
305
|
+
|
|
306
|
+
if item_id:
|
|
307
|
+
console.print(f"[bold green]Selected item:[/bold green] {item_title} (ID: {item_id}, Type: {item_type})")
|
|
308
|
+
|
|
309
|
+
# Call the site's search function with direct_item parameter to process download
|
|
310
|
+
try:
|
|
311
|
+
func(direct_item=selected_item)
|
|
312
|
+
except Exception as e:
|
|
313
|
+
console.print(f"[bold red]Error processing download:[/bold red] {str(e)}")
|
|
314
|
+
else:
|
|
315
|
+
console.print("[bold red]Error: Item ID not found.[/bold red]")
|
StreamingCommunity/run.py
CHANGED
|
@@ -18,6 +18,7 @@ from rich.prompt import Prompt
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
# Internal utilities
|
|
21
|
+
from .global_search import global_search
|
|
21
22
|
from StreamingCommunity.Util.message import start_message
|
|
22
23
|
from StreamingCommunity.Util.config_json import config_manager
|
|
23
24
|
from StreamingCommunity.Util.os import os_summary
|
|
@@ -54,6 +55,7 @@ def run_function(func: Callable[..., None], close_console: bool = False, search_
|
|
|
54
55
|
func(search_terms)
|
|
55
56
|
|
|
56
57
|
|
|
58
|
+
# !!! DA METTERE IN COMUNE CON QUELLA DI GLOBAL
|
|
57
59
|
def load_search_functions():
|
|
58
60
|
modules = []
|
|
59
61
|
loaded_functions = {}
|
|
@@ -237,6 +239,11 @@ def main(script_id = 0):
|
|
|
237
239
|
'--specific_list_subtitles', type=str, help='Comma-separated list of specific subtitle languages to download (e.g., eng,spa).'
|
|
238
240
|
)
|
|
239
241
|
|
|
242
|
+
# Add global search option
|
|
243
|
+
parser.add_argument(
|
|
244
|
+
'--global', action='store_true', help='Perform a global search across multiple sites.'
|
|
245
|
+
)
|
|
246
|
+
|
|
240
247
|
# Add arguments for search functions
|
|
241
248
|
color_map = {
|
|
242
249
|
"anime": "red",
|
|
@@ -253,6 +260,7 @@ def main(script_id = 0):
|
|
|
253
260
|
parser.add_argument(f'-{short_option}', f'--{long_option}', action='store_true', help=f'Search for {alias.split("_")[0]} on streaming platforms.')
|
|
254
261
|
|
|
255
262
|
parser.add_argument('-s', '--search', default=None, help='Search terms')
|
|
263
|
+
|
|
256
264
|
# Parse command-line arguments
|
|
257
265
|
args = parser.parse_args()
|
|
258
266
|
|
|
@@ -280,6 +288,11 @@ def main(script_id = 0):
|
|
|
280
288
|
|
|
281
289
|
config_manager.write_config()
|
|
282
290
|
|
|
291
|
+
# Check if global search is requested
|
|
292
|
+
if getattr(args, 'global'):
|
|
293
|
+
global_search(search_terms)
|
|
294
|
+
return
|
|
295
|
+
|
|
283
296
|
# Map command-line arguments to functions
|
|
284
297
|
arg_to_function = {alias: func for alias, (func, _) in search_functions.items()}
|
|
285
298
|
|
|
@@ -295,13 +308,18 @@ def main(script_id = 0):
|
|
|
295
308
|
# Create dynamic prompt message and choices
|
|
296
309
|
choice_labels = {str(i): (alias.split("_")[0].capitalize(), use_for) for i, (alias, (_, use_for)) in enumerate(search_functions.items())}
|
|
297
310
|
|
|
311
|
+
# Add global search option to the menu
|
|
312
|
+
#global_search_key = str(len(choice_labels))
|
|
313
|
+
#choice_labels[global_search_key] = ("Global Search", "all")
|
|
314
|
+
#input_to_function[global_search_key] = global_search
|
|
315
|
+
|
|
298
316
|
# Display the category legend in a single line
|
|
299
317
|
legend_text = " | ".join([f"[{color}]{category.capitalize()}[/{color}]" for category, color in color_map.items()])
|
|
300
318
|
console.print(f"\n[bold green]Category Legend:[/bold green] {legend_text}")
|
|
301
319
|
|
|
302
320
|
# Construct the prompt message with color-coded site names
|
|
303
321
|
prompt_message = "[green]Insert category [white](" + ", ".join(
|
|
304
|
-
[f"{key}: [{color_map
|
|
322
|
+
[f"{key}: [{color_map.get(label[1], 'white')}]{label[0]}[/{color_map.get(label[1], 'white')}]" for key, label in choice_labels.items()]
|
|
305
323
|
) + "[white])"
|
|
306
324
|
|
|
307
325
|
if TELEGRAM_BOT:
|
|
@@ -330,10 +348,16 @@ def main(script_id = 0):
|
|
|
330
348
|
|
|
331
349
|
# Run the corresponding function based on user input
|
|
332
350
|
if category in input_to_function:
|
|
333
|
-
|
|
351
|
+
"""if category == global_search_key:
|
|
352
|
+
# Run global search
|
|
353
|
+
run_function(input_to_function[category], search_terms=search_terms)
|
|
354
|
+
|
|
355
|
+
else:"""
|
|
356
|
+
|
|
357
|
+
# Run normal site-specific search
|
|
358
|
+
run_function(input_to_function[category], search_terms=search_terms)
|
|
334
359
|
|
|
335
360
|
else:
|
|
336
|
-
|
|
337
361
|
if TELEGRAM_BOT:
|
|
338
362
|
bot.send_message(f"Categoria non valida", None)
|
|
339
363
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: StreamingCommunity
|
|
3
|
-
Version: 2.9.
|
|
3
|
+
Version: 2.9.5
|
|
4
4
|
Home-page: https://github.com/Lovi-0/StreamingCommunity
|
|
5
5
|
Author: Lovi-0
|
|
6
6
|
Project-URL: Bug Reports, https://github.com/Lovi-0/StreamingCommunity/issues
|
|
@@ -79,6 +79,7 @@ Dynamic: requires-python
|
|
|
79
79
|
- 📥 [Download](#m3u8_download-settings)
|
|
80
80
|
- 🔍 [Parser](#m3u8_parser-settings)
|
|
81
81
|
- 📝 [Command](#command)
|
|
82
|
+
- 🔍 [Global search](#global-search)
|
|
82
83
|
- 💻 [Examples of terminal](#examples-of-terminal-usage)
|
|
83
84
|
- 🔧 [Manual domain configuration](#update-domains)
|
|
84
85
|
- 🐳 [Docker](#docker)
|
|
@@ -668,19 +669,44 @@ The API-based domain updates are currently deprecated. To use it anyway, set `us
|
|
|
668
669
|
|
|
669
670
|
Note: If `use_api` is set to `false` and no `domains.json` file is found, the script will raise an error.
|
|
670
671
|
|
|
671
|
-
|
|
672
|
+
#### 💡 Adding a New Site to the Legacy API
|
|
673
|
+
If you want to add a new site to the legacy API, just message me on the Discord server, and I'll add it!
|
|
672
674
|
|
|
673
|
-
|
|
674
|
-
* **Example:** `1` will download *Season 1* only.
|
|
675
|
+
# Global Search
|
|
675
676
|
|
|
676
|
-
|
|
677
|
-
* **Example:** `*` will download all seasons in the series.
|
|
677
|
+
You can now search across multiple streaming sites at once using the Global Search feature. This allows you to find content more efficiently without having to search each site individually.
|
|
678
678
|
|
|
679
|
-
|
|
680
|
-
* **Example:** `1-2` will download *Seasons 1 and 2*.
|
|
679
|
+
## Using Global Search
|
|
681
680
|
|
|
682
|
-
|
|
683
|
-
|
|
681
|
+
The Global Search feature provides a unified interface to search across all supported sites:
|
|
682
|
+
|
|
683
|
+
## Search Options
|
|
684
|
+
|
|
685
|
+
When using Global Search, you have three ways to select which sites to search:
|
|
686
|
+
|
|
687
|
+
1. **Search all sites** - Searches across all available streaming sites
|
|
688
|
+
2. **Search by category** - Group sites by their categories (movies, series, anime, etc.)
|
|
689
|
+
3. **Select specific sites** - Choose individual sites to include in your search
|
|
690
|
+
|
|
691
|
+
## Navigation and Selection
|
|
692
|
+
|
|
693
|
+
After performing a search:
|
|
694
|
+
|
|
695
|
+
1. Results are displayed in a consolidated table showing:
|
|
696
|
+
- Title
|
|
697
|
+
- Media type (movie, TV series, etc.)
|
|
698
|
+
- Source site
|
|
699
|
+
|
|
700
|
+
2. Select an item by number to view details or download
|
|
701
|
+
|
|
702
|
+
3. The system will automatically use the appropriate site's API to handle the download
|
|
703
|
+
|
|
704
|
+
## Command Line Arguments
|
|
705
|
+
|
|
706
|
+
The Global Search can be configured from the command line:
|
|
707
|
+
|
|
708
|
+
- `--global` - Perform a global search across multiple sites.
|
|
709
|
+
- `-s`, `--search` - Specify the search terms.
|
|
684
710
|
|
|
685
711
|
# Examples of terminal usage
|
|
686
712
|
|
|
@@ -693,6 +719,9 @@ python test_run.py --specific_list_audio ita,eng --specific_list_subtitles eng,s
|
|
|
693
719
|
|
|
694
720
|
# Keep console open after download
|
|
695
721
|
python test_run.py --not_close true
|
|
722
|
+
|
|
723
|
+
# Use global search
|
|
724
|
+
python test_run.py --global -s "cars"
|
|
696
725
|
```
|
|
697
726
|
|
|
698
727
|
# Docker
|
|
@@ -1,40 +1,41 @@
|
|
|
1
1
|
StreamingCommunity/__init__.py,sha256=Cw-N0VCg7sef1WqdtvVwrhs1zc4LoUhs5C8k7vpM1lQ,207
|
|
2
|
-
StreamingCommunity/
|
|
2
|
+
StreamingCommunity/global_search.py,sha256=1U74JtXLWDGC_r5KCsQt4kC-XRO76QIWk3QnUz-1AqY,12126
|
|
3
|
+
StreamingCommunity/run.py,sha256=tR4DxDgbaiBRPfJ0766TpEZ-u1FqzJRdWJ7GfbLNYTU,12929
|
|
3
4
|
StreamingCommunity/Api/Player/ddl.py,sha256=M_ePETCMBpIHr5K5Yb7EML5VXwqkR7vJHQcGIv4AEQw,2261
|
|
4
5
|
StreamingCommunity/Api/Player/maxstream.py,sha256=WXg8xncFXFiaUmTVXxB3NyknQtbvd0sF1eRaoDO24bU,4822
|
|
5
6
|
StreamingCommunity/Api/Player/supervideo.py,sha256=hr9QViI-XD0Dqhcx90oaH8_j0d6cxpVaf-EuCjMs6hI,5199
|
|
6
7
|
StreamingCommunity/Api/Player/vixcloud.py,sha256=NOZhW59hyBnG5FfmppcnIudAztr7seWzQBzAN3KC_3M,6317
|
|
7
8
|
StreamingCommunity/Api/Player/Helper/Vixcloud/js_parser.py,sha256=U-8QlD5kGzIk3-4t4D6QyYmiDe8UBrSuVi1YHRQb7AU,4295
|
|
8
9
|
StreamingCommunity/Api/Player/Helper/Vixcloud/util.py,sha256=QLUgbwQrpuPIVNzdBlAiEJXnd-eCj_JQFckZZEEL55w,5214
|
|
9
|
-
StreamingCommunity/Api/Site/1337xx/__init__.py,sha256=
|
|
10
|
-
StreamingCommunity/Api/Site/1337xx/site.py,sha256=
|
|
10
|
+
StreamingCommunity/Api/Site/1337xx/__init__.py,sha256=En0bGDLm9fTKuR9ApQw2V8HuFcQNRjsy8sAcgjadIfM,2041
|
|
11
|
+
StreamingCommunity/Api/Site/1337xx/site.py,sha256=WZMcCm8uoJAb16QVNeGvyQBvRqf9pi2ioMcrdECZxfg,2247
|
|
11
12
|
StreamingCommunity/Api/Site/1337xx/title.py,sha256=lGb-IbWEIfg9Eu3XIu6IfxTOjvXkFL_NO9UEZcxOAfE,1831
|
|
12
|
-
StreamingCommunity/Api/Site/altadefinizione/__init__.py,sha256=
|
|
13
|
-
StreamingCommunity/Api/Site/altadefinizione/film.py,sha256=
|
|
14
|
-
StreamingCommunity/Api/Site/altadefinizione/series.py,sha256=
|
|
15
|
-
StreamingCommunity/Api/Site/altadefinizione/site.py,sha256=
|
|
16
|
-
StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py,sha256=
|
|
17
|
-
StreamingCommunity/Api/Site/animeunity/__init__.py,sha256=
|
|
18
|
-
StreamingCommunity/Api/Site/animeunity/film_serie.py,sha256=
|
|
19
|
-
StreamingCommunity/Api/Site/animeunity/site.py,sha256=
|
|
13
|
+
StreamingCommunity/Api/Site/altadefinizione/__init__.py,sha256=dBRK4a3URd3i8IhYSXbKg6hb_lXaY8u1qJ9pDLkKKdk,3266
|
|
14
|
+
StreamingCommunity/Api/Site/altadefinizione/film.py,sha256=BOCQPA736xQPB8yn0VGke0LVLVjmNqm9AyC4FbdJFYA,4328
|
|
15
|
+
StreamingCommunity/Api/Site/altadefinizione/series.py,sha256=slS79oaGeJFam2QkIRCSeaBkJBXAUhD2wp4OleZ2FJo,7507
|
|
16
|
+
StreamingCommunity/Api/Site/altadefinizione/site.py,sha256=955zCDOOlS92xy9SC7RfHQo-6qmhXUstfnpn7WRwC0o,2709
|
|
17
|
+
StreamingCommunity/Api/Site/altadefinizione/util/ScrapeSerie.py,sha256=tdO3ebcmU-cPnJQX4L1PVPN7IHNzu4hS-hjPWo_evCk,2526
|
|
18
|
+
StreamingCommunity/Api/Site/animeunity/__init__.py,sha256=DH6ltjOAh2W5utxRYDQhhx05GcHp5-5xDhICL9DH2jk,3097
|
|
19
|
+
StreamingCommunity/Api/Site/animeunity/film_serie.py,sha256=Bi214vFB7g6jHCjCLdBT8TIpoLZRf5odFApqr5li2Io,6053
|
|
20
|
+
StreamingCommunity/Api/Site/animeunity/site.py,sha256=HagIr6UcJSsSo-AJSxzMn_W9ie8Bd8I8pktHmcSWdF0,4954
|
|
20
21
|
StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py,sha256=6Vbw5KVwUbgooGjUIRAuXr9cWSkHDkAFP7EiXF2T4OM,2709
|
|
21
|
-
StreamingCommunity/Api/Site/cb01new/__init__.py,sha256=
|
|
22
|
+
StreamingCommunity/Api/Site/cb01new/__init__.py,sha256=C-6-HDxG73xXV6FK6LnQhs5yjkJawke4nq5kBQCVjSM,2081
|
|
22
23
|
StreamingCommunity/Api/Site/cb01new/film.py,sha256=trrEGcklB6FhqpJvGaEwHI0EThK__e9O6DuknKAFNHw,1628
|
|
23
|
-
StreamingCommunity/Api/Site/cb01new/site.py,sha256=
|
|
24
|
-
StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py,sha256=
|
|
24
|
+
StreamingCommunity/Api/Site/cb01new/site.py,sha256=b_FJdSDBJma9s09IoVJo9wCNEjQckTKj2WI1lwzqcEU,2093
|
|
25
|
+
StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py,sha256=H_Z46fvmoWHfrafhlgTHouhkhDbokxCAaDRmk8d07P8,2183
|
|
25
26
|
StreamingCommunity/Api/Site/ddlstreamitaly/series.py,sha256=z3te51do5C_O77rDTR1N01aQ76BIGe5pm5i_PWJepQ4,3369
|
|
26
27
|
StreamingCommunity/Api/Site/ddlstreamitaly/site.py,sha256=ZbzGqu24jqKPARKPfyXt5wB6QPRiygXitbgVRb9B2zk,2476
|
|
27
28
|
StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py,sha256=HY8YEvzWp3sy1q07rFLXLZhGYvapA1amMZByYvs0iJM,2553
|
|
28
|
-
StreamingCommunity/Api/Site/guardaserie/__init__.py,sha256=
|
|
29
|
+
StreamingCommunity/Api/Site/guardaserie/__init__.py,sha256=_VtuSxR-6mWET-TRPg1nHhe5QWHImdnZRB8chQtGrm0,2040
|
|
29
30
|
StreamingCommunity/Api/Site/guardaserie/series.py,sha256=xXuMR9NiAtXkHrErsmXRY9IkE2FVGuhqjATYEfapb0Y,5670
|
|
30
|
-
StreamingCommunity/Api/Site/guardaserie/site.py,sha256=
|
|
31
|
+
StreamingCommunity/Api/Site/guardaserie/site.py,sha256=5aFytbQxal7elrRFiYkM-PhVA_kMP-A60jNgycXbxNE,2131
|
|
31
32
|
StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py,sha256=4sZRWm8r5X80q285hemRf7MAWeaN5yfOU6i1SjKU4Tg,3268
|
|
32
|
-
StreamingCommunity/Api/Site/mostraguarda/__init__.py,sha256=
|
|
33
|
+
StreamingCommunity/Api/Site/mostraguarda/__init__.py,sha256=RHUGgn_2uSLMHgPrCXAUqDDK6qv7PqimFr5z1mAYtrM,1933
|
|
33
34
|
StreamingCommunity/Api/Site/mostraguarda/film.py,sha256=dA7Vo9bU7g8eY8Vaj06_n2MHlKBMHh4B_MIw2sO872A,2719
|
|
34
|
-
StreamingCommunity/Api/Site/streamingcommunity/__init__.py,sha256=
|
|
35
|
+
StreamingCommunity/Api/Site/streamingcommunity/__init__.py,sha256=akhH6AVIFvDskJ_uDlcNpistwnctbDxA-YiuVgIXm0A,3267
|
|
35
36
|
StreamingCommunity/Api/Site/streamingcommunity/film.py,sha256=LaZzEQms9t7r30_PjHPgIOUkVDyotX0qFDBMKMVNSWo,2530
|
|
36
|
-
StreamingCommunity/Api/Site/streamingcommunity/series.py,sha256=
|
|
37
|
-
StreamingCommunity/Api/Site/streamingcommunity/site.py,sha256=
|
|
37
|
+
StreamingCommunity/Api/Site/streamingcommunity/series.py,sha256=KNvEw7w9HJV2ocqDQ7VmsiEkPc89HeRKC7_igFx_dn0,8415
|
|
38
|
+
StreamingCommunity/Api/Site/streamingcommunity/site.py,sha256=SoUtZDFAe-jckSpB38GJN9OY9FAJhYZPtOUAgQgEPAE,2985
|
|
38
39
|
StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py,sha256=4WU0YFPXcsBpEANMGpAsbtffu3HxCqLsiC0K6_4OlHM,4525
|
|
39
40
|
StreamingCommunity/Api/Template/__init__.py,sha256=oyfd_4_g5p5q6mxb_rKwSsudZnTM3W3kg1tLwxg-v-Q,46
|
|
40
41
|
StreamingCommunity/Api/Template/config_loader.py,sha256=2RT_0mqQmWzXM4rYaqss-yhXztYAcfNkTalFPjzv270,2056
|
|
@@ -44,8 +45,8 @@ StreamingCommunity/Api/Template/Util/__init__.py,sha256=ZWQQd6iymNFDol9HaKPhVBoR
|
|
|
44
45
|
StreamingCommunity/Api/Template/Util/manage_ep.py,sha256=FYe2DC9SXIXzlRYI7fW4ieBpfrxYzsUgt2C47tYRk7U,9252
|
|
45
46
|
StreamingCommunity/Lib/Downloader/__init__.py,sha256=JhbBh5hOnSM7VmtkxJ7zZ_FtWEC1JdnKThsSBjLV5FY,140
|
|
46
47
|
StreamingCommunity/Lib/Downloader/HLS/downloader.py,sha256=s3ZXyKsuBN3wE4Y0Y9xXuDauBPbaI9Qhgoy83IeMnbs,21590
|
|
47
|
-
StreamingCommunity/Lib/Downloader/HLS/segments.py,sha256=
|
|
48
|
-
StreamingCommunity/Lib/Downloader/MP4/downloader.py,sha256=
|
|
48
|
+
StreamingCommunity/Lib/Downloader/HLS/segments.py,sha256=4KXC4wE7EF4gWKTgUHLB_D1gnSRXvPBVlQpr486NpRo,18469
|
|
49
|
+
StreamingCommunity/Lib/Downloader/MP4/downloader.py,sha256=o-LdIdPvnHfKhmtexRlu4D7T81qj6igg-g8IiNSXSFs,7456
|
|
49
50
|
StreamingCommunity/Lib/Downloader/TOR/downloader.py,sha256=KVZxCl1VB1-OuTjUhVS5Ycog_P0vCGTfRzhZPv8O7Ps,11267
|
|
50
51
|
StreamingCommunity/Lib/FFmpeg/__init__.py,sha256=6PBsZdE1jrD2EKOVyx3JEHnyDZzVeKlPkH5T0zyfOgU,130
|
|
51
52
|
StreamingCommunity/Lib/FFmpeg/capture.py,sha256=73BEpTijksErZOu46iRxwl3idKzZ-sVXXRr4nocIGY0,5168
|
|
@@ -62,18 +63,18 @@ StreamingCommunity/Lib/TMBD/tmdb.py,sha256=byg0EFnlmd9JeLvn1N9K3QkB1KEfeMuFa7OVf
|
|
|
62
63
|
StreamingCommunity/TelegramHelp/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
63
64
|
StreamingCommunity/TelegramHelp/telegram_bot.py,sha256=Qe1__aoK4PpDuing8JtWgdHzLee8LuYYyfeLNA7yADU,26307
|
|
64
65
|
StreamingCommunity/Upload/update.py,sha256=TXWAOfvZr1So_oME11YvX_L5zRy2tM-ijF-_g1jf87o,2548
|
|
65
|
-
StreamingCommunity/Upload/version.py,sha256=
|
|
66
|
+
StreamingCommunity/Upload/version.py,sha256=tFcpeSHbzC-UvP64UbgBklbKokJ7cvOYQuZGO_DghLA,171
|
|
66
67
|
StreamingCommunity/Util/color.py,sha256=NvD0Eni-25oOOkY-szCEoc0lGvzQxyL7xhM0RE4EvUM,458
|
|
67
|
-
StreamingCommunity/Util/config_json.py,sha256=
|
|
68
|
+
StreamingCommunity/Util/config_json.py,sha256=ocf1wsC1o0Nq8UStHUwj_QryMi_2O0yPpLEAkaMZPGg,18978
|
|
68
69
|
StreamingCommunity/Util/ffmpeg_installer.py,sha256=q5yb_ZXKe9PhcG7JbKLfo1AZa8DNukgHqymPbudDuAY,13585
|
|
69
70
|
StreamingCommunity/Util/headers.py,sha256=TItkaFMx1GqsVNEIS3Tr0BGU5EHyF-HkZVliHORT3P8,308
|
|
70
71
|
StreamingCommunity/Util/logger.py,sha256=9kGD6GmWj2pM8ADpJc85o7jm8DD0c5Aguqnq-9kmxos,3314
|
|
71
72
|
StreamingCommunity/Util/message.py,sha256=SJaIPLvWeQqsIODVUKw3TgYRmBChovmlbcF6OUxqMI8,1425
|
|
72
73
|
StreamingCommunity/Util/os.py,sha256=MUGJKQbNMWeoUrnJ2Ug3hoyYlrPDqU9BY94UmiUbxfA,14858
|
|
73
|
-
StreamingCommunity/Util/table.py,sha256=
|
|
74
|
-
streamingcommunity-2.9.
|
|
75
|
-
streamingcommunity-2.9.
|
|
76
|
-
streamingcommunity-2.9.
|
|
77
|
-
streamingcommunity-2.9.
|
|
78
|
-
streamingcommunity-2.9.
|
|
79
|
-
streamingcommunity-2.9.
|
|
74
|
+
StreamingCommunity/Util/table.py,sha256=QDVCVewMQ2JIQV3yDxQEL7Ac_m7NyRmynFg11BDeSBQ,9621
|
|
75
|
+
streamingcommunity-2.9.5.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
76
|
+
streamingcommunity-2.9.5.dist-info/METADATA,sha256=I5Huc0USVCd3Z1y43tqMD_qn1wc4IQpIPiTQqbVWqMQ,24365
|
|
77
|
+
streamingcommunity-2.9.5.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
|
78
|
+
streamingcommunity-2.9.5.dist-info/entry_points.txt,sha256=Qph9XYfDC8n4LfDLOSl6gJGlkb9eFb5f-JOr_Wb_5rk,67
|
|
79
|
+
streamingcommunity-2.9.5.dist-info/top_level.txt,sha256=YsOcxKP-WOhWpIWgBlh0coll9XUx7aqmRPT7kmt3fH0,19
|
|
80
|
+
streamingcommunity-2.9.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|