mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-07 12:05:35 +00:00
Fix range for options * in series
This commit is contained in:
parent
556bdbbdf7
commit
bdc252803e
@ -93,8 +93,8 @@ You can change some behaviors by tweaking the configuration file.
|
|||||||
"M3U8": {
|
"M3U8": {
|
||||||
"tdqm_workers": 20,
|
"tdqm_workers": 20,
|
||||||
"tqdm_progress_timeout": 10,
|
"tqdm_progress_timeout": 10,
|
||||||
"minium_ts_files_in_folder": 15,
|
"minimum_ts_files_in_folder": 15,
|
||||||
"donwload_percentage": 1,
|
"download_percentage": 1,
|
||||||
"requests_timeout": 5,
|
"requests_timeout": 5,
|
||||||
"enable_time_quit": false,
|
"enable_time_quit": false,
|
||||||
"tqdm_show_progress": false,
|
"tqdm_show_progress": false,
|
||||||
@ -136,8 +136,8 @@ You can change some behaviors by tweaking the configuration file.
|
|||||||
| M3U8 | | Contains options specific to M3U8. | |
|
| M3U8 | | Contains options specific to M3U8. | |
|
||||||
| tdqm_workers | 20 | The number of workers that will cooperate to download .ts files.**A high value may slow down your PC** | 40 |
|
| tdqm_workers | 20 | The number of workers that will cooperate to download .ts files.**A high value may slow down your PC** | 40 |
|
||||||
| tqdm_progress_timeout | 10 | The timeout duration for progress display updates in seconds after quit download. | 5 |
|
| tqdm_progress_timeout | 10 | The timeout duration for progress display updates in seconds after quit download. | 5 |
|
||||||
| minium_ts_files_in_folder | 15 | The minimum number of .ts files expected in a folder. | 10 |
|
| minimum_ts_files_in_folder | 15 | The minimum number of .ts files expected in a folder. | 10 |
|
||||||
| donwload_percentage | 1 | The percentage of download completion required to consider the download complete. | 0.95 |
|
| download_percentage | 1 | The percentage of download completion required to consider the download complete. | 0.95 |
|
||||||
| requests_timeout | 5 | The timeout duration for HTTP requests in seconds. | 10 |
|
| requests_timeout | 5 | The timeout duration for HTTP requests in seconds. | 10 |
|
||||||
| enable_time_quit | false | Whether to enable quitting the download after a certain time period. | true |
|
| enable_time_quit | false | Whether to enable quitting the download after a certain time period. | true |
|
||||||
| tqdm_show_progress | false | Whether to show progress during downloads or not.**May slow down your PC** | true |
|
| tqdm_show_progress | false | Whether to show progress during downloads or not.**May slow down your PC** | true |
|
||||||
|
@ -5,6 +5,7 @@ from Src.Util.console import console, msg
|
|||||||
from Src.Util.config import config_manager
|
from Src.Util.config import config_manager
|
||||||
from Src.Util.table import TVShowManager
|
from Src.Util.table import TVShowManager
|
||||||
from Src.Util.message import start_message
|
from Src.Util.message import start_message
|
||||||
|
from Src.Util.os import remove_special_characters
|
||||||
from Src.Lib.FFmpeg.my_m3u8 import Downloader
|
from Src.Lib.FFmpeg.my_m3u8 import Downloader
|
||||||
from .Class import VideoSource
|
from .Class import VideoSource
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ video_source.set_url_base_name(STREAM_SITE_NAME)
|
|||||||
table_show_manager = TVShowManager()
|
table_show_manager = TVShowManager()
|
||||||
|
|
||||||
|
|
||||||
|
# --> LOGIC
|
||||||
def manage_selection(cmd_insert: str, max_count: int) -> list[int]:
|
def manage_selection(cmd_insert: str, max_count: int) -> list[int]:
|
||||||
"""
|
"""
|
||||||
Manage user selection for seasons to download.
|
Manage user selection for seasons to download.
|
||||||
@ -51,7 +53,7 @@ def manage_selection(cmd_insert: str, max_count: int) -> list[int]:
|
|||||||
elif cmd_insert == "*":
|
elif cmd_insert == "*":
|
||||||
list_season_select = list(range(1, max_count+1))
|
list_season_select = list(range(1, max_count+1))
|
||||||
|
|
||||||
# Return list of selected seasons
|
# Return list of selected seasons)
|
||||||
return list_season_select
|
return list_season_select
|
||||||
|
|
||||||
def display_episodes_list() -> str:
|
def display_episodes_list() -> str:
|
||||||
@ -90,6 +92,8 @@ def display_episodes_list() -> str:
|
|||||||
|
|
||||||
return last_command
|
return last_command
|
||||||
|
|
||||||
|
|
||||||
|
# --> DOWNLOAD
|
||||||
def donwload_video(tv_name: str, index_season_selected: int, index_episode_selected: int) -> None:
|
def donwload_video(tv_name: str, index_season_selected: int, index_episode_selected: int) -> None:
|
||||||
"""
|
"""
|
||||||
Download a single episode video.
|
Download a single episode video.
|
||||||
@ -106,8 +110,8 @@ def donwload_video(tv_name: str, index_season_selected: int, index_episode_selec
|
|||||||
episode_id = video_source.obj_episode_manager.episodes[index_episode_selected - 1].id
|
episode_id = video_source.obj_episode_manager.episodes[index_episode_selected - 1].id
|
||||||
|
|
||||||
# Define filename and path for the downloaded video
|
# Define filename and path for the downloaded video
|
||||||
mp4_name = f"{index_episode_selected}.mp4"
|
mp4_name = f"{index_episode_selected}_{remove_special_characters(video_source.obj_episode_manager.episodes[index_episode_selected - 1].name)}.mp4"
|
||||||
mp4_path = os.path.join(ROOT_PATH, SERIES_FOLDER, tv_name, f"S{index_season_selected}", f"E{index_episode_selected}")
|
mp4_path = os.path.join(ROOT_PATH, SERIES_FOLDER, tv_name, f"S{index_season_selected}")
|
||||||
os.makedirs(mp4_path, exist_ok=True)
|
os.makedirs(mp4_path, exist_ok=True)
|
||||||
|
|
||||||
# Get iframe and content for the episode
|
# Get iframe and content for the episode
|
||||||
@ -146,25 +150,26 @@ def donwload_episode(tv_name: str, index_season_selected: int, donwload_all: boo
|
|||||||
|
|
||||||
# Download all episodes wihtout ask
|
# Download all episodes wihtout ask
|
||||||
if donwload_all:
|
if donwload_all:
|
||||||
for i_episode in range(0, episodes_count):
|
for i_episode in range(1, episodes_count+1):
|
||||||
donwload_video(tv_name, index_season_selected, i_episode)
|
donwload_video(tv_name, index_season_selected, i_episode)
|
||||||
|
|
||||||
# Exit
|
console.print(f"\n[red]Download [yellow]season: [red]{index_season_selected}.")
|
||||||
console.print("\n[red]Done")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
# Display episodes list and manage user selection
|
# If not download all episode but a single season
|
||||||
last_command = display_episodes_list()
|
if not donwload_all:
|
||||||
list_episode_select = manage_selection(last_command, episodes_count)
|
|
||||||
|
|
||||||
# Download selected episodes
|
# Display episodes list and manage user selection
|
||||||
if len(list_episode_select) == 1 and last_command != "*":
|
last_command = display_episodes_list()
|
||||||
donwload_video(tv_name, index_season_selected, list_episode_select[0])
|
list_episode_select = manage_selection(last_command, episodes_count)
|
||||||
|
|
||||||
# Download all other episodes selecter
|
# Download selected episodes
|
||||||
else:
|
if len(list_episode_select) == 1 and last_command != "*":
|
||||||
for i_episode in list_episode_select:
|
donwload_video(tv_name, index_season_selected, list_episode_select[0])
|
||||||
donwload_video(tv_name, index_season_selected, i_episode)
|
|
||||||
|
# Download all other episodes selecter
|
||||||
|
else:
|
||||||
|
for i_episode in list_episode_select:
|
||||||
|
donwload_video(tv_name, index_season_selected, i_episode)
|
||||||
|
|
||||||
def download_series(tv_id: str, tv_name: str, version: str, domain: str) -> None:
|
def download_series(tv_id: str, tv_name: str, version: str, domain: str) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -29,18 +29,20 @@ from Src.Util.os import (
|
|||||||
compute_sha1_hash,
|
compute_sha1_hash,
|
||||||
convert_to_hex
|
convert_to_hex
|
||||||
)
|
)
|
||||||
from Src.Lib.FFmpeg.util.helper import (
|
|
||||||
print_duration_table,
|
|
||||||
transcode_with_subtitles,
|
|
||||||
join_audios,
|
|
||||||
concatenate_and_save
|
|
||||||
)
|
|
||||||
|
|
||||||
# Logic class
|
# Logic class
|
||||||
from .util.math_calc import TSFileSizeCalculator
|
from .util import (
|
||||||
from .util.url_fix import M3U8_UrlFix
|
print_duration_table,
|
||||||
from .util.decryption import M3U8_Decryption
|
concatenate_and_save,
|
||||||
from .util.parser import M3U8_Parser
|
join_audios,
|
||||||
|
transcode_with_subtitles
|
||||||
|
)
|
||||||
|
from .util import (
|
||||||
|
M3U8_Decryption,
|
||||||
|
M3U8_Ts_Files,
|
||||||
|
M3U8_Parser,
|
||||||
|
M3U8_UrlFix
|
||||||
|
)
|
||||||
|
|
||||||
# Config
|
# Config
|
||||||
Download_audio = config_manager.get_bool('M3U8_OPTIONS', 'download_audio')
|
Download_audio = config_manager.get_bool('M3U8_OPTIONS', 'download_audio')
|
||||||
@ -49,11 +51,11 @@ DOWNLOAD_SPECIFIC_AUDIO = config_manager.get_list('M3U8_OPTIONS', 'specific_list
|
|||||||
DOWNLOAD_SPECIFIC_SUBTITLE = config_manager.get_list('M3U8_OPTIONS', 'specific_list_subtitles')
|
DOWNLOAD_SPECIFIC_SUBTITLE = config_manager.get_list('M3U8_OPTIONS', 'specific_list_subtitles')
|
||||||
TQDM_MAX_WORKER = config_manager.get_int('M3U8', 'tdqm_workers')
|
TQDM_MAX_WORKER = config_manager.get_int('M3U8', 'tdqm_workers')
|
||||||
TQDM_PROGRESS_TIMEOUT = config_manager.get_int('M3U8', 'tqdm_progress_timeout')
|
TQDM_PROGRESS_TIMEOUT = config_manager.get_int('M3U8', 'tqdm_progress_timeout')
|
||||||
COMPLETED_PERCENTAGE = config_manager.get_float('M3U8', 'donwload_percentage')
|
COMPLETED_PERCENTAGE = config_manager.get_float('M3U8', 'download_percentage')
|
||||||
REQUESTS_TIMEOUT = config_manager.get_int('M3U8', 'requests_timeout')
|
REQUESTS_TIMEOUT = config_manager.get_int('M3U8', 'requests_timeout')
|
||||||
ENABLE_TIME_TIMEOUT = config_manager.get_bool('M3U8', 'enable_time_quit')
|
ENABLE_TIME_TIMEOUT = config_manager.get_bool('M3U8', 'enable_time_quit')
|
||||||
TQDM_SHOW_PROGRESS = config_manager.get_bool('M3U8', 'tqdm_show_progress')
|
TQDM_SHOW_PROGRESS = config_manager.get_bool('M3U8', 'tqdm_show_progress')
|
||||||
MIN_TS_FILES_IN_FOLDER = config_manager.get_int('M3U8', 'minium_ts_files_in_folder')
|
MIN_TS_FILES_IN_FOLDER = config_manager.get_int('M3U8', 'minimum_ts_files_in_folder')
|
||||||
REMOVE_SEGMENTS_FOLDER = config_manager.get_bool('M3U8', 'cleanup_tmp_folder')
|
REMOVE_SEGMENTS_FOLDER = config_manager.get_bool('M3U8', 'cleanup_tmp_folder')
|
||||||
|
|
||||||
# Variable
|
# Variable
|
||||||
@ -88,7 +90,7 @@ class M3U8_Segments:
|
|||||||
# Config
|
# Config
|
||||||
self.enable_timer = ENABLE_TIME_TIMEOUT
|
self.enable_timer = ENABLE_TIME_TIMEOUT
|
||||||
self.progress_timeout = TQDM_PROGRESS_TIMEOUT
|
self.progress_timeout = TQDM_PROGRESS_TIMEOUT
|
||||||
self.class_ts_files_size = TSFileSizeCalculator()
|
self.class_ts_files_size = M3U8_Ts_Files()
|
||||||
|
|
||||||
def parse_data(self, m3u8_content: str) -> None:
|
def parse_data(self, m3u8_content: str) -> None:
|
||||||
"""
|
"""
|
||||||
|
@ -1 +1,18 @@
|
|||||||
# TO DO
|
# 02.04.24
|
||||||
|
|
||||||
|
from .helper import (
|
||||||
|
has_audio_stream,
|
||||||
|
get_video_duration,
|
||||||
|
format_duration,
|
||||||
|
print_duration_table,
|
||||||
|
compute_sha1_hash,
|
||||||
|
add_subtitle,
|
||||||
|
concatenate_and_save,
|
||||||
|
join_audios,
|
||||||
|
transcode_with_subtitles
|
||||||
|
)
|
||||||
|
from .decryption import M3U8_Decryption
|
||||||
|
from .installer import check_ffmpeg
|
||||||
|
from .math_calc import M3U8_Ts_Files
|
||||||
|
from .parser import M3U8_Parser
|
||||||
|
from .url_fix import M3U8_UrlFix
|
@ -386,4 +386,4 @@ def transcode_with_subtitles(video: str, subtitles_list: list[dict[str, str]], o
|
|||||||
|
|
||||||
except ffmpeg.Error as ffmpeg_error:
|
except ffmpeg.Error as ffmpeg_error:
|
||||||
print(f"Error: {ffmpeg_error}")
|
print(f"Error: {ffmpeg_error}")
|
||||||
return ""
|
return ""
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
from Src.Util.os import format_size
|
from Src.Util.os import format_size
|
||||||
|
|
||||||
class TSFileSizeCalculator:
|
class M3U8_Ts_Files:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
Initialize the TSFileSizeCalculator object.
|
Initialize the TSFileSizeCalculator object.
|
||||||
|
@ -7,6 +7,7 @@ import time
|
|||||||
import json
|
import json
|
||||||
import hashlib
|
import hashlib
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
def remove_folder(folder_path: str) -> None:
|
def remove_folder(folder_path: str) -> None:
|
||||||
"""
|
"""
|
||||||
@ -39,14 +40,32 @@ def remove_file(file_path: str) -> None:
|
|||||||
print(f"Error removing file '{file_path}': {e}")
|
print(f"Error removing file '{file_path}': {e}")
|
||||||
#else:
|
#else:
|
||||||
# print(f"File '{file_path}' does not exist.")
|
# print(f"File '{file_path}' does not exist.")
|
||||||
|
|
||||||
|
def remove_special_characters(filename) -> str:
|
||||||
|
"""
|
||||||
|
Removes special characters from a filename to make it suitable for creating a filename in Windows.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filename (str): The original filename containing special characters.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The cleaned filename without special characters.
|
||||||
|
"""
|
||||||
|
|
||||||
def move_file_one_folder_up(file_path):
|
# Define the regex pattern to match special characters
|
||||||
|
pattern = r'[^\w\-_\. ]'
|
||||||
|
|
||||||
|
# Replace special characters with an empty string
|
||||||
|
cleaned_filename = re.sub(pattern, '', filename)
|
||||||
|
|
||||||
|
return cleaned_filename
|
||||||
|
|
||||||
|
def move_file_one_folder_up(file_path) -> None:
|
||||||
"""
|
"""
|
||||||
Move a file one folder up from its current location.
|
Move a file one folder up from its current location.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
file_path (str): Path to the file to be moved.
|
file_path (str): Path to the file to be moved.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Get the directory of the file
|
# Get the directory of the file
|
||||||
@ -79,7 +98,7 @@ def read_json(path: str):
|
|||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
def save_json(json_obj, path: str) -> (None):
|
def save_json(json_obj, path: str) -> None:
|
||||||
"""Saves JSON object to the specified file path.
|
"""Saves JSON object to the specified file path.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -90,7 +109,7 @@ def save_json(json_obj, path: str) -> (None):
|
|||||||
with open(path, 'w') as file:
|
with open(path, 'w') as file:
|
||||||
json.dump(json_obj, file, indent=4) # Adjust the indentation as needed
|
json.dump(json_obj, file, indent=4) # Adjust the indentation as needed
|
||||||
|
|
||||||
def clean_json(path: str) -> (None):
|
def clean_json(path: str) -> None:
|
||||||
"""Reads JSON data from the file, cleans it, and saves it back.
|
"""Reads JSON data from the file, cleans it, and saves it back.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -113,7 +132,7 @@ def clean_json(path: str) -> (None):
|
|||||||
# Save the modified JSON data back to the file
|
# Save the modified JSON data back to the file
|
||||||
save_json(modified_data, path)
|
save_json(modified_data, path)
|
||||||
|
|
||||||
def format_size(size_bytes: float):
|
def format_size(size_bytes: float) -> str:
|
||||||
"""
|
"""
|
||||||
Format the size in bytes into a human-readable format.
|
Format the size in bytes into a human-readable format.
|
||||||
|
|
||||||
@ -135,7 +154,7 @@ def format_size(size_bytes: float):
|
|||||||
# Round the size to two decimal places and return with the appropriate unit
|
# Round the size to two decimal places and return with the appropriate unit
|
||||||
return f"{size_bytes:.2f} {units[unit_index]}"
|
return f"{size_bytes:.2f} {units[unit_index]}"
|
||||||
|
|
||||||
def compute_sha1_hash(input_string: str) -> (str):
|
def compute_sha1_hash(input_string: str) -> str:
|
||||||
"""
|
"""
|
||||||
Computes the SHA-1 hash of the input string.
|
Computes the SHA-1 hash of the input string.
|
||||||
|
|
||||||
@ -151,7 +170,7 @@ def compute_sha1_hash(input_string: str) -> (str):
|
|||||||
# Return the hashed string
|
# Return the hashed string
|
||||||
return hashed_string
|
return hashed_string
|
||||||
|
|
||||||
def decode_bytes(bytes_data: bytes, encodings_to_try: list[str] = None) -> (str):
|
def decode_bytes(bytes_data: bytes, encodings_to_try: list[str] = None) -> str:
|
||||||
"""
|
"""
|
||||||
Decode a byte sequence using a list of encodings and return the decoded string.
|
Decode a byte sequence using a list of encodings and return the decoded string.
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
"M3U8": {
|
"M3U8": {
|
||||||
"tdqm_workers": 20,
|
"tdqm_workers": 20,
|
||||||
"tqdm_progress_timeout": 10,
|
"tqdm_progress_timeout": 10,
|
||||||
"minium_ts_files_in_folder": 15,
|
"minimum_ts_files_in_folder": 15,
|
||||||
"donwload_percentage": 1,
|
"download_percentage": 1,
|
||||||
"requests_timeout": 5,
|
"requests_timeout": 5,
|
||||||
"enable_time_quit": false,
|
"enable_time_quit": false,
|
||||||
"tqdm_show_progress": false,
|
"tqdm_show_progress": false,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user