From 13bcc98cacc83475b54f1f4e9df268547f868c20 Mon Sep 17 00:00:00 2001 From: QuBerto Date: Sun, 14 Jul 2024 19:50:15 +0200 Subject: [PATCH] before frames update --- api/woocommerce_api.py | 2 +- config/encrypt_config.py | 7 +- images/image-7.jpg | Bin 0 -> 107471 bytes main.py | 73 ++++++--- ui/local_processing_tab.py | 314 ++++++++++++++++++++----------------- ui/log_window.py | 49 ++++-- ui/options_window.py | 165 ++++++++----------- ui/settings_tab.py | 81 +++++----- utils/file_operations.py | 39 +++++ 9 files changed, 400 insertions(+), 330 deletions(-) create mode 100644 images/image-7.jpg diff --git a/api/woocommerce_api.py b/api/woocommerce_api.py index aea126b..28bcb43 100644 --- a/api/woocommerce_api.py +++ b/api/woocommerce_api.py @@ -55,7 +55,7 @@ def load_credentials(): with open("config.enc", "rb") as file: encrypted = file.read() decrypted = fernet.decrypt(encrypted).decode() - return json.loads(decrypted) + return json.loads(decrypted).get("credentials") def get_wcapi(): diff --git a/config/encrypt_config.py b/config/encrypt_config.py index 7a56889..074f25d 100644 --- a/config/encrypt_config.py +++ b/config/encrypt_config.py @@ -13,6 +13,7 @@ class ConfigEncryptor: encrypted_data = self.fernet.encrypt(json_data.encode()) with open(self.filename, "wb") as encrypted_file: encrypted_file.write(encrypted_data) + print("Credentials saved") def get_key(self): return self.key.decode() @@ -38,7 +39,11 @@ class ConfigEncryptor: with open(self.filename, "rb") as encrypted_file: encrypted_data = encrypted_file.read() decrypted_data = self.fernet.decrypt(encrypted_data).decode() - return json.loads(decrypted_data) + config = json.loads(decrypted_data) + + # Filter only relevant keys + keys_to_return = ["credentials", "options"] + return {key: config[key] for key in keys_to_return if key in config} except FileNotFoundError: return None diff --git a/images/image-7.jpg b/images/image-7.jpg new file mode 100644 index 0000000000000000000000000000000000000000..504d5c9d9cd9b727d893ea63b81bdd5306e004cc GIT binary patch literal 107471 zcmb6Ac{p3^+6RtPv(jyD1l>XeF;qxsf*xWXDi8A0OXb8vw3iSqIB3G>PD3-Iv+tsfsSztDe=oZ#J?~if*e@78Mz5)?GLEwskA;N&a@PFI;HH3|NMuK?_B-=j(!IiM&SS2SAGlzY?dBY4i3Q4Eh2;#AEoMGjZrl=F!|30 zpB0~|u&{`*kf?}=h?tnDxP+Xf#QF0QiZZf4$*F*UzN7+HR#t`TYpSa0sw*pNnP}@8 zAdpDp&zflSD~4wJMo7aSgYb)qiAkK707*)M3?a%8!~f6Qe_rxQiwa&5xg)@@#&=Gd zUqG7wKcjqLKK}pR{=0@BfB5;%2?z=a1NT7xuRA|(0{8y&nomLi=p`i}1zh+}T;D(4 zeHFZUE~DdIcWss5envRbw$~a}St0K?=zQSF2uJQ2hbo~8cC6GxyT!DHA(^o-msAv1 za1yL@;S1>CX_t9iGmm{<^~quccZDMwcyNRDAy!DS=H>5{nnVUm^&?tv98;@N4U_G;nC%E#k+<5A;!PSv<- zT(PA)XvO}4R?>{@doQD>S=O@`N~c>~R_?pm zXW2Ly3Ema5D(r#vI)vp`x62A<$w`#dhf6#{g+`#ylAUU!!gFE0HL&BER!PbWO{Y?_ zQ+6aba+L1?JZC8(Ao#+-S*FEB=YC9i#J#j-;nFb% zhv{r6%+xb{f1uc}54K2SND32-D29iI%-y))SM0u4Q#T12ertDC$r7wgw)kpb>~n;u zTl$NQa)*Di>E+2mHjuQy3Y02y%1Zo@Vnlz$r6WUQxOceK>N8R`0)DHE&8C!bm|(2UXyvB27M!mROnl%#WU6^ewER|g)XXvqsT zg47P=k(7c#q~Rkw5ZpB|c+n)}^+&#hq{@sl`Y<&PS7}445RCpzHISU2y1|5OomVSbc4GkE2Ws3jP!PR znguRMMk+%*tvN$D4GS#lFVmT`Jmo)4O%zh&!{i7w+f<4E%0hUSdNfkEGfId>mu}2f zQ-SH(dKw{$aol}kPE2)u1qxIF!)~50Z83s`jp6J26khM0Nno6P%d6MODhbQO{Ts2L z*AfDJ4xH}gJ`yU*o|+;ZpP%0?O9{9|JmPJS)ph#O$bKjNn3~ap+%i@5k~Xaj!|+}s z!RM1s`pA}e`}uPMmIMbYoEpJ#mLP9MlGTVaDw#jGCyWnm5pJl!qNLc8#5|(p<~B*) z!Xr#ecs5*yAtQsWr!{K9Ad>|IX&W4#AY`#1>i@4l$`8qkyp8rL%&E;skK_v0Nh4RY9 zfNTEB0UH7Sm^jY%(?e=qgQ{*IG6Z&7Lp683;yUqAAsO*}HAPwcC_luM>x2qbeu*fV zmuKA9>c^+KIW&f&6!Ej^B?t){Tv;|c&k)cn@PbuosIsujhU=3TG`= zPFNxaEL&rFzG372ZLy!6@~*qTd!z4Jf5RKWikpLA$Ys>7t2bAZY2*6Iz`d<`cmEBGAYpttcL{L8M<8bRHyX)t#D zrCi>V#h$k4+^JA|sJ4VU$se6x7UzJ?Y$>zlPo)M)lg>MoyYtKqX?@=0SXx}gpu?Q+ zCVR~Vb>Er&#_^~sj(y)M-{aY>SF5*`*}=R{^fvJz|7LFsqAVGNd?jWX!e1}z8C2h( z#==6<+yaB#LSgW1NG21W-H_=hV}WI8NvAeeLEsFgR(c@Costg47G+w)A@z|XIJ~?3 zIh>k|K&TriyS^eFp4!M@x;GZ2!!iS_j0~KycmzRvquk>)Wx~UmT_P!w=cGnZ_}st0 zYf@1*O|&*B>jh^LecYF4JkvshOBv-P6oBgciUUPkzV1+A0ZMFq^T?vXSuPd(2rSVu ztDtE{+)zeuen*TLCyeW$DtgY%Xk{dpe5oXSOvi%L-ZIpadBRt`>)v zmkWoB1MtNFXE%bt@J41vR!dtUf?_Yl|IgD_*;?)oX#f&nt4 zw;@V*nuC>Yg)H(In>v(*4zlBuhMo(Q5{G`pzVpzYMR_5zc4wjv2GD-z?Te;!W>j4Wt87ge!^sYc!su@o)uUGCxO7K z&BN%ZHRa`4O3$=#FL5TP7|reBq1ju8#QGvRO%nc`pfwx{NX^Tp@W#NV*-?jDH=o?s z{8A{WfwMcHuXy45is_j$tVN-8E|c8^cPs_oRbVDbz`|Kpz|z23n4zVe)`;@0vbS%5 z0NT&|!3tnv%}@xV2y$luKW}g4Ht!;s9xmYKEH4PK2jXqwN?m2Y+&!VZk|Is5Bi)FX z(KGN}xkXN+zjhmr;UktVpZuYj=_fcO~L<12}PZpz3*EOI5!X*iVO85v>)m6TMe z2(de1Fi4t*kq`vvm0Azzh7=Q$U0?K?0TaQ914BR|*$l9jCkQ4EtOO1L3@8(x83w~P zf}p-#`U_hUXKzY^Q29l)M34!{n1IY^im&a{(LMA#bb&R`G}EFG9o>0xUO6lIUV$c# z3+D?~W2#N+ZhgsLt1uT4JPyGUUA%Q#jB-q7#~ID4()3I{Rq#x}UH45P(w z_O3M!k1w^c2cX9y9JpRFQx6k^H%-65fkgu=m~iJsNySi@SXv{)*5Hx7hoT!W!@z=! zG6qwvAR;KOu>uZ!sR<5I15SYH11C}d)HQ;%{rYU=ZQT8n;>-Ig55nie=NBJ$=tp%= zo{0!NmenCrF;v$GjM>V5(V^B>h8J-ePz7+e{-#4O8WZqOpSt0s^XA^CtS?+6Qjf7m z{eu3ND%}cH4Uf1LQ%fcaIzJ{zJzsE^v?qADFX1S6wyZELJ*V1;V%Y9jWA2d#z|7{2 zb2$+PE)bNwkTpfPOi?(yUaIBCLRtiHWtj_}@q!ByvVt!l?lMv@43OvK0N&bE;_`#O z{@}3ovi$X6u{12xC$K_TOuW7V3aq;c3NNXEiKjLV(vGTMEnu|4F1oXWp%KX6Fg){% z`L~sqDuaw^{dEttKE#$k9zK4S!)>JpL|w{DYP)Txr=lM-T%fcPJGd~tS%E37#@SlW zmXJo(#=jjIRrX&t zbyuLn#>U!eHu9s}X=(@sH;N-*C&bg{3Fq$NBnSk+L|VG#$^aVW9%fO{ViYdsWqgOp ztgq;0z~R~TK-Y8|roE*i4e6n14ZuPpfQe;_0+#r0#_TvAp3N9M`Ec38`b~q1%;V54 zc0}?~t&$NPBbyMbJdjftMm4H1pUSpzjQJ{A0Wr&?afVL4C{^#Y zl6z83k@BnT|1iUP_Sc7rfNO!g zjvY=}&AJP*Fc-|FwROhCjuwEfX0QA2Ato;K63>PE;*&`4P?Bz;@+o2|`W;z^dX2 za#rpcX;KuibJ(WoRN!1*>dW@)UvSxRA87e&80359o$g7)N?mM^HB*e)q$r8(yDLU~ zMZF!i8^6aM3?CmvOdrr|=g~vCuhU`+97yn7*zBq*_*{v7Fr!GO2n5y^F96KL4-N&- zE~qGkrvvPyprB0*z}o5O2nk847YMwJ+!zj=J4+CJfe^)~KaVu**_)RYs#i2ZRLaQB zjsmz2^s2Uz)e08_1}kYhZvieh0+0dT3}psZ3B=rYJT-#1rCJ$^T5acdMQFkINNzRe+91_TEzP(Qu$ zZS1!$=cIvS((nWpQP+RNTzS^m!_IIpFs&&={0B$?3~3<1Kjd*Ti7MPQ^=P(C7N=c} zl}Ud-Y1mS4BWcOp^g-zie`q6y7xvDsBC7K$-l&3&ywgi9G)gt>9h;ekZ8aYoSA^PP zU+W$qqR>OG2_q;Civ_|t1LqPzX$7!9jHZJGLEhRxH!RS{@8I<*CTn&d)L$)@w#@EV z1a{jf+bDjNOl7~~KtYA%op7-`7NJ@)fLA?ZF)1m81gw0Pgp9U<4?kT;aG$$%>Nl{z zl{j&m&AEI@;yYq*tS8hTr<%ie(6%m(tCaDuSj%0I`EY?E|d~A=!--W_BY3 z=2$@SL`qb>g;Cqe{ApXRH;-z`7p-}b;;HJM;ca5MuiK3j;wmw?`?05kJ1>S`DY+)l zh3Q7B;eaUup=!0Ja&B4zXeLzwGty9#8b!98_6`IXCvKR<*2bhwTA&JKrc^;tNLsKI zV2W*EMg~YLk$~IkA625Sc3uqUb+nq+SIoIT;q}!;0)qN&&auvF^^(Uz&XqUTI}z-? zk7ys1;dKaWf5EmfOAxCSkr|wA-FDt3c(r7;GFFuuQMt_CTJ0Yqu9-F{x7PIrb9=%R zXG`$}XeJ(e*P^Gaz8^FI(<7ADmvHL!Y@<*)&cXYj$BN$Erja(=%+xG!Hg+}41Lxya zyZ!)m;5C!%!Fl#)dHz#V?qB6>>hnKCMpI$}jFve0BDcKM`)MzalwH$kbI$9#%J6J) z;HhWp4-fs^fK2+E9WMZjat~VZp0hO6$T0EJ>D1-r?eWS?$==&>oH>Nx5 z9R12L8WH7s-9LR~# zyGQr^PK}8<1X4+cQMgc6O4q}HE?3Mg-eE%d_OJfjXaDodKU@BN?cv97mES;Lem~;v zhA)Gf81CiC+^Tzb;%Ia3TrV6V@-dge>EqQcj2$X-(}Jlw_@0QUu<~SHTj%R-;KO4b z(c`!$jicVX(D7ulhlq2FWEt(Tm)RHDvXrUkpSYrBn9p;rz#hT;4yj)N#x z9`9Vq$iOw)!{KR-pmg}1c|fcLUpP12nRh15%Sv0~@G41XKb46=kIQ(2`7 zfWfaJx5U@*!fHM;lTMF+f*k3dT-wyE_CE>nU4DXTpFX;*^O$~b^U51~)+U;2k6D;J z^v!A3)CtNvvZsI@vmr6W)psi0a|&_ew(%KD!a2EB5{E~Zb-&-8>l`v0JPV%~D*yE% zm38{jMZiYlzW$S?sgXB%C*S^h_E0Z`$9ps9eG-tnK7Q!8?d!uW@_Wv~7%lNHj_=)X zDKDKbzvyt|lbu8&k2bvzi_$cYGWcV2?cqQ3T#~-NC9bK&SBBN$!9lcd!f? z94g1|FE)~KKfL=`-@e_L+JPQUuypLyz2RHI_d=dcc<4s)V{NOc_}GzRl5&xwcoy< zEytLKPDCEyX%r@dsk@J^HDa9t+A^m?y7ldhOg!CQ^!v7T?}uc0j!us2x6PzzBys{O zv%K$dLheI}>{WKpNA+ahWpZBi{;iFGuPRPUw@fbk)>Zjr%u)@oYevmv6NkzIDG_5! zQL!)`G=g=6R!m~Edlb|mVt}66Ks*GqJ#1hk0iy0F6rMOwuvnClhl3@mb2maNSJCD| z9Cl2kxL~^T-KBEE->~?krvRAugG`8b>wnD3&W9_KWVRN|6>03{CL7emtbylDZKfnU z`!_D$J=h5F`!nSEZDq~70o?fAl(JY9*R}l0LLtU1+3WVv7r7yc5`F%&VEVEbp=05iq07@eykD`LB4=e=_# zt1vk&%$jMJ3FmqxNUJtV%P?Tx7L1Gw!{430o2{SzY5W_;Z#yBx(tF+3pjKk}c@>wc zi|z$|s3p%mbgUVo4sT)3woLAac0Vwm`==lJ$o$H-5|33B3dGbE6PMrpYTL{Dj{Y)d zm*{-F(p*jSq*t;QZ1M^YXs(01j7@kh*;Gfiq`>&p^?@(tW>A$vdd6Q?UcHlkcu#>+e)Pg3CLmP5tinkD7}prVNLFsL`S8RZ1Irv(YUr z!fZ~15mgI3sU^$L;Iz@GPI=QjbM?|?gGKQ3XdXDXx*K*!swjLG03`v%iZ(y{ENcWF zh*jbTTmd7tekH}2XXSvBheZ*JV?)fX$_5E{V`Gi|w$1x!Z~Zy3`_juNCtcSbmiyKv zZLm&;vUuiTv!O3>r1RFSCI*QwtybzBp_;74^{HQI34eX4kc_G!lZU7YTVMc3peR4H;dBDT29vl(PF zS{0)|JA!j#+HN{6`PqN`HnNaw`zWhWOJ-*V66vRutD=5k+r-fz5+~qE^BuP$rnee< zDE9Num)Fj-s&aiNofY~5kJ@g1y74YyYWzr3GCtqVxdLEG#pfaRWJ|e~wTD(8{61cK z)}^O%DPo{1dNhtbVONlV7JL1^)|C*)o?73%Oyg=gpGL=pbsxHK>xx+KF5MQ3ujM(C zmT9PSjalftD`E4L87+OmH?tTst7kV!bFQ~uvpwU1<4X%(N$s|4x)8aCGcP|>U*UE5U2`p-Ne=(*%Y{U@orI3}Uu4ClY-&Z! z62`cQHDelvG^-L@Q`cX!=Kk(A5a>V($Ei}V%WM-*f?=PmA`oAgA`l!!g)^Kiopht9 z)sHw~QbpVz8%5&^RJC}vhyE@qu4-%vw`;E0Y2vmM-JAbdIDIvb<2;koq1>7FZkaYm zyrMFCN?yvlhJLF(dFZA4$Av^o^w}KoHZStzEI2i3Wo4(;N&Ik{GFtse(@Amg;u^HFOK;0cc#q11=}r3NRxf@w zoqF*}c~G~eV zC)S46iw@aclMkni z)hLn+I}GQ0Dc7!IH9EKu1o9{8#y+nuNo03kj&ho4z3uY(fR<6j>v=-%CM)&T1l)ld zv>AY3wChsN`%1SXku5GelchC1A*8tmD(K^TkIGfo+Mu0LQw65ntd#XyY#QB@ zRn^}aU#lOQfSy@WEBk$B;pL!e3#|0*l>@+XiSD0-bZ`dfGq{DlF0X2RAZCad0Q*~O zjb^SdPB!E4Hu7>IVHJ;IE^?~XN$tImUNs6JiLFi;pCaXE{&ulmvBlZ&$;k2OWRN6? zH7}Q*%HSp|1TBFEfn=mIxA1NgZO~Q)=6~o%#Xorr!VspGE4U{?D}f96KG90;DUR|= zWq;H7U|2*Ls>KWZp2q9FIl5?F7OzO4T_>BLttQU-EDt!dx7dD>&KNFh!YTin4bOEz zb)RGlxzS};^i)>^YAuJ&B26h;tdR6}xZQS(A5NbV4_>vk2?9$jhjYuX&}!CO!M)bD zjYK2TX-&(PW84}fB}9gT!n4_tYp%D(lQ(Nkug}ixUzzX_Yp;q(MCHVZ)vvUX<|&)= z3`$rTEJHfeeJXZI+S=ZOMVHGZ)$mZmHkFTCbvpBZYX0TwP&e->|C|rKF8O2$-F>49 zyQ-ERpHcJtJjuoOQejR6keD6Bab5*&J{h#VP&j!A)6=={<`Xv45F3rS4kNfmAMV9T zDCww|1?$EH$uQKSi%Z>p9w>k#XPguh4rmR}|?|9jY(8S-rixQsD9Z{MtaH)3{QxqH)932?S&z;(6X zQk>TJoL2W%w|p?RC zDBlu7Oe;!W)AjzXvzaybZ(9qaXLhy6wisW-o?=-msXJBd392H-&+$XdbmE-y`s>}^ zPIg3mMJ6Re%rYYEKGB638>BWyE_bFXfB49z#*xj{FPuGD{d!sXyT<9IO0x;3*;jfc zcf;GnA*ViQzL~*cm3qq3s|Wo|bA7xn6dR}M0@TmdvzIvD9SdfSu?^0);zw@FR?i!R z`}t1Q9QW2G@9}D%j6J=qcNS93?!4|?**617;TzIjv-P97bK#sooBRmfLza^4h5EAY z=yHYapKPhM8@LhwFDTxR1JPAAMOfGjNM2@Ai6??X{K6PE~y$#-O83dKLe2f0Y z&Q*o>Y>?O1!467qP|Tf`5vx&pkw>;O>wW$H(tU0h4UplNyT$g|=j$cCb${?l_2xMb z-=tQjlK3Rt`nH!}C{jj0#M8sRUGzwTGCR}@26kx$;~=e8wLNJy7u_uIxg`*uQ!km} zl4=kVGx@>mVo#0hyYUaoolUWW3cnpF(>AZv9+`bj0-ms@NSj}0DtCU;uvj)M(wlvw zw6aoCVP_o#usRr-I{vZd(#hu(_Orxi<#W$whZ7fa{S|K<=Cb6qEyEad7B3#{#Z8kO zrz5Uf)c&>NfYg@I5M^7+z^jC0?DL$AE{R$)2Iouo?%NB3&6g_#SF6sheNu# zn2Ppjtv8kNB-DR*iKoQ6Qi`qYSPm?*vVt3zosO9=^2buIBhiQ~< zkpW|Y;880N^SP*NU#g?O2Hv9A&8qYk9CfCYx3E89_P3n|mxxQOr6ez+K^4dID+lAP z@rLUXIz=~b>7UMD6X#AS*LF{>CP=Va2nC5PY--PqWSzQ}(|Fcm(`dNcg7uD3&urDC z8-=H7rD&=QKmIndn6%yh(v=4vtl2*Z#(3u)m0tGBFYn+2O=4cUL8*0NyWxjjJ6}ME zG_Ay1rP~p}j--r6&QhMo832*&p_({$>Ff6@y>r@YX46}-kdkE>zf6W0v&_Q-8SbDF zoQKXMHZPSScL^MDPgSqdqw!U3auTEQE)2u>U2)m@e7pk-i9 z+IYMN$qs23fd6E!*3V|eqjamveMe9Yxjxy;1S?h}-})3?14g6K(H%R5St#*h#lDI` zof-4uyRWX)p44;}=ERhixHTI#_1kDUE6|Nc;M$hJ^d-%9j$-L;smXqa`+*q08O$cV zdAhu97Nb1U49o!Su*_4DI6psH#Wyd^8X;Xov>Sf%4x;G;br+3$dDes3a?MK>OSP5; zhG9e}TsaYI&3}YF7cuDnMrfA3ghB4dj7&qMtKdX!EYQGxU+6uT5il?QocFU4^ zwf_CQsr@TM$5f5lMy+ddvtu@ewS(ey+_7QYkuCqQoI32 ztvPdpYZ7c6*c+r@18aw!h=QFXu*;2Vd!TxFF1xX*0d$e1PO?hS+TglWW=wY!EIUYA zGRAryg*&FEQ7wq9br+H@Yw`Gb?FC}z`g_gDz|L~yLd8nvelRM~wH!lj1|Y-xDE7jD zDv<8!e_?9o(E+HVcFJbh*;T@Aud)XoyI%9(td^7L3rXo`bvHiVm^v`~*5$A_o!rZl zoln|csN>(mAdthZ9fLbbJee-lgZKm zSJSBK20v1fu+7bw%^H5+p_mQ_@=#U=!nrHGkaoxr{}6vK^r?i1RjvPpm?8d!o$-(H zaY?wr*(!2Pg+CDLWcIr7m~K;lSYPk`D=nlvHABggMQm2tu2d{Dvn~hXkg21 zxK{9mzf3Q^>YpQA=q_%~+zQVS_RtZ0p}K6F%Ai1PnL$uHV%SoxeofB@Zp#NUaqwWy zsUz4p*nd6mN^$cv27v5wQ$GRrh;j0DWOA4JrGc5|Ge3<_UB>iWcm7F6tTOOOnxT)L4F}@#5}` z&&xp?xYu2pDCsTRlC;Mi&^r9gI{e&x9P8R8cX;CZ0F~?=wv@h<;g8q${E|mH^7e{W z2gKHIgd~u}jgAXNhB;Po`jei5cH>;_5{AFloAGX**0q_nc4_ZEm9L{dx$#tc?CRMY}@hw}*%j0oaY@dvk)F?vK76^tQ>My$4r&H82(;0zCZK#!C>e~k) zha|;HVSIQ8qBw@TTv_!znC96C%78d1AzHOYwE$Zp6d#s{ULIOQbv}RtF%uGHrDCOG z-a$ffS$IU#CdvG~!Li@qa)@u(*pi+3br)JPuG&IWi`WWANw8i}4CA~CUtf8%|JzsB zpOT*(g%aRWO~xS>62fVYa0XoHhkXMuuOQ*cgh$DB=$$gMiV?|WLJviKUkr2);ZIn^Y5)+lLS}9=w6*6#dEC@)P6J}ok!6yR# zQ7ROu8zB$_9kojD1m^tukbRcBTQ|sUUS$WRJWDp$6dxK!#wA5{xCrj^>ZX(C9Fwl$ z>!|a@(ND_JW3fYaIvvXSJ+aA7IhGnO*j*&gy#Xlv04j@CD&FLQMg204?Z`z>qa7A` zVXJ$!$_E|p-~y5+qE+TBX#z0gPwppjFXeDFTTVrqPWxZK)1>Ccv+Xv4u zO3tqrK7SY~HwQ?49=gL1F(eK6k1oGAf4M%|HTb#xcsMTQvf8uunaiCgQ%A$yhr^%u z(YCW0$F@M835-wz7~my`g`HYmJ1d!wGa86$N7|t0X+q7LR@0`i6~RZNgE30%mDOD@ zU!YiP0RX0BKzrlZEe)QKds=O=KMa@Wv29J`E&<>Psc}#G&S~4aY~Jl2HT8oY0rkH( z@+aVfoAd<>Y8oHf$K{LYaho-c2Ar61iJGcfpR-Z~i zUC#chnfg^E`;V1(Pt%jG+us->vHcMw7g13eA*V9nMFnM+LUoT+=gDql%P=??%VZka z<0a(93xE2bf86}COLieyPghL_;osz{)wmN{@ff=P7KhiJNZr)YfSOk-N91m&s{A#9op`5nBL~<6GG$ zgEM2tYv zauc={#-^6Ei-U5oB&>9>^YTEnIel&J)|WX?91Yg!erGqijwoLL##DaS6~GX8KI!?A)OtH<{OR?w2mae$i%HXG%CHo_CcvM6pr_Q+ z+0XHR#lML6pW0bfd zZk2ud1Vp%dgt$07a-lv4g=00i*~{`}CvLws2d&0)dUCBqU+BLFwZ%@3B0L+)GQ&IM za!UNB0NWzg1K=dyL2WezcfJ$^Fwh(0$9fd#QfYh`2$xyYQlm4V4e+Vs3XW=Wck^4G#qx_=F<%^H$+&}1fn^&HO?R^wWm1jaG zm)+9GecT%v9L6jV_L{wSexPc|5Zp6@J%r>y`E^&wsCvQd*qxp*B@mg6Trc(@Nl#0q zsu5Qm(|W~<`bpNQnT;UP^h{}SH7$EkHl%0Sy6b;T8ckyXy9Wa0crQGmd)gcXbzBKu z;TlV~)|Gn-bj%T2;S}jiif}Q`N_@(fk!PbW-LCbd_`04xYy5ciV66L|e&zG%9pakV2;d*o2%cRE{6d~49-1)|C$zS()d*n^SApJfQ)Qcv zHx}l3u;1k>Wr$KrS078k7K#D;|B{gMXl^ zRzLO_vMSKQ4QLTa-l^4(uQhoI6nTC8w$%Ibf#taCoKT8iHOA~DVGfZDDvk!v+t&0P zLb5KxAFV_6<0UH-S#~b8W`F>>wj%dWT;~*1jyRV(Zm!>cko`;8wg-E>b4?plL+=zX0ZkotpocRs*iK;?<(gkTrqeN}X<_X^3j(czqMv5_Oe7SIBR zdkgo0pIA6$Nq2j4V|o=`TMY;O=nY&TxH+7aqD*f{#rV;arhE~wUK<$$v5I9|)^x!D zeQrNLtTrffiQ}?f>{4%CO-}l<8`F`>P`R@4=JE9P*x;b<+-{CYO$Yk=bI)>nd-3tuLNU9+^%)N%|RE z=e4MOscphvXuP-aUWj{GgbN98VG$iOQ1JA0)b-Ot&8AZk#;G0M>^!FCZqnoosV6o+ zFu2@J|Bgv0ilp3dAyNmH24CD;eqwAJB~~hHs0-9jejYryc{Tf&tAmGEj^Y=n z2J6#tPkyaLSV;EW!k^3LnnIk)Zj zF|H=mFx10P>K;yxC7gytHd{~(BAxLz=d%({FAQj>_^Cfm8c)@2#H-76OACmu12t5$ zgQ9_`ic9~#ZcQ8i%u)ll!HcYmKpA(f!P`K23vwlDA>e#nkM}dU7?~RtTbO8*T=-q0O7ZVCF%6rV;g& zs*KE~5(>ozn$aAN;vbS8sEU}3;@NotVN9nXnSH?x4)VP}U!Jv^jN($Ewt$6um=p*o zB;jiule&lR!}8@vMoy<^N$u)^Aqs73GI!>&{OyL1ZTyPDdnmJc6{~^4aA6Kry8fc2 z{b-wjRC=y8P7Wt$dq+kXk`=INI*u4VlCg4oiIcQ8G@y$w>PWqGkhCE}UA#C^?%ap;hYBKYM0$4XmYqc@Kdv0z7F-v!X76eaR^<*&98hRxlQmsY}tP(8N zm|_nq<(tRKU43x5QJ0Fz)rJ}rSy`~>ktp3=csd;?X@hfcw8H0E*+UVMo(}qrAW62Z z*2;`#3inbgFX0#Bj_m7yB?b(QPjr92-~T)6(fJSewsqPUE-4xE< z*(dp*ONZLyduy@<_*rQYFVXj`EL5?!A)Z#2va>Ghz;A#O&BfB^#U8b^i&I{P&+5xB z*rthTxHRrEKHG#FAFX0E26zPX#Xm9Kvm zLYI*TAnUs5k@S-CU|CPga}2Kr_*H@I)3J`>zW7H!vg@702M5Cko7=?wCw4zFCXbS7 z&&?IL!OrW;y9>yZg++ALBNbXLcg3LAKxLH!CoXuu zRb+5je-KR`ym8PL;_hQii>H@9L2NXP_&<{Gtz1PgMCUiHT7NOIifPg$>v>}~56{R2 ziEqpMsA|!DKokQL5{Pl8y5}eBBbIdE`EX6&UD;kDjvd_@P!2fxMmv(7d3L~iO1$FV zAK-tMe>osDk&AIm2m-nw}` z;hMtJnBBSds-!N@Yo><}R6bn0VE$s8_i680$h>Cx)x5ftg}b$HVTcV)Sw_uPg@@9M z`z>?mHBHT5J*FOnCUyB<@>;lCW*)>#nGmTT4gm6bpn?9=t-jxn)-q4Y^S+ZCAl};u zo;m-n`Sic8-MV%BC-if`!L5r6FW%o?Ofos%i}8NJVr3;vgjBLzqUNl*m{!S;0x4#n zS~ZoL!j^-wS0aqiKcvmeB;pD+rq%~u5YNx(ha-Qo-)U%lXt7j$+w5=Gd(Gns>K!K- zYS}8EuWdYUF-~jF)z_GE5u+27pB=gxvCB>tkGUPRGx5wUu@|?O9QVsr^U5xx{ll9B z2Ya+7`jvy?y5y)U{zqu=Lhcb+;8C8;>R{LTh{+GtW*>LPn7hJJ(Xo zSsSdoy0=ywYefzz`%a}KDy`*#u!_FOl&Ca!+lq-`G`KRf?+_LTg#+^eQ;~8p^U9OMr{-p<$G2{WeL36Cx~=r>&tI+;9%%wafVG&v%6wiB=alUb5^)$iX!7;z}ci}#nGx>*K$sq`{In3*Ox4d4XX~Bt@ z*0@X0+;XYdR8ua0y0`xJpV1lpT-Wiqr@Dckx-f~i-sD#xDbr6;lcu5c<_uJb)85gm zPUXLEH~r3gyZrmnlJZa9Nqp zBKyz3|8eC(*UZjo`7wFtY-wYJquF&SKZ3k8x^^+>new&PU#pw{AlD=#CYoXnI*63h z%P!wqZhIA1{V`FV-#ReBkv;nTUp2emKXDFXKAfIZoqgI1|6V>_4AgesZ+&RqnbT4I zY4_mr?by8d-Tt#rBbnbdtL^;%`oo;P`kMFD@b~1x8Gpmr@y}svoRUviKWF7wuGqu!~`t~sAht+hVvrdN^8>E&1dMEl1+QHI4QIPi)(2-E~}`Gp}N!_~AdWu}3q7^QScPq2Ci+Yj534xuh2Vwwn4D zy%@Hb^@vB;^eUnBv3u#ZkB3uytgtZ??RFPxLy9}>l)5y&Tu)1WcsUHO6Yck1`KZe* z*4*^{>ene_hhlH%>$k4i{Q?VFdw6xN>#9O)bjqvPv(szRAB$%WZb#kv_p{>(-9L_$ z&E7iI-pc(u?wiQU@k5<|IGx|#{^R7K?9cy`_50<1zrUh?^=iHq@T-H_)8t+H!++YD z#Vejt=P#PI=Tb2<8*`Iie>F+^)%N!@bCc?Ma;KcMMEw3U+S=XOqjB!*zB3a;xHM{y)8cwfuJPq0_>NdH0#YsXwn#kzI?rXHs)&Qca>) zosBj1GI$+(d4*+#w1%EWo;4atLb1-By!?7I!SE9#`qHrav%lVdPm)G&QVxI`Ec#gI z-xvJ*r~OT-a|!G3-u^1`@M_a`w4I zRyRJl@qzUTt)Oe`|Njv8pHWS1U-&5OQA#i<2|=0)BtR(ALg-Q?h8~or(p%`F(nLUn zLr5S%XaRvB(m_;?5C;`)OoA*PAJ^b9Ysq2e%Krc>cq5 zD{S?;o-t3zHTB*yk*+ffZPyMSwNW@4e91L1^y#1H!mqQ=Ms3_LJEP(>e^NVSuCVaE zTKc`0c~3Uq7d_Z~VQF%yApecX&BY?a9?Ej4WkFUc+?daLUT7*^Dk_*|sap%K^3R`u zu}*tO{?y&e+w#f106$}MQZ`?GAXldxYrIlje?e+EfbJI{Pc7{i^$)YoPaU(bSg?L> zy%azQNURVYm$m-ePPqza>?Kn&_*YE{_`7 z_(xE_Z|gyqsMg%0$Zu5>5B?boy{|b!D$^+)H%xwX#o^I08T6AZieSLN^MFfFEJp5^ zrJA6#UIyG%Qp;O5&Ud8}Bz8Tx0PN7Y9UV)muoj;5s_`=; zi)xIIW`lOu?4AeQ9_N#HQVaF#HT^=%Zv1Hd-tM`&4dZ_3z!TaExA|v6Zlp&&$aBosoV{HA*?&uB*4pVyApZ=i{EneDf<_eH<^QD#T`U?By85&PQeSUW3ZsnWrzBu#k<1^*hTO{C zfea(;NnPU6r2$I9EQ9f)xYq4^-@MrCkd<1qtkn@#8${u*pO5(Z_2PfQ!C?yh6EjyR zSBMWBo)=&GVW75`4W)a4!0w=h|q79zd!_W>GvP{9=!nc=kjl}8WROUCxBzHoTErN5%7e`oSP z73RBkA45Oh9n{c!+=0pEYjEpY-E(YKAoirQUc`&28hq4pQ}{|;*8evw*W4>Vakmbv z6DxG^GeezkJ6xz&e~$-(1BQa$6bTMu=~c(}0nN9T6ml$Tf${{RFpH30+LitLfC^jO za^SN-7eS!=if++{f^yE|m;#8?WY-;GfCfF41iE!SZd1@xT6W;#tPbV z`0Q#seoOP6Nt|0N(Ef9gdv_JEbu*X2(xjWhzYfSS5$s#${}9R2{|NkYma^Ul!3kdb zE@&{r?o$~5754H>Y%7>7lXgpJT9N92^rHMa#P{*xdky_H_;CQbC1BmIiFssrgqs3u zYr4dTtT3?v+$4rWk%obZ{A!8f-jwx$#hFQ#-q#<^a1YP~5KXjO4Zw&f8jiFljf_alBCzW)Ax zWMp_Xfb~BmKIQdKdr{z46(egkXL?h5lZrSK*T)aS{n^dKUo9smCq)Vw&KvpS9|%rS zQHbIFp+8&}#FFB}PGdr(0e9khHyP+69X-?7FNX55OI>7Ky08Dx9^ zd?QM!qM{<~+4aSm7Z>PD;Gn{rI0s}PbwDy;@+W2T5ox*P8qlOvaGbLS$s&-!XSo>vb!#;-?y*5?u&@kW${2o*PgKgI17YZ1n|JD763N|#BxDG| z3AvsYKti0{mKtM~Jx&krTMJAnNUg7_2kHr$?$7O@^hKibupCN99bu;BHROoA=E5E& zWW-+DQ7IqRT*aoqx+3kw_3wx=9PC-%J9YrgZkE#9+D1m&WaY~8{g?Y7_z_1(FmR|r zcc`HR3Y4Qvvn3}hH1?#+EY<)x=J?@_ZGlVF4&T6hA--i{(nAy#=~HM19Mc+@)14wk z(^i`w$uhQ(sO%ib|_MDpC{P_B7PyPkY%7iMvV+ZuZs8T z`7%Kefru$XJ7YBOE*3915$G%48Y{xn4***za+sRgUcJX4G}p%|5d3=pZC z_nnzu4YaKPF%LusWc0Ot+c#<{BqTJypEmE^IpXRfqkYcLMJo=lbbT`PFtM1WAOAHY z#R9J|L>XqU^O-38lS?rK&N;3*gG$=TiK>TC~tk&%JGIU<#g_WrH+xEKMjx=6hY zTRI3Cp*zHt>Kwm)`@59B-S8T`381W49f{e}idEP$txq;heTr~UM>qs+mB8@ZK5UNY zngG1g$6k^~6eC13HyyD5AOj^(?Edd__eR zshv;*u!0k^gy7H|3RA(skwIO<#7~6pRk+C%qwLMRoyV0deSlJ-Ahz-iz!kNEy_s6& zJTr1MMPVe`sop<3-Y6hrd2M`%R1)%r|)N7us%(0X5V8_(O3+a=B z2eS|ivZ}k7Ul<}^oH)yIuftK2(nDzvCt1#zO>1B#gosU5m}y#z8@K@`7QafVO{agsBg4T*lqRT#?o?3M9q|mK zT6=p(WSCGKa9Ii-1ZkGoI31Q^VKh>B2PCrI#3>}CY~%LSglJK(CO{>>LIdHmheww%%&CPiGazYTisQlo?_ua)sdS| zS$C5L4^V0R&rbT~A4N(aE)PM(Ca^^%N)24r?qMf@ic+{=izD2xc?ma7d6JIS?`L}l zgk}cWcDs+}WeR+>t7Ztp1Et7HcZ9p1Y}qn_hC(5f=TPZMwh?<1-=aqL+c2cw#W7Y} zFcA1he=eL!yIEGx{4GzL#QyKVSO7I0`kg?dL6Dd z2>DpKuX%u10GP79w)9KE{15u!2SMp0HNv%iRe1WR>x(*eJ; z*vWps(;FRlD@&a2!XC&Ds~;aniNaf;Y$J-`fAy@=Zn{ojzNbjPFM+l(fp81#K^w$R zm~`+Kl$XHkT>z#)1&_h$BAs>O3d^E+H*|9S=6gT3WNbl*poRd-vSXHAAAeu1R&c~KnAc6DVf>b_?iv6g4$G;oP@WdU=XF$j+d#>m{L(uBP;={m%bA z>Gwke`ol6BN&-#9kPue`?!}^*G9@KtHuYu!(dWDVexA-`%lt39CIJOBd!P0{Cji=u zWTuCJ#Inqe`Tsa--zY-V*6o$8&-+Hyo&2eEF1&;tM|ifPbTAtmyzFg~H8@)PUm*v| zQwQ)d$bX*TQE2GCrT3pi zg2Cnr;3fp9yf2TS9}a{wP!qgQJF3B?5m%L~n;Q-ET=x{y%hyv!r*z*fW{JnJ4K9WS ztL%psFewO;?@Zb)%`7q7smGl08{=Q+3K#bMvkxyI(tj}jR(QS?3td)4#AOet)lZ>(VGuBuwbc%*@P((Ej-@uuEm>F9QGfO0fmUeVt_K=IzrAa2BYO z*l3{L0v&ZhC~63-0bl^qUT;d`TVRYBaBS;q^DUYG1b+?p zXK$_iQixY7N~ia?pdkM3yRyU`z6XN!F@S3R6=O52`{4VB?;B$uf}8`^>4{D=#-z(g zW_HgvTclZ(zp&`-?YFfXSGUA%-2F^^_n-9oQvl3Guy-a8twq#v_OHbTR#l++;YG80aAGT6fmoIyLiNUY{~Py{ljnoh2C=F5;8(f z>0_AS<(B|MyDx8J_7d5`#a`Wq6k~ozfjwz@`OC}f1ACk&*@-y)n=W7B(Z@*5=%A^sq3JTBH ze7JU8?3&E8yXn5$zYlC)*p9rYg>H5qZ&$BLuWHq=Ok%LgC(7THr*F1?6A-sH{H9i9 zYxWIx3omYU%S?Q!e4==)`~`i-Vp%CJ*En`rL6hUOs3c>DgetsU0r`pH~hO951GI~mT z7ae%F;B(|T=YotN!mF7VaU%qp_Y|fzT8I|eQc{qUA|qMQ^maWYD$ODx^o~}~eAl73 zl)9|(Tr@ZEj#Ad(-=34rel`jdrZ~L@xgLlE$`c>knu%e4?rM$e`$^jD7^1PM3pUk1>q)<&*}J^}lN4I7l4pz}g`O+MtFlsyvSP&Rp!D9v3-mwzp( z93put6jzXA4!G-s9Nzoir+>@FopU~MLM)SCGH!$AwmLtb6Pj%UHlkjJe&zXi)Km|o z9)~^}@+7BZjoBeI;zr1D?1dV2mV&LBg!NEW9F#WBCzuJ9CNKHL1)0C3KJ?Qqa zNs#KmWOX3HOX={5WV}L7psx%{aItpyaL9~N#goIOQ?R6RlV3KL+|2HI9DNEUm48a1 zL!qj+bc!^kHeXwE_?&x#SA(TaIZcvK3%#PqP_%|QI!V((`EKTwBba06f7P_XG@ejn zWr0Og<7h%;(fW9VMn>5>KG3obf|@qHJ>y}K~WLzA1G*e1r?G+S1L!#PGAQBx>V(EY6CWwraH?(o(!uFL>!Z6%|RtRumX)jD5i z#m9N`2e}Z0TDuq3kk^7a7qvIC-qwPRsiPA&_piwm3-@HLdM8+B>+(tNa=eYh!M}Tb zoBUsG2bp=n@vU1@-+1ejEi8`6W|=lvNS&o+Bqf*EmiB;i9C3ncfjMJxa-{Zi9O-6X z?Ct$U)p88I5T@leA-bhdukc)6Tj|?yveUtGJ3Sq#VGxs}2`S)|2smxyFB)X;z%hH< zvO?YPy0Q&v3GGgoS5jJ7QkRRr#HbENoo)!d}#JuZ6N^Z`1#yrzLJOL}eL zKF4ReeBuNjQ6&7bZ2ioZmKHov(8dTwvi5&fCBh$sk|VVR6&Gls-dfBjb?UEe_0U4k z3k+3{KFS;mmCgd+B2=}PjX&uB=26l!LVdl19EcG|lsiuFhVek?Ob|BH^j^t;^Tz?( z*5Jr!xVEL0s}4og2}PH!vTIehih}wnmOnjenk>Pf$eT8(elv{0zJ!Iiq02?VMvdbF zw+KO$aF5r@kY%o#9=o&MOPBZ{S1Q#YCxV5!1{mJLW*JTAj7wM8<@?H1&;LF^#rLda zjp?5Ka@2yFnXV5lW}r+=XBr!;n)wKYRFr$eQPr&Jd|z3ucv?0BZ+4F>O~hNE06{0c zHfwK3(NHQ&QDJ7@FtB~0@_(QV* z=e@{exn_=Lm0JaK5Kc7ZCpugYaiqN%`rG+Da<&jIM|4lTVpmbxvBa;+YS=B5QTD?5kE$?qLt_E43>Zx8xT$ddhGX znQ@P{3d8*HMT8W%Y46MgRlWE*jaaZScTGu8RTeee%0AUncZvT9!3HBQ*TFzH7mrm% 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 z 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 z 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 DMU-Y2 literal 0 HcmV?d00001 diff --git a/main.py b/main.py index 85d63d8..7ec7128 100644 --- a/main.py +++ b/main.py @@ -2,14 +2,12 @@ Main module for the Image Processor application. """ -import tkinter as tk -from tkinter import ttk -import customtkinter +import customtkinter as ctk from ui.log_window import LogWindow from ui.local_processing_tab import LocalProcessingTab from ui.settings_tab import SettingsTab from config.decrypt_config import ConfigDecryptor, DECRYPTION_KEY - +from config.encrypt_config import ConfigEncryptor class ImageProcessorApp: """ @@ -21,42 +19,69 @@ class ImageProcessorApp: Initialize the ImageProcessorApp. Args: - root (tk.Tk): The root Tkinter window. + root (ctk.CTk): The root CustomTkinter window. """ self.root = root self.root.title("Image Processor") - self.root.geometry("500x450") + self.root.geometry("520x600") - self.tab_parent = ttk.Notebook(self.root) - self.log_window = None + # Create menu frame at the top + menu_frame = ctk.CTkFrame(self.root) + menu_frame.pack(side="top", fill="x") - self.local_processing_tab = LocalProcessingTab( - self.tab_parent, "Local Processing", self.open_log_window - ) - self.settings_tab = SettingsTab(self.tab_parent, "Settings") + local_processing_button = ctk.CTkButton(menu_frame, text="Local Processing", command=self.show_local_processing_tab) + local_processing_button.pack(side="left", padx=5, pady=5) - self.tab_parent.pack(expand=True, fill="both") + settings_button = ctk.CTkButton(menu_frame, text="Settings", command=self.show_settings_tab) + settings_button.pack(side="left", padx=5, pady=5) - def open_log_window(self): + # Create main frame to hold tabs and log window + main_frame = ctk.CTkFrame(self.root) + main_frame.pack(expand=True, fill="both") + + self.tab_parent = ctk.CTkFrame(main_frame) + self.tab_parent.grid(row=0, column=0, sticky="nsew") + + self.log_frame = ctk.CTkFrame(main_frame) + self.log_frame.grid(row=1, column=0, sticky="nsew") + + main_frame.grid_rowconfigure(0, weight=3) + main_frame.grid_rowconfigure(1, weight=1) + main_frame.grid_columnconfigure(0, weight=1) + + self.log_window = LogWindow(self.log_frame) + + self.local_processing_tab = LocalProcessingTab(self.tab_parent, self.log_window) + self.settings_tab = SettingsTab(self.tab_parent) + + self.local_processing_tab.tab.grid(row=0, column=0, sticky="nsew") + self.settings_tab.tab.grid(row=0, column=0, sticky="nsew") + + self.show_local_processing_tab() + + def show_local_processing_tab(self): """ - Open the log window. If it already exists, bring it to the front. + Show the Local Processing tab. """ - if self.log_window is None or not self.log_window.winfo_exists(): - self.log_window = LogWindow(self.root) - else: - self.log_window.lift() + self.local_processing_tab.tab.tkraise() + + def show_settings_tab(self): + """ + Show the Settings tab. + """ + self.settings_tab.tab.tkraise() def run(self): """ - Run the Tkinter main loop. + Run the CustomTkinter main loop. """ self.root.mainloop() if __name__ == "__main__": try: - decryptor = ConfigDecryptor(DECRYPTION_KEY) - config = decryptor.decrypt() + decryptor = ConfigEncryptor(DECRYPTION_KEY) + config = decryptor.load_config() wc_url = config["url"] wc_consumer_key = config["consumer_key"] wc_consumer_secret = config["consumer_secret"] @@ -65,6 +90,8 @@ if __name__ == "__main__": except FileNotFoundError as e: print(f"File not found: {e}") - root = customtkinter.CTk() + root = ctk.CTk() + ctk.set_appearance_mode("dark") + ctk.set_default_color_theme("blue") app = ImageProcessorApp(root) app.run() diff --git a/ui/local_processing_tab.py b/ui/local_processing_tab.py index cb9fdbe..94a9337 100644 --- a/ui/local_processing_tab.py +++ b/ui/local_processing_tab.py @@ -4,40 +4,39 @@ Module for the Local Processing Tab in the Image Processor application. import tempfile import threading -import tkinter as tk -from tkinter import ttk +import customtkinter as ctk from tkinter.scrolledtext import ScrolledText -from tkinter import Tk, Label, Button, Entry, Toplevel, StringVar, BooleanVar +from tkinter import StringVar, BooleanVar from PIL import Image, ImageTk from utils.file_operations import FileProcessor from utils.image_processing import ImageProcessor from api.woocommerce_api import process_product_images, process_all_products from ui.options_window import OptionsWindow -from pprint import pformat, pprint +from pprint import pformat from config.encrypt_config import ConfigEncryptor +import os + class LocalProcessingTab: """ Class for the Local Processing Tab in the Image Processor application. """ - def __init__(self, tab_parent, text, log): + def __init__(self, tab_parent, log_window): """ Initialize the LocalProcessingTab. Args: - tab_parent (ttk.Notebook): The parent notebook widget. - text (str): The text to display on the tab. - log (function): The function to log messages. + tab_parent (ctk.CTkFrame): The parent frame widget. + log_window (LogWindow): The log window frame. """ key = b"u4xTBY5Ns4WYdLvqMjEr138mpMmDEhhqTszKCcDy2cI=" - - self.log = log - self.tab = ttk.Frame(tab_parent) + + self.log_window = log_window + self.log = self.log_window.log_message + self.tab = ctk.CTkFrame(tab_parent) self.root = self.tab.winfo_toplevel() # Store the root window reference - tab_parent.add(self.tab, text=text) self.config = ConfigEncryptor(key) - self.log_window = None self.canvas_width = 900 self.canvas_height = 900 @@ -48,7 +47,7 @@ class LocalProcessingTab: self.image_format = "AUTO" self.image_size = "contain" self.load_config() - self.source_type = StringVar(value="local") + self.source_type = StringVar(value="directory") self.checkbox_var = BooleanVar(value=False) self.file = FileProcessor() self.image = ImageProcessor() @@ -58,8 +57,8 @@ class LocalProcessingTab: self.update_options() def load_config(self): - config = self.config.load_config() + print(config) if config: if options := config.get("options"): self.canvas_width = options.get("canvas_width", 900) @@ -71,125 +70,126 @@ class LocalProcessingTab: self.image_format = options.get("image_format", "AUTO") self.image_size = options.get("image_size", "contain") - - def create_log_window(self): - """ - Create and display the log window. - """ - if self.log_window and Toplevel.winfo_exists(self.log_window): - return - self.log_window = Toplevel() - self.log_window.title("Processing Log") - self.log_text = ScrolledText( - self.log_window, state="disabled", wrap="word", height=20, width=80 - ) - - self.log_text.pack(expand=True, fill="both") - - def log_message(self, message): - """ - Log a message to the log window. - - Args: - message (str): The message to log. - """ - if self.log_window: - self.log_text.config(state="normal") - self.log_text.insert(tk.END, message + "\n") - self.log_text.see(tk.END) - self.log_text.config(state="disabled") - self.log_text.update_idletasks() - def setup_ui(self): """ Set up the user interface for the tab. """ - # Source selection section - self.source_label = Label(self.tab, text="Source Type:") - self.source_label.grid(row=0, column=0, padx=5, pady=5, sticky="w") + current_row = 0 - self.source_dropdown = ttk.Combobox( + # Source selection section + self.source_label = ctk.CTkLabel(self.tab, anchor="w", width=500, text="Source Type:") + self.source_label.grid(row=current_row, column=0, columnspan=6, padx=5, pady=5, sticky="w") + + current_row += 1 + + self.source_dropdown = ctk.CTkComboBox( self.tab, - textvariable=self.source_type, - values=["local", "product", "all_products"], + variable=self.source_type, + values=["directory", "file", "wp_image", "product", "all_products"], state="readonly", + command=self.update_options ) - self.source_dropdown.grid(row=1, column=0, padx=5, pady=5, sticky="w") + self.source_dropdown.grid(row=current_row, column=0, columnspan=2, padx=5, pady=5, sticky="w") self.source_dropdown.bind( "<>", lambda e: self.update_options() ) - - self.browse_button = ttk.Button( - self.tab, text="Browse", command=self.browse_directory_command - ) - self.browse_button.grid(row=2, column=0, padx=5, pady=5, sticky="w") - - # WooCommerce Product ID section - self.product_id_label = Label(self.tab, text="Product ID:") - self.product_id_label.grid(row=2, column=0, padx=5, pady=5, sticky="w") - - self.product_id_entry = Entry(self.tab) - self.product_id_entry.grid(row=3, column=0, padx=5, pady=5, sticky="w") - - # SKU section - self.additional_name_label = Label(self.tab, text="Add suffix:") - self.additional_name_label.grid( - row=2, column=1, padx=5, pady=5, sticky="w") - - self.additional_name_entry = Entry(self.tab) - self.additional_name_entry.grid( - row=2, column=2, padx=5, pady=5, sticky="w") - - # Options button - self.options_button = ttk.Button( + # Options button + self.options_button = ctk.CTkButton( self.tab, text="Options", command=self.open_options_window ) - self.options_button.grid(row=2, column=3, columnspan=2, padx=5, pady=5, sticky="w") + self.options_button.grid(row=current_row, column=4, columnspan=2, padx=5, pady=5, sticky="w") - self.button_start = Button( + current_row += 1 + + self.button_start = ctk.CTkButton( self.tab, text="Start Processing", command=self.start_processing ) self.button_start.grid( - row=1, column=3, columnspan=2, padx=5, pady=5, sticky="w" + row=current_row, column=4, columnspan=2, padx=5, pady=5, sticky="w" ) + self.browse_button = ctk.CTkButton( + self.tab, text="Browse directory", command=self.browse_directory_command + ) + self.browse_button.grid(row=current_row, column=0, columnspan=2, padx=5, pady=5, sticky="w") + + self.browse_file_button = ctk.CTkButton( + self.tab, text="Browse file", command=self.browse_file_command + ) + self.browse_file_button.grid(row=current_row, column=0, columnspan=2, padx=5, pady=5, sticky="w") + + # WooCommerce Product ID section + self.product_id_button = ctk.CTkButton(self.tab, text="Get", width=25) + self.product_id_button.grid(row=2, column=2, columnspan=1, padx=5, pady=5, sticky="w") + + self.product_id_entry = ctk.CTkEntry(self.tab) + self.product_id_entry.grid(row=current_row, column=0, columnspan=2,padx=5, pady=5, sticky="w") + + # SKU section + self.additional_name_label = ctk.CTkLabel(self.tab, text="Add suffix:") + self.additional_name_label.grid( + row=current_row, column=1, padx=5, pady=5, sticky="w") + + self.additional_name_entry = ctk.CTkEntry(self.tab) + self.additional_name_entry.grid( + row=current_row, column=2, padx=5, pady=5, sticky="w") + + current_row += 1 + + # Destination selection section + self.destionation_label = ctk.CTkLabel(self.tab, anchor="w", width=500, text="Destination Type:") + self.destionation_label.grid(row=current_row, column=0, columnspan=6, padx=5, pady=5, sticky="w") + + current_row += 1 + + self.destionation_dropdown = ctk.CTkComboBox( + self.tab, + variable=self.source_type, + values=["auto", "directory", "file", "wp_image", "product"], + state="readonly", + command=self.update_options + ) + self.destionation_dropdown.grid(row=current_row, column=0, columnspan=2, padx=5, pady=5, sticky="w") + self.destionation_dropdown.bind( + "<>", lambda e: self.update_options() + ) + + current_row += 1 + # Image previews - self.before_label = Label(self.tab, text="Before:") - self.before_label.grid(row=5, column=0, padx=5, pady=5, sticky="w") - self.before_image_label = Label(self.tab) - self.before_image_label.grid( - row=6, column=0, padx=5, pady=5, sticky="w") + self.before_label = ctk.CTkLabel(self.tab, text="Before:") + self.before_label.grid(row=current_row, column=0, padx=5, pady=5, sticky="w") - self.after_label = Label(self.tab, text="After:") - self.after_label.grid(row=5, column=1, padx=5, pady=5, sticky="w") - self.after_image_label = Label(self.tab) + self.after_label = ctk.CTkLabel(self.tab, text="After:") + self.after_label.grid(row=current_row, column=3, padx=5, pady=5, sticky="w") + + current_row += 1 + + self.after_image_label = ctk.CTkLabel(self.tab, text="") self.after_image_label.grid( - row=6, column=1, padx=5, pady=5, sticky="w") + row=current_row, column=3, columnspan=3, padx=5, pady=5, sticky="w") + + self.before_image_label = ctk.CTkLabel(self.tab, text="") + self.before_image_label.grid( + row=current_row, column=0, columnspan=3, padx=5, pady=5, sticky="w") - def update_options(self): + def update_options(self, text=None): """ Update the UI elements based on the selected source type. """ - if self.source_type.get() == "local": + self.product_id_button.grid_remove() + self.product_id_entry.grid_remove() + self.additional_name_label.grid_remove() + self.additional_name_entry.grid_remove() + self.browse_button.grid_remove() + self.browse_file_button.grid_remove() + if self.source_type.get() == "directory": self.browse_button.grid() - self.product_id_label.grid_remove() - self.product_id_entry.grid_remove() - self.additional_name_label.grid_remove() - self.additional_name_entry.grid_remove() elif self.source_type.get() == "product": - self.browse_button.grid_remove() - self.product_id_label.grid() + self.product_id_button.grid() self.product_id_entry.grid() - self.additional_name_label.grid_remove() - self.additional_name_entry.grid_remove() - else: - self.browse_button.grid_remove() - self.product_id_label.grid_remove() - self.product_id_entry.grid_remove() - self.product_id_label.grid() - self.product_id_entry.grid() - self.additional_name_label.grid_remove() - self.additional_name_entry.grid_remove() + elif self.source_type.get() == "file": + self.browse_file_button.grid() self.update_previews() def update_previews(self, before_path=None, after_path=None): @@ -200,39 +200,40 @@ class LocalProcessingTab: before_path (str, optional): The path to the 'before' image. after_path (str, optional): The path to the 'after' image. """ + first_image_path = self.file.get_first_image_path() + if not before_path and not first_image_path: + first_image_path = "images/image-7.jpg" # Set the path to your image here if before_path and after_path: before_img = Image.open(before_path) - before_img.thumbnail((150, 150)) + before_img.thumbnail((200, 200)) before_photo = ImageTk.PhotoImage(before_img) - self.before_image_label.config(image=before_photo) + self.before_image_label.configure(image=before_photo) self.before_image_label.image = before_photo after_img = Image.open(after_path) - after_img.thumbnail((150, 150)) + after_img.thumbnail((200, 200)) after_photo = ImageTk.PhotoImage(after_img) - self.after_image_label.config(image=after_photo) + self.after_image_label.configure(image=after_photo) self.after_image_label.image = after_photo - else: - first_image_path = self.file.get_first_image_path() - if first_image_path: - with tempfile.NamedTemporaryFile( - suffix=".jpg", delete=False - ) as temp_file: - output_path = temp_file.name - self.image.resize_image( - first_image_path, output_path, self.get_options() - ) - before_img = Image.open(first_image_path) - before_img.thumbnail((150, 150)) - before_photo = ImageTk.PhotoImage(before_img) - self.before_image_label.config(image=before_photo) - self.before_image_label.image = before_photo + elif first_image_path: + with tempfile.NamedTemporaryFile( + suffix=".jpg", delete=False + ) as temp_file: + output_path = temp_file.name + self.image.resize_image( + first_image_path, output_path, self.get_options() + ) + before_img = Image.open(first_image_path) + before_img.thumbnail((200, 200)) + before_photo = ImageTk.PhotoImage(before_img) + self.before_image_label.configure(image=before_photo) + self.before_image_label.image = before_photo - after_img = Image.open(output_path) - after_img.thumbnail((150, 150)) - after_photo = ImageTk.PhotoImage(after_img) - self.after_image_label.config(image=after_photo) - self.after_image_label.image = after_photo + after_img = Image.open(output_path) + after_img.thumbnail((200, 200)) + after_photo = ImageTk.PhotoImage(after_img) + self.after_image_label.configure(image=after_photo) + self.after_image_label.image = after_photo def set_image_preview(self, image_path, label): """ @@ -240,24 +241,41 @@ class LocalProcessingTab: Args: image_path (str): The path to the image file. - label (Label): The label to set the image on. + label (ctk.CTkLabel): The label to set the image on. """ img = Image.open(image_path) img.thumbnail((150, 150)) photo = ImageTk.PhotoImage(img) - label.config(image=photo) + label.configure(image=photo) label.image = photo + def browse_file_command(self): + """ + Command to browse for a file. + """ + file = self.file.browse_files() + if file: + file_name = os.path.basename(file) + if len(file_name) > 20: + file_name = f"...{file_name[-20:]}" + self.browse_file_button.configure(text=file_name) + self.apply_options(self.get_options()) + self.update_previews() + def browse_directory_command(self): """ Command to browse for a directory. """ directory = self.file.browse_directory() if directory: - self.browse_button.config(text=directory) + dir_name = os.path.basename(directory) + if len(dir_name) > 20: + dir_name = f"...{dir_name[-20:]}" + self.browse_button.configure(text=dir_name) self.apply_options(self.get_options()) self.update_previews() + def apply_canvas_size(self): """ Apply the canvas size settings and update previews. @@ -275,7 +293,6 @@ class LocalProcessingTab: Apply the canvas size settings and update previews. """ self.image.set_background_color(self.background_color) - def get_options(self) -> dict: """ @@ -288,7 +305,7 @@ class LocalProcessingTab: "selected_directory": self.browse_button.cget("text"), "canvas_width": self.canvas_width, "canvas_height": self.canvas_height, - "log_message": self.log_message, + "log_message": self.log, # Use the log method from the log_window "format_log_message": self.pprint_log_message, "update_previews": self.update_previews, "product_id": self.product_id_entry.get(), @@ -330,25 +347,25 @@ class LocalProcessingTab: "default": self.delete_images, }, "background_color": { - "type": "color", - "label": "Background Color:", + "type": "color", + "label": "Background Color:", "default": self.background_color - }, + }, "image_format": { - "type": "dropdown", - "label": "Image Format:", + "type": "dropdown", + "label": "Image Format:", "options": ["AUTO", "JPEG", "PNG", "GIF", "DZI"], "default": self.image_format }, "image_size": { - "type": "dropdown", - "label": "Image Size:", + "type": "dropdown", + "label": "Image Size:", "options": ["contain", "cover"], "default": self.image_size } } - + OptionsWindow(self.root, self.apply_options, current_options) def apply_options(self, options): @@ -359,8 +376,7 @@ class LocalProcessingTab: options (dict): The options to apply. """ if self.log_window: - self.log_window.destroy() - self.log_window = None + self.log_window.clear() # Clear the log window if it exists self.canvas_width = options["canvas_width"] self.canvas_height = options["canvas_height"] self.template = options["template"] @@ -383,17 +399,16 @@ class LocalProcessingTab: obj (object): The object to format and log. """ formatted_message = pformat(obj) - self.log_message(formatted_message) + self.log(formatted_message) def start_processing(self): """ Start the image processing based on the selected options. """ - self.create_log_window() source = self.source_type.get() options = self.get_options() - if source == "local": + if source == "directory": threading.Thread( target=self.file.process_directory_with_logging, args=(options,) ).start() @@ -402,6 +417,11 @@ class LocalProcessingTab: target=process_product_images, args=(options,) ).start() + elif source == "file": + threading.Thread( + target=self.file.proces_single_image, + args=(options,) + ).start() elif source == "all_products": threading.Thread( target=process_all_products, diff --git a/ui/log_window.py b/ui/log_window.py index 9486c0d..06e7e0f 100644 --- a/ui/log_window.py +++ b/ui/log_window.py @@ -1,18 +1,37 @@ -from tkinter import Toplevel, Text -from pprint import pprint +import customtkinter as ctk -class LogWindow(Toplevel): - def __init__(self, master=None, **kwargs): - super().__init__(master, **kwargs) - self.title("Log Window") - self.geometry("500x300") - self.text = Text(self) - self.text.pack(expand=True, fill="both") - self.protocol("WM_DELETE_WINDOW", self.hide) +class LogWindow: + def __init__(self, parent): + self.frame = ctk.CTkFrame(parent) + self.frame.pack(expand=True, fill="both") - def log(self, message): - self.text.insert("end", pprint(message) + "\n") - self.text.see("end") + self.log_text = ctk.CTkTextbox(self.frame, state="disabled", wrap="word", height=10) + self.log_text.pack(side="left", expand=True, fill="both") - def hide(self): - self.withdraw() + self.scrollbar = ctk.CTkScrollbar(self.frame, command=self.log_text.yview) + self.scrollbar.pack(side="right", fill="y") + + self.log_text.configure(yscrollcommand=self.scrollbar.set) + + def log_message(self, message): + self.log_text.configure(state="normal") + self.log_text.insert(ctk.END, message + "\n") + self.log_text.see(ctk.END) + self.log_text.configure(state="disabled") + self.log_text.update_idletasks() + + def clear(self): + self.log_text.configure(state="normal") + self.log_text.delete('1.0', ctk.END) + self.log_text.configure(state="disabled") + +# Example usage +if __name__ == "__main__": + root = ctk.CTk() + log_window = LogWindow(root) + + # Example log messages + log_window.log_message("This is a test message.") + log_window.log_message("Another test message.") + + root.mainloop() diff --git a/ui/options_window.py b/ui/options_window.py index 4a9831b..71b41b9 100644 --- a/ui/options_window.py +++ b/ui/options_window.py @@ -1,7 +1,8 @@ -import tkinter as tk -from tkinter import ttk, colorchooser, messagebox -from pprint import pprint -class OptionsWindow(tk.Toplevel): +import customtkinter as ctk +from tkinter import colorchooser, messagebox + + +class OptionsWindow(ctk.CTkToplevel): def __init__(self, parent, apply_callback, current_options): super().__init__(parent) self.title("Options") @@ -12,6 +13,8 @@ class OptionsWindow(tk.Toplevel): self.inputs = {} self.setup_ui() + self.attributes('-topmost', True) # Ensure the window stays on top + self.lift() # Bring the window to the front def setup_ui(self): """ @@ -19,27 +22,33 @@ class OptionsWindow(tk.Toplevel): """ self.row_index = 0 for name, details in self.options.items(): - if details["type"] == "number": - self.add_number_input( - name, - details["label"], - details["default"], - details["min"], - details["max"], - ) - elif details["type"] == "text": - self.add_text_input(name, details["label"], details["default"]) - elif details["type"] == "checkbox": - self.add_checkbox(name, details["label"], details["default"]) - elif details["type"] == "dropdown": - self.add_dropdown( - name, details["label"], details["options"], details["default"] - ) - elif details["type"] == "color": - self.add_color_picker(name, details["label"], details["default"]) + self.create_option(name, details) self.create_apply_button() + def create_option(self, name, details): + """ + Create an option based on its type. + """ + if details["type"] == "number": + self.add_number_input( + name, + details["label"], + details["default"], + details["min"], + details["max"], + ) + elif details["type"] == "text": + self.add_text_input(name, details["label"], details["default"]) + elif details["type"] == "checkbox": + self.add_checkbox(name, details["label"], details["default"]) + elif details["type"] == "dropdown": + self.add_dropdown( + name, details["label"], details["options"], details["default"] + ) + elif details["type"] == "color": + self.add_color_picker(name, details["label"], details["default"]) + def add_number_input(self, name, label, default, min_val, max_val): """ Add a number input field. @@ -51,10 +60,10 @@ class OptionsWindow(tk.Toplevel): min_val (int): The minimum value. max_val (int): The maximum value. """ - lbl = tk.Label(self, text=label) - lbl.grid(row=self.row_index, columnspan=1,column=0, padx=5, pady=5, sticky="w") + lbl = ctk.CTkLabel(self, text=label) + lbl.grid(row=self.row_index, columnspan=1, column=0, padx=5, pady=5, sticky="w") - entry = tk.Entry(self) + entry = ctk.CTkEntry(self) entry.insert(0, str(default)) entry.grid(row=self.row_index, columnspan=2, column=1, padx=5, pady=5, sticky="w") @@ -75,10 +84,10 @@ class OptionsWindow(tk.Toplevel): label (str): The label for the input field. default (str): The default value. """ - lbl = tk.Label(self, text=label) + lbl = ctk.CTkLabel(self, text=label) lbl.grid(row=self.row_index, column=0, padx=5, pady=5, sticky="w") - entry = tk.Entry(self) + entry = ctk.CTkEntry(self) entry.insert(0, default) entry.grid(row=self.row_index, columnspan=2, column=1, padx=5, pady=5, sticky="w") @@ -94,8 +103,8 @@ class OptionsWindow(tk.Toplevel): label (str): The label for the input field. default (bool): The default value. """ - var = tk.BooleanVar(value=default) - chk = tk.Checkbutton(self, text=label, variable=var) + var = ctk.BooleanVar(value=default) + chk = ctk.CTkCheckBox(self, text=label, variable=var) chk.grid(row=self.row_index, column=0, columnspan=2, padx=5, pady=5, sticky="w") @@ -112,32 +121,24 @@ class OptionsWindow(tk.Toplevel): options (list): The list of options. default (str): The default value. """ - lbl = tk.Label(self, text=label) + lbl = ctk.CTkLabel(self, text=label) lbl.grid(row=self.row_index, column=0, padx=5, pady=5, sticky="w") - combo = ttk.Combobox(self, values=options, state="readonly") + combo = ctk.CTkComboBox(self, values=options, state="readonly") combo.set(default) - combo.grid(row=self.row_index,columnspan=2, column=1, padx=5, pady=5, sticky="w") + combo.grid(row=self.row_index, columnspan=2, column=1, padx=5, pady=5, sticky="w") self.inputs[name] = {"type": "dropdown", "widget": combo} self.row_index += 1 - def check_transparent(self, var, color_entry, pick_button, color_preview): - if var.get(): - color_entry.config(state="disabled") - pick_button.config(state="disabled") - color_preview.config(bg="white") - else: - color_entry.config(state="normal") - pick_button.config(state="normal") - color_preview.config(bg=color_entry.get()) + def pick_color(self, button): + self.attributes('-topmost', False) # Temporarily disable topmost to allow colorchooser to be on top + color_code = colorchooser.askcolor(parent=self, title="Choose color")[1] + self.attributes('-topmost', True) # Re-enable topmost for this window - def pick_color(self, color_entry, color_preview): - color_code = colorchooser.askcolor(title="Choose color")[1] if color_code: - color_entry.delete(0, tk.END) - color_entry.insert(0, color_code) - color_preview.config(bg=color_code) + button.configure(fg_color=color_code) + self.inputs[button.name]["color"] = color_code def add_color_picker(self, name, label, default): """ @@ -148,36 +149,32 @@ class OptionsWindow(tk.Toplevel): label (str): The label for the color picker. default (str): The default color. """ - if default == "transparent": - default = "#ffffff" - var = tk.BooleanVar(value=True) - else: - var = tk.BooleanVar(value=False) - lbl = tk.Label(self, text=label) + lbl = ctk.CTkLabel(self, text=label) lbl.grid(row=self.row_index, column=0, padx=5, pady=5, sticky="w") - color_preview = tk.Label(self, bg=default, width=2, height=1) - color_preview.grid(row=self.row_index, column=1, padx=5, pady=5, sticky="w") + color_button = ctk.CTkButton(self, text="", width=30, command=lambda: self.pick_color(color_button)) + color_button.name = name + color_button.configure(fg_color=default) + color_button.grid(row=self.row_index, column=1, padx=5, pady=5, sticky="w") - color_entry = tk.Entry(self) - color_entry.insert(0, default) - color_entry.grid(row=self.row_index, column=2, padx=5, pady=5, sticky="w") + chk_var = ctk.BooleanVar(value=(default == "transparent")) + chk = ctk.CTkCheckBox(self, text="Transparent", variable=chk_var, command=lambda: self.check_transparent(chk_var, color_button)) + chk.grid(row=self.row_index, column=2, padx=5, pady=5, sticky="w") - pick_button = tk.Button(self, text="Pick", command=lambda: self.pick_color(color_entry, color_preview)) - pick_button.grid(row=self.row_index, column=3, padx=5, pady=5, sticky="w") - - - chk = tk.Checkbutton(self, text="Transparent", variable=var, command=lambda: self.check_transparent(var, color_entry, pick_button, color_preview)) - chk.grid(row=self.row_index, column=4, padx=5, pady=5, sticky="w") - - self.inputs[name] = {"type": "color", "entry": color_entry, "transparent_var": var} + self.inputs[name] = {"type": "color", "button": color_button, "transparent_var": chk_var, "color": default} self.row_index += 1 + def check_transparent(self, var, button): + if var.get(): + button.configure(state="disabled", fg_color="#ffffff") + else: + button.configure(state="normal") + def create_apply_button(self): """ Create the apply button. """ - apply_button = tk.Button( + apply_button = ctk.CTkButton( self, text="Apply", command=self.apply_options) apply_button.grid(row=self.row_index, column=0, columnspan=2, pady=10) @@ -205,10 +202,10 @@ class OptionsWindow(tk.Toplevel): elif details["type"] == "dropdown": options[name] = details["widget"].get() elif details["type"] == "color": - if "value" in details: - options[name] = details["value"] - else: + if details["transparent_var"].get(): options[name] = "transparent" + else: + options[name] = details["color"] self.apply_callback(options) self.destroy() @@ -222,33 +219,7 @@ class OptionsWindow(tk.Toplevel): condition (function): The condition function that returns a boolean. """ if condition(): - if self.inputs[name]["type"] == "number": - self.add_number_input( - name, - self.inputs[name]["label"], - self.inputs[name]["default"], - self.inputs[name]["min"], - self.inputs[name]["max"], - ) - elif self.inputs[name]["type"] == "text": - self.add_text_input( - name, self.inputs[name]["label"], self.inputs[name]["default"] - ) - elif self.inputs[name]["type"] == "checkbox": - self.add_checkbox( - name, self.inputs[name]["label"], self.inputs[name]["default"] - ) - elif self.inputs[name]["type"] == "dropdown": - self.add_dropdown( - name, - self.inputs[name]["label"], - self.inputs[name]["options"], - self.inputs[name]["default"], - ) - elif self.inputs[name]["type"] == "color": - self.add_color_picker( - name, self.inputs[name]["label"], self.inputs[name]["default"] - ) + self.create_option(name, self.inputs[name]) # Example usage @@ -256,7 +227,7 @@ if __name__ == "__main__": def apply_options(options): print(options) - root = tk.Tk() + root = ctk.CTk() current_options = { "canvas_width": {"type": "number", "label": "Width:", "default": 900, "min": 1, "max": 2540}, "canvas_height": {"type": "number", "label": "Height:", "default": 900, "min": 1, "max": 2540}, diff --git a/ui/settings_tab.py b/ui/settings_tab.py index 72468c3..af198fa 100644 --- a/ui/settings_tab.py +++ b/ui/settings_tab.py @@ -1,60 +1,49 @@ -import tkinter as tk -from tkinter import ttk +import customtkinter as ctk from api.woocommerce_api import save_credentials, load_credentials - class SettingsTab: - def __init__(self, tab_parent, text): - self.tab = ttk.Frame(tab_parent) - tab_parent.add(self.tab, text=text) - + def __init__(self, tab_parent): + self.tab = ctk.CTkFrame(tab_parent) + self.tab.grid(row=0, column=0, sticky="nsew") self.credentials = load_credentials() + self.inputs = {} self.setup_ui() def setup_ui(self): - url_label = tk.Label(self.tab, text="WooCommerce URL:") - url_label.pack(pady=5) + settings_options = { + "url": {"type": "text", "label": "WooCommerce URL:", "default": self.credentials.get('url', '')}, + "consumer_key": {"type": "text", "label": "Consumer Key:", "default": self.credentials.get('consumer_key', '')}, + "consumer_secret": {"type": "text", "label": "Consumer Secret:", "default": self.credentials.get('consumer_secret', '')}, + "username": {"type": "text", "label": "Username:", "default": self.credentials.get('username', '')}, + "password": {"type": "text", "label": "Password:", "default": self.credentials.get('password', ''), "show": "*"} + } - self.url_entry = tk.Entry(self.tab) - self.url_entry.insert(0, self.credentials.get('url', '')) - self.url_entry.pack(pady=5) + row_index = 0 + for name, details in settings_options.items(): + self.create_setting(name, details, row_index) + row_index += 1 - consumer_key_label = tk.Label(self.tab, text="Consumer Key:") - consumer_key_label.pack(pady=5) + save_button = ctk.CTkButton(self.tab, text="Save Credentials", command=self.save_credentials) + save_button.grid(row=row_index, column=0, columnspan=2, pady=10) - self.consumer_key_entry = tk.Entry(self.tab) - self.consumer_key_entry.insert(0, self.credentials.get('consumer_key', '')) - self.consumer_key_entry.pack(pady=5) + def create_setting(self, name, details, row_index): + """ + Create a setting based on its type. + """ + lbl = ctk.CTkLabel(self.tab, text=details["label"]) + lbl.grid(row=row_index, column=0, padx=5, pady=5, sticky="w") - consumer_secret_label = tk.Label(self.tab, text="Consumer Secret:") - consumer_secret_label.pack(pady=5) - - self.consumer_secret_entry = tk.Entry(self.tab, show="*") - self.consumer_secret_entry.insert(0, self.credentials.get('consumer_secret', '')) - self.consumer_secret_entry.pack(pady=5) - - username_label = tk.Label(self.tab, text="Username:") - username_label.pack(pady=5) - - self.username_entry = tk.Entry(self.tab) - self.username_entry.insert(0, self.credentials.get('username', '')) - self.username_entry.pack(pady=5) - - password_label = tk.Label(self.tab, text="Password:") - password_label.pack(pady=5) - - self.password_entry = tk.Entry(self.tab, show="*") - self.password_entry.insert(0, self.credentials.get('password', '')) - self.password_entry.pack(pady=5) - - save_button = tk.Button(self.tab, text="Save Credentials", command=self.save_credentials) - save_button.pack(pady=5) + if details["type"] == "text": + entry = ctk.CTkEntry(self.tab, show=details.get("show", None)) + entry.insert(0, details["default"]) + entry.grid(row=row_index, column=1, padx=5, pady=5, sticky="w") + self.inputs[name] = entry def save_credentials(self): save_credentials( - self.url_entry.get(), - self.consumer_key_entry.get(), - self.consumer_secret_entry.get(), - self.username_entry.get(), - self.password_entry.get() - ) \ No newline at end of file + self.inputs["url"].get(), + self.inputs["consumer_key"].get(), + self.inputs["consumer_secret"].get(), + self.inputs["username"].get(), + self.inputs["password"].get() + ) diff --git a/utils/file_operations.py b/utils/file_operations.py index c40e270..308ea0c 100644 --- a/utils/file_operations.py +++ b/utils/file_operations.py @@ -11,6 +11,7 @@ class FileProcessor: """ def __init__(self): + self.selected_file = "" self.selected_directory = "" def browse_directory(self): @@ -23,6 +24,16 @@ class FileProcessor: self.selected_directory = filedialog.askdirectory() return self.selected_directory + def browse_files(self): + """ + Open a dialog to select a directory. + + Returns: + str: The selected directory path. + """ + self.selected_file = filedialog.askopenfilename() + return self.selected_file + def get_first_image_path(self): """ Get the path of the first image in the selected directory. @@ -30,6 +41,9 @@ class FileProcessor: Returns: str: The path to the first image, or None if no images found. """ + if self.selected_file: + return self.selected_file + if not self.selected_directory: return None @@ -159,6 +173,31 @@ class FileProcessor: os.remove(file_path) self.log_message(f"Processed: {file_path}", log) + def proces_single_image(self, options): + """ + Process images in the selected directory with logging. + + Args: + options (dict): Processing options. + """ + if not self.selected_file: + messagebox.showwarning( + "No File", "Please select a file.") + return + log = options.get("log_message", None) + self.log_message( + f"Processing started for file: {self.selected_file}", log + ) + + output_directory = self.create_output_directory(log) + image_paths = [self.selected_file] + + self.process_images(image_paths, output_directory, options, log) + + messagebox.showinfo("Process Complete", + "Image processing is complete.") + self.log_message("Processing complete.", log) + def generate_output_path(self, output_directory, file_path, options, product = None): """ Generate the output path for resized images based on a template.