Commit db940340d9c10c5a36fc46957d694fc99c0ef1b3

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

add get menu-items api ver.

Showing 10 changed files with 57 additions and 25 deletions Inline Diff

__pycache__/main.cpython-310.pyc
No preview for this file type
__pycache__/routes.cpython-310.pyc
No preview for this file type
components/k2test/__pycache__/__init__.cpython-310.pyc
No preview for this file type
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
1 - category: dashboards 1 - category: dashboards
2 icon: mdi-chart-timeline-variant 2 icon: mdi-chart-timeline-variant
3 id: 1 3 id: 1
4 title: Analytics Dashboard 4 title: Analytics Dashboard
5 url: 5 url:
6 name: dashboards-analytics 6 name: dashboards-analytics
7 - category: dashboards 7 - category: dashboards
8 icon: mdi-cart-outline 8 icon: mdi-cart-outline
9 id: 2 9 id: 2
10 title: CRM Dashboard 10 title: CRM Dashboard
11 url: 11 url:
12 name: dashboards-crm 12 name: dashboards-crm
13 - category: error
14 icon: error
15 id: 3
16 title: k2test--error
17 url:
18 name: error
19 - category: error
20 icon: error
21 id: 4
22 title: k2test--error
23 url:
24 name: error
13 - category: "\u0422\u0435\u0441\u0442\u043E\u0432\u0430 \u043A\u043E\u043C\u043F\u043E\ 25 - category: "\u0422\u0435\u0441\u0442\u043E\u0432\u0430 \u043A\u043E\u043C\u043F\u043E\
14 \u043D\u0435\u043D\u0442\u0430" 26 \u043D\u0435\u043D\u0442\u0430"
15 icon: mdi-chart-timeline-variant 27 icon: mdi-chart-timeline-variant
16 id: 3 28 id: 5
17 title: "\u0422\u0435\u0441\u0442 2" 29 title: "\u0422\u0435\u0441\u0442 2"
18 url: 30 url:
19 name: new2 31 name: new2
20 - category: "\u0422\u0435\u0441\u0442\u043E\u0432\u0430 \u043A\u043E\u043C\u043F\u043E\ 32 - category: "\u0422\u0435\u0441\u0442\u043E\u0432\u0430 \u043A\u043E\u043C\u043F\u043E\
21 \u043D\u0435\u043D\u0442\u0430" 33 \u043D\u0435\u043D\u0442\u0430"
22 icon: mdi-chart-timeline-variant 34 icon: mdi-chart-timeline-variant
23 id: 4 35 id: 6
24 title: "\u0422\u0435\u0441\u0442 3" 36 title: "\u0422\u0435\u0441\u0442 3"
25 url: 37 url:
26 name: new3 38 name: new3
27 - category: "\u0422\u0435\u0441\u0442\u043E\u0432\u0430 \u043A\u043E\u043C\u043F\u043E\ 39 - category: "\u0422\u0435\u0441\u0442\u043E\u0432\u0430 \u043A\u043E\u043C\u043F\u043E\
28 \u043D\u0435\u043D\u0442\u0430" 40 \u043D\u0435\u043D\u0442\u0430"
29 icon: mdi-chart-timeline-variant 41 icon: mdi-chart-timeline-variant
30 id: 5 42 id: 7
31 title: "\u0422\u0435\u0441\u0442 4" 43 title: "\u0422\u0435\u0441\u0442 4"
32 url: 44 url:
33 name: new4 45 name: new4
34 46
No preview for this file type
k2/__pycache__/k2inst.cpython-310.pyc
No preview for this file type
1 import zipfile 1 import zipfile
2 from flask import Flask, Blueprint, jsonify, render_template, redirect, url_for, session, g 2 from flask import Flask, Blueprint, jsonify, render_template, redirect, url_for, session, g
3 import os 3 import os
4 import shutil 4 import shutil
5 from datetime import datetime 5 from datetime import datetime
6 import uuid 6 import uuid
7 from flask import request 7 from flask import request
8 from k2.k2cfg import k2 8 from k2.k2cfg import k2
9 from flask_migrate import Migrate 9 from flask_migrate import Migrate
10 import requests 10 import requests
11 import subprocess 11 import subprocess
12 from flask import current_app 12 from flask import current_app
13 import yaml 13 import yaml
14 from functools import wraps 14 from functools import wraps
15 import os
16 import sys
15 17
18
19 # initialize db
16 db = k2.db 20 db = k2.db
17 #migrate = Migrate(app, db) 21 #migrate = Migrate(app, db)
22
18 def generate_id(): 23 def generate_id():
19 generated_id = uuid.uuid4().hex[:32] 24 generated_id = uuid.uuid4().hex[:32]
20 return ''.join([generated_id[i:i + 4] for i in range(0, len(generated_id), 4)]) 25 return ''.join([generated_id[i:i + 4] for i in range(0, len(generated_id), 4)])
21 class Component(db.Model): 26 class Component(db.Model):
22 __bind_key__ = 'db2' 27 __bind_key__ = 'db2'
23 __tablename__ = 'component' 28 __tablename__ = 'component'
24 __table_args__ = {'extend_existing': True} 29 __table_args__ = {'extend_existing': True}
25 id = db.Column(db.String(36), primary_key=True, default=generate_id) 30 id = db.Column(db.String(36), primary_key=True, default=generate_id)
26 name = db.Column(db.String(100), nullable=False) 31 name = db.Column(db.String(100), nullable=False)
27 description = db.Column(db.String(200)) 32 description = db.Column(db.String(200))
28 version = db.Column(db.String(20)) 33 version = db.Column(db.String(20))
29 git_link = db.Column(db.String(200)) 34 git_link = db.Column(db.String(200))
30 dependencies = db.Column(db.String) 35 dependencies = db.Column(db.String)
31 date_installed = db.Column(db.DateTime, default=datetime.utcnow) 36 date_installed = db.Column(db.DateTime, default=datetime.utcnow)
32 installed = db.Column(db.Boolean, default=False) 37 installed = db.Column(db.Boolean, default=False)
33 38
34 def __init__(self, name, description, version, git_link, dependencies, installed): 39 def __init__(self, name, description, version, git_link, dependencies, installed):
35 self.name = name 40 self.name = name
36 self.description = description 41 self.description = description
37 self.version = version 42 self.version = version
38 self.git_link = git_link 43 self.git_link = git_link
39 self.dependencies = dependencies 44 self.dependencies = dependencies
40 self.installed = installed 45 self.installed = installed
41 def __repr__(self): 46 def __repr__(self):
42 return f"Component('{self.name}', '{self.version}')" 47 return f"Component('{self.name}', '{self.version}')"
43 @classmethod 48 @classmethod
44 def get_repository_by_id(self,rep_id): 49 def get_repository_by_id(self,rep_id):
45 component = db.session.query(Component).filter(Component.id == rep_id).first() 50 component = db.session.query(Component).filter(Component.id == rep_id).first()
46 return component 51 return component
47 components_bp = Blueprint('components', __name__, template_folder='templates') 52 components_bp = Blueprint('components', __name__, template_folder='templates')
48 config = yaml.safe_load(open("db/first-login.yml")) 53 config = yaml.safe_load(open("db/first-login.yml"))
49 54
50 def first_login_required(view_func): 55 def first_login_required(view_func):
51 @wraps(view_func) 56 @wraps(view_func)
52 def decorated_view(*args, **kwargs): 57 def decorated_view(*args, **kwargs):
53 if 'username' not in session: 58 if 'username' not in session:
54 return redirect(url_for('components.first_login')) 59 return redirect(url_for('components.first_login'))
55 return view_func(*args, **kwargs) 60 return view_func(*args, **kwargs)
56 return decorated_view 61 return decorated_view
57 62
58 def append_to_yaml_file(file_path, data): 63 def append_to_yaml_file(file_path, data):
59 with open(file_path, 'r') as f: 64 with open(file_path, 'r') as f:
60 existing_data = yaml.safe_load(f) or [] 65 existing_data = yaml.safe_load(f) or []
61 66
62 if not existing_data: 67 if not existing_data:
63 start_id = 1 68 start_id = 1
64 else: 69 else:
65 start_id = max(item.get('id', 0) for item in existing_data) + 1 70 start_id = max(item.get('id', 0) for item in existing_data) + 1
66 71
67 for i, item in enumerate(data, start=start_id): 72 for i, item in enumerate(data, start=start_id):
68 item['id'] = i 73 item['id'] = i
69 existing_data.append(item) 74 existing_data.append(item)
70 75
71 with open(file_path, 'w') as f: 76 with open(file_path, 'w') as f:
72 yaml.dump(existing_data, f, default_flow_style=False) 77 yaml.dump(existing_data, f, default_flow_style=False)
73 78
74 @components_bp.route('/api/languages', methods=['GET']) 79 @components_bp.route('/api/languages', methods=['GET'])
75 def find_language(): 80 def find_language():
76 components = Component.query.all() 81 components = Component.query.all()
77 languages_paths = [] 82 languages_paths = []
78 # Додаємо головну директорію languages 83 # Додаємо головну директорію languages
79 languages_paths.append('languages') 84 languages_paths.append('languages')
80 # Знаходимо шляхи до директорій languages всередині папки components 85 # Знаходимо шляхи до директорій languages всередині папки components
81 for component in components: 86 for component in components:
82 component_languages_directory = 'components/' + component.name + '/' + component.name + '/languages' 87 component_languages_directory = 'components/' + component.name + '/' + component.name + '/languages'
83 languages_paths.append(component_languages_directory) 88 languages_paths.append(component_languages_directory)
84 result = ';'.join(languages_paths) 89 result = ';'.join(languages_paths)
85 print(result) 90 print(result)
86 return result 91 return result
87 92
88 @components_bp.route('/', methods=['GET', 'POST']) 93 @components_bp.route('/', methods=['GET', 'POST'])
89 @first_login_required 94 @first_login_required
90 def home(): 95 def home():
91 return redirect('/dashboard') 96 return redirect('/dashboard')
92 97
93 @components_bp.route('/login', methods=['GET', 'POST']) 98 @components_bp.route('/login', methods=['GET', 'POST'])
94 def first_login(): 99 def first_login():
95 if request.method == "POST": 100 if request.method == "POST":
96 username = request.form.get("username") 101 username = request.form.get("username")
97 password = request.form.get("password") 102 password = request.form.get("password")
98 for user in config["users"]: 103 for user in config["users"]:
99 if user["username"] == username and user["password"] == password: 104 if user["username"] == username and user["password"] == password:
100 session['username'] = username # Збереження ім'я користувача в сесії 105 session['username'] = username # Збереження ім'я користувача в сесії
101 return redirect(url_for('components.dashboard')) 106 return redirect(url_for('components.dashboard'))
102 return "Невірне ім'я користувача або пароль." 107 return "Невірне ім'я користувача або пароль."
103 return render_template('first-login.html') 108 return render_template('first-login.html')
104 109
105 @components_bp.route('/logout') 110 @components_bp.route('/logout')
106 def logout(): 111 def logout():
107 session.pop('username', None) # Видалення ім'я користувача з сесії 112 session.pop('username', None) # Видалення ім'я користувача з сесії
108 return redirect(url_for('components.first_login')) 113 return redirect(url_for('components.first_login'))
109 114
110 @components_bp.route('/change_language/<lang>') 115 @components_bp.route('/change_language/<lang>')
111 def change_language(lang): 116 def change_language(lang):
112 session['lang'] = lang 117 session['lang'] = lang
113 k2.current_language = lang 118 k2.current_language = lang
114 return redirect(url_for('components.dashboard')) 119 return redirect(url_for('components.dashboard'))
115 120
116 @components_bp.route('/dashboard') 121 @components_bp.route('/dashboard')
117 @first_login_required 122 @first_login_required
118 def dashboard(): 123 def dashboard():
119 124
120 # Компоненти доступні для встановлення 125 # Компоненти доступні для встановлення
121 try: 126 try:
122 # GET-запит до API 127 # GET-запит до API
123 response = requests.get('http://127.0.0.1:8001/api/components') 128 response = requests.get(f'{k2.update_domain}api/components')
124 json_data = response.json() 129 json_data = response.json()
125 # Перетворення JSON-об'єкту на масив 130 # Перетворення JSON-об'єкту на масив
126 component_server = [item for item in json_data] 131 component_server = [item for item in json_data]
127 except: 132 except:
128 component_server = None 133 component_server = None
129 134
130 # Встановлені компоненти 135 # Встановлені компоненти
131 components = Component.query.all() 136 components = Component.query.all()
132 components_names = [component.name for component in components] 137 components_names = [component.name for component in components]
133 # Отримання значення пошукового запиту з параметрів URL 138 # Отримання значення пошукового запиту з параметрів URL
134 search_query = request.args.get('search_query') 139 search_query = request.args.get('search_query')
135 #print(search_query) 140 #print(search_query)
136 filtered_components = [] 141 filtered_components = []
137 if search_query: 142 if search_query:
138 filtered_components = [component for component in component_server if 143 filtered_components = [component for component in component_server if
139 (search_query.lower() in component['name'].lower() if component['name'] else False) or 144 (search_query.lower() in component['name'].lower() if component['name'] else False) or
140 (search_query.lower() in component['description'].lower() if component[ 145 (search_query.lower() in component['description'].lower() if component[
141 'description'] else False)] 146 'description'] else False)]
142 else: 147 else:
143 filtered_components = component_server 148 filtered_components = component_server
144 current_language = k2.current_language 149 current_language = k2.current_language
145 150
146 return render_template('dashboard.html', components=components, 151 return render_template('dashboard.html', components=components,
147 components_names=components_names, component_server=filtered_components, 152 components_names=components_names, component_server=filtered_components,
148 search_query=search_query, language=k2.menu ) 153 search_query=search_query, language=k2.menu )
149 154
150 @components_bp.route('/show_components/<string:component_id>') 155 @components_bp.route('/show_components/<string:component_id>')
151 def show_components(component_id): 156 def show_components(component_id):
152 response = requests.get('http://127.0.0.1:8001/api/components') 157 response = requests.get(f'{k2.update_domain}api/components')
153 json_data = response.json() 158 json_data = response.json()
154 selected_component = next((component for component in json_data if component['id'] == component_id), None) 159 selected_component = next((component for component in json_data if component['id'] == component_id), None)
155 return render_template('component-info.html', selected_component=selected_component) 160 return render_template('component-info.html', selected_component=selected_component)
156 161
157 @components_bp.route('/install_components_git/<string:component_id>') 162 @components_bp.route('/install_components_git/<string:component_id>')
158 def install_components_git(component_id): 163 def install_components_git(component_id):
159 # Шлях до головної папки проекту 164 # Шлях до головної папки проекту
160 project_folder = 'components' 165 project_folder = 'components'
161 #component = Component.get_repository_by_id(component_id) 166 #component = Component.get_repository_by_id(component_id)
162 response = requests.get('http://127.0.0.1:8001/api/components') 167 response = requests.get(f'{k2.update_domain}api/components')
163 json_data = response.json() 168 json_data = response.json()
164 selected_component = next((component for component in json_data if component['id'] == component_id), None) 169 selected_component = next((component for component in json_data if component['id'] == component_id), None)
165 # Назва репозиторія 170 # Назва репозиторія
166 repository_name = selected_component['name'] 171 repository_name = selected_component['name']
167 # Шлях до папки репозиторія в межах проекту 172 # Шлях до папки репозиторія в межах проекту
168 repository_folder = os.path.join(project_folder, repository_name) 173 repository_folder = os.path.join(project_folder, repository_name)
169 # URL репозиторія 174 # URL репозиторія
170 175
171 git_repo_url = selected_component['git_link'] 176 git_repo_url = selected_component['git_link']
172 try: 177 try:
173 # Перевірка наявності папки репозиторія 178 # Перевірка наявності папки репозиторія
174 if not os.path.exists(repository_folder): 179 if not os.path.exists(repository_folder):
175 # Створення папки репозиторія 180 # Створення папки репозиторія
176 os.makedirs(repository_folder) 181 os.makedirs(repository_folder)
177 # Шлях до файлу __init__.py 182 # Шлях до файлу __init__.py
178 init_file = os.path.join(repository_folder, '__init__.py') 183 init_file = os.path.join(repository_folder, '__init__.py')
179 # Перевірка наявності файлу __init__.py 184 # Перевірка наявності файлу __init__.py
180 if not os.path.exists(init_file): 185 if not os.path.exists(init_file):
181 # Створення пустого файлу __init__.py 186 # Створення пустого файлу __init__.py
182 open(init_file, 'a').close() 187 open(init_file, 'a').close()
183 #підключення до приватного репозиторію 188 #підключення до приватного репозиторію
184 #os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW' 189 #os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW'
185 #git_repo_url_with_token = git_repo_url.replace('https://', 190 #git_repo_url_with_token = git_repo_url.replace('https://',
186 # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@') 191 # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@')
187 192
188 # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія 193 # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія
189 command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url, '--target=' + repository_folder] 194 command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url, '--target=' + repository_folder]
190 # Виконуємо команду встановлення 195 # Виконуємо команду встановлення
191 subprocess.check_call(command) 196 subprocess.check_call(command)
192 197
193 # Шлях до файлу, до якого потрібно додати код 198 # Шлях до файлу, до якого потрібно додати код
194 file_path = 'routes.py' 199 file_path = 'routes.py'
195 # Код, який потрібно додати 200 # Код, який потрібно додати
196 code = selected_component['dependencies'] 201 code = selected_component['dependencies']
197 # Відкриття файлу у режимі дозапису 202 # Відкриття файлу у режимі дозапису
198 with open(file_path, 'a') as file: 203 with open(file_path, 'a') as file:
199 # Запис нового коду у файл 204 # Запис нового коду у файл
200 file.write('\n') 205 file.write('\n')
201 file.write(code) 206 file.write(code)
202 file.write('\n') 207 file.write('\n')
203 component = Component.query.filter_by(name=selected_component['name']).first() 208 component = Component.query.filter_by(name=selected_component['name']).first()
204 if not component: 209 if not component:
205 new_component = Component( 210 new_component = Component(
206 name=selected_component['name'], 211 name=selected_component['name'],
207 description=selected_component['description'], 212 description=selected_component['description'],
208 version=selected_component['version'], 213 version=selected_component['version'],
209 git_link=selected_component['git_link'], 214 git_link=selected_component['git_link'],
210 dependencies=selected_component['dependencies'], 215 dependencies=selected_component['dependencies'],
211 installed=True 216 installed=True
212 ) 217 )
213 # Add the new component to the database 218 # Add the new component to the database
214 db.session.add(new_component) 219 db.session.add(new_component)
215 db.session.commit() 220 db.session.commit()
216 221
217 # Повертаємо повідомлення про успішне встановлення 222 # Повертаємо повідомлення про успішне встановлення
218 return f'Installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 223 return f'Installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
219 except subprocess.CalledProcessError as e: 224 except subprocess.CalledProcessError as e:
220 return 'Error installing : ' + str(e) 225 return 'Error installing : ' + str(e)
221 226
222 @components_bp.route('/install_components/<string:component_id>') 227 @components_bp.route('/install_components/<string:component_id>')
223 def install_component_from_archive(component_id): 228 def install_component_from_archive(component_id):
224 # Шлях до головної папки проекту 229 # Шлях до головної папки проекту
225 project_folder = 'components' 230 project_folder = 'components'
226 # Отримати відповідну компоненту зі списку компонент 231 # Отримати відповідну компоненту зі списку компонент
227 response = requests.get('http://127.0.0.1:8001/api/components') 232 response = requests.get(f'{k2.update_domain}api/components')
228 json_data = response.json() 233 json_data = response.json()
229 selected_component = next((component for component in json_data if component['id'] == component_id), None) 234 selected_component = next((component for component in json_data if component['id'] == component_id), None)
230 if selected_component is None: 235 if selected_component is None:
231 return 'Component not found' 236 return 'Component not found'
232 # Отримати посилання на архів компоненти та версію 237 # Отримати посилання на архів компоненти та версію
233 archive_url = selected_component['latest_component_data'] 238 archive_url = selected_component['latest_component_data']
234 version = selected_component['latest_version'] 239 version = selected_component['latest_version']
235 try: 240 try:
236 # Створити шлях до папки компоненти згідно назви та версії 241 # Створити шлях до папки компоненти згідно назви та версії
237 component_folder = os.path.join(project_folder) 242 component_folder = os.path.join(project_folder)
238 os.makedirs(component_folder, exist_ok=True) 243 os.makedirs(component_folder, exist_ok=True)
239 # Завантажити архів компоненти 244 # Завантажити архів компоненти
240 response = requests.get(archive_url, stream=True) 245 response = requests.get(archive_url, stream=True)
241 response.raise_for_status() 246 response.raise_for_status()
242 # Шлях до завантаженого архіву 247 # Шлях до завантаженого архіву
243 archive_path = os.path.join(component_folder, f"{selected_component['name']}.zip") 248 archive_path = os.path.join(component_folder, f"{selected_component['name']}.zip")
244 # Встановити залежності з файлу requirements.txt 249 # Встановити залежності з файлу requirements.txt
245 250
246 # Зберегти архів на диск 251 # Зберегти архів на диск
247 with open(archive_path, "wb") as file: 252 with open(archive_path, "wb") as file:
248 for chunk in response.iter_content(chunk_size=8192): 253 for chunk in response.iter_content(chunk_size=8192):
249 file.write(chunk) 254 file.write(chunk)
250 # Розпакувати архів 255 # Розпакувати архів
251 with zipfile.ZipFile(archive_path, "r") as zip_ref: 256 with zipfile.ZipFile(archive_path, "r") as zip_ref:
252 zip_ref.extractall(component_folder) 257 zip_ref.extractall(component_folder)
253 258
254 # Видалити архів 259 # Видалити архів
255 os.remove(archive_path) 260 os.remove(archive_path)
256 261
257 # Шлях до файлу, до якого потрібно додати код 262 # Шлях до файлу, до якого потрібно додати код
258 file_path = 'routes.py' 263 file_path = 'routes.py'
259 # Код, який потрібно додати 264 # Код, який потрібно додати
260 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']}')''' 265 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']}')'''
261 #selected_component['dependencies'] 266 #selected_component['dependencies']
262 267
263 # Відкриття файлу у режимі дозапису 268 # Відкриття файлу у режимі дозапису
264 with open(file_path, 'a') as file: 269 with open(file_path, 'a') as file:
265 # Запис нового коду у файл 270 # Запис нового коду у файл
266 file.write('\n') 271 file.write('\n')
267 file.write(code) 272 file.write(code)
268 file.write('\n') 273 file.write('\n')
269 274
270 #Update database with the installed component 275 #Update database with the installed component
271 component = Component.query.filter_by(name=selected_component['name']).first() 276 component = Component.query.filter_by(name=selected_component['name']).first()
272 if not component: 277 if not component:
273 component = Component( 278 component = Component(
274 name=selected_component['name'], 279 name=selected_component['name'],
275 description=selected_component['description'], 280 description=selected_component['description'],
276 version=version, 281 version=version,
277 git_link=selected_component['git_link'], 282 git_link=selected_component['git_link'],
278 dependencies=code, 283 dependencies=code,
279 installed=True 284 installed=True
280 ) 285 )
281 db.session.add(component) 286 db.session.add(component)
282 else: 287 else:
283 component.version = version 288 component.version = version
284 component.git_link = selected_component['git_link'] 289 component.git_link = selected_component['git_link']
285 component.dependencies = code 290 component.dependencies = code
286 component.installed = True 291 component.installed = True
287 292
288 db.session.commit() 293 db.session.commit()
289 # add menu items 294 # add menu items yml
290 file_path_input = f"components/{selected_component['name']}/menu_items.yml" 295 #file_path_input = f"components/{selected_component['name']}/menu_items.yml"
291 if os.path.exists(file_path_input): 296 #if os.path.exists(file_path_input):
292 with open(file_path_input, 'r', encoding='utf-8') as file: 297 # with open(file_path_input, 'r', encoding='utf-8') as file:
293 data = yaml.safe_load(file) 298 # data = yaml.safe_load(file)
294 else: 299 #else:
295 data = { 300 # data = {
296 'url': {'name': 'error'}, 301 # 'url': {'name': 'error'},
297 'icon': 'error', 302 # 'icon': 'error',
298 'title': f"{selected_component['name']}--error", 303 # 'title': f"{selected_component['name']}--error",
299 'category': 'error', 304 # 'category': 'error',
300 } 305 # }
301 306
302 file_path = 'components/menu.yml' 307 #file_path = 'components/menu.yml'
303 append_to_yaml_file(file_path, data) 308 #append_to_yaml_file(file_path, data)
304 309
305 #add language folders 310 #add language folders
306 k2.search_babel_translation_directories() 311 k2.search_babel_translation_directories()
307 312
308 return f'''Component installed successfully: {selected_component["name"]} v{version} {k2.babel_translation_directories}, 313 return f'''Component installed successfully: {selected_component["name"]} v{version} {k2.babel_translation_directories},
309 \n \n please wait installing requirments... 314 \n \n please wait installing requirments...
310 <meta http-equiv="refresh" content="0;url=/install-requirments/{selected_component["name"]}" />''' 315 <meta http-equiv="refresh" content="0;url=/install-requirments/{selected_component["name"]}" />'''
311 316
312 except Exception as e: 317 except Exception as e:
313 return f'Error installing component: {str(e)}' 318 return f'Error installing component: {str(e)}'
314 319
315 @components_bp.route('/install-requirments/<string:selected_component_name>', methods=['GET']) 320 @components_bp.route('/install-requirments/<string:selected_component_name>', methods=['GET'])
316 def install_requirments(selected_component_name): 321 def install_requirments(selected_component_name):
322 #menu items api
323 response = requests.get(f"{k2.domain}{selected_component_name}/menu-items")
324 if response.status_code == 200:
325 data = response.json()
326 print(data)
327 else:
328 data = [{
329 'url': {'name': 'error'},
330 'icon': 'error',
331 'title': f"{selected_component_name}--error",
332 'category': 'error',
333 }]
334
335 file_path = 'components/menu.yml'
336 append_to_yaml_file(file_path, data)
337 k2.get_menu_elenents()
338
339 #install requirements
317 requirements_file = os.path.join('components', selected_component_name, "requirements.txt") 340 requirements_file = os.path.join('components', selected_component_name, "requirements.txt")
318 if os.path.isfile(requirements_file): 341 if os.path.isfile(requirements_file):
319 pip_command = f"{k2.venv_bin_path}/python -m pip install -r {requirements_file}" 342 pip_command = f"{k2.venv_bin_path}/python -m pip install -r {requirements_file}"
320 subprocess.run(pip_command, shell=True, check=True) 343 subprocess.run(pip_command, shell=True, check=True)
321 return f'''Requirements installed successfully 344 return f'''Requirements installed successfully
322 \n \n please wait installing requirments components... 345 \n \n please wait installing requirments components...
323 <meta http-equiv="refresh" content="1;url=/install-requirments-components" />''' 346 <meta http-equiv="refresh" content="1;url=/install-requirments-components" />'''
324
325 347
326 @components_bp.route('/install-requirments-components') 348 @components_bp.route('/install-requirments-components')
327 def install_requirements_components(): 349 def install_requirements_components():
328 # Откриття файлу requirements_components.txt 350 # Откриття файлу requirements_components.txt
329 requirements_file = 'requirements_components.txt' 351 requirements_file = 'requirements_components.txt'
330 component_ids = None 352 component_ids = None
331 if os.path.isfile(requirements_file): 353 if os.path.isfile(requirements_file):
332 with open('requirements_components.txt', 'r') as file: 354 with open('requirements_components.txt', 'r') as file:
333 component_ids = file.read().splitlines() 355 component_ids = file.read().splitlines()
334 if component_ids: 356 if component_ids:
335 for component_id in component_ids: 357 for component_id in component_ids:
336 # Виклик роуту '/install_components/<string:component_name>' для кожної назви компоненти 358 # Виклик роуту '/install_components/<string:component_name>' для кожної назви компоненти
337 response = requests.get( 359 response = requests.get(
338 f'/install_components/{component_id}') 360 f'/install_components/{component_id}')
339 return f'Requirements components installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 361 return f'Requirements components installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
340 else: 362 else:
341 return f'<meta http-equiv="refresh" content="1;url=/dashboard" />' 363 return f'<meta http-equiv="refresh" content="1;url=/dashboard" />'
342 # Опрацювання відповіді (за потреби) 364 # Опрацювання відповіді (за потреби)
343 365
344 366
345 @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET']) 367 @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET'])
346 def remove_dependencies(component_id): 368 def remove_dependencies(component_id):
347 # Знаходимо компоненту за її ID 369 # Знаходимо компоненту за її ID
348 component = Component.query.get(component_id) 370 component = Component.query.get(component_id)
349 if not component: 371 if not component:
350 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />' 372 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />'
351 373
352 # Шлях до файлу, з якого потрібно видалити залежності 374 # Шлях до файлу, з якого потрібно видалити залежності
353 file_path = 'routes.py' 375 file_path = 'routes.py'
354 376
355 # Зчитуємо вміст файлу 377 # Зчитуємо вміст файлу
356 with open(file_path, 'r') as file: 378 with open(file_path, 'r') as file:
357 lines = file.readlines() 379 lines = file.readlines()
358 380
359 # Видаляємо рядки, що містять залежності компоненти 381 # Видаляємо рядки, що містять залежності компоненти
360 updated_lines = [line for line in lines if line.strip() not in component.dependencies] 382 updated_lines = [line for line in lines if line.strip() not in component.dependencies]
361 383
362 # Записуємо оновлений вміст у файл 384 # Записуємо оновлений вміст у файл
363 with open(file_path, 'w') as file: 385 with open(file_path, 'w') as file:
364 file.writelines(updated_lines) 386 file.writelines(updated_lines)
365 387
366 # Оновлюємо статус компоненти 388 # Оновлюємо статус компоненти
367 component.installed = False 389 component.installed = False
368 db.session.commit() 390 db.session.commit()
369 391
370 return 'Component successfully turn off <meta http-equiv="refresh" content="1;url=/dashboard" />' 392 return 'Component successfully turn off <meta http-equiv="refresh" content="1;url=/dashboard" />'
371 393
372 @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET']) 394 @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET'])
373 def add_dependencies(component_id): 395 def add_dependencies(component_id):
374 396
375 # Знаходимо компоненту за її ID 397 # Знаходимо компоненту за її ID
376 component = Component.query.get(component_id) 398 component = Component.query.get(component_id)
377 if not component: 399 if not component:
378 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />' 400 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />'
379 401
380 # Шлях до файлу, з якого потрібно видалити залежності 402 # Шлях до файлу, з якого потрібно видалити залежності
381 file_path = 'routes.py' 403 file_path = 'routes.py'
382 code = component.dependencies 404 code = component.dependencies
383 # Відкриття файлу у режимі дозапису 405 # Відкриття файлу у режимі дозапису
384 with open(file_path, 'a') as file: 406 with open(file_path, 'a') as file:
385 # Запис нового коду у файл 407 # Запис нового коду у файл
386 file.write(code) 408 file.write(code)
387 409
388 # Оновлюємо статус компоненти 410 # Оновлюємо статус компоненти
389 component.installed = True 411 component.installed = True
390 db.session.commit() 412 db.session.commit()
391 return 'Dependencies added successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 413 return 'Dependencies added successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
392 414
393 @components_bp.route('/remove-component/<string:component_id>') 415 @components_bp.route('/remove-component/<string:component_id>')
394 def remove_component(component_id): 416 def remove_component(component_id):
395 # Шлях до головної папки проекту 417 # Шлях до головної папки проекту
396 project_folder = 'components' 418 project_folder = 'components'
397 component = Component.query.get(component_id) 419 component = Component.query.get(component_id)
398 # Назва репозиторія 420 # Назва репозиторія
399 repository_name = component.name 421 repository_name = component.name
400 # Шлях до папки репозиторія в межах проекту 422 # Шлях до папки репозиторія в межах проекту
401 repository_folder = os.path.join(project_folder, repository_name) 423 repository_folder = os.path.join(project_folder, repository_name)
402 try: 424 try:
403 # Перевірка наявності папки репозиторія 425 # Перевірка наявності папки репозиторія
404 if os.path.exists(repository_folder): 426 if os.path.exists(repository_folder):
405 # Видалення папки репозиторія 427 # Видалення папки репозиторія
406 shutil.rmtree(repository_folder) 428 shutil.rmtree(repository_folder)
407 # Видаляємо компоненту з бази 429 # Видаляємо компоненту з бази
408 if component: 430 if component:
409 db.session.delete(component) 431 db.session.delete(component)
410 db.session.commit() 432 db.session.commit()
411 433
412 # Повертаємо повідомлення про успішне видалення 434 # Повертаємо повідомлення про успішне видалення
413 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" />'
414 except Exception as e: 436 except Exception as e:
415 # Повертаємо повідомлення про помилку видалення 437 # Повертаємо повідомлення про помилку видалення
416 return 'Error removing component: ' + str(e) 438 return 'Error removing component: ' + str(e)
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 k2.k2inst import * 3 #from k2.k2inst import *
4 from flask import Flask 4 from flask import Flask
5 from k2.k2cfg import k2 5 from k2.k2cfg import k2
6 6
7 # configure flask app 7 # configure flask app
8 app = Flask(__name__) 8 app = Flask(__name__)
9 app.config['SECRET_KEY'] = k2.secret_key 9 app.config['SECRET_KEY'] = k2.secret_key
10 #app.config.from_object(k2) 10 #app.config.from_object(k2)
11 11
12 # init db 12 # init db
13 k2().init_db(app) 13 k2().init_db(app)
14 CORS(app) 14 CORS(app)
15 15
16 #translate 16 #translate
17 k2.load_babel_translation_directories() 17 k2.load_babel_translation_directories()
18 app.config['BABEL_TRANSLATION_DIRECTORIES'] = k2.babel_translation_directories 18 app.config['BABEL_TRANSLATION_DIRECTORIES'] = k2.babel_translation_directories
19 babel = Babel(app) 19 babel = Babel(app)
20 babel.init_app(app, locale_selector=k2.get_locale) 20 babel.init_app(app, locale_selector=k2.get_locale)
21 21
22 #menu
23 k2.get_menu_elenents()
24 22
25 # flask routing 23 # flask routing
26 from routes import * 24 from routes import *
27 25
28 if __name__ == '__main__': 26 if __name__ == '__main__':
29 app.run(debug=True, port=5000) 27 app.run(debug=True, port=5000)
30 28
31 29
32 30
33 31