Fix range for options * in series

This commit is contained in:
Ghost 2024-04-02 14:47:32 +02:00
parent 556bdbbdf7
commit bdc252803e
8 changed files with 89 additions and 46 deletions

View File

@ -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 |

View File

@ -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:
""" """

View File

@ -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:
""" """

View File

@ -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

View File

@ -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.

View File

@ -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:
""" """
@ -40,13 +41,31 @@ def remove_file(file_path: str) -> None:
#else: #else:
# print(f"File '{file_path}' does not exist.") # print(f"File '{file_path}' does not exist.")
def move_file_one_folder_up(file_path): 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.
"""
# 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.

View File

@ -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,