mirror of
https://github.com/Dictionarry-Hub/profilarr.git
synced 2026-01-22 10:51:02 +01:00
## Backend Changes - Refactored and restructured backend code - Consolidated utility functions and updated directory structure - Improved Git clone functionality to merge local files - Enhanced Git status retrieval and diff parsing - Implemented file revert and delete functionality - Optimized Git status checks for better performance ## Frontend Enhancements - Added smooth animated background transition in navbar - Implemented comprehensive Git status display in SettingsManager - Created branch management modal with improved UI and functionality - Added loading indicators for Git operations - Integrated DiffViewer for side-by-side comparisons of changes - Implemented Toast notifications for better user feedback - Enhanced file management with conditional revert/delete options - Added ability to selectively pull incoming changes ## UI/UX Improvements - Improved branch management UI with tooltips and confirmation dialogs - Enhanced alert notifications using react-toastify - Added fun loading messages for Git status - Implemented CommitSection component for improved commit functionality ## Miscellaneous - Updated sanitization to be less aggressive - Initialized database folders on Flask startup - Added Docker volumes for data storage - Changed application name to Profilarr
64 lines
2.0 KiB
Python
64 lines
2.0 KiB
Python
import os
|
|
import git
|
|
import datetime
|
|
import re
|
|
import yaml
|
|
from yaml import safe_load
|
|
from collections import OrderedDict
|
|
import logging
|
|
|
|
def get_next_id(directory):
|
|
max_id = 0
|
|
for filename in os.listdir(directory):
|
|
if filename.endswith('.yml'):
|
|
file_path = os.path.join(directory, filename)
|
|
with open(file_path, 'r') as file:
|
|
content = yaml.safe_load(file)
|
|
file_id = content.get('id', None)
|
|
if isinstance(file_id, int):
|
|
if file_id > max_id:
|
|
max_id = file_id
|
|
else:
|
|
logging.warning(f"File {filename} has an invalid or missing 'id': {file_id}")
|
|
return max_id + 1
|
|
|
|
def generate_filename(directory, id, name):
|
|
sanitized_name = name.replace(' ', '_').lower()
|
|
return os.path.join(directory, f"{id}_{sanitized_name}.yml")
|
|
|
|
def get_current_timestamp():
|
|
return datetime.datetime.now().isoformat()
|
|
|
|
def sanitize_input(input_str):
|
|
if not isinstance(input_str, str):
|
|
return input_str
|
|
|
|
# Remove any leading/trailing whitespace
|
|
sanitized_str = input_str.strip()
|
|
|
|
# Replace tabs with spaces
|
|
sanitized_str = sanitized_str.replace('\t', ' ')
|
|
|
|
# Collapse multiple spaces into a single space
|
|
sanitized_str = re.sub(r'\s+', ' ', sanitized_str)
|
|
|
|
# Escape special characters for YAML
|
|
special_chars = r'[:#&*?|<>%@`]'
|
|
sanitized_str = re.sub(special_chars, lambda m: '\\' + m.group(0), sanitized_str)
|
|
|
|
# If the string starts with any of these characters, quote the entire string
|
|
if re.match(r'^[\'"-]', sanitized_str):
|
|
sanitized_str = yaml.dump(sanitized_str, default_style='"').strip()
|
|
|
|
# Handle multi-line strings
|
|
if '\n' in sanitized_str:
|
|
sanitized_str = '|\n' + '\n'.join(f' {line}' for line in sanitized_str.split('\n'))
|
|
|
|
return sanitized_str
|
|
|
|
def represent_ordereddict(dumper, data):
|
|
return dumper.represent_mapping('tag:yaml.org,2002:map', data.items())
|
|
|
|
yaml.add_representer(OrderedDict, represent_ordereddict, Dumper=yaml.SafeDumper)
|
|
|