Commit 631cba615723ea77d9926903a2a1d980e7f0decd

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

fix folder name from git bug

Showing 1 changed file with 140 additions and 79 deletions Side-by-side Diff

1 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, jsonify
3 3 import os
4 4 import shutil
5 5 from flask import request
6 6  
... ... @@ -15,12 +15,11 @@
15 15 import sys
16 16  
17 17 # initialize db
18   -#migrate = Migrate(app, db)
  18 +# migrate = Migrate(app, db)
19 19  
20 20 components_bp = Blueprint('components', __name__, template_folder='templates')
21 21 config = yaml.safe_load(open("db/first-login.yml"))
22 22  
23   -
24 23 db = k2.db
25 24  
26 25  
27 26  
28 27  
29 28  
30 29  
... ... @@ -30,25 +29,27 @@
30 29 if 'username' not in session:
31 30 return redirect(url_for('components.first_login'))
32 31 return view_func(*args, **kwargs)
  32 +
33 33 return decorated_view
34 34  
35   -def append_to_yaml_file(file_path, data):
36   - with open(file_path, 'r') as f:
37   - existing_data = yaml.safe_load(f) or []
38 35  
39   - if not existing_data:
40   - start_id = 1
41   - else:
42   - start_id = max(item.get('id', 0) for item in existing_data) + 1
  36 +# def append_to_yaml_file(file_path, data):
  37 +# with open(file_path, 'r') as f:
  38 +# existing_data = yaml.safe_load(f) or []
  39 +#
  40 +# if not existing_data:
  41 +# start_id = 1
  42 +# else:
  43 +# start_id = max(item.get('id', 0) for item in existing_data) + 1
  44 +#
  45 +# for i, item in enumerate(data, start=start_id):
  46 +# item['id'] = i
  47 +# existing_data.append(item)
  48 +#
  49 +# with open(file_path, 'w') as f:
  50 +# yaml.dump(existing_data, f, default_flow_style=False)
43 51  
44   - for i, item in enumerate(data, start=start_id):
45   - item['id'] = i
46   - existing_data.append(item)
47 52  
48   - with open(file_path, 'w') as f:
49   - yaml.dump(existing_data, f, default_flow_style=False)
50   -
51   -
52 53 def remove_from_yaml_file(file_path, component_name):
53 54 with open(file_path, 'r') as f:
54 55 existing_data = yaml.safe_load(f) or []
... ... @@ -58,6 +59,7 @@
58 59 with open(file_path, 'w') as f:
59 60 yaml.dump(updated_data, f, default_flow_style=False)
60 61  
  62 +
61 63 @components_bp.route('/api/languages', methods=['GET'])
62 64 def find_language():
63 65 components = Component.query.all()
64 66  
... ... @@ -72,29 +74,13 @@
72 74 print(result)
73 75 return result
74 76  
75   -@components_bp.route('/api/add-to-menu', methods=['GET'])
76   -def add_to_menu():
77   - data = []
78   - components = Component.query.all()
79   - components_names = [component.name for component in components]
80   - for components_names in components_names:
81   - response = requests.get(f"{k2.domain}{components_names}/menu-admin-items")
82   - print(response)
83   - if response.status_code == 200:
84   - data.append(response.json()[0])
85   - else:
86   - data
87   - # add component_name key for menu items
88   - for item in data:
89   - item['component_name'] = components_names
90   - k2.menu = data
91   - return k2.menu
92 77  
93 78 @components_bp.route('/home', methods=['GET', 'POST'])
94 79 @first_login_required
95 80 def home():
96 81 return redirect('/dashboard')
97 82  
  83 +
98 84 @components_bp.route('/first-login', methods=['GET', 'POST'])
99 85 def first_login():
100 86 if request.method == "POST":
101 87  
... ... @@ -114,10 +100,11 @@
114 100 k2.current_language = lang
115 101 return redirect(url_for('components.dashboard'))
116 102  
  103 +
117 104 @components_bp.route('/dashboard')
118 105 @first_login_required
119 106 def dashboard():
120   - # Компоненти доступні для встановлення
  107 + # Компоненти доступні для встановлення
121 108 try:
122 109 # GET-запит до API
123 110 response = requests.get(f'{k2.update_domain}api/components')
... ... @@ -132,7 +119,7 @@
132 119 components_names = [component.name for component in components]
133 120 # Отримання значення пошукового запиту з параметрів URL
134 121 search_query = request.args.get('search_query')
135   - #print(search_query)
  122 + # print(search_query)
136 123 filtered_components = []
137 124 if search_query:
138 125 filtered_components = [component for component in component_server if
139 126  
... ... @@ -145,8 +132,9 @@
145 132  
146 133 return render_template('dashboard.html', components=components,
147 134 components_names=components_names, component_server=filtered_components,
148   - search_query=search_query, language=k2.menu )
  135 + search_query=search_query, language=k2.menu)
149 136  
  137 +
150 138 @components_bp.route('/show_components/<string:component_id>')
151 139 def show_components(component_id):
152 140 response = requests.get(f'{k2.update_domain}api/components')
153 141  
... ... @@ -154,11 +142,12 @@
154 142 selected_component = next((component for component in json_data if component['id'] == component_id), None)
155 143 return render_template('component-info.html', selected_component=selected_component)
156 144  
  145 +
157 146 @components_bp.route('/install_components_git/<string:component_id>')
158 147 def install_components_git(component_id):
159 148 # Шлях до головної папки проекту
160 149 project_folder = 'components'
161   - #component = Component.get_repository_by_id(component_id)
  150 + # component = Component.get_repository_by_id(component_id)
162 151 response = requests.get(f'{k2.update_domain}api/components')
163 152 json_data = response.json()
164 153 selected_component = next((component for component in json_data if component['id'] == component_id), None)
165 154  
... ... @@ -180,13 +169,14 @@
180 169 if not os.path.exists(init_file):
181 170 # Створення пустого файлу __init__.py
182 171 open(init_file, 'a').close()
183   - #підключення до приватного репозиторію
184   - #os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW'
185   - #git_repo_url_with_token = git_repo_url.replace('https://',
  172 + # підключення до приватного репозиторію
  173 + # os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW'
  174 + # git_repo_url_with_token = git_repo_url.replace('https://',
186 175 # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@')
187 176  
188 177 # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія
189   - command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url, '--target=' + repository_folder]
  178 + command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url,
  179 + '--target=' + repository_folder]
190 180 # Виконуємо команду встановлення
191 181 subprocess.check_call(command)
192 182  
193 183  
... ... @@ -200,16 +190,16 @@
200 190 file.write('\n')
201 191 file.write(code)
202 192 file.write('\n')
203   - component = Component.query.filter_by(name=selected_component['name']).first()
  193 + component = Component.query.filter_by(name=selected_component['name']).first()
204 194 if not component:
205 195 new_component = Component(
206   - name=selected_component['name'],
207   - description=selected_component['description'],
208   - version=selected_component['version'],
209   - git_link=selected_component['git_link'],
210   - dependencies=selected_component['dependencies'],
211   - installed=True
212   - )
  196 + name=selected_component['name'],
  197 + description=selected_component['description'],
  198 + version=selected_component['version'],
  199 + git_link=selected_component['git_link'],
  200 + dependencies=selected_component['dependencies'],
  201 + installed=True
  202 + )
213 203 # Add the new component to the database
214 204 db.session.add(new_component)
215 205 db.session.commit()
... ... @@ -219,6 +209,7 @@
219 209 except subprocess.CalledProcessError as e:
220 210 return 'Error installing : ' + str(e)
221 211  
  212 +
222 213 @components_bp.route('/install_components/<string:component_id>')
223 214 def install_component_from_archive(component_id):
224 215 # Шлях до головної папки проекту
... ... @@ -241,8 +232,6 @@
241 232 response.raise_for_status()
242 233 # Шлях до завантаженого архіву
243 234 archive_path = os.path.join(component_folder, f"{selected_component['name']}.zip")
244   - # Встановити залежності з файлу requirements.txt
245   -
246 235 # Зберегти архів на диск
247 236 with open(archive_path, "wb") as file:
248 237 for chunk in response.iter_content(chunk_size=8192):
249 238  
250 239  
251 240  
... ... @@ -250,15 +239,22 @@
250 239 # Розпакувати архів
251 240 with zipfile.ZipFile(archive_path, "r") as zip_ref:
252 241 zip_ref.extractall(component_folder)
253   -
254 242 # Видалити архів
255 243 os.remove(archive_path)
  244 + #перейменувати якщо git
  245 + component_name = selected_component['name']
  246 + old_folder_path = os.path.join(component_folder, component_name + ".git")
  247 + new_folder_path = os.path.join(component_folder, component_name)
  248 + # Перевірка наявності папки зі старою назвою
  249 + if os.path.exists(old_folder_path) and os.path.isdir(old_folder_path):
  250 + # Перейменування папки зі старою назвою на нову назву
  251 + os.rename(old_folder_path, new_folder_path)
256 252  
257   - # Шлях до файлу, до якого потрібно додати код
  253 + # Шлях до файлу, до якого потрібно додати роути
258 254 file_path = 'routes.py'
259 255 # Код, який потрібно додати
260 256 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']
  257 + # selected_component['dependencies']
262 258  
263 259 # Відкриття файлу у режимі дозапису
264 260 with open(file_path, 'a') as file:
... ... @@ -267,7 +263,7 @@
267 263 file.write(code)
268 264 file.write('\n')
269 265  
270   - #Update database with the installed component
  266 + # Update database with the installed component
271 267 component = Component.query.filter_by(name=selected_component['name']).first()
272 268 if not component:
273 269 component = Component(
... ... @@ -287,7 +283,7 @@
287 283  
288 284 db.session.commit()
289 285  
290   - #add language folders
  286 + # add language folders
291 287 k2.search_babel_translation_directories()
292 288 return f'''Component installed successfully: {selected_component["name"]} v{version} {k2.babel_translation_directories},
293 289 \n \n please wait installing requirments...
294 290  
295 291  
... ... @@ -296,23 +292,13 @@
296 292 except Exception as e:
297 293 return f'Error installing component: {str(e)}'
298 294  
  295 +
299 296 @components_bp.route('/install-requirments/<string:selected_component_name>', methods=['GET'])
300 297 def install_requirments(selected_component_name):
301   - #menu items api
302   - response = requests.get(f"{k2.domain}{selected_component_name}/menu-items")
303   - if response.status_code == 200:
304   - data = response.json()
305   -
306   - else:
307   - data = []
308   - # add component_name key for menu items
309   - for item in data:
310   - item['component_name'] = selected_component_name
311   - file_path = 'components/menu.yml'
312   - append_to_yaml_file(file_path, data)
  298 + # menu items
313 299 get_admin_menu()
314 300  
315   - #install requirements
  301 + # install requirements
316 302 requirements_file = os.path.join('components', selected_component_name, "requirements.txt")
317 303 if os.path.isfile(requirements_file):
318 304 pip_command = f"{k2.venv_bin_path}/python -m pip install -r {requirements_file}"
... ... @@ -321,6 +307,7 @@
321 307 \n \n please wait installing requirments components...
322 308 <meta http-equiv="refresh" content="1;url=/install-requirments-components" />'''
323 309  
  310 +
324 311 @components_bp.route('/install-requirments-components')
325 312 def install_requirements_components():
326 313 # Откриття файлу requirements_components.txt
327 314  
328 315  
... ... @@ -337,19 +324,20 @@
337 324 return f'Requirements components installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
338 325 else:
339 326 return f'<meta http-equiv="refresh" content="1;url=/dashboard" />'
340   - # Опрацювання відповіді (за потреби)
  327 + # Опрацювання відповіді (за потреби)
341 328  
  329 +
342 330 @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET'])
343 331 def remove_dependencies(component_id):
344 332 # Знаходимо компоненту за її ID
345 333 component = Component.query.get(component_id)
346 334 if not component:
347 335 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />'
348   - #remove menu items
349   - component_name = component.name
350   - file_path = "components/menu.yml"
351   - remove_from_yaml_file(file_path, component_name)
352   -
  336 + # remove menu items
  337 + component_name = component.name
  338 + # file_path = "components/menu.yml"
  339 + # remove_from_yaml_file(file_path, component_name)
  340 + requests.get(f"{k2.domain}api/add-to-menu")
353 341 # remove routes
354 342 file_path = 'routes.py'
355 343 with open(file_path, 'r') as file:
356 344  
357 345  
... ... @@ -364,15 +352,14 @@
364 352  
365 353 return 'Component successfully turn off <meta http-equiv="refresh" content="1;url=/dashboard" />'
366 354  
  355 +
367 356 @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET'])
368 357 def add_dependencies(component_id):
369   -
370 358 # Знаходимо компоненту за її ID
371 359 component = Component.query.get(component_id)
372 360 if not component:
373 361 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />'
374 362  
375   - # Шлях до файлу, з якого потрібно видалити залежності
376 363 file_path = 'routes.py'
377 364 code = component.dependencies
378 365 # Відкриття файлу у режимі дозапису
... ... @@ -385,6 +372,7 @@
385 372 db.session.commit()
386 373 return 'Dependencies added successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
387 374  
  375 +
388 376 @components_bp.route('/remove-component/<string:component_id>')
389 377 def remove_component(component_id):
390 378 # Шлях до головної папки проекту
391 379  
... ... @@ -410,8 +398,80 @@
410 398 # Повертаємо повідомлення про помилку видалення
411 399 return 'Error removing component: ' + str(e)
412 400  
  401 +
  402 +
  403 +
  404 +@components_bp.route('/component/add')
  405 +def component_add():
  406 + # components for install
  407 + try:
  408 + # GET-requests to API
  409 + response = requests.get(f'{k2.update_domain}api/components')
  410 + json_data = response.json()
  411 + for item in json_data:
  412 + item['button'] = f"{k2.domain}/install_components/{item['id']}"
  413 +
  414 + except:
  415 + json_data = None
  416 + return jsonify(json_data)
  417 +
  418 +
  419 +@components_bp.route('/component/list')
  420 +def component_list():
  421 + # Встановлені компоненти
  422 + component_list = []
  423 + components = Component.query.all()
  424 + for component in components:
  425 + component_dict = {}
  426 + component_dict['name'] = component.name
  427 + component_dict['id'] = component.id
  428 + component_dict['description'] = component.description
  429 + component_dict['version'] = component.version
  430 + component_dict['button_off'] =f"{k2.domain}/remove_dependencies/{component.id}"
  431 + component_dict['button_on'] = f"{k2.domain}/add_dependencies/{component.id}"
  432 + component_dict['button_del'] = f"{k2.domain}/remove-component/{component.id}"
  433 + component_list.append(component_dict)
  434 + return jsonify(component_list)
  435 +
  436 +# menu
  437 +@components_bp.route('/api/add-to-menu', methods=['GET'])
  438 +def add_to_menu():
  439 + data = []
  440 + response = requests.get(f"{k2.domain}/menu-admin-items")
  441 + data.append(response.json()[0])
  442 + components = Component.query.all()
  443 + components_names = [component.name for component in components]
  444 + for components_names in components_names:
  445 + response = requests.get(f"{k2.domain}{components_names}/menu-admin-items")
  446 + print(response)
  447 + if response.status_code == 200:
  448 + data.append(response.json()[0])
  449 + else:
  450 + data
  451 + # add component_name key for menu items
  452 + for item in data:
  453 + item['component_name'] = components_names
  454 + k2.menu = data
  455 + return k2.menu
  456 +
  457 +
413 458 @components_bp.route('/api/main-menu/')
414 459 def get_admin_menu():
415 460 requests.get(f"{k2.domain}api/add-to-menu")
416 461 return k2.menu
  462 +
  463 +
  464 +@components_bp.route('/menu-admin-items')
  465 +def menu_items():
  466 + menu = [
  467 + {
  468 + "title": 'Add components',
  469 + "icon": {"icon": 'mdi-account-circle-outline'},
  470 + "children": [
  471 + {'title': 'Install components', 'to': 'component-add'},
  472 + {'title': 'Installed components', 'to': 'component-list'},
  473 +
  474 + ],
  475 + }]
  476 + return menu