#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
fix_times_one_script_fixed.py
Opravená verze — škáluje jen to, co se smí (bez double-scalingu a bez škálování length média)
"""
from xml.etree import ElementTree as ET
from pathlib import Path
from decimal import Decimal, getcontext, ROUND_HALF_UP
import re, shutil, sys
# ======= NASTAVENÍ =======
INPUT_FILE = Path("./Jede vlak.mlt")
OUTPUT_FILE = Path("./Jede vlak_fixed.mlt")
SCALE = Decimal("0.5") # 0.5 = polovina času
RESOURCE_FROM = "/1/" # nebo None
RESOURCE_TO = "/2/"
# ==================================================
getcontext().prec = 28
getcontext().rounding = ROUND_HALF_UP
TIME_RE = re.compile(r'^(?P<h>\d{2}):(?P<m>\d{2}):(?P<s>\d{2})(?:\.(?P<frac>\d+))?$')
def parse_time_to_decimal(text):
if text is None:
return None, 0
t = text.strip()
m = TIME_RE.match(t)
if not m:
return None, 0
h = int(m.group('h'))
mm = int(m.group('m'))
ss = int(m.group('s'))
frac = m.group('frac') or ""
frac_len = len(frac)
frac_dec = Decimal("0." + frac) if frac_len > 0 else Decimal(0)
total = Decimal(h)*3600 + Decimal(mm)*60 + Decimal(ss) + frac_dec
return total, frac_len
def format_decimal_seconds(total_seconds: Decimal, frac_len: int = 3):
if total_seconds < 0:
total_seconds = Decimal(0)
hours = int(total_seconds // 3600)
rem = total_seconds - Decimal(hours)*3600
minutes = int(rem // 60)
sec_dec = rem - Decimal(minutes)*60
if frac_len > 0:
q = Decimal(1).scaleb(-frac_len)
sec_q = sec_dec.quantize(q, rounding=ROUND_HALF_UP)
if sec_q >= 60:
sec_q -= 60
minutes += 1
if minutes >= 60:
minutes -= 60
hours += 1
frac_part = f"{sec_q - int(sec_q):.{frac_len}f}"[1:]
sec_str = f"{int(sec_q):02d}{frac_part}"
else:
sec_str = f"{int(sec_dec):02d}"
return f"{hours:02d}:{minutes:02d}:{sec_str}"
def scale_time_text(txt, scale):
total, frac_len = parse_time_to_decimal(txt)
if total is None:
return None
new_total = total * scale
target_frac = frac_len if frac_len > 0 else 3
return format_decimal_seconds(new_total, target_frac)
def backup_file(p: Path):
bak = p.with_suffix(p.suffix + ".bak")
if not bak.exists():
shutil.copy2(p, bak)
return bak
def main():
if not INPUT_FILE.exists():
print("Chyba: vstupní soubor nenalezen:", INPUT_FILE)
sys.exit(1)
xml = INPUT_FILE.read_text(encoding="utf-8")
root = ET.fromstring(xml)
counts = {"tractor":0, "chain_out":0, "playlist_entry":0, "markers":0, "resource_repl":0}
samples = []
# 1. playlist entry in/out
for playlist in root.findall(".//playlist"):
for entry in playlist.findall("entry"):
for a in ("in", "out"):
v = entry.get(a)
new = scale_time_text(v, SCALE) if v else None
if new:
entry.set(a, new)
counts["playlist_entry"] += 1
samples.append(("playlist_entry", entry.get("producer"), a, v, new))
# 2. tractor in/out
for tractor in root.findall(".//tractor"):
for a in ("in", "out"):
v = tractor.get(a)
new = scale_time_text(v, SCALE) if v else None
if new:
tractor.set(a, new)
counts["tractor"] += 1
samples.append(("tractor", tractor.get("id"), a, v, new))
# 3. chains: ŠKÁLUJEME POUZE out atribut (NE length property!)
for chain in root.findall(".//chain"):
for a in ("in", "out"): # in obvykle není, ale pro jistotu
v = chain.get(a)
new = scale_time_text(v, SCALE) if v else None
if new:
chain.set(a, new)
counts["chain_out"] += 1
samples.append(("chain_out", chain.get("id"), a, v, new))
# ŽÁDNÉ škálování <property name="length"> !!!
# resource replacement (pokud chceš)
if RESOURCE_FROM:
for prop in chain.findall("property[@name='resource']"):
if prop.text:
old = prop.text
newres = old.replace(RESOURCE_FROM, RESOURCE_TO)
if newres != old:
prop.text = newres
counts["resource_repl"] += 1
samples.append(("resource", chain.get("id"), old, newres))
# 4. markery – jen jednou!
for props in root.findall(".//properties[@name='shotcut:markers']"):
for marker in props.findall("properties"):
for prop_name in ("start", "end"):
prop = marker.find(f"property[@name='{prop_name}']")
if prop is not None and prop.text:
new = scale_time_text(prop.text, SCALE)
if new:
prop.text = new
counts["markers"] += 1
samples.append((f"marker_{prop_name}", marker.get("name"), prop.text, new))
# ZÁLOHA + ZÁPIS
bak = backup_file(INPUT_FILE)
print("Záloha:", bak)
OUTPUT_FILE.write_text(ET.tostring(root, encoding="utf-8", method="xml").decode("utf-8"), encoding="utf-8")
print("Uloženo:", OUTPUT_FILE)
# Souhrn
print("\nZměny:")
for k, v in counts.items():
print(f" - {k}: {v}")
print("\nUkázka (prvních 30):")
for s in samples[:30]:
print(s)
if __name__ == "__main__":
main()
Žádné komentáře:
Okomentovat