Commit a22c466d91e61d9104eae5088b9b557e7f00638b

Authored by Василь Свідрик
1 parent 80af188087
Exists in master

add update server, fix upd bags

Showing 30 changed files with 162 additions and 36 deletions Inline Diff

__pycache__/app.cpython-310.pyc
No preview for this file type
__pycache__/routes.cpython-310.pyc
No preview for this file type
1 from flask_cors import CORS 1 from flask_cors import CORS
2 from flask_babel import Babel 2 from flask_babel import Babel
3 from flask_jwt_extended import JWTManager 3 from flask_jwt_extended import JWTManager
4 #from k2.k2rout import * 4 #from k2.k2rout import *
5 from flask import Flask 5 from flask import Flask
6 from k2.k2cfg import k2 6 from k2.k2cfg import k2
7 7
8 8
9 9
10 # configure flask app 10 # configure flask app
11 app = Flask(__name__) 11 app = Flask(__name__)
12 app.config['SECRET_KEY'] = k2.secret_key 12 app.config['SECRET_KEY'] = k2.secret_key
13 app.json.sort_keys = k2.json_sort_keys 13 app.json.sort_keys = k2.json_sort_keys
14 #app.config.from_object(k2) 14 #app.config.from_object(k2)
15 15
16 16
17 # init db 17 # init db
18 k2().init_db(app) 18 k2().init_db(app)
19 CORS(app) 19 CORS(app)
20 20
21 21
22 #translate 22 #translate
23 k2.load_babel_translation_directories() 23 k2.load_babel_translation_directories()
24 app.config['BABEL_TRANSLATION_DIRECTORIES'] = k2.babel_translation_directories 24 app.config['BABEL_TRANSLATION_DIRECTORIES'] = k2.babel_translation_directories
25 app.config['BABEL_DEFAULT_LOCALE'] = k2.default_language 25 app.config['BABEL_DEFAULT_LOCALE'] = k2.default_language
26 app.config['BABEL_LANGUAGES'] = k2.languages 26 app.config['BABEL_LANGUAGES'] = k2.languages
27 app.config['BABEL_DEFAULT_TIMEZONE'] = k2.timezone 27 app.config['BABEL_DEFAULT_TIMEZONE'] = k2.timezone
28 babel = Babel(app) 28 babel = Babel(app)
29 babel.init_app(app, locale_selector=k2.get_locale) 29 babel.init_app(app, locale_selector=k2.get_locale)
30 30
31 #menu 31 #menu
32 @app.context_processor 32 @app.context_processor
33 def inject_static_variable(): 33 def inject_static_variable():
34 return {'menu': k2.menu} 34 return {'menu': k2.menu}
35 #platform
36 k2.platform =k2.get_platform()
35 37
36 # flask routing 38 # flask routing
37 from routes import * 39 from routes import *
38 40
39 if __name__ == '__main__': 41 if __name__ == '__main__':
40 app.run() 42 app.run()
41 43
42 44
43 45
44 46
45 47
46 48
47 49
48 50
components/k2test/README.md
File was created 1 Base k2 component
2
3 language - .mo, .po files with translates
4
5 static - css, js, mediafiles
6
7 templates - components templates
8
9 views.py - routes
10
11 history.txt -
12
13 reguirments-components.txt -
14
15 requirements.txt -
16
17 setup.py -
components/k2test/__pycache__/__init__.cpython-310.pyc
No preview for this file type
components/k2test/history.txt
File was created 1 1.0.0.0 base component
2 1.0.0.1 add some routes
components/k2test/k2test/__pycache__/__init__.cpython-310.pyc
No preview for this file type
components/k2test/k2test/__pycache__/views.cpython-310.pyc
No preview for this file type
components/k2test/k2test/languages/en/LC_MESSAGES/messages.mo
No preview for this file type
components/k2test/k2test/languages/en/LC_MESSAGES/messages.po
File was created 1 msgid "New 2 page"
2 msgstr "Нова сторінка 2"
3 msgid "title_menu_items"
4 msgstr "Test menu items"
components/k2test/k2test/languages/uk/LC_MESSAGES/messages.mo
No preview for this file type
components/k2test/k2test/languages/uk/LC_MESSAGES/messages.po
File was created 1 msgid "New 2 page"
2 msgstr "Нова сторінка 2"
3 msgid "title_menu_items"
4 msgstr "Тестова компонента"
components/k2test/k2test/templates/new2.html
File was created 1
2
3 <h2>{{ _('New 2 page') }}</h2>
components/k2test/k2test/views.py
File was created 1 from flask import render_template, redirect, request, jsonify
2 from flask_babel import gettext
3 from flask_login import login_user, current_user, logout_user, login_required
4 from flask import current_app as k2
5 from flask import Blueprint, json
6 from flask_sqlalchemy import SQLAlchemy
7
8
9 #bliueprint
10 k2test = Blueprint('k2test', __name__, template_folder='templates', static_folder='static')
11
12 #component routes
13 @k2test.route('/new')
14 def new_component():
15 db = k2.extensions['sqlalchemy'].db
16 connection = db.engine.connect()
17 query = db.text("SELECT email, login FROM k2users")
18 result = connection.execute(query).fetchall()
19 rows = [dict(email=row.email, login=row.login) for row in result]
20 # Перетворення результату на JSON
21 json_result = json.dumps(rows)
22 return json_result
23
24 @k2test.route('/new2')
25 def new_component2():
26 return render_template('new2.html')
27
28 @k2test.route('/new3')
29 def new_component3():
30 return jsonify({'data': 'page new3'})
31
32 @k2test.route('/new4')
33 def new_component4():
34 return jsonify({'data': 'page new4'})
35
36 # menu items for admin
37 @k2test.route('/menu-admin-items')
38 def menu_items():
39 data = [
40 {
41 'title': f"{gettext('title_menu_items')}",
42 'icon': {'icon': 'mdi-chart-timeline-variant'},
43 'children': [
44 {'title': 'Тест 3', 'to': 'k2test-new3'},
45 {'title': 'Тест 3', 'to': 'k2test-new4'},
46 ],
47 }
48
49 ]
50 return data
51
52
components/k2test/reguirments-components.txt
File was created 1 grid==1.0.1
components/k2test/requirements.txt
File was created 1 Flask-Login==0.6.2
2
components/k2test/setup.py
File was created 1 from setuptools import setup, find_packages
2
3 setup(
4 name='k2test',
5 version='1.0.0.8',
6 description='Description of my project version 1.0.0.8',
7 author='k2 cloud',
8 author_email='rs@corp2.net',
9 keywords="k2test, k2",
10 python_requires=">=3.7, <=3.11.2",
11 packages=['k2test'],
12 package_data={ # Optional
13 },
14 install_requires=[""],
15 )
16
No preview for this file type
k2/__pycache__/k2admmenu.cpython-310.pyc
No preview for this file type
k2/__pycache__/k2cfg.cpython-310.pyc
No preview for this file type
k2/__pycache__/k2obj.cpython-310.pyc
No preview for this file type
k2/__pycache__/k2rout.cpython-310.pyc
No preview for this file type
1 import hashlib 1 import hashlib
2 import uuid 2 import uuid
3 from .k2cfg import k2 3 from .k2cfg import k2
4 4
5 5
6 db = k2.db 6 db = k2.db
7 7
8 class K2admin_menus(db.Model): 8 class K2admin_menus(db.Model):
9 __tablename__ = 'k2admin_menus' 9 __tablename__ = 'k2admin_menus'
10 menuid = db.Column(db.String(75), primary_key=True) 10 menuid = db.Column(db.String(75), primary_key=True)
11 namemenu = db.Column(db.String(150), index=True) 11 namemenu = db.Column(db.String(150), index=True)
12 prevmenu = db.Column(db.String(150), index=True) 12 prevmenu = db.Column(db.String(150), index=True)
13 ccount = db.Column(db.Integer) 13 ccount = db.Column(db.Integer)
14 scriptrun = db.Column(db.Text) 14 scriptrun = db.Column(db.Text)
15 prevmenu_text = db.Column(db.String(150)) 15 prevmenu_text = db.Column(db.String(150))
16 module_name = db.Column(db.String(150), index=True) 16 module_name = db.Column(db.String(150), index=True)
17 magazinsid = db.Column(db.String(75), index=True) 17 magazinsid = db.Column(db.String(75), index=True)
18 active = db.Column(db.Integer, index=True) 18 active = db.Column(db.Integer, index=True)
19 createuser = db.Column(db.String(75), index=True) 19 createuser = db.Column(db.String(75), index=True)
20 createdate = db.Column(db.DateTime, index=True) 20 createdate = db.Column(db.DateTime, index=True)
21 updateuser = db.Column(db.String(75), index=True) 21 updateuser = db.Column(db.String(75), index=True)
22 updatedate = db.Column(db.DateTime, index=True) 22 updatedate = db.Column(db.DateTime, index=True)
23 order_ins = db.Column(db.String(150), index=True) 23 order_ins = db.Column(db.String(150), index=True)
24 caption = db.Column(db.String(1024)) 24 caption = db.Column(db.String(1024))
25 url = db.Column(db.String(2048)) 25 url = db.Column(db.String(2048))
26 26
27 27
28 def __init__(self, **kwargs): 28 def __init__(self, **kwargs):
29 self.menuid = hashlib.md5(str(uuid.uuid4()).encode()).hexdigest() 29 self.menuid = hashlib.md5(str(uuid.uuid4()).encode()).hexdigest()
30 super(K2admin_menus, self).__init__(**kwargs) 30 super(K2admin_menus, self).__init__(**kwargs)
31 31
32 32
33 def __repr__(self): 33 def __repr__(self):
34 return f"{self.namemenu}')" 34 return f"{self.namemenu}')"
35 35
36 @classmethod 36 @classmethod
37 def get_menu_items_by_roles(cls, roleid): 37 def get_menu_items_by_roles(cls, roleid):
38 menu_query = f""" 38 menu_query = f"""
39 SELECT menus.namemenu 39 SELECT menus.namemenu
40 FROM k2admin_menus menus 40 FROM k2admin_menus menus
41 JOIN k2admin_menus_prava prava ON menus.menuid = prava.menuid 41 JOIN k2admin_menus_prava prava ON menus.menuid = prava.menuid
42 WHERE prava.roleid = '{roleid}' 42 WHERE prava.roleid = '{roleid}'
43 """ 43 """
44 result = db.session.execute(db.text(menu_query)).fetchall() 44 result = db.session.execute(db.text(menu_query)).fetchall()
45 menu_items = [item[0].decode('utf-8') for item in result] 45 if k2.platform == 'Linux':
46 return menu_items 46 menu_items = [item[0] for item in result]
47 return menu_items
48 elif k2.platform == 'Windows':
49 menu_items = [item[0].decode('utf-8')for item in result]
50 return menu_items
47 51
48 class K2admin_Menus_Prava(db.Model): 52 class K2admin_Menus_Prava(db.Model):
49 __tablename__ = 'k2admin_menus_prava' 53 __tablename__ = 'k2admin_menus_prava'
50 pravrepid = db.Column(db.String(75), primary_key=True) 54 pravrepid = db.Column(db.String(75), primary_key=True)
51 menuid = db.Column(db.String(75), db.ForeignKey('k2admin_menus.menuid')) 55 menuid = db.Column(db.String(75), db.ForeignKey('k2admin_menus.menuid'))
52 username = db.Column(db.String(150)) 56 username = db.Column(db.String(150))
53 r = db.Column(db.Integer) 57 r = db.Column(db.Integer)
54 w = db.Column(db.Integer) 58 w = db.Column(db.Integer)
55 i = db.Column(db.Integer) 59 i = db.Column(db.Integer)
56 d = db.Column(db.Integer) 60 d = db.Column(db.Integer)
57 c = db.Column(db.Integer) 61 c = db.Column(db.Integer)
58 exp = db.Column(db.Integer) 62 exp = db.Column(db.Integer)
59 imp = db.Column(db.Integer) 63 imp = db.Column(db.Integer)
60 settable = db.Column(db.Integer) 64 settable = db.Column(db.Integer)
61 cutpast = db.Column(db.Integer) 65 cutpast = db.Column(db.Integer)
62 enable = db.Column(db.Integer) 66 enable = db.Column(db.Integer)
63 magazinsid = db.Column(db.String(75)) 67 magazinsid = db.Column(db.String(75))
64 active = db.Column(db.Integer) 68 active = db.Column(db.Integer)
65 createuser = db.Column(db.String(75)) 69 createuser = db.Column(db.String(75))
66 createdate = db.Column(db.DateTime) 70 createdate = db.Column(db.DateTime)
67 updateuser = db.Column(db.String(75)) 71 updateuser = db.Column(db.String(75))
68 updatedate = db.Column(db.DateTime) 72 updatedate = db.Column(db.DateTime)
69 order_ins = db.Column(db.Integer) 73 order_ins = db.Column(db.Integer)
70 roleid = db.Column(db.String(150)) 74 roleid = db.Column(db.String(150))
71 75
72 menu = db.relationship('K2admin_menus', backref='prava') 76 menu = db.relationship('K2admin_menus', backref='prava')
73 77
74 def __init__(self, **kwargs): 78 def __init__(self, **kwargs):
75 self.pravrepid = hashlib.md5(str(uuid.uuid4()).encode()).hexdigest() 79 self.pravrepid = hashlib.md5(str(uuid.uuid4()).encode()).hexdigest()
76 super(K2admin_Menus_Prava, self).__init__(**kwargs) 80 super(K2admin_Menus_Prava, self).__init__(**kwargs)
77 81
78 82
1 from flask_sqlalchemy import SQLAlchemy 1 from flask_sqlalchemy import SQLAlchemy
2 from sqlalchemy import text 2 from sqlalchemy import text
3 from .k2obj import k2obj 3 from .k2obj import k2obj
4 import yaml 4 import yaml
5 import os 5 import os
6 import requests 6 import requests
7 import pytz 7 import pytz
8 import os 8 import os
9 import sys 9 import sys
10 from flask import session, request 10 from flask import session, request
11 from flask_login import LoginManager 11 from flask_login import LoginManager
12 import platform
12 13
13
14 class k2(k2obj): 14 class k2(k2obj):
15 version = '2.5.1.27' 15 version = '2.5.1.27'
16 db = SQLAlchemy() 16 db = SQLAlchemy()
17 domain = 'http://127.0.0.1:5000/' 17 domain = 'http://127.0.0.1:5000/'
18 update_domain = 'http://127.0.0.1:8000/' #'http://185.174.172.137/' 18 update_domain = 'http://192.168.20.229/' #'http://185.174.172.137/'
19 venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/Scripts') #for windows 19 venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/Scripts') #for windows
20 #venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/bin') #for linux 20 #venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/bin') #for linux
21 json_sort_keys = False 21 json_sort_keys = False
22 timezone = pytz.timezone('Europe/Kiev') 22 timezone = pytz.timezone('Europe/Kiev')
23 secret_key = 'JH&INH987gFDHdsagh&8dwbjdw8ckw' 23 secret_key = 'JH&INH987gFDHdsagh&8dwbjdw8ckw'
24 default_language = 'en' 24 default_language = 'en'
25 current_language = '' 25 current_language = ''
26 babel_translation_directories = '' 26 babel_translation_directories = ''
27 languages = { 27 languages = {
28 'en': 'English', 28 'en': 'English',
29 'uk': 'Українська', 29 'uk': 'Українська',
30 'pl': 'Polski' 30 'pl': 'Polski'
31 } 31 }
32 components = '' 32 components = ''
33 login_manager = LoginManager() 33 login_manager = LoginManager()
34 34
35 35
36 36
37 37
38 def __init__(self): 38 def __init__(self):
39 super().__init__() 39 super().__init__()
40 40
41 @classmethod 41 @classmethod
42 def load_babel_translation_directories(cls): 42 def load_babel_translation_directories(cls):
43 with open('languages/babel_translation_directories.yml', 'r') as f: 43 with open('languages/babel_translation_directories.yml', 'r') as f:
44 data = yaml.safe_load(f) 44 data = yaml.safe_load(f)
45 #print(data['babel_translation_directories']) 45 #print(data['babel_translation_directories'])
46 cls.babel_translation_directories = data['babel_translation_directories'] 46 cls.babel_translation_directories = data['babel_translation_directories']
47 47
48 @classmethod 48 @classmethod
49 def get_locale(cls): 49 def get_locale(cls):
50 if 'lang' in session: 50 if 'lang' in session:
51 # Отримати обрану мову з сеансу користувача 51 # Отримати обрану мову з сеансу користувача
52 return session['lang'] 52 return session['lang']
53 else: 53 else:
54 # Повернути мову за замовчуванням з налаштувань додатку 54 # Повернути мову за замовчуванням з налаштувань додатку
55 return cls.default_language #app.config['DEFAULT_LANGUAGE'] 55 return cls.default_language #app.config['DEFAULT_LANGUAGE']
56 56
57 @classmethod 57 @classmethod
58 def search_babel_translation_directories(cls): 58 def search_babel_translation_directories(cls):
59 response = requests.get(f'{cls.domain}api/languages') 59 response = requests.get(f'{cls.domain}api/languages')
60 if response.status_code == 200: 60 if response.status_code == 200:
61 cls.babel_translation_directories = response.text 61 cls.babel_translation_directories = response.text
62 data = {'babel_translation_directories': response.text} 62 data = {'babel_translation_directories': response.text}
63 else: 63 else:
64 cls.babel_translation_directories = 'languages' 64 cls.babel_translation_directories = 'languages'
65 data = {'babel_translation_directories': 'languages'} 65 data = {'babel_translation_directories': 'languages'}
66 66
67 with open('languages/babel_translation_directories.yml', 'w') as f: 67 with open('languages/babel_translation_directories.yml', 'w') as f:
68 yaml.dump(data, f) 68 yaml.dump(data, f)
69 69
70 70
71 71
72 # load database settings from yml file 72 # load database settings from yml file
73 def init_db_uri(self): 73 def init_db_uri(self):
74 with open('db/db.yml', 'r') as f: 74 with open('db/db.yml', 'r') as f:
75 db_config = yaml.load(f, Loader=yaml.FullLoader) 75 db_config = yaml.load(f, Loader=yaml.FullLoader)
76 return db_config 76 return db_config
77 77
78 # creating a connection 78 # creating a connection
79 def init_db(self, app): 79 def init_db(self, app):
80 db_config = self.init_db_uri() 80 db_config = self.init_db_uri()
81 db_uri = f"mysql+{db_config['driver']}://{db_config['user']}:{db_config['password']}@{db_config['host']}/{db_config['dbname']}" 81 db_uri = f"mysql+{db_config['driver']}://{db_config['user']}:{db_config['password']}@{db_config['host']}/{db_config['dbname']}"
82 app.config['SQLALCHEMY_DATABASE_URI'] = db_uri 82 app.config['SQLALCHEMY_DATABASE_URI'] = db_uri
83 db_path = '../db/database.db' 83 db_path = '../db/database.db'
84 app.config['SQLALCHEMY_BINDS'] = {'db2': f'sqlite:///{db_path}'} 84 app.config['SQLALCHEMY_BINDS'] = {'db2': f'sqlite:///{db_path}'}
85 self.db.init_app(app) 85 self.db.init_app(app)
86 86
87 def init_lm(self, app): 87 def init_lm(self, app):
88 # Initialize LoginManager 88 # Initialize LoginManager
89 self.login_manager.init_app(app) 89 self.login_manager.init_app(app)
90 @classmethod
91 def get_platform(cls):
92 operating_system = platform.system()
93 cls.platform = operating_system
94 return cls.platform
90 95
91 96
92 97
98
1 class k2obj: 1 class k2obj:
2 name = '' 2 name = ''
3 version = '' 3 version = ''
4 domain = '' 4 domain = ''
5 timezone = '' 5 timezone = ''
6 menu = '' 6 menu = ''
7 permissions = { 7 permissions = {
8 'r': '0', 8 'r': '0',
9 'w': '0', 9 'w': '0',
10 'i': '0', 10 'i': '0',
11 'd': '0', 11 'd': '0',
12 'c': '0', 12 'c': '0',
13 'exp': '0', 13 'exp': '0',
14 'imp': '0', 14 'imp': '0',
15 'settable': '0', 15 'settable': '0',
16 'cutpast': '0', 16 'cutpast': '0',
17 'enable': '0' 17 'enable': '0'
18 } 18 }
19 languages = '' 19 languages = ''
20 components = '' 20 components = ''
21 platform = ''
21 22
22 23
23 24
24 25
25 26
1 import zipfile 1 import zipfile
2 from flask import Flask, Blueprint, jsonify, render_template, redirect, url_for, session, jsonify 2 from flask import Flask, Blueprint, jsonify, render_template, redirect, url_for, session, jsonify
3 import os 3 import os
4 import shutil 4 import shutil
5 from flask import request 5 from flask import request
6 from .k2cfg import k2 6 from .k2cfg import k2
7 from .k2comp import Component 7 from .k2comp import Component
8 from flask_migrate import Migrate 8 from flask_migrate import Migrate
9 import requests 9 import requests
10 import subprocess 10 import subprocess
11 from flask import current_app 11 from flask import current_app
12 import yaml 12 import yaml
13 from functools import wraps 13 from functools import wraps
14 import os 14 import os
15 import sys 15 import sys
16 from .k2admmenu import K2admin_menus, K2admin_Menus_Prava 16 from .k2admmenu import K2admin_menus, K2admin_Menus_Prava
17 from sqlalchemy import text 17 from sqlalchemy import text
18 from flask_jwt_extended import get_jwt_identity, jwt_required 18 from flask_jwt_extended import get_jwt_identity, jwt_required
19 from flask_login import login_user, current_user, logout_user, login_required 19 from flask_login import login_user, current_user, logout_user, login_required
20 import platform
20 21
21 22
22 # initialize db 23 # initialize db
23 # migrate = Migrate(app, db) 24 # migrate = Migrate(app, db)
24 25
25 components_bp = Blueprint('components', __name__, template_folder='templates') 26 components_bp = Blueprint('components', __name__, template_folder='templates')
26 config = yaml.safe_load(open("db/first-login.yml")) 27 config = yaml.safe_load(open("db/first-login.yml"))
27 28
28 db = k2.db 29 db = k2.db
29 30
30 31
31 def first_login_required(view_func): 32 def first_login_required(view_func):
32 @wraps(view_func) 33 @wraps(view_func)
33 def decorated_view(*args, **kwargs): 34 def decorated_view(*args, **kwargs):
34 if 'username' not in session: 35 if 'username' not in session:
35 return redirect(url_for('components.first_login')) 36 return redirect(url_for('components.first_login'))
36 return view_func(*args, **kwargs) 37 return view_func(*args, **kwargs)
37 38
38 return decorated_view 39 return decorated_view
39 40
40 # def append_to_yaml_file(file_path, data): 41 # def append_to_yaml_file(file_path, data):
41 # with open(file_path, 'r') as f: 42 # with open(file_path, 'r') as f:
42 # existing_data = yaml.safe_load(f) or [] 43 # existing_data = yaml.safe_load(f) or []
43 # 44 #
44 # if not existing_data: 45 # if not existing_data:
45 # start_id = 1 46 # start_id = 1
46 # else: 47 # else:
47 # start_id = max(item.get('id', 0) for item in existing_data) + 1 48 # start_id = max(item.get('id', 0) for item in existing_data) + 1
48 # 49 #
49 # for i, item in enumerate(data, start=start_id): 50 # for i, item in enumerate(data, start=start_id):
50 # item['id'] = i 51 # item['id'] = i
51 # existing_data.append(item) 52 # existing_data.append(item)
52 # 53 #
53 # with open(file_path, 'w') as f: 54 # with open(file_path, 'w') as f:
54 # yaml.dump(existing_data, f, default_flow_style=False) 55 # yaml.dump(existing_data, f, default_flow_style=False)
55 56
56 def remove_from_yaml_file(file_path, component_name): 57 def remove_from_yaml_file(file_path, component_name):
57 with open(file_path, 'r') as f: 58 with open(file_path, 'r') as f:
58 existing_data = yaml.safe_load(f) or [] 59 existing_data = yaml.safe_load(f) or []
59 60
60 updated_data = [item for item in existing_data if item.get('component_name') != component_name] 61 updated_data = [item for item in existing_data if item.get('component_name') != component_name]
61 62
62 with open(file_path, 'w') as f: 63 with open(file_path, 'w') as f:
63 yaml.dump(updated_data, f, default_flow_style=False) 64 yaml.dump(updated_data, f, default_flow_style=False)
64 65
65 66
66 @components_bp.route('/api/languages', methods=['GET']) 67 @components_bp.route('/api/languages', methods=['GET'])
67 def find_language(): 68 def find_language():
68 components = Component.query.all() 69 components = Component.query.all()
69 languages_paths = [] 70 languages_paths = []
70 # Додаємо головну директорію languages 71 # Додаємо головну директорію languages
71 languages_paths.append('languages') 72 languages_paths.append('languages')
72 # Знаходимо шляхи до директорій languages всередині папки components 73 # Знаходимо шляхи до директорій languages всередині папки components
73 for component in components: 74 for component in components:
74 component_languages_directory = 'components/' + component.name + '/' + component.name + '/languages' 75 component_languages_directory = 'components/' + component.name + '/' + component.name + '/languages'
75 languages_paths.append(component_languages_directory) 76 languages_paths.append(component_languages_directory)
76 result = ';'.join(languages_paths) 77 result = ';'.join(languages_paths)
77 print(result) 78 print(result)
78 return result 79 return result
79 80
80 81
81 @components_bp.route('/', methods=['GET', 'POST']) 82 @components_bp.route('/', methods=['GET', 'POST'])
82 def home(): 83 def home():
83 components = Component.query.all() 84 components = Component.query.all()
84 components_names = [component.name for component in components] 85 components_names = [component.name for component in components]
85 if 'k2site' in components_names: 86 if 'k2site' in components_names:
86 return redirect(url_for('k2site.new_component2')) #змінити на ендпоінт головної k2site 87 return redirect(url_for('components.component_add_dasb')) #змінити на ендпоінт головної k2site
87 else: 88 else:
88 return redirect('/dashboard') 89 return redirect('/dashboard')
89 90
90 91
91 92
92 @components_bp.route('/first-login', methods=['GET', 'POST']) 93 @components_bp.route('/first-login', methods=['GET', 'POST'])
93 def first_login(): 94 def first_login():
94 if request.method == "POST": 95 if request.method == "POST":
95 username = request.form.get("username") 96 username = request.form.get("username")
96 password = request.form.get("password") 97 password = request.form.get("password")
97 for user in config["users"]: 98 for user in config["users"]:
98 if user["username"] == username and user["password"] == password: 99 if user["username"] == username and user["password"] == password:
99 session['username'] = username # Збереження ім'я користувача в сесії 100 session['username'] = username # Збереження ім'я користувача в сесії
100 return redirect(url_for('components.dashboard')) 101 return redirect(url_for('components.dashboard'))
101 return "Невірне ім'я користувача або пароль." 102 return "Невірне ім'я користувача або пароль."
102 return render_template('first-login.html') 103 return render_template('first-login.html')
103 104
104 105
105 @components_bp.route('/change_language/<lang>') 106 @components_bp.route('/change_language/<lang>')
106 def change_language(lang): 107 def change_language(lang):
107 session['lang'] = lang 108 session['lang'] = lang
108 k2.current_language = lang 109 k2.current_language = lang
109 return redirect(request.referrer) 110 return redirect(request.referrer)
110 111
111 112
112 @components_bp.route('/dashboard') 113 @components_bp.route('/dashboard')
113 def dashboard(): 114 def dashboard():
114 components = Component.query.all() 115 components = Component.query.all()
115 components_names = [] 116 components_names = []
116 components_names = [component.name for component in components] 117 components_names = [component.name for component in components]
117 if 'k2site' in components_names: 118 if 'k2site' in components_names:
118 return redirect(url_for('components.component_list_dasb')) # змінити на ендпоінт головної k2site 119 return redirect(url_for('components.home'))
119 else: 120 else:
120 # Компоненти доступні для встановлення 121 # Компоненти доступні для встановлення
121 # GET-запит до API 122 # GET-запит до API
122 try: 123 try:
123 response = requests.get(f'{k2.update_domain}api/components') 124 response = requests.get(f'{k2.update_domain}api/components')
124 json_data = response.json() 125 json_data = response.json()
125 # Перетворення JSON-об'єкту на масив 126 # Перетворення JSON-об'єкту на масив
126 component_server = [item for item in json_data] 127 component_server = [item for item in json_data]
127 except: 128 except:
128 component_server = None 129 component_server = None
129 130
130 # Встановлені компоненти 131 # Встановлені компоненти
131 components = Component.query.all() 132 components = Component.query.all()
132 components_names = [component.name for component in components] 133 components_names = [component.name for component in components]
133 # Отримання значення пошукового запиту з параметрів URL 134 # Отримання значення пошукового запиту з параметрів URL
134 search_query = request.args.get('search_query') 135 search_query = request.args.get('search_query')
135 # print(search_query) 136 # print(search_query)
136 filtered_components = [] 137 filtered_components = []
137 if search_query: 138 if search_query:
138 filtered_components = [component for component in component_server if 139 filtered_components = [component for component in component_server if
139 (search_query.lower() in component['name'].lower() if component['name'] else False) or 140 (search_query.lower() in component['name'].lower() if component['name'] else False) or
140 (search_query.lower() in component['description'].lower() if component[ 141 (search_query.lower() in component['description'].lower() if component[
141 'description'] else False)] 142 'description'] else False)]
142 else: 143 else:
143 filtered_components = component_server 144 filtered_components = component_server
144 current_language = k2.current_language 145 current_language = k2.current_language
145 146
146 return render_template('dashboard.html', components=components, 147 return render_template('dashboard.html', components=components,
147 components_names=components_names, component_server=filtered_components, 148 components_names=components_names, component_server=filtered_components,
148 search_query=search_query, language=current_language) 149 search_query=search_query, language=current_language)
149 150
150 151
151 @components_bp.route('/show_components/<string:component_id>') 152 @components_bp.route('/show_components/<string:component_id>')
152 def show_components(component_id): 153 def show_components(component_id):
153 response = requests.get(f'{k2.update_domain}api/components') 154 response = requests.get(f'{k2.update_domain}api/components')
154 json_data = response.json() 155 json_data = response.json()
155 selected_component = next((component for component in json_data if component['id'] == component_id), None) 156 selected_component = next((component for component in json_data if component['id'] == component_id), None)
156 return render_template('component-info.html', selected_component=selected_component) 157 return render_template('component-info.html', selected_component=selected_component)
157 158
158 159
159 @components_bp.route('/show_components-site/<string:component_id>') 160 @components_bp.route('/show_components-site/<string:component_id>')
160 def show_components_site(component_id): 161 def show_components_site(component_id):
161 response = requests.get(f'{k2.update_domain}api/components') 162 response = requests.get(f'{k2.update_domain}api/components')
162 json_data = response.json() 163 json_data = response.json()
163 selected_component = next((component for component in json_data if component['id'] == component_id), None) 164 selected_component = next((component for component in json_data if component['id'] == component_id), None)
164 return render_template('component-info-site.html', selected_component=selected_component) 165 return render_template('component-info-site.html', selected_component=selected_component)
165 166
166 167
167 @components_bp.route('/install_components_git/<string:component_id>') 168 @components_bp.route('/install_components_git/<string:component_id>')
168 def install_components_git(component_id): 169 def install_components_git(component_id):
169 # Шлях до головної папки проекту 170 # Шлях до головної папки проекту
170 project_folder = 'components' 171 project_folder = 'components'
171 # component = Component.get_repository_by_id(component_id) 172 # component = Component.get_repository_by_id(component_id)
172 response = requests.get(f'{k2.update_domain}api/components') 173 response = requests.get(f'{k2.update_domain}api/components')
173 json_data = response.json() 174 json_data = response.json()
174 selected_component = next((component for component in json_data if component['id'] == component_id), None) 175 selected_component = next((component for component in json_data if component['id'] == component_id), None)
175 # Назва репозиторія 176 # Назва репозиторія
176 repository_name = selected_component['name'] 177 repository_name = selected_component['name']
177 # Шлях до папки репозиторія в межах проекту 178 # Шлях до папки репозиторія в межах проекту
178 repository_folder = os.path.join(project_folder, repository_name) 179 repository_folder = os.path.join(project_folder, repository_name)
179 # URL репозиторія 180 # URL репозиторія
180 181
181 git_repo_url = selected_component['git_link'] 182 git_repo_url = selected_component['git_link']
182 try: 183 try:
183 # Перевірка наявності папки репозиторія 184 # Перевірка наявності папки репозиторія
184 if not os.path.exists(repository_folder): 185 if not os.path.exists(repository_folder):
185 # Створення папки репозиторія 186 # Створення папки репозиторія
186 os.makedirs(repository_folder) 187 os.makedirs(repository_folder)
187 # Шлях до файлу __init__.py 188 # Шлях до файлу __init__.py
188 init_file = os.path.join(repository_folder, '__init__.py') 189 init_file = os.path.join(repository_folder, '__init__.py')
189 # Перевірка наявності файлу __init__.py 190 # Перевірка наявності файлу __init__.py
190 if not os.path.exists(init_file): 191 if not os.path.exists(init_file):
191 # Створення пустого файлу __init__.py 192 # Створення пустого файлу __init__.py
192 open(init_file, 'a').close() 193 open(init_file, 'a').close()
193 # підключення до приватного репозиторію 194 # підключення до приватного репозиторію
194 # os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW' 195 # os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW'
195 # git_repo_url_with_token = git_repo_url.replace('https://', 196 # git_repo_url_with_token = git_repo_url.replace('https://',
196 # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@') 197 # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@')
197 198
198 # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія 199 # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія
199 command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url, 200 command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url,
200 '--target=' + repository_folder] 201 '--target=' + repository_folder]
201 # Виконуємо команду встановлення 202 # Виконуємо команду встановлення
202 subprocess.check_call(command) 203 subprocess.check_call(command)
203 204
204 # Шлях до файлу, до якого потрібно додати код 205 # Шлях до файлу, до якого потрібно додати код
205 file_path = 'routes.py' 206 file_path = 'routes.py'
206 # Код, який потрібно додати 207 # Код, який потрібно додати
207 code = selected_component['dependencies'] 208 code = selected_component['dependencies']
208 # Відкриття файлу у режимі дозапису 209 # Відкриття файлу у режимі дозапису
209 with open(file_path, 'a') as file: 210 with open(file_path, 'a') as file:
210 # Запис нового коду у файл 211 # Запис нового коду у файл
211 file.write('\n') 212 file.write('\n')
212 file.write(code) 213 file.write(code)
213 file.write('\n') 214 file.write('\n')
214 component = Component.query.filter_by(name=selected_component['name']).first() 215 component = Component.query.filter_by(name=selected_component['name']).first()
215 if not component: 216 if not component:
216 new_component = Component( 217 new_component = Component(
217 name=selected_component['name'], 218 name=selected_component['name'],
218 description=selected_component['description'], 219 description=selected_component['description'],
219 version=selected_component['version'], 220 version=selected_component['version'],
220 git_link=selected_component['git_link'], 221 git_link=selected_component['git_link'],
221 dependencies=selected_component['dependencies'], 222 dependencies=selected_component['dependencies'],
222 installed=True 223 installed=True
223 ) 224 )
224 # Add the new component to the database 225 # Add the new component to the database
225 db.session.add(new_component) 226 db.session.add(new_component)
226 db.session.commit() 227 db.session.commit()
227 228
228 # Повертаємо повідомлення про успішне встановлення 229 # Повертаємо повідомлення про успішне встановлення
229 return f'Installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 230 return f'Installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
230 except subprocess.CalledProcessError as e: 231 except subprocess.CalledProcessError as e:
231 return 'Error installing : ' + str(e) 232 return 'Error installing : ' + str(e)
232 233
233 234
234 @components_bp.route('/install_components/<string:component_id>') 235 @components_bp.route('/install_components/<string:component_id>')
235 def install_component_from_archive(component_id): 236 def install_component_from_archive(component_id):
236 # Шлях до головної папки проекту 237 # Шлях до головної папки проекту
237 project_folder = 'components' 238 project_folder = 'components'
238 # Отримати відповідну компоненту зі списку компонент 239 # Отримати відповідну компоненту зі списку компонент
239 response = requests.get(f'{k2.update_domain}api/components') 240 response = requests.get(f'{k2.update_domain}api/components')
240 json_data = response.json() 241 json_data = response.json()
241 selected_component = next((component for component in json_data if component['id'] == component_id), None) 242 selected_component = next((component for component in json_data if component['id'] == component_id), None)
242 if selected_component is None: 243 if selected_component is None:
243 return 'Component not found' 244 return 'Component not found'
244 # Отримати посилання на архів компоненти та версію 245 # Отримати посилання на архів компоненти та версію
245 archive_url = selected_component['latest_component_data'] 246 archive_url = selected_component['latest_component_data']
246 version = selected_component['latest_version'] 247 version = selected_component['latest_version']
247 try: 248 try:
248 # Створити шлях до папки компоненти згідно назви та версії 249 # Створити шлях до папки компоненти згідно назви та версії
249 component_folder = os.path.join(project_folder) 250 component_folder = os.path.join(project_folder)
250 os.makedirs(component_folder, exist_ok=True) 251 os.makedirs(component_folder, exist_ok=True)
251 # Завантажити архів компоненти 252 # Завантажити архів компоненти
252 response = requests.get(archive_url, stream=True) 253 response = requests.get(archive_url, stream=True)
253 response.raise_for_status() 254 response.raise_for_status()
254 # Шлях до завантаженого архіву 255 # Шлях до завантаженого архіву
255 archive_path = os.path.join(component_folder, f"{selected_component['name']}.zip") 256 archive_path = os.path.join(component_folder, f"{selected_component['name']}.zip")
256 # Зберегти архів на диск 257 # Зберегти архів на диск
257 with open(archive_path, "wb") as file: 258 with open(archive_path, "wb") as file:
258 for chunk in response.iter_content(chunk_size=8192): 259 for chunk in response.iter_content(chunk_size=8192):
259 file.write(chunk) 260 file.write(chunk)
260 # Розпакувати архів 261 # Розпакувати архів
261 with zipfile.ZipFile(archive_path, "r") as zip_ref: 262 with zipfile.ZipFile(archive_path, "r") as zip_ref:
262 zip_ref.extractall(component_folder) 263 zip_ref.extractall(component_folder)
263 # Видалити архів 264 # Видалити архів
264 os.remove(archive_path) 265 os.remove(archive_path)
265 #перейменувати якщо git 266 #перейменувати якщо git
266 component_name = selected_component['name'] 267 component_name = selected_component['name']
267 old_folder_path = os.path.join(component_folder, component_name + ".git") 268 old_folder_path = os.path.join(component_folder, component_name + ".git")
268 new_folder_path = os.path.join(component_folder, component_name) 269 new_folder_path = os.path.join(component_folder, component_name)
269 # Перевірка наявності папки зі старою назвою 270 # Перевірка наявності папки зі старою назвою
270 if os.path.exists(old_folder_path) and os.path.isdir(old_folder_path): 271 if os.path.exists(old_folder_path) and os.path.isdir(old_folder_path):
271 # Перейменування папки зі старою назвою на нову назву 272 # Перейменування папки зі старою назвою на нову назву
272 os.rename(old_folder_path, new_folder_path) 273 os.rename(old_folder_path, new_folder_path)
273 274
274 # Шлях до файлу, до якого потрібно додати роути 275 # Шлях до файлу, до якого потрібно додати роути
275 file_path = 'routes.py' 276 file_path = 'routes.py'
276 # Код, який потрібно додати 277 # Код, який потрібно додати
277 if component_name == 'k2grid_base': 278 if component_name == 'k2grid_base':
278 code = f'''from components.{selected_component['name']}.{selected_component['name']}.views import {selected_component['name']}\napp.register_blueprint({selected_component['name']}, url_prefix='/')''' 279 code = f'''from components.{selected_component['name']}.{selected_component['name']}.views import {selected_component['name']}\napp.register_blueprint({selected_component['name']}, url_prefix='/')'''
279 elif component_name == 'k2site': 280 elif component_name == 'k2site':
280 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']}')\nlogin_manager = k2().init_lm(app)''' 281 code = f'''login_manager = k2().init_lm(app)\nfrom components.{selected_component['name']}.{selected_component['name']}.views import {selected_component['name']}\napp.register_blueprint({selected_component['name']}, url_prefix='/{selected_component['name']}')'''
281 else: 282 else:
282 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']}')''' 283 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']}')'''
283 284
284 285
285 286
286 # Відкриття файлу у режимі дозапису 287 # Відкриття файлу у режимі дозапису
287 with open(file_path, 'a') as file: 288 with open(file_path, 'a') as file:
288 # Запис нового коду у файл 289 # Запис нового коду у файл
289 file.write('\n') 290 file.write('\n')
290 file.write(code) 291 file.write(code)
291 file.write('\n') 292 file.write('\n')
292 293
293 # Update database with the installed component 294 # Update database with the installed component
294 component = Component.query.filter_by(name=selected_component['name']).first() 295 component = Component.query.filter_by(name=selected_component['name']).first()
295 if not component: 296 if not component:
296 component = Component( 297 component = Component(
297 name=selected_component['name'], 298 name=selected_component['name'],
298 description=selected_component['description'], 299 description=selected_component['description'],
299 version=version, 300 version=version,
300 git_link=selected_component['git_link'], 301 git_link=selected_component['git_link'],
301 dependencies=code, 302 dependencies=code,
302 installed=True 303 installed=True
303 ) 304 )
304 db.session.add(component) 305 db.session.add(component)
305 else: 306 else:
306 component.version = version 307 component.version = version
307 component.git_link = selected_component['git_link'] 308 component.git_link = selected_component['git_link']
308 component.dependencies = code 309 component.dependencies = code
309 component.installed = True 310 component.installed = True
310 311
311 db.session.commit() 312 db.session.commit()
312 313
313 # add language folders 314 # add language folders
314 k2.search_babel_translation_directories() 315 k2.search_babel_translation_directories()
315 return f'''Component installed successfully: {selected_component["name"]} v{version} {k2.babel_translation_directories}, 316 return f'''Component installed successfully: {selected_component["name"]} v{version} {k2.babel_translation_directories},
316 \n \n please wait installing requirments... 317 \n \n please wait installing requirments...
317 <meta http-equiv="refresh" content="0;url=/install-requirments/{selected_component["name"]}" />''' 318 <meta http-equiv="refresh" content="0;url=/install-requirments/{selected_component["name"]}" />'''
318 319
319 except Exception as e: 320 except Exception as e:
320 return f'Error installing component: {str(e)}' 321 return f'Error installing component: {str(e)}'
321 322
322 323
323 @components_bp.route('/install-requirments/<string:selected_component_name>', methods=['GET']) 324 @components_bp.route('/install-requirments/<string:selected_component_name>', methods=['GET'])
324 def install_requirments(selected_component_name): 325 def install_requirments(selected_component_name):
325 # menu items
326 get_admin_menu()
327 326
327 try:
328 if k2.platform == 'Windows':
329 # install requirements for windows
330 venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/Scripts')
331 requirements_file = os.path.join('components', selected_component_name, "requirements.txt")
332 if os.path.isfile(requirements_file):
333 pip_command = f"{venv_bin_path}/python -m pip install -r {requirements_file}"
334 subprocess.run(pip_command, shell=True, check=True)
335 elif k2.platform == 'Linux':
336 #install requirements for linux
337 venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/bin')
338 requirements_file = os.path.join('components', selected_component_name, "requirements.txt")
339 if os.path.isfile(requirements_file):
340 pip_command = f"{venv_bin_path}/python3 -m pip install -r {requirements_file}"
341 subprocess.run(pip_command, shell=True, check=True)
328 342
329 ## install requirements for windows 343 return f'''Requirements installed successfully
330 #venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/Scripts') 344 \n \n please wait installing requirments components...
331 #requirements_file = os.path.join('components', selected_component_name, "requirements.txt") 345 <meta http-equiv="refresh" content="1;url=/install-requirments-components" />'''
332 #if os.path.isfile(requirements_file): 346 except Exception as e:
333 # pip_command = f"{venv_bin_path}/python -m pip install -r {requirements_file}" 347 return f'Error installing requirmets: {str(e)}'
334 # subprocess.run(pip_command, shell=True, check=True)
335 348
336 #install requirements for linux
337 venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/bin')
338 requirements_file = os.path.join('components', selected_component_name, "requirements.txt")
339 if os.path.isfile(requirements_file):
340 pip_command = f"{venv_bin_path}/python3 -m pip install -r {requirements_file}"
341 subprocess.run(pip_command, shell=True, check=True)
342
343 return f'''Requirements installed successfully
344 \n \n please wait installing requirments components...
345 <meta http-equiv="refresh" content="1;url=/install-requirments-components" />'''
346
347
348 @components_bp.route('/install-requirments-components') 349 @components_bp.route('/install-requirments-components')
349 def install_requirements_components(): 350 def install_requirements_components():
350 # Откриття файлу requirements_components.txt 351 # Откриття файлу requirements_components.txt
351 requirements_file = 'requirements_components.txt' 352 requirements_file = 'requirements_components.txt'
352 component_ids = None 353 component_ids = None
353 if os.path.isfile(requirements_file): 354 if os.path.isfile(requirements_file):
354 with open('requirements_components.txt', 'r') as file: 355 with open('requirements_components.txt', 'r') as file:
355 component_ids = file.read().splitlines() 356 component_ids = file.read().splitlines()
356 if component_ids: 357 if component_ids:
357 for component_id in component_ids: 358 for component_id in component_ids:
358 # Виклик роуту '/install_components/<string:component_name>' для кожної назви компоненти 359 # Виклик роуту '/install_components/<string:component_name>' для кожної назви компоненти
359 response = requests.get( 360 response = requests.get(
360 f'/install_components/{component_id}') 361 f'/install_components/{component_id}')
361 return f'Requirements components installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 362 return f'Requirements components installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
362 else: 363 else:
363 return f'<meta http-equiv="refresh" content="1;url=/dashboard" />' 364 return f'<meta http-equiv="refresh" content="1;url=/dashboard" />'
364 # Опрацювання відповіді (за потреби) 365 # Опрацювання відповіді (за потреби)
365 366
366 367
367 @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET']) 368 @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET'])
368 def remove_dependencies(component_id): 369 def remove_dependencies(component_id):
369 # Знаходимо компоненту за її ID 370 # Знаходимо компоненту за її ID
370 component = Component.query.get(component_id) 371 component = Component.query.get(component_id)
371 if not component: 372 if not component:
372 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />' 373 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />'
373 # remove menu items 374 # remove menu items
374 component_name = component.name 375 component_name = component.name
375 # file_path = "components/menu.yml" 376 # file_path = "components/menu.yml"
376 # remove_from_yaml_file(file_path, component_name) 377 # remove_from_yaml_file(file_path, component_name)
377 requests.get(f"{k2.domain}api/add-to-menu") 378 requests.get(f"{k2.domain}api/add-to-menu")
378 # remove routes 379 # remove routes
379 file_path = 'routes.py' 380 file_path = 'routes.py'
380 with open(file_path, 'r') as file: 381 with open(file_path, 'r') as file:
381 lines = file.readlines() 382 lines = file.readlines()
382 383
383 updated_lines = [line for line in lines if line.strip() not in component.dependencies] 384 updated_lines = [line for line in lines if line.strip() not in component.dependencies]
384 with open(file_path, 'w') as file: 385 with open(file_path, 'w') as file:
385 file.writelines(updated_lines) 386 file.writelines(updated_lines)
386 387
387 component.installed = False 388 component.installed = False
388 db.session.commit() 389 db.session.commit()
389 response = requests.get(f"{k2.domain}/k2site/new_component2") 390
390 return 'Component successfully turn off <meta http-equiv="refresh" content="1;url=/dashboard" />' 391 return 'Component successfully turn off <meta http-equiv="refresh" content="1;url=/dashboard" />'
391 392
392 393
393 @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET']) 394 @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET'])
394 def add_dependencies(component_id): 395 def add_dependencies(component_id):
395 # Знаходимо компоненту за її ID 396 # Знаходимо компоненту за її ID
396 component = Component.query.get(component_id) 397 component = Component.query.get(component_id)
397 if not component: 398 if not component:
398 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />' 399 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />'
399 400
400 file_path = 'routes.py' 401 file_path = 'routes.py'
401 code = component.dependencies 402 code = component.dependencies
402 # Відкриття файлу у режимі дозапису 403 # Відкриття файлу у режимі дозапису
403 with open(file_path, 'a') as file: 404 with open(file_path, 'a') as file:
404 # Запис нового коду у файл 405 # Запис нового коду у файл
405 file.write(code) 406 file.write(code)
406 407
407 # Оновлюємо статус компоненти 408 # Оновлюємо статус компоненти
408 component.installed = True 409 component.installed = True
409 db.session.commit() 410 db.session.commit()
410 response = requests.get(f"{k2.domain}/k2site/new_component2") 411
411 return 'Dependencies added successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 412 return 'Dependencies added successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
412 413
413 414
414 @components_bp.route('/remove-component/<string:component_id>') 415 @components_bp.route('/remove-component/<string:component_id>')
415 def remove_component(component_id): 416 def remove_component(component_id):
416 # Шлях до головної папки проекту 417 # Шлях до головної папки проекту
417 project_folder = 'components' 418 project_folder = 'components'
418 component = Component.query.get(component_id) 419 component = Component.query.get(component_id)
419 # Назва репозиторія 420 # Назва репозиторія
420 repository_name = component.name 421 repository_name = component.name
421 # Шлях до папки репозиторія в межах проекту 422 # Шлях до папки репозиторія в межах проекту
422 repository_folder = os.path.join(project_folder, repository_name) 423 repository_folder = os.path.join(project_folder, repository_name)
423 try: 424 try:
424 # Перевірка наявності папки репозиторія 425 # Перевірка наявності папки репозиторія
425 if os.path.exists(repository_folder): 426 if os.path.exists(repository_folder):
426 # Видалення папки репозиторія 427 # Видалення папки репозиторія
427 shutil.rmtree(repository_folder) 428 shutil.rmtree(repository_folder)
428 # Видаляємо компоненту з бази 429 # Видаляємо компоненту з бази
429 if component: 430 if component:
430 db.session.delete(component) 431 db.session.delete(component)
431 db.session.commit() 432 db.session.commit()
432 433
433 # Повертаємо повідомлення про успішне видалення 434 # Повертаємо повідомлення про успішне видалення
434 return 'Component removed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 435 return 'Component removed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
435 except Exception as e: 436 except Exception as e:
436 # Повертаємо повідомлення про помилку видалення 437 # Повертаємо повідомлення про помилку видалення
437 return 'Error removing component: ' + str(e) 438 return 'Error removing component: ' + str(e)
438 response = requests.get(f"{k2.domain}/k2site/new_component2") 439
439 440
440 441
441 # @components_bp.route('/component/add') 442 # @components_bp.route('/component/add')
442 # def component_add(): 443 # def component_add():
443 # # components for install 444 # # components for install
444 # try: 445 # try:
445 # # GET-requests to API 446 # # GET-requests to API
446 # response = requests.get(f'{k2.update_domain}api/components') 447 # response = requests.get(f'{k2.update_domain}api/components')
447 # json_data = response.json() 448 # json_data = response.json()
448 # for item in json_data: 449 # for item in json_data:
449 # item['button'] = f"{k2.domain}/install_components/{item['id']}" 450 # item['button'] = f"{k2.domain}/install_components/{item['id']}"
450 # 451 #
451 # except: 452 # except:
452 # json_data = None 453 # json_data = None
453 # return jsonify(json_data) 454 # return jsonify(json_data)
454 # 455 #
455 # 456 #
456 # @components_bp.route('/component/list') 457 # @components_bp.route('/component/list')
457 # def component_list(): 458 # def component_list():
458 # # Встановлені компоненти 459 # # Встановлені компоненти
459 # component_list = [] 460 # component_list = []
460 # components = Component.query.all() 461 # components = Component.query.all()
461 # for component in components: 462 # for component in components:
462 # component_dict = {} 463 # component_dict = {}
463 # component_dict['name'] = component.name 464 # component_dict['name'] = component.name
464 # component_dict['id'] = component.id 465 # component_dict['id'] = component.id
465 # component_dict['description'] = component.description 466 # component_dict['description'] = component.description
466 # component_dict['version'] = component.version 467 # component_dict['version'] = component.version
467 # component_dict['button_off'] =f"{k2.domain}/remove_dependencies/{component.id}" 468 # component_dict['button_off'] =f"{k2.domain}/remove_dependencies/{component.id}"
468 # component_dict['button_on'] = f"{k2.domain}/add_dependencies/{component.id}" 469 # component_dict['button_on'] = f"{k2.domain}/add_dependencies/{component.id}"
469 # component_dict['button_del'] = f"{k2.domain}/remove-component/{component.id}" 470 # component_dict['button_del'] = f"{k2.domain}/remove-component/{component.id}"
470 # component_list.append(component_dict) 471 # component_list.append(component_dict)
471 # return jsonify(component_list) 472 # return jsonify(component_list)
472 473
473 474
474 # menu 475 # menu
475 @components_bp.route('/api/add-to-menu', methods=['GET']) 476 @components_bp.route('/api/add-to-menu', methods=['GET'])
476 def add_to_menu(): 477 def add_to_menu():
477 data = [] 478 data = []
478 response = requests.get(f"{k2.domain}/menu-admin-items") 479 response = requests.get(f"{k2.domain}/menu-admin-items")
479 data.append(response.json()[0]) 480 data.append(response.json()[0])
480 prev_menu = response.json()[0]['title'] 481 prev_menu = response.json()[0]['title']
481 for item in response.json()[0]['children']: 482 for item in response.json()[0]['children']:
482 name_menu = 'k2itm'+ item['to'].replace('/','-') 483 name_menu = 'k2itm'+ item['to'].replace('/','-')
483 caption_menu = item['title'] 484 caption_menu = item['title']
484 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu) 485 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu)
485 components = Component.query.all() 486 components = Component.query.all()
486 components_names = [component.name for component in components] 487 components_names = [component.name for component in components]
487 for components_names in components_names: 488 for components_names in components_names:
488 response = requests.get(f"{k2.domain}{components_names}/menu-admin-items") 489 response = requests.get(f"{k2.domain}{components_names}/menu-admin-items")
489 if response.status_code == 200: 490 if response.status_code == 200:
490 data.append(response.json()[0]) 491 data.append(response.json()[0])
491 #prev_menu = 492 #prev_menu =
492 prev_menu = response.json()[0]['title'] 493 prev_menu = response.json()[0]['title']
493 for item in response.json()[0]['children']: 494 for item in response.json()[0]['children']:
494 name_menu = 'k2itm'+ item['to'].replace('/','-') 495 name_menu = 'k2itm'+ item['to'].replace('/','-')
495 caption_menu = item['title'] 496 caption_menu = item['title']
496 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu) 497 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu)
497 else: 498 else:
498 continue 499 continue
499 # add component_name key for menu items 500 # add component_name key for menu items
500 #for item in data: 501 #for item in data:
501 # item['component_name'] = components_names 502 # item['component_name'] = components_names
502 #k2.menu = data 503 #k2.menu = data
503 return data 504 return data
504 505
505 506
506 507
507 508
508 @components_bp.route('/api/main-menu/') 509 @components_bp.route('/api/main-menu/')
509 @login_required 510 @login_required
510 def get_admin_menu(): 511 def get_admin_menu():
511 components = Component.query.all() 512 components = Component.query.all()
512 components_names = [component.name for component in components] 513 components_names = [component.name for component in components]
513 if 'k2site' in components_names: 514 if 'k2site' in components_names:
514 role_id = current_user.get_role_id() 515 role_id = current_user.get_role_id()
515 filter_menu = [] 516 filter_menu = []
516 response = requests.get(f"{k2.domain}api/add-to-menu") 517 response = requests.get(f"{k2.domain}api/add-to-menu")
517 menu_items_list = K2admin_menus.get_menu_items_by_roles(role_id) 518 menu_items_list = K2admin_menus.get_menu_items_by_roles(role_id)
518 #print(menu_items_list)
519 for item in response.json(): 519 for item in response.json():
520 filtered_children = [] 520 filtered_children = []
521 for im in item['children']: 521 for im in item['children']:
522 if 'k2itm' + im['to'].replace('/','-') in menu_items_list: 522 if 'k2itm' + im['to'].replace('/','-') in menu_items_list:
523 filtered_children.append(im) 523 filtered_children.append(im)
524 if filtered_children: 524 if filtered_children:
525 item['children'] = filtered_children 525 item['children'] = filtered_children
526 filter_menu.append(item) 526 filter_menu.append(item)
527 # filter_menu.append({"heading": 'APPS & PAGES'}) 527 # filter_menu.append({"heading": 'APPS & PAGES'})
528 return jsonify(filter_menu) 528 return jsonify(filter_menu)
529 529
530 530
531 def add_menu_with_permissions_db(name_menu, prev_menu, caption_menu): 531 def add_menu_with_permissions_db(name_menu, prev_menu, caption_menu):
532 532
533 # Створення об'єкта k2admin_menus 533 # Створення об'єкта k2admin_menus
534 menu = text('SELECT COUNT(*) FROM k2admin_menus WHERE namemenu = :name_menu') 534 menu = text('SELECT COUNT(*) FROM k2admin_menus WHERE namemenu = :name_menu')
535 result = db.session.execute(menu, {'name_menu': name_menu}).fetchone() 535 result = db.session.execute(menu, {'name_menu': name_menu}).fetchone()
536 count = result[0] 536 count = result[0]
537 if count == 0: 537 if count == 0:
538 new_menu_element = K2admin_menus( 538 new_menu_element = K2admin_menus(
539 namemenu=name_menu, 539 namemenu=name_menu,
540 prevmenu=prev_menu, 540 prevmenu=prev_menu,
541 caption=caption_menu, 541 caption=caption_menu,
542 module_name=name_menu 542 module_name=name_menu
543 ) 543 )
544 db.session.add(new_menu_element) 544 db.session.add(new_menu_element)
545 db.session.commit() 545 db.session.commit()
546 # Створення об'єкта k2admin_menus_prava 546 # Створення об'єкта k2admin_menus_prava
547 new_prava = K2admin_Menus_Prava( 547 new_prava = K2admin_Menus_Prava(
548 menuid=new_menu_element.menuid, # Зв'язуємо зовнішній ключ з menuid нового меню 548 menuid=new_menu_element.menuid, # Зв'язуємо зовнішній ключ з menuid нового меню
549 username=None, 549 username=None,
550 r=0, 550 r=0,
551 w=0, 551 w=0,
552 i=0, 552 i=0,
553 d=0, 553 d=0,
554 c=0, 554 c=0,
555 exp=0, 555 exp=0,
556 imp=0, 556 imp=0,
557 settable=0, 557 settable=0,
558 cutpast=0, 558 cutpast=0,
559 enable=0, 559 enable=0,
560 roleid=-1 560 roleid=-1
561 ) 561 )
562 # Додавання об'єкта k2admin_menus_prava до сесії 562 # Додавання об'єкта k2admin_menus_prava до сесії
563 db.session.add(new_prava) 563 db.session.add(new_prava)
564 db.session.commit() 564 db.session.commit()
565 565
566 @components_bp.route('/component-add') 566 @components_bp.route('/component-add')
567 @login_required 567 @login_required
568 def component_add_dasb(): 568 def component_add_dasb():
569 try: 569 try:
570 response = requests.get(f'{k2.update_domain}api/components') 570 response = requests.get(f'{k2.update_domain}api/components')
571 json_data = response.json() 571 json_data = response.json()
572 # Перетворення JSON-об'єкту на масив 572 # Перетворення JSON-об'єкту на масив
573 component_server = [item for item in json_data] 573 component_server = [item for item in json_data]
574 except: 574 except:
575 component_server = None 575 component_server = None
576 # Отримання значення пошукового запиту з параметрів URL 576 # Отримання значення пошукового запиту з параметрів URL
577 search_query = request.args.get('search_query') 577 search_query = request.args.get('search_query')
578 # print(search_query) 578 # print(search_query)
579 filtered_components = [] 579 filtered_components = []
580 if search_query: 580 if search_query:
581 filtered_components = [component for component in component_server if 581 filtered_components = [component for component in component_server if
582 (search_query.lower() in component['name'].lower() if component[ 582 (search_query.lower() in component['name'].lower() if component[
583 'name'] else False) or 583 'name'] else False) or
584 (search_query.lower() in component['description'].lower() if component[ 584 (search_query.lower() in component['description'].lower() if component[
585 'description'] else False)] 585 'description'] else False)]
586 else: 586 else:
587 filtered_components = component_server 587 filtered_components = component_server
588 components = Component.query.all() 588 components = Component.query.all()
589 components_names = [component.name for component in components] 589 components_names = [component.name for component in components]
590 components_version = [{component.name: component.version} for component in components]
590 591
591 return render_template('dashboard-add.html', 592 return render_template('dashboard-add.html',
592 component_server=filtered_components, search_query=search_query, components_names=components_names ) 593 component_server=filtered_components, search_query=search_query, components_names=components_names, components_version=components_version )
593 594
594 595
595 596
596 @components_bp.route('/component-list') 597 @components_bp.route('/component-list')
597 @login_required 598 @login_required
598 def component_list_dasb(): 599 def component_list_dasb():
599 components = Component.query.all() 600 components = Component.query.all()
600 601
601 return render_template('dashboard-list.html', components=components) 602 return render_template('dashboard-list.html', components=components)
602 603
603 604
604 605
605 606
606 @components_bp.route('/menu-admin-items') 607 @components_bp.route('/menu-admin-items')
607 def menu_items(): 608 def menu_items():
608 menu = [ 609 menu = [
609 { 610 {
610 "title": 'Add components', 611 "title": 'Add components',
languages/babel_translation_directories.yml
1 babel_translation_directories: languages;components/k2site/k2site/languages;components/k2adm/k2adm/languages;components/k2test/k2test/languages;components/k2grid_base/k2grid_base/languages 1 babel_translation_directories: languages;components/k2site/k2site/languages;components/k2test/k2test/languages
2 2
1 #app = Flask(__name__) 1 #app = Flask(__name__)
2 from app import app 2 from app import app
3 from k2.k2rout import components_bp 3 from k2.k2rout import components_bp
4 from k2.k2cfg import k2 4 from k2.k2cfg import k2
5 app.register_blueprint(components_bp) 5 app.register_blueprint(components_bp)
6 #k2grid_base 6 #k2grid_base
7 from components.k2test.k2test.views import k2test
8 app.register_blueprint(k2test, url_prefix='/k2test')
7 9
static/css/style.css
1 .btn 1 .btn
2 { 2 {
3 width: 100px; 3 width: 100px;
4 } 4 }
5 5
6 6
7 img.logo { 7 img.logo {
8 8
9 padding-left: 20%; 9 padding-left: 20%;
10 } 10 }
11 a.btn.btn-primary.btn-lg.px-4.me-sm-3 { 11 a.btn.btn-primary.btn-lg.px-4.me-sm-3 {
12 width: 300px; 12 width: 300px;
13 } 13 }
14 14
15 a.btn.btn-primary { 15 a.btn.btn-primary {
16 margin-bottom: 2px; 16 margin-bottom: 2px;
17 } 17 }
18 18
19 #popupBackdrop { 19 #popupBackdrop {
20 position: fixed; 20 position: fixed;
21 top: 0; 21 top: 0;
22 left: 0; 22 left: 0;
23 width: 100%; 23 width: 100%;
24 height: 100%; 24 height: 100%;
25 background-color: rgba(0, 0, 0, 0.5); 25 background-color: rgba(0, 0, 0, 0.5);
26 display: none; /* Початково приховуємо затемнювач */ 26 display: none; /* Початково приховуємо затемнювач */
27 z-index: 999; /* Визначте певне значення z-index для забезпечення відображення поверх іншого вмісту */ 27 z-index: 999; /* Визначте певне значення z-index для забезпечення відображення поверх іншого вмісту */
28 } 28 }
29 29
30 #popupBackdrop .loader { 30 #popupBackdrop .loader {
31 position: absolute; 31 position: absolute;
32 top: 50%; 32 top: 50%;
33 left: 50%; 33 left: 50%;
34 transform: translate(-50%, -50%); 34 transform: translate(-50%, -50%);
35 } 35 }
36 .loader { 36 .loader {
37 color: #fff; 37 color: #fff;
38 font-size: x-large; 38 font-size: x-large;
39 } 39 }
40 40
41 41
42 .loading-dots { 42 .loading-dots {
43 display: inline-block; 43 display: inline-block;
44 font-size: 24px; 44 font-size: 24px;
45 line-height: 1; 45 line-height: 1;
46 } 46 }
47 47
48 .dot { 48 .dot {
49 display: inline-block; 49 display: inline-block;
50 animation: loading 1.5s infinite; 50 animation: loading 1.5s infinite;
51 } 51 }
52 52
53 @keyframes loading { 53 @keyframes loading {
54 0% { 54 0% {
55 opacity: 0; 55 opacity: 0;
56 } 56 }
57 50% { 57 50% {
58 opacity: 1; 58 opacity: 1;
59 } 59 }
60 100% { 60 100% {
61 opacity: 0; 61 opacity: 0;
62 } 62 }
63 } 63 }
64
65 .update_avaible {
66 color: #eca80c;
67 }
templates/dashboard-add.html
1 {% extends 'base.html' %} 1 {% extends 'base.html' %}
2 2
3 {% block styles %} 3 {% block styles %}
4 <style> 4 <style>
5 .table { 5 .table {
6 border-collapse: collapse; 6 border-collapse: collapse;
7 width: 100%; 7 width: 100%;
8 } 8 }
9 9
10 .table th, .table td { 10 .table th, .table td {
11 text-align: left; 11 text-align: left;
12 padding: 8px; 12 padding: 8px;
13 border-bottom: 1px solid #ddd; 13 border-bottom: 1px solid #ddd;
14 } 14 }
15 15
16 .table tr:hover { 16 .table tr:hover {
17 background-color: #f5f5f5; 17 background-color: #f5f5f5;
18 } 18 }
19 19
20 .search-form { 20 .search-form {
21 margin-bottom: 20px; 21 margin-bottom: 20px;
22 } 22 }
23 23
24 .search-form .input-group { 24 .search-form .input-group {
25 width: 300px; 25 width: 300px;
26 } 26 }
27 </style> 27 </style>
28 {% endblock %} 28 {% endblock %}
29 29
30 <div class="content"> 30 <div class="content">
31 {% block content %} 31 {% block content %}
32 32
33 <div class="container px-4 py-5" id="hanging-icons"> 33 <div class="container px-4 py-5" id="hanging-icons">
34 <h2 class="pb-2 border-bottom">{{gettext('t_components_shop')}}</h2> 34 <h2 class="pb-2 border-bottom">{{gettext('t_components_shop')}}</h2>
35 <form action="{{ url_for('components.dashboard') }}" method="GET" class="search-form"> 35 <form action="{{ url_for('components.dashboard') }}" method="GET" class="search-form">
36 <div class="input-group"> 36 <div class="input-group">
37 <input type="text" name="search_query" class="form-control" placeholder="Search components"> 37 <input type="text" name="search_query" class="form-control" placeholder="Search components">
38 <button type="submit" class="btn btn-primary">Search</button> 38 <button type="submit" class="btn btn-primary">Search</button>
39 </div> 39 </div>
40 </form> 40 </form>
41 41
42 42
43 <div class="row g-4 py-5 row-cols-1 row-cols-lg-3"> 43 <div class="row g-4 py-5 row-cols-1 row-cols-lg-3">
44 {% if component_server %} 44 {% if component_server %}
45 {% for component in component_server %} 45 {% for component in component_server %}
46 <div class="col d-flex align-items-start"> 46 <div class="col d-flex align-items-start">
47 <div class="icon-square bg-light text-dark flex-shrink-0 me-3"> 47 <div class="icon-square bg-light text-dark flex-shrink-0 me-3">
48 <img class="d-block mx-auto mb-4" src="/static/img/logo-k2.png" alt="" width="60"> 48 <img class="d-block mx-auto mb-4" src="/static/img/logo-k2.png" alt="" width="60">
49 </div> 49 </div>
50 <div> 50 <div>
51 <h2>{{ component.name|title }}</h2> 51 <h2>{{ component.name|title }}</h2>
52 <p>{{ component.description }}</p> 52 <p>{{ component.description }}</p>
53 <p>version {{ component.latest_version }}</p> 53 <p>version {{ component.latest_version }}</p>
54 {% for component_upd_ver in components_version %}
55 {% for key, value in component_upd_ver.items() %}
56 {% if key == component.name and value < component.latest_version %}
57 <p class="update_avaible"> Update avaible</p>
58 {% endif %}
59 {% endfor %}
60 {% endfor %}
61
54 {% if component.name in components_names %} 62 {% if component.name in components_names %}
55 <button type="button" class="btn btn-success">Installed</button> 63 <button type="button" class="btn btn-success">Installed</button>
56 {% else %} 64 {% else %}
57 <a href="/show_components-site/{{ component.id }}" class="btn btn-primary">Install</a> 65 <a href="/show_components-site/{{ component.id }}" class="btn btn-primary">Install</a>
58 {% endif %} 66 {% endif %}
59 </div> 67 </div>
60 </div> 68 </div>
61 {% endfor %} 69 {% endfor %}
62 {% else %} 70 {% else %}
63 <div class="col"> 71 <div class="col">
64 <p>No components available.</p> 72 <p>No components available.</p>
65 </div> 73 </div>
66 {% endif %} 74 {% endif %}
67 </div> 75 </div>
68 </div> 76 </div>
69 77
70 {% endblock %} 78 {% endblock %}
71
72 79
73 </div> 80 </div>