diff --git a/__pycache__/main.cpython-310.pyc b/__pycache__/main.cpython-310.pyc index 4dc5246324f31d7a8e96c3fc900612632c52aa9f..f2625dc9426206487a83d5ecbff2d5b808847f68 100644 GIT binary patch literal 717 zcmaJ-J#X7E5GD0t$+Da{Njs)PHWz3H4;_M_sO_qN(ZCLDb%+MTrI}r||40 zOaFs2_7C*OaP89mg)S}0pg^Y*;N81B^1X*+?REgv`LTPzxdp&?UHp3-RlHSKd{Y4f z3@IpK0-?qhwMsj&4YsLMx`}JBLmQ=+cn}bm_Y zOxrVn)$JbrRNg@sN@qBk&Qx{>>4H!V-qTbR3Rp!?2D4~5jbij6x|8RF{vf(R@w7jl z-Sp$pWQ^X8rqM8-Oh=KXIHoL1DM5lzlGTi>7JMmvgvvCp5Q_7MGbL$B7n8+yC7li9 z^|Yb zQlo0g%&Zz*{L6_vP9Ap{`|tq}UQ$}qHjgM8Rg*|$!i^ZO6ZmCS_z literal 1020 zcmYjQOK;Oa5Z-kh$IYV+ebMqdA{9Z?Ry<0n5NYbtl+>wW7YVD9 zi#uaW&ZRp)M6b*x%=0^emkxobjdsTZEclV1xugpeKLAy3#eF~8_ad)P8QA$PuS*TCEAZP2n;TbPlMx$fM9OLRWMh*ukjosMDt^Nk+{Ueq7K zbL&k42lA0$t}t$=zPeQU;$c;w92uCSK-sy_7Ol zc$7Hhx%52ch2h#Vi{p%!t~LeYF_pq9uBsq6Bbmn3kqmz{8R5c?4? z5TA)Pt|g2f`|tULct2N0XuUW(_WNAV{E&{J9Xv0Sa*f3!XbR7 zjt-&L^e8=jbQZJW(ZPA|#AD$BiwCrqrANaxQS~*54lO6=T;B|1G79KR_$N{N7?h66 aScon~GIaqLL8?*XQvu7jS&>aX9Fb{}B? diff --git a/__pycache__/routes.cpython-310.pyc b/__pycache__/routes.cpython-310.pyc index 4ec99cb883f44b385ad79c76b3bf5dd33c577646..0c2d39d25ea0cc90918dc3dfa497f37497d7f10b 100644 GIT binary patch delta 268 zcmaFCIGb5JpO=@50SH_xJ5pE~85kaeILLqn$Z-JT;(&?T3Z@Jx%sH&NY*B2C45`cu z*i+dSGBPrxFr={LaO84Eae_p%*i$)ESX0<~nSe6v!3>%l69Z&SH5qU5Cg9!4%k9ws410I{P&i~s-t delta 90 zcmbQu{DM(CpO=@50SG!Tx1|IC>Bk@rGGGF79Dul3VWPGID|0Y|Cd9C)`=Ho ZI9D&QG*eBaF`f#uSnLG?4OaQC14if+X diff --git a/components/k2test/.idea/.gitignore b/components/k2test/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/components/k2test/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/components/k2test/.idea/gittest.iml b/components/k2test/.idea/gittest.iml new file mode 100644 index 0000000..74d515a --- /dev/null +++ b/components/k2test/.idea/gittest.iml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/components/k2test/.idea/inspectionProfiles/profiles_settings.xml b/components/k2test/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/components/k2test/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/components/k2test/.idea/misc.xml b/components/k2test/.idea/misc.xml new file mode 100644 index 0000000..c72cfa7 --- /dev/null +++ b/components/k2test/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/components/k2test/.idea/modules.xml b/components/k2test/.idea/modules.xml new file mode 100644 index 0000000..49cd08a --- /dev/null +++ b/components/k2test/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/components/k2test/.idea/vcs.xml b/components/k2test/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/components/k2test/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/components/k2test/__init__.py b/components/k2test/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/components/k2test/__init__.py @@ -0,0 +1 @@ + diff --git a/components/k2test/__pycache__/__init__.cpython-310.pyc b/components/k2test/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3828ca304502e47847dbfc8265e04e41fb91dfc GIT binary patch literal 169 zcmd1j<>g`k0@uop6ho7MH}t$7kkc cmc+;F6;$5hu*uC&Da}c>1KCo{1SD7(0CXWLzW@LL literal 0 HcmV?d00001 diff --git a/components/k2test/k2test/__init__.py b/components/k2test/k2test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/components/k2test/k2test/__pycache__/__init__.cpython-310.pyc b/components/k2test/k2test/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be027c37ffed2d64b1fef489644d2f2d0689cbdf GIT binary patch literal 176 zcmd1j<>g`k0@uop6cGIwL?8o3AjbiSi&=m~3PUi1CZpdI zQ(UH7o?nz56Hu9)kyw-)P?VpQnp{#GlWkO#pI-u_lJj#5^7B&jz!D{?#UKeV6(66O emst`YuUAlci^C>2KczG$)edA?F%ytrVE_Qe-7S6q literal 0 HcmV?d00001 diff --git a/components/k2test/k2test/__pycache__/views.cpython-310.pyc b/components/k2test/k2test/__pycache__/views.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..67f4b8a7ee476b581d8a82a59210e85514f04dc1 GIT binary patch literal 1601 zcma)6&2Jk;6rY*hwb$#9xJg=CQ6zI?p$*8%2}KbQ!U2^K2wYY{mf4v!w)exCnQa=& zmVoxar3WsYog=rNk>GDgu5;zYmEJh<-fRp_p%P=w+c&>?Z+>syd*i&>3oyehxvBXWi$V)3xC9Ou))Q^0NJ78Oj0;{{A z*Q0vch#Ge7CC#)IwI~sFUJ*;Y%6(pY;zn)Jo?qj^8Rd1}cuXGAXxSo7Kw5msA}bbY z19FWoTV&NDD}b!>>lV4rZ|sxsmER$15;|r{ii``{(;^)weJzYH1s_NeYg3itxDZN* zt_hO-{vhiWN=Va)3kgoTT-9MGFD@6Y(hU9J2p&>XUl{kt+bz4w#&NTjExGU{p|G_^%E%2br@>p={@OAD}fm?sdjX_i};%ZdATCQf3!)?#3Z zpmby#rurC!CPT{UEiz;?G9^Q2?w*kuoszl7*%_U&DV#@e$p9rF>5NOz`qy_ z6bx=3rn(K{K7{jCFr%7G>5#%?oIGJauww>P6fW=CgN$9rW)s2h7IRxurO8eP{ajx;-SzGagxY7Fd2^*=~#so`5LZ*OD8zZ zc+jR2xcQ+5lQt0_fs~O{dRf2ztr7{x4SS zA!L2#g5V`%u?+gfw-?`?|9bJw#gFH|od10Ow6p#q?aR2=vHhN5pe~bd!KdWjcqzAh z6O7=d|INGce|a}LaE!cz;x35Y@P_dYlfD|2Npo-mZyD7s+Ov%>J%sV)$SMj@Aa~NDtbMMH8-Awe=cF`Y}0PMsoUZQ%)DK`fI9v2D_OP7% literal 0 HcmV?d00001 diff --git a/components/k2test/k2test/languages/en/LC_MESSAGES/messages.mo b/components/k2test/k2test/languages/en/LC_MESSAGES/messages.mo new file mode 100644 index 0000000000000000000000000000000000000000..c64ccfd831f970e0b1a81567febd154b3678ff59 GIT binary patch literal 861 zcmc(dO>fgc5Qbf-_%I+OR5&3ty|t<~IF3|RP7~EloMPmU$Z;ycZR>1ZgR^VxZh%Vs z2TuGu-~_iGIdWjO2`&5rR(|!&j7IOQ$Nu(c{j-JVKI$pzqe=ccUogIf`igpp`i?Ta zKT-EkYipKu2l)VLBcC8QkekSL)-XO}yr`JML>01X zE*p<34N=A4S|L}O);0M0PsnCaT-jI&oii(8@4T4fV=3OSLX&Vt zRwWO{S^6><f5_bTu+5~pP7!;935!=2Y@64(({n&gsl zRZ}gb2cu~eLE^^&?Ef>mkFC61;JbOi_*Fu3M(3si`%!dIS1lpSzCErNlGbD-E1%0 ulD+FbbNf>!Nx%y+t9a?b-btnHBgUD;72z_^JvgK%tOmE$#>f6||G{tR(%zi_ literal 0 HcmV?d00001 diff --git a/components/k2test/k2test/languages/en/LC_MESSAGES/messages.po b/components/k2test/k2test/languages/en/LC_MESSAGES/messages.po new file mode 100644 index 0000000..0e49b1b --- /dev/null +++ b/components/k2test/k2test/languages/en/LC_MESSAGES/messages.po @@ -0,0 +1,32 @@ +msgid "Installed components" +msgstr "Installed components" + +msgid "Name" +msgstr "Name" + +msgid "Description" +msgstr "Description" + +msgid "Version" +msgstr "Version" + +msgid "Dependencies" +msgstr "Dependencies" + +msgid "Git Link" +msgstr "Git Link" + +msgid "Install At" +msgstr "Install At" + +msgid "Status" +msgstr "Status" + +msgid "Action" +msgstr "Action" + +msgid "Components Shop" +msgstr "Components Shop" + +msgid "New 2 page" +msgstr "New 2 page" diff --git a/components/k2test/k2test/languages/uk/LC_MESSAGES/messages.mo b/components/k2test/k2test/languages/uk/LC_MESSAGES/messages.mo new file mode 100644 index 0000000000000000000000000000000000000000..eab9c9a61a6dd8f3f3d22232372054fc3069e4b9 GIT binary patch literal 574 zcmY*W&2H2%5Dth_j$Gj|AW=~jFHV9`^+qf-372GFsHUhSgISt955^hn2kAUare-SYN@)@|d9frrZQhWq zVi3fB7;XELNgB-O<}As`SP8E21v24UFtDlZ5c-r@7T6A>&IWZTMIuSX+oI3(oA)yC zQxYd+;=^9T;&9_tG7Zd#H=1OM%ckVIQVe!qL=jB=H~{y*)FY(Iyv1f1v`2pfk_mp? zpMV=h+hsARR6a6iWvh5eb}MzLKefOL#U zp8e;_^`7+ZrGmN^h11h333BK)>q9dRT$j9% zLs-1#su9|2^=Jj(p6p93LQ7sFZGuS*RwE0X(p>WvvEhh|i_<<n>IwR-d}>-8Ve2jbDKKr0@U$ literal 0 HcmV?d00001 diff --git a/components/k2test/k2test/languages/uk/LC_MESSAGES/messages.po b/components/k2test/k2test/languages/uk/LC_MESSAGES/messages.po new file mode 100644 index 0000000..8c1c9a8 --- /dev/null +++ b/components/k2test/k2test/languages/uk/LC_MESSAGES/messages.po @@ -0,0 +1,2 @@ +msgid "New 2 page" +msgstr "Нова сторінка 2" diff --git a/components/k2test/k2test/static/default.css b/components/k2test/k2test/static/default.css new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/components/k2test/k2test/static/default.css @@ -0,0 +1 @@ + diff --git a/components/k2test/k2test/static/style.css b/components/k2test/k2test/static/style.css new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/components/k2test/k2test/static/style.css @@ -0,0 +1 @@ + diff --git a/components/k2test/k2test/templates/login.html b/components/k2test/k2test/templates/login.html new file mode 100644 index 0000000..a46884d --- /dev/null +++ b/components/k2test/k2test/templates/login.html @@ -0,0 +1 @@ +login diff --git a/components/k2test/k2test/templates/new2.html b/components/k2test/k2test/templates/new2.html new file mode 100644 index 0000000..f3fbd57 --- /dev/null +++ b/components/k2test/k2test/templates/new2.html @@ -0,0 +1,3 @@ + + +

{{ _('New 2 page') }}

\ No newline at end of file diff --git a/components/k2test/k2test/views.py b/components/k2test/k2test/views.py new file mode 100644 index 0000000..988afac --- /dev/null +++ b/components/k2test/k2test/views.py @@ -0,0 +1,34 @@ +from flask import render_template, redirect, request +from flask_login import login_user, current_user, logout_user, login_required +from flask import current_app as k2 +from flask import Blueprint, json +from flask_sqlalchemy import SQLAlchemy + + + +k2test = Blueprint('k2test', __name__, template_folder='templates', static_folder='static',) + + + +@k2test.route('/new') +def new_component(): + db = k2.extensions['sqlalchemy'].db + connection = db.engine.connect() + query = db.text("SELECT email, login FROM k2users") + result = connection.execute(query).fetchall() + rows = [dict(email=row.email, login=row.login) for row in result] + # Перетворення результату на JSON + json_result = json.dumps(rows) + return json_result + +@k2test.route('/new2') +def new_component2(): + return render_template('new2.html') + +@k2test.route('/new3') +def new_component3(): + return 'сторінка 3' + +@k2test.route('/new4') +def new_component4(): + return 'сторінка 4' diff --git a/components/k2test/requirements.txt b/components/k2test/requirements.txt new file mode 100644 index 0000000..b1a7563 --- /dev/null +++ b/components/k2test/requirements.txt @@ -0,0 +1 @@ +Flask-Login==0.6.2 diff --git a/db/__pycache__/database.cpython-310.pyc b/db/__pycache__/database.cpython-310.pyc deleted file mode 100644 index 88aca9e4843bf37f0df08c3229ae992d5e96e394..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1013 zcmYjQOK;Oa5Z;#`agvgv3RDS+bA)I_4;-q3nm!PfN>m6Hsujtyvkq};$6?oLNtAF2 zSKtRAq~^$9+AAmiLJq*J)1dBZKYu&xdF;$=S}r>XM*GPpUZ4p5(wp0Zz-AAY+y~%@ z;}|8_#aMF^lZ3i7=QL(60~w7C*WipBpOI^Zc!peyo7{q(&1n-=?cZPrRk3oKuTSc6 zyBj7W*s(19m^Iq^Y&EoJ8`c3Vxd)JecTQ&H+xiq`xJM=$DW_k^6u*Ob7|a<&Gr>*t z1j)@Sh*HmUSXx$Pjd6hoH6Cn@l2~B@e$A8A=b@-F#nM68S8U|N5sN|UIxmKCd~;3| z?kG_9+G)QNz5j_s5h7YVJJ@NR$xz6aynK9>ii_6isNMBNaw^hZ*v@3@Vq2tXw)*g( z#r@0=d>L*HMyeR~qs#-VLlK$!nk9e|zKfl|j8y(GBFZ3WV}R8#fN0lwR=xts&%J>?;Ghv`hBAjbhK-0c1Owc^<2*~kzV{9fP`5}Jfnp{Mep%~MhT1~Mbq-lY7 zls)jJgjDeb-czib%4~sa@NdxflhD1dyW-^F<wiG6wD!A1P#TM)YKU465afPz3+8t!S(2E_vn+Qcolx+_HP+ulu5 VK8(ZXx^Z&nCFm+!PhuJ+@(=YW`E>vQ diff --git a/db/database.db b/db/database.db index 7e14d2920f1ace3b8e211588200b9e8525d3b2d0..807e7d8fbfb157ca7702d474d29d0fd3d7afb917 100644 GIT binary patch delta 330 zcmaivy-EW?6oq#;jgbwbg@`B^5Ic9BxpQ~+&UV3Siv^2-*k%6Gh$5I)NE&M;FA&5w zplspGVw0_IrCLAUnQ@{@%ruLDqeq0K2Fn^)e)=zlKOUkZ=AONqDe+p zX;7L+R{^U2;3ygQ0qrt&o z)L-0s01#lU4nd=lqVoWelVl5C=sRYOXPVN1Q-~2fAKBh_vA_0EGQ7dvpGe_m&wt<)FRE& z(8R(l&B(|k$->Ao)hx*($=t}oJTb*M%^)Q)CD%~Tz|hFR$XM6FOxMs*!NAhW5Qq%) zOwEl9ObsS~(hKKhU|`tpE6FR$>&Vd45-h_z(UW! z%*f2rU~-+V*yauTAqE^E$MH|%pR}1Lp^cvfXjeiGY@IZvqsFNjwpgp@q;pYS)#D^L9w@<2Ifk~B_*3cH%KXJ*dKocW!vO=~rez;ku- zo%j&A->@_LaOm8ErZXUd2%3-~^(jT3C2Z*U4)BiP2_JHw+wnqD@Cz_sNQ!>ZeoKDI zeqG-^GhX(~&@U$5u;N!J`8N?I;XWh6m3+_ftD>+@n&szkGHFudt^fD&?IhZi!yV}H zOn#F+r$mIDjNe#ZUTNpmEjik1uSY5#XZk^2xj#|qShhcpOB19#`TQ{_Z|uzZfw4DLu_~ZV*5rk*fva#42clYlLvVQ&4H%tKr*sN_UQpZ zGlRCY(`2TgCu6CM8wBwv&Vm4Kqh-?jg_?2@L`kT15d1<8*Y2)8`BF=zpXjX*wo^5D z^2JWH8LHtID(%ZC(@zGgDowM~4{%X$qcz@96*&71R06fB)4VcRZJnHVMq|{}g?1N( z?*PfbWd++~Kh$<+xxhq7U-v*b)_iJcVCY&WQC4pma$vcPF zl5n&!2{)u}cf+nsf=q=YorD>9S|DNt>ZdA}y0tS*3{~dJYo(gpaInhA@SPCk%R21I zAW1`^&Vj~F$2d`<4ec2&!YovCFnB~7z?rvDGI;F)S3pi93{_U8mtWLb{x1ORuh*S{ z^2GQS$_ucWpc&aB%0)<*!2DCvr{DyvV>rUoWU7ezHH7SilOzjHFl$nE5hh-}hqoa? zCXK>Gz75kF7rV@5MJKO;wx_daw8DJ!(!e=%GH^)Hg#83s{mj6)bV~bqnUgW*RdaXcbyKP!rYD1v*;?K)X$-<`6lbHFH>br5s{aFLH^UBo&@sgu{jaoj$+ zsDAz{C}fRj$}b1iJPaDT-7Fhd$)^*kGi@BWo+*lS7{()0(OH;HbP%OND)eBxg<3@J zJTB&9G8{L#g%LN=<8%a(w1fheki6m||I{*6(dO%&gPOlI%`ND>jJuVn!&!1a$IXNx{ryBV-KBlU+~bh08Fvin7m}?wq_+&;Om%ih+aTK=g+u9I#ESa(?!){4`8v3F`~SD^ z++M#QeEGje`FyJdsJAiwbVDs$qH7${UCli>D$XPv(e@iNi|;(@+*=2WTmukH@d#_f zV3ljJ3&-PT!5YLkz^nH_43$9G;m@EOjKgg6Roj$~VaF_P?c&mpsYf|oqz#&Tr*>&x z#o~h(3IgK=!7vq*1o>(ZJe`Ee@k|NO!9N3qCR86H!Mx+wCS$m#432}5rP^@R$MAj% z!C8Xzjyo7f?`TsTE7^;`F*U5SK{p;*)lI#xp%Ca)Wx+s#7$5IsxpA|2DD!kAji+U# zAl<>Fx(tV!Ml?}Mj!u*0QOKh=nToBMLz!)+LSfZYn9tR_NDyFk9f+wN*VafTNf69{ zS3?o36siOS9aQ=y7@p8sd2LRvB|V$_mh2$OE;8Yu7bvexnDqdk}!h!=t}0 zi=2->a57+%6^4P$Q|cyi|3GpN$t@tJV0W>l!EQXGsm)rprnxtdjP@xO9gW4N3Sn4< Lv~>Db=_30BHxi*- literal 0 HcmV?d00001 diff --git a/k2/__pycache__/k2inst.cpython-310.pyc b/k2/__pycache__/k2inst.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d7fa229bbac1c7376604949c3c3c9722904ca5e GIT binary patch literal 11943 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 literal 0 HcmV?d00001 diff --git a/k2/__pycache__/k2obj.cpython-310.pyc b/k2/__pycache__/k2obj.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..427186a3cba840d8040d580efd6ffd84c215804d GIT binary patch literal 369 zcmY+9y-ve05Xa9++FGSu`UI>Q%FwYws1gGbLsbc}Sdpv{8$-9@aValyhAw$+;hMu8in*A)avl(v`cvP8Pf$ z?WJ|K(S9h5Dr@a&TPyiyv}Bo*y88kf7VG6_dA%&|9S#(3KYum0DK>}dskCZi%~n>e xE1HEhrad~0@KYDh2OHK2xCsh{jKo7p-&yC;A0La+8D94EGOlpd&nH-#!7u!dR6+m% literal 0 HcmV?d00001 diff --git a/k2/__pycache__/root.cpython-310.pyc b/k2/__pycache__/root.cpython-310.pyc deleted file mode 100644 index 47af5b3c420f03627d8661ef412f06717feec49f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12018 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 N#3U}F@I83%{{f?%ySxAZ diff --git a/k2/k2cfg.py b/k2/k2cfg.py new file mode 100644 index 0000000..0c6a5bd --- /dev/null +++ b/k2/k2cfg.py @@ -0,0 +1,77 @@ +from flask_sqlalchemy import SQLAlchemy +from sqlalchemy import text +from .k2obj import k2obj +import yaml +import os +import requests +import pytz +import os +import sys +from flask import session + +class k2(k2obj): + + version = '2.5.1.27' + db = SQLAlchemy() + domain = 'http://127.0.0.1:5000/' + update_domain ='http://127.0.0.1:8001/' + venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/Scripts') + json_sort_keys = False + timezone = pytz.timezone('Europe/Kiev') + secret_key = 'JH&INH987gFDHdsagh&8dwbjdw8ckw' + default_language = 'en' + current_language = '' + babel_translation_directories = '' + + def __init__(self): + super().__init__() + + @classmethod + def load_babel_translation_directories(cls): + with open('languages/babel_translation_directories.yml', 'r') as f: + data = yaml.safe_load(f) + cls.babel_translation_directories = data['babel_translation_directories'] + + @classmethod + def get_locale(cls): + if 'lang' in session: + # Отримати обрану мову з сеансу користувача + return session['lang'] + else: + # Повернути мову за замовчуванням з налаштувань додатку + return cls.default_language #app.config['DEFAULT_LANGUAGE'] + + @classmethod + def search_babel_translation_directories(cls): + response = requests.get(f'{cls.domain}api/languages') + if response.status_code == 200: + cls.babel_translation_directories = response.text + data = {'babel_translation_directories': response.text} + else: + cls.babel_translation_directories = 'languages' + data = {'babel_translation_directories': 'languages'} + + with open('languages/babel_translation_directories.yml', 'w') as f: + yaml.dump(data, f) + + # load database settings from yml file + def init_db_uri(self): + with open('db/db.yml', 'r') as f: + db_config = yaml.load(f, Loader=yaml.FullLoader) + return db_config + + # creating a connection string + + + def init_db(self, app): + db_config = self.init_db_uri() + db_uri = f"mysql+{db_config['driver']}://{db_config['user']}:{db_config['password']}@{db_config['host']}/{db_config['dbname']}" + app.config['SQLALCHEMY_DATABASE_URI'] = db_uri + db_path = '../db/database.db' + app.config['SQLALCHEMY_BINDS'] = {'db2': f'sqlite:///{db_path}'} + self.db.init_app(app) + + + + + diff --git a/k2/k2inst.py b/k2/k2inst.py new file mode 100644 index 0000000..da81ec6 --- /dev/null +++ b/k2/k2inst.py @@ -0,0 +1,395 @@ +import zipfile +from flask import Flask, Blueprint, jsonify, render_template, redirect, url_for, session, g +import os +import shutil +from datetime import datetime +import uuid +from flask import request +from k2.k2cfg import k2 +from flask_migrate import Migrate +import requests +import subprocess +from flask import current_app +import yaml +from functools import wraps + +db = k2.db +#migrate = Migrate(app, db) +def generate_id(): + generated_id = uuid.uuid4().hex[:32] + return ''.join([generated_id[i:i + 4] for i in range(0, len(generated_id), 4)]) +class Component(db.Model): + __bind_key__ = 'db2' + __tablename__ = 'component' + __table_args__ = {'extend_existing': True} + id = db.Column(db.String(36), primary_key=True, default=generate_id) + name = db.Column(db.String(100), nullable=False) + description = db.Column(db.String(200)) + version = db.Column(db.String(20)) + git_link = db.Column(db.String(200)) + dependencies = db.Column(db.String) + date_installed = db.Column(db.DateTime, default=datetime.utcnow) + installed = db.Column(db.Boolean, default=False) + + def __init__(self, name, description, version, git_link, dependencies, installed): + self.name = name + self.description = description + self.version = version + self.git_link = git_link + self.dependencies = dependencies + self.installed = installed + def __repr__(self): + return f"Component('{self.name}', '{self.version}')" + @classmethod + def get_repository_by_id(self,rep_id): + component = db.session.query(Component).filter(Component.id == rep_id).first() + return component +components_bp = Blueprint('components', __name__, template_folder='templates') +config = yaml.safe_load(open("db/first-login.yml")) + +def first_login_required(view_func): + @wraps(view_func) + def decorated_view(*args, **kwargs): + if 'username' not in session: + return redirect(url_for('first_login')) + return view_func(*args, **kwargs) + + return decorated_view + + +@components_bp.route('/api/languages', methods=['GET']) +def find_language(): + components = Component.query.all() + languages_paths = [] + # Додаємо головну директорію languages + languages_paths.append('languages') + # Знаходимо шляхи до директорій languages всередині папки components + for component in components: + component_languages_directory = 'components/' + component.name + '/' + component.name + '/languages' + languages_paths.append(component_languages_directory) + result = ';'.join(languages_paths) + print(result) + return result + +@components_bp.route('/', methods=['GET', 'POST']) +@first_login_required +def home(): + return redirect('/dashboard') + +@components_bp.route('/login', methods=['GET', 'POST']) +def first_login(): + if request.method == "POST": + username = request.form.get("username") + password = request.form.get("password") + for user in config["users"]: + if user["username"] == username and user["password"] == password: + session['username'] = username # Збереження ім'я користувача в сесії + return redirect(url_for('components.dashboard')) + return "Невірне ім'я користувача або пароль." + return render_template('first-login.html') + +@components_bp.route('/logout') +def logout(): + session.pop('username', None) # Видалення ім'я користувача з сесії + return redirect(url_for('first_login')) + +@components_bp.route('/change_language/') +def change_language(lang): + session['lang'] = lang + k2.current_language = lang + return redirect(url_for('components.dashboard')) + +@components_bp.route('/dashboard') +@first_login_required +def dashboard(): + + # Компоненти доступні для встановлення + try: + # GET-запит до API + response = requests.get('http://127.0.0.1:8001/api/components') + json_data = response.json() + # Перетворення JSON-об'єкту на масив + component_server = [item for item in json_data] + except: + component_server = None + + # Встановлені компоненти + components = Component.query.all() + components_names = [component.name for component in components] + # Отримання значення пошукового запиту з параметрів URL + search_query = request.args.get('search_query') + #print(search_query) + filtered_components = [] + if search_query: + filtered_components = [component for component in component_server if + (search_query.lower() in component['name'].lower() if component['name'] else False) or + (search_query.lower() in component['description'].lower() if component[ + 'description'] else False)] + else: + filtered_components = component_server + current_language = k2.current_language + + return render_template('dashboard.html', components=components, + components_names=components_names, component_server=filtered_components, + search_query=search_query, language=current_language ) + +@components_bp.route('/show_components/') +@first_login_required +def show_components(component_id): + response = requests.get('http://127.0.0.1:8001/api/components') + json_data = response.json() + selected_component = next((component for component in json_data if component['id'] == component_id), None) + return render_template('component-info.html', selected_component=selected_component) + +@components_bp.route('/install_components_git/') +@first_login_required +def install_components_git(component_id): + # Шлях до головної папки проекту + project_folder = 'components' + #component = Component.get_repository_by_id(component_id) + response = requests.get('http://127.0.0.1:8001/api/components') + json_data = response.json() + selected_component = next((component for component in json_data if component['id'] == component_id), None) + # Назва репозиторія + repository_name = selected_component['name'] + # Шлях до папки репозиторія в межах проекту + repository_folder = os.path.join(project_folder, repository_name) + # URL репозиторія + + git_repo_url = selected_component['git_link'] + try: + # Перевірка наявності папки репозиторія + if not os.path.exists(repository_folder): + # Створення папки репозиторія + os.makedirs(repository_folder) + # Шлях до файлу __init__.py + init_file = os.path.join(repository_folder, '__init__.py') + # Перевірка наявності файлу __init__.py + if not os.path.exists(init_file): + # Створення пустого файлу __init__.py + open(init_file, 'a').close() + #підключення до приватного репозиторію + #os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW' + #git_repo_url_with_token = git_repo_url.replace('https://', + # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@') + + # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія + command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url, '--target=' + repository_folder] + # Виконуємо команду встановлення + subprocess.check_call(command) + + # Шлях до файлу, до якого потрібно додати код + file_path = 'routes.py' + # Код, який потрібно додати + code = selected_component['dependencies'] + # Відкриття файлу у режимі дозапису + with open(file_path, 'a') as file: + # Запис нового коду у файл + file.write('\n') + file.write(code) + file.write('\n') + component = Component.query.filter_by(name=selected_component['name']).first() + if not component: + new_component = Component( + name=selected_component['name'], + description=selected_component['description'], + version=selected_component['version'], + git_link=selected_component['git_link'], + dependencies=selected_component['dependencies'], + installed=True + ) + # Add the new component to the database + db.session.add(new_component) + db.session.commit() + + # Повертаємо повідомлення про успішне встановлення + return f'Installed successfully ' + except subprocess.CalledProcessError as e: + return 'Error installing : ' + str(e) + +@components_bp.route('/install_components/') +@first_login_required +def install_component_from_archive(component_id): + # Шлях до головної папки проекту + project_folder = 'components' + # Отримати відповідну компоненту зі списку компонент + response = requests.get('http://127.0.0.1:8001/api/components') + json_data = response.json() + selected_component = next((component for component in json_data if component['id'] == component_id), None) + if selected_component is None: + return 'Component not found' + # Отримати посилання на архів компоненти та версію + archive_url = selected_component['latest_component_data'] + version = selected_component['latest_version'] + try: + # Створити шлях до папки компоненти згідно назви та версії + component_folder = os.path.join(project_folder) + os.makedirs(component_folder, exist_ok=True) + # Завантажити архів компоненти + response = requests.get(archive_url, stream=True) + response.raise_for_status() + # Шлях до завантаженого архіву + archive_path = os.path.join(component_folder, f"{selected_component['name']}.zip") + # Встановити залежності з файлу requirements.txt + + # Зберегти архів на диск + with open(archive_path, "wb") as file: + for chunk in response.iter_content(chunk_size=8192): + file.write(chunk) + # Розпакувати архів + with zipfile.ZipFile(archive_path, "r") as zip_ref: + zip_ref.extractall(component_folder) + + # Видалити архів + os.remove(archive_path) + + # Шлях до файлу, до якого потрібно додати код + file_path = 'routes.py' + # Код, який потрібно додати + code = f'''from components.{selected_component['name']}.{selected_component['name']}.views import {selected_component['name']}\napp.register_blueprint({selected_component['name']}, url_prefix='/{selected_component['name']}')''' + #selected_component['dependencies'] + + # Відкриття файлу у режимі дозапису + with open(file_path, 'a') as file: + # Запис нового коду у файл + file.write('\n') + file.write(code) + file.write('\n') + + # Оновити базу даних з встановленою компонентою + component = Component.query.filter_by(name=selected_component['name']).first() + if not component: + component = Component( + name=selected_component['name'], + description=selected_component['description'], + version=version, + git_link=selected_component['git_link'], + dependencies=code, + installed=True + ) + db.session.add(component) + else: + component.version = version + component.git_link = selected_component['git_link'] + component.dependencies = code + component.installed = True + + db.session.commit() + + + k2.search_babel_translation_directories() + + return f'''Component installed successfully: {selected_component["name"]} v{version} {k2.babel_translation_directories}, + \n \n please wait installing requirments... + ''' + + except Exception as e: + return f'Error installing component: {str(e)}' + +@components_bp.route('/install-requirments/', methods=['GET']) +@first_login_required +def install_requirments(selected_component_name): + requirements_file = os.path.join('components', selected_component_name, "requirements.txt") + if os.path.isfile(requirements_file): + pip_command = f"{k2.venv_bin_path}/python -m pip install -r {requirements_file}" + subprocess.run(pip_command, shell=True, check=True) + return f'''Requirements installed successfully + \n \n please wait installing requirments components... + ''' + + +@components_bp.route('/install-requirments-components') +@first_login_required +def install_requirements_components(): + # Откриття файлу requirements_components.txt + requirements_file = 'requirements_components.txt' + component_ids = None + if os.path.isfile(requirements_file): + with open('requirements_components.txt', 'r') as file: + component_ids = file.read().splitlines() + if component_ids: + for component_id in component_ids: + # Виклик роуту '/install_components/' для кожної назви компоненти + response = requests.get( + f'/install_components/{component_id}') + return f'Requirements components installed successfully ' + else: + return f'' + # Опрацювання відповіді (за потреби) + + +@components_bp.route('/remove_dependencies/', methods=['GET']) +@first_login_required +def remove_dependencies(component_id): + # Знаходимо компоненту за її ID + component = Component.query.get(component_id) + if not component: + return 'Component not found ' + + # Шлях до файлу, з якого потрібно видалити залежності + file_path = 'routes.py' + + # Зчитуємо вміст файлу + with open(file_path, 'r') as file: + lines = file.readlines() + + # Видаляємо рядки, що містять залежності компоненти + updated_lines = [line for line in lines if line.strip() not in component.dependencies] + + # Записуємо оновлений вміст у файл + with open(file_path, 'w') as file: + file.writelines(updated_lines) + + # Оновлюємо статус компоненти + component.installed = False + db.session.commit() + + return 'Component successfully turn off ' + +@components_bp.route('/add_dependencies/', methods=['GET']) +@first_login_required +def add_dependencies(component_id): + + # Знаходимо компоненту за її ID + component = Component.query.get(component_id) + if not component: + return 'Component not found ' + + # Шлях до файлу, з якого потрібно видалити залежності + file_path = 'routes.py' + code = component.dependencies + # Відкриття файлу у режимі дозапису + with open(file_path, 'a') as file: + # Запис нового коду у файл + file.write(code) + + # Оновлюємо статус компоненти + component.installed = True + db.session.commit() + return 'Dependencies added successfully ' + +@components_bp.route('/remove-component/') +@first_login_required +def remove_component(component_id): + # Шлях до головної папки проекту + project_folder = 'components' + component = Component.query.get(component_id) + # Назва репозиторія + repository_name = component.name + # Шлях до папки репозиторія в межах проекту + repository_folder = os.path.join(project_folder, repository_name) + try: + # Перевірка наявності папки репозиторія + if os.path.exists(repository_folder): + # Видалення папки репозиторія + shutil.rmtree(repository_folder) + # Видаляємо компоненту з бази + if component: + db.session.delete(component) + db.session.commit() + + # Повертаємо повідомлення про успішне видалення + return 'Component removed successfully ' + except Exception as e: + # Повертаємо повідомлення про помилку видалення + return 'Error removing component: ' + str(e) diff --git a/k2/k2obj.py b/k2/k2obj.py new file mode 100644 index 0000000..da79942 --- /dev/null +++ b/k2/k2obj.py @@ -0,0 +1,8 @@ +class k2obj: + name = '' + version = '' + domain = '' + timezone = '' + menu = '' + + diff --git a/k2/root.py b/k2/root.py deleted file mode 100644 index 52ff7a5..0000000 --- a/k2/root.py +++ /dev/null @@ -1,401 +0,0 @@ -import zipfile -from flask import Flask, Blueprint, jsonify, render_template, redirect, url_for, session, g -import os -import shutil -from datetime import datetime -import uuid -from flask import request -from db.database import db -from flask_migrate import Migrate -from main import app -import requests -import subprocess -from flask import current_app -import yaml -from functools import wraps -from languages.views import get_locale - - -with app.app_context(): - - #migrate = Migrate(app, db) - def generate_id(): - generated_id = uuid.uuid4().hex[:32] - return ''.join([generated_id[i:i + 4] for i in range(0, len(generated_id), 4)]) - class Component(db.Model): - __bind_key__ = 'db2' - __tablename__ = 'component' - __table_args__ = {'extend_existing': True} - id = db.Column(db.String(36), primary_key=True, default=generate_id) - name = db.Column(db.String(100), nullable=False) - description = db.Column(db.String(200)) - version = db.Column(db.String(20)) - git_link = db.Column(db.String(200)) - dependencies = db.Column(db.String) - date_installed = db.Column(db.DateTime, default=datetime.utcnow) - installed = db.Column(db.Boolean, default=False) - - def __init__(self, name, description, version, git_link, dependencies, installed): - self.name = name - self.description = description - self.version = version - self.git_link = git_link - self.dependencies = dependencies - self.installed = installed - def __repr__(self): - return f"Component('{self.name}', '{self.version}')" - @classmethod - def get_repository_by_id(self,rep_id): - component = db.session.query(Component).filter(Component.id == rep_id).first() - return component - components_bp = Blueprint('components', __name__, template_folder='templates') - config = yaml.safe_load(open("db/first-login.yml")) - - - def first_login_required(view_func): - @wraps(view_func) - def decorated_view(*args, **kwargs): - if 'username' not in session: - return redirect(url_for('first_login')) - return view_func(*args, **kwargs) - - return decorated_view - - - def find_language(): - components = Component.query.all() - languages_paths = [] - # Додаємо головну директорію languages - languages_paths.append('languages') - # Знаходимо шляхи до директорій languages всередині папки components - for component in components: - component_languages_directory = 'components/' + component.name + '/languages' - languages_paths.append(component_languages_directory) - result = ';'.join(languages_paths) - return result - - @app.route('/', methods=['GET', 'POST']) - @first_login_required - def home(): - return redirect('/dashboard') - - - @app.route('/login', methods=['GET', 'POST']) - def first_login(): - if request.method == "POST": - username = request.form.get("username") - password = request.form.get("password") - for user in config["users"]: - if user["username"] == username and user["password"] == password: - session['username'] = username # Збереження ім'я користувача в сесії - return redirect(url_for('components.dashboard')) - return "Невірне ім'я користувача або пароль." - return render_template('first-login.html') - - - @app.route('/logout') - def logout(): - session.pop('username', None) # Видалення ім'я користувача з сесії - return redirect(url_for('login')) - - - @components_bp.route('/change_language/') - def change_language(lang): - session['lang'] = lang - app.config['CURRENT_LANGUAGE'] = lang - return redirect(url_for('components.dashboard')) - - @components_bp.route('/dashboard') - @first_login_required - def dashboard(): - - # Компоненти доступні для встановлення - try: - # GET-запит до API - response = requests.get('http://127.0.0.1:8001/api/components') - json_data = response.json() - # Перетворення JSON-об'єкту на масив - component_server = [item for item in json_data] - except: - component_server = None - - # Встановлені компоненти - components = Component.query.all() - components_names = [component.name for component in components] - # Отримання значення пошукового запиту з параметрів URL - search_query = request.args.get('search_query') - #print(search_query) - filtered_components = [] - if search_query: - filtered_components = [component for component in component_server if - (search_query.lower() in component['name'].lower() if component['name'] else False) or - (search_query.lower() in component['description'].lower() if component[ - 'description'] else False)] - else: - filtered_components = component_server - current_language = app.config['CURRENT_LANGUAGE'] #get_locale() - - return render_template('dashboard.html', components=components, - components_names=components_names, component_server=filtered_components, - search_query=search_query, language=current_language) - - @components_bp.route('/show_components/') - @first_login_required - def show_components(component_id): - response = requests.get('http://127.0.0.1:8001/api/components') - json_data = response.json() - selected_component = next((component for component in json_data if component['id'] == component_id), None) - return render_template('component-info.html', selected_component=selected_component) - - @components_bp.route('/install_components_git/') - @first_login_required - def install_components_git(component_id): - # Шлях до головної папки проекту - project_folder = 'components' - #component = Component.get_repository_by_id(component_id) - response = requests.get('http://127.0.0.1:8001/api/components') - json_data = response.json() - selected_component = next((component for component in json_data if component['id'] == component_id), None) - # Назва репозиторія - repository_name = selected_component['name'] - # Шлях до папки репозиторія в межах проекту - repository_folder = os.path.join(project_folder, repository_name) - # URL репозиторія - - git_repo_url = selected_component['git_link'] - try: - # Перевірка наявності папки репозиторія - if not os.path.exists(repository_folder): - # Створення папки репозиторія - os.makedirs(repository_folder) - # Шлях до файлу __init__.py - init_file = os.path.join(repository_folder, '__init__.py') - # Перевірка наявності файлу __init__.py - if not os.path.exists(init_file): - # Створення пустого файлу __init__.py - open(init_file, 'a').close() - #підключення до приватного репозиторію - #os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW' - #git_repo_url_with_token = git_repo_url.replace('https://', - # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@') - - # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія - command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url, '--target=' + repository_folder] - # Виконуємо команду встановлення - subprocess.check_call(command) - - # Шлях до файлу, до якого потрібно додати код - file_path = 'routes.py' - # Код, який потрібно додати - code = selected_component['dependencies'] - # Відкриття файлу у режимі дозапису - with open(file_path, 'a') as file: - # Запис нового коду у файл - file.write('\n') - file.write(code) - file.write('\n') - component = Component.query.filter_by(name=selected_component['name']).first() - if not component: - new_component = Component( - name=selected_component['name'], - description=selected_component['description'], - version=selected_component['version'], - git_link=selected_component['git_link'], - dependencies=selected_component['dependencies'], - installed=True - ) - # Add the new component to the database - db.session.add(new_component) - db.session.commit() - - # Повертаємо повідомлення про успішне встановлення - return f'Installed successfully ' - except subprocess.CalledProcessError as e: - return 'Error installing : ' + str(e) - - @components_bp.route('/install_components/') - @first_login_required - def install_component_from_archive(component_id): - # Шлях до головної папки проекту - project_folder = 'components' - # Отримати відповідну компоненту зі списку компонент - response = requests.get('http://127.0.0.1:8001/api/components') - json_data = response.json() - selected_component = next((component for component in json_data if component['id'] == component_id), None) - if selected_component is None: - return 'Component not found' - # Отримати посилання на архів компоненти та версію - archive_url = selected_component['latest_component_data'] - version = selected_component['latest_version'] - try: - # Створити шлях до папки компоненти згідно назви та версії - component_folder = os.path.join(project_folder) - os.makedirs(component_folder, exist_ok=True) - # Завантажити архів компоненти - response = requests.get(archive_url, stream=True) - response.raise_for_status() - # Шлях до завантаженого архіву - archive_path = os.path.join(component_folder, f"{selected_component['name']}.zip") - # Встановити залежності з файлу requirements.txt - - # Зберегти архів на диск - with open(archive_path, "wb") as file: - for chunk in response.iter_content(chunk_size=8192): - file.write(chunk) - # Розпакувати архів - with zipfile.ZipFile(archive_path, "r") as zip_ref: - zip_ref.extractall(component_folder) - - # Видалити архів - os.remove(archive_path) - - # Шлях до файлу, до якого потрібно додати код - file_path = 'routes.py' - # Код, який потрібно додати - code = f'''from components.{selected_component['name']}.{selected_component['name']}.views import {selected_component['name']}\napp.register_blueprint({selected_component['name']}, url_prefix='/{selected_component['name']}')''' - #selected_component['dependencies'] - - # Відкриття файлу у режимі дозапису - with open(file_path, 'a') as file: - # Запис нового коду у файл - file.write('\n') - file.write(code) - file.write('\n') - - # Оновити базу даних з встановленою компонентою - component = Component.query.filter_by(name=selected_component['name']).first() - if not component: - component = Component( - name=selected_component['name'], - description=selected_component['description'], - version=version, - git_link=selected_component['git_link'], - dependencies=code, - installed=True - ) - db.session.add(component) - else: - component.version = version - component.git_link = selected_component['git_link'] - component.dependencies = code - component.installed = True - - db.session.commit() - - return f'''Component installed successfully: {selected_component["name"]} v{version}, - \n \n please wait installing requirments... - ''' - - except Exception as e: - return f'Error installing component: {str(e)}' - - @components_bp.route('/install-requirments/', methods=['GET']) - @first_login_required - def install_requirments(selected_component_name): - requirements_file = os.path.join('components', selected_component_name, "requirements.txt") - if os.path.isfile(requirements_file): - pip_command = f"{current_app.config['VENV_BIN_PATH']}/python -m pip install -r {requirements_file}" - subprocess.run(pip_command, shell=True, check=True) - return f'''Requirements installed successfully - \n \n please wait installing requirments components... - ''' - - - @components_bp.route('/install-requirments-components') - @first_login_required - def install_requirements_components(): - # Откриття файлу requirements_components.txt - requirements_file = 'requirements_components.txt' - component_ids = None - if os.path.isfile(requirements_file): - with open('requirements_components.txt', 'r') as file: - component_ids = file.read().splitlines() - if component_ids: - for component_id in component_ids: - # Виклик роуту '/install_components/' для кожної назви компоненти - response = requests.get( - f'/install_components/{component_id}') - return f'Requirements components installed successfully ' - else: - return f'' - # Опрацювання відповіді (за потреби) - - - - - @components_bp.route('/remove_dependencies/', methods=['GET']) - @first_login_required - def remove_dependencies(component_id): - # Знаходимо компоненту за її ID - component = Component.query.get(component_id) - if not component: - return 'Component not found ' - - # Шлях до файлу, з якого потрібно видалити залежності - file_path = 'routes.py' - - # Зчитуємо вміст файлу - with open(file_path, 'r') as file: - lines = file.readlines() - - # Видаляємо рядки, що містять залежності компоненти - updated_lines = [line for line in lines if line.strip() not in component.dependencies] - - # Записуємо оновлений вміст у файл - with open(file_path, 'w') as file: - file.writelines(updated_lines) - - # Оновлюємо статус компоненти - component.installed = False - db.session.commit() - - return 'Component successfully turn off ' - - @components_bp.route('/add_dependencies/', methods=['GET']) - @first_login_required - def add_dependencies(component_id): - - # Знаходимо компоненту за її ID - component = Component.query.get(component_id) - if not component: - return 'Component not found ' - - # Шлях до файлу, з якого потрібно видалити залежності - file_path = 'routes.py' - code = component.dependencies - # Відкриття файлу у режимі дозапису - with open(file_path, 'a') as file: - # Запис нового коду у файл - file.write(code) - - # Оновлюємо статус компоненти - component.installed = True - db.session.commit() - return 'Dependencies added successfully ' - - @components_bp.route('/remove-component/') - @first_login_required - def remove_component(component_id): - # Шлях до головної папки проекту - project_folder = 'components' - component = Component.query.get(component_id) - # Назва репозиторія - repository_name = component.name - # Шлях до папки репозиторія в межах проекту - repository_folder = os.path.join(project_folder, repository_name) - try: - # Перевірка наявності папки репозиторія - if os.path.exists(repository_folder): - # Видалення папки репозиторія - shutil.rmtree(repository_folder) - # Видаляємо компоненту з бази - if component: - db.session.delete(component) - db.session.commit() - - # Повертаємо повідомлення про успішне видалення - return 'Component removed successfully ' - except Exception as e: - # Повертаємо повідомлення про помилку видалення - return 'Error removing component: ' + str(e) - app.register_blueprint(components_bp) \ No newline at end of file diff --git a/languages/__pycache__/find_language.cpython-310.pyc b/languages/__pycache__/find_language.cpython-310.pyc deleted file mode 100644 index 3789632d1319423648962801ed3f2e2c7e60d27e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 546 zcmY*WO;5r=5S`t&2$c_SdhrMJAS5JS)EE;y$c2~~FQkSv?8;Z$t-D17X>Z2g0Z0GR zUOo92I5|r~!AWLz`rh=tc2?ACE?^{=U#v?3e$2yRAO?4s>I@45MnZ^4pAcY_S)b6S z%zgsT`9&5yqAMK{B_if=IyA^G9BgdN4yJm*lERd%=o)euK~6HVvKU#TY6kc4QqL)) z8J*gvz^qfqEyHJ);os`aUO5@g=61Gq?&(Sx#G`pI;%a$3+}W$v(rp#QhFp6kY5qk! zZ*wje+6ux@mx3hWG1GP&L|ofbF^N4#yL*v-qmURRK{{5tQjq=gq8;p~*hKPSD$t=M zxtfRRH^>_LZn~W-|5_<|Tnxv7j2@+!;w#FZwWSd0?kFVv*GbF@hi0&W5-m8HjHYcFN+#GR0$F^HlJ+mChXx68 zEi0`pbmedkUcl#b7hdoSsmA_`%>rzQfgFL@=b&n+BgmS3j;~RTzmO~R6<^~wfQ7!fWXD2-&+!jFI1OK{oLu7`(ruc$HuBT-t|Q>tIzXhfP8q)pJ=ny5bOMTRxE^ zrMYn7+!R#}VCke#(zUmLenX}Q(0=!io@7HSjm_-h!BU%9cD5S7!xsv`B*$5QFjC2BX8_Wc|{hRE_N(FOklXQ%~MHfyKx3ilzfe+A<7gf{I_*t9L onj(%BRZ)-NS?qN8ESm-bds=F7spK;Zp@t!bVjKeq7T#+816K;DqW}N^ diff --git a/languages/babel_translation_directories.yml b/languages/babel_translation_directories.yml new file mode 100644 index 0000000..d52449d --- /dev/null +++ b/languages/babel_translation_directories.yml @@ -0,0 +1 @@ +babel_translation_directories: languages;components/k2test/k2test/languages diff --git a/languages/find_language.py b/languages/find_language.py deleted file mode 100644 index f05abd2..0000000 --- a/languages/find_language.py +++ /dev/null @@ -1,2 +0,0 @@ -from k2.root import Component - diff --git a/languages/views.py b/languages/views.py deleted file mode 100644 index d1ca3c8..0000000 --- a/languages/views.py +++ /dev/null @@ -1,17 +0,0 @@ -import yaml -from flask import session, g -from main import app, babel - -def load_languages(): - with open('languages/languages.yml', 'r') as file: - languages = yaml.safe_load(file) - return print(languages) - -def get_locale(): - if 'lang' in session: - # Отримати обрану мову з сеансу користувача - return session['lang'] - else: - # Повернути мову за замовчуванням з налаштувань додатку - return app.config['DEFAULT_LANGUAGE'] -babel.init_app(app, locale_selector=get_locale) diff --git a/main.py b/main.py index ead358d..86dc048 100644 --- a/main.py +++ b/main.py @@ -1,34 +1,29 @@ -import pytz -from flask import Flask from flask_cors import CORS -from db.database import init_db -import os -import sys -from k2.root import * -from flask_login import LoginManager from flask_babel import Babel - +#from k2.k2inst import * +from flask import Flask +from k2.k2cfg import k2 # configure flask app app = Flask(__name__) -venv_path = os.path.join(os.path.dirname(sys.prefix), 'venv/Scripts') -app.config['VENV_BIN_PATH'] = venv_path -app.config['JSON_SORT_KEYS'] = False -app.config['TIMEZONE'] = pytz.timezone('Europe/Kiev') -app.config['SECRET_KEY'] = 'JH&INH987gFDHdsagh&8dwbjdw8ckw' -app.config['DOMAIN'] = 'http://127.0.0.1:5001/' -app.config['DEFAULT_LANGUAGE'] = 'en' -app.config['CURRENT_LANGUAGE'] = '' -app.config['BABEL_TRANSLATION_DIRECTORIES'] = 'languages;components/k2test/k2test/languages' - -# setting flask app -init_db(app) +app.config['SECRET_KEY'] = k2.secret_key +app.config.from_object(k2) + +# init db +k2().init_db(app) CORS(app) + +#translate +k2.load_babel_translation_directories() +app.config['BABEL_TRANSLATION_DIRECTORIES'] = k2.babel_translation_directories babel = Babel(app) +babel.init_app(app, locale_selector=k2.get_locale) # flask routing from routes import * + if __name__ == '__main__': app.run(debug=True, port=5000) + diff --git a/routes.py b/routes.py index a2bc41d..2529214 100644 --- a/routes.py +++ b/routes.py @@ -1,4 +1,8 @@ from flask import Flask #app = Flask(__name__) from main import app, babel +from k2.k2inst import components_bp +app.register_blueprint(components_bp) +from components.k2test.k2test.views import k2test +app.register_blueprint(k2test, url_prefix='/k2test') diff --git a/templates/dashboard.html b/templates/dashboard.html index 5eac493..17c9caf 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -32,6 +32,7 @@

вихід

en | uk

{{language}} +{{lang_d}}

{{ _('Installed components') }}

@@ -130,7 +131,7 @@

{{ component.name|title }}

{{ component.description }}

-

ВЕРСІЯ {{ component.version }}

+

ВЕРСІЯ {{ component.latest_version }}

{% if component.name in components_names %} {% else %}