StreamingCommunity 1.0.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.
- StreamingCommunity/__init__.py +0 -0
- StreamingCommunity/__main__.py +6 -0
- StreamingCommunity/cli/__init__.py +7 -0
- StreamingCommunity/cli/command/global_search.py +248 -0
- StreamingCommunity/cli/run.py +453 -0
- StreamingCommunity/core/N_m3u8/__init__.py +11 -0
- StreamingCommunity/core/N_m3u8/downloader.py +488 -0
- StreamingCommunity/core/N_m3u8/models.py +117 -0
- StreamingCommunity/core/N_m3u8/parser.py +240 -0
- StreamingCommunity/core/N_m3u8/progress.py +366 -0
- StreamingCommunity/core/N_m3u8/utils.py +163 -0
- StreamingCommunity/core/N_m3u8/wrapper.py +448 -0
- StreamingCommunity/core/__init__.py +0 -0
- StreamingCommunity/core/downloader/__init__.py +14 -0
- StreamingCommunity/core/downloader/dash.py +384 -0
- StreamingCommunity/core/downloader/hls.py +271 -0
- StreamingCommunity/core/downloader/mega.py +221 -0
- StreamingCommunity/core/downloader/mp4.py +205 -0
- StreamingCommunity/core/extractors/__init__.py +12 -0
- StreamingCommunity/core/extractors/ex_mpd.py +246 -0
- StreamingCommunity/core/extractors/ex_playready.py +107 -0
- StreamingCommunity/core/extractors/ex_widevine.py +119 -0
- StreamingCommunity/core/media/__init__.py +6 -0
- StreamingCommunity/core/media/tmdb_client.py +100 -0
- StreamingCommunity/core/processors/__init__.py +9 -0
- StreamingCommunity/core/processors/capture.py +224 -0
- StreamingCommunity/core/processors/merge.py +255 -0
- StreamingCommunity/core/processors/util.py +193 -0
- StreamingCommunity/player/mediapolisvod.py +64 -0
- StreamingCommunity/player/supervideo.py +159 -0
- StreamingCommunity/player/sweetpixel.py +38 -0
- StreamingCommunity/player/vixcloud.py +376 -0
- StreamingCommunity/services/__init__.py +0 -0
- StreamingCommunity/services/_base/__init__.py +15 -0
- StreamingCommunity/services/_base/config_loader.py +60 -0
- StreamingCommunity/services/_base/episode_manager.py +353 -0
- StreamingCommunity/services/_base/loader.py +163 -0
- StreamingCommunity/services/_base/object.py +185 -0
- StreamingCommunity/services/_base/site.py +85 -0
- StreamingCommunity/services/altadefinizione/__init__.py +109 -0
- StreamingCommunity/services/altadefinizione/film.py +85 -0
- StreamingCommunity/services/altadefinizione/series.py +150 -0
- StreamingCommunity/services/altadefinizione/site.py +83 -0
- StreamingCommunity/services/altadefinizione/util/ScrapeSerie.py +126 -0
- StreamingCommunity/services/animeunity/__init__.py +103 -0
- StreamingCommunity/services/animeunity/film.py +40 -0
- StreamingCommunity/services/animeunity/serie.py +111 -0
- StreamingCommunity/services/animeunity/site.py +125 -0
- StreamingCommunity/services/animeunity/util/ScrapeSerie.py +106 -0
- StreamingCommunity/services/animeworld/__init__.py +104 -0
- StreamingCommunity/services/animeworld/film.py +60 -0
- StreamingCommunity/services/animeworld/serie.py +104 -0
- StreamingCommunity/services/animeworld/site.py +101 -0
- StreamingCommunity/services/animeworld/util/ScrapeSerie.py +89 -0
- StreamingCommunity/services/crunchyroll/__init__.py +108 -0
- StreamingCommunity/services/crunchyroll/film.py +73 -0
- StreamingCommunity/services/crunchyroll/series.py +172 -0
- StreamingCommunity/services/crunchyroll/site.py +108 -0
- StreamingCommunity/services/crunchyroll/util/ScrapeSerie.py +253 -0
- StreamingCommunity/services/crunchyroll/util/client.py +352 -0
- StreamingCommunity/services/crunchyroll/util/get_license.py +111 -0
- StreamingCommunity/services/discoveryeu/__init__.py +102 -0
- StreamingCommunity/services/discoveryeu/series.py +175 -0
- StreamingCommunity/services/discoveryeu/site.py +106 -0
- StreamingCommunity/services/discoveryeu/util/ScrapeSerie.py +166 -0
- StreamingCommunity/services/discoveryeu/util/get_license.py +177 -0
- StreamingCommunity/services/discoveryus/__init__.py +102 -0
- StreamingCommunity/services/discoveryus/series.py +157 -0
- StreamingCommunity/services/discoveryus/site.py +82 -0
- StreamingCommunity/services/discoveryus/util/ScrapeSerie.py +156 -0
- StreamingCommunity/services/discoveryus/util/get_license.py +179 -0
- StreamingCommunity/services/dmax/__init__.py +100 -0
- StreamingCommunity/services/dmax/series.py +71 -0
- StreamingCommunity/services/dmax/site.py +69 -0
- StreamingCommunity/services/foodnetwork/__init__.py +100 -0
- StreamingCommunity/services/foodnetwork/series.py +71 -0
- StreamingCommunity/services/foodnetwork/site.py +69 -0
- StreamingCommunity/services/guardaserie/__init__.py +104 -0
- StreamingCommunity/services/guardaserie/series.py +171 -0
- StreamingCommunity/services/guardaserie/site.py +61 -0
- StreamingCommunity/services/guardaserie/util/ScrapeSerie.py +149 -0
- StreamingCommunity/services/homegardentv/__init__.py +100 -0
- StreamingCommunity/services/homegardentv/series.py +70 -0
- StreamingCommunity/services/homegardentv/site.py +69 -0
- StreamingCommunity/services/ipersphera/__init__.py +97 -0
- StreamingCommunity/services/ipersphera/film.py +78 -0
- StreamingCommunity/services/ipersphera/site.py +79 -0
- StreamingCommunity/services/mediasetinfinity/__init__.py +108 -0
- StreamingCommunity/services/mediasetinfinity/film.py +63 -0
- StreamingCommunity/services/mediasetinfinity/series.py +156 -0
- StreamingCommunity/services/mediasetinfinity/site.py +85 -0
- StreamingCommunity/services/mediasetinfinity/util/ScrapeSerie.py +336 -0
- StreamingCommunity/services/mediasetinfinity/util/fix_mpd.py +64 -0
- StreamingCommunity/services/mediasetinfinity/util/get_license.py +277 -0
- StreamingCommunity/services/nove/__init__.py +100 -0
- StreamingCommunity/services/nove/series.py +71 -0
- StreamingCommunity/services/nove/site.py +69 -0
- StreamingCommunity/services/raiplay/__init__.py +108 -0
- StreamingCommunity/services/raiplay/film.py +71 -0
- StreamingCommunity/services/raiplay/series.py +170 -0
- StreamingCommunity/services/raiplay/site.py +99 -0
- StreamingCommunity/services/raiplay/util/ScrapeSerie.py +193 -0
- StreamingCommunity/services/raiplay/util/fix_mpd.py +27 -0
- StreamingCommunity/services/raiplay/util/get_license.py +30 -0
- StreamingCommunity/services/realtime/__init__.py +101 -0
- StreamingCommunity/services/realtime/series.py +163 -0
- StreamingCommunity/services/realtime/site.py +69 -0
- StreamingCommunity/services/realtime/util/ScrapeSerie.py +164 -0
- StreamingCommunity/services/realtime/util/get_license.py +63 -0
- StreamingCommunity/services/streamingcommunity/__init__.py +107 -0
- StreamingCommunity/services/streamingcommunity/film.py +74 -0
- StreamingCommunity/services/streamingcommunity/series.py +185 -0
- StreamingCommunity/services/streamingcommunity/site.py +116 -0
- StreamingCommunity/services/streamingcommunity/util/ScrapeSerie.py +142 -0
- StreamingCommunity/services/tubitv/__init__.py +107 -0
- StreamingCommunity/services/tubitv/film.py +81 -0
- StreamingCommunity/services/tubitv/series.py +170 -0
- StreamingCommunity/services/tubitv/site.py +130 -0
- StreamingCommunity/services/tubitv/util/ScrapeSerie.py +181 -0
- StreamingCommunity/services/tubitv/util/get_license.py +97 -0
- StreamingCommunity/setup/__init__.py +18 -0
- StreamingCommunity/setup/binary_paths.py +141 -0
- StreamingCommunity/setup/checker.py +140 -0
- StreamingCommunity/setup/device_install.py +180 -0
- StreamingCommunity/setup/system.py +80 -0
- StreamingCommunity/upload/__init__.py +6 -0
- StreamingCommunity/upload/update.py +91 -0
- StreamingCommunity/upload/version.py +5 -0
- StreamingCommunity/utils/__init__.py +16 -0
- StreamingCommunity/utils/config.py +462 -0
- StreamingCommunity/utils/console/__init__.py +9 -0
- StreamingCommunity/utils/console/message.py +35 -0
- StreamingCommunity/utils/console/table.py +198 -0
- StreamingCommunity/utils/http_client.py +274 -0
- StreamingCommunity/utils/os.py +204 -0
- streamingcommunity-1.0.0.dist-info/METADATA +413 -0
- streamingcommunity-1.0.0.dist-info/RECORD +141 -0
- streamingcommunity-1.0.0.dist-info/WHEEL +5 -0
- streamingcommunity-1.0.0.dist-info/entry_points.txt +2 -0
- streamingcommunity-1.0.0.dist-info/licenses/LICENSE +674 -0
- streamingcommunity-1.0.0.dist-info/top_level.txt +1 -0
|
File without changes
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
# 17.03.25
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
import logging
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# External library
|
|
8
|
+
from rich.console import Console
|
|
9
|
+
from rich.prompt import Prompt
|
|
10
|
+
from rich.table import Table
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Internal utilities
|
|
14
|
+
from StreamingCommunity.utils.console.message import start_message
|
|
15
|
+
from StreamingCommunity.services._base import load_search_functions
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Variable
|
|
19
|
+
console = Console()
|
|
20
|
+
msg = Prompt()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def global_search(search_terms: str = None, selected_sites: list = None):
|
|
24
|
+
"""
|
|
25
|
+
Perform a search across multiple sites based on selection.
|
|
26
|
+
|
|
27
|
+
Parameters:
|
|
28
|
+
search_terms (str, optional): The terms to search for. If None, will prompt the user.
|
|
29
|
+
selected_sites (list, optional): List of site aliases to search. If None, will search all sites.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
dict: Consolidated search results from all searched sites.
|
|
33
|
+
"""
|
|
34
|
+
search_functions = load_search_functions()
|
|
35
|
+
all_results = {}
|
|
36
|
+
|
|
37
|
+
if search_terms is None:
|
|
38
|
+
search_terms = msg.ask("\n[purple]Enter search terms for global search: ").strip()
|
|
39
|
+
|
|
40
|
+
# Organize sites by category for better display
|
|
41
|
+
sites_by_category = {}
|
|
42
|
+
for alias, (func, category) in search_functions.items():
|
|
43
|
+
if category not in sites_by_category:
|
|
44
|
+
sites_by_category[category] = []
|
|
45
|
+
sites_by_category[category].append((alias, func))
|
|
46
|
+
|
|
47
|
+
# If no sites are specifically selected, prompt the user
|
|
48
|
+
if selected_sites is None:
|
|
49
|
+
console.print("\n[green]Select sites to search:")
|
|
50
|
+
console.print("[cyan]1. Search all sites")
|
|
51
|
+
console.print("[cyan]2. Search by category")
|
|
52
|
+
console.print("[cyan]3. Select specific sites")
|
|
53
|
+
|
|
54
|
+
choice = msg.ask("[green]Enter your choice (1-3)", choices=["1", "2", "3"], default="1")
|
|
55
|
+
|
|
56
|
+
if choice == "1":
|
|
57
|
+
# Search all sites
|
|
58
|
+
selected_sites = list(search_functions.keys())
|
|
59
|
+
|
|
60
|
+
elif choice == "2":
|
|
61
|
+
# Search by category
|
|
62
|
+
console.print("\n[green]Select categories to search:")
|
|
63
|
+
for i, category in enumerate(sites_by_category.keys(), 1):
|
|
64
|
+
console.print(f"[cyan]{i}. {category.capitalize()}")
|
|
65
|
+
|
|
66
|
+
category_choices = msg.ask("[green]Enter category numbers separated by commas", default="1")
|
|
67
|
+
selected_categories = [list(sites_by_category.keys())[int(c.strip())-1] for c in category_choices.split(",")]
|
|
68
|
+
|
|
69
|
+
selected_sites = []
|
|
70
|
+
for category in selected_categories:
|
|
71
|
+
for alias, _ in sites_by_category.get(category, []):
|
|
72
|
+
selected_sites.append(alias)
|
|
73
|
+
|
|
74
|
+
else:
|
|
75
|
+
# Select specific sites
|
|
76
|
+
console.print("\n[green]Select specific sites to search:")
|
|
77
|
+
|
|
78
|
+
for i, (alias, _) in enumerate(search_functions.items(), 1):
|
|
79
|
+
site_name = alias.split("_")[0].capitalize()
|
|
80
|
+
console.print(f"[cyan]{i}.{site_name}")
|
|
81
|
+
|
|
82
|
+
site_choices = msg.ask("[green]Enter site numbers separated by commas", default="1")
|
|
83
|
+
selected_indices = [int(c.strip())-1 for c in site_choices.split(",")]
|
|
84
|
+
selected_sites = [list(search_functions.keys())[i] for i in selected_indices if i < len(search_functions)]
|
|
85
|
+
|
|
86
|
+
# Display progress information
|
|
87
|
+
console.print(f"\n[green]Searching for: [yellow]{search_terms}")
|
|
88
|
+
console.print(f"[green]Searching across: {len(selected_sites)} sites \n")
|
|
89
|
+
|
|
90
|
+
# Search each selected site
|
|
91
|
+
for alias in selected_sites:
|
|
92
|
+
site_name = alias.split("_")[0].capitalize()
|
|
93
|
+
console.print(f"[cyan]Search url in: {site_name}")
|
|
94
|
+
|
|
95
|
+
func, _ = search_functions[alias]
|
|
96
|
+
try:
|
|
97
|
+
# Call the search function with get_onlyDatabase=True to get database object
|
|
98
|
+
database = func(search_terms, get_onlyDatabase=True)
|
|
99
|
+
|
|
100
|
+
# Check if database has media_list attribute and it's not empty
|
|
101
|
+
if database and hasattr(database, 'media_list') and len(database.media_list) > 0:
|
|
102
|
+
# Store media_list items with additional source information
|
|
103
|
+
all_results[alias] = []
|
|
104
|
+
for element in database.media_list:
|
|
105
|
+
# Convert element to dictionary if it's an object
|
|
106
|
+
if hasattr(element, '__dict__'):
|
|
107
|
+
item_dict = element.__dict__.copy()
|
|
108
|
+
else:
|
|
109
|
+
item_dict = {} # Fallback for non-object items
|
|
110
|
+
|
|
111
|
+
# Add source information
|
|
112
|
+
item_dict['source'] = site_name
|
|
113
|
+
item_dict['source_alias'] = alias
|
|
114
|
+
all_results[alias].append(item_dict)
|
|
115
|
+
|
|
116
|
+
console.print(f"[green]Found result: {len(database.media_list)}\n")
|
|
117
|
+
|
|
118
|
+
except Exception as e:
|
|
119
|
+
console.print(f"[red]Error searching {site_name}: {str(e)}")
|
|
120
|
+
|
|
121
|
+
# Display the consolidated results
|
|
122
|
+
if all_results:
|
|
123
|
+
all_media_items = []
|
|
124
|
+
for alias, results in all_results.items():
|
|
125
|
+
for item in results:
|
|
126
|
+
all_media_items.append(item)
|
|
127
|
+
|
|
128
|
+
# Display consolidated results
|
|
129
|
+
display_consolidated_results(all_media_items, search_terms)
|
|
130
|
+
|
|
131
|
+
# Allow user to select an item
|
|
132
|
+
selected_item = select_from_consolidated_results(all_media_items)
|
|
133
|
+
if selected_item:
|
|
134
|
+
# Process the selected item - download or further actions
|
|
135
|
+
process_selected_item(selected_item, search_functions)
|
|
136
|
+
|
|
137
|
+
else:
|
|
138
|
+
console.print(f"\n[red]No results found for: [yellow]{search_terms}")
|
|
139
|
+
|
|
140
|
+
# Optionally offer to search again or return to main menu
|
|
141
|
+
if msg.ask("[green]Search again? (y/n)", choices=["y", "n"], default="y") == "y":
|
|
142
|
+
global_search()
|
|
143
|
+
|
|
144
|
+
return all_results
|
|
145
|
+
|
|
146
|
+
def display_consolidated_results(all_media_items, search_terms):
|
|
147
|
+
"""
|
|
148
|
+
Display consolidated search results from multiple sites.
|
|
149
|
+
|
|
150
|
+
Parameters:
|
|
151
|
+
all_media_items (list): List of media items from all searched sites.
|
|
152
|
+
search_terms (str): The search terms used.
|
|
153
|
+
"""
|
|
154
|
+
time.sleep(1)
|
|
155
|
+
start_message()
|
|
156
|
+
|
|
157
|
+
console.print(f"\n[green]Search results for: [yellow]{search_terms} \n")
|
|
158
|
+
|
|
159
|
+
table = Table(show_header=True, header_style="cyan")
|
|
160
|
+
table.add_column("#", style="dim", width=4)
|
|
161
|
+
table.add_column("Title", min_width=20)
|
|
162
|
+
table.add_column("Type", width=15)
|
|
163
|
+
table.add_column("Source", width=25)
|
|
164
|
+
|
|
165
|
+
for i, item in enumerate(all_media_items, 1):
|
|
166
|
+
|
|
167
|
+
# Extract values from item dict, with fallbacks if keys don't exist
|
|
168
|
+
title = item.get('title', item.get('name', 'Unknown'))
|
|
169
|
+
media_type = item.get('type', item.get('media_type', 'Unknown'))
|
|
170
|
+
source = item.get('source', 'Unknown')
|
|
171
|
+
|
|
172
|
+
table.add_row(
|
|
173
|
+
str(i),
|
|
174
|
+
str(title),
|
|
175
|
+
str(media_type),
|
|
176
|
+
str(source),
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
console.print(table)
|
|
180
|
+
|
|
181
|
+
def select_from_consolidated_results(all_media_items):
|
|
182
|
+
"""
|
|
183
|
+
Allow user to select an item from consolidated results.
|
|
184
|
+
|
|
185
|
+
Parameters:
|
|
186
|
+
all_media_items (list): List of media items from all searched sites.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
dict: The selected media item or None if no selection was made.
|
|
190
|
+
"""
|
|
191
|
+
if not all_media_items:
|
|
192
|
+
return None
|
|
193
|
+
|
|
194
|
+
max_index = len(all_media_items)
|
|
195
|
+
choice = msg.ask(
|
|
196
|
+
f"[green]Select item # (1-{max_index}) or 0 to cancel",
|
|
197
|
+
choices=[str(i) for i in range(max_index + 1)],
|
|
198
|
+
default="1",
|
|
199
|
+
show_choices=False
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
if choice == "0":
|
|
203
|
+
return None
|
|
204
|
+
|
|
205
|
+
return all_media_items[int(choice) - 1]
|
|
206
|
+
|
|
207
|
+
def process_selected_item(selected_item, search_functions):
|
|
208
|
+
"""
|
|
209
|
+
Process the selected item - download the media using the appropriate site API.
|
|
210
|
+
|
|
211
|
+
Parameters:
|
|
212
|
+
selected_item (dict): The selected media item.
|
|
213
|
+
search_functions (dict): Dictionary of search functions by alias.
|
|
214
|
+
"""
|
|
215
|
+
source_alias = selected_item.get('source_alias')
|
|
216
|
+
if not source_alias or source_alias not in search_functions:
|
|
217
|
+
console.print("[red]Error: Cannot process this item - source information missing.")
|
|
218
|
+
return
|
|
219
|
+
|
|
220
|
+
# Get the appropriate search function for this source
|
|
221
|
+
func, _ = search_functions[source_alias]
|
|
222
|
+
|
|
223
|
+
console.print(f"\n[green]Processing selection from: {selected_item.get('source')}")
|
|
224
|
+
|
|
225
|
+
# Extract necessary information to pass to the site's search function
|
|
226
|
+
item_id = None
|
|
227
|
+
for id_field in ['id', 'media_id', 'ID', 'item_id', 'url']:
|
|
228
|
+
item_id = selected_item.get(id_field)
|
|
229
|
+
if item_id:
|
|
230
|
+
break
|
|
231
|
+
|
|
232
|
+
item_type = selected_item.get('type', selected_item.get('media_type', 'unknown'))
|
|
233
|
+
item_title = selected_item.get('title', selected_item.get('name', 'Unknown'))
|
|
234
|
+
|
|
235
|
+
if item_id:
|
|
236
|
+
console.print(f"[green]Selected item: {item_title} (ID: {item_id}, Type: {item_type})")
|
|
237
|
+
|
|
238
|
+
try:
|
|
239
|
+
func(direct_item=selected_item)
|
|
240
|
+
|
|
241
|
+
except Exception as e:
|
|
242
|
+
console.print(f"[red]Error processing download: {str(e)}")
|
|
243
|
+
logging.exception("Download processing error")
|
|
244
|
+
|
|
245
|
+
else:
|
|
246
|
+
console.print("[red]Error: Item ID not found. Available fields:")
|
|
247
|
+
for key in selected_item.keys():
|
|
248
|
+
console.print(f"[yellow]- {key}: {selected_item[key]}")
|