import os import re # ================= CONFIG ================= PARTS_DIR = r"downloads/PC_Pro_2011-07" OUTPUT_DIR = r"downloads" # ========================================== ybegin_re = re.compile(r"size=(\d+)") name_re = re.compile(r"name=(.+)") ypart_re = re.compile(r"begin=(\d+)\s+end=(\d+)") parts = [] total_size = None final_name = None # --- 1. načti všechny yEnc hlavičky --- for fname in os.listdir(PARTS_DIR): if not fname.endswith(".yEncHeader"): continue part_id = fname.replace(".yEncHeader", "") hdr_path = os.path.join(PARTS_DIR, fname) bin_path = os.path.join(PARTS_DIR, f"{part_id}.bin") if not os.path.exists(bin_path): raise RuntimeError(f"Missing bin file for {fname}") with open(hdr_path, "r", encoding="utf-8", errors="replace") as f: lines = f.read().splitlines() begin = end = None for line in lines: if line.startswith("=ybegin"): if total_size is None: m = ybegin_re.search(line) if m: total_size = int(m.group(1)) m = name_re.search(line) if m: final_name = m.group(1) if line.startswith("=ypart"): m = ypart_re.search(line) if not m: raise RuntimeError(f"Cannot parse ypart in {fname}") begin = int(m.group(1)) end = int(m.group(2)) if begin is None or end is None: raise RuntimeError(f"Missing begin/end in {fname}") parts.append({ "bin": bin_path, "begin": begin, "end": end }) # --- sanity checks --- if total_size is None or final_name is None: raise RuntimeError("Missing ybegin info (size/name)") output_path = os.path.join(OUTPUT_DIR, final_name) print(f"📄 Final file: {output_path}") print(f"📦 Total size: {total_size} bytes") print(f"🧩 Parts: {len(parts)}") # --- 2. alokuj cílový soubor --- with open(output_path, "wb") as f: f.truncate(total_size) # --- 3. zapiš jednotlivé části na správné offsety --- with open(output_path, "r+b") as out: for p in parts: expected_len = p["end"] - p["begin"] + 1 with open(p["bin"], "rb") as bf: data = bf.read() if len(data) != expected_len: print( f"⚠️ Size mismatch in {os.path.basename(p['bin'])}: " f"expected {expected_len}, got {len(data)}" ) # kratší data jsou OK (CRC, padding, end-of-part) out.seek(p["begin"] - 1) # yEnc je 1-based out.write(data) print("🎉 DONE – file assembled correctly")