scripts-fabq/scripts/library/tools.py

135 lines
3.9 KiB
Python

#!/usr/bin/env python3
import colorama
import os
import re
colorama.init()
creset = colorama.Fore.RESET
cgreen = colorama.Fore.GREEN
cred = colorama.Fore.RED
# Define patterns to search for various resolutions
resolution_patterns = {
2160: r"(4096x2160|3840x2160|2880p|2160p|2160|1440p|4k)",
1080: r"(1920x1080|1080p|1080)",
720: r"(1280x720|720p|720)",
}
# Wrap each pattern to only match when isolated by non-alphanumeric chars or string boundaries
resolution_patterns = {
res: rf"(?<![a-zA-Z0-9]){pat}(?![a-zA-Z0-9])"
for res, pat in resolution_patterns.items()
}
def apply_resolution_rename(name, max_height):
"""
Apply resolution substitution to a filename or directory name if an isolated
resolution pattern greater than max_height is found.
Args:
name (str): The filename or directory name to process (without path).
max_height (int): The target resolution height to substitute to.
Returns:
str: The renamed string if a match was found, or the original string unchanged.
"""
for resolution, pattern in resolution_patterns.items():
if resolution > max_height and re.search(pattern, name, re.IGNORECASE):
return re.sub(pattern, f"{max_height}p", name, flags=re.IGNORECASE)
return name
def deletefile(filepath):
"""Delete a file, Returns a boolean
Args:
filepath : A string containing the full filepath
Returns:
Bool : The success of the operation
"""
try:
os.remove(filepath)
except OSError:
print(f"{cred}Error deleting {filepath}{creset}")
return False
print(f"{cgreen}Successfully deleted {filepath}{creset}")
return True
def get_intermediate_dirs(input_path, file_path):
"""
Return the list of directory paths between input_path (exclusive) and
the directory containing file_path (inclusive), ordered deepest first.
Args:
input_path (str): The root path (exclusive upper bound).
file_path (str): The full path to a file.
Returns:
list: List of directory paths, deepest first.
Raises:
ValueError: If file_path not under input_path.
"""
input_path = os.path.realpath(input_path)
current = os.path.realpath(os.path.dirname(file_path))
if current != input_path and not current.startswith(input_path + os.sep):
raise ValueError(
f"file_path '{file_path}' is not under input_path '{input_path}'"
)
dirs = []
while current != input_path and current != os.path.dirname(current):
dirs.append(current)
current = os.path.dirname(current)
return dirs
def findfreename(filepath, attempt=0):
"""
Given a filepath, it will try to find a free filename by appending a number to the name.
First, it tries using the filepath passed in the argument, then adds a number to the end. If all fail, it appends (#).
Args:
filepath (str): A string containing the full filepath.
attempt (int): The number of attempts already made to find a free filename.
Returns:
str: The first free filepath found.
"""
attempt += 1
filename = str(filepath)[: str(filepath).rindex(".")]
extension = str(filepath)[str(filepath).rindex(".") :]
copynumpath = filename + f"({attempt})" + extension
if not os.path.exists(filepath) and attempt <= 2:
return filepath
elif not os.path.exists(copynumpath):
return copynumpath
return findfreename(filepath, attempt)
def get_spacer(name: str) -> str:
"""
Determine the spacer character ('-' or '_') to use for naming a virtual environment
based on the given project name. Default to underscore.
Args:
name (str): The project name to analyze.
Returns:
str: The detected spacer ('-' or '_'), or '_' if none found.
"""
if "-" in name:
return "-"
elif "_" in name:
return "_"
return "_"