StreamingCommunity 1.9.90__py3-none-any.whl → 2.0.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 +1 -1
- StreamingCommunity/Api/Site/altadefinizione/__init__.py +1 -1
- StreamingCommunity/Api/Site/animeunity/__init__.py +1 -1
- StreamingCommunity/Api/Site/cb01new/__init__.py +1 -1
- StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +1 -3
- StreamingCommunity/Api/Site/ddlstreamitaly/series.py +1 -1
- StreamingCommunity/Api/Site/guardaserie/__init__.py +1 -3
- StreamingCommunity/Api/Site/guardaserie/series.py +2 -2
- StreamingCommunity/Api/Site/ilcorsaronero/__init__.py +1 -1
- StreamingCommunity/Api/Site/ilcorsaronero/util/ilCorsarScraper.py +14 -6
- StreamingCommunity/Api/Site/mostraguarda/__init__.py +1 -1
- StreamingCommunity/Api/Site/mostraguarda/film.py +5 -3
- StreamingCommunity/Api/Site/streamingcommunity/__init__.py +1 -1
- StreamingCommunity/Api/Site/streamingcommunity/film.py +1 -1
- StreamingCommunity/Api/Site/streamingcommunity/series.py +1 -1
- StreamingCommunity/Api/Site/streamingcommunity/site.py +8 -7
- StreamingCommunity/Api/Template/Util/get_domain.py +12 -11
- StreamingCommunity/Lib/Downloader/HLS/downloader.py +42 -34
- StreamingCommunity/Lib/Downloader/HLS/segments.py +10 -11
- StreamingCommunity/Lib/FFmpeg/capture.py +1 -1
- StreamingCommunity/Lib/FFmpeg/util.py +1 -1
- StreamingCommunity/Lib/M3U8/decryptor.py +2 -2
- StreamingCommunity/Lib/M3U8/estimator.py +53 -25
- StreamingCommunity/Upload/update.py +2 -3
- StreamingCommunity/Upload/version.py +1 -1
- StreamingCommunity/Util/ffmpeg_installer.py +65 -28
- StreamingCommunity/Util/os.py +16 -25
- StreamingCommunity/run.py +2 -3
- {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/METADATA +73 -44
- {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/RECORD +34 -34
- {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/WHEEL +1 -1
- {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/entry_points.txt +1 -0
- {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/LICENSE +0 -0
- {StreamingCommunity-1.9.90.dist-info → StreamingCommunity-2.0.5.dist-info}/top_level.txt +0 -0
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# 20.02.24
|
|
2
|
-
|
|
3
1
|
import os
|
|
4
2
|
import time
|
|
5
3
|
import logging
|
|
@@ -34,10 +32,13 @@ class M3U8_Ts_Estimator:
|
|
|
34
32
|
self.now_downloaded_size = 0
|
|
35
33
|
self.total_segments = total_segments
|
|
36
34
|
self.lock = threading.Lock()
|
|
37
|
-
self.speed = {"upload": "N/A", "download": "N/A"}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
self.speed = {"upload": "N/A", "download": "N/A"}
|
|
36
|
+
|
|
37
|
+
# Only start the speed capture thread if TQDM_USE_LARGE_BAR is True
|
|
38
|
+
if not TQDM_USE_LARGE_BAR:
|
|
39
|
+
self.speed_thread = threading.Thread(target=self.capture_speed)
|
|
40
|
+
self.speed_thread.daemon = True
|
|
41
|
+
self.speed_thread.start()
|
|
41
42
|
|
|
42
43
|
def add_ts_file(self, size: int, size_download: int, duration: float):
|
|
43
44
|
"""
|
|
@@ -56,43 +57,71 @@ class M3U8_Ts_Estimator:
|
|
|
56
57
|
self.ts_file_sizes.append(size)
|
|
57
58
|
self.now_downloaded_size += size_download
|
|
58
59
|
|
|
59
|
-
def capture_speed(self, interval: float = 1):
|
|
60
|
+
def capture_speed(self, interval: float = 1, pid: int = None):
|
|
60
61
|
"""
|
|
61
|
-
Capture the internet speed periodically
|
|
62
|
+
Capture the internet speed periodically for a specific process (identified by PID)
|
|
63
|
+
or the entire system if no PID is provided.
|
|
62
64
|
"""
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
|
|
66
|
+
def get_network_io(process=None):
|
|
67
|
+
"""
|
|
68
|
+
Get network I/O counters for a specific process or system-wide if no process is specified.
|
|
69
|
+
"""
|
|
65
70
|
try:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
71
|
+
if process:
|
|
72
|
+
io_counters = process.io_counters()
|
|
73
|
+
return io_counters
|
|
74
|
+
else:
|
|
75
|
+
io_counters = psutil.net_io_counters()
|
|
76
|
+
return io_counters
|
|
69
77
|
except Exception as e:
|
|
70
78
|
logging.warning(f"Unable to access network I/O counters: {e}")
|
|
71
79
|
return None
|
|
72
80
|
|
|
81
|
+
# If a PID is provided, attempt to attach to the corresponding process
|
|
82
|
+
process = None
|
|
83
|
+
if pid is not None:
|
|
84
|
+
try:
|
|
85
|
+
process = psutil.Process(pid)
|
|
86
|
+
except psutil.NoSuchProcess:
|
|
87
|
+
logging.error(f"Process with PID {pid} does not exist.")
|
|
88
|
+
return
|
|
89
|
+
except Exception as e:
|
|
90
|
+
logging.error(f"Failed to attach to process with PID {pid}: {e}")
|
|
91
|
+
return
|
|
92
|
+
|
|
73
93
|
while True:
|
|
74
|
-
old_value = get_network_io()
|
|
94
|
+
old_value = get_network_io(process)
|
|
75
95
|
|
|
76
|
-
if old_value is None: # If psutil
|
|
96
|
+
if old_value is None: # If psutil fails, continue with the next interval
|
|
77
97
|
time.sleep(interval)
|
|
78
98
|
continue
|
|
79
99
|
|
|
80
100
|
time.sleep(interval)
|
|
81
|
-
new_value = get_network_io()
|
|
82
|
-
|
|
101
|
+
new_value = get_network_io(process)
|
|
102
|
+
|
|
83
103
|
if new_value is None: # Handle again if psutil fails in the next call
|
|
84
104
|
time.sleep(interval)
|
|
85
105
|
continue
|
|
86
106
|
|
|
87
107
|
with self.lock:
|
|
88
|
-
|
|
89
|
-
|
|
108
|
+
|
|
109
|
+
# Calculate speed based on process-specific counters if process is specified
|
|
110
|
+
if process:
|
|
111
|
+
upload_speed = (new_value.write_bytes - old_value.write_bytes) / interval
|
|
112
|
+
download_speed = (new_value.read_bytes - old_value.read_bytes) / interval
|
|
113
|
+
|
|
114
|
+
else:
|
|
115
|
+
# System-wide counters
|
|
116
|
+
upload_speed = (new_value.bytes_sent - old_value.bytes_sent) / interval
|
|
117
|
+
download_speed = (new_value.bytes_recv - old_value.bytes_recv) / interval
|
|
90
118
|
|
|
91
119
|
self.speed = {
|
|
92
120
|
"upload": internet_manager.format_transfer_speed(upload_speed),
|
|
93
121
|
"download": internet_manager.format_transfer_speed(download_speed)
|
|
94
122
|
}
|
|
95
123
|
|
|
124
|
+
|
|
96
125
|
def get_average_speed(self) -> float:
|
|
97
126
|
"""
|
|
98
127
|
Calculate the average internet speed.
|
|
@@ -159,18 +188,17 @@ class M3U8_Ts_Estimator:
|
|
|
159
188
|
units_file_downloaded = downloaded_file_size_str.split(' ')[1]
|
|
160
189
|
units_file_total_size = file_total_size.split(' ')[1]
|
|
161
190
|
|
|
162
|
-
average_internet_speed = self.get_average_speed()[0]
|
|
163
|
-
average_internet_unit = self.get_average_speed()[1]
|
|
164
|
-
|
|
165
191
|
# Update the progress bar's postfix
|
|
166
192
|
if TQDM_USE_LARGE_BAR:
|
|
193
|
+
average_internet_speed = self.get_average_speed()[0]
|
|
194
|
+
average_internet_unit = self.get_average_speed()[1]
|
|
167
195
|
progress_counter.set_postfix_str(
|
|
168
196
|
f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded} {Colors.WHITE}< {Colors.GREEN}{number_file_total_size} {Colors.RED}{units_file_total_size} "
|
|
169
197
|
f"{Colors.WHITE}| {Colors.CYAN}{average_internet_speed} {Colors.RED}{average_internet_unit}"
|
|
170
198
|
)
|
|
199
|
+
|
|
171
200
|
else:
|
|
172
201
|
progress_counter.set_postfix_str(
|
|
173
202
|
f"{Colors.WHITE}[ {Colors.GREEN}{number_file_downloaded}{Colors.RED} {units_file_downloaded} "
|
|
174
|
-
f"{Colors.WHITE}| {Colors.CYAN}{
|
|
175
|
-
)
|
|
176
|
-
|
|
203
|
+
f"{Colors.WHITE}| {Colors.CYAN}N/A{Colors.RED} N/A"
|
|
204
|
+
)
|
|
@@ -57,11 +57,10 @@ def update():
|
|
|
57
57
|
|
|
58
58
|
# Check installed version
|
|
59
59
|
if str(__version__).replace('v', '') != str(last_version).replace('v', '') :
|
|
60
|
-
console.print(f"[red]New version available: [yellow]{last_version}")
|
|
60
|
+
console.print(f"[red]New version available: [yellow]{last_version} \n")
|
|
61
61
|
else:
|
|
62
|
-
console.print(f"[
|
|
62
|
+
console.print(f" [yellow]Everything is up to date \n")
|
|
63
63
|
|
|
64
|
-
console.print("\n")
|
|
65
64
|
console.print(f"[red]{__title__} has been downloaded [yellow]{total_download_count} [red]times, but only [yellow]{percentual_stars}% [red]of users have starred it.\n\
|
|
66
65
|
[cyan]Help the repository grow today by leaving a [yellow]star [cyan]and [yellow]sharing [cyan]it with others online!")
|
|
67
66
|
|
|
@@ -116,21 +116,34 @@ class FFMPEGDownloader:
|
|
|
116
116
|
def _check_existing_binaries(self) -> Tuple[Optional[str], Optional[str], Optional[str]]:
|
|
117
117
|
"""
|
|
118
118
|
Check if FFmpeg binaries already exist in the base directory.
|
|
119
|
-
|
|
120
|
-
Returns:
|
|
121
|
-
Tuple[Optional[str], Optional[str], Optional[str]]: Paths to ffmpeg, ffprobe, and ffplay executables.
|
|
122
|
-
Returns None for each executable that is not found.
|
|
119
|
+
Enhanced to check both the binary directory and system paths on macOS.
|
|
123
120
|
"""
|
|
124
121
|
config = FFMPEG_CONFIGURATION[self.os_name]
|
|
125
122
|
executables = config['executables']
|
|
126
123
|
found_executables = []
|
|
127
124
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
125
|
+
# For macOS, check both binary directory and system paths
|
|
126
|
+
if self.os_name == 'darwin':
|
|
127
|
+
potential_paths = [
|
|
128
|
+
'/usr/local/bin',
|
|
129
|
+
'/opt/homebrew/bin',
|
|
130
|
+
'/usr/bin',
|
|
131
|
+
self.base_dir
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
for executable in executables:
|
|
135
|
+
found = None
|
|
136
|
+
for path in potential_paths:
|
|
137
|
+
full_path = os.path.join(path, executable)
|
|
138
|
+
if os.path.exists(full_path) and os.access(full_path, os.X_OK):
|
|
139
|
+
found = full_path
|
|
140
|
+
break
|
|
141
|
+
found_executables.append(found)
|
|
142
|
+
else:
|
|
143
|
+
# Original behavior for other operating systems
|
|
144
|
+
for executable in executables:
|
|
145
|
+
exe_paths = glob.glob(os.path.join(self.base_dir, executable))
|
|
146
|
+
found_executables.append(exe_paths[0] if exe_paths else None)
|
|
134
147
|
|
|
135
148
|
return tuple(found_executables) if len(found_executables) == 3 else (None, None, None)
|
|
136
149
|
|
|
@@ -275,37 +288,61 @@ class FFMPEGDownloader:
|
|
|
275
288
|
def check_ffmpeg() -> Tuple[Optional[str], Optional[str], Optional[str]]:
|
|
276
289
|
"""
|
|
277
290
|
Check for FFmpeg executables in the system and download them if not found.
|
|
291
|
+
Enhanced detection for macOS systems.
|
|
278
292
|
|
|
279
293
|
Returns:
|
|
280
294
|
Tuple[Optional[str], Optional[str], Optional[str]]: Paths to ffmpeg, ffprobe, and ffplay executables.
|
|
281
|
-
Returns None for each executable that couldn't be found or downloaded.
|
|
282
|
-
|
|
283
|
-
The function first checks if FFmpeg executables are available in the system PATH:
|
|
284
|
-
- On Windows, uses the 'where' command
|
|
285
|
-
- On Unix-like systems, uses 'which'
|
|
286
|
-
|
|
287
|
-
If the executables are not found in PATH, it attempts to download and install them
|
|
288
|
-
using the FFMPEGDownloader class.
|
|
289
295
|
"""
|
|
290
296
|
try:
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
297
|
+
system_platform = platform.system().lower()
|
|
298
|
+
|
|
299
|
+
# Special handling for macOS
|
|
300
|
+
if system_platform == 'darwin':
|
|
301
|
+
# Common installation paths on macOS
|
|
302
|
+
potential_paths = [
|
|
303
|
+
'/usr/local/bin', # Homebrew default
|
|
304
|
+
'/opt/homebrew/bin', # Apple Silicon Homebrew
|
|
305
|
+
'/usr/bin', # System default
|
|
306
|
+
os.path.expanduser('~/Applications/binary'), # Custom installation
|
|
307
|
+
'/Applications/binary' # Custom installation
|
|
308
|
+
]
|
|
295
309
|
|
|
296
|
-
|
|
297
|
-
|
|
310
|
+
for path in potential_paths:
|
|
311
|
+
ffmpeg_path = os.path.join(path, 'ffmpeg')
|
|
312
|
+
ffprobe_path = os.path.join(path, 'ffprobe')
|
|
313
|
+
ffplay_path = os.path.join(path, 'ffplay')
|
|
314
|
+
|
|
315
|
+
if (os.path.exists(ffmpeg_path) and os.path.exists(ffprobe_path) and
|
|
316
|
+
os.access(ffmpeg_path, os.X_OK) and os.access(ffprobe_path, os.X_OK)):
|
|
317
|
+
# Return found executables, with ffplay being optional
|
|
318
|
+
ffplay_path = ffplay_path if os.path.exists(ffplay_path) else None
|
|
319
|
+
return ffmpeg_path, ffprobe_path, ffplay_path
|
|
320
|
+
|
|
321
|
+
# Windows detection
|
|
322
|
+
elif system_platform == 'windows':
|
|
323
|
+
try:
|
|
324
|
+
ffmpeg_path = subprocess.check_output(['where', 'ffmpeg'], text=True).strip().split('\n')[0]
|
|
325
|
+
ffprobe_path = subprocess.check_output(['where', 'ffprobe'], text=True).strip().split('\n')[0]
|
|
326
|
+
ffplay_path = subprocess.check_output(['where', 'ffplay'], text=True).strip().split('\n')[0]
|
|
327
|
+
|
|
328
|
+
if ffmpeg_path and ffprobe_path:
|
|
329
|
+
return ffmpeg_path, ffprobe_path, ffplay_path
|
|
330
|
+
except subprocess.CalledProcessError:
|
|
331
|
+
pass
|
|
332
|
+
|
|
333
|
+
# Linux detection
|
|
298
334
|
else:
|
|
299
335
|
ffmpeg_path = shutil.which('ffmpeg')
|
|
300
336
|
ffprobe_path = shutil.which('ffprobe')
|
|
301
337
|
ffplay_path = shutil.which('ffplay')
|
|
302
338
|
|
|
303
|
-
if
|
|
339
|
+
if ffmpeg_path and ffprobe_path:
|
|
304
340
|
return ffmpeg_path, ffprobe_path, ffplay_path
|
|
305
|
-
|
|
341
|
+
|
|
342
|
+
# If executables were not found, attempt to download FFmpeg
|
|
306
343
|
downloader = FFMPEGDownloader()
|
|
307
344
|
return downloader.download()
|
|
308
|
-
|
|
345
|
+
|
|
309
346
|
except Exception as e:
|
|
310
|
-
logging.error(f"Error checking FFmpeg: {e}")
|
|
347
|
+
logging.error(f"Error checking or downloading FFmpeg executables: {e}")
|
|
311
348
|
return None, None, None
|
StreamingCommunity/Util/os.py
CHANGED
|
@@ -317,16 +317,13 @@ class InternManager():
|
|
|
317
317
|
def check_internet():
|
|
318
318
|
while True:
|
|
319
319
|
try:
|
|
320
|
-
httpx.get("https://www.google.com")
|
|
321
|
-
#console.log("[bold green]Internet is available![/bold green]")
|
|
320
|
+
httpx.get("https://www.google.com", timeout=15)
|
|
322
321
|
break
|
|
323
322
|
|
|
324
323
|
except urllib.error.URLError:
|
|
325
324
|
console.log("[bold red]Internet is not available. Waiting...[/bold red]")
|
|
326
325
|
time.sleep(5)
|
|
327
326
|
|
|
328
|
-
print()
|
|
329
|
-
|
|
330
327
|
|
|
331
328
|
class OsSummary:
|
|
332
329
|
|
|
@@ -353,20 +350,17 @@ class OsSummary:
|
|
|
353
350
|
console.print(f"{command[0]} not found", style="bold red")
|
|
354
351
|
sys.exit(0)
|
|
355
352
|
|
|
356
|
-
def check_ffmpeg_location(self, command: list):
|
|
353
|
+
def check_ffmpeg_location(self, command: list) -> str:
|
|
357
354
|
"""
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
Returns:
|
|
361
|
-
str: Location of FFmpeg executable or None if not found
|
|
355
|
+
Check if a specific executable (ffmpeg or ffprobe) is located using the given command.
|
|
356
|
+
Returns the path of the executable or None if not found.
|
|
362
357
|
"""
|
|
363
358
|
try:
|
|
364
|
-
result = subprocess.check_output(command,
|
|
365
|
-
return result
|
|
359
|
+
result = subprocess.check_output(command, text=True).strip()
|
|
360
|
+
return result.split('\n')[0] if result else None
|
|
366
361
|
|
|
367
362
|
except subprocess.CalledProcessError:
|
|
368
|
-
|
|
369
|
-
sys.exit(0)
|
|
363
|
+
return None
|
|
370
364
|
|
|
371
365
|
def get_library_version(self, lib_name: str):
|
|
372
366
|
"""
|
|
@@ -467,27 +461,24 @@ class OsSummary:
|
|
|
467
461
|
console.print(f"[cyan]Python[white]: [bold red]{python_version} ({python_implementation} {arch}) - {os_info} ({glibc_version})[/bold red]")
|
|
468
462
|
logging.info(f"Python: {python_version} ({python_implementation} {arch}) - {os_info} ({glibc_version})")
|
|
469
463
|
|
|
470
|
-
#
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
# Usa il comando 'which' su Unix/Linux
|
|
475
|
-
else:
|
|
476
|
-
command = 'which'
|
|
464
|
+
# Use the 'where' command on Windows and 'which' command on Unix-like systems
|
|
465
|
+
system_platform = platform.system().lower()
|
|
466
|
+
command = 'where' if system_platform == 'windows' else 'which'
|
|
477
467
|
|
|
478
|
-
# Locate ffmpeg and ffprobe from
|
|
479
|
-
if self.ffmpeg_path
|
|
468
|
+
# Locate ffmpeg and ffprobe from the PATH environment
|
|
469
|
+
if self.ffmpeg_path is not None and "binary" not in self.ffmpeg_path:
|
|
480
470
|
self.ffmpeg_path = self.check_ffmpeg_location([command, 'ffmpeg'])
|
|
481
471
|
|
|
482
|
-
if self.ffprobe_path
|
|
472
|
+
if self.ffprobe_path is not None and "binary" not in self.ffprobe_path:
|
|
483
473
|
self.ffprobe_path = self.check_ffmpeg_location([command, 'ffprobe'])
|
|
484
474
|
|
|
485
|
-
#
|
|
475
|
+
# If ffmpeg or ffprobe is not located, fall back to using the check_ffmpeg function
|
|
486
476
|
if self.ffmpeg_path is None or self.ffprobe_path is None:
|
|
487
477
|
self.ffmpeg_path, self.ffprobe_path, self.ffplay_path = check_ffmpeg()
|
|
488
478
|
|
|
479
|
+
# If still not found, print error and exit
|
|
489
480
|
if self.ffmpeg_path is None or self.ffprobe_path is None:
|
|
490
|
-
console.log("[red]
|
|
481
|
+
console.log("[red]Can't locate ffmpeg or ffprobe")
|
|
491
482
|
sys.exit(0)
|
|
492
483
|
|
|
493
484
|
ffmpeg_version = self.get_executable_version([self.ffprobe_path, '-version'])
|
StreamingCommunity/run.py
CHANGED
|
@@ -112,7 +112,7 @@ def initialize():
|
|
|
112
112
|
if platform.system() == "Windows" and "7" in platform.version():
|
|
113
113
|
os.system('mode 120, 40')
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
# Check python version
|
|
116
116
|
if sys.version_info < (3, 7):
|
|
117
117
|
console.log("[red]Install python version > 3.7.16")
|
|
118
118
|
sys.exit(0)
|
|
@@ -120,9 +120,8 @@ def initialize():
|
|
|
120
120
|
# Attempting GitHub update
|
|
121
121
|
try:
|
|
122
122
|
git_update()
|
|
123
|
-
print()
|
|
124
123
|
except:
|
|
125
|
-
console.log("[red]Error with loading github.")
|
|
124
|
+
console.log("[red]Error with loading github.")
|
|
126
125
|
|
|
127
126
|
|
|
128
127
|
def main():
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: StreamingCommunity
|
|
3
|
-
Version:
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 2.0.5
|
|
4
|
+
Summary: UNKNOWN
|
|
5
5
|
Home-page: https://github.com/Lovi-0/StreamingCommunity
|
|
6
6
|
Author: Lovi-0
|
|
7
|
+
License: UNKNOWN
|
|
7
8
|
Project-URL: Bug Reports, https://github.com/Lovi-0/StreamingCommunity/issues
|
|
8
9
|
Project-URL: Source, https://github.com/Lovi-0/StreamingCommunity
|
|
9
|
-
Keywords:
|
|
10
|
+
Keywords: streaming community
|
|
11
|
+
Platform: UNKNOWN
|
|
10
12
|
Requires-Python: >=3.8
|
|
11
13
|
Description-Content-Type: text/markdown
|
|
12
|
-
License-File: LICENSE
|
|
13
14
|
Requires-Dist: httpx
|
|
14
|
-
Requires-Dist: cffi
|
|
15
15
|
Requires-Dist: bs4
|
|
16
16
|
Requires-Dist: rich
|
|
17
17
|
Requires-Dist: tqdm
|
|
@@ -26,38 +26,67 @@ Requires-Dist: qbittorrent-api
|
|
|
26
26
|
Requires-Dist: python-qbittorrent
|
|
27
27
|
Requires-Dist: googlesearch-python
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
<p align="center">
|
|
30
|
+
<img src="https://i.ibb.co/PFnjvBc/immagine-2024-12-26-180318047.png" alt="Project Logo" width="700"/>
|
|
31
|
+
</p>
|
|
32
|
+
|
|
33
|
+
<p align="center">
|
|
34
|
+
<a href="https://pypi.org/project/streamingcommunity">
|
|
35
|
+
<img src="https://img.shields.io/pypi/v/streamingcommunity?logo=pypi&labelColor=555555&style=for-the-badge" alt="PyPI"/>
|
|
36
|
+
</a>
|
|
37
|
+
<a href="https://www.python.org">
|
|
38
|
+
<img src="https://img.shields.io/badge/Python->=3.8-3776AB?style=for-the-badge&logo=python&logoColor=white" alt="Python"/>
|
|
39
|
+
</a>
|
|
40
|
+
<a href="https://www.paypal.com/donate/?hosted_button_id=UXTWMT8P6HE2C">
|
|
41
|
+
<img src="https://img.shields.io/badge/_-Donate-red.svg?logo=githubsponsors&labelColor=555555&style=for-the-badge" alt="Donate"/>
|
|
42
|
+
</a>
|
|
43
|
+
<a href="https://github.com/Lovi-0/StreamingCommunity/blob/main/LICENSE">
|
|
44
|
+
<img src="https://img.shields.io/badge/License-GPL_3.0-blue.svg?style=for-the-badge" alt="License"/>
|
|
45
|
+
</a>
|
|
46
|
+
<a href="https://github.com/Lovi-0/StreamingCommunity/commits">
|
|
47
|
+
<img src="https://img.shields.io/github/commit-activity/m/Lovi-0/StreamingCommunity?label=commits&style=for-the-badge" alt="Commits"/>
|
|
48
|
+
</a>
|
|
49
|
+
<a href="https://github.com/Lovi-0/StreamingCommunity/commits">
|
|
50
|
+
<img src="https://img.shields.io/github/last-commit/Lovi-0/StreamingCommunity/main?label=&style=for-the-badge&display_timestamp=committer" alt="Last Commit"/>
|
|
51
|
+
</a>
|
|
52
|
+
</p>
|
|
53
|
+
|
|
54
|
+
<p align="center">
|
|
55
|
+
<a href="https://pypi.org/project/streamingcommunity">
|
|
56
|
+
<img src="https://img.shields.io/pypi/dm/streamingcommunity?style=for-the-badge" alt="PyPI Downloads"/>
|
|
57
|
+
</a>
|
|
58
|
+
<a href="https://github.com/Lovi-0/StreamingCommunity/network/members">
|
|
59
|
+
<img src="https://img.shields.io/github/forks/Lovi-0/StreamingCommunity?style=for-the-badge" alt="Forks"/>
|
|
60
|
+
</a>
|
|
61
|
+
<a href="https://github.com/Lovi-0/StreamingCommunity">
|
|
62
|
+
<img src="https://img.shields.io/github/languages/code-size/Lovi-0/StreamingCommunity?style=for-the-badge" alt="Code Size"/>
|
|
63
|
+
</a>
|
|
64
|
+
<a href="https://github.com/Lovi-0/StreamingCommunity">
|
|
65
|
+
<img src="https://img.shields.io/github/repo-size/Lovi-0/StreamingCommunity?style=for-the-badge" alt="Repo Size"/>
|
|
66
|
+
</a>
|
|
67
|
+
</p>
|
|
38
68
|
|
|
39
69
|
# 📋 Table of Contents
|
|
40
70
|
|
|
41
|
-
- [Website available](#website-status)
|
|
42
|
-
- [Installation](#installation)
|
|
43
|
-
- [PyPI Installation](#1-pypi-installation)
|
|
44
|
-
- [Automatic Installation](#2-automatic-installation)
|
|
45
|
-
- [Manual Installation](#3-manual-installation)
|
|
46
|
-
- [Win 7](https://github.com/Ghost6446/StreamingCommunity_api/wiki/Installation#win-7)
|
|
47
|
-
- [Termux](https://github.com/Ghost6446/StreamingCommunity_api/wiki/Termux)
|
|
48
|
-
- [Configuration](#configuration)
|
|
49
|
-
- [Default](#default-settings)
|
|
50
|
-
- [Request](#requests-settings)
|
|
51
|
-
- [Download](#m3u8_download-settings)
|
|
52
|
-
- [Parser](#m3u8_parser-settings)
|
|
53
|
-
- [Docker](#docker)
|
|
54
|
-
- [Tutorial](#tutorials)
|
|
55
|
-
- [To
|
|
56
|
-
- [Support](#support)
|
|
57
|
-
- [Contribute](#contributing)
|
|
58
|
-
- [
|
|
59
|
-
|
|
60
|
-
|
|
71
|
+
- 🌐 [Website available](#website-status)
|
|
72
|
+
- 🛠️ [Installation](#installation)
|
|
73
|
+
- 📦 [PyPI Installation](#1-pypi-installation)
|
|
74
|
+
- 🔄 [Automatic Installation](#2-automatic-installation)
|
|
75
|
+
- 📝 [Manual Installation](#3-manual-installation)
|
|
76
|
+
- 💻 [Win 7](https://github.com/Ghost6446/StreamingCommunity_api/wiki/Installation#win-7)
|
|
77
|
+
- 📱 [Termux](https://github.com/Ghost6446/StreamingCommunity_api/wiki/Termux)
|
|
78
|
+
- ⚙️ [Configuration](#configuration)
|
|
79
|
+
- 🔧 [Default](#default-settings)
|
|
80
|
+
- 📩 [Request](#requests-settings)
|
|
81
|
+
- 📥 [Download](#m3u8_download-settings)
|
|
82
|
+
- 🔍 [Parser](#m3u8_parser-settings)
|
|
83
|
+
- 🐳 [Docker](#docker)
|
|
84
|
+
- 🎓 [Tutorial](#tutorials)
|
|
85
|
+
- 📝 [To do](#to-do)
|
|
86
|
+
- 💬 [Support](#support)
|
|
87
|
+
- 🤝 [Contribute](#contributing)
|
|
88
|
+
- ⚠️ [Disclaimer](#disclaimer)
|
|
89
|
+
- ⚡ [Contributors](#contributors)
|
|
61
90
|
|
|
62
91
|
# Installation
|
|
63
92
|
|
|
@@ -226,7 +255,7 @@ The configuration file is divided into several main sections:
|
|
|
226
255
|
* `%(episode)` : Is the number of the episode
|
|
227
256
|
* `%(episode_name)` : Is the name of the episode
|
|
228
257
|
`<br/><br/>`
|
|
229
|
-
|
|
258
|
+
|
|
230
259
|
- `not_close`: If true, continues running after downloading
|
|
231
260
|
|
|
232
261
|
### qBittorrent Configuration
|
|
@@ -330,10 +359,8 @@ forced-ita hin - Hindi pol - Polish tur - Turkish
|
|
|
330
359
|
|
|
331
360
|
<br>
|
|
332
361
|
|
|
333
|
-
|
|
334
362
|
# COMMAND
|
|
335
363
|
|
|
336
|
-
|
|
337
364
|
- Download a specific season by entering its number.
|
|
338
365
|
* **Example:** `1` will download *Season 1* only.
|
|
339
366
|
|
|
@@ -404,13 +431,7 @@ The `run-container` command mounts also the `config.json` file, so any change to
|
|
|
404
431
|
|
|
405
432
|
# To Do
|
|
406
433
|
|
|
407
|
-
-
|
|
408
|
-
|
|
409
|
-
# Support
|
|
410
|
-
|
|
411
|
-
If you'd like to support this project, consider making a donation!
|
|
412
|
-
|
|
413
|
-
[](https://www.paypal.com/donate/?hosted_button_id=UXTWMT8P6HE2C)
|
|
434
|
+
- Finish [website API](https://github.com/Lovi-0/StreamingCommunity/tree/test_gui_1)
|
|
414
435
|
|
|
415
436
|
# Contributing
|
|
416
437
|
|
|
@@ -425,3 +446,11 @@ Contributions are welcome! Steps:
|
|
|
425
446
|
# Disclaimer
|
|
426
447
|
|
|
427
448
|
This software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
|
|
449
|
+
|
|
450
|
+
## Contributors
|
|
451
|
+
|
|
452
|
+
<a href="https://github.com/Lovi-0/StreamingCommunity/graphs/contributors" alt="View Contributors">
|
|
453
|
+
<img src="https://contrib.rocks/image?repo=Lovi-0/StreamingCommunity&max=1000&columns=10" alt="Contributors" />
|
|
454
|
+
</a>
|
|
455
|
+
|
|
456
|
+
|