Commit d7c01d3dac0148eebc93739a47f33bb87fcc7243

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

add install from reguirments.txt

Showing 6 changed files with 20 additions and 15 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
No preview for this file type
k2/__pycache__/root.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 2 from flask import Flask, Blueprint, jsonify, render_template, redirect, url_for
3 import os 3 import os
4 import shutil 4 import shutil
5 from flask_login import current_user 5 from flask_login import current_user
6 from flask_bcrypt import bcrypt 6 from flask_bcrypt import bcrypt
7 from flask_login import login_user, current_user, logout_user, login_required 7 from flask_login import login_user, current_user, logout_user, login_required
8 import requests
9 from datetime import datetime 8 from datetime import datetime
10 from flask_login import UserMixin 9 from flask_login import UserMixin
11 import uuid 10 import uuid
12 from flask_wtf import FlaskForm 11 from flask_wtf import FlaskForm
13 from wtforms import StringField, PasswordField, SubmitField 12 from wtforms import StringField, PasswordField, SubmitField
14 from wtforms.validators import DataRequired, Length 13 from wtforms.validators import DataRequired, Length
15 import subprocess
16 from flask import request 14 from flask import request
17 from db.database import db 15 from db.database import db
18 from flask_bcrypt import Bcrypt 16 from flask_bcrypt import Bcrypt
19 from flask_login import LoginManager 17 from flask_login import LoginManager
20 from flask_migrate import Migrate 18 from flask_migrate import Migrate
21 from flask import current_app as k2 19 from flask import current_app as k2
22 from main import app 20 from main import app
21 import requests
22 import subprocess
23 from flask import current_app
24
23 import string 25 import string
24 26
25 with app.app_context(): 27 with app.app_context():
26 bcrypt = Bcrypt(app) 28 bcrypt = Bcrypt(app)
27 login_manager = LoginManager(app) 29 login_manager = LoginManager(app)
28 login_manager.login_view = 'login' 30 login_manager.login_view = 'login'
29 31
30 #migrate = Migrate(app, db) 32 #migrate = Migrate(app, db)
31 def generate_id(): 33 def generate_id():
32 generated_id = uuid.uuid4().hex[:32] 34 generated_id = uuid.uuid4().hex[:32]
33 return ''.join([generated_id[i:i + 4] for i in range(0, len(generated_id), 4)]) 35 return ''.join([generated_id[i:i + 4] for i in range(0, len(generated_id), 4)])
34 36
35 class LoginForm(FlaskForm): 37 class LoginForm(FlaskForm):
36 username = StringField('Username', validators=[DataRequired(), Length(min=3, max=20)]) 38 username = StringField('Username', validators=[DataRequired(), Length(min=3, max=20)])
37 password = PasswordField('Password', validators=[DataRequired()]) 39 password = PasswordField('Password', validators=[DataRequired()])
38 submit = SubmitField('Login') 40 submit = SubmitField('Login')
39 41
40 class User(UserMixin, db.Model): 42 class User(UserMixin, db.Model):
41 __bind_key__ = 'db2' 43 __bind_key__ = 'db2'
42 __tablename__ = 'user' 44 __tablename__ = 'user'
43 __table_args__ = {'extend_existing': True} 45 __table_args__ = {'extend_existing': True}
44 id = db.Column(db.String(36), primary_key=True, default=generate_id) 46 id = db.Column(db.String(36), primary_key=True, default=generate_id)
45 username = db.Column(db.String(50)) 47 username = db.Column(db.String(50))
46 active = db.Column(db.Boolean) 48 active = db.Column(db.Boolean)
47 last_name = db.Column(db.String(50)) 49 last_name = db.Column(db.String(50))
48 first_name = db.Column(db.String(50)) 50 first_name = db.Column(db.String(50))
49 middle_name = db.Column(db.String(50)) 51 middle_name = db.Column(db.String(50))
50 email = db.Column(db.String(100)) 52 email = db.Column(db.String(100))
51 phone = db.Column(db.String(20)) 53 phone = db.Column(db.String(20))
52 rights = db.Column(db.String(50)) 54 rights = db.Column(db.String(50))
53 manufacturer = db.Column(db.String(50)) 55 manufacturer = db.Column(db.String(50))
54 manufacturer_id = db.Column(db.Integer) 56 manufacturer_id = db.Column(db.Integer)
55 created_date = db.Column(db.DateTime) 57 created_date = db.Column(db.DateTime)
56 created_by = db.Column(db.String(50)) 58 created_by = db.Column(db.String(50))
57 oblast_id = db.Column(db.Integer) 59 oblast_id = db.Column(db.Integer)
58 password = db.Column(db.String(50)) 60 password = db.Column(db.String(50))
59 #role_id = db.Column(db.Integer, db.ForeignKey('role.id', name='fk_user_role_id')) 61 #role_id = db.Column(db.Integer, db.ForeignKey('role.id', name='fk_user_role_id'))
60 #role = db.relationship('main.Role', backref='users') 62 #role = db.relationship('main.Role', backref='users')
61 def __repr__(self): 63 def __repr__(self):
62 return f'<User {self.username}>' 64 return f'<User {self.username}>'
63 65
64 class Role(db.Model): 66 class Role(db.Model):
65 __bind_key__ = 'db2' 67 __bind_key__ = 'db2'
66 __tablename__ = 'role' 68 __tablename__ = 'role'
67 __table_args__ = {'extend_existing': True} 69 __table_args__ = {'extend_existing': True}
68 id = db.Column(db.String(36), primary_key=True, default=generate_id) 70 id = db.Column(db.String(36), primary_key=True, default=generate_id)
69 name = db.Column(db.String(50)) 71 name = db.Column(db.String(50))
70 sorting = db.Column(db.Integer) 72 sorting = db.Column(db.Integer)
71 note = db.Column(db.String(100)) 73 note = db.Column(db.String(100))
72 enabled = db.Column(db.Boolean) 74 enabled = db.Column(db.Boolean)
73 public = db.Column(db.Boolean) 75 public = db.Column(db.Boolean)
74 is_admin = db.Column(db.Boolean) 76 is_admin = db.Column(db.Boolean)
75 actions = db.Column(db.String(100)) 77 actions = db.Column(db.String(100))
76 def __repr__(self): 78 def __repr__(self):
77 return f'<Role {self.name}>' 79 return f'<Role {self.name}>'
78 def __repr__(self): 80 def __repr__(self):
79 return f'<User {self.username}>' 81 return f'<User {self.username}>'
80 82
81 class Component(db.Model): 83 class Component(db.Model):
82 __bind_key__ = 'db2' 84 __bind_key__ = 'db2'
83 __tablename__ = 'component' 85 __tablename__ = 'component'
84 __table_args__ = {'extend_existing': True} 86 __table_args__ = {'extend_existing': True}
85 id = db.Column(db.String(36), primary_key=True, default=generate_id) 87 id = db.Column(db.String(36), primary_key=True, default=generate_id)
86 name = db.Column(db.String(100), nullable=False) 88 name = db.Column(db.String(100), nullable=False)
87 description = db.Column(db.String(200)) 89 description = db.Column(db.String(200))
88 version = db.Column(db.String(20)) 90 version = db.Column(db.String(20))
89 git_link = db.Column(db.String(200)) 91 git_link = db.Column(db.String(200))
90 dependencies = db.Column(db.String) 92 dependencies = db.Column(db.String)
91 date_installed = db.Column(db.DateTime, default=datetime.utcnow) 93 date_installed = db.Column(db.DateTime, default=datetime.utcnow)
92 installed = db.Column(db.Boolean, default=False) 94 installed = db.Column(db.Boolean, default=False)
93 95
94 def __init__(self, name, description, version, git_link, dependencies, installed): 96 def __init__(self, name, description, version, git_link, dependencies, installed):
95 self.name = name 97 self.name = name
96 self.description = description 98 self.description = description
97 self.version = version 99 self.version = version
98 self.git_link = git_link 100 self.git_link = git_link
99 self.dependencies = dependencies 101 self.dependencies = dependencies
100 self.installed = installed 102 self.installed = installed
101 def __repr__(self): 103 def __repr__(self):
102 return f"Component('{self.name}', '{self.version}')" 104 return f"Component('{self.name}', '{self.version}')"
103 @classmethod 105 @classmethod
104 def get_repository_by_id(self,rep_id): 106 def get_repository_by_id(self,rep_id):
105 component = db.session.query(Component).filter(Component.id == rep_id).first() 107 component = db.session.query(Component).filter(Component.id == rep_id).first()
106 return component 108 return component
107 109
108 components_bp = Blueprint('components', __name__, template_folder='templates') 110 components_bp = Blueprint('components', __name__, template_folder='templates')
109 login_manager = LoginManager(k2) 111 login_manager = LoginManager(k2)
110 @login_manager.user_loader 112 @login_manager.user_loader
111 def load_user(user_id): 113 def load_user(user_id):
112 # Код для завантаження користувача з бази даних за його ідентифікатором 114 # Код для завантаження користувача з бази даних за його ідентифікатором
113 return User.query.get(user_id) 115 return User.query.get(user_id)
114 @components_bp.route('/', methods=['GET', 'POST']) 116 @components_bp.route('/', methods=['GET', 'POST'])
115 def home(): 117 def home():
116 118
117 if current_user.is_authenticated: 119 if current_user.is_authenticated:
118 # Логіка для авторизованого користувача 120 # Логіка для авторизованого користувача
119 return redirect('/dashboard') 121 return redirect('/dashboard')
120 else: 122 else:
121 # Логіка для неавторизованого користувача 123 # Логіка для неавторизованого користувача
122 return redirect('/login') 124 return redirect('/login')
123 @components_bp.route('/login', methods=['GET', 'POST']) 125 @components_bp.route('/login', methods=['GET', 'POST'])
124 def login(): 126 def login():
125 127
126 form = LoginForm() 128 form = LoginForm()
127 if form.validate_on_submit(): 129 if form.validate_on_submit():
128 # Отримання даних з форми 130 # Отримання даних з форми
129 username = form.username.data 131 username = form.username.data
130 password = form.password.data 132 password = form.password.data
131 # Перевірка введених даних 133 # Перевірка введених даних
132 user = User.query.filter_by(username=username).first() 134 user = User.query.filter_by(username=username).first()
133 if user and bcrypt.check_password_hash(user.password, password): # 135 if user and bcrypt.check_password_hash(user.password, password): #
134 login_user(user) 136 login_user(user)
135 return redirect('/dashboard') 137 return redirect('/dashboard')
136 else: 138 else:
137 # Невірні дані для авторизації 139 # Невірні дані для авторизації
138 error_message = f'Неправильне ім`я користувача чи пароль {username} {password} {user.password}' 140 error_message = f'Неправильне ім`я користувача чи пароль {username} {password} {user.password}'
139 141
140 return render_template('/login.html', form=form, error_message=error_message) 142 return render_template('/login.html', form=form, error_message=error_message)
141 143
142 return render_template('/login.html', form=form) 144 return render_template('/login.html', form=form)
143 @components_bp.route('/logout') 145 @components_bp.route('/logout')
144 @login_required 146 @login_required
145 def logout(): 147 def logout():
146 logout_user() 148 logout_user()
147 return redirect('/login') 149 return redirect('/login')
148 @components_bp.route('/dashboard') 150 @components_bp.route('/dashboard')
149 def dashboard(): 151 def dashboard():
150 if not current_user.is_authenticated: 152 if not current_user.is_authenticated:
151 return redirect('/login') 153 return redirect('/login')
152 # Компоненти доступні для встановлення 154 # Компоненти доступні для встановлення
153 try: 155 try:
154 # GET-запит до API 156 # GET-запит до API
155 response = requests.get('http://127.0.0.1:8001/api/components') 157 response = requests.get('http://127.0.0.1:8001/api/components')
156 json_data = response.json() 158 json_data = response.json()
157 # Перетворення JSON-об'єкту на масив 159 # Перетворення JSON-об'єкту на масив
158 component_server = [item for item in json_data] 160 component_server = [item for item in json_data]
159 except: 161 except:
160 component_server = None 162 component_server = None
161 163
162 # Встановлені компоненти 164 # Встановлені компоненти
163 components = Component.query.all() 165 components = Component.query.all()
164 components_names = [component.name for component in components] 166 components_names = [component.name for component in components]
165 167
166 if current_user.is_authenticated: 168 if current_user.is_authenticated:
167 username = current_user.username 169 username = current_user.username
168 users_data = User.query.all() 170 users_data = User.query.all()
169 else: 171 else:
170 username = '' 172 username = ''
171 173
172 174
173 # Отримання значення пошукового запиту з параметрів URL 175 # Отримання значення пошукового запиту з параметрів URL
174 search_query = request.args.get('search_query') 176 search_query = request.args.get('search_query')
175 #print(search_query) 177 #print(search_query)
176 filtered_components = [] 178 filtered_components = []
177 if search_query: 179 if search_query:
178 filtered_components = [component for component in component_server if 180 filtered_components = [component for component in component_server if
179 (search_query.lower() in component['name'].lower() if component['name'] else False) or 181 (search_query.lower() in component['name'].lower() if component['name'] else False) or
180 (search_query.lower() in component['description'].lower() if component[ 182 (search_query.lower() in component['description'].lower() if component[
181 'description'] else False)] 183 'description'] else False)]
182 else: 184 else:
183 filtered_components = component_server 185 filtered_components = component_server
184 186
185 return render_template('dashboard.html', username=username, users=users_data, components=components, 187 return render_template('dashboard.html', username=username, users=users_data, components=components,
186 components_names=components_names, component_server=filtered_components, 188 components_names=components_names, component_server=filtered_components,
187 search_query=search_query) 189 search_query=search_query)
188 190
189 @components_bp.route('/show_components/<string:component_id>') 191 @components_bp.route('/show_components/<string:component_id>')
190 @login_required 192 @login_required
191 def show_components(component_id): 193 def show_components(component_id):
192 response = requests.get('http://127.0.0.1:8001/api/components') 194 response = requests.get('http://127.0.0.1:8001/api/components')
193 json_data = response.json() 195 json_data = response.json()
194 selected_component = next((component for component in json_data if component['id'] == component_id), None) 196 selected_component = next((component for component in json_data if component['id'] == component_id), None)
195 return render_template('component-info.html', selected_component=selected_component) 197 return render_template('component-info.html', selected_component=selected_component)
196 198
197 @components_bp.route('/install_components_bl/<string:component_id>') 199 @components_bp.route('/install_components_bl/<string:component_id>')
198 @login_required 200 @login_required
199 def install_components_bl(component_id): 201 def install_components_bl(component_id):
200 # Шлях до головної папки проекту 202 # Шлях до головної папки проекту
201 project_folder = 'components' 203 project_folder = 'components'
202 #component = Component.get_repository_by_id(component_id) 204 #component = Component.get_repository_by_id(component_id)
203 response = requests.get('http://127.0.0.1:8001/api/components') 205 response = requests.get('http://127.0.0.1:8001/api/components')
204 json_data = response.json() 206 json_data = response.json()
205 selected_component = next((component for component in json_data if component['id'] == component_id), None) 207 selected_component = next((component for component in json_data if component['id'] == component_id), None)
206 # Назва репозиторія 208 # Назва репозиторія
207 repository_name = selected_component['name'] 209 repository_name = selected_component['name']
208 # Шлях до папки репозиторія в межах проекту 210 # Шлях до папки репозиторія в межах проекту
209 repository_folder = os.path.join(project_folder, repository_name) 211 repository_folder = os.path.join(project_folder, repository_name)
210 # URL репозиторія 212 # URL репозиторія
211 213
212 214
213 git_repo_url = selected_component['git_link'] 215 git_repo_url = selected_component['git_link']
214 try: 216 try:
215 # Перевірка наявності папки репозиторія 217 # Перевірка наявності папки репозиторія
216 if not os.path.exists(repository_folder): 218 if not os.path.exists(repository_folder):
217 # Створення папки репозиторія 219 # Створення папки репозиторія
218 os.makedirs(repository_folder) 220 os.makedirs(repository_folder)
219 # Шлях до файлу __init__.py 221 # Шлях до файлу __init__.py
220 init_file = os.path.join(repository_folder, '__init__.py') 222 init_file = os.path.join(repository_folder, '__init__.py')
221 # Перевірка наявності файлу __init__.py 223 # Перевірка наявності файлу __init__.py
222 if not os.path.exists(init_file): 224 if not os.path.exists(init_file):
223 # Створення пустого файлу __init__.py 225 # Створення пустого файлу __init__.py
224 open(init_file, 'a').close() 226 open(init_file, 'a').close()
225 #підключення до приватного репозиторію 227 #підключення до приватного репозиторію
226 #os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW' 228 #os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW'
227 #git_repo_url_with_token = git_repo_url.replace('https://', 229 #git_repo_url_with_token = git_repo_url.replace('https://',
228 # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@') 230 # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@')
229 231
230 # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія 232 # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія
231 command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url, '--target=' + repository_folder] 233 command = ['venv/Scripts/python.exe', '-m', 'pip', 'install', '--use-pep517', 'git+' + git_repo_url, '--target=' + repository_folder]
232 # Виконуємо команду встановлення 234 # Виконуємо команду встановлення
233 subprocess.check_call(command) 235 subprocess.check_call(command)
234 236
235 # Шлях до файлу, до якого потрібно додати код 237 # Шлях до файлу, до якого потрібно додати код
236 file_path = 'routes.py' 238 file_path = 'routes.py'
237 # Код, який потрібно додати 239 # Код, який потрібно додати
238 code = selected_component['dependencies'] 240 code = selected_component['dependencies']
239 # Відкриття файлу у режимі дозапису 241 # Відкриття файлу у режимі дозапису
240 with open(file_path, 'a') as file: 242 with open(file_path, 'a') as file:
241 # Запис нового коду у файл 243 # Запис нового коду у файл
242 file.write('\n') 244 file.write('\n')
243 file.write(code) 245 file.write(code)
244 file.write('\n') 246 file.write('\n')
245 component = Component.query.filter_by(name=selected_component['name']).first() 247 component = Component.query.filter_by(name=selected_component['name']).first()
246 if not component: 248 if not component:
247 new_component = Component( 249 new_component = Component(
248 name=selected_component['name'], 250 name=selected_component['name'],
249 description=selected_component['description'], 251 description=selected_component['description'],
250 version=selected_component['version'], 252 version=selected_component['version'],
251 git_link=selected_component['git_link'], 253 git_link=selected_component['git_link'],
252 dependencies=selected_component['dependencies'], 254 dependencies=selected_component['dependencies'],
253 installed=True 255 installed=True
254 ) 256 )
255 # Add the new component to the database 257 # Add the new component to the database
256 db.session.add(new_component) 258 db.session.add(new_component)
257 db.session.commit() 259 db.session.commit()
258 260
259 # Повертаємо повідомлення про успішне встановлення 261 # Повертаємо повідомлення про успішне встановлення
260 return f'Installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 262 return f'Installed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
261 except subprocess.CalledProcessError as e: 263 except subprocess.CalledProcessError as e:
262 return 'Error installing : ' + str(e) 264 return 'Error installing : ' + str(e)
263 265
264 266
265 import os
266 import requests
267 import shutil
268 import subprocess
269 from flask import current_app
270
271
272 @components_bp.route('/install_components/<string:component_id>') 267 @components_bp.route('/install_components/<string:component_id>')
273 @login_required 268 @login_required
274 def install_component_from_archive(component_id): 269 def install_component_from_archive(component_id):
275 # Шлях до головної папки проекту 270 # Шлях до головної папки проекту
276 project_folder = 'components' 271 project_folder = 'components'
277 # Отримати відповідну компоненту зі списку компонент 272 # Отримати відповідну компоненту зі списку компонент
278 response = requests.get('http://127.0.0.1:8001/api/components') 273 response = requests.get('http://127.0.0.1:8001/api/components')
279 json_data = response.json() 274 json_data = response.json()
280 selected_component = next((component for component in json_data if component['id'] == component_id), None) 275 selected_component = next((component for component in json_data if component['id'] == component_id), None)
281 if selected_component is None: 276 if selected_component is None:
282 return 'Component not found' 277 return 'Component not found'
283 # Отримати посилання на архів компоненти та версію 278 # Отримати посилання на архів компоненти та версію
284 archive_url = selected_component['latest_component_data'] 279 archive_url = selected_component['latest_component_data']
285 version = selected_component['latest_version'] 280 version = selected_component['latest_version']
286 try: 281 try:
287 # Створити шлях до папки компоненти згідно назви та версії 282 # Створити шлях до папки компоненти згідно назви та версії
288 component_folder = os.path.join(project_folder) 283 component_folder = os.path.join(project_folder)
289 os.makedirs(component_folder, exist_ok=True) 284 os.makedirs(component_folder, exist_ok=True)
290 # Завантажити архів компоненти 285 # Завантажити архів компоненти
291 response = requests.get(archive_url, stream=True) 286 response = requests.get(archive_url, stream=True)
292 response.raise_for_status() 287 response.raise_for_status()
293 # Шлях до завантаженого архіву 288 # Шлях до завантаженого архіву
294 archive_path = os.path.join(component_folder, f"{selected_component['name']}.zip") 289 archive_path = os.path.join(component_folder, f"{selected_component['name']}.zip")
290 # Встановити залежності з файлу requirements.txt
291
295 # Зберегти архів на диск 292 # Зберегти архів на диск
296 with open(archive_path, "wb") as file: 293 with open(archive_path, "wb") as file:
297 for chunk in response.iter_content(chunk_size=8192): 294 for chunk in response.iter_content(chunk_size=8192):
298 file.write(chunk) 295 file.write(chunk)
299 # Розпакувати архів 296 # Розпакувати архів
300 with zipfile.ZipFile(archive_path, "r") as zip_ref: 297 with zipfile.ZipFile(archive_path, "r") as zip_ref:
301 zip_ref.extractall(component_folder) 298 zip_ref.extractall(component_folder)
299
302 # Видалити архів 300 # Видалити архів
303 os.remove(archive_path) 301 os.remove(archive_path)
304 # Встановити залежності з файлу requirements.txt 302
305 requirements_file = os.path.join(component_folder, "requirements.txt")
306 if os.path.isfile(requirements_file):
307 pip_command = f"{current_app.config['VENV_BIN_PATH']}/python -m pip install -r {requirements_file}"
308 subprocess.run(pip_command, shell=True, check=True)
309 # Шлях до файлу, до якого потрібно додати код 303 # Шлях до файлу, до якого потрібно додати код
310 file_path = 'routes.py' 304 file_path = 'routes.py'
311 # Код, який потрібно додати 305 # Код, який потрібно додати
312 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']}')''' 306 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']}')'''
313 #selected_component['dependencies'] 307 #selected_component['dependencies']
314 308
315 # Відкриття файлу у режимі дозапису 309 # Відкриття файлу у режимі дозапису
316 with open(file_path, 'a') as file: 310 with open(file_path, 'a') as file:
317 # Запис нового коду у файл 311 # Запис нового коду у файл
318 file.write('\n') 312 file.write('\n')
319 file.write(code) 313 file.write(code)
320 file.write('\n') 314 file.write('\n')
321 315
316
322 # Оновити базу даних з встановленою компонентою 317 # Оновити базу даних з встановленою компонентою
323 component = Component.query.filter_by(name=selected_component['name']).first() 318 component = Component.query.filter_by(name=selected_component['name']).first()
324 if not component: 319 if not component:
325 component = Component( 320 component = Component(
326 name=selected_component['name'], 321 name=selected_component['name'],
327 description=selected_component['description'], 322 description=selected_component['description'],
328 version=version, 323 version=version,
329 git_link=selected_component['git_link'], 324 git_link=selected_component['git_link'],
330 dependencies=code, 325 dependencies=code,
331 installed=True 326 installed=True
332 ) 327 )
333 db.session.add(component) 328 db.session.add(component)
334 else: 329 else:
335 component.version = version 330 component.version = version
336 component.git_link = selected_component['git_link'] 331 component.git_link = selected_component['git_link']
337 component.dependencies = code 332 component.dependencies = code
338 component.installed = True 333 component.installed = True
339 334
340 db.session.commit() 335 db.session.commit()
341 336
342 return f'Component installed successfully: {selected_component["name"]} v{version} <meta http-equiv="refresh" content="1;url=/dashboard" />' 337 return f'Component installed successfully: {selected_component["name"]} v{version}, please wait installing requirments... <meta http-equiv="refresh" content="0;url=/install-requirments/{selected_component["name"]}" />'
343 338
344 except Exception as e: 339 except Exception as e:
345 return f'Error installing component: {str(e)}' 340 return f'Error installing component: {str(e)}'
341
342 @components_bp.route('/install-requirments/<string:selected_component_name>', methods=['GET'])
343 @login_required
344 def install_requirments(selected_component_name):
345 requirements_file = os.path.join('components', selected_component_name, "requirements.txt")
346 if os.path.isfile(requirements_file):
347 pip_command = f"{current_app.config['VENV_BIN_PATH']}/python -m pip install -r {requirements_file}"
348 subprocess.run(pip_command, shell=True, check=True)
349 return f'Requirements installed successfully: <meta http-equiv="refresh" content="1;url=/dashboard" />'
346 350
347 351
348 @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET']) 352 @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET'])
349 @login_required 353 @login_required
350 def remove_dependencies(component_id): 354 def remove_dependencies(component_id):
351 355
352 # Знаходимо компоненту за її ID 356 # Знаходимо компоненту за її ID
353 component = Component.query.get(component_id) 357 component = Component.query.get(component_id)
354 if not component: 358 if not component:
355 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />' 359 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />'
356 360
357 # Шлях до файлу, з якого потрібно видалити залежності 361 # Шлях до файлу, з якого потрібно видалити залежності
358 file_path = 'routes.py' 362 file_path = 'routes.py'
359 363
360 # Зчитуємо вміст файлу 364 # Зчитуємо вміст файлу
361 with open(file_path, 'r') as file: 365 with open(file_path, 'r') as file:
362 lines = file.readlines() 366 lines = file.readlines()
363 367
364 # Видаляємо рядки, що містять залежності компоненти 368 # Видаляємо рядки, що містять залежності компоненти
365 updated_lines = [line for line in lines if line.strip() not in component.dependencies] 369 updated_lines = [line for line in lines if line.strip() not in component.dependencies]
366 370
367 # Записуємо оновлений вміст у файл 371 # Записуємо оновлений вміст у файл
368 with open(file_path, 'w') as file: 372 with open(file_path, 'w') as file:
369 file.writelines(updated_lines) 373 file.writelines(updated_lines)
370 374
371 # Оновлюємо статус компоненти 375 # Оновлюємо статус компоненти
372 component.installed = False 376 component.installed = False
373 db.session.commit() 377 db.session.commit()
374 378
375 return 'Dependencies removed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 379 return 'Dependencies removed successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
376 380
377 @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET']) 381 @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET'])
378 @login_required 382 @login_required
379 def add_dependencies(component_id): 383 def add_dependencies(component_id):
380 384
381 # Знаходимо компоненту за її ID 385 # Знаходимо компоненту за її ID
382 component = Component.query.get(component_id) 386 component = Component.query.get(component_id)
383 if not component: 387 if not component:
384 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />' 388 return 'Component not found <meta http-equiv="refresh" content="1;url=/dashboard" />'
385 389
386 # Шлях до файлу, з якого потрібно видалити залежності 390 # Шлях до файлу, з якого потрібно видалити залежності
387 file_path = 'routes.py' 391 file_path = 'routes.py'
388 code = component.dependencies 392 code = component.dependencies
389 # Відкриття файлу у режимі дозапису 393 # Відкриття файлу у режимі дозапису
390 with open(file_path, 'a') as file: 394 with open(file_path, 'a') as file:
391 # Запис нового коду у файл 395 # Запис нового коду у файл
392 file.write(code) 396 file.write(code)
393 397
394 # Оновлюємо статус компоненти 398 # Оновлюємо статус компоненти
395 component.installed = True 399 component.installed = True
396 db.session.commit() 400 db.session.commit()
397 return 'Dependencies added successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' 401 return 'Dependencies added successfully <meta http-equiv="refresh" content="1;url=/dashboard" />'
398 402
399 @components_bp.route('/remove-component/<string:component_id>') 403 @components_bp.route('/remove-component/<string:component_id>')
400 @login_required 404 @login_required
401 def remove_component(component_id): 405 def remove_component(component_id):
402 # Шлях до головної папки проекту 406 # Шлях до головної папки проекту
403 project_folder = 'components' 407 project_folder = 'components'
404 component = Component.query.get(component_id) 408 component = Component.query.get(component_id)
405 # Назва репозиторія 409 # Назва репозиторія
406 repository_name = component.name 410 repository_name = component.name
407 # Шлях до папки репозиторія в межах проекту 411 # Шлях до папки репозиторія в межах проекту
408 repository_folder = os.path.join(project_folder, repository_name) 412 repository_folder = os.path.join(project_folder, repository_name)
409 try: 413 try:
410 # Перевірка наявності папки репозиторія 414 # Перевірка наявності папки репозиторія
411 if os.path.exists(repository_folder): 415 if os.path.exists(repository_folder):
1 import pytz 1 import pytz
2 from flask import Flask 2 from flask import Flask
3 from flask_cors import CORS 3 from flask_cors import CORS
4 from db.database import init_db 4 from db.database import init_db
5 5
6 6
7 # configure flask app 7 # configure flask app
8 app = Flask(__name__) 8 app = Flask(__name__)
9 app.config['JSON_SORT_KEYS'] = False 9 app.config['JSON_SORT_KEYS'] = False
10 app.config['TIMEZONE'] = pytz.timezone('Europe/Kiev') 10 app.config['TIMEZONE'] = pytz.timezone('Europe/Kiev')
11 app.config['SECRET_KEY'] = 'JH&INH987gFDHdsagh&8dwbjdw8ckw' 11 app.config['SECRET_KEY'] = 'JH&INH987gFDHdsagh&8dwbjdw8ckw'
12 app.config['DOMAIN'] = 'http://127.0.0.1:5001/' 12 app.config['DOMAIN'] = 'http://127.0.0.1:5001/'
13 app.config['VENV_BIN_PATH'] = 'C:/Users/sv-work/PycharmProjects/k2root/venv/Scripts'
13 # setting flask app 14 # setting flask app
14 init_db(app) 15 init_db(app)
15 CORS(app) 16 CORS(app)
16 from k2.root import * 17 from k2.root import *
17 18
18 19
19 # реєстрація роутів 20 # реєстрація роутів
20 21
21 from routes import * 22 from routes import *
22 if __name__ == '__main__': 23 if __name__ == '__main__':
23 app.run(debug=True, port=5000) 24 app.run(debug=True, port=5000)
24 25
25 26
26 27