From 897bfc83d95ecfc91e5b487cb067ecc79b6ab133 Mon Sep 17 00:00:00 2001 From: hetima <33700+hetima@users.noreply.github.com> Date: Tue, 27 Jan 2026 14:09:37 +0900 Subject: [PATCH] add SLPFilenamePrefix --- README-ja.md | 14 ++++++++- README.md | 14 ++++++++- __init__.py | 4 ++- assets/slp03.jpg | Bin 0 -> 21445 bytes js/slp_filename_prefix.js | 22 ++++++++++++++ slp_filename_prefix.py | 62 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 assets/slp03.jpg create mode 100644 js/slp_filename_prefix.js create mode 100644 slp_filename_prefix.py diff --git a/README-ja.md b/README-ja.md index c4119c2..29c13a6 100644 --- a/README-ja.md +++ b/README-ja.md @@ -30,7 +30,19 @@ デフォルトのローダーとほぼ同じです。LoRAファイルの指定部分がコンボボックスではなくテキストになっているのでSingle Line Pickerを直接繋げることができます。 -出力パラメータ`stem`を持っています。LoRAファイルの拡張子を除いたファイル名を出力します([audioscavenger/save-image-extended-comfyui](https://github.com/audioscavenger/save-image-extended-comfyui) はLoRAの名前を参照することができますが、SLP Lora Loaderの`lora_name`を参照しようとするとエラーが出たため名前を`lora_name_text`に変更しています。この`lora_name_text`を参照したとしてもエラーにはなりませんが、正常な値は取得できません。`stem`出力を加工するなりして対応してください)。 +出力パラメータ`stem`を持っています。LoRAファイルの拡張子を除いたファイル名を出力します。次節のSLP Filename Prefixで利用できます。 + + +### SLP Filename Prefix + +「画像を保存」などのファイルを書き出すノードは`filename_prefix(ファイル名_プレフィックス)`パラメータを持ち`%date:%`方式で現在の日付時刻を設定できます。ただしこれはフロントエンドで前処理されるため、実行中の出力と組み合わせることが難しいのです。`filename_prefix`にインプット接続しても日付時刻の処理はされません。 + +それを解決するためにこのノードでは、日付時刻の処理に加えてプレースホルダによる文字列置き換えを行った結果を出力します。「画像を保存」などの`filename_prefix`に有効な値を渡すことができます。 + +プレースホルダは`$1` `$2` `$3` `$4`と最大4個作ることができ、それぞれ同名のインプットで置き換えられます。入力は文字列と数値に対応しています。 + +![screecshot03](./assets/slp03.jpg) + ## Changelog diff --git a/README.md b/README.md index 9a87eac..fb3b3f5 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,19 @@ When select this node, a button marked with the ![icon](./assets/lora.svg) icon It's almost identical to the default loader. Since the LoRA file selection part is text instead of a combo box so that connect a Single Line Picker directly. -It has an output parameter called `stem`. It outputs LoRA filename without file extension ([audioscavenger/save-image-extended-comfyui](https://github.com/audioscavenger/save-image-extended-comfyui) can reference LoRA name, but since attempting to reference `lora_name` in the SLP Lora Loader caused an error, the name has been changed to `lora_name_text`. Referencing this `lora_name_text` will not cause an error, but it will not retrieve the correct value. Please handle this by modifying the `stem` output or similar means). +It has an output parameter called `stem`. It outputs LoRA filename without file extension. Available in the next section's SLP Filename Prefix. + + +### SLP Filename Prefix + +Nodes that export files, such as "Save Image" feature a `filename_prefix` parameter that can be set to the current date and time using the `%date:%` format. However, since this is preprocessed by the frontend, it is difficult to combine with backend's runtime output. Connecting an input to `filename_prefix` will not process the date and time. + +To resolve this, this node outputs the result of processing the date and time, along with replacing placeholders with strings. You can pass valid value for `filename_prefix` such as "Save Image". + +Placeholders can be created up to four: `$1`, `$2`, `$3`, and `$4`. Each is replaced with an input of the same name. Inputs support string and numeric values. + +![screecshot03](./assets/slp03.jpg) + ## Changelog diff --git a/__init__.py b/__init__.py index 4d5f563..a52a66b 100644 --- a/__init__.py +++ b/__init__.py @@ -1,17 +1,19 @@ from .single_line_picker import SLPSingleLinePicker from .slp_lora_loader import SLPLoraLoader, SLPLoraLoaderModelOnly - +from .slp_filename_prefix import SLPFilenamePrefix NODE_CLASS_MAPPINGS = { SLPSingleLinePicker.NAME: SLPSingleLinePicker, SLPLoraLoader.NAME: SLPLoraLoader, SLPLoraLoaderModelOnly.NAME: SLPLoraLoaderModelOnly, + SLPFilenamePrefix.NAME: SLPFilenamePrefix, } NODE_DISPLAY_NAME_MAPPINGS = { SLPSingleLinePicker.NAME: SLPSingleLinePicker.DISPLAY_NAME, SLPLoraLoader.NAME: SLPLoraLoader.DISPLAY_NAME, SLPLoraLoaderModelOnly.NAME: SLPLoraLoaderModelOnly.DISPLAY_NAME, + SLPFilenamePrefix.NAME: SLPFilenamePrefix.DISPLAY_NAME, } diff --git a/assets/slp03.jpg b/assets/slp03.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b5d5a61cb1ceff9bd22dfe2b7fd47220189dedcf GIT binary patch literal 21445 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

p{hp61pgh@pJ#Kam5ui8K= zKFbSO@+y9+@wJ~R$OLGm1rcwFOhTO*;ht@cJS$*RY_v340F1l_d2a1#e;^>7EF?3G z;)#2`#cL3M+RKGL&{W@4XP?9-hZYlEL#cW_nRxAe0Dja^+msB`X|ZYsfWX$BqctT- zfV#ef?{q;7T`(IS_wWRCka?c<;#n)YuYJwpu;QG9^PII%sR1loLu~P8;9Z|{+WIUIse-4i{|=wzL=$Kp7Qb`BUI?zx z7?)~lNpb_5IfF}PKOP(%dN*ZZJPX@?G5@@#swjXZ?JhQFxE~;f+e%n z&UINcVbY9WT$tzM{k8=Mg{01|ssV|2zSmx{?GapjF=dGETMarY50h7+VOp6Tn#y-c zdGlrXm&_J9axQM^1-`tTEMlm_dS1rIWg}>q---;018!?xFJ)3Yi4rE^C-Fq!Z!TGA zo#9aGL0ldDLRJg*#6 zPTi1@@lhj2MV8Rmu#i$gtdp#ny1MLJPQ5iLgEljfdd8-jg^Kjf$(qH8a%S%b3%Jaj z20^jH&b$%4cp2>}x3*5&%Va@Aa{^M~<}y!sTxCf%RJt5LqFqwdj35meAPES$JaD`Q zJB;mRL|}%Mw#>8fdikml5sx>tR~nXleC1jSFC`Ad5rxBQ%~1#T^-Nf;s$J~JV~0y{ zE3-;~!#QEwA7;qXSMIoz6syy>IIbcEDc`MB@$JcAxQ1)Og;z0u4ca;}yNAHaKoa`F#meg!6gys!nV4pZeT*CUltJ65|eRHtd+*}i`WNBw8 zLGuZ5$`DcJL2CuyPL!wjbgDJ?Vwq_Q$!s^xXD=t}fi5RMHqJwNfYYSL;>a7FCEd`V zgAW3xEs*E?I zD;mv{Zs8uNr(~Tc%NL&=v=dWITX)6{^cUY_=dI$r#kc@QT!#S$bLx+{IBiMy9`_}e z>vO;wJMs=R8f5jhsZH)nrF&ecvL;jIBn#`=8gXb=@@AnrYs#`D;|)&hxTQ4gJ$T!k zsL1NTBz2l`$Hovn!6exT-e^x0@Bp%R_za`*06w!Vb`YM^_;JuxfNXI-4t&b?FX^aP`gZztkL^~gD#F?l(JIEregOhx_e%PWGQ{?F#cok9;D!6oN3NWCGJ zHhk+k+E`r7}yhBA+T$ex2F7g&Q7l2Q)c02?yRhGo0dWu`TGqiVr!_jIn)rg1SNE}gj7(?>; zD>D{$Ek6b^s6_U;oNGDH6vlRzBmoR+Ff4S1r$AC2RLIpFE6%NTv{T$>n{ zzK=O2CD#aW1Q*?mdzwc~I4FtKuVml8j5JoKtwaTE*1FvgJ-HzQjAm-JHDM#h7;9w? zN``PpAVMy1F}!y!`8TuO?3i!{GW7De!lHBRD7I(;CO6Y&_W)xl=q387jP*nJMX<%~ zY++E>PAjPgl5m!v1qdS5QWv|b?W!9r$&OV~g5l1)cU~fJ7fE~<32^pIY$feUeO%}E z=n*DUDa{V0OaM&AfPz+B|3z8%1A$d`Q!=o?Oo)a?2p z{i%i+;}wV|(gdNsEd&W^DGmI7T<3)}%?qz)y!>~KkEOq^ku}{0o7r7(LEnH~`qm$~ zvXM$Y@vYAFtWPR%Up05e_}RTjQ0#c81W=K!%vm{Fb;{e(I z%VJ{*RZDx4=;rmXHuEUpTEUu{vRspLL>$QKAbTF0075+;gkFcDg3L>m=k-?Kwf0!) z2L{|vL8XbF=~H2{BrGBH>>v23wXv&5SNsWo@sKjbSbtJ-Uhitx#NsxG2*_A_lP%Lh z9?V|v)sr;%0Eay?mxh=6c_}(}Fl_DRPYJs`e^tO^G}?X$pJAwn*%o0g1c^s=U${(8{luab$`DRBy806Q;lIuX)?<9({%C3VKM;tEg~i1^TU8L=M&|L2OL)9Jisy((LrkslqwGsQ~TnzCVvD0{kj zC~5jSEv=Y9BtiL?Vu+oG@6et`bUcZF31h5O5@cAU#D*kPTxHeR(2x3wXAH%dysyym zWq_2l!G_u|k=H(6Kh>4A1E%JN#`^gujJ)t%17{WdNvE*G=eW#R~ck0GEC?Faz6-6 z>3_NndxCkw@Rn3(Y&Vg)P)BFU@?_99Ji(-Sme^s0+ES$4_>g>Exyd(1#_ZExtSs~1 zd$jOyhgYF*&~O6Sqh4f|%iT4?TAqS+b>y(p)%A6j-^&J|Fyz@Q2*ibbToCEYwZ8{Y z`SF(O;-_Jjirg?y=%9pVVfdeiKHQ&?5$p%|m(xTgfbG?I90GfIFA6P9S?aRw1U2HyRPiH$ ztyugf=y4f@3P=jp>3=ySq^Z?teWyc7o@wW7{Hg1Pt&a`4kB@NV+mzx#`?q8Xj|<;( zjgJpfuWy4n)4aCuqJC3pbq}!VtKF&XCeUUwM&@uNM^{{#!Q;A~_ zgKUlrLzxS9<;XU*lDO(P-`&;!?qVnvKu~AuS_W{)i}WWAv3n?PVwBdc`{1>%2sBn_ zKpgCxkI{^3Ml3qyUgbrlJ6-t*Sr^w@haUNSaVXInfp1|tdN7kvv!R4NlcD7*&`tz6 zt*jksH;<#)Hz!tbke=IOQj?%r=8&35IpmU;f1IS#O!T3W$pISj9G|jYpI!C1-frCk z#7X5f>Zi;hy~m^*iN(coRJ}IE4gv}9d`@GcdqIkxfYm;V?zk(%NYCX*s{g^dlZ_8;_S(D7WInh*uyVmWw6 zNFB5_igr5t8Iv_jb~=X`GiVXo_uuuy50$=N zROgG_Oz>pdu4~?Pn5S@3n|3gJM#KHZQke z)~Q?WtaL_=s@jJ7zR8t$bmlu5ZI~~-dkYx*-^&T5kGypuJo}1}J3K@-<{zbekTQ_q z#@AGDO)}|#k++~zA0}el#3OY%U|0KAu$I<#c9;RD43}L6_l$RWrljlg5`rto`}%-? zg$mhrLkx(M6_g>;Lf{mO$vt45G_gyDGM1lKp|NVBE{R%_MF)TxZ&8Sg&k3Ug{P$Pv z(yEv2xR+&KhzXxIwNY8SIKL8nv9SY9Ci6)a&#_E(tBL(kEbr|D=89xrFG4Rl;?yA3 zfU&28FlWn}xpP+hVf<*xI+-!+xt&7g{iWejLt*!p4%F{Oa ziP6sjMQYbW?OD!Q?WLWDI1geLlJG=JxGW$*sU(72#k==eOQX(nPo7LBR@}sD z#RvJNidNW{W&U{ydZ%>}*T#aQNNGdn4t93%CtVtRp9p3%+v=7f^$0F6SY2W#6r2qQ z#+R@<*0HzhT?|lN%Hf`mALX{U)Yr9n)R;7x${!yPDD_rgtTle&j`XaE=ZkIr^|2wH zUACPQ>!CrHYYB7;eo6?uLEU{V?@+kto~hI{5zQPv_}r?r&bS$FG%d5IRq@T%$4YO? z@ipg3c)hFq+D5^H{%h6E_o~%-rtZaBC#ggHmkKc|7vo-LFB2Y0sl^G@%kXwmHo2ueB|}a@Yim%FTD?kY7pZYj+W2IY`{F{Q8UYX7zk-HRk7iPDonLF7 zD#VTUeZBZ||7s4OX@yWva zaqz+uReBU`Yv50RvEUC)IhkGP8f)R`!f<7Lkn6A(i+V=~mzvW`d=EgiY~Xpw)EFSp zSB}3duq4qSP4Og=>K>rQD@e9g?=T5~1_A%O3x?z#uuHz9eV)zU#pGQooF9py(q!8a z2V(P7PZeqUqEl9+#ZGV~r68|edlPw{{UFgIC;zP!dISed2U$T;EE~!;O8)GZMUjN( zz=TwA{dMxZtG1r}v_)F&21o`3k~hPH?S+pdWcR zai#nNM%U5au?$^Dk}pBDQ$5tXozWxI3m? zusP{8qVaMvPC65M^855Vm+TYsP|DsdxilR1sDiVFnogoM>p%N1zs9c5?p!k zaWh#Y%FTzz1{|(>jA5dl;P*~&Ggk=af>KLz=-p7+V;zQc>sP5nz}axLIgMqnS-BU} zRQuiF5q;0;wvx)MLxJ^8u_#i&$cCyCYrxzBJ1HiFd-Y+twy&D0KoZo;NC2%oGK;Kw#19XW>d@iQPJ(=qQiVs=cj``fRwrw zGtoPa+4w)}iV=@t2ynE=f|)Lc?szD-ts=|25*yh^aAT#ZNJ@LUwY-r_d$Y?XRrYa> zfomy=T)LCo)^{3`UVHtAsP-AwiSuX0M!oT^QiuZ64$G@`MhHeq-U3SgN%w$y7xJpR zHwTv@CeRufGHaXL+OSIWaorJ;ug$X5hJBxksH3g;>GKl1@)COnKhRHYq@YNC6d&y~ zHK2lzctnj5ssx9_%a>>OaJOd@W!!z0XC+9v8y0BYdi2`QmhUJ=>r9ofR3!9VH)!th zNB9$>1uD_d93F}U7&QO~(lcFO9IJ+DIZM2cK~F8#oNx%KHFitZUnzMZ5=vkN^{*GcGbZmaAg(@0>CXuR(ESfCkc|g(#=ElX(RXI}WK)?cJwNx7lLl6) zH}`<7Qv4Iau>H=2OOJ ze!CNEp7|<-G+ysRzuUlH4+?j9=|Xaxm>T~|dSO>UGZg|YiXt>HqIV#_Jtx2H&ys#V zgWaD^rRW&*F**yo+a45)^@)0b+OfUVH&XXQTeaEUv8;{!pe>elS2PveaNm?;t{wct ztCY3sp8#^Pp|wrQ_kh6Fuu8LgkiX6pBQA3p@7jnh*Z({)*VLrdxjehnQMK8xL zHCDh6FPtqcB51~rq2n8NGp}4x`^A{QbOFG}cwL-eivapqDNv`1Xc>ye!UDO3mfC-! z?T6exU3l}c?Q^#<@7Ims_YJCLo_U2K4WfijkO?xRUGLIQzkuicBGiwjHBq2-2iRCI zXR&URN7o(TWpb*XPg&r|j}KHG4D|~=(K>Fr2RsY$4>o)9#jf0PioEVwnWzuvHiOpK z1O1=dStM`)RP>|m0VDJ4^UdEj;h?b(!kr8SXz>I zqJYUW>cW^pz|+Luo(6+Jg2Wq3yK>%E?F_mL;?Kw06YawsdWfUvdU(s2uT7IeA{)|6 z!DyxLPTfaHK1v-@DMlBO6$)lrZ4_m}hSB|xFLnlf4SD)Sm*l-L$<$U;Q)9S7vq$+oU^**eL+C?c)sfoxz^a_bD;z>}wrF59 zJvb;0J!7r{yzx4GUS4HW8=*cpJ#D;;AdtCdB*v$SBqIy%=~o@Alm}%hDA1e%iwjLG z53C5Az$*lY{*K-kyqDQKzI)em_kicJX$((KWU71e(?NJ@CUM&gXBp&EFDLOk&u%j7 zYYw%7OsdIpNlU#x8O*kSjoZmIy>Uz5iu~X+)VxJ1umycKl4vm!SW8`2=|R=b%k;tV ztGASsJY$`I-^u`%y*pJUDW;0P5bIF<>Qo;Z%csB$q-90I;w(tt-PZhv#mys;T^`%s zwWYeDPupNdnUns<)A=}MDAeWyjhgTe51%b#bUa*&ZB)s3VWg(I6rFOOg}-d^9(pg? z@FtccS2#1fXl3l^@Tq}$eWEb~S17f9R}t``e;*-I+>UNz&h9-xZv5bc=t!eA@$dzE ztgcb!%TJj-1!I*^??a+1ZA~4{g@`Jys3lWVZ<4qB_p*UAdhd zDf5IEKOVf;99SD_R5>Y%NDq%V6rSDUo}C>?Oe&Oev&^Y(Y)Mj%C#mJ60ct_s!3hn^ zb6BE&3qWX$6*Fdu7(!*g3PbY%Eb-$bx!^;fIkOWI7gtD&Z*sq6j+N@pkuP4_kwx+% zokX2+@ihh{UeCfay}axR=j?(sdKdCyF0YZNk9V83`N!-R9y#;8ZCjvufm!Eg?E>nghSpPxHL69mn=Gl=!-9gl{QW%^YNa*c7*b7StG*JK{N zTU?K)^y_gH+h*UBv&-5|(tLy^W^8||d&~gOC$TME*{HK!(CW`^x!jr}1DVg${YZnV zS4yz@GMbO#ptHB!*)f&3-V!oxZt+N|21HFj3>mG)Fu2Q9;v0EZNNRg$XZY&NOu`5U z&m-}XgODX<+xE|=&q!O_I41;&94#ATnOh&%4YFwE0V(fRNX4(u%l8_ZAl=j1ElEz2 z#ZU7XaY}r>(?10ARg}%?wuj++i7`n(Phos5b0r=0anKb21CKykJnW=84#_OMN?WnMky6nj-NmPd~yT1JKE zG^6WsHKY#eVG$Xj25S8I;%2OIDPxvp-qSqnnS@v5{E>_lf^f<89kP20b!$l9ROzy$wF|x>bzP^|EIba-?OOJ*b!lK_%kYC65x(`B z7Ou{`GQB={OS!X`zcvQG9EOO zLqz03HCoX0SVyDDC8+8p&MF0f!mY;b#XTo@tA0beOXp zwT;uPgq%cHmZ!WX?i~!?$lWeF3_DTF8}jOh#{TuDuyU?SN>|M zU9tLTCgBx|O&Xt5qh>vd3B@iZ;DZwxh(SucD&Nk$?11i65*Jxm4sp=jU(cnjC{x2{ zj<#mm_>KG_OIdEpuyv|F|KyT9VkQ+;N9*g}#WWT+n2x?39mRqk?$3;9cSJy}UdkKs zojoGG1=~JJ0;OF6SRW%gxS`k6XNot=zQLC1m^!+w4Lr%b4Rf0w1(->%IMdb&7$v$J zj>S`)yhC(#lOk^?9_Q#>`H{z8$@E(8ayX<+9ph)bVrI(M$5cvhug$&($V&-7d+Fu( zrqDOVkJp#G?IGkF`HG5Y?ZR-h7*?#NfI2>#tZ+KxXgw+ZxDeI;3vf4%?q?f(_cDBV zuoe}S(XFgCuph7D zFXE+t%fI3t(3RpH{2`$Txo!uc&ic_Di^>3RwDY=ryK^()2-4R|p)907DrvHevJNmr zind$7650>xt=T=$2-UIeDnTzM8EsGa)yXJEv`&17U z8m8*ec+q(-Rip_aSf1WO49Sn*RRd!kWlONPOJC-XEIZt#7fSo2arN+pjgSOzHdiU~ z3i(mvB@}{pS~A}pJ@>RNGXjsL>nV&lpQ68>7rV)5XF)0#Bahq)m%8EC0+(+KNREnQ zECzE%todMYf)bv)7r6L0Xw5yI*S$-wm?Drd?%{tmpXQL>{J#k(|0B@EI^#}Bm3Xk6 zFhZdbvu(`{FauO6DXN0=Baxw%R2mUlCrK6*#%<qvId8Q-*@EHI;>p18~N(@vng^_BcPF@iS{wxkHA zV{(1`3k@yltM3(PZAU*EMnnrgr3gSOToOFr%x-8-8D3#wUS}W3bV({YP*#49*3j}H z+tgGjy?!!gegsm(El9@ZlT1S5f@clEiL~2ShVJn!hA!L#f}$c=#!)Z!Ma#nI;Ea6n z_8K`q34+sxfbj2T*CHaw7S`4I>UFPnFOh$+{v zHEZ&7*9kh;kcvn|;X5#Ue_A!R$MJ>?yIIbtliZk`Gu--xlyi2d4MVWZY(WPJ83Ru!7A`fNzG3Nh*LY zv`1{iC{QmHwWXuo2K6BpKZ60N-<+J@5ycvcdR#k!m#Om*{o}$~ z*hsM{1vC)U*oUlnTUEI#b>P6ElY7>hUlQ+$6EjT(6K5$Aiovhr!;P0t?qZ3T8KcVz z$zGHI1#|D9G3!yabi8jH`P~KGBKhsH!Qee0k{Eh^Cxh`S^EgZDL(-~{lcau&Pr+yf zGFqD!osc~-?;g0eqOj#dlXZA&K~wUFv)G}wsL8mLH_pDN-M*XErxsT<@+(16rCObG-7`xJ0aX1H};{OW+Fs>#~xGYa$Oi|WC$2obm; z$&&;o3Sw#1#Ev@)tPEwyneXLn{_Om-qvvEYr%2yMUHwq}0G>FynbUElCR1Bp5_U3GC|E#ku?>dJk_C`_~%_XY*Fkh>6DUDRy z`r92w&OvJ+aUB61lpP&|fl<=|AW_7p6wZiZy?YY=#I|1c<=bwUd$KJeSF7#G&hzVq(%LQVyW~C6eFs{*g%TKPWCzr80CTGh93WgWkV%^DzHOZZaRD2QnW* z6jkOQR6wR^oFx$edpd%FAw#z(qz^1L99&hFap3H&v_?Bnc;SFk^NQ!Rdumf*Ri?aD z6*{p-z!Nzo{}flS`rSH>wU;(9!l7CEYDkSDKnxzc6R}nPiE6F4fZ{#iZQ<-t;q|No zr194GMg7388}{O^+Y_vc*>y)X<9elV>Q61jV+v(V1veBnuTJI*I9m%BFH4l>^z}Lg zzs~mq*#P4$#gs5Rao{##M%~XxD7pGaHSVhjtOt+pCVD6->_!NB2Slk;atoymKRle| zx*^pV%E3pJ3lTOnrZ?@ki#zl`i7@jMT>3u@qXCN03d#v+JY9-sIAAX+M}$*H34OAa z`D_Fj7uV07i_MG^>*yek_^fSba_UH-1PhuoNB*CrqrUf{FCR~re-#h&cjrrmPd#3{ zt1aVL1>>*e$cA#DVe{RFYlrI3s_S zBePw2r2(dQ6 zs7ZW*Tyc+CK-gxu9B`=eC+#a{V|S@m5ZR%1@Vx}X?BJ9}m7M(%>2LjB@iH%ge>SdExVBj|mvf2u3o!gj( zT)~<=2^(dEc@pC>H2~79#Zn=i14DPb0<32A;{excQWVk$G&F~vk7wSLD>K>FBZa9| zO%x=+aRwz_W-^lcH7sDcZx(%8S$w40e8ZiBkfKG|gaAJf26qr={tm{J!4YMc&7(q$ z^;~N`;AzWy%|`v`s+d}$Yu2m_+!`yQy2eP?OSeeJ0i^*G+ipdhYcD10tYem#yq#;! z`LgVf2G1kS&?8V?+J4-54@jswCWjZ(@5N|9r+ylR;ucyMR{;3 zOEM}PcOgd-#A1;(krtCyGNU|J6|xsF^AljyXPHrh);WHC-p}*S^a-l~ zwvEJ-p#b|we(Xnz`j4c7Sy^5&Wd}X}R;R_1m$t8jB+>$(^eR_`wZIy5qXG3wf;W}G zED5p;uo{Vfl&D9yB1UET{NSmCuTLz0u(`G#K3o>9P^+gBk~T&{{*F$_yXgy@rMprU zi)roWF?BFnwlMBj%_D;X&Lu6ByUHyTva%JQJrSSS8r%*3wl1Ecd~A} zk1XSQOil%s`>x6cI8POzHcClraZA2{viEb12ML3n`9>&ZDEW)q8A8PDl6iTOD*YGI zK-rC+fqm4coz{9=wM@M+O9md?e=DqU?LgJ^eY z?a8$y_&uCgY6j*>5RViUSw3Lgk*p}v+y>OKn?=<^kADgd+3fg`W~xoRVx`WY>yiw} zg-c>+9icFE*i$>In{)nl@OsOD-~Dz3XzoaV)7sXzg$pCMe*#@@IHiArsh|Jk8Ly*v zIfFkwUnWl!y7@LCZ%GEhk#9$`FoZj`O^TR&|0a~?9loM4jhG*w5WjC|7W%Kb$$#M0 z!WAhWYp&0~p9lX|OLR5@l-;y;TqKz=FKUioOAv6xfjm6g+~c&9!6}O6odIR0#f@P5 z>EP6xs`sE-y|%o)SE5v^gs5UWBMSDu4BF0ndoGa$wM~&G6qN4o5P>EzF(dFw2zEco z{W)blO>&W>puMcIW85SF&SDh#j^dn`1Qk$v;o-ZLocj}k z&LtV~WX{wp8_LGSjq-O)HDbgZ6<%o=NYl{B>?5%&MpnTt;38Jg@MXLEKE zP$^-!??NBMXtwdEwCzlZL!Za_|Ff9?e|gW{qFP)&?nn7<6@N`o!`tFHCz=z8Q5agd z3U7uk3Z&~VmIP^*?$!#;<87(NuMxbsUb4kFb$qAHi?}Zp~|z`twB_sJUH+1yjG#gmqhSs6C8HB zd{N_L6!l}+-0@RGNQzAjkXY-%0nC)yLyJDp_c{s4D z52W}yb{&!Gk)5|j@TfEIX38?(<^F)xD(B7l{6-%XaDiQyB$t)F zeuc!ui|LCMmE*K##@h2p1yxlC7)&)D@#B{+Fm%5P6*;;Az zb)95c3aqOQX+oH4=vkAbzf8tk_>h|WX_cAumGf-gjk6Ugv#DLJ9czGkjcmt02B+!{ z7$M@o_Q8iFJ2&_lm2NMAfzEP2M_hEa`5sJ)O+P{Cy84&jM`v~zJ3UL&^yRjXPb+A{ z%$pNp&D3}e9*Yr2jgq;ScuIxmTV1QMNt**zE3$EMMyS*Gk&Ql)BEjLp^!#9u@=c|- z2)lm$Qp`&y<}A?1(U05+4Ka0dCT8j)9V@-ekn!Wr0{1}i;Iix+y!0e6_!iv5b)_Ro z4}yzTAQw^K6eThL2XXWI+n%`C+xCgd#QJS*8`CH7!LD1g=&_tTLt?AU*e^#-+LE3H z$~T4VKYfc*lNV970%E0?P}F9qMiIOhCV}K$Knu2VfclGGqTk>`WJv-A8_yWb!7vH*PCWc zn&sN07!$CVO1Ayq(gM+W*heo`%OqDH;1A0S$!}DjoFk1cf;DtfqMaPIPBkDPxzs zOr^VP_zp7IFo;3C6^hQnl~a0pp|JY%>zF!YaFfhN2-uCPLw-fY56e`k%w@~+cR!bUE`+q~;F-XVZ%i$YoNC(V?$UA~r@L zWuN=@`9=af5!%DK@^~6;*>yKl1Uwd`7IgE11D&_1EqY%tv^9o0zX=l(K3PsBe#;Wv zk6k@WIJNdF?d)JrPk7tg;Dmfl>gR_jsZZ@{sr9^1;xpBstjzuSk%e)iJj2zdu#fgd0w zqyLtO4=F8G&E%z16Be|bUOS0sBh@`qz9vZ{I-Wq^I;oLB%n{W zqM_07pBunlg;aQXejrNpZjw{?#hZnd5U0&oizmS(w)5aRE@q=8UxF_SzE;FiDc;2o zD_*8Nh6lLwQUIi^{r^K@%JnrR8;`lCx@&50GG^fu?0@_r!hA zG0)1b6IDpc0ETKL5wKpr%Bg-Il!iJnmmj`M9{S%Rb|9y|&q6Y4T3GO^7~bNC310br zusGd-TxG$w$iCLRNN4HkIZ^~U*Qu*7QlfTxOYyIP>W8kNo440vTc7VvWrm$|1)P{c zQC%6px@p_h#@cbCnn-dFQ;J##P=}$THMQJi!MI)U0vfRlb{r0@6akhe_MY19?`d*6 z72+*>69tH?z7^~e%dFu~7i`i!sB;U}9g-RLQ664;1Bgje1s*?2&zs*F-_gLtYl$H? zGZl!^q%;9EHsghVM?yN2^>T<)!fLBa#CpPZ-*mi8u+@Fw>42F^-nk75Poj{cq#SM7 zp$SOihBRkM&hEmJ6}ItRzu)&{E4n$J{~s6t8(sIXP4LqA!o1E9!h6T=8Z{t)pJQk9 z`L@&pnb(RU>Bw@#kLyAn`7`sdM;Vhe$lA`)esJo3`IjN0#5nF@E0xYyD-8_+%tEzx zul&PUhnlv4)%|-z@7Y(@zi9Hju3 zYLDf+>v&2Zr{@n&+YH$Xc3$?#_HTDQ5j=UIS$~Xom&Ovqf#{Xr%8_u@SmBHAG=UfQ zmj-9d)%kjhl;QE=&!!zM4zN7HxXDA~URrRAZ$Itf3s zcdUP9<0}*SKKBp#!}%BxTC0M=okC;rx40%Y0bK!K zuEFE^kWbA7{R@iANU$~Ue+w0wVf=?4g-3n+7I(MyLrCmz&46if(|$Pr3{<{QvS>y7 zzJV*3Bf>`3gfBA0l+ZZvog!mDRe$>HL~uDcW}^xz7iuD7l6c=Yb^l&y_22ycpF2nz zUKPcc+QoHMKmIkqf9xT@A0!_Ow~KF8koviY%!Lor@0~7^*e-Y_TnBvvuIW>w%88@O z0m5NsYkN{_d!m>*$xYW|P1mDv|F1h0G(MB>osRgwHrYYYr;xjFp0?c<_2ZLnT1WtM zvkB}p3M)w|^9SiR$=4R2{PSXo(Z?OGDh8>_E0m_(QDB(U^X1VBAI7}ZiPK2`)4Y%I8QjFV+fe-`f{2F?@b{j}!ne+@hW zpyD!6tDczt--Tw=o-^;$5EtBd;H3Jk6)BHJfX#qK50k#%N@i!7e`@MFK|g8b5358{ z=52}5iT~}Ct9y>UCSW_qaqh`KLV4yS^-R3f-P(OWtNY5okhKL}1vlke0~V`%1)A`m z;g)blUP1Mv)*WsZG4l_B%ueZ>5~CCMJ0x!Tr={5)SGP?nvR&2cTMC@}(fn|hM}dnE#ks}zU6!<9`4_V6k*S3xOLZt0r^=Iy1sfNnJ1p#T zu;tTaJtW|95?HVGc`^tUSaJExKL>Qxqi041M*bTX+;LmZuF#*g&{1X1EIl#Zvjt^| zA-#uJiiQTx5CWb2q2~Y8&HuSa(yHkRtBiatRWfGx**Y!*H-|Ks9`3v?W$3?m-j~`H zQ+1!pE^aCgI0-y!;KF}~1N-MXPwpvOUKp`$yXy?CW1e%bMr;+Re}K7SKc8B{2_^RK7mA#Jy(@2hg5im6An3 z;oOqYt}Q8o@4dgxzx)2?vBGOBCxH^j?0+%;8Qw1c0*s5qk_aIs6+VBHruXVh#`D*P z029@sH#*VTi`IlLR_Lz^E(u{uQjl{u^_k@7uX1tnPf)^%6=Uh>WS)Fh>8@D9YT)AP ztH4lg@Br3pK#y%M-}2y?;}^9lcSRXybg)l68@yQk6VRduJJNyIaX3Yae z$g=JK8K&+3dIp#dHE`*CxJ!%CP=H@~7VE_XkB$kJHdk%tpXvdp&g_!NrZp*(-#hL; zco1l7D5JuY0#{H9Fn4uOQ(}Bl?0%~=2xzN?I?z|276Uy74EL?ObPk3Yd46923C2|o zpnd6GdSZH}r`7Luw$=K|XQ_Hux@SC?bJb?@wVpZ2TY=7h6!WuBL_NOBZP%@%WpaF0 zSHkvx{4~G+(=zXWyZpcR0#%%j6|uLAp9owUju2$hIC!Gh zQSM5hL&H%?OT(4wxB9j0e?FW4{lua!Hkc0gsq%k5`~Q9dT(n9HA+KaNON}MJKn|M+ zbt8>!L^57~S_?y9ffY~55=8iEEO2}ZnsB=O@23bNs6+w`5K0h1tieD{(Rf|6w>Ng2 zD+EqS uDS(+InE9bebn&VFf0fJsegZZ-s3|1k)>S0v_?2k_G)Dj(L3C97zX<@iv)JVT literal 0 HcmV?d00001 diff --git a/js/slp_filename_prefix.js b/js/slp_filename_prefix.js new file mode 100644 index 0000000..4a76ae8 --- /dev/null +++ b/js/slp_filename_prefix.js @@ -0,0 +1,22 @@ +const { app } = window.comfyAPI.app; +const { applyTextReplacements } = window.comfyAPI.utils; + +app.registerExtension({ + name: "hetima.SLPFilenamePrefix", + async beforeRegisterNodeDef(nodeType, nodeData, app) { + if (nodeData.name === "HetimaSLPFilenamePrefix") { + + const onNodeCreated = nodeType.prototype.onNodeCreated; + nodeType.prototype.onNodeCreated = function () { + const ret = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined; + + const widget = this.widgets.find((w) => w.name === "filename_prefix"); + widget.serializeValue = () => { + return applyTextReplacements(app, widget.value); + }; + + return ret; + }; + } + }, +}); diff --git a/slp_filename_prefix.py b/slp_filename_prefix.py new file mode 100644 index 0000000..11bf8e0 --- /dev/null +++ b/slp_filename_prefix.py @@ -0,0 +1,62 @@ +import re + +class AnyType(str): + """A special class that is always equal in not equal comparisons. Credit to pythongosssss""" + def __ne__(self, __value: object) -> bool: + return False + +any_type = AnyType("*") + +class SLPFilenamePrefix: + + NAME = "HetimaSLPFilenamePrefix" + DISPLAY_NAME = "SLP Filename Prefix" + + CATEGORY = "SingleLinePicker" + DESCRIPTION = "Builds a filename_prefix and return one includes placeholder replacements." + + @classmethod + def INPUT_TYPES(cls): + return { + "required": { + "filename_prefix": ("STRING", {"multiline": False, "default": "%date:yyyy-MM-dd%/$1", "tooltip": 'can include "%date:%", "$1", "$2", "$3" and "$4"'}), + }, + "optional": { + "$1": (any_type, {"multiline": False, "default": "", "forceInput": True, "tooltip": 'replace "$1" with this value'}), + "$2": (any_type, {"multiline": False, "default": "", "forceInput": True, "tooltip": 'replace "$2" with this value'}), + "$3": (any_type, {"multiline": False, "default": "", "forceInput": True, "tooltip": 'replace "$3" with this value'}), + "$4": (any_type, {"multiline": False, "default": "", "forceInput": True, "tooltip": 'replace "$4" with this value'}), + }, + } + + RETURN_TYPES = ("STRING",) + RETURN_NAMES = ("STRING",) + OUTPUT_TOOLTIPS = ("built filename_prefix",) + OUTPUT_NODE = True + FUNCTION = "execute" + + def to_storing(self, val): + if isinstance(val, str) and len(val) > 0: + val = val.splitlines()[0] + trans = val.maketrans("?/<>\\:*|\"", "_________") + val = val.translate(trans) + return val + if isinstance(val, (int, float, bool)): + return str(val) + return "" + + def execute(self, **kwargs): + filename_prefix = kwargs["filename_prefix"] + if not filename_prefix: + return "" + + s1 = self.to_storing(kwargs.get("$1", "")) + s2 = self.to_storing(kwargs.get("$2", "")) + s3 = self.to_storing(kwargs.get("$3", "")) + s4 = self.to_storing(kwargs.get("$4", "")) + mapping = {"$1": s1, "$2": s2, "$3": s3, "$4": s4,} + + pattern = re.compile("|".join(re.escape(k) for k in mapping.keys())) + filename_prefix = pattern.sub(lambda m: mapping[m.group(0)], filename_prefix) + + return (filename_prefix,)