mirror of
https://github.com/Arrowar/StreamingCommunity.git
synced 2025-06-07 12:05:35 +00:00
Add config.ini, backup path
This commit is contained in:
parent
d942613dd8
commit
5d6a42d3d5
52
README.md
52
README.md
@ -69,50 +69,6 @@ python3 update.py
|
||||
|
||||
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
|
||||
|
||||
@ -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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
@ -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).
|
||||
* 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:
|
||||
You can choose different vars:
|
||||
* `%(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_name)` : Is the name of the episode
|
||||
>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)
|
||||
|
@ -19,7 +19,7 @@ from Src.Util.config import config_manager
|
||||
# Variable
|
||||
DEBUG_MODE = config_manager.get_bool("DEFAULT", "debug")
|
||||
DEBUG_FFMPEG = "debug" if DEBUG_MODE else "error"
|
||||
USE_CODECS = False
|
||||
USE_CODECS = config_manager.get_bool("M3U8", "use_codecs")
|
||||
|
||||
|
||||
|
||||
|
@ -146,17 +146,20 @@ def move_ffmpeg_exe_to_top_level(install_dir: str) -> None:
|
||||
raise
|
||||
|
||||
def add_install_dir_to_environment_path(install_dir: str) -> None:
|
||||
'''
|
||||
"""
|
||||
Add the install directory to the environment PATH variable.
|
||||
|
||||
Args:
|
||||
install_dir (str): The directory to be added to the environment PATH variable.
|
||||
'''
|
||||
"""
|
||||
|
||||
install_dir = os.path.abspath(os.path.join(install_dir, 'bin'))
|
||||
set_env_path(install_dir)
|
||||
|
||||
def download_ffmpeg():
|
||||
"""
|
||||
Main function to donwload ffmpeg and add to win path
|
||||
"""
|
||||
|
||||
# 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')
|
||||
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.
|
||||
|
||||
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
|
||||
FFmpeg and add it to the system PATH.
|
||||
|
||||
Returns:
|
||||
bool: If ffmpeg is present or not
|
||||
"""
|
||||
|
||||
console.print("[green]Checking FFmpeg...")
|
||||
@ -209,6 +215,8 @@ def check_ffmpeg():
|
||||
if show_version:
|
||||
get_version()
|
||||
|
||||
return True
|
||||
|
||||
except:
|
||||
|
||||
try:
|
||||
@ -225,3 +233,5 @@ def check_ffmpeg():
|
||||
console.print("[red]Unable to download or add FFmpeg to the PATH.[/red]")
|
||||
console.print(f"Error: {e}")
|
||||
raise
|
||||
|
||||
return False
|
188
Src/Util/_tmpConfig.py
Normal file
188
Src/Util/_tmpConfig.py
Normal 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)
|
||||
|
@ -1,9 +1,5 @@
|
||||
# 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 os
|
||||
import logging
|
||||
@ -98,16 +94,23 @@ def backup_path():
|
||||
original_path = get_env("Path")
|
||||
|
||||
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")
|
||||
|
||||
with open(backup_file, "w") as f:
|
||||
for path in original_path.split("\n"):
|
||||
if len(path) > 3:
|
||||
f.write(f"{path}; \n")
|
||||
# Check if backup file exist
|
||||
if not os.path.exists(backup_file):
|
||||
|
||||
logging.info("Backup of PATH variable created.")
|
||||
print("Backup of PATH variable created.")
|
||||
with open(backup_file, "w") as f:
|
||||
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:
|
||||
logging.error(f"Failed to create backup of PATH variable: {e}")
|
||||
|
@ -1,9 +1,17 @@
|
||||
# 10.04.24
|
||||
|
||||
|
||||
# Internal utilities
|
||||
from Src.Lib.Unidecode import transliterate
|
||||
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')
|
||||
|
||||
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.
|
||||
|
||||
@ -15,9 +23,11 @@ def map_episode_title(tv_name: str, episode, number_season: int):
|
||||
Returns:
|
||||
str: The mapped episode title.
|
||||
"""
|
||||
|
||||
map_episode_temp = map_episode
|
||||
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("%(episode)", str(episode.number).zfill(2))
|
||||
map_episode_temp = map_episode_temp.replace("%(episode_name)", episode.name)
|
||||
|
||||
return transliterate(map_episode_temp)
|
@ -27,6 +27,7 @@
|
||||
"download_percentage": 1,
|
||||
"requests_timeout": 5,
|
||||
"use_openssl": false,
|
||||
"use_codecs": false,
|
||||
"enable_time_quit": false,
|
||||
"tqdm_show_progress": false,
|
||||
"cleanup_tmp_folder": true
|
||||
|
26
run.py
26
run.py
@ -19,13 +19,15 @@ from Src.Api import (
|
||||
from Src.Util.message import start_message
|
||||
from Src.Util.console import console, msg
|
||||
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.Upload.update import update as git_update
|
||||
from Src.Lib.FFmpeg import check_ffmpeg
|
||||
from Src.Util.logger import Logger
|
||||
|
||||
|
||||
# Variable
|
||||
# Config
|
||||
DEBUG_MODE = config_manager.get_bool("DEFAULT", "debug")
|
||||
DEBUG_GET_ALL_INFO = config_manager.get_bool('DEFAULT', 'get_info')
|
||||
SWITCH_TO = config_manager.get_bool('DEFAULT', 'swith_anime')
|
||||
@ -41,6 +43,7 @@ def initialize():
|
||||
# Get system where script is run
|
||||
run_system = platform.system()
|
||||
|
||||
|
||||
# Enable debug with info
|
||||
if DEBUG_MODE:
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
@ -54,20 +57,38 @@ def initialize():
|
||||
console.log("Install python version > 3.11")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
# Removing temporary folder
|
||||
remove_folder("tmp")
|
||||
remove_file("debug.log")
|
||||
start_message()
|
||||
|
||||
|
||||
# Attempting GitHub update
|
||||
try:
|
||||
git_update()
|
||||
except Exception as e:
|
||||
console.print(f"[blue]Req github [white]=> [red]Failed: {e}")
|
||||
|
||||
|
||||
# Checking ffmpeg availability ( only win )
|
||||
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():
|
||||
"""
|
||||
@ -111,6 +132,7 @@ def main():
|
||||
# End
|
||||
console.print("\n[red]Done")
|
||||
|
||||
|
||||
def main_switch():
|
||||
"""
|
||||
Main function for anime unity
|
||||
|
Loading…
x
Reference in New Issue
Block a user