""" Generator PSD — Podziękowanie dla gości weselnych (buteleczka, Wzór 8). Otwiera szablon PSD, podmienia inicjały, datę i opcjonalnie życzenia w Smart Object "Projekt" z zachowaniem pozycji warstw, zapisuje jako nowy PSD. Wymaga: uruchomiony Adobe Photoshop, pakiet photoshop-python-api. Użycie: python buteleczki_wzor8.py --inicjal_zenski "K" --inicjal_meski "Ł" \ --data "30.04.2026" --klient "Kinga Klimczak" python buteleczki_wzor8.py --inicjal_zenski "K" --inicjal_meski "Ł" \ --data "30.04.2026" --zyczenia "Na zdrowie!" --klient "Kinga Klimczak" """ import argparse import os import photoshop.api as ps # --- Ścieżki --- PROJEKT_DIR = os.path.join( r"d:\pomysloweprezenty.pl\projekty\ślub - buteleczki", "Podziękowanie dla gości weselnych buteleczka z nadrukiem UV - Wzór 8", ) SZABLON_PATH = os.path.join(PROJEKT_DIR, "szablon 370x300.psd") GOTOWE_DIR = os.path.join(PROJEKT_DIR, "_gotowe") SMART_OBJECT_LAYER = "Projekt" def open_smart_object(app): """Otwiera zawartość aktywnej warstwy Smart Object do edycji.""" desc = ps.ActionDescriptor() ref = ps.ActionReference() ref.putEnumerated( app.stringIDToTypeID("layer"), app.stringIDToTypeID("ordinal"), app.stringIDToTypeID("targetEnum"), ) desc.putReference(app.stringIDToTypeID("null"), ref) app.executeAction(app.stringIDToTypeID("placedLayerEditContents"), desc) def change_text_preserve_position(layer, new_text): """Zmienia tekst warstwy z zachowaniem jej oryginalnej pozycji.""" bounds_before = [float(b) for b in layer.bounds] layer.textItem.contents = new_text bounds_after = [float(b) for b in layer.bounds] dx = bounds_before[0] - bounds_after[0] dy = bounds_before[1] - bounds_after[1] if dx != 0 or dy != 0: layer.translate(dx, dy) def generate(inicjal_zenski, inicjal_meski, data, klient, zyczenia=None): """Generuje PSD z podmienionymi danymi.""" os.makedirs(GOTOWE_DIR, exist_ok=True) output_path = os.path.join(GOTOWE_DIR, f"{klient}.psd") app = ps.Application() doc = app.open(SZABLON_PATH) print(f"Otwarto szablon: {doc.name}") # Znajdź i otwórz Smart Object for layer in doc.layers: if layer.name == SMART_OBJECT_LAYER: app.activeDocument.activeLayer = layer break else: doc.close(ps.SaveOptions.DoNotSaveChanges) raise RuntimeError(f"Nie znaleziono warstwy '{SMART_OBJECT_LAYER}'") open_smart_object(app) so_doc = app.activeDocument # Nawiguj do warstw tekstowych tekst_group = so_doc.layerSets["Tekst"] # Data i życzenia — bezpośrednio w grupie Tekst replacements = { "data": data, "inicjal_zenski": inicjal_zenski, "inicjal_meski": inicjal_meski, } if zyczenia is not None: replacements["zyczenia"] = zyczenia # Podmiana daty i życzeń for layer_name in ["data", "zyczenia"]: if layer_name not in replacements: continue layer = tekst_group.artLayers[layer_name] old_text = layer.textItem.contents change_text_preserve_position(layer, replacements[layer_name]) print(f' {layer_name}: "{old_text}" -> "{replacements[layer_name]}"') # Podmiana inicjałów — Tekst → → Inicjaly inicjaly_group = None for ls in tekst_group.layerSets: try: inicjaly_group = ls.layerSets["Inicjaly"] break except Exception: continue if inicjaly_group is None: print(" UWAGA: Nie znaleziono grupy Inicjaly!") else: for layer_name in ["inicjal_zenski", "inicjal_meski"]: layer = inicjaly_group.artLayers[layer_name] old_text = layer.textItem.contents change_text_preserve_position(layer, replacements[layer_name]) print(f' {layer_name}: "{old_text}" -> "{replacements[layer_name]}"') # Zapisz Smart Object so_doc.save() so_doc.close() print("Smart Object zapisany") # Zapisz jako nowy PSD psd_opts = ps.PhotoshopSaveOptions() app.activeDocument.saveAs(output_path, psd_opts, True) print(f"Zapisano: {output_path}") # Zamknij bez zapisu oryginału app.activeDocument.close(ps.SaveOptions.DoNotSaveChanges) print("Gotowe!") return output_path def main(): parser = argparse.ArgumentParser( description="Generator PSD - buteleczki weselne Wzór 8" ) parser.add_argument("--inicjal_zenski", required=True, help="Inicjał żeński (np. K)") parser.add_argument("--inicjal_meski", required=True, help="Inicjał męski (np. Ł)") parser.add_argument("--data", required=True, help="Data uroczystości (np. 30.04.2026)") parser.add_argument("--klient", required=True, help="Imię i nazwisko klienta (nazwa pliku wyjściowego)") parser.add_argument("--zyczenia", default=None, help="Tekst życzeń (domyślnie: oryginalny z szablonu)") args = parser.parse_args() generate( inicjal_zenski=args.inicjal_zenski, inicjal_meski=args.inicjal_meski, data=args.data, klient=args.klient, zyczenia=args.zyczenia, ) if __name__ == "__main__": main()