Te same tematy co w rozdziałach 4, 7, 16 i 18, ale tym razem piszesz kod: prosty publish script, hook do niego i okienko PySide, które to wszystko spina — krok po kroku.
Cały kod poniżej to zwykły Python — nie potrzebujesz Mayi ani żadnego innego DCC, żeby go uruchomić. Zamiast prawdziwej sceny 3D „publikujemy" mały plik JSON, udając plik roboczy artysty — mechanizm jest identyczny, tylko dane są uproszczone do minimum, żebyś mógł to odpalić w dowolnym terminalu i zobaczyć wynik.
Zaczynamy od najprostszego elementu: funkcji, która buduje ścieżkę do pliku na podstawie kontekstu, zamiast pozwalać komukolwiek wpisywać ją ręcznie.
import os def build_path(show, task, filename, kind="work"): """kind: 'work' albo 'publish'""" return os.path.join(show, task, kind, filename) print(build_path("DEMO", "lighting", "shot0100.json")) # DEMO/lighting/work/shot0100.json
To dosłownie cała treść Rozdziału 4 zamknięta w jednej funkcji: nazwa i lokalizacja pliku przestają być czymś, co artysta wpisuje z pamięci, i stają się wynikiem obliczenia z kontekstu.
Zanim zobaczysz gotowe rozwiązanie — spróbuj sam. Napisz funkcję next_version(publish_dir), która przeszuka folder publish_dir w poszukiwaniu plików nazwanych *_v001.json, *_v002.json itd., i zwróci numer o jeden większy niż najwyższy znaleziony (albo 1, jeśli folder jest pusty).
import glob, re def next_version(publish_dir): versions = [] for f in glob.glob(os.path.join(publish_dir, "*_v*.json")): m = re.search(r"_v(\d+)\.json$", f) if m: versions.append(int(m.group(1))) return max(versions, default=0) + 1
Mając build_path() i next_version(), publish script pisze się niemal sam:
import json def publish(show, task, name, data): publish_dir = build_path(show, task, "", kind="publish") os.makedirs(publish_dir, exist_ok=True) v = next_version(publish_dir) out_path = os.path.join(publish_dir, f"{name}_v{v:03d}.json") with open(out_path, "w") as f: json.dump(data, f, indent=2) print(f"Opublikowano: {out_path}") return out_path publish("DEMO", "lighting", "shot0100", {"pass": "beauty"}) # Opublikowano: DEMO/lighting/publish/shot0100_v001.json
Uruchom to dwa razy z rzędu — zobaczysz shot0100_v001.json, potem shot0100_v002.json. To już cały mechanizm z Rozdziału 7, tylko bez kroku zatwierdzenia i bez Perforce w tle.
Dopiszmy prosty mechanizm hooków — listę funkcji wywoływanych automatycznie po każdej publikacji, dokładnie jak w Rozdziale 18.
hooks = [] def register_hook(fn): hooks.append(fn) def run_hooks(published_path): for hook in hooks: hook(published_path) # dopisz na końcu funkcji publish(), przed "return out_path": # run_hooks(out_path) def notify_department(path): print(f"[hook] Nowa publikacja gotowa -> {path}") register_hook(notify_department)
Dodaj wywołanie run_hooks(out_path) na końcu publish(), tuż przed return, i przetestuj ponownie — zobaczysz, że powiadomienie pojawia się samo, bez zmiany ani jednej linijki w miejscu, gdzie wywołujesz publish(). To dokładnie ten mechanizm rozdziela od siebie Rozdział 18: logika publikacji nie musi nic wiedzieć o tym, kto i dlaczego chce zareagować na jej wynik.
Ten fragment wymaga już zainstalowanego PySide (pip install PySide6) albo uruchomienia wewnątrz DCC, który je osadza (Rozdział 16) — potraktuj go jako kod do przeczytania i samodzielnego wypróbowania, nie do wklejenia w ten sam plik co poprzednie kroki.
from PySide6.QtWidgets import ( QApplication, QWidget, QVBoxLayout, QLabel, QPushButton ) class PublishWindow(QWidget): def __init__(self, show, task, name, data): super().__init__() self.show_, self.task, self.name, self.data = show, task, name, data self.setWindowTitle("Publish") layout = QVBoxLayout(self) # kontekst pokazany, nie do edycji — zasada z Rozdziału 16 layout.addWidget(QLabel(f"{show} / {task} / {name}")) btn = QPushButton("Publish") btn.clicked.connect(self.on_publish) layout.addWidget(btn) def on_publish(self): publish(self.show_, self.task, self.name, self.data)
Zwróć uwagę, że on_publish() woła dokładnie tę samą funkcję publish(), którą napisałeś w Kroku 2 — okno nie duplikuje logiki, tylko daje jej przycisk. Dokładnie tak, jak Rozdział 15 opisał różnicę między skryptem a narzędziem.
Masz już wszystkie cztery elementy: konwencję ścieżek, publish script, hook i okno. Spróbuj rozbudować to samodzielnie — dodaj plik logu symulujący system śledzenia z Rozdziału 8, albo prostą blokadę pliku odzwierciedlającą mechanizm z Rozdziału 6. Każdy z tych kroków to już tylko powtórzenie tego samego wzorca: mały, czytelny fragment kodu, rozwiązujący dokładnie jeden problem.