update
This commit is contained in:
@@ -4,3 +4,5 @@
|
||||
- [feedback_edit_icon_pattern.md](feedback_edit_icon_pattern.md) — Ikonka ✎ na hover z dropdown menu — reuse pattern
|
||||
- [feedback_generowanie_imie_dziecka.md](feedback_generowanie_imie_dziecka.md) — Imię dziecka do skryptów generowania musi być w dopełniaczu (Ignacy → Ignacego)
|
||||
- [feedback_generowanie_pythonutf8.md](feedback_generowanie_pythonutf8.md) — Skrypty generowania uruchamiaj z PYTHONUTF8=1 (emoji/Unicode w od_kogo/życzeniach)
|
||||
- [feedback_generowanie_widocznosc_warstw.md](feedback_generowanie_widocznosc_warstw.md) — Przy eksploracji PSD sprawdzaj visible warstw — niewidoczne grupy mylą wybór celu edycji
|
||||
- [feedback_mysql_polskie_znaki.md](feedback_mysql_polskie_znaki.md) — LIKE z polskimi znakami (ł) przez shell→mysql może fałszywie zwracać 0 — użyj hex-encoded CONCAT
|
||||
|
||||
11
.claude/memory/feedback_generowanie_widocznosc_warstw.md
Normal file
11
.claude/memory/feedback_generowanie_widocznosc_warstw.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
name: Widocznosc warstw przy eksploracji PSD
|
||||
description: Przy eksplorowaniu struktury szablonu PSD sprawdzaj visible, nie tylko strukturę — niewidoczne grupy mogą zmylić, którą grupę edytować
|
||||
type: feedback
|
||||
originSessionId: 6b490a59-53d2-4351-8049-2be9d065ec83
|
||||
---
|
||||
Przy pisaniu skryptów generowania z szablonu PSD — eksplorator warstw MUSI raportować `visible` dla każdej grupy i warstwy. Sama struktura nazw nie wystarczy.
|
||||
|
||||
**Why:** W szablonie Łabędzie były dwie grupy o tej samej funkcji — `dane` (semantyczne nazwy: imiona, data, podziekowanie — ale `visible=False`, niedokończony eksperyment) oraz `Warstwa 1` (literalne nazwy: "Przemek", "Ania", "17.08.2024" — `visible=True`, aktywny design). Skrypt edytował `dane` (lepiej nazwane), ale render pokazywał `Warstwa 1`. Plik wychodził "nietknięty" mimo że log pokazywał podmianę.
|
||||
|
||||
**How to apply:** W `_tmp_explore_*.py` zawsze drukuj `visible` dla `layerSets` i `artLayers`. Przy wyborze grupy docelowej — preferuj `visible=True`. Jeśli są dwie kandydatki (widoczna z dziwnymi nazwami + ukryta z ładnymi) — najpierw przemianuj warstwy w widocznej na czytelne semantyczne nazwy, potem pisz skrypt.
|
||||
21
.claude/memory/feedback_mysql_polskie_znaki.md
Normal file
21
.claude/memory/feedback_mysql_polskie_znaki.md
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
name: Polskie znaki w mysql LIKE przez shell
|
||||
description: LIKE z polskimi znakami (szczególnie ł) w zapytaniach mysql uruchamianych z git-bash nie zawsze dopasowuje — użyj hex-encoded pattern w CONCAT
|
||||
type: feedback
|
||||
originSessionId: 6b490a59-53d2-4351-8049-2be9d065ec83
|
||||
---
|
||||
Przy filtrowaniu klientów w `/wygeneruj-projekty` — jeśli imię/nazwisko zawiera polskie znaki (szczególnie `ł`, ale też `ę`/`ń` w niektórych kombinacjach), LIKE w postaci `WHERE oa.name LIKE '%Małgorzata%'` przekazane przez `mysql.exe -e "..."` z git-bash może zwracać **zero wyników**, mimo że rekord istnieje w bazie.
|
||||
|
||||
**Why:** shell/terminal/console transkoduje polskie znaki niespójnie między git-bash a mysql.exe (ConvertTo z UTF-8 na code page Windows i z powrotem). Charset kliencki `--default-character-set=utf8mb4` nie zawsze to naprawia. Rekord w bazie jest poprawnie UTF-8, ale pattern LIKE po przejściu przez shell zawiera inne bajty.
|
||||
|
||||
**How to apply:** Jeśli zapytanie dopasowania klienta po nazwisku zwraca 0 wyników, a jesteś pewny że rekord istnieje — ponów z hex-encoded wzorcem:
|
||||
|
||||
```sql
|
||||
-- Zamiast: WHERE oa.name LIKE '%Stępińska%'
|
||||
-- Użyj:
|
||||
WHERE oa.name LIKE CONCAT('%', 0x5374C4997069C584736B61, '%')
|
||||
```
|
||||
|
||||
Hex wygenerować w shell: `printf 'Stępińska' | od -An -tx1 | tr -d ' \n'` → `5374C4997069C584736B61`.
|
||||
|
||||
Lub użyj samego fragmentu bez polskich znaków (np. tylko nazwisko `%tarnowska%`, `%fundakowska%`) gdy to wystarcza do jednoznacznego dopasowania.
|
||||
71
.paul/governance/governance_2026-04-22.jsonl
Normal file
71
.paul/governance/governance_2026-04-22.jsonl
Normal file
@@ -0,0 +1,71 @@
|
||||
{"ts":"2026-04-21T22:42:24Z","tool":"Bash","cmd":"cmd //c start \"\" \"C:\\\\Program Files\\\\Adobe\\\\Adobe Photoshop 2026\\\\Photoshop.exe\"\",\"description\":\"Launch Photoshop 2026\"},\"tool_response\":{\"stdout\":\"\",\"stderr\":\"\",\"interrupt","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T07:27:22Z","tool":"Bash","cmd":"tasklist //FI \"IMAGENAME eq Photoshop.exe\" 2>/dev/null | grep -i photoshop\",\"description\":\"Check if Photoshop is running\"},\"tool_response\":{\"stdout\":\"\",\"stderr\":\"\",\"interrupted\":fal","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T07:29:27Z","tool":"Bash","cmd":"tasklist //FI \"IMAGENAME eq Photoshop.exe\" 2>/dev/null | grep -i photoshop\",\"description\":\"Verify Photoshop is running\"},\"tool_response\":{\"stdout\":\"Binary file (standard input) matches\",\","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T07:51:04Z","tool":"Bash","cmd":"tasklist //FI \"IMAGENAME eq Photoshop.exe\" 2>/dev/null | grep -i photoshop || echo \"Photoshop NIE jest uruchomiony\"\",\"description\":\"Check if Photoshop is running\"},\"tool_response\":{\"stdout","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T07:53:14Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tools\\\\generowanie\\\\_tmp_explore_wzor3.py","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:20:18Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && php -r \"require 'config/bootstrap.php'; \\\\$db = \\\\$GLOBALS['db'] ?? null; if(!\\\\$db){ \\\\$db = (require 'config/database.php'); } \\\\$rows = ","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:20:45Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:20:55Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:21:07Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:21:15Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:21:52Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\_tmp_mapping.sql","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:22:02Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:22:12Z","tool":"Bash","cmd":"rm \"C:/visual studio code/projekty/orderPRO/_tmp_mapping.sql\" && echo OK\",\"description\":\"Remove temp SQL file\"},\"tool_response\":{\"stdout\":\"OK\",\"stderr\":\"\",\"interrupted\":false,\"isIm","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:23:00Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\_tmp_query.sql","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:23:06Z","tool":"Bash","cmd":"tasklist //FI \"IMAGENAME eq Photoshop.exe\" 2>/dev/null | grep -ci photoshop || echo \"0\"\",\"description\":\"Check if Photoshop is running\"},\"tool_response\":{\"stdout\":\"1\",\"stderr\":\"\",\"i","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:23:15Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:23:27Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && python tools/generowanie/email_message_fetcher.py --email \"leszek.krzem@wp.pl\" --days 60 --json 2>&1 | head -20\",\"timeout\":60000,\"description\":","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:23:55Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && PYTHONUTF8=1 python tools/generowanie/buteleczki_urodziny_wzor3.py --imie \"Agnieszki\" --wiek \"50\" --klient \"Agnieszka Krzemińska\" 2>&1\",\"time","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:24:09Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\_tmp_mark.sql","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:24:17Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:26:06Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\_tmp_query.sql","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:26:15Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:26:27Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && python tools/generowanie/email_message_fetcher.py --email \"oliwia.mowinska.06@wp.pl\" --days 60 --json 2>&1 | head -5\",\"timeout\":60000,\"descripti","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:27:00Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && PYTHONUTF8=1 python tools/generowanie/buteleczki_slub_wzor4.py --imie_zenskie \"Oliwia\" --imie_meskie \"Dominik\" --data \"20.06.2026\" --klient \"Ol","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:27:07Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\_tmp_mark.sql","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:27:17Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:35:02Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\_tmp_query.sql","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:35:11Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:35:27Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && python tools/generowanie/email_message_fetcher.py --email \"aleksandrazuchniarz@wp.pl\" --days 60 --json 2>&1 | head -3\",\"timeout\":60000,\"descript","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:36:00Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && PYTHONUTF8=1 python tools/generowanie/buteleczki_slub_mloda_para.py --imiona \"Aleksandra i Piotr\" --data \"15.08.2026\" --klient \"Aleksandra Zuchni","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:36:07Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\_tmp_mark.sql","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:36:22Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:37:37Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\_tmp_query.sql","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:37:46Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:37:57Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && python tools/generowanie/email_message_fetcher.py --email \"aniapilarczyk@onet.pl\" --days 60 --json 2>&1 | head -3\",\"timeout\":60000,\"description\","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:38:19Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && PYTHONUTF8=1 python tools/generowanie/buteleczki_slub_mloda_para.py --imiona \"Ania i Maciek\" --data \"09.05.2026\" --klient \"Ania Pilarczyk\" 2>&1\","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:38:25Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\_tmp_mark.sql","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:38:33Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:39:31Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\_tmp_query.sql","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:39:43Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && source <(grep -E '^(DB_HOST_REMOTE|DB_HOST|DB_PORT|DB_DATABASE|DB_USERNAME|DB_PASSWORD)=' .env | sed 's/=\\\\(.*\\\\)/=\"\\\\1\"/') && HOST=${DB_HOST_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:40:09Z","tool":"Bash","cmd":"rm \"C:/visual studio code/projekty/orderPRO/_tmp_query.sql\" 2>/dev/null && echo OK\",\"description\":\"Cleanup temp SQL file\"},\"tool_response\":{\"stdout\":\"OK\",\"stderr\":\"\",\"interrupted\":f","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:41:25Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tools\\\\generowanie\\\\_tmp_explore_labedzie.py","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:42:23Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && PYTHONUTF8=1 python tools/generowanie/buteleczki_slub_labedzie.py --imiona \"Ania i Maciek\" --data \"09.05.2026\" --klient \"TEST_Ania_Pilarczyk\" 2>","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:46:45Z","tool":"Bash","cmd":"tasklist //FI \"IMAGENAME eq Photoshop.exe\" 2>/dev/null | grep -i photoshop || echo \"Photoshop NIE jest uruchomiony\"\",\"description\":\"Check if Photoshop is running\"},\"tool_response\":{\"stdout","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:47:42Z","tool":"Bash","cmd":"where python 2>/dev/null; where python3 2>/dev/null; where py 2>/dev/null\",\"description\":\"Find Python installation\"},\"tool_response\":{\"stdout\":\"C:\\\\Users\\\\jacek\\\\AppData\\\\Local\\\\Pr","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T08:54:20Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tools\\\\generowanie\\\\buteleczki_slub_labedzie.py","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T09:05:38Z","tool":"Bash","cmd":"rm \"C:/visual studio code/projekty/orderPRO/tools/generowanie/_tmp_explore_labedzie.py\" && echo \"Usunięto\"\",\"description\":\"Remove temporary explorer file\"},\"tool_response\":{\"stdout\":\"Us","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T09:11:26Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tools\\\\generowanie\\\\buteleczki_slub_labedzie.py","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T09:11:36Z","tool":"Bash","cmd":"rm \"d:/pomysloweprezenty.pl/projekty/ślub - buteleczki/Podziękowanie dla gości weselnych buteleczka z nadrukiem UV - Łabędzie/_gotowe/Ania Pilarczyk.psd\" && echo \"usunieto stary plik\"\",\"des","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T09:11:53Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tools\\\\generowanie\\\\buteleczki_slub_labedzie.py","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T09:15:07Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tools\\\\generowanie\\\\buteleczki_slub_labedzie.py","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T09:16:05Z","tool":"Write","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\projects\\\\C--visual-studio-code-projekty-orderPRO\\\\memory\\\\feedback_generowanie_widocznosc_warstw.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T09:16:14Z","tool":"Edit","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\projects\\\\C--visual-studio-code-projekty-orderPRO\\\\memory\\\\MEMORY.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T10:27:54Z","tool":"Write","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\projects\\\\C--visual-studio-code-projekty-orderPRO\\\\memory\\\\feedback_mysql_polskie_znaki.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T10:28:01Z","tool":"Edit","file":"C:\\\\Users\\\\jacek\\\\.claude\\\\projects\\\\C--visual-studio-code-projekty-orderPRO\\\\memory\\\\MEMORY.md","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T10:56:16Z","tool":"Bash","cmd":"tasklist //FI \"IMAGENAME eq Photoshop.exe\" 2>/dev/null | grep -i photoshop; ls -la \"d:/pomysloweprezenty.pl/projekty/ślub - magnesy/Magnes podziękowanie dla gości weselnych na plastrze brzozy - ","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T10:56:34Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tools\\\\generowanie\\\\_explore_tmp.py","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T10:56:42Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && PYTHONUTF8=1 python tools/generowanie/_explore_tmp.py 2>&1 | head -200\",\"description\":\"Explore PSD structure\"},\"tool_response\":{\"stdout\":\"==","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:12:09Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tools\\\\generowanie\\\\_explore_tmp.py","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:12:16Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && PYTHONUTF8=1 python tools/generowanie/_explore_tmp.py 2>&1 | tail -10\",\"description\":\"Check layer bounds\"},\"tool_response\":{\"stdout\":\"\"Sewe","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:12:26Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tools\\\\generowanie\\\\_rename_tmp.py","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:12:34Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && PYTHONUTF8=1 python tools/generowanie/_rename_tmp.py 2>&1 | tail -5\",\"description\":\"Rename layers in PSD\"},\"tool_response\":{\"stdout\":\"OK ren","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:13:03Z","tool":"Write","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tools\\\\generowanie\\\\magnes_slub_plaster_brzozy_kwiaty_wzor8.py","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:13:11Z","tool":"Edit","file":"C:\\\\visual studio code\\\\projekty\\\\orderPRO\\\\tools\\\\generowanie\\\\magnes_slub_plaster_brzozy_kwiaty_wzor8.py","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:13:24Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && PYTHONUTF8=1 python tools/generowanie/magnes_slub_plaster_brzozy_kwiaty_wzor8.py --klient \"test_ania_maciek\" --imie_zenskie \"Ania\" --imie_meskie \","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:13:30Z","tool":"Bash","cmd":"rm \"C:/visual studio code/projekty/orderPRO/tools/generowanie/_explore_tmp.py\" \"C:/visual studio code/projekty/orderPRO/tools/generowanie/_rename_tmp.py\"\",\"description\":\"Remove temp scripts\"}","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:15:19Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && grep -E \"^(DB_HOST_REMOTE|DB_DATABASE|DB_USERNAME|DB_PASSWORD|DB_PORT)=\" .env\",\"description\":\"Read DB env\"},\"tool_response\":{\"stdout\":\"DB_","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:15:30Z","tool":"Bash","cmd":"\"C:/xampp/mysql/bin/mysql.exe\" -h host700513.hostido.net.pl -P 3306 -u host700513_orderpro -phrDNtUBg9grwZ7syN77S host700513_orderpro --default-character-set=utf8mb4 -e \"SELECT oi.id AS item_id, oi","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:15:40Z","tool":"Bash","cmd":"cd \"C:/visual studio code/projekty/orderPRO\" && python tools/generowanie/email_message_fetcher.py --email \"edyta1407@op.pl\" --days 60 --json 2>&1 | tail -20\",\"description\":\"Check client emails","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:16:09Z","tool":"Bash","cmd":"rm -f \"d:/pomysloweprezenty.pl/projekty/ślub - magnesy/Magnes podziękowanie dla gości weselnych na plastrze brzozy - Kwiaty Wzór 8/_gotowe/test_ania_maciek.psd\" && cd \"C:/visual studio code/pro","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
{"ts":"2026-04-22T11:16:17Z","tool":"Bash","cmd":"\"C:/xampp/mysql/bin/mysql.exe\" -h host700513.hostido.net.pl -P 3306 -u host700513_orderpro -phrDNtUBg9grwZ7syN77S host700513_orderpro --default-character-set=utf8mb4 -e \"UPDATE order_items SET proj","cwd":"/c/visual studio code/projekty/orderPRO"}
|
||||
56
.vscode/ftp-kr.sync.cache.json
vendored
56
.vscode/ftp-kr.sync.cache.json
vendored
@@ -5739,6 +5739,12 @@
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"buteleczki_slub_wzor3.py": {
|
||||
"type": "-",
|
||||
"size": 5701,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"buteleczki_slub_wzor4.py": {
|
||||
"type": "-",
|
||||
"size": 5304,
|
||||
@@ -5781,11 +5787,17 @@
|
||||
"lmtime": 1776018627219,
|
||||
"modified": false
|
||||
},
|
||||
"_explore_psd.py": {
|
||||
"type": "-",
|
||||
"size": 1571,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"_explore_temp.py": {
|
||||
"type": "-",
|
||||
"size": 1681,
|
||||
"size": 3438,
|
||||
"lmtime": 1776017342215,
|
||||
"modified": false
|
||||
"modified": true
|
||||
},
|
||||
"_explore_tmp.py": {
|
||||
"type": "-",
|
||||
@@ -5793,6 +5805,12 @@
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"_explore_wzor3.py": {
|
||||
"type": "-",
|
||||
"size": 3585,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"magnes_babcia_kocham_babciu.py": {
|
||||
"type": "-",
|
||||
"size": 2208,
|
||||
@@ -5817,6 +5835,12 @@
|
||||
"lmtime": 1776029394137,
|
||||
"modified": false
|
||||
},
|
||||
"magnes_wieczor_panienski_pierscionek.py": {
|
||||
"type": "-",
|
||||
"size": 2896,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"magnes_wieczor_panienski_szampan.py": {
|
||||
"type": "-",
|
||||
"size": 2807,
|
||||
@@ -5829,6 +5853,12 @@
|
||||
"lmtime": 1776031123643,
|
||||
"modified": false
|
||||
},
|
||||
"pudelko_chrzest_aniolek_chlopak_hdf_uv.py": {
|
||||
"type": "-",
|
||||
"size": 3588,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"pudelko_chrzest_dlonie_uv.py": {
|
||||
"type": "-",
|
||||
"size": 3483,
|
||||
@@ -5921,11 +5951,17 @@
|
||||
"modified": false
|
||||
}
|
||||
},
|
||||
"_rename_psd.py": {
|
||||
"type": "-",
|
||||
"size": 1978,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"_rename_temp.py": {
|
||||
"type": "-",
|
||||
"size": 1394,
|
||||
"size": 1700,
|
||||
"lmtime": 1776017830161,
|
||||
"modified": false
|
||||
"modified": true
|
||||
},
|
||||
"_rename_tmp.py": {
|
||||
"type": "-",
|
||||
@@ -5933,6 +5969,12 @@
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"_rename_wzor3.py": {
|
||||
"type": "-",
|
||||
"size": 2723,
|
||||
"lmtime": 0,
|
||||
"modified": false
|
||||
},
|
||||
"_tmp_photos": {
|
||||
"01_IMG_7330.jpeg": {
|
||||
"type": "-",
|
||||
@@ -5958,6 +6000,12 @@
|
||||
"size": 5328,
|
||||
"lmtime": 1776032317220,
|
||||
"modified": false
|
||||
},
|
||||
"pudelko_chrzest_spiacy_aniolek_chlopak_hdf_uv.py": {
|
||||
"type": "-",
|
||||
"size": 3588,
|
||||
"lmtime": 1776763857067,
|
||||
"modified": false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
173
tools/generowanie/buteleczki_slub_labedzie.py
Normal file
173
tools/generowanie/buteleczki_slub_labedzie.py
Normal file
@@ -0,0 +1,173 @@
|
||||
"""
|
||||
Generator PSD — Podziękowanie dla gości weselnych (buteleczka, Łabędzie).
|
||||
|
||||
Szablon 370x300 to layout 8-up: 8 instancji Smart Object linkujących do
|
||||
jednego źródła (Warstwa 1.psb). Edycja zawartości jednej warstwy SO
|
||||
propaguje się na wszystkie 8 kopii w arkuszu.
|
||||
|
||||
Wewnątrz SO warstwy tekstowe są w grupie "Warstwa 1":
|
||||
imie_zenskie, imie_meskie, data, zyczenia
|
||||
(separator "&" zostaje bez zmian)
|
||||
|
||||
Wymaga: uruchomiony Adobe Photoshop, pakiet photoshop-python-api.
|
||||
|
||||
Użycie:
|
||||
python buteleczki_slub_labedzie.py --klient "Ania Pilarczyk" \
|
||||
--imie_zenskie "Ania" --imie_meskie "Maciek" --data "09.05.2026"
|
||||
|
||||
python buteleczki_slub_labedzie.py --klient "Ania Pilarczyk" \
|
||||
--imie_zenskie "Ania" --imie_meskie "Maciek" --data "09.05.2026" \
|
||||
--zyczenia "DZIĘKUJEMY!"
|
||||
"""
|
||||
|
||||
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 - Łabędzie",
|
||||
)
|
||||
SZABLON_PATH = os.path.join(PROJEKT_DIR, "szablon 370x300.psd")
|
||||
GOTOWE_DIR = os.path.join(PROJEKT_DIR, "_gotowe")
|
||||
|
||||
# Grupa z tekstami wewnątrz Smart Object (Warstwa 1.psb)
|
||||
TEKST_GROUP = "Warstwa 1"
|
||||
|
||||
# Kind code dla Smart Object w photoshop-python-api
|
||||
SMART_OBJECT_KIND = 17
|
||||
|
||||
|
||||
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 zachowując środek bounding boxa
|
||||
(kompensacja dla warstw z wyśrodkowaną justyfikacją)."""
|
||||
b = [float(x) for x in layer.bounds]
|
||||
cx_before, cy_before = (b[0] + b[2]) / 2, (b[1] + b[3]) / 2
|
||||
|
||||
layer.textItem.contents = new_text
|
||||
|
||||
b2 = [float(x) for x in layer.bounds]
|
||||
cx_after, cy_after = (b2[0] + b2[2]) / 2, (b2[1] + b2[3]) / 2
|
||||
|
||||
dx, dy = cx_before - cx_after, cy_before - cy_after
|
||||
if dx or dy:
|
||||
layer.translate(dx, dy)
|
||||
|
||||
|
||||
def find_first_smart_object(doc):
|
||||
"""Zwraca pierwszą warstwę Smart Object w dokumencie.
|
||||
|
||||
Wszystkie 8 kopii linkuje do jednego .psb, więc edycja jednej
|
||||
propaguje zmiany na pozostałe.
|
||||
"""
|
||||
for layer in doc.artLayers:
|
||||
if layer.kind == SMART_OBJECT_KIND:
|
||||
return layer
|
||||
raise RuntimeError("Nie znaleziono warstwy Smart Object w szablonie")
|
||||
|
||||
|
||||
def close_all_without_saving(app):
|
||||
"""Zamyka wszystkie otwarte dokumenty bez zapisu (awaryjne sprzątanie)."""
|
||||
while app.documents.length > 0:
|
||||
app.activeDocument.close(ps.SaveOptions.DoNotSaveChanges)
|
||||
|
||||
|
||||
def generate(klient, imie_zenskie, imie_meskie, data, 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}")
|
||||
|
||||
try:
|
||||
so_layer = find_first_smart_object(doc)
|
||||
app.activeDocument.activeLayer = so_layer
|
||||
open_smart_object(app)
|
||||
so_doc = app.activeDocument
|
||||
print(f"Wszedłem do Smart Object: {so_doc.name}")
|
||||
|
||||
tekst = so_doc.layerSets[TEKST_GROUP]
|
||||
|
||||
replacements = {
|
||||
"imie_zenskie": imie_zenskie,
|
||||
"imie_meskie": imie_meskie,
|
||||
"data": data,
|
||||
}
|
||||
if zyczenia is not None:
|
||||
replacements["zyczenia"] = zyczenia
|
||||
|
||||
print("Podmiana tekstów:")
|
||||
for layer_name, new_text in replacements.items():
|
||||
layer = tekst.artLayers[layer_name]
|
||||
old_text = layer.textItem.contents
|
||||
change_text_preserve_position(layer, new_text)
|
||||
print(f' {layer_name}: "{old_text}" -> "{new_text}"')
|
||||
|
||||
so_doc.save()
|
||||
so_doc.close()
|
||||
print("Smart Object zapisany")
|
||||
|
||||
# Wymus odswiezenie cache wszystkich Smart Objectow w glownym dokumencie
|
||||
# — bez tego saveAs zapisze stary composite, mimo ze warstwy tekstowe
|
||||
# wewnatrz SO maja nowe wartosci.
|
||||
app.executeAction(
|
||||
app.stringIDToTypeID("placedLayerUpdateAllModified"),
|
||||
ps.ActionDescriptor(),
|
||||
)
|
||||
|
||||
psd_opts = ps.PhotoshopSaveOptions()
|
||||
app.activeDocument.saveAs(output_path, psd_opts, True)
|
||||
print(f"Zapisano: {output_path}")
|
||||
|
||||
app.activeDocument.close(ps.SaveOptions.DoNotSaveChanges)
|
||||
except Exception:
|
||||
close_all_without_saving(app)
|
||||
raise
|
||||
|
||||
print("Gotowe!")
|
||||
return output_path
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generator PSD - buteleczki ślubne (Łabędzie) 370x300 8-up"
|
||||
)
|
||||
parser.add_argument("--klient", required=True, help="Nazwa pliku wyjściowego (bez rozszerzenia)")
|
||||
parser.add_argument("--imie_zenskie", required=True, help="Imię żeńskie (np. Ania)")
|
||||
parser.add_argument("--imie_meskie", required=True, help="Imię męskie (np. Maciek)")
|
||||
parser.add_argument("--data", required=True, help="Data uroczystości (DD.MM.YYYY)")
|
||||
parser.add_argument(
|
||||
"--zyczenia",
|
||||
default=None,
|
||||
help='Tekst życzeń (opcjonalnie, domyślnie "NA ZDROWIE!" z szablonu)',
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
generate(
|
||||
klient=args.klient,
|
||||
imie_zenskie=args.imie_zenskie,
|
||||
imie_meskie=args.imie_meskie,
|
||||
data=args.data,
|
||||
zyczenia=args.zyczenia,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
160
tools/generowanie/buteleczki_urodziny_wzor3.py
Normal file
160
tools/generowanie/buteleczki_urodziny_wzor3.py
Normal file
@@ -0,0 +1,160 @@
|
||||
"""
|
||||
Generator PSD — Podziękowanie dla gości buteleczka urodziny (Wzór 3).
|
||||
|
||||
Otwiera szablon PSD, podmienia teksty w Smart Object z zachowaniem pozycji warstw,
|
||||
zapisuje jako nowy PSD w folderze _gotowe.
|
||||
|
||||
Szablon zawiera 8 linked instancji tego samego Smart Object (arkusz drukarski) —
|
||||
edycja jednego SO propaguje się do wszystkich 8 kopii.
|
||||
|
||||
Wymaga: uruchomiony Adobe Photoshop, pakiet photoshop-python-api.
|
||||
|
||||
Użycie:
|
||||
python buteleczki_urodziny_wzor3.py --imie "Agnieszki" --wiek "25" --klient "Agnieszka Kowalska"
|
||||
|
||||
python buteleczki_urodziny_wzor3.py --imie "Agnieszki" --wiek "25" \
|
||||
--naglowek "urodziny" --klient "Agnieszka Kowalska"
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import photoshop.api as ps
|
||||
|
||||
|
||||
# --- Ścieżki ---
|
||||
PROJEKT_DIR = os.path.join(
|
||||
r"d:\pomysloweprezenty.pl\projekty\urodziny - buteleczki",
|
||||
"Podziękowanie dla gości buteleczka z nadrukiem UV - Wzór 3",
|
||||
)
|
||||
SZABLON_PATH = os.path.join(PROJEKT_DIR, "szablon 370x300.psd")
|
||||
GOTOWE_DIR = os.path.join(PROJEKT_DIR, "_gotowe")
|
||||
|
||||
# Nazwa warstwy Smart Object w głównym PSD.
|
||||
# W szablonie jest 8 linked kopii tego samego SO ("Warstwa 2", "Warstwa 2 kopia", ...).
|
||||
# Wystarczy wejść w dowolną — zmiana propaguje się do wszystkich.
|
||||
SMART_OBJECT_LAYER = "Warstwa 2"
|
||||
|
||||
# Grupa w Smart Object, w której leżą warstwy tekstowe.
|
||||
TEKST_GROUP = "Warstwa 1"
|
||||
|
||||
|
||||
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.
|
||||
|
||||
Uwzglednia justowanie:
|
||||
- center (2): zachowuje srodek poziomy
|
||||
- right (3): zachowuje prawa krawedz
|
||||
- left (1): zachowuje lewa krawedz
|
||||
W pionie zawsze zachowuje gora (pierwsza linia bazowa).
|
||||
"""
|
||||
bounds_before = [float(b) for b in layer.bounds]
|
||||
|
||||
try:
|
||||
just_int = int(layer.textItem.justification)
|
||||
except Exception:
|
||||
just_int = 1
|
||||
|
||||
layer.textItem.contents = new_text
|
||||
bounds_after = [float(b) for b in layer.bounds]
|
||||
|
||||
if just_int == 2:
|
||||
cx_before = (bounds_before[0] + bounds_before[2]) / 2
|
||||
cx_after = (bounds_after[0] + bounds_after[2]) / 2
|
||||
dx = cx_before - cx_after
|
||||
elif just_int == 3:
|
||||
dx = bounds_before[2] - bounds_after[2]
|
||||
else:
|
||||
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(imie, wiek, klient, naglowek=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
|
||||
try:
|
||||
target = doc.artLayers[SMART_OBJECT_LAYER]
|
||||
except Exception:
|
||||
doc.close(ps.SaveOptions.DoNotSaveChanges)
|
||||
raise RuntimeError(f"Nie znaleziono warstwy '{SMART_OBJECT_LAYER}'")
|
||||
|
||||
app.activeDocument.activeLayer = target
|
||||
open_smart_object(app)
|
||||
so_doc = app.activeDocument
|
||||
|
||||
# Nawigacja do grupy z tekstami
|
||||
grupa = so_doc.layerSets[TEKST_GROUP]
|
||||
|
||||
# Podmiana tekstów
|
||||
replacements = {
|
||||
"imie": imie,
|
||||
"wiek": str(wiek),
|
||||
}
|
||||
if naglowek is not None:
|
||||
replacements["naglowek"] = naglowek
|
||||
|
||||
for layer_name, new_text in replacements.items():
|
||||
layer = grupa.artLayers[layer_name]
|
||||
old_text = layer.textItem.contents
|
||||
change_text_preserve_position(layer, new_text)
|
||||
print(f" {layer_name}: \"{old_text}\" -> \"{new_text}\"")
|
||||
|
||||
# Zapisz Smart Object (propaguje do wszystkich 8 linked instancji)
|
||||
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 oryginał bez zapisu
|
||||
app.activeDocument.close(ps.SaveOptions.DoNotSaveChanges)
|
||||
print("Gotowe!")
|
||||
return output_path
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generator PSD - buteleczki urodziny Wzór 3"
|
||||
)
|
||||
parser.add_argument("--imie", required=True, help="Imię w dopełniaczu (np. Agnieszki)")
|
||||
parser.add_argument("--wiek", required=True, help="Wiek jubilata (np. 25)")
|
||||
parser.add_argument("--klient", required=True, help="Imię i nazwisko klienta (nazwa pliku wyjściowego)")
|
||||
parser.add_argument("--naglowek", default=None, help="Tekst nagłówka (domyślnie: 'urodziny' z szablonu)")
|
||||
|
||||
args = parser.parse_args()
|
||||
generate(
|
||||
imie=args.imie,
|
||||
wiek=args.wiek,
|
||||
klient=args.klient,
|
||||
naglowek=args.naglowek,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
110
tools/generowanie/magnes_slub_plaster_brzozy_kwiaty_wzor8.py
Normal file
110
tools/generowanie/magnes_slub_plaster_brzozy_kwiaty_wzor8.py
Normal file
@@ -0,0 +1,110 @@
|
||||
"""
|
||||
Generator PSD — Magnes podziekowanie na plastrze brzozy (Kwiaty, Wzor 8).
|
||||
|
||||
Szablon jest plaski (bez Smart Object). Warstwy tekstowe:
|
||||
doc."data" — data uroczystosci
|
||||
doc."<grupa>"."Dane"."imie_zenskie" — imie panny mlodej (lewa)
|
||||
doc."<grupa>"."Dane"."imie_meskie" — imie pana mlodego (prawa)
|
||||
|
||||
Wymaga: uruchomiony Adobe Photoshop, pakiet photoshop-python-api.
|
||||
|
||||
Uzycie:
|
||||
python magnes_slub_plaster_brzozy_kwiaty_wzor8.py --klient "Nowak" \\
|
||||
--imie_zenskie "Kasia" --imie_meskie "Jakub" --data "31.07.2025"
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import photoshop.api as ps
|
||||
|
||||
|
||||
PROJEKT_DIR = os.path.join(
|
||||
"d:\\pomysloweprezenty.pl\\projekty\\ślub - magnesy",
|
||||
"Magnes podziękowanie dla gości weselnych na plastrze brzozy - Kwiaty Wzór 8",
|
||||
)
|
||||
SZABLON_PATH = os.path.join(
|
||||
PROJEKT_DIR,
|
||||
"Magnes podziękowanie dla gości weselnych na plastrze brzozy - Kwiaty Wzór 8.psd",
|
||||
)
|
||||
GOTOWE_DIR = os.path.join(PROJEKT_DIR, "_gotowe")
|
||||
|
||||
GRUPA_TOP = "<grupa>"
|
||||
GRUPA_DANE = "Dane"
|
||||
|
||||
|
||||
def change_text_preserve_position(layer, new_text):
|
||||
"""Zmienia tekst warstwy zachowujac srodek bounding boxa."""
|
||||
b = [float(x) for x in layer.bounds]
|
||||
cx_before, cy_before = (b[0] + b[2]) / 2, (b[1] + b[3]) / 2
|
||||
|
||||
layer.textItem.contents = new_text
|
||||
|
||||
b2 = [float(x) for x in layer.bounds]
|
||||
cx_after, cy_after = (b2[0] + b2[2]) / 2, (b2[1] + b2[3]) / 2
|
||||
|
||||
dx, dy = cx_before - cx_after, cy_before - cy_after
|
||||
if dx or dy:
|
||||
layer.translate(dx, dy)
|
||||
|
||||
|
||||
def close_all_without_saving(app):
|
||||
while app.documents.length > 0:
|
||||
app.activeDocument.close(ps.SaveOptions.DoNotSaveChanges)
|
||||
|
||||
|
||||
def generate(klient, imie_zenskie, imie_meskie, data):
|
||||
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}")
|
||||
|
||||
try:
|
||||
dane = doc.layerSets[GRUPA_TOP].layerSets[GRUPA_DANE]
|
||||
|
||||
replacements = [
|
||||
(doc.artLayers["data"], data, "data"),
|
||||
(dane.artLayers["imie_zenskie"], imie_zenskie, "imie_zenskie"),
|
||||
(dane.artLayers["imie_meskie"], imie_meskie, "imie_meskie"),
|
||||
]
|
||||
|
||||
print("Podmiana tekstow:")
|
||||
for layer, new_text, label in replacements:
|
||||
old = layer.textItem.contents
|
||||
change_text_preserve_position(layer, new_text)
|
||||
print(f' {label}: "{old}" -> "{new_text}"')
|
||||
|
||||
psd_opts = ps.PhotoshopSaveOptions()
|
||||
app.activeDocument.saveAs(output_path, psd_opts, True)
|
||||
print(f"Zapisano: {output_path}")
|
||||
|
||||
app.activeDocument.close(ps.SaveOptions.DoNotSaveChanges)
|
||||
except Exception:
|
||||
close_all_without_saving(app)
|
||||
raise
|
||||
|
||||
print("Gotowe!")
|
||||
return output_path
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generator PSD - Magnes slubny na plastrze brzozy (Kwiaty Wzor 8)"
|
||||
)
|
||||
parser.add_argument("--klient", required=True, help="Nazwa pliku wyjsciowego (bez rozszerzenia)")
|
||||
parser.add_argument("--imie_zenskie", required=True, help="Imie panny mlodej (lewa strona)")
|
||||
parser.add_argument("--imie_meskie", required=True, help="Imie pana mlodego (prawa strona)")
|
||||
parser.add_argument("--data", required=True, help="Data uroczystosci (DD.MM.YYYY)")
|
||||
|
||||
args = parser.parse_args()
|
||||
generate(
|
||||
klient=args.klient,
|
||||
imie_zenskie=args.imie_zenskie,
|
||||
imie_meskie=args.imie_meskie,
|
||||
data=args.data,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user