diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2da5d63 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/components/adm/ +/components/grid/ +/components/vue/ diff --git a/components/__pycache__/__init__.cpython-310.pyc b/components/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 4ce13a2e623981757fe5e8707f6224e2b69850b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 140 zcmd1j<>g`kf}n#PDIoeWh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o2B>KO;XkRlhPZ zFHt|+s3&M4u=4F<|$LkeT-r}&y%}*)KNwotRRLle - - - - - - - - - - \ No newline at end of file diff --git a/components/adm/adm/.idea/inspectionProfiles/Project_Default.xml b/components/adm/adm/.idea/inspectionProfiles/Project_Default.xml deleted file mode 100644 index 62102dd..0000000 --- a/components/adm/adm/.idea/inspectionProfiles/Project_Default.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - \ No newline at end of file diff --git a/components/adm/adm/.idea/inspectionProfiles/profiles_settings.xml b/components/adm/adm/.idea/inspectionProfiles/profiles_settings.xml deleted file mode 100644 index 105ce2d..0000000 --- a/components/adm/adm/.idea/inspectionProfiles/profiles_settings.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/components/adm/adm/.idea/misc.xml b/components/adm/adm/.idea/misc.xml deleted file mode 100644 index dc9ea49..0000000 --- a/components/adm/adm/.idea/misc.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/components/adm/adm/.idea/modules.xml b/components/adm/adm/.idea/modules.xml deleted file mode 100644 index 52b9a11..0000000 --- a/components/adm/adm/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/components/adm/adm/.idea/vcs.xml b/components/adm/adm/.idea/vcs.xml deleted file mode 100644 index 6c0b863..0000000 --- a/components/adm/adm/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/components/adm/adm/__init__.py b/components/adm/adm/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/components/adm/adm/__pycache__/__init__.cpython-310.pyc b/components/adm/adm/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index e2ab797d9944c811b990c246aeb45d593d05e011..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148 zcmd1j<>g`kg2XEwDIoeWh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vUKO;XkRlhPZ zFHt|+s3nEnlgl8K**n{ zY!4rluVLy2fD=w7$?(f0ty#uuFY{_Y^C{Xq8Ps7GI@y;|9cQtV1KFvQEO9cG-K-0~ zq3qTDY(R+!Z%MZEE#VQ5?+A~@&aIaXIXxk1=N`@^$Ejz-m#v)Djg7u*j2H=J!xN*b zW|UGp?DopiCvQOvnN~ju9E|2@9~gFcO>ic z0q^kSj%EX~!@In9M_{)h??d)GHkusGv{3p740o!kx={0cBIfr;5Y_#!2zvk}1=tJ* z0`!r54^y857_y{>8E@&YVDDwHA}hKKS7br*XhD}Trz;9_2mPGRV13&waaPZHb)D=x zx##4-$$d^B;_%o8vK>{8ji-gym#yN~Z;D#jK-5JgZ7?0TjYtPJ8W(yjt5fUM{Dt+j zQP!W$DsBVB&uu80vgN{d#^Q=sBcY9ruoOACcq3ud05VfM2t$Njghv1=v%VJc%!ZT8 zLXGtAM75f79I3W7n@`!+QwXXt`mo@&n>8FQ^}%#*<2>283aSlDW^{${B!Tdk9L|@24mSa)R zElK;9O^$3Lu8e4O)i&BPerh8PcN;VtT+D=;+wiQCMyM@nJcd{m-VlXtQBMG@hXf3) zS4zF*`57+x$guxbtyj#<7#mW;gYpr$X(Zf$`IONwsPBjWgw$u(dz%t&yC0`iJqPb} z7m0)yAG0=>WQOu=NxxWQ~1v2Ek17^GlPv?s35#fo;s8oQ|=M)YvH-IA;~(K`9#iZ{Rt1 dLHu71HvV#5$glAI(^!U>>}^tjZ|Lo@e*rFLs`3B; diff --git a/components/adm/adm/__pycache__/views.cpython-310.pyc b/components/adm/adm/__pycache__/views.cpython-310.pyc deleted file mode 100644 index 476e19f29996f431487ea9aa3f4506d11e3dee23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3895 zcmbtX*>4-i8Qvm%#Ta^>0G z+9D_*u?iF@YPSUp2Pjg60{UVg4~`L|&SB?YSia6{pZwf6_xydclq}i_`cM+{&GCIR z-^_P!SSl4Y{QhzKxBPBJ)BZ-2-M<_rr_iFyOw+i=S)etto;4WedZ71=hS4({X3uI^ zjBp0l>_$$F%^=?^Gzz_9qlmf1?O>+oG#sXR2G4mVp63N#TM%gQOE8O9wHsj^1 zI+^hXM(-6iHNKDUCmeRoD(rzN>;gYH!Okh{Q&ZSO z{O|-judqj^uut>a1iM#ZpP9lw%a2a5`xN#$z8Ck^=^g4`&+}sw{Ca-+FD(gPWMvWBr;!kTvpp&+@uwsgT#;5A3&!XcI8%2B#|c~X}G*63$fQ* z3*6X?q#ea>?6(HyA`swS*+w;2!hm~1mNJ6vX=O4^M9^Gw~G#UM48ezyD; zG3$A8C*)C!p0xclF|g5IM~f~1#9EhaXtCZkI9t%VX4l$agN4}UwyzDfzp!g;Lm#qH zZm4fDreT!d($MRp!j`sSaD8a_>}_osYxIwc+~B4U!{FA6Zfm~)rk*<|i_yiv4O$(q zw=NyG)$*dK8HcN0Us|3Jp^(n`zMJ5>!XJ42!5<;7n_7KF7`UM{N$gTzJt2$U<=E>- ze%Ozs&M(MZgo7{>1)_scxwKnhujj|IKsrz?1iiU#N_))}ZZ8st)S09QX=Mcau_6dO zJh|8jd*0%@+jkdNPlzy#w>uoW7WSdeh*YH7uYB)P^wQe8%x}xSiZh~l09!9Jot0UU zFlUqsw_KKbf-%=c9e$9=dOQGOm4lD#+Q|u+M51^h?vK9w0 zmIh>(iPRybkPWwBrs8R$R?@UYjmFOtI7Z+Z0?!iI5vDjwQzAKn7Ljahy$E4A%v55j z>Iyr^kx0TMmd4pLZ%qk?+(t)Jf}sOArx?qQndfAWSnjv+Lre0J($Sl0|Ry4c?x zfOvAX?Ms>5ja_M}oq~?t#ZmD-iZxkm3!gU?(MdXq-s%|Qo9Mt+gn>8hy;$F2D_+9n zrg2UzqL-E;{$HFF(f2_wP7rt*U{IPoFYw8@zw(ueo%j}Q`^x8()JvMJ?5I;jtN47I z_&AF_ub;S?^Z#FL96G2uIqA#}m+ugl{9@m`bRG(x;$Q$pA>wtk=u-f4Fct3*_cmZl zBQv(PSl5no-8|P9kXo-Y72(*BMdxEHE{LM4 zjXHsUK^i^&vNWO?c`8YK4i^DDDQ&Oc3b`i>9q%&t+sL-!FfpOfk$JB%VW_So4S4b{ zmpTeEnVYEor|m8_ zhI-fx)=uqEWBn2JP;VAsDX=%D^{eq7Zu6Y7h&)+@nir<#DD*N5symsrz)*gGt4jyf z1PX>M4@d_Bdo-&Euep0c8AI{{wxu7Wx5n?J_tVeDzpJJ9(mMohrJtl9r+3nOwe)r^ z{Rs2Frgy}vAWtaKJ-KK6E>5_eeu4HesPBxgh*v-;eh5&X{W9wkR1}LJ5g_jsrwE)T zpse>b8j)HanVUFE(>Dk_VL8rr$wro)C9KD?KzZ5>eu-mLHZL1CZ087a_(7zvs$SI{ zCYFF5%&4Gt+()@K9Xcs<&7di(c@u*yb5V6f>6tXh^Y81bD5oAiuI43PRy~Sx)$if6 z)VFOu_rB5ADOMrt%_Hk|JeT|Z_P{y4w6t71R$DrK_RMlp2dnfC5b)>Y8|l6Ajq$tV zE8};@n-KafDDB?(_ciDNy2J9OH2qfCA5?qXub~~MoOQvCyoBVEzL%Ym-l{=o+xovY zm__+>d|FT_fGw1{fhYAiOsGmo|EzRD@tfXVWATCG_c)et=utA~|HIs$7^*I7_dC zH_2%;{h|iZ-LIvelVOjq4JvfhuDn$@#4>h>p99EztK$b8UjZr*q2e})^6{utRM|>d z$VKdmh@)-jx~=DRDh{*1{?PoV`ERo--UhmUP$=7`+$OD+z>QV~l?IueQvoI@A}N=V zvkI?1H&k`ZJuaw(QO+an9-?XxWdSyn!Gj34pi=_;zLyig3`92 ztg51t^fc4 diff --git a/components/adm/adm/__pycache__/views.cpython-311.pyc b/components/adm/adm/__pycache__/views.cpython-311.pyc deleted file mode 100644 index 1fd4961259cfcdff8899daa48ed2e44b133afdaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1119 zcmZ`%%}X0W6rb6TY?384ND4M77)lF`2UkoD7D5lL(nCR{?V*Iil4iyvx*uV7Q>#SC zL3;M4mqJcf(QE&YjRcedLFlQs6mOpTX4`xn`j~k;^WK}^{^tGWdm<4>V659BzJ$O)_%9L3$vpPbYSIR)J3iMoJ=dvk?C>c@ z9YUGuQ@df6eVW5O=GEM7v&!m(%VlC$@DLCo71lD$TOZsZ^2c%ni*5{TlG`3`q0U%# zP=%1Mjn+gu2E4N&=Hw2e7KYo%Ydj9D%to1&ZI36atm*g_*YTNac{zm%c06jDPT8iW z$)_2u);%9?_-Sx?7J-tS1ea?xcxr?-s_+EWZ1!%&sJS*ZT#IgbWrr|how=K|;(Ny8 z!eZWdv-rw#n`HIvx>0fMhU-uVQUDmv&vm-(%{O+~Jpc=x_^($0*GAWw$DNNqmb;l^ zFH;PZnSK9{1omJMj8e;Fp>+mMN%-4L|I>lTOt;}I2 zv}gChc|xHqn-crfz=@rg2G>S6`gD8cT2CJpPe`EWyL!H-=L03rl8|1@>0I5g%HCEe z6%$-TX#Qx_#ChNm&aseqkfC%;ha)@zB_qYc{&JPMO^{k}Iz{2%LXvmUqV1BVMPIOo zkP_^@18{vAV|;~{g8z>zv>Z&1o8*Io*wK^DOgA~#OU|_ueMQ6BJ{r1dBu!o7)CEo* hd^k}%+W}5>vC+duUy|^%J_7e!M$*DWBn*d){{S6C2-^Sv diff --git a/components/adm/adm/models.py b/components/adm/adm/models.py deleted file mode 100644 index d765f05..0000000 --- a/components/adm/adm/models.py +++ /dev/null @@ -1,43 +0,0 @@ -import uuid -from sqlalchemy import Column, Integer, String -from sqlalchemy.ext.declarative import declarative_base -from flask_jwt_extended import create_access_token -from datetime import timedelta -import hashlib -from flask import current_app as k2 - - -Base = declarative_base() - -class k2users(Base): - __tablename__ = 'k2users' - user_id = Column(Integer, primary_key=True) - login = Column(String(50)) - name = Column(String(50)) - email = Column(String(150)) - password = Column(String(50)) - phone = Column(String(20)) - - def __init__(self, **kwargs): - self.user_id = hashlib.md5(str(uuid.uuid4()).encode()).hexdigest() - self.login = kwargs.get('login') - self.password = hashlib.md5(kwargs.get('password').encode()).hexdigest() - self.name = kwargs.get('name') - self.email = kwargs.get('email') - self.phone = kwargs.get('phone') - - def get_token(self, expire_time=24): - expires_delta = timedelta(expire_time) - token = create_access_token(identity=self.user_id, expires_delta=expires_delta) - return token - - @classmethod - def authenticate(cls, login, password): - session = k2.extensions['sqlalchemy'].db.session - user = '' - try: - user = session.query(cls).filter(cls.login == login).filter(cls.password == hashlib.md5(password.encode()).hexdigest()).one() - except: - user = None - - return user \ No newline at end of file diff --git a/components/adm/adm/views.py b/components/adm/adm/views.py deleted file mode 100644 index a36583b..0000000 --- a/components/adm/adm/views.py +++ /dev/null @@ -1,131 +0,0 @@ -import hashlib -import uuid -from flask import Blueprint, request, jsonify -from flask import current_app as k2 -from flask_jwt_extended import jwt_required, get_jwt_identity -# from flask_sqlalchemy import session -# from sqlalchemy.orm import sessionmaker -# from k2.k2inst import Component - -from .models import k2users - - -adm = Blueprint('adm', __name__, template_folder='templates', static_folder='static', static_url_path='/adm') - - -@adm.route('/register', methods=["POST"]) -def register(): - params = request.json - session = k2.extensions['sqlalchemy'].db.session - try: - user = k2users(**params) - session.add(user) - session.commit() - token = user.get_token() - return {'access_token': token} - except: - return jsonify({'error': 'Unauthorized'}), 401 - - -@adm.route('/login', methods=["POST"]) -def login(): - params = request.json - login = params.get('login') - password = params.get('password') - user = k2users.authenticate(login, password) - if user: - token = user.get_token() - return {'access_token': token} - else: - return jsonify({'error': 'Unauthorized'}), 401 - - -@adm.route('/logout', methods=["GET"]) -@jwt_required() -def logout(): - response = { - 'message': 'Logged out successfully' - } - return jsonify(response) - - -@adm.route('/users', methods=["GET"]) -@jwt_required() -def grid_users(): - return jsonify({"data": "users"}) - - -@adm.route('/roles', methods=["GET"]) -@jwt_required() -def grid_roles(): - return jsonify({"data": "roles"}) - - -@adm.route('/usersclients', methods=["GET"]) -@jwt_required() -def users_clients(): - return jsonify({"data": "roles"}) - -@adm.route('/menuaaccess', methods=["GET"]) -@jwt_required() -def menu_aaccess(): - return jsonify({"data": "roles"}) - - -@adm.route('/newUser', methods=["GET", "POST"]) -@jwt_required() -def newUser(): - session = k2.extensions['sqlalchemy'].db.session - exist = session.query(k2users).filter_by(login=request.json['login']).first() - if not exist: - res = k2users( - user_id=hashlib.md5(str(uuid.uuid4()).encode()).hexdigest(), - login=request.json['login'], - name=request.json['name'], - email=request.json['email'], - password=hashlib.md5(request.json['password'].encode()).hexdigest(), - phone=request.json['phone']) - if res: - session.add(res) - session.commit() - return jsonify({'status': 'ok'}) - else: - return jsonify({'error': 'Such user exist'}), 404 - - -@adm.route('/changePassword', methods=["POST"]) -@jwt_required() -def changePassword(): - session = k2.extensions['sqlalchemy'].db.session - current_user = get_jwt_identity() - user = session.query(k2users).filter_by(user_id=current_user).first() - if user.password == hashlib.md5(request.json['old_password'].encode()).hexdigest(): - if request.json['new_password'] == request.json['re_new_password']: - user.password = hashlib.md5(request.json['new_password'].encode()).hexdigest() - session.commit() - else: - return jsonify({'error': 'Пароль не найден в базе'}), 404 - else: - return jsonify({'error': 'Пароль не совпвдает'}), 404 - return jsonify({'status': 'ok'}) - - -@adm.route('/menu-items') -def menu_items(): - menu = [ - - { - "title": 'Адміністрування сайту', - - "icon": {"icon": 'mdi mdi-database'}, - "children": [ - {'title': 'Зміна паролю', 'to': 'adm-changePassword'}, - {'title': 'Новий користувач', 'to': 'adm-newUser'}, - {'title': 'Користувачі', 'to': 'adm-users'}, - {'title': 'Користувачі клієнти', 'to': 'adm-usersclients'}, - {'title': 'Права', 'to': 'adm-roles'}, - {'title': 'Доступ до меню', 'to': 'adm-menuaaccess'}, - ], - }] - - return menu \ No newline at end of file diff --git a/components/adm/requirements.txt b/components/adm/requirements.txt deleted file mode 100644 index d0af8ce..0000000 --- a/components/adm/requirements.txt +++ /dev/null @@ -1,30 +0,0 @@ -blinker==1.6.2 -click==8.1.3 -dnspython==2.3.0 -email-validator==2.0.0.post2 -Flask==2.3.2 -Flask-Cors==3.0.10 -Flask-JWT-Extended==4.5.2 -Flask-Login==0.6.2 -Flask-Mail==0.9.1 -Flask-MySQLdb==1.0.1 -Flask-SQLAlchemy==3.0.3 -flask-staticdirs==1.0.1 -Flask-WTF==1.1.1 -greenlet==2.0.2 -idna==3.4 -itsdangerous==2.1.2 -Jinja2==3.1.2 -jsonify==0.5 -MarkupSafe==2.1.2 -mysql-connector-python==8.0.33 -mysqlclient==2.1.1 -protobuf==3.20.3 -PyJWT==2.7.0 -pytz==2023.3 -PyYAML==6.0 -six==1.16.0 -SQLAlchemy==2.0.15 -typing_extensions==4.6.2 -Werkzeug==2.3.4 -WTForms==3.0.1 diff --git a/components/adm/setup.py b/components/adm/setup.py deleted file mode 100644 index 8370eae..0000000 --- a/components/adm/setup.py +++ /dev/null @@ -1,15 +0,0 @@ -from setuptools import setup - -setup( - name='adm', - version='1.0.0', - description='Description of my project', - author='Your Name', - author_email='yourname@example.com', - keywords="adm, k2", - python_requires=">=3.7, <=3.11.2", - packages=['adm'], - package_data={ # Optional - }, - install_requires=[""], -) \ No newline at end of file diff --git a/components/k2test/__pycache__/__init__.cpython-310.pyc b/components/k2test/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 0aa0c6d2196a9364ca1378a515b4997ac4362e21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmd1j<>g`kf}n#PDU3k+F^Gcg`kf}n#PDIoeWh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vOKO;XkRlhPZ zFHt|+s3A>v6yMpMy^p;QJGPV9AxH;^;zDervkQbQ3kab=!3a#X5;`qAV|(rWIM2++ z@#!o9NrjYxhKk~hXy_uOGzc4szu??XOGTXyQSjcZFYyr~v8Q=E@3(K}z4^^==CVe^ zv)~!r_=f#hvaCPQx%dEPy#r1D4u)Bb#8yIllGwhTIKD#=vtydLzMGW%Qd0KINyV=i z+=1At@0mV@e$B5Xb-!+WH*O?Nzey}!V%@}0PAhUqXvC9UzY>+E}TxIhHxxyAUt@gD)VI5Z6(Nlt_jEk<~ zNiPl**A>B8BzUNFS@8XwOVy^@i?i)0?dFmTT@P~sgH++w;7gXDJIx{t$H5e=O>}J> z9Q1l^TUXzUbKVnCsx;k|Sqc%}<|lXFjl&(D9O}|uM?pee9akfDNvc3aA&i|GgWatx zhLUxo_;l{}>2k^sLR{AP!A*0Z-GU}R1f#57!pMTPYadwyYu6dlW9x_vtf9;7V{&8< z$gnhk-mna~!yHB*SOe#Mp#O-f%CI`15akYBAkf{=p4^XvqVj%g^Y)$Fw?1p}B#7dh zEyF|WgHJ#HsI}KY)?`Q^|M;6!PIS!c%%tG&!$AQ0qVP` zpU#AU0Jd=LMnDzlC^-4|3G9iz(XV3o(vC{vHW3(gAvf-TFab<4NFFv9GJ;4x$_ zD}7JFFB`w|)UO)fEBtK-k2UO0Z9~&ENH|#7qyDvoMT?*>p%zt?@ED}HcsCGHkg6Q7 z{m~Dj$H;4|lfQPs9i5JT27-a*)6uV^-@u-X9*<6d|3`2oI=P57jX<2*RgsE8#Ub3E z+ZpH+)2>WTy<))CNwDA$E&7fU#j|dlGyodzyE>Pj3ismIWNKJ7dr;9<)?mJP3Z@SX$ zBFo*bz=Ne-0e=MC944b}BQmq+rlt$adnVD!T9UCm=IglmvIS<&nkRKKjg3~QM=BmP J=e*G-`3ENc30VLD diff --git a/components/k2test/k2test/languages/en/LC_MESSAGES/messages.mo b/components/k2test/k2test/languages/en/LC_MESSAGES/messages.mo index c64ccfd831f970e0b1a81567febd154b3678ff59..edaecf87f18eff792777f2a358e0343c1c6145cc 100644 GIT binary patch delta 193 zcmcc1wv?s*o)F7a1|VPtVi_Pd0dbIk50K3T#J)f*0K^eM+|S6skO`!vf%qqo%@3qS znSg{}YPo`uLP27BDnm(TNlt2fZfag>d}c{%ZZShZQGQlxa*3{Iif&kHQE_H|o|QsC z(By1JKQ=Q3Lt`tG&HEYE7 K02!$OF%kgU@-)Bz delta 482 zcmcJ}y-EW?6b0bBx~x$X1Tj`3lSZ&J5iAsh5K#o(CM5l`xtJlz?2sAJLdYYCg^%C^ z_$;<2m3EevDLmI~#Lmir!#97-nWu0ZjV9~iBViPgE#yuXzs4)(5i&;BkT*o`ej=+# z5D*n$39i6RxB)9Lga`Tl5tMgM;S#)r_W_Nll^?t>%nClB6ilHMEHBOq%1{cnp%m;w zDLBse8&C>jC-N)j7Pl#nI0}wC)u?!IFfH+9N2FT_DVp|}-$;iOq0i>mYSP7)TFST63NTDDx UJ#}J6Dx0B#k+GG*#>+j70L;S;7XSbN diff --git a/components/k2test/k2test/languages/uk/LC_MESSAGES/messages.po b/components/k2test/k2test/languages/uk/LC_MESSAGES/messages.po index 8c1c9a8..397ef8f 100644 --- a/components/k2test/k2test/languages/uk/LC_MESSAGES/messages.po +++ b/components/k2test/k2test/languages/uk/LC_MESSAGES/messages.po @@ -1,2 +1,4 @@ msgid "New 2 page" msgstr "Нова сторінка 2" +msgid "title_menu_items" +msgstr "Тестова компонента" \ No newline at end of file diff --git a/components/k2test/k2test/static/default.css b/components/k2test/k2test/static/default.css deleted file mode 100644 index 8b13789..0000000 --- a/components/k2test/k2test/static/default.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/components/k2test/k2test/static/style.css b/components/k2test/k2test/static/style.css deleted file mode 100644 index 8b13789..0000000 --- a/components/k2test/k2test/static/style.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/components/k2test/k2test/templates/login.html b/components/k2test/k2test/templates/login.html deleted file mode 100644 index a46884d..0000000 --- a/components/k2test/k2test/templates/login.html +++ /dev/null @@ -1 +0,0 @@ -login diff --git a/components/k2test/k2test/views.py b/components/k2test/k2test/views.py index 9ce7b9c..fcf569d 100644 --- a/components/k2test/k2test/views.py +++ b/components/k2test/k2test/views.py @@ -1,15 +1,15 @@ from flask import render_template, redirect, request, jsonify +from flask_babel import gettext 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 +#bliueprint +k2test = Blueprint('k2test', __name__, template_folder='templates', static_folder='static') -k2test = Blueprint('k2test', __name__, template_folder='templates', static_folder='static',) - - - +#component routes @k2test.route('/new') def new_component(): db = k2.extensions['sqlalchemy'].db @@ -33,12 +33,12 @@ def new_component3(): def new_component4(): return jsonify({'data': 'page new4'}) - -@k2test.route('/menu-items') +# menu items for admin +@k2test.route('/menu-admin-items') def menu_items(): data = [ { - 'title': 'Тестова компонента', + 'title': f"{gettext('title_menu_items')}", 'icon': {'icon': 'mdi-chart-timeline-variant'}, 'children': [ {'title': 'Тест 3', 'to': 'k2test-new3'}, @@ -47,4 +47,5 @@ def menu_items(): } ] - return data \ No newline at end of file + return data + diff --git a/components/k2test/menu_items.yml b/components/k2test/menu_items.yml deleted file mode 100644 index 166a9e5..0000000 --- a/components/k2test/menu_items.yml +++ /dev/null @@ -1,15 +0,0 @@ -- url: - name: new2 - icon: mdi-chart-timeline-variant - title: Тест 2 - category: Тестова компонента -- url: - name: new3 - icon: mdi-chart-timeline-variant - title: Тест 3 - category: Тестова компонента -- url: - name: new4 - icon: mdi-chart-timeline-variant - title: Тест 4 - category: Тестова компонента diff --git a/components/k2test/setup.py b/components/k2test/setup.py index 1c35e51..46cdf60 100644 --- a/components/k2test/setup.py +++ b/components/k2test/setup.py @@ -4,8 +4,8 @@ setup( name='k2test', version='1.0.0', description='Description of my project', - author='Your Name', - author_email='yourname@example.com', + author='k2 cloud', + author_email='rs@corp2.net', keywords="k2test, k2", python_requires=">=3.7, <=3.11.2", packages=['k2test'], diff --git a/components/menu.yml b/components/menu.yml deleted file mode 100644 index 0b82138..0000000 --- a/components/menu.yml +++ /dev/null @@ -1,33 +0,0 @@ -- heading: APPS & PAGES -- children: - - title: "\u0422\u0435\u0441\u0442 3" - to: k2test-new3 - - title: "\u0422\u0435\u0441\u0442 3" - to: k2test-new4 - component_name: k2test - icon: - icon: mdi-chart-timeline-variant - id: 2 - title: "\u0422\u0435\u0441\u0442\u043E\u0432\u0430 \u043A\u043E\u043C\u043F\u043E\ - \u043D\u0435\u043D\u0442\u0430" -- children: - - title: "\u0417\u043C\u0456\u043D\u0430 \u043F\u0430\u0440\u043E\u043B\u044E" - to: adm-changePassword - - title: "\u041D\u043E\u0432\u0438\u0439 \u043A\u043E\u0440\u0438\u0441\u0442\u0443\ - \u0432\u0430\u0447" - to: adm-newUser - - title: "\u041A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0456" - to: adm-users - - title: "\u041A\u043E\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0456 \u043A\ - \u043B\u0456\u0454\u043D\u0442\u0438" - to: adm-usersclients - - title: "\u041F\u0440\u0430\u0432\u0430" - to: adm-roles - - title: "\u0414\u043E\u0441\u0442\u0443\u043F \u0434\u043E \u043C\u0435\u043D\u044E" - to: adm-menuaaccess - component_name: adm - icon: - icon: mdi mdi-database - id: 3 - title: "\u0410\u0434\u043C\u0456\u043D\u0456\u0441\u0442\u0440\u0443\u0432\u0430\ - \u043D\u043D\u044F \u0441\u0430\u0439\u0442\u0443" diff --git a/db/database.db b/db/database.db index f687958489f7157e3dde936a90012dc5c849c3e8..f4f61e41bedec16130d0dc0a023cc7d16dbe288f 100644 GIT binary patch delta 663 zcmaiyy^7RO6vyLa5oeg)D549pU_eXf=6>JYY$581h@{&>5YhX&jxtHeq}j&V0V^xr z)WYHuC{tKk_!_qR0zQEWh_KsCaf)*|f6k8|=lFDRd^-4aYY^(sdk-&%IsmWszS}Ri zqn(dII6e!ar`x~AXJfm*cJ*M~+Iy?z>c!S5zkYxB*@NL~Ut7!tQ^qPKC}&bL4{hoY z6{+()Wy;Q{Zei+K)y&EwE`2;dimSSO>r8_H1n^DMR9TW7&Kh9Ky27AvO>(qIx*+I= z7-BMke1g&#p^VCmT%mwd$)#xjfal9;ILdE4+THG09$TCe$qYrBX^L2yN=Y2y&UCH8 z939p(djX~&ox}NmkH?T_3}yrZhJ}E{*X2Am<-95jS2PRIM?w1%JXr=o@Us`vL+m4I zyW7eeBpsDZDoQkgm}96M@j`4Aa-M*q3}e73>>w@@^oqJ_heSp=Wjh(AEh zTR|w&KOlMNkMJ*){tw@rkSOX)pN2VSzH`oZ=I}T?JPto?hT-|=>kn4L^8oDbd^cZj zL_rXQ^^+jluAfBPRWrMM>3MZ(?oSQ?qX=;vN9EvW>)O_pm(B9z6*UZDWt64b(@JHE zP|78;l4yqv>f*wV3*5!+y-u;8c0e%CRh_uXXi z9C&gULrfZwHz11gTCz-W3V(`o?xCJ?s#@oc>ASwdycmA zVQu;&**y3UyjKZ=m7~`B-K)=<lsK7F zVYIZl9}-d^qA*f4Grf6vf8') -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(f'{k2.update_domain}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=k2.menu ) - -@components_bp.route('/show_components/') -def show_components(component_id): - response = requests.get(f'{k2.update_domain}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/') -def install_components_git(component_id): - # Шлях до головної папки проекту - project_folder = 'components' - #component = Component.get_repository_by_id(component_id) - response = requests.get(f'{k2.update_domain}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/') -def install_component_from_archive(component_id): - # Шлях до головної папки проекту - project_folder = 'components' - # Отримати відповідну компоненту зі списку компонент - response = requests.get(f'{k2.update_domain}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') - - #Update database with the installed component - 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() - # add menu items yml - #file_path_input = f"components/{selected_component['name']}/menu_items.yml" - #if os.path.exists(file_path_input): - # with open(file_path_input, 'r', encoding='utf-8') as file: - # data = yaml.safe_load(file) - #else: - # data = { - # 'url': {'name': 'error'}, - # 'icon': 'error', - # 'title': f"{selected_component['name']}--error", - # 'category': 'error', - # } - - #file_path = 'components/menu.yml' - #append_to_yaml_file(file_path, data) - - #add language folders - k2.search_babel_translation_directories() - print(k2.domain) - 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']) -def install_requirments(selected_component_name): - #menu items api - response = requests.get(f"{k2.domain}{selected_component_name}/menu-items") - if response.status_code == 200: - data = response.json() - print(data) - else: - data = [{ - 'url': {'name': 'error'}, - 'icon': 'error', - 'title': f"{selected_component_name}--error", - 'category': 'error', - }] - # add component_name key for menu items - for item in data: - item['component_name'] = selected_component_name - file_path = 'components/menu.yml' - append_to_yaml_file(file_path, data) - k2.get_menu_elenents() - - #install requirements - 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') -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']) -def remove_dependencies(component_id): - # Знаходимо компоненту за її ID - component = Component.query.get(component_id) - if not component: - return 'Component not found ' - #remove menu items - component_name = component.name - file_path = "components/menu.yml" - remove_from_yaml_file(file_path, component_name) - - # remove routes - 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']) -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/') -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) - -@components_bp.route('/api/main-menu/') -def project_menu(): - return k2.menu diff --git a/k2/k2obj.py b/k2/k2obj.py index 5db2744..52457cc 100644 --- a/k2/k2obj.py +++ b/k2/k2obj.py @@ -16,6 +16,7 @@ class k2obj: 'cutpast': '0', 'enable': '0' } + components = '' diff --git a/k2/k2rout.py b/k2/k2rout.py new file mode 100644 index 0000000..4a37121 --- /dev/null +++ b/k2/k2rout.py @@ -0,0 +1,416 @@ +import zipfile +from flask import Flask, Blueprint, jsonify, render_template, redirect, url_for, session, g +import os +import shutil +from flask import request +from .k2cfg import k2 +from .k2comp import Component +from flask_migrate import Migrate +import requests +import subprocess +from flask import current_app +import yaml +from functools import wraps +import os +import sys + +# initialize db +#migrate = Migrate(app, db) + +components_bp = Blueprint('components', __name__, template_folder='templates') +config = yaml.safe_load(open("db/first-login.yml")) + + +db = k2.db + + +def first_login_required(view_func): + @wraps(view_func) + def decorated_view(*args, **kwargs): + if 'username' not in session: + return redirect(url_for('components.first_login')) + return view_func(*args, **kwargs) + return decorated_view + +def append_to_yaml_file(file_path, data): + with open(file_path, 'r') as f: + existing_data = yaml.safe_load(f) or [] + + if not existing_data: + start_id = 1 + else: + start_id = max(item.get('id', 0) for item in existing_data) + 1 + + for i, item in enumerate(data, start=start_id): + item['id'] = i + existing_data.append(item) + + with open(file_path, 'w') as f: + yaml.dump(existing_data, f, default_flow_style=False) + + +def remove_from_yaml_file(file_path, component_name): + with open(file_path, 'r') as f: + existing_data = yaml.safe_load(f) or [] + + updated_data = [item for item in existing_data if item.get('component_name') != component_name] + + with open(file_path, 'w') as f: + yaml.dump(updated_data, f, default_flow_style=False) + +@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('/api/add-to-menu', methods=['GET']) +def add_to_menu(): + data = [] + components = Component.query.all() + components_names = [component.name for component in components] + for components_names in components_names: + response = requests.get(f"{k2.domain}{components_names}/menu-admin-items") + print(response) + if response.status_code == 200: + data.append(response.json()[0]) + else: + data + # add component_name key for menu items + for item in data: + item['component_name'] = components_names + k2.menu = data + return k2.menu + +@components_bp.route('/home', methods=['GET', 'POST']) +@first_login_required +def home(): + return redirect('/dashboard') + +@components_bp.route('/first-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('/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(f'{k2.update_domain}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=k2.menu ) + +@components_bp.route('/show_components/') +def show_components(component_id): + response = requests.get(f'{k2.update_domain}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/') +def install_components_git(component_id): + # Шлях до головної папки проекту + project_folder = 'components' + #component = Component.get_repository_by_id(component_id) + response = requests.get(f'{k2.update_domain}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/') +def install_component_from_archive(component_id): + # Шлях до головної папки проекту + project_folder = 'components' + # Отримати відповідну компоненту зі списку компонент + response = requests.get(f'{k2.update_domain}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') + + #Update database with the installed component + 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() + + #add language folders + 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']) +def install_requirments(selected_component_name): + #menu items api + response = requests.get(f"{k2.domain}{selected_component_name}/menu-items") + if response.status_code == 200: + data = response.json() + + else: + data = [] + # add component_name key for menu items + for item in data: + item['component_name'] = selected_component_name + file_path = 'components/menu.yml' + append_to_yaml_file(file_path, data) + get_admin_menu() + + #install requirements + 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') +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']) +def remove_dependencies(component_id): + # Знаходимо компоненту за її ID + component = Component.query.get(component_id) + if not component: + return 'Component not found ' + #remove menu items + component_name = component.name + file_path = "components/menu.yml" + remove_from_yaml_file(file_path, component_name) + + # remove routes + 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']) +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/') +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) + +@components_bp.route('/api/main-menu/') +def get_admin_menu(): + requests.get(f"{k2.domain}api/add-to-menu") + return k2.menu diff --git a/languages/babel_translation_directories.yml b/languages/babel_translation_directories.yml index d52449d..a0533f7 100644 --- a/languages/babel_translation_directories.yml +++ b/languages/babel_translation_directories.yml @@ -1 +1 @@ -babel_translation_directories: languages;components/k2test/k2test/languages +babel_translation_directories: languages;components/k2test/k2test/languages;components/grid/grid/languages;components/adm/adm/languages diff --git a/main.py b/main.py index 9abcfbe..c967ee3 100644 --- a/main.py +++ b/main.py @@ -8,7 +8,7 @@ from k2.k2cfg import k2 # configure flask app app = Flask(__name__) app.config['SECRET_KEY'] = k2.secret_key - +app.json.sort_keys = k2.json_sort_keys #app.config.from_object(k2) # init db @@ -22,9 +22,6 @@ app.config['BABEL_TRANSLATION_DIRECTORIES'] = k2.babel_translation_directories babel = Babel(app) babel.init_app(app, locale_selector=k2.get_locale) -#menu -k2.get_menu_elenents() - # flask routing from routes import * diff --git a/routes.py b/routes.py index 9c7200c..9fbc182 100644 --- a/routes.py +++ b/routes.py @@ -1,11 +1,6 @@ -from flask import Flask #app = Flask(__name__) -from main import app, babel -from k2.k2inst import components_bp +from main import app +from k2.k2rout import components_bp app.register_blueprint(components_bp) - from components.k2test.k2test.views import k2test app.register_blueprint(k2test, url_prefix='/k2test') - -from components.adm.adm.views import adm -app.register_blueprint(adm, url_prefix='/adm') diff --git a/templates/dashboard.html b/templates/dashboard.html index 17c9caf..007c567 100644 --- a/templates/dashboard.html +++ b/templates/dashboard.html @@ -112,7 +112,7 @@
-

{{_('Components Shop')}}

+

{{_('ADD Components')}}

diff --git a/templates/first-login.html b/templates/first-login.html index 33ba9be..ae45a14 100644 --- a/templates/first-login.html +++ b/templates/first-login.html @@ -64,7 +64,7 @@

K2CloudERP-2.5.1.27

- +

diff --git a/templates/index.html b/templates/index.html deleted file mode 100644 index 66191be..0000000 --- a/templates/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - Головна сторінка - - - -

Index Main

-
- -
{{ name }}
- {% for js_file in js_files %} - - {% endfor %} - -