Add config.ini, backup path

This commit is contained in:
Helper 2024-04-11 10:41:55 +02:00
parent d942613dd8
commit 5d6a42d3d5
8 changed files with 258 additions and 66 deletions

View File

@ -69,50 +69,6 @@ python3 update.py
You can change some behaviors by tweaking the configuration file. You can change some behaviors by tweaking the configuration file.
```json
{
"DEFAULT": {
"debug": false,
"get_info": false,
"show_message": true,
"clean_console": true,
"get_moment_title": false,
"root_path": "videos",
"movies_folder_name": "Movies",
"series_folder_name": "Series",
"anime_folder_name": "Anime",
"not_close": false,
"swith_anime": false
},
"SITE": {
"streaming_site_name": "streamingcommunity",
"streaming_domain": "forum",
"anime_site_name": "animeunity",
"anime_domain": "to"
},
"M3U8": {
"tdqm_workers": 20,
"tqdm_progress_timeout": 10,
"minimum_ts_files_in_folder": 15,
"download_percentage": 1,
"requests_timeout": 5,
"enable_time_quit": false,
"tqdm_show_progress": false,
"cleanup_tmp_folder": true
},
"M3U8_OPTIONS": {
"download_audio": true,
"download_subtitles": true,
"specific_list_audio": [
"ita"
],
"specific_list_subtitles": [
"eng"
],
"map_episode_name": "%(tv_name)_S%(season)E%(episode)_%(episode_name)",
}
}
```
#### Options #### Options
@ -140,6 +96,8 @@ You can change some behaviors by tweaking the configuration file.
| minimum_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 |
| download_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 |
| use_openssl | false | Indicates whether OpenSSL should be utilized for encryption during the conversion of TS files with key and IV. | true |
| use_codecs | false | Specifies whether specific codecs (e.g., h264 for video, AAC for audio) should be used for converting TS files to MP4. | true |
| 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 |
| cleanup_tmp_folder | true | Whether to clean up temporary folders after processing or not. | false | | cleanup_tmp_folder | true | Whether to clean up temporary folders after processing or not. | false |
@ -159,9 +117,6 @@ You can change some behaviors by tweaking the configuration file.
* Windows: `C:\\MyLibrary\\Folder` or `\\\\MyServer\\MyLibrary` (if you want to use a network folder). * Windows: `C:\\MyLibrary\\Folder` or `\\\\MyServer\\MyLibrary` (if you want to use a network folder).
* Linux/MacOS: `Desktop/MyLibrary/Folder` * Linux/MacOS: `Desktop/MyLibrary/Folder`
## Tutorial
For a detailed walkthrough, refer to the [video tutorial](https://www.youtube.com/watch?v=Ok7hQCgxqLg&ab_channel=Nothing)
#### Episode name usage: #### Episode name usage:
You can choose different vars: You can choose different vars:
* `%(tv_name)` : Is the name of TV Show * `%(tv_name)` : Is the name of TV Show
@ -169,3 +124,6 @@ You can choose different vars:
* `%(episode)` : Is the number of the episode * `%(episode)` : Is the number of the episode
* `%(episode_name)` : Is the name of the episode * `%(episode_name)` : Is the name of the episode
>NOTE: You don't need to add .mp4 at the end >NOTE: You don't need to add .mp4 at the end
## Tutorial
For a detailed walkthrough, refer to the [video tutorial](https://www.youtube.com/watch?v=Ok7hQCgxqLg&ab_channel=Nothing)

View File

@ -19,7 +19,7 @@ from Src.Util.config import config_manager
# Variable # Variable
DEBUG_MODE = config_manager.get_bool("DEFAULT", "debug") DEBUG_MODE = config_manager.get_bool("DEFAULT", "debug")
DEBUG_FFMPEG = "debug" if DEBUG_MODE else "error" DEBUG_FFMPEG = "debug" if DEBUG_MODE else "error"
USE_CODECS = False USE_CODECS = config_manager.get_bool("M3U8", "use_codecs")

View File

@ -146,17 +146,20 @@ def move_ffmpeg_exe_to_top_level(install_dir: str) -> None:
raise raise
def add_install_dir_to_environment_path(install_dir: str) -> None: def add_install_dir_to_environment_path(install_dir: str) -> None:
''' """
Add the install directory to the environment PATH variable. Add the install directory to the environment PATH variable.
Args: Args:
install_dir (str): The directory to be added to the environment PATH variable. install_dir (str): The directory to be added to the environment PATH variable.
''' """
install_dir = os.path.abspath(os.path.join(install_dir, 'bin')) install_dir = os.path.abspath(os.path.join(install_dir, 'bin'))
set_env_path(install_dir) set_env_path(install_dir)
def download_ffmpeg(): def download_ffmpeg():
"""
Main function to donwload ffmpeg and add to win path
"""
# Get FFMPEG download URL # Get FFMPEG download URL
ffmpeg_url = get_ffmpeg_download_url() ffmpeg_url = get_ffmpeg_download_url()
@ -189,13 +192,16 @@ def download_ffmpeg():
logging.info(f'Adding {install_dir} to environment PATH variable') logging.info(f'Adding {install_dir} to environment PATH variable')
add_install_dir_to_environment_path(install_dir) add_install_dir_to_environment_path(install_dir)
def check_ffmpeg(): def check_ffmpeg() -> bool:
""" """
Check if FFmpeg is installed and available on the system PATH. Check if FFmpeg is installed and available on the system PATH.
This function checks if FFmpeg is installed and available on the system PATH. This function checks if FFmpeg is installed and available on the system PATH.
If FFmpeg is found, it prints its version. If not found, it attempts to download If FFmpeg is found, it prints its version. If not found, it attempts to download
FFmpeg and add it to the system PATH. FFmpeg and add it to the system PATH.
Returns:
bool: If ffmpeg is present or not
""" """
console.print("[green]Checking FFmpeg...") console.print("[green]Checking FFmpeg...")
@ -209,6 +215,8 @@ def check_ffmpeg():
if show_version: if show_version:
get_version() get_version()
return True
except: except:
try: try:
@ -225,3 +233,5 @@ def check_ffmpeg():
console.print("[red]Unable to download or add FFmpeg to the PATH.[/red]") console.print("[red]Unable to download or add FFmpeg to the PATH.[/red]")
console.print(f"Error: {e}") console.print(f"Error: {e}")
raise raise
return False

188
Src/Util/_tmpConfig.py Normal file
View File

@ -0,0 +1,188 @@
# 11.04.24
import os
import tempfile
import configparser
import logging
import json
from typing import Union, List
# Costant
repo_name = "StreamingCommunity_api"
config_file_name = f"{repo_name}_config.ini"
class ConfigError(Exception):
"""
Exception raised for errors related to configuration management.
"""
def __init__(self, message: str):
"""
Initialize ConfigError with the given error message.
Args:
message (str): The error message.
"""
self.message = message
super().__init__(self.message)
logging.error(self.message)
class ConfigManager:
"""
Class to manage configuration settings using a config file.
"""
def __init__(self, config_file_name: str = config_file_name, defaults: dict = None):
"""
Initialize ConfigManager.
Args:
config_file_name (str, optional): The name of the configuration file. Default is 'config.ini'.
defaults (dict, optional): A dictionary containing default values for variables. Default is None.
"""
self.config_file_path = os.path.join(tempfile.gettempdir(), config_file_name)
self.config = configparser.ConfigParser()
self.logger = logging.getLogger(__name__)
# Create config file if it doesn't exist
if not os.path.exists(self.config_file_path):
with open(self.config_file_path, 'w') as config_file:
if defaults:
for section, options in defaults.items():
if not self.config.has_section(section):
self.config.add_section(section)
for key, value in options.items():
self.config.set(section, key, str(value))
self.config.write(config_file)
# Read existing config
self.config.read(self.config_file_path)
def _check_section_and_key(self, section: str, key: str) -> None:
"""
Check if the given section and key exist in the configuration file.
Args:
section (str): The section in the config file.
key (str): The key of the variable.
Raises:
ConfigError: If the section or key does not exist.
"""
if not self.config.has_section(section):
raise ConfigError(f"Section '{section}' does not exist in the configuration file.")
if not self.config.has_option(section, key):
raise ConfigError(f"Key '{key}' does not exist in section '{section}'.")
def get_int(self, section: str, key: str, default: Union[int, None] = None) -> Union[int, None]:
"""
Get the value of a variable from the config file as an integer.
Args:
section (str): The section in the config file.
key (str): The key of the variable.
default (int, optional): Default value if the variable doesn't exist. Default is None.
Returns:
int or None: Value of the variable as an integer or default value.
"""
try:
self._check_section_and_key(section, key)
return int(self.config.get(section, key))
except (ConfigError, ValueError):
return default
def get_string(self, section: str, key: str, default: Union[str, None] = None) -> Union[str, None]:
"""
Get the value of a variable from the config file as a string.
Args:
section (str): The section in the config file.
key (str): The key of the variable.
default (str, optional): Default value if the variable doesn't exist. Default is None.
Returns:
str or None: Value of the variable as a string or default value.
"""
try:
self._check_section_and_key(section, key)
return self.config.get(section, key)
except ConfigError:
return default
def get_bool(self, section: str, key: str, default: Union[bool, None] = None) -> Union[bool, None]:
"""
Get the value of a variable from the config file as a boolean.
Args:
section (str): The section in the config file.
key (str): The key of the variable.
default (bool, optional): Default value if the variable doesn't exist. Default is None.
Returns:
bool or None: Value of the variable as a boolean or default value.
"""
try:
self._check_section_and_key(section, key)
return self.config.getboolean(section, key)
except ConfigError:
return default
def get_list(self, section: str, key: str, default: Union[List, None] = None) -> Union[List, None]:
"""
Get the value of a variable from the config file as a list.
Args:
section (str): The section in the config file.
key (str): The key of the variable.
default (List, optional): Default value if the variable doesn't exist. Default is None.
Returns:
List or None: Value of the variable as a list or default value.
"""
try:
self._check_section_and_key(section, key)
value = self.config.get(section, key)
return json.loads(value)
except (ConfigError, json.JSONDecodeError):
return default
def add_variable(self, section: str, key: str, value: Union[int, str, bool, List]) -> None:
"""
Add or update a variable in the config file.
Args:
section (str): The section in the config file.
key (str): The key of the variable.
value (int, str, bool, List): The value of the variable.
"""
if not self.config.has_section(section):
self.config.add_section(section)
self.config.set(section, key, str(value))
with open(self.config_file_path, 'w') as config_file:
self.config.write(config_file)
self.logger.info(f"Added or updated variable '{key}' in section '{section}'")
def reload_config(self) -> None:
"""
Reload the configuration from the file.
"""
self.config.clear()
self.config.read(self.config_file_path)
self.logger.info("Configuration file reloaded")
# Output
defaults = {
'Requirements': {
'ffmpeg': False
},
'Backup' : {
'path': False
}
}
temp_config_manager = ConfigManager(defaults=defaults)

View File

@ -1,9 +1,5 @@
# 07.04.24 # 07.04.24
# to do
# run somehwere backup
# add config to trace if ffmpeg is install, using config in local or temp
import platform import platform
import os import os
import logging import logging
@ -98,16 +94,23 @@ def backup_path():
original_path = get_env("Path") original_path = get_env("Path")
try: try:
script_dir = os.path.dirname(__file__)
# Create backup dir
script_dir = os.path.join(os.path.expanduser("~"), "Backup")
os.makedirs(script_dir, exist_ok=True)
backup_file = os.path.join(script_dir, "path_backup.txt") backup_file = os.path.join(script_dir, "path_backup.txt")
with open(backup_file, "w") as f: # Check if backup file exist
for path in original_path.split("\n"): if not os.path.exists(backup_file):
if len(path) > 3:
f.write(f"{path}; \n")
logging.info("Backup of PATH variable created.") with open(backup_file, "w") as f:
print("Backup of PATH variable created.") for path in original_path.split("\n"):
if len(path) > 3:
f.write(f"{path}; \n")
logging.info("Backup of PATH variable created.")
print("Backup of PATH variable created.")
except Exception as e: except Exception as e:
logging.error(f"Failed to create backup of PATH variable: {e}") logging.error(f"Failed to create backup of PATH variable: {e}")

View File

@ -1,9 +1,17 @@
# 10.04.24
# Internal utilities
from Src.Lib.Unidecode import transliterate from Src.Lib.Unidecode import transliterate
from Src.Util.config import config_manager from Src.Util.config import config_manager
from Src.Api.Class.EpisodeType import Episode
# Config
map_episode = config_manager.get('M3U8_OPTIONS', 'map_episode_name') map_episode = config_manager.get('M3U8_OPTIONS', 'map_episode_name')
def map_episode_title(tv_name: str, episode, number_season: int):
def map_episode_title(tv_name: str, episode: Episode, number_season: int):
""" """
Maps the episode title to a specific format. Maps the episode title to a specific format.
@ -15,9 +23,11 @@ def map_episode_title(tv_name: str, episode, number_season: int):
Returns: Returns:
str: The mapped episode title. str: The mapped episode title.
""" """
map_episode_temp = map_episode map_episode_temp = map_episode
map_episode_temp = map_episode_temp.replace("%(tv_name)", tv_name) map_episode_temp = map_episode_temp.replace("%(tv_name)", tv_name)
map_episode_temp = map_episode_temp.replace("%(season)", str(number_season).zfill(2)) map_episode_temp = map_episode_temp.replace("%(season)", str(number_season).zfill(2))
map_episode_temp = map_episode_temp.replace("%(episode)", str(episode.number).zfill(2)) map_episode_temp = map_episode_temp.replace("%(episode)", str(episode.number).zfill(2))
map_episode_temp = map_episode_temp.replace("%(episode_name)", episode.name) map_episode_temp = map_episode_temp.replace("%(episode_name)", episode.name)
return transliterate(map_episode_temp) return transliterate(map_episode_temp)

View File

@ -27,6 +27,7 @@
"download_percentage": 1, "download_percentage": 1,
"requests_timeout": 5, "requests_timeout": 5,
"use_openssl": false, "use_openssl": false,
"use_codecs": false,
"enable_time_quit": false, "enable_time_quit": false,
"tqdm_show_progress": false, "tqdm_show_progress": false,
"cleanup_tmp_folder": true "cleanup_tmp_folder": true

26
run.py
View File

@ -19,13 +19,15 @@ from Src.Api import (
from Src.Util.message import start_message from Src.Util.message import start_message
from Src.Util.console import console, msg from Src.Util.console import console, msg
from Src.Util.config import config_manager from Src.Util.config import config_manager
from Src.Util._tmpConfig import temp_config_manager
from Src.Util._win32 import backup_path
from Src.Util.os import remove_folder, remove_file from Src.Util.os import remove_folder, remove_file
from Src.Upload.update import update as git_update from Src.Upload.update import update as git_update
from Src.Lib.FFmpeg import check_ffmpeg from Src.Lib.FFmpeg import check_ffmpeg
from Src.Util.logger import Logger from Src.Util.logger import Logger
# Variable # Config
DEBUG_MODE = config_manager.get_bool("DEFAULT", "debug") DEBUG_MODE = config_manager.get_bool("DEFAULT", "debug")
DEBUG_GET_ALL_INFO = config_manager.get_bool('DEFAULT', 'get_info') DEBUG_GET_ALL_INFO = config_manager.get_bool('DEFAULT', 'get_info')
SWITCH_TO = config_manager.get_bool('DEFAULT', 'swith_anime') SWITCH_TO = config_manager.get_bool('DEFAULT', 'swith_anime')
@ -41,6 +43,7 @@ def initialize():
# Get system where script is run # Get system where script is run
run_system = platform.system() run_system = platform.system()
# Enable debug with info # Enable debug with info
if DEBUG_MODE: if DEBUG_MODE:
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
@ -54,20 +57,38 @@ def initialize():
console.log("Install python version > 3.11") console.log("Install python version > 3.11")
sys.exit(0) sys.exit(0)
# Removing temporary folder # Removing temporary folder
remove_folder("tmp") remove_folder("tmp")
remove_file("debug.log") remove_file("debug.log")
start_message() start_message()
# Attempting GitHub update # Attempting GitHub update
try: try:
git_update() git_update()
except Exception as e: except Exception as e:
console.print(f"[blue]Req github [white]=> [red]Failed: {e}") console.print(f"[blue]Req github [white]=> [red]Failed: {e}")
# Checking ffmpeg availability ( only win ) # Checking ffmpeg availability ( only win )
if run_system == 'Windows': if run_system == 'Windows':
check_ffmpeg()
# Check if backup of path exist
if not temp_config_manager.get_bool('Backup', 'path'):
# Make backup of init path
backup_path()
temp_config_manager.add_variable('Backup', 'path', True)
# Check if tmp config ffmpeg is present
if not temp_config_manager.get_bool('Requirements', 'ffmpeg'):
output_ffmpeg = check_ffmpeg()
# If ffmpeg is present is win systems change config
if output_ffmpeg:
temp_config_manager.add_variable('Requirements', 'ffmpeg', True)
def main(): def main():
""" """
@ -111,6 +132,7 @@ def main():
# End # End
console.print("\n[red]Done") console.print("\n[red]Done")
def main_switch(): def main_switch():
""" """
Main function for anime unity Main function for anime unity