123 lines
3.7 KiB
Python
123 lines
3.7 KiB
Python
import xml.etree.ElementTree as ET
|
||
from pathlib import Path
|
||
|
||
# Default XML content to write if missing
|
||
DEFAULT_XML = """<?xml version="1.0" encoding="UTF-8"?>
|
||
<config>
|
||
<general>
|
||
<processing_folder>processing</processing_folder>
|
||
<suffix> -EHX</suffix>
|
||
<extensions>.mkv,.mp4</extensions>
|
||
</general>
|
||
<path_mappings>
|
||
<map from="P:\\tv" to="/mnt/plex/tv" />
|
||
<map from="P:\\anime" to="/mnt/plex/anime" />
|
||
</path_mappings>
|
||
<encode>
|
||
<cq>
|
||
<tv_1080>28</tv_1080>
|
||
<tv_720>32</tv_720>
|
||
<movie_1080>32</movie_1080>
|
||
<movie_720>34</movie_720>
|
||
</cq>
|
||
<fallback>
|
||
<bitrate_1080>1500k</bitrate_1080>
|
||
<maxrate_1080>1750k</maxrate_1080>
|
||
<bufsize_1080>2250k</bufsize_1080>
|
||
<bitrate_720>900k</bitrate_720>
|
||
<maxrate_720>1250k</maxrate_720>
|
||
<bufsize_720>1600k</bufsize_720>
|
||
</fallback>
|
||
<filters>
|
||
<default>lanczos</default>
|
||
<tv>bicubic</tv>
|
||
</filters>
|
||
</encode>
|
||
<audio>
|
||
<stereo>
|
||
<low>64000</low>
|
||
<medium>96000</medium>
|
||
<high>128000</high>
|
||
</stereo>
|
||
<multi_channel>
|
||
<low>160000</low>
|
||
<high>192000</high>
|
||
</multi_channel>
|
||
</audio>
|
||
</config>
|
||
"""
|
||
|
||
def load_config_xml(path: Path) -> dict:
|
||
if not path.exists():
|
||
path.write_text(DEFAULT_XML, encoding="utf-8")
|
||
print(f"ℹ️ Created default config.xml at {path}")
|
||
|
||
tree = ET.parse(path)
|
||
root = tree.getroot()
|
||
|
||
# --- General ---
|
||
general = root.find("general")
|
||
processing_folder_elem = general.find("processing_folder") if general is not None else None
|
||
processing_folder = processing_folder_elem.text if processing_folder_elem is not None else "processing"
|
||
|
||
suffix_elem = general.find("suffix") if general is not None else None
|
||
suffix = suffix_elem.text if suffix_elem is not None else " -EHX"
|
||
|
||
extensions_elem = general.find("extensions") if general is not None else None
|
||
extensions = extensions_elem.text.split(",") if extensions_elem is not None else [".mkv", ".mp4"]
|
||
|
||
# --- Path Mappings ---
|
||
path_mappings = {}
|
||
for m in root.findall("path_mappings/map"):
|
||
f = m.attrib.get("from")
|
||
t = m.attrib.get("to")
|
||
if f and t:
|
||
path_mappings[f] = t
|
||
|
||
# --- Encode ---
|
||
encode_elem = root.find("encode")
|
||
cq = {}
|
||
fallback = {}
|
||
filters = {}
|
||
if encode_elem is not None:
|
||
cq_elem = encode_elem.find("cq")
|
||
if cq_elem is not None:
|
||
for child in cq_elem:
|
||
if child.text:
|
||
cq[child.tag] = int(child.text)
|
||
|
||
fallback_elem = encode_elem.find("fallback")
|
||
if fallback_elem is not None:
|
||
for child in fallback_elem:
|
||
if child.text:
|
||
fallback[child.tag] = child.text
|
||
|
||
filters_elem = encode_elem.find("filters")
|
||
if filters_elem is not None:
|
||
for child in filters_elem:
|
||
if child.text:
|
||
filters[child.tag] = child.text
|
||
|
||
# --- Audio ---
|
||
audio = {"stereo": {}, "multi_channel": {}}
|
||
stereo_elem = root.find("audio/stereo")
|
||
if stereo_elem is not None:
|
||
for child in stereo_elem:
|
||
if child.text:
|
||
audio["stereo"][child.tag] = int(child.text)
|
||
|
||
multi_elem = root.find("audio/multi_channel")
|
||
if multi_elem is not None:
|
||
for child in multi_elem:
|
||
if child.text:
|
||
audio["multi_channel"][child.tag] = int(child.text)
|
||
|
||
return {
|
||
"processing_folder": processing_folder,
|
||
"suffix": suffix,
|
||
"extensions": [ext.lower() for ext in extensions],
|
||
"path_mappings": path_mappings,
|
||
"encode": {"cq": cq, "fallback": fallback, "filters": filters},
|
||
"audio": audio
|
||
}
|