add copy/replace files and dirs
This commit is contained in:
@ -1,2 +1,8 @@
|
|||||||
# Jellyfin-Mods-Automated-Scripts
|
# Jellyfin-Mods-Automated-Scripts
|
||||||
|
|
||||||
|
Verwendung:
|
||||||
|
python script.py config.yaml
|
||||||
|
|
||||||
|
Voraussetzungen:
|
||||||
|
Python
|
||||||
|
PyYAML-Bibliothek (pip install pyyaml)
|
12
config.yaml
12
config.yaml
@ -5,7 +5,7 @@ modifications:
|
|||||||
- file_pattern: 'session-login-index-html\..*\.bundle\.js'
|
- file_pattern: 'session-login-index-html\..*\.bundle\.js'
|
||||||
insert_rules:
|
insert_rules:
|
||||||
- after_text: '<div class="padded-left padded-right padded-bottom-page margin-auto-y">'
|
- after_text: '<div class="padded-left padded-right padded-bottom-page margin-auto-y">'
|
||||||
insert_text: '<img src="/web/logo.png" width=350px style="padding: 0px;display:block; margin-left: auto; margin-right: auto;">'
|
insert_text: '<img id="login-logo" src="/web/assets/img/banner-dark.png" width=350px style="padding: 0px;display:block; margin-left: auto; margin-right: auto;">'
|
||||||
|
|
||||||
# Instancename, Jellyseer I-Frame
|
# Instancename, Jellyseer I-Frame
|
||||||
- file_pattern: 'index.html'
|
- file_pattern: 'index.html'
|
||||||
@ -16,6 +16,16 @@ modifications:
|
|||||||
- old_text: '<title>Jellyfin</title>'
|
- old_text: '<title>Jellyfin</title>'
|
||||||
new_text: '<title>SpaceCloud - Cinema</title>'
|
new_text: '<title>SpaceCloud - Cinema</title>'
|
||||||
|
|
||||||
|
# Instancename, Jellyseer I-Frame
|
||||||
|
- file_pattern: 'main.jellyfin.bundle.js'
|
||||||
|
replace_rules:
|
||||||
|
# Set limit on how many days items should be in the next up section (last number)
|
||||||
|
- old_text: 't("maxDaysForNextUp",e.toString(),!1);var t=parseInt(this.get("maxDaysForNextUp",!1),10);return 0===t?0:t||365}}'
|
||||||
|
new_text: 't("maxDaysForNextUp",e.toString(),!1);var t=parseInt(this.get("maxDaysForNextUp",!1),10);return 0===t?0:t||28}}'
|
||||||
|
# Default user page size (last number), 99 fits perfect on most desktops
|
||||||
|
- old_text: 'this.get("libraryPageSize",!1),10);return 0===t?0:t||100}'
|
||||||
|
new_text: 'this.get("libraryPageSize",!1),10);return 0===t?0:t||99}'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
32
customizeAndCopy-Config.yaml
Normal file
32
customizeAndCopy-Config.yaml
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Zielverzeichnis für Operationen
|
||||||
|
destination_directory: './target_directory'
|
||||||
|
|
||||||
|
# Kopierregeln
|
||||||
|
copy_rules:
|
||||||
|
- sources:
|
||||||
|
- './source_folder' # Gesamter Ordner
|
||||||
|
- './specific_file.txt' # Einzelne Datei
|
||||||
|
- './source_directory/*.js' # Alle JS-Dateien
|
||||||
|
mode: 'replace' # Überschreibt vorhandene Dateien/Ordner
|
||||||
|
|
||||||
|
# Modifikationsregeln
|
||||||
|
modification_rules:
|
||||||
|
- file_pattern: '\.html$'
|
||||||
|
# Einfügeregeln
|
||||||
|
insert_rules:
|
||||||
|
- after_text: '<body>'
|
||||||
|
insert_text: '<div class="new-banner">Zusätzlicher Inhalt</div>'
|
||||||
|
|
||||||
|
# Ersetzungsregeln
|
||||||
|
replace_rules:
|
||||||
|
- old_text: '<title>Ein Titel</title>'
|
||||||
|
new_text: '<title>Cinema</title>'
|
||||||
|
|
||||||
|
- file_pattern: '\.js$'
|
||||||
|
replace_rules:
|
||||||
|
- old_text: 'const version = "1.0.0";'
|
||||||
|
new_text: 'const version = "2.0.0";'
|
||||||
|
|
||||||
|
insert_rules:
|
||||||
|
- before_text: 'function initializeApp() {'
|
||||||
|
insert_text: '// Neue Initialisierungsvorbereitungen'
|
206
customizeAndCopy.py
Normal file
206
customizeAndCopy.py
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import yaml
|
||||||
|
import shutil
|
||||||
|
import glob
|
||||||
|
|
||||||
|
def load_configuration(config_path):
|
||||||
|
"""
|
||||||
|
Load configuration from a YAML file.
|
||||||
|
"""
|
||||||
|
with open(config_path, 'r', encoding='utf-8') as config_file:
|
||||||
|
return yaml.safe_load(config_file)
|
||||||
|
|
||||||
|
def copy_with_mode(src, dest, mode='copy'):
|
||||||
|
"""
|
||||||
|
Copy files or directories with different modes.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Ensure destination directory exists
|
||||||
|
os.makedirs(os.path.dirname(dest), exist_ok=True)
|
||||||
|
|
||||||
|
# Determine copy mode
|
||||||
|
if mode == 'copy':
|
||||||
|
# Skip if destination already exists
|
||||||
|
if os.path.exists(dest):
|
||||||
|
print(f'Skipping {src}: Destination already exists')
|
||||||
|
return False
|
||||||
|
|
||||||
|
elif mode == 'replace':
|
||||||
|
# Remove existing destination before copying
|
||||||
|
if os.path.exists(dest):
|
||||||
|
if os.path.isdir(dest):
|
||||||
|
shutil.rmtree(dest)
|
||||||
|
else:
|
||||||
|
os.remove(dest)
|
||||||
|
|
||||||
|
elif mode == 'update':
|
||||||
|
# Only copy if source is newer
|
||||||
|
if os.path.exists(dest):
|
||||||
|
src_mtime = os.path.getmtime(src)
|
||||||
|
dest_mtime = os.path.getmtime(dest)
|
||||||
|
if src_mtime <= dest_mtime:
|
||||||
|
print(f'Skipping {src}: Destination is up to date')
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Perform copy
|
||||||
|
if os.path.isdir(src):
|
||||||
|
shutil.copytree(src, dest)
|
||||||
|
else:
|
||||||
|
shutil.copy2(src, dest)
|
||||||
|
|
||||||
|
print(f'Copied: {src} -> {dest}')
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Error copying {src}: {e}')
|
||||||
|
return False
|
||||||
|
|
||||||
|
def matches_file_pattern(filename, pattern):
|
||||||
|
"""
|
||||||
|
Check if filename matches the given pattern.
|
||||||
|
"""
|
||||||
|
return re.search(pattern, filename) is not None
|
||||||
|
|
||||||
|
def apply_insert_rules(content, insert_rules):
|
||||||
|
"""
|
||||||
|
Apply insertion rules to the content.
|
||||||
|
"""
|
||||||
|
modified_content = content
|
||||||
|
modified = False
|
||||||
|
|
||||||
|
for rule in insert_rules:
|
||||||
|
insert_text = rule.get('insert_text')
|
||||||
|
|
||||||
|
# Insert after specific text
|
||||||
|
if 'after_text' in rule:
|
||||||
|
search_text = rule.get('after_text')
|
||||||
|
if insert_text not in modified_content:
|
||||||
|
modified_content = modified_content.replace(
|
||||||
|
search_text,
|
||||||
|
f'{search_text}\n{insert_text}'
|
||||||
|
)
|
||||||
|
modified = True
|
||||||
|
|
||||||
|
# Insert before specific text
|
||||||
|
elif 'before_text' in rule:
|
||||||
|
search_text = rule.get('before_text')
|
||||||
|
if insert_text not in modified_content:
|
||||||
|
modified_content = modified_content.replace(
|
||||||
|
search_text,
|
||||||
|
f'{insert_text}\n{search_text}'
|
||||||
|
)
|
||||||
|
modified = True
|
||||||
|
|
||||||
|
return modified_content, modified
|
||||||
|
|
||||||
|
def apply_replace_rules(content, replace_rules):
|
||||||
|
"""
|
||||||
|
Apply replacement rules to the content.
|
||||||
|
"""
|
||||||
|
modified_content = content
|
||||||
|
modified = False
|
||||||
|
|
||||||
|
for rule in replace_rules:
|
||||||
|
old_text = rule.get('old_text')
|
||||||
|
new_text = rule.get('new_text')
|
||||||
|
|
||||||
|
# Replace text if found
|
||||||
|
if old_text in modified_content:
|
||||||
|
modified_content = modified_content.replace(old_text, new_text)
|
||||||
|
modified = True
|
||||||
|
|
||||||
|
return modified_content, modified
|
||||||
|
|
||||||
|
def process_copy_and_modify_rules(config):
|
||||||
|
"""
|
||||||
|
Process copy, insertion, and replacement rules.
|
||||||
|
"""
|
||||||
|
successful_operations = {
|
||||||
|
'copies': 0,
|
||||||
|
'modifications': 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get destination directory
|
||||||
|
dest_dir = config.get('destination_directory', '.')
|
||||||
|
os.makedirs(dest_dir, exist_ok=True)
|
||||||
|
|
||||||
|
# Process copy rules
|
||||||
|
for copy_rule in config.get('copy_rules', []):
|
||||||
|
sources = copy_rule.get('sources', [])
|
||||||
|
mode = copy_rule.get('mode', 'copy')
|
||||||
|
|
||||||
|
for src in sources:
|
||||||
|
# Expand potential wildcards
|
||||||
|
matching_sources = glob.glob(src)
|
||||||
|
|
||||||
|
for matched_src in matching_sources:
|
||||||
|
# Determine destination path
|
||||||
|
if os.path.isdir(matched_src):
|
||||||
|
dest = os.path.join(dest_dir, os.path.basename(matched_src))
|
||||||
|
else:
|
||||||
|
dest = os.path.join(dest_dir, os.path.basename(matched_src))
|
||||||
|
|
||||||
|
# Perform copy
|
||||||
|
if copy_with_mode(matched_src, dest, mode):
|
||||||
|
successful_operations['copies'] += 1
|
||||||
|
|
||||||
|
# Process modification rules
|
||||||
|
for mod_rule in config.get('modification_rules', []):
|
||||||
|
search_pattern = mod_rule.get('file_pattern')
|
||||||
|
insert_rules = mod_rule.get('insert_rules', [])
|
||||||
|
replace_rules = mod_rule.get('replace_rules', [])
|
||||||
|
|
||||||
|
# Walk through destination directory
|
||||||
|
for root, _, files in os.walk(dest_dir):
|
||||||
|
for filename in files:
|
||||||
|
# Check if file matches pattern
|
||||||
|
if matches_file_pattern(filename, search_pattern):
|
||||||
|
full_path = os.path.join(root, filename)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Read file content
|
||||||
|
with open(full_path, 'r', encoding='utf-8') as file:
|
||||||
|
content = file.read()
|
||||||
|
|
||||||
|
# Apply insert rules
|
||||||
|
content_after_insert, insert_modified = apply_insert_rules(
|
||||||
|
content, insert_rules
|
||||||
|
)
|
||||||
|
|
||||||
|
# Apply replace rules
|
||||||
|
final_content, replace_modified = apply_replace_rules(
|
||||||
|
content_after_insert, replace_rules
|
||||||
|
)
|
||||||
|
|
||||||
|
# Save modified file
|
||||||
|
if insert_modified or replace_modified:
|
||||||
|
with open(full_path, 'w', encoding='utf-8') as file:
|
||||||
|
file.write(final_content)
|
||||||
|
|
||||||
|
successful_operations['modifications'] += 1
|
||||||
|
print(f'Modified: {full_path}')
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f'Error processing file {full_path}: {e}')
|
||||||
|
|
||||||
|
return successful_operations
|
||||||
|
|
||||||
|
def main():
|
||||||
|
# Check command-line argument
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Please provide the path to the configuration file.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
config_path = sys.argv[1]
|
||||||
|
|
||||||
|
# Load configuration and process rules
|
||||||
|
config = load_configuration(config_path)
|
||||||
|
results = process_copy_and_modify_rules(config)
|
||||||
|
|
||||||
|
print(f'\nTotal successful copies: {results["copies"]}')
|
||||||
|
print(f'Total file modifications: {results["modifications"]}')
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Reference in New Issue
Block a user