Video2Crops/v2cmodules/toolbox.py

186 lines
6.8 KiB
Python
Raw Normal View History

2023-10-09 23:18:06 +00:00
import re, os, urllib.request
import tkinter as tk
from datetime import datetime
from bs4 import BeautifulSoup
from tkinter import filedialog, simpledialog, messagebox, scrolledtext
from v2cmodules.common import *
def extract_version(title):
# Use regular expressions to extract the version number from the title
match = re.search(r'(\d+\.\d+\.\d+)', title)
if match:
return match.group(1)
return None
def fetch_ini():
global INVALID_INI
try:
with open(CONFIG_FILE, 'w') as file:
config_url = 'https://git.rolfsvaag.no/frarol96/Video2Crops/raw/branch/main/config.ini'
with urllib.request.urlopen(config_url) as config_template:
config_template = config_template.read().decode("utf-8")
file.write(config_template)
2023-10-11 20:02:18 +00:00
tk.messagebox.showinfo("Reset config file", f"Config file has been reset")
2023-10-09 23:18:06 +00:00
debug('DEBUG', f"Config file was reset to default")
INVALID_INI = False
except:
print(f"[ERROR] Unable to fetch the missing config.ini file!\nCheck directory permissions and network connectivity!")
exit
# Debug function
def debug(state, message):
if DEBUG:
allowed_states = ['LOG EVENT', 'DEBUG', 'ERROR', 'INFO']
if state in allowed_states:
debug_message = f"[{state}] {message}"
print(f"{debug_message}")
debugfile_path = os.path.join(os.getcwd(), 'debugfile.txt')
with open(debugfile_path, 'a') as debugfile:
log_debug_message = f"{datetime.now().strftime('%m-%d_%H:%M:%S')} | [{state}] {message}\n"
debugfile.write(log_debug_message)
else:
raise ValueError(f"Invalid state '{state}'. Please choose from {', '.join(allowed_states)}.")
def checkinifile():
global INVALID_INI
# Check for the presence of sections and keys
expected_sections = ['settings', 'debug']
expected_settings_keys = {
'frame_step': int,
'contrast_threshold': float,
'duplicate_threshold': int,
'save_output': bool,
'show_playback': bool,
'roi_size': int,
2023-10-11 20:02:18 +00:00
'window_size': str,
'user_defined_output_dir': str
2023-10-09 23:18:06 +00:00
}
expected_debug_keys = {
'debug_output': bool
}
CHECK_SECTIONS = True
CHECK_KEYS = True
CHECK_VALUES = False
# Check for the presence of sections
if CHECK_SECTIONS:
for section in expected_sections:
if section not in config.sections():
INVALID_INI = True
print(f"Missing section: [{section}]")
# Check for the presence of keys and their types in the 'settings' section
if 'settings' in config.sections():
for key, expected_type in expected_settings_keys.items():
if key not in config['settings']:
if CHECK_KEYS:
INVALID_INI = True
print(f"Missing key '{key}' in [settings] section")
else:
value = config.get('settings', key)
if not isinstance(value, expected_type):
if CHECK_VALUES:
INVALID_INI = True
print(f"Value of '{key}' in [settings] section is not of expected type {expected_type}")
# Check for the presence of keys and their types in the 'debug' section
if 'debug' in config.sections():
for key, expected_type in expected_debug_keys.items():
if key not in config['debug']:
if CHECK_KEYS:
INVALID_INI = True
print(f"Missing key '{key}' in [debug] section")
else:
value = config.get('debug', key)
if not isinstance(value, expected_type):
if CHECK_VALUES:
INVALID_INI = True
print(f"Value of '{key}' in [debug] section is not of expected type {expected_type}")
if INVALID_INI:
fetch_ini()
def write2ini(section, variable, value):
config.set(section, str(variable), str(value))
# Save the changes to the INI file
with open(CONFIG_FILE, 'w') as configfile:
config.write(configfile)
def extract_changelog(description):
# Parse the HTML content using BeautifulSoup
soup = BeautifulSoup(description, 'html.parser')
# Find all changelog sections
changelog_sections = soup.find_all('h3', id='user-content-changelog')
changelogs = []
for changelog_section in changelog_sections:
# Extract the changelog text as plain text
changelog_text = changelog_section.find_next('ul').get_text()
changelogs.append(changelog_text.strip())
# Join the changelogs into a single string
changelog_str = '\n'.join(changelogs)
return changelog_str if changelog_str else None
def toggle_save():
if not processing:
global SAVE
SAVE = not SAVE
write2ini('settings', 'save_output', SAVE)
debug('DEBUG', f"Saving output: {SAVE}")
else:
messagebox.showinfo("Info", "Video2Crops is currently processing files!")
def toggle_show():
if not processing:
global SHOW
SHOW = not SHOW
write2ini('settings', 'show_playback', SHOW)
debug('DEBUG', f"Displaying output: {SHOW}")
else:
messagebox.showinfo("Info", "Video2Crops is currently processing files!")
2023-10-11 20:02:18 +00:00
# Function to create the output directory and return its path
def create_output_directory(video_filename):
debug('DEBUG', f"Creating output directory")
base_directory = user_defined_output_dir
video_filename_base, _ = os.path.splitext(os.path.basename(video_filename))
output_folder_path = os.path.join(base_directory, video_filename_base)
# Create the output directory if it doesn't exist
if not os.path.exists(output_folder_path):
os.makedirs(output_folder_path)
debug('DEBUG', f"Processing file: {video_filename}")
debug('DEBUG', f"Created output directory at: {output_folder_path}")
return output_folder_path
def truncate_path(path, pre_max=None, post_max=None):
# Split the path into components
path_components = os.path.normpath(path).split(os.path.sep)
# Ensure the first two components are displayed in full
pre_part = os.path.sep.join(path_components[:2])
# Ensure the last two components are displayed in full
post_part = os.path.sep.join(path_components[-2:])
# Truncate the pre-portion if pre_max is specified
if pre_max is not None:
pre_part = pre_part[:pre_max]
# Truncate the post-portion if post_max is specified
if post_max is not None:
post_part = post_part[-post_max:]
# Combine the parts with ellipsis in between
truncated_path = f"{pre_part}...{post_part}"
debug('DEBUG', f"Truncated the path \'{path}\' to \'{truncated_path}\'")
return truncated_path