From 6b391a37a5630b0417e2f6449065eae358eacc72 Mon Sep 17 00:00:00 2001 From: va1is Date: Thu, 18 Sep 2025 10:19:56 +0300 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=BC=D0=B5=D0=BD=D0=B0=20ip=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20api=20=D0=B4=D0=BB=D1=8F=20=D1=82=D0=BE=D0=B2?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=20zarahome?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Parsing ZARAHOME/src/categories.xlsx | Bin 16055 -> 16085 bytes Parsing ZARAHOME/src/xlsx_recorder.py | 2 +- Processing/9_01_Конвертация_xlsx-to-vcf.py | 170 +++++++++++++++++++++ Парсер_IKEA/main_win proxy.py | 2 +- Парсер_IKEA/~$leaf_categories.xlsx | Bin 165 -> 0 bytes 5 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 Processing/9_01_Конвертация_xlsx-to-vcf.py delete mode 100644 Парсер_IKEA/~$leaf_categories.xlsx diff --git a/Parsing ZARAHOME/src/categories.xlsx b/Parsing ZARAHOME/src/categories.xlsx index 9634944957e9d446278dc87a2007cfbe40686b5b..b88308118c375e18118495fabdb1ed3424b19f30 100644 GIT binary patch delta 8628 zcmY*f1yq|sv&Eg_ZY>VQT?5661~2aJ#We(4S{w?&gBK0%E!N@%3Y1ccySo*)m+(J1 zFX!82cJ7_Kv$LBo=R2Dg&?KmK2m?J=whLPTGKN712F~%3cIGwuM};uZmO42xp{Rlx zKW)Du!7%!y)pzwoH}@TCbUUkh2a zi3b#?56-U7hDmGJqi_kn@P=7&c+_&Te2!M7nh5-8Hn6jteTu?O6!I1KW5!6p&yS4N zUT?NpqHL)qWi5)^_3(}9k5JNe15Hx>xK4?mR|oc=gYaW2r7kqxabE2BVp#Di&lxLU z`7OVurJUc?u$&FjAGP5~$=Hz&>sR}2azcVhQV&jg*XQ@lPyV#l)_?xb+Ywbi^B=H= z{#~hXqOD0sv?6_%zR2|s!m5tV&BC7dRAbY9I<4f~!~Q~|sY9PqwToY4PjO-Y0&w+Z zySe^=?Hfp;zVvM6#$4%X%4Q=b*Sh7KP$$=G2xk{kc2m4>s)yBKmLn0F=w1}BCciog zi+B#ErF7b#a1kz$XyVL7#{z2+GIV~XG6+y#yL2!h;oOrJl!qAS^*9CGg-Ug+_FoZb z{64_ABGCUm&5SP3m}Z+kHU>e-E?#2yC@e-FW9!lV@j%t_-dMH|qF<4lVcSw2V|cT^ z>mr78yBPYXMcQF`rmA{tTH0TzzNdO_k8lhet33UH(e)#N0oQoPN8cWm?m2;Ts~z=( zqRop0i<9-}eglW|x{*6qN7p6w@0)UM%dXYAXjW-|SCc8CGcd~(=Xn%-mnu7&afbul zI@Y6sU41O0K}Q)UP*V1m_G(YG4H{?U*?b{WotR}CsMUMohxfW5f0UM><{0B60vQHy zsB|d!?$vUxh=EIvqpiwPyHYN55s$66K#7r5Qd*|-0KMmY?ujKX2<9XG{+}4%eoGsu zbkf_cOvyI5XlwdDbf96br)+YOt*5JuE|WTQZ^?qPcLukuHFj?zZWm{^%SW!`VuZ5F zZwlJ5(a(8#Zd|-|dffBaJp`~ge(B>A>PvO7O$#htDLoq> z*u;8pdB^vM@TRex+5Mq_0E`MrLM4T4OFe54#$iE0{{#%&G;FZI%S8sG`w^aPecDog zjV0|YG1ju5h@PhR7E@CR^yBwb1}Q&_Uc2tY&kXemAM)bC1+i=UW*JL%38jkdY|)^` zW$Q@yk)eA*vG4)3V$E>^TnZ(tK`~!=- z2k&)F%irG#7N>_-YCbT4k&qrAkq~c{Icf=X14N1~a&M8X9Xf~dWJ&n)!&_ec!XHLe z`v`qFSfuj!m5O})EY2GfWjckF$cW5$&)eM=9C~|xetyeq@eO=`dd=|d@wP|i;kYj3 z?)c)e=3B>s%zgXg-QMMWcMVE%#%iXStQF$p^Cj^?L(@ z^wqYKzj7+?#b!2Cn^6}AZxSH~kTr1!xYPAc%*dZ*E_@L(d2zbt+LP*r+1gOWzy^H^ zQO|DNPz5)m(hX>HRkcr7@6qkJCtt5I8HEUV?JDc_l`p&WwnkZ5 zH}pt+2i@@f7f^uGPKu2&8d^i;>{T&7B8nWPMN$!=WY7|YB6&SM0JJit=%rb9hx0^g z)W6Qo5_(G4Rvk#S&kL@}%ZTKN;@HDV5j(gnc!e}kVX}maXa~qf9|O}cV*H&0oVTj@ zZ-eZ~*q$Rhj8KD~%`wDQr6p2e)thNp8(D}$747ID%cxLMC2Ttk<>w4^Nd zJ1a*bGskNDdk^TylE;lpvNk4KK;$Sxe zwbgM9`Esgu^a}p7n@EZJ7ka8E0xdFC(NUwS_sdpl(b1=>Gdo#=Wc^)L$s)xU3j@mNfZ zWK(dxsy!{|)Qy@(tV62-+%XNGLr1BJTyF^?JO>Ok#hO42fgsN!O0W|Vr2&O06iLFz zbo$SjFafv!jH&;hAYj>0BVt`O4I*Ibd1f1Wsl~tHNwDe@F*ZMC_x_qu&vnKYUajkh zIBvw`B=aP)Ma+y!t5YamK!*_(5zCenP1gX!H(Zh?)>gfWnu5eB_J*m5TeR|Pzy`1( zdRU^bxE<@jRKz!0dEh1jce{_3mqm^aJ5}+ZkChK@Q5A2DvGU&v$Ow|#0fOqv)uXj8 zsbd8aJEna~6v~)BpTez_C+k!5sr5vb1Kda00!qD^FH~`l`P2gULBS4XHt}-HL$Mm3 zxdjPvL&DDgmX+W3P>!SXpud5SFxWoxTimz;SjEzIfe<-6t^XFG?2>3_=(^#K*`D&`A? zuf;-=A^WYxFq6o!T9bMkgZQ?CzT4`Ah^k0Eq`Xb$CHEv$0>IYcsOQD5{6b~O;zIJz zwv7Uz0f(gp@dV*rmK*a*`klVr0_p*WRqnyQHZXC`I)KRotO8uThYW2)ve!4c30T$v zG9D@);U449nqJAJEmD8fUT1h}Bq9w?nb3OyMlbo<0)vN(bANyi7nAopZrMEPLC=||*J@fM3)P54&vcNm$e zdUwP2hBCmN^cJe#A^l6q+27!5z7aN4js3O{+(BGZm(Hno-xPtHH?-ebjKVH8cgx^Q zk{K3zcevbuoW72_C{r$cBUD;kBd+0;FotWIOcn50^mltAdmWQU!wEPYU^ZnF)RfFC z0Z@CZlDk}}#1}h8c8BM?#4t%}e?s*>ui!Aw8O&FI)!sFxbwpLsP7k_RPQL33?pxhG z7LQP?$C^@u3p1N0s|7IFG$}2$>C1e3KAet}r~8Gu;uuiw91R#$abE%H=qoK%=nLQ- zK{y3&xO!LuKdKqDJj-+W!aR2jsBn%4IHqRz=r4W(Ev_X0>^aSmlKNKCW>Zf<(d4NF zKB0=rD_Hb34F#MUMX8+uZiF z2Oge5v-S;Oj^dJoEkVnf)uzA+e72ps?7pD`77zE2U1!~&gqv2Nt_zR zt6fl6@Heaq(#Xg!Y-wv`rM|_6j@pROYMytmc+;l4is!28gL2oBH3oE}v&Vc*>kka$ z!^!fFuBdhc=nS$*Lahw8m`5@NK5Kf{UkAW)x%YgC&dN`IfGN88eWh}%L za{Z<3MfuY=vktL1kA%^8NM1q zonH1Gm@m+~fT)=X(01ErQhX3yxCOJ+NmIwws5(up31?L%<(mgejhQ ziJJIh+nauBU+PWz$FTs@h7&_!*qFa5CdGpM3C!x;zR3I;i>%eWfzTLkajVBEL1r;6iYiBS~>_5hV@+82--W&Ot?hd4Fvm^6--hCtsp}z6Q26jJ-gm? zGV*k<_08!zMJv`Ns)u$O!Q7EYWvqt9v|f{267a2<0BdEsH60NCnox0CVX)-a2j4W1 z)SJdtZ@Q^=ySmwlf*V)FMp{sn-g-NCQhM7$;;nWO_xNq+4vTP9libo@0=Kpe ziat#@g0jzJkLCl@K6jI2eMy4Je&khEaDLqxCQ(PMud{4BSxisSpnx0Y9VBnA!YBr$8#aUt(Z!b z+34_Hgv$FtM3NZ%@?>a8Hpp-**BYT0(2Eeci$sWsgjgY5x$ilnq_qu^W~1xuuo1HR z?A-_wO(-J0em~kWlp#a-+RtLdT>JlsJ#~COe5m5zPKn3%snS4kbG*Odu^*AnoO*=nOF& zRc3yY20Wp*jPMR3i=W7aPgyw9AyB+dM6LQGXr8Ef1^<(UTr47sIO`|WhvaGgKj{%Y zL>Bo3Pg%sRJXN9{9}&FYJ%%WqP+ERoxZpP z2IBKp^hsc31i^s5ZGe|eWXO=(jw@auO=$~Zki?JH3Bg@CHclyZLJ|YN*=?L4uV`uD zZ4q)yOAH~R4~Fp3o5Gti1cdAtMgk1K-z`wd`aj1*}?4*_;zB?;_>uuIFaE&x4LF2^x+H)4g}p^+{`@?ScJ~z zy^{f5-|ZYsO-&tr3%P$dA8rt4)WyX1eJxX?h>wIM14-hb2YY>%Ansg(fg<$|GsBQ+ znv;L_mCv$GgOI3(MM&brlzSm(|8ASm3<>iZN>jf=f9iEQH5uQZ`HGG$fz7ib{b%-! zn|KokTdq!CHK$7aIoR1a`Sy72uO|g?WSV{NsQ1!>UZyDY?%`$(Eal=xf816T8Yo3G zalf~tV&D)+1ipdp+Qx##VGoRWq5GPet$W2{+YKq3zopz(18#kYd~dI`$_s>f6QO1o zSA31`BGYia#6WF1fb1jp>o*sS#$G*6p0}yr zJGPRj1?oDSTG#~ViyfGH|}*x(%c8+(Akrqq@ZY&QB6XbgQJKv7p*|AZACi zfHe_IAfcM=$?KdVuSZsCa4sBD>_|kX$ z!%UHP#}V5=lq4!iMq@#XP`N&1?|_xi;#EYCA2_f(yUK=dmy;&gAY@6}YX3uZg`*N@ zvZd1nxtB*O$=SlD#&hoy=I}#~Er2f@D$1kW0MvD$X@hDzU+?iROj>%xt^1sOz&tx> zeD#%rF?RbAj>;IiVPLjr-Qw>1gqyCLD%+kG%e#wCq627StH!iL-Q#15Vf-Se%JhY` z6&O|^s(i7X42jsIwS-3lfq7bM0e5WUr{*p9|8#^FQRA&upm z+Jl+yrqh@^ilD_>hD+DBD9pd|Le`E1SRHQ0Df``)7aKY>+*T1Ow00^)^d^-x%CQ<^ z?`~9*uvPfllrw?eWx_*-DHNlbudlAvGXmS^KsB~ZynLhS%!|E0rUaWYGisJ~F2Nn# zfKQia_})M9^Dk`lzJ_3CZISa&WS&!rD=`E|T_-;|;Ts z`UK|ArImbt^E3N-0;RmCi00MTT{^HBcU)t&d~4ptyBJb zDTFCPlkRhmIaJ*kH^T=LE@T{1_ob7@o74f_9^egqGSQA{y_W55F`5if4ypuS5BXDg zW_zRO)Q|gP=c!#f45w$@UOm(KrY-yGgzgRBt(_*z;wNoJC8F~0rTM1lhrh!eHBGr$ z$Z4AGm9kS!RxwtROr|R;xC3yT%@UDPiD%=EIC1s7CJ9o^_5?{?jqlQBc>e`zOP^j)|pf84g3C@o*?`CEmR@MW$&{u_Wr3S3*j?+3m+({ zMXHK_%sbj=6pm|FXVrS;)wI)2Nt zk)wga6)*kn&?#ud1<1M6#lgeYP-e?{m*F8g1MX8T-J{918v(!NOuqhEEPGwAk$?zF z2J{zi)zXNK69(Yso9Wse*apyvyuC3jeF8tqQ+3%F% z5?9B&19j?a`~apb7s}Y>Z^C6=KX-J^lhTD+QIa*b8kw4Q`-y@Zv;rnwHxEi|gekMg zpJ&C%tP2hQDqjikxg4qX@TmV+$jHk7a_tzZMC%x3>S-{Nz|$5?TcNPhcs7(6=}U7XX;`?2d9!^FTeXY( z&+Bu;bl(RHubraz9#+EdVw^lSTOan$rFQscflPuz{>uH}A&qe9qB@#wh6yw5!}LA0 zEeTN0*;$i4J~@c@a4?kpQ%yY6q5nRbH#I|>Mp?bZF&h6^CDW)EZ&0tH$Y4)@$NsQ| zp<4eYLAIEGQW~~*>s;}^$iCOm$b-TlF)oHsOOGRf>c}&|0VTHr){aQCguH zhqGEwS3wT&^oKZzTb*Qbuj|K=LfZ5;YR4a#M*G&@X!U4D`|5Jbozrd9he9nlc<9#T zH8HJt?k|2+yGOso_xAFZWSixVWs8zb`}dOBqNtIvQ$G_40e?*8w zKkq9k)MIDqDUGl0#y4WMIlBenof0$k9OBRR#H~^w9}QIjqpDq;Mf-rmBn80)%lL0= zD4p>ZI?GD<^E>3Qm5ltU_{ycL-scbb4L>iSVe$Ro#9%F6dhu$=yeH$0oV%9Lub+v8 zhw7chCt!xW9!fkVQy0$qiFX~s{P_5Z-lZIp>L3imn_`W+_!(|TRimcs?^<-!)BBl~ zfjEm*QkHvR)QRi)#1E{qUNd{sVy$JCqW*8>z8*?ACNT!|FXbGnY6#&1G1X^k_9kXm zRLl<2Fu$4KwRb5GH9(WxA9r5{hgH{1fbIyVfne6LA)eR)v8@`zV{ErDNA+ix&$%O9 z3!Z&;R@Al0|7!yh*{|Yg)AJ$i8N&*s9BF8P-jT0hhG1$ZNV;b(nOQ~RSbSoAK{N>+r?pBOTt@Ob8G&$FnKmzO3Z>y@)nRpnp`>aBX^rE)9%w0U? zFf{N3VIdifVo;sotL{;nbg#F=X-af|%q=mOvv`6Ywo%e_W zID&V6#k$}ov~DB{AJO5lXJ=MGcn4O;6TMvGx(qmKcW*cPzN@D$TziL^*}S+N3WkqcqD*sK$CO8 z>i785+?*DES%QAp_X-;mS{P!|7ck3njE~ISrJ?M|P|VXGGj$x#RZEl5R_BOP2J13E zI?Fz)|H5Q)WdC(&Uoto8GS5h3O(I@#QWeOVn6n#na*Mgi%JTesJSW z2X6kq92#tHjXz=KN^bF&`z61)-VdJ-E)`~zZ>dCZ-@mz> zlCkhu_AeiuUZ=U%y}{`IBgi{bY2$n7;ua-yqJvwB8#WRJBM4cDR~85f{NOTvnIm@j zS-V9^|HDx=o}T;4Ew@F6V>?7>!%+Cr;6vUqa{JUHGU9L&{h0tuhh)Qzh#)d}J|@Ok zg%f!D(dxJ+k;!p@0JNtI`{-Mt!* z7q#N(EW)gLu%FTO8rhMZt+;G~r}-YfZ-xasNqonVBKaxUj^1CwR4A=;{LG2oZ3YEx zKxi zejN}0K4h}F`;?#8Dux^C@5D^VM%2z0+eJJ^TCW}dLbvc9&u!neaFowZu`3qvFZA6d zyWeh6Oz?9CIUO+rBUd!A3v6X4RzM%Ys4>kWW4dH{NQk;M*o!No{`dbPYNd3LX&|W5 z+%!)IyyWnwR#9XmO8D{W|Gj_^HEBiUc}SA9EM6rm5>kLGueVR2s~v;^Kt}Vw54)O3 sNTmN41GnNK_y9KAr!_)GLb`-EqW_1Zi9)mh(#U?01OO9;j1&Ueh=A14olg*?K^Q_|0O@X|I|UR}x;usxkgjir z-~U_RTK`$|X6`+EpMB2T_q{dit~V2b4S`idSeT%5A8H=xC>9OiG{!^PuCz+Suw)ZA z#yFf~T?7z8^^2OTQH7zYjnUs2AJ^A<$(nXL{AG~9Y9$)58v{paQR+DiNDY{`yN`I! zuTc!wR2_WLHPz*1zd;j(7@~Go-qBqCaFMA5f5DbRFWs`HB18VY9%~AP>c}A zLt!V&HQg2KHp~Y^If}&y1xq{mC~ESkQjW<>jrr1wVZ3JK)1EMt)FcDjFv7t=p5A~F z9U)>nof_53SBxA*SXb;@-*$ctdC)Z`4z(22>wqUwTzl{;=!~_jlI=YFOmI}3aUc1s z1URs*P!9o}Wkv7gz;>Tz)2{A^O8RIw(c~dNr^7$0 zVYQ(Xhq$}}^6ccD$CGyE?X8Gj+$hQfTx61)uHb;ov&=P%A?H8vLH2EjqgOA@HTw+* zN$+!1n&(jNzpAFC<-JkvjoRC}JkLY1q4XR|x3}v$fp6p202+tc!#+t;?|(9FXNm0u@7&pHXliw~@1b-yp0e_)9z(vEu! z2xJeB$ij+NW?sa`k6c-%Up8dd2J)e%7qOFV;@^%p ztl-eL`emf6k7?xHA=6resMdjRwkyU4wLR}_j({;(b=flABAWOvOvm3Ft--6lME`K9 zBk2ANSUZV-iE&`({;fVzF(u}Q!@8Z~tgIJ{j&Yuj-Irod35Ga-D~W0CEVhLaddbK5 z*g+yLeo7VlOpMi%ZtK$@WR_>{9z}U5EA~_`O@24M|NV!4Bx`!&xsxV;3AHWu7|y;J zpJmPB0%XL1dUv~lk>;l&bJ8iiLo`!vixi@{#kKCHIj~YX*k`4=RD0BSs#jC!4hZdb zv^?$Dk6V^zek4bbt=XcwdO&xz&Vm9>Kqswb!{tZAJYo5#u2gG*pNR@Q7sq*fhwuB> zf1F4*K5gWL>)JAyiEO?L3Z|?1C&;Xzjze~sB+bt}CXk_E=O(Pt{$>Bk)2O)L>|$H7 zv|NqT*(SAa_xKviyfSc|e{y==telieIo2YF)0+Xpq~fd>QH^LYbJdt`IBH;$_bdFa z#^OMiC=Sn0K*2x0Pp5;xJvs`?{XGiuqbvh7LNib;-yrLPx?0|B2B3kKQK@{WF>bq# zI}e&FTNz{l4Lg?*V27B6Yhw1TfqnJ+E2-yUDiZE4co-(BB#Twl{I zrk)?R-|e3`o1bR|EdqC^b9Zvrc6Es0&Dw6m(*4yyL&ptpd765-bX#hg)p2uE2;3i^ zoes}AUz-Qq=+0hi(sjtg?&t2eZVk-OrSDJ1PH!$&va+OtE^6)@P69Ob%?7=`iqD*` zS!o*7&}?f=2Eq2+nC5~HtZoMe&*IlEedh~_C&3GsQlILGDD<7_IP*1Zx zQV#^R)@?kX^5IG0`}K zhj=>S%}JLja+e(y4u%Yn)=)8Pd6b8c3R_`;fai;8fqYobv2I5ONKZ9|Ec^3B0S6KM z7g=?=etLy`-nG8g@QLJCMl-l>rCPB@5W z6AH5@Nr~`~D2q_CNv|5$F-)7bC`G26Pk3fqY9i(24CE^%9GemJjY!EuyRqa54{3#H z3c98A(PDP9y(-Q068XHtXq^riNH?>vC}M8eZY(Ln<2=&G&u3NuU_zYNICTw3C$q4i z$bX)hZB$2l9IpukuFwHDtJ;tx?UIuIW=REUGW_96U7h;~(yYj1S*>0<4pb98&BK#v zf`lMSJNOoBRI3bmszy!wa;N9W=b3=z3#TzQ#4r^kg3W|vB9+f)<(uE>APN_fm}u6r zsmeDu=w*-m1en=~;2JDfH8TRpPI~!OYwc9!#b_t{K#Kucwwhqdx6-ykph)F`<8f@; z^pd)N2V)cEHe<0}Ym-Rwtxi!qJ2&4}(gL72Ncye~g?t z{4Eboi&e9EAYD6z7hLTJ{M`b^lMyC6K@qN1YCv!o3fPe{^38L)$aX>_2$1fHXAo9f z=pZPCBn(2365<3WB9aVI=XwjMHs5DXZ)wbV)RWLNWj zv|=h`hwyQObf^h3OPmlFAS;#%0!$hHBxu@h)fB7Aiyhu9wZCsAEkZ>tW_G$<qd3$@)p65cIWqCI+o;-wRyuC|d zi6^?UcmGs0LYoy1ik%*3MSC}>4zY%p1SCSsS~rSAf%&aXuE7x#?o-@l{(mX!+gz!M z6E3T1j4WULhV$jQ=Nl_x;Jiv8qQhaw;m<$XHnbTi3QWhSpdAgYsoU-I?J+9u>*;!* z-OU`-(_RQ$WsP~?yTLJy?BYiET7ae`u${(d4@9$pKN8kpQp3(FnM({TVm)QM#+H6R z667)fsaN#7dV!VtgZ!q= zJI}Hl8X4zYlGBq%MNAXjFN(QKM#W4My?tI9(#Wjpz^v#}=Bh`fO%sEC%q_mjFAV^& z_2-MJhSvYsG-`;3HA|)FTqCv4_bUsURiC~GjfxDawF0`H;J^^*Uhi>j?x?0|Vs<0` zH=Qt|X%8^8&@f2y>`RoI8(C`hVo5;zYGO>^vHQ1CBh$ohK1-}Q;K0q*#QDDKOdZNV zKPW-J+LCK?2ECkbGh=`DV`sYjmTs1w-lsp2d~e;(m_mVq;fw-I40DgDWw zofFy)SsFE67Lu#h0YU%x)L%#cg&cITu@HiSvJ2%U%&R4%0f=%or15bRTarOx%_Ogn zbFN5PeB&F6q5(_hz(UliJxTo!zym5qrR1n*@l?pp^q7`I&im9i9^njAN%_#0WW}Y` za`(w3^F5F5jxq{l) za=d`7!$#(%qo4~y?~kM2rnQHLj(1XXN12WySu5kZ8mBXH=Gg}s)kPV+t=$DbrDx*K z*W#`y11oh0y;|wKbrqM;HEL)Kii@S@TtW4g8)X$zQ;1RvB2laQS-TfxJKu|(l(Ke# zM&_xbpa{~~HFuh+fEpKYOUJ0E=@`6QFLvWUo{wWvN3N#ZF=Y>KoWVn;VeV{cK*gG5 zrzeEQe(&p*`oqdiIOL9cm_p$`(yY;Qziq@S20dEolJpd*X)58I32( zL$KhuzGJ6x3 z(Jf1B)Y*E`B`Qt*Z{{j}hui!#&K15DV33DF794R#T5hMmR`_YAAY%F_6N0erf`&LN zv5Fxt-M|9Gm402qPN8+$gm4XU!x{vpK}`p)Y2<+g8mXTuHl&BCgvq}PMd6=UZ;5mG zt^`<`;?C6~zHcL3*%M3AjF*~n1y!seu*q%zkwGQ$((H*H@j67&M!JndL`bE5?e
?}kvE1IBX2J5q(WTL4=M3G0%2W$3B0j-uFom)mzZsMwrGIP zC%+{*+!s;j)BN=758vP4c6bC~JlbNxs}j$^oL=~ewiovf)r+DQrN!Oo{q4m7+TLSp z)Ozk(lq!-e3ob@7i5|A^Xq_4X9~0vBP{fZY7e(|@_j+warVKHW3{E++(2W?(uNhB2 z^5~=P_wpE3XpqYOZsja;FVB@3mAK$4tjkfgtVs*t3KFeC}aS`^}v zQiW1S(sR+pj^L0#L2_I`51hhaBxfEE!68I)J{;B}Qn3PU$bMe}mAmx4*IOQaqzXOowG7cg7Yi6uhT8~bHWC%x2os@lh3pbb*%GPpBaHo#eIFWP zRM3mm>kUV$Ts%RlJR9pqh9t1{2*Y!b_1At7BXvczLy@GB#}){M7^tKcW>U4pS{42S zHWY%y9;dxQU_gu|y&}I(6EsA?nutvh*2Q!`uJWLX_by2N3DXcjS@XczN5GY*rp-!L`lKNX7F?r}>QSPCO z-(nBa0Z6Z6ss$dX(sKXXMJV}07kzJ$D4h8Ll|)XEUC7YYy+O9|dHcbpo=c?nYkL7m zmdFgP-mCxoz#gncw&A{rge@l@u8McYNY~gbn^-NIRs&o;2$0|ZoF6jN(;xg@d55qK z0{!%C5voH&jW|f?whXDPIb-=!6e-nmWAefMf3}|?2fsxhBJR*Gnnma@8d+!voh0-x z?I_|PtsSGoLxon+lhz*7_xLI52c(~a)*|>B2I6}%y7ZTIOh})M+0>j7Wp{VFW zke}+@_4ZkB&QYy6=d5_%COow{{&)Qi!;nX6rjFU0g=OQVb}7(tunC`wS3B7Noi*$4 zpU52x23;`BsnYD6{k!>_1>AG6(*o_bFJ?d3>T+b!E#?PZoE@KcNZL8JFE^A21&L6P z-L4&h4Qzagu1a^TqB}%O?ildzrn6{0r_@}3*|7c0_nq%OIy++6Ia^W7|2Qcj4e^@k zNzE?57yk|{-i;1JE6g*0;H@~^pik|d?rQ#yu5JEancOVl^)nYjcYgef!xM;n+>aBqDL6Kv7;y} z>nik7WPE0<_b?wW`6BfanXK$e@PhpeH69sza)p7SzM@g`;Ml9;80;Jjx}JTI_{Yl-eq? zCoYfeajh@nvTU~eoD2T(B@x4~5azIRfdA+QkJ1_O3!G~6^@H}UL+P1S+Fa-^S6rLO zX-=4oyfMzScUayQTA2he(r8$DDx-A!=2pLE#epZN%~}4My&OVvX13QM&7_~(ph{fd zZur@Ln;=orZ=G>P3_IH8Q}Rw&_NON?1j16yIs!wmLC+D3uB%c;wM&hUdE&)9k9*I2 zk~$U7v=3s_ul7?=lJ-7N{pK(zvHSF0gmS~gDQHSPyEsv>JBlI)z^yogH~WU6CPTg{ zv_qKO%YTZ7$g|I+Z4+Gnu<)58-9AnVtZbX^P|{jw(=V{@*C6BSg@9&0W~|Q0>7JAE za7eC8w6xwA_yWU^4gl%(mtTW&G@R`5;CiYXm z)Jq{-G#x0!i{r@6~k6nWkRL1aQNfBTbz?2>zG%!u-^2i zY(T#kLoIgmc%btxMbhJd1==yZh})-n+}0uMO`g9zYyuV2{wQS*k4|4s1@Pv63Zi74 z(A(yh;8y5?P`v4I#|%S4>O0{Rk z$6()35edqB{e7~mOp@n<2eo9epc|wJWw2z`-NKPxXhSayOPIVKnEPcyD+7O}Wf>dt z{%5S64!Z|d>^FlPC9L<_SsAu*4ep+EiIpK$vZDCfhoxD6lOed-Xg%Q}$7N|BIGol# zJCLnQ>^Yw>0xP%$_IXvFT-%>}v}W?YDK}M0Dj8BN?_?F-|KWSrQ#2V7)hIsUY4y4! zAN$%5%X^T^QDLF=#c36MAwY%iGJp&C}hsTZ&E zLxpn9tb=7Mu7dvr1b%$ab(_Sr7fu_QBCf3FI3KbALZ{4*><`u_5>+GruED}w9UDU^ zhQrGGp5!8EEaCOsm8}_COPm?aBZ^w`1?E1R(L8a5Y~obB@gtQHnpuK%lujU&VZt$b z{wMnC$M*nOy-?BC5#A65$6+;C z(66_tPS%c^^^oJZ{ChJ|>R2eoi(_kSHt|o@a$Buw$z8h>A{xCx?bO<4Z1!KR2jj~1gbDxhV~=kRy!i2FLr&Dcw`bQ?+aK#a z?P(`-uRfQ~PMx#V^TT+@DZ$aqWXiexg^HM7yfQfL2@ah{$^s|tRlN|pBB?x3Jc3d; z3JhoRi;Rc}Ea}nZQ4>_Zfi!nxJMb#Yu-vsiDtNMRv z!V$aa;;FT@uJvgQ-FMoQ>nfS~F$e0m=MkuXB|r(x+Dpk5eq8(ACfw5AmXS|E#v5rw z8QvkV`bus+%HQ4#^2J%c{_B7!n|9jYb6`@DZS@|d`;4YxjoyNkMc0AyBmHNA-D1U3 z^6caHf0o9bmwja$x2bUx>8NyYu!5};gtMEBo@2)8hJlT!#9bWWoYp7Pg{Tsad4Bei zq0fe>3;#9|#nUSNi*0({Bj*_)p!?M-6<2B~Dt2?TTZ(jZ&IRT%z`Y{zsY#_p$sgzu zs*?(TXX9o^h$zwDO~)RPc00GWfe$pY>j=OIxP5 z*pKP4y~hNv5^LOa-aN6}!@8RC&_vtc5bJ8vFyFcfC^iaHSc>+qJ;YsiSc|x(5$}R+ zPCMn+K=3l@H&=XnjSl4EpAPH$PtOBizTJe?TS4wRX|}lk@L6bhwe;?k%kvj z4AbR?S*8{4mfI^iNq>l#4h6N$)3CIVZ?cxG>-oT(0@W+D=YeabCl~D$Z&g z^KB%Q%i?4~2**9NVIeGZLA!RUP5Jj{s-9ATQ!2(PrtagnT2($2R=#6Aj2;5Ef0}zP z2478Bx8tO9zut@Knr~!lPj;I6^%_b;mu17BttazhjMdn*ErHxZvm6v3`Sz{VbeoJn zrLZxs@OJ}}hMwom6~zl8l8&yS0QZ~s!ksN|1^7G&^3wX>7c{-BAiEsmDMsFMOQc_N) z+*-M__RH=_iC|AK2nI>BvaOvtw+D{$xhO71y1z{4w!C#Gu5fQcSL|os(V^~(3|lWb zfB9UPJh8O6BUF8`v?gmS_0tzm{dxHl+PsFn2uzWR!?q9Gm7m{cZ9RdxrX`|L2}?J- zOU0MIin_t}@W*Ui)jcKvfR|pg30*?k^#?8J+&)PW?R8bF0n1<#ukMwm=f=YKRUg9n zgK|K>yY(j)J;y_AZ`}j~&y78|-S>jJWU35R+koFuI z^eC@6frW}P*XZ#m5PP}e;3kfY*X+J$NxLOhQvctoulx0m!)Aoe^#jwv=P0_WE-$k4 z%c!b0m0g+rLRG=saZ{gA0pfqq0&4Wvi!vtv0{caOZ2_4^U+5vMRyA#2?}OmfD_aK>MZQBZmF zHSUd)e8~N^(BQHK2Fv;Po9g@^K$Jik2EW1}O?O1N{-Eku(@AR!bqwj|wE> z7L_q3qj)MXF-E=GKkX)EplyIlvxqO|R+vJPW55?jr zHc#z8eTDTIC9XJEqQBVhK+mYzO6o56Xtbm7&iXl{zqg>q;b%EluOhzvHuQ$FJ;T)0 zv#?**vH9)$5|FguHz(o}7|wEG>5%lb@cpX!?JQy!JD?MM?}t0moFsp+nN!8`8Dbfv zBK)ED1pZXdH;t|j&NHG}F!SC@F7cf=<{d#%v!HZG$rZ-K)7(%|1@!;-cZd-QZB$C= zb4f1hho`&bC@9jxs3=bn``Q0{sYC4~6;KDEm6ESezd-*=(o_Hcd*A=#`awCQSe`ws h3n~iAIpQGtKM*n65`sEONunA;%cNdlJ(oaY{{t%7z*hhO diff --git a/Parsing ZARAHOME/src/xlsx_recorder.py b/Parsing ZARAHOME/src/xlsx_recorder.py index 643a24c..977cd84 100644 --- a/Parsing ZARAHOME/src/xlsx_recorder.py +++ b/Parsing ZARAHOME/src/xlsx_recorder.py @@ -20,7 +20,7 @@ SEND_JSON = ask("SEND_JSON") # отправка POST SAVE_JSON = ask("SAVE_JSON") # сохранять копию JSON # ─────────────────────── прочие настройки ───────────────────────── -POST_URL = "http://localhost:3005/parser/data" +POST_URL = "http://172.25.4.101:3005/parser/data" MIN_PRICE = 40 MAX_PRICE = 1200 EXCLUSION_FILE = Path(__file__).with_name("exclusion_materials.txt") # в том же каталоге diff --git a/Processing/9_01_Конвертация_xlsx-to-vcf.py b/Processing/9_01_Конвертация_xlsx-to-vcf.py new file mode 100644 index 0000000..ab5469c --- /dev/null +++ b/Processing/9_01_Конвертация_xlsx-to-vcf.py @@ -0,0 +1,170 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import re +from pathlib import Path +import pandas as pd + +# ── НАСТРОЙКИ (поменяйте под себя) ──────────────────────────────────────────── +BASE_DIR = Path("/Users/valis/Downloads/") # папка, где лежат файлы +INPUT_XLSX_NAME = "Книга3.xlsx" # имя исходного XLSX +SHEET_NAME = "orders" # имя листа или None (первый лист) +OUTPUT_VCF_NAME = "contacts.vcf" # общее vcf с ВСЕМИ контактами +# ─────────────────────────────────────────────────────────────────────────────── + +# распознаваемые заголовки столбцов +FIRST_NAMES = {"first_name", "firstname", "имя", "name", "givenname", "given_name"} +LAST_NAMES = {"last_name", "lastname", "фамилия", "surname", "familyname", "family_name"} +PHONES = {"phone2", "телефон", "mobile", "mobile_phone", "тел"} +EMAILS = {"email", "e-mail", "почта", "mail"} +ORGS = {"org", "company", "компания", "организация"} +TITLES = {"title", "должность"} +NOTES = {"note", "notes", "заметки", "примечание"} + +PHONE_SPLIT_REGEX = re.compile(r"[;\n\r\t,\/\|]+") # разделители телефонов +ONLY_PLUS_DIGITS = re.compile(r"[^\d+]") +INVALID_FN_CHARS = re.compile(r"[^A-Za-z0-9А-Яа-яЁё _\-\.\(\)]") # для имён файлов + +def safe_filename(s: str, maxlen: int = 80) -> str: + s = INVALID_FN_CHARS.sub("_", s).strip() + s = re.sub(r"\s+", " ", s) + return (s[:maxlen] or "contact").strip() + +def pick_col(df, candidates): + """Найти первую подходящую колонку из набора имён (без регистра/пробелов).""" + norm = {str(c).lower().strip(): c for c in df.columns} + for want in candidates: + if want in norm: + return norm[want] + # мягкий матч: без пробелов + for k, orig in norm.items(): + if k.replace(" ", "") in candidates: + return orig + return None + +def normalize_phone(s: str) -> str: + s = str(s or "").strip() + if not s: + return "" + s = ONLY_PLUS_DIGITS.sub("", s) + if s.startswith("00"): + s = "+" + s[2:] + return s + +def split_phones(cell) -> list[str]: + raw = str(cell or "").strip() + if not raw: + return [] + parts = [p.strip() for p in PHONE_SPLIT_REGEX.split(raw) if p.strip()] + out, seen = [], set() + for p in parts: + n = normalize_phone(p) + if n and n not in seen: + seen.add(n) + out.append(n) + return out + +def build_vcard_row(row, col_first, col_last, col_phone, col_email, col_org, col_title, col_note) -> tuple[str|None, str]: + """Вернёт (vcard_text_or_None, display_name_for_filename).""" + first = str(row.get(col_first, "")).strip() if col_first else "" + last = str(row.get(col_last, "")).strip() if col_last else "" + full = (f"{first} {last}".strip() or first or last).strip() + phones = split_phones(row.get(col_phone, "")) if col_phone else [] + email = str(row.get(col_email, "")).strip() if col_email else "" + org = str(row.get(col_org, "")).strip() if col_org else "" + title = str(row.get(col_title, "")).strip() if col_title else "" + note = str(row.get(col_note, "")).strip().replace("\r", "") if col_note else "" + + if not (full or phones or email or org or title or note): + return None, "" + + lines = ["BEGIN:VCARD", "VERSION:3.0"] + if full: + ln, fn = (last or ""), (first or "") + lines.append(f"N:{ln};{fn};;;") + lines.append(f"FN:{full}") + if org: + lines.append(f"ORG:{org}") + if title: + lines.append(f"TITLE:{title}") + for p in phones: + lines.append(f"TEL;TYPE=CELL:{p}") + if email: + lines.append(f"EMAIL:{email}") + if note: + lines.append(f"NOTE:{note}") + lines.append("END:VCARD") + return "\n".join(lines) + "\n", (full or (phones[0] if phones else "contact")) + +def main(): + xlsx_path = BASE_DIR / INPUT_XLSX_NAME + out_vcf_path = BASE_DIR / OUTPUT_VCF_NAME + + if not xlsx_path.exists(): + print(f"Файл не найден: {xlsx_path}") + return + + try: + df = pd.read_excel(xlsx_path, sheet_name=SHEET_NAME, dtype=str, engine="openpyxl") + except Exception as e: + print(f"Ошибка чтения XLSX: {e}") + return + + df = df.fillna("").copy() + if df.empty: + print("В XLSX нет данных.") + return + + # подрежем полностью пустые колонки + non_empty_cols = [c for c in df.columns if not df[c].astype(str).str.strip().eq("").all()] + df = df[non_empty_cols] + if df.empty: + print("Все колонки пустые.") + return + + # нормализуем заголовки (только для поиска, сами значения не трогаем) + df.columns = [str(c).strip() for c in df.columns] + + col_first = pick_col(df, FIRST_NAMES) + col_last = pick_col(df, LAST_NAMES) + col_phone = pick_col(df, PHONES) + col_email = pick_col(df, EMAILS) + col_org = pick_col(df, ORGS) + col_title = pick_col(df, TITLES) + col_note = pick_col(df, NOTES) + + if not col_phone and not col_email: + print("Не найдены колонки с телефонами/почтой. Ожидались: phone/телефон или email/почта (любая).") + return + + # папка для индивидуальных карточек: // + per_contact_dir = BASE_DIR / xlsx_path.stem + per_contact_dir.mkdir(parents=True, exist_ok=True) + + combined = [] + count = 0 + + for idx, row in df.iterrows(): + vcard, disp = build_vcard_row(row, col_first, col_last, col_phone, col_email, col_org, col_title, col_note) + if not vcard: + continue + combined.append(vcard) + count += 1 + + # имя файла контакта: 0001_Имя Фамилия.vcf + safe_disp = safe_filename(disp) + file_name = f"{count:04d}_{safe_disp}.vcf" + (per_contact_dir / file_name).write_text(vcard, encoding="utf-8") + + if not combined: + print("Нечего экспортировать (все строки пустые).") + return + + out_vcf_path.write_text("".join(combined), encoding="utf-8") + + print("ГОТОВО ✅") + print(f"- Общее VCF: {out_vcf_path}") + print(f"- Индивидуальные карточки: {per_contact_dir} (всего {count})") + +if __name__ == "__main__": + main() diff --git a/Парсер_IKEA/main_win proxy.py b/Парсер_IKEA/main_win proxy.py index 85485d2..c832d86 100644 --- a/Парсер_IKEA/main_win proxy.py +++ b/Парсер_IKEA/main_win proxy.py @@ -689,7 +689,7 @@ def main(): details_json = row.get("productInformationSection.productDetailsProps") or {} - if not (20 <= price <= 1500): + if not (20 <= price <= 2000): pass elif total_kg > 30: pass diff --git a/Парсер_IKEA/~$leaf_categories.xlsx b/Парсер_IKEA/~$leaf_categories.xlsx deleted file mode 100644 index 0f76e2b62fb0d45b3b161726360a55ebac6f0ccc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165 ocmd;Rdi~(Zi#IPmD3Am=7=&1?SqxZASS(m+sD*ylh