Commit 4d53c4ce922296ede5df394ad70dddf121bb564c

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

fix update server

Showing 22 changed files with 3 additions and 104 deletions Inline Diff

__pycache__/routes.cpython-310.pyc
No preview for this file type
components/k2test/README.md
1 Base k2 component File was deleted
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
1 1.0.0.0 base component File was deleted
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
1 msgid "New 2 page" File was deleted
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
1 msgid "New 2 page" File was deleted
2 msgstr "Нова сторінка 2"
3 msgid "title_menu_items"
4 msgstr "Тестова компонента"
components/k2test/k2test/templates/new2.html
1 File was deleted
2
3 <h2>{{ _('New 2 page') }}</h2>
components/k2test/k2test/views.py
1 from flask import render_template, redirect, request, jsonify File was deleted
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 1 from flask import render_template, redirect, request, jsonify
52 2 from flask_babel import gettext
components/k2test/reguirments-components.txt
1 grid==1.0.1 File was deleted
components/k2test/requirements.txt
1 Flask-Login==0.6.2 File was deleted
2 1 Flask-Login==0.6.2
components/k2test/setup.py
1 from setuptools import setup, find_packages File was deleted
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 1 from setuptools import setup, find_packages
No preview for this file type
k2/__pycache__/k2rout.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, 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 import platform
21 21
22 22
23 # initialize db 23 # initialize db
24 # migrate = Migrate(app, db) 24 # migrate = Migrate(app, db)
25 25
26 components_bp = Blueprint('components', __name__, template_folder='templates') 26 components_bp = Blueprint('components', __name__, template_folder='templates')
27 config = yaml.safe_load(open("db/first-login.yml")) 27 config = yaml.safe_load(open("db/first-login.yml"))
28 28
29 db = k2.db 29 db = k2.db
30 30
31 31
32 def first_login_required(view_func): 32 def first_login_required(view_func):
33 @wraps(view_func) 33 @wraps(view_func)
34 def decorated_view(*args, **kwargs): 34 def decorated_view(*args, **kwargs):
35 if 'username' not in session: 35 if 'username' not in session:
36 return redirect(url_for('components.first_login')) 36 return redirect(url_for('components.first_login'))
37 return view_func(*args, **kwargs) 37 return view_func(*args, **kwargs)
38 38
39 return decorated_view 39 return decorated_view
40 40
41 # def append_to_yaml_file(file_path, data): 41 # def append_to_yaml_file(file_path, data):
42 # with open(file_path, 'r') as f: 42 # with open(file_path, 'r') as f:
43 # existing_data = yaml.safe_load(f) or [] 43 # existing_data = yaml.safe_load(f) or []
44 # 44 #
45 # if not existing_data: 45 # if not existing_data:
46 # start_id = 1 46 # start_id = 1
47 # else: 47 # else:
48 # 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
49 # 49 #
50 # for i, item in enumerate(data, start=start_id): 50 # for i, item in enumerate(data, start=start_id):
51 # item['id'] = i 51 # item['id'] = i
52 # existing_data.append(item) 52 # existing_data.append(item)
53 # 53 #
54 # with open(file_path, 'w') as f: 54 # with open(file_path, 'w') as f:
55 # yaml.dump(existing_data, f, default_flow_style=False) 55 # yaml.dump(existing_data, f, default_flow_style=False)
56 56
57 def remove_from_yaml_file(file_path, component_name): 57 def remove_from_yaml_file(file_path, component_name):
58 with open(file_path, 'r') as f: 58 with open(file_path, 'r') as f:
59 existing_data = yaml.safe_load(f) or [] 59 existing_data = yaml.safe_load(f) or []
60 60
61 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]
62 62
63 with open(file_path, 'w') as f: 63 with open(file_path, 'w') as f:
64 yaml.dump(updated_data, f, default_flow_style=False) 64 yaml.dump(updated_data, f, default_flow_style=False)
65 65
66 66
67 @components_bp.route('/api/languages', methods=['GET']) 67 @components_bp.route('/api/languages', methods=['GET'])
68 def find_language(): 68 def find_language():
69 components = Component.query.all() 69 components = Component.query.all()
70 languages_paths = [] 70 languages_paths = []
71 # Додаємо головну директорію languages 71 # Додаємо головну директорію languages
72 languages_paths.append('languages') 72 languages_paths.append('languages')
73 # Знаходимо шляхи до директорій languages всередині папки components 73 # Знаходимо шляхи до директорій languages всередині папки components
74 for component in components: 74 for component in components:
75 component_languages_directory = 'components/' + component.name + '/' + component.name + '/languages' 75 component_languages_directory = 'components/' + component.name + '/' + component.name + '/languages'
76 languages_paths.append(component_languages_directory) 76 languages_paths.append(component_languages_directory)
77 result = ';'.join(languages_paths) 77 result = ';'.join(languages_paths)
78 print(result) 78 print(result)
79 return result 79 return result
80 80
81 81
82 @components_bp.route('/', methods=['GET', 'POST']) 82 @components_bp.route('/', methods=['GET', 'POST'])
83 def home(): 83 def home():
84 components = Component.query.all() 84 components = Component.query.all()
85 components_names = [component.name for component in components] 85 components_names = [component.name for component in components]
86 if 'k2site' in components_names: 86 if 'k2site' in components_names:
87 return redirect(url_for('components.component_add_dasb')) #змінити на ендпоінт головної k2site 87 return redirect(url_for('k2site.main_page')) #змінити на ендпоінт головної k2site
88 else: 88 else:
89 return redirect('/dashboard') 89 return redirect('/dashboard')
90 90
91 91
92 92
93 @components_bp.route('/first-login', methods=['GET', 'POST']) 93 @components_bp.route('/first-login', methods=['GET', 'POST'])
94 def first_login(): 94 def first_login():
95 if request.method == "POST": 95 if request.method == "POST":
96 username = request.form.get("username") 96 username = request.form.get("username")
97 password = request.form.get("password") 97 password = request.form.get("password")
98 for user in config["users"]: 98 for user in config["users"]:
99 if user["username"] == username and user["password"] == password: 99 if user["username"] == username and user["password"] == password:
100 session['username'] = username # Збереження ім'я користувача в сесії 100 session['username'] = username # Збереження ім'я користувача в сесії
101 return redirect(url_for('components.dashboard')) 101 return redirect(url_for('components.dashboard'))
102 return "Невірне ім'я користувача або пароль." 102 return "Невірне ім'я користувача або пароль."
103 return render_template('first-login.html') 103 return render_template('first-login.html')
104 104
105 105
106 @components_bp.route('/change_language/<lang>') 106 @components_bp.route('/change_language/<lang>')
107 def change_language(lang): 107 def change_language(lang):
108 session['lang'] = lang 108 session['lang'] = lang
109 k2.current_language = lang 109 k2.current_language = lang
110 return redirect(request.referrer) 110 return redirect(request.referrer)
111 111
112 112
113 @components_bp.route('/dashboard') 113 @components_bp.route('/dashboard')
114 def dashboard(): 114 def dashboard():
115 components = Component.query.all() 115 components = Component.query.all()
116 components_names = [] 116 components_names = []
117 components_names = [component.name for component in components] 117 components_names = [component.name for component in components]
118 if 'k2site' in components_names: 118 if 'k2site' in components_names:
119 return redirect(url_for('components.home')) 119 return redirect(url_for('components.home'))
120 else: 120 else:
121 # Компоненти доступні для встановлення 121 # Компоненти доступні для встановлення
122 # GET-запит до API 122 # GET-запит до API
123 try: 123 try:
124 response = requests.get(f'{k2.update_domain}api/components') 124 response = requests.get(f'{k2.update_domain}api/components')
125 json_data = response.json() 125 json_data = response.json()
126 # Перетворення JSON-об'єкту на масив 126 # Перетворення JSON-об'єкту на масив
127 component_server = [item for item in json_data] 127 component_server = [item for item in json_data]
128 except: 128 except:
129 component_server = None 129 component_server = None
130 130
131 # Встановлені компоненти 131 # Встановлені компоненти
132 components = Component.query.all() 132 components = Component.query.all()
133 components_names = [component.name for component in components] 133 components_names = [component.name for component in components]
134 # Отримання значення пошукового запиту з параметрів URL 134 # Отримання значення пошукового запиту з параметрів URL
135 search_query = request.args.get('search_query') 135 search_query = request.args.get('search_query')
136 # print(search_query) 136 # print(search_query)
137 filtered_components = [] 137 filtered_components = []
138 if search_query: 138 if search_query:
139 filtered_components = [component for component in component_server if 139 filtered_components = [component for component in component_server if
140 (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
141 (search_query.lower() in component['description'].lower() if component[ 141 (search_query.lower() in component['description'].lower() if component[
142 'description'] else False)] 142 'description'] else False)]
143 else: 143 else:
144 filtered_components = component_server 144 filtered_components = component_server
145 current_language = k2.current_language 145 current_language = k2.current_language
146 146
147 return render_template('dashboard.html', components=components, 147 return render_template('dashboard.html', components=components,
148 components_names=components_names, component_server=filtered_components, 148 components_names=components_names, component_server=filtered_components,
149 search_query=search_query, language=current_language) 149 search_query=search_query, language=current_language)
150 150
151 151
152 @components_bp.route('/show_components/<string:component_id>') 152 @components_bp.route('/show_components/<string:component_id>')
153 def show_components(component_id): 153 def show_components(component_id):
154 response = requests.get(f'{k2.update_domain}api/components') 154 response = requests.get(f'{k2.update_domain}api/components')
155 json_data = response.json() 155 json_data = response.json()
156 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)
157 return render_template('component-info.html', selected_component=selected_component) 157 return render_template('component-info.html', selected_component=selected_component)
158 158
159 159
160 @components_bp.route('/show_components-site/<string:component_id>') 160 @components_bp.route('/show_components-site/<string:component_id>')
161 def show_components_site(component_id): 161 def show_components_site(component_id):
162 response = requests.get(f'{k2.update_domain}api/components') 162 response = requests.get(f'{k2.update_domain}api/components')
163 json_data = response.json() 163 json_data = response.json()
164 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)
165 return render_template('component-info-site.html', selected_component=selected_component) 165 return render_template('component-info-site.html', selected_component=selected_component)
166 166
167 167
168 @components_bp.route('/install_components_git/<string:component_id>') 168 @components_bp.route('/install_components_git/<string:component_id>')
169 def install_components_git(component_id): 169 def install_components_git(component_id):
170 # Шлях до головної папки проекту 170 # Шлях до головної папки проекту
171 project_folder = 'components' 171 project_folder = 'components'
172 # component = Component.get_repository_by_id(component_id) 172 # component = Component.get_repository_by_id(component_id)
173 response = requests.get(f'{k2.update_domain}api/components') 173 response = requests.get(f'{k2.update_domain}api/components')
174 json_data = response.json() 174 json_data = response.json()
175 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)
176 # Назва репозиторія 176 # Назва репозиторія
177 repository_name = selected_component['name'] 177 repository_name = selected_component['name']
178 # Шлях до папки репозиторія в межах проекту 178 # Шлях до папки репозиторія в межах проекту
179 repository_folder = os.path.join(project_folder, repository_name) 179 repository_folder = os.path.join(project_folder, repository_name)
180 # URL репозиторія 180 # URL репозиторія
181 181
182 git_repo_url = selected_component['git_link'] 182 git_repo_url = selected_component['git_link']
183 try: 183 try:
184 # Перевірка наявності папки репозиторія 184 # Перевірка наявності папки репозиторія
185 if not os.path.exists(repository_folder): 185 if not os.path.exists(repository_folder):
186 # Створення папки репозиторія 186 # Створення папки репозиторія
187 os.makedirs(repository_folder) 187 os.makedirs(repository_folder)
188 # Шлях до файлу __init__.py 188 # Шлях до файлу __init__.py
189 init_file = os.path.join(repository_folder, '__init__.py') 189 init_file = os.path.join(repository_folder, '__init__.py')
190 # Перевірка наявності файлу __init__.py 190 # Перевірка наявності файлу __init__.py
191 if not os.path.exists(init_file): 191 if not os.path.exists(init_file):
192 # Створення пустого файлу __init__.py 192 # Створення пустого файлу __init__.py
193 open(init_file, 'a').close() 193 open(init_file, 'a').close()
194 # підключення до приватного репозиторію 194 # підключення до приватного репозиторію
195 # os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW' 195 # os.environ['GITLAB_PRIVATE_TOKEN'] = '8xxTpxrKVDGoXD5ynjiW'
196 # git_repo_url_with_token = git_repo_url.replace('https://', 196 # git_repo_url_with_token = git_repo_url.replace('https://',
197 # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@') 197 # f'https://oauth2:{os.environ["GITLAB_PRIVATE_TOKEN"]}@')
198 198
199 # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія 199 # Команда для встановлення з використанням git_repo_url і повного шляху до папки репозиторія
200 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,
201 '--target=' + repository_folder] 201 '--target=' + repository_folder]
202 # Виконуємо команду встановлення 202 # Виконуємо команду встановлення
203 subprocess.check_call(command) 203 subprocess.check_call(command)
204 204
205 # Шлях до файлу, до якого потрібно додати код 205 # Шлях до файлу, до якого потрібно додати код
206 file_path = 'routes.py' 206 file_path = 'routes.py'
207 # Код, який потрібно додати 207 # Код, який потрібно додати
208 code = selected_component['dependencies'] 208 code = selected_component['dependencies']
209 # Відкриття файлу у режимі дозапису 209 # Відкриття файлу у режимі дозапису
210 with open(file_path, 'a') as file: 210 with open(file_path, 'a') as file:
211 # Запис нового коду у файл 211 # Запис нового коду у файл
212 file.write('\n') 212 file.write('\n')
213 file.write(code) 213 file.write(code)
214 file.write('\n') 214 file.write('\n')
215 component = Component.query.filter_by(name=selected_component['name']).first() 215 component = Component.query.filter_by(name=selected_component['name']).first()
216 if not component: 216 if not component:
217 new_component = Component( 217 new_component = Component(
218 name=selected_component['name'], 218 name=selected_component['name'],
219 description=selected_component['description'], 219 description=selected_component['description'],
220 version=selected_component['version'], 220 version=selected_component['version'],
221 git_link=selected_component['git_link'], 221 git_link=selected_component['git_link'],
222 dependencies=selected_component['dependencies'], 222 dependencies=selected_component['dependencies'],
223 installed=True 223 installed=True
224 ) 224 )
225 # Add the new component to the database 225 # Add the new component to the database
226 db.session.add(new_component) 226 db.session.add(new_component)
227 db.session.commit() 227 db.session.commit()
228 228
229 # Повертаємо повідомлення про успішне встановлення 229 # Повертаємо повідомлення про успішне встановлення
230 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" />'
231 except subprocess.CalledProcessError as e: 231 except subprocess.CalledProcessError as e:
232 return 'Error installing : ' + str(e) 232 return 'Error installing : ' + str(e)
233 233
234 234
235 @components_bp.route('/install_components/<string:component_id>') 235 @components_bp.route('/install_components/<string:component_id>')
236 def install_component_from_archive(component_id): 236 def install_component_from_archive(component_id):
237 # Шлях до головної папки проекту 237 # Шлях до головної папки проекту
238 project_folder = 'components' 238 project_folder = 'components'
239 # Отримати відповідну компоненту зі списку компонент 239 # Отримати відповідну компоненту зі списку компонент
240 response = requests.get(f'{k2.update_domain}api/components') 240 response = requests.get(f'{k2.update_domain}api/components')
241 json_data = response.json() 241 json_data = response.json()
242 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)
243 if selected_component is None: 243 if selected_component is None:
244 return 'Component not found' 244 return 'Component not found'
245 # Отримати посилання на архів компоненти та версію 245 # Отримати посилання на архів компоненти та версію
246 archive_url = selected_component['latest_component_data'] 246 archive_url = selected_component['latest_component_data']
247 version = selected_component['latest_version'] 247 version = selected_component['latest_version']
248 try: 248 try:
249 # Створити шлях до папки компоненти згідно назви та версії 249 # Створити шлях до папки компоненти згідно назви та версії
250 component_folder = os.path.join(project_folder) 250 component_folder = os.path.join(project_folder)
251 os.makedirs(component_folder, exist_ok=True) 251 os.makedirs(component_folder, exist_ok=True)
252 # Завантажити архів компоненти 252 # Завантажити архів компоненти
253 response = requests.get(archive_url, stream=True) 253 response = requests.get(archive_url, stream=True)
254 response.raise_for_status() 254 response.raise_for_status()
255 # Шлях до завантаженого архіву 255 # Шлях до завантаженого архіву
256 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")
257 # Зберегти архів на диск 257 # Зберегти архів на диск
258 with open(archive_path, "wb") as file: 258 with open(archive_path, "wb") as file:
259 for chunk in response.iter_content(chunk_size=8192): 259 for chunk in response.iter_content(chunk_size=8192):
260 file.write(chunk) 260 file.write(chunk)
261 # Розпакувати архів 261 # Розпакувати архів
262 with zipfile.ZipFile(archive_path, "r") as zip_ref: 262 with zipfile.ZipFile(archive_path, "r") as zip_ref:
263 zip_ref.extractall(component_folder) 263 zip_ref.extractall(component_folder)
264 # Видалити архів 264 # Видалити архів
265 os.remove(archive_path) 265 os.remove(archive_path)
266 #перейменувати якщо git 266 #перейменувати якщо git
267 component_name = selected_component['name'] 267 component_name = selected_component['name']
268 old_folder_path = os.path.join(component_folder, component_name + ".git") 268 old_folder_path = os.path.join(component_folder, component_name + ".git")
269 new_folder_path = os.path.join(component_folder, component_name) 269 new_folder_path = os.path.join(component_folder, component_name)
270 # Перевірка наявності папки зі старою назвою 270 # Перевірка наявності папки зі старою назвою
271 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):
272 # Перейменування папки зі старою назвою на нову назву 272 # Перейменування папки зі старою назвою на нову назву
273 os.rename(old_folder_path, new_folder_path) 273 os.rename(old_folder_path, new_folder_path)
274 274
275 # Шлях до файлу, до якого потрібно додати роути 275 # Шлях до файлу, до якого потрібно додати роути
276 file_path = 'routes.py' 276 file_path = 'routes.py'
277 # Код, який потрібно додати 277 # Код, який потрібно додати
278 if component_name == 'k2grid_base': 278 if component_name == 'k2grid_base':
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 code = f'''from components.{selected_component['name']}.{selected_component['name']}.views import {selected_component['name']}\napp.register_blueprint({selected_component['name']}, url_prefix='/')'''
280 elif component_name == 'k2site': 280 elif component_name == 'k2site':
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 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']}')'''
282 else: 282 else:
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 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']}')'''
284 284
285 285
286 286
287 # Відкриття файлу у режимі дозапису 287 # Відкриття файлу у режимі дозапису
288 with open(file_path, 'a') as file: 288 with open(file_path, 'a') as file:
289 # Запис нового коду у файл 289 # Запис нового коду у файл
290 file.write('\n') 290 file.write('\n')
291 file.write(code) 291 file.write(code)
292 file.write('\n') 292 file.write('\n')
293 293
294 # Update database with the installed component 294 # Update database with the installed component
295 component = Component.query.filter_by(name=selected_component['name']).first() 295 component = Component.query.filter_by(name=selected_component['name']).first()
296 if not component: 296 if not component:
297 component = Component( 297 component = Component(
298 name=selected_component['name'], 298 name=selected_component['name'],
299 description=selected_component['description'], 299 description=selected_component['description'],
300 version=version, 300 version=version,
301 git_link=selected_component['git_link'], 301 git_link=selected_component['git_link'],
302 dependencies=code, 302 dependencies=code,
303 installed=True 303 installed=True
304 ) 304 )
305 db.session.add(component) 305 db.session.add(component)
306 else: 306 else:
307 component.version = version 307 component.version = version
308 component.git_link = selected_component['git_link'] 308 component.git_link = selected_component['git_link']
309 component.dependencies = code 309 component.dependencies = code
310 component.installed = True 310 component.installed = True
311 311
312 db.session.commit() 312 db.session.commit()
313 313
314 # add language folders 314 # add language folders
315 k2.search_babel_translation_directories() 315 k2.search_babel_translation_directories()
316 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},
317 \n \n please wait installing requirments... 317 \n \n please wait installing requirments...
318 <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"]}" />'''
319 319
320 except Exception as e: 320 except Exception as e:
321 return f'Error installing component: {str(e)}' 321 return f'Error installing component: {str(e)}'
322 322
323 323
324 @components_bp.route('/install-requirments/<string:selected_component_name>', methods=['GET']) 324 @components_bp.route('/install-requirments/<string:selected_component_name>', methods=['GET'])
325 def install_requirments(selected_component_name): 325 def install_requirments(selected_component_name):
326 326
327 try: 327 try:
328 if k2.platform == 'Windows': 328 if k2.platform == 'Windows':
329 # install requirements for windows 329 # install requirements for windows
330 venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/Scripts') 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") 331 requirements_file = os.path.join('components', selected_component_name, "requirements.txt")
332 if os.path.isfile(requirements_file): 332 if os.path.isfile(requirements_file):
333 pip_command = f"{venv_bin_path}/python -m pip install -r {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) 334 subprocess.run(pip_command, shell=True, check=True)
335 elif k2.platform == 'Linux': 335 elif k2.platform == 'Linux':
336 #install requirements for linux 336 #install requirements for linux
337 venv_bin_path = os.path.join(os.path.dirname(sys.prefix), 'venv/bin') 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") 338 requirements_file = os.path.join('components', selected_component_name, "requirements.txt")
339 if os.path.isfile(requirements_file): 339 if os.path.isfile(requirements_file):
340 pip_command = f"{venv_bin_path}/python3 -m pip install -r {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) 341 subprocess.run(pip_command, shell=True, check=True)
342 342
343 return f'''Requirements installed successfully 343 return f'''Requirements installed successfully
344 \n \n please wait installing requirments components... 344 \n \n please wait installing requirments components...
345 <meta http-equiv="refresh" content="1;url=/install-requirments-components" />''' 345 <meta http-equiv="refresh" content="1;url=/install-requirments-components" />'''
346 except Exception as e: 346 except Exception as e:
347 return f'Error installing requirmets: {str(e)}' 347 return f'Error installing requirmets: {str(e)}'
348 348
349 @components_bp.route('/install-requirments-components') 349 @components_bp.route('/install-requirments-components')
350 def install_requirements_components(): 350 def install_requirements_components():
351 # Откриття файлу requirements_components.txt 351 # Откриття файлу requirements_components.txt
352 requirements_file = 'requirements_components.txt' 352 requirements_file = 'requirements_components.txt'
353 component_ids = None 353 component_ids = None
354 if os.path.isfile(requirements_file): 354 if os.path.isfile(requirements_file):
355 with open('requirements_components.txt', 'r') as file: 355 with open('requirements_components.txt', 'r') as file:
356 component_ids = file.read().splitlines() 356 component_ids = file.read().splitlines()
357 if component_ids: 357 if component_ids:
358 for component_id in component_ids: 358 for component_id in component_ids:
359 # Виклик роуту '/install_components/<string:component_name>' для кожної назви компоненти 359 # Виклик роуту '/install_components/<string:component_name>' для кожної назви компоненти
360 response = requests.get( 360 response = requests.get(
361 f'/install_components/{component_id}') 361 f'/install_components/{component_id}')
362 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" />'
363 else: 363 else:
364 return f'<meta http-equiv="refresh" content="1;url=/dashboard" />' 364 return f'<meta http-equiv="refresh" content="1;url=/dashboard" />'
365 # Опрацювання відповіді (за потреби) 365 # Опрацювання відповіді (за потреби)
366 366
367 367
368 @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET']) 368 @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET'])
369 def remove_dependencies(component_id): 369 def remove_dependencies(component_id):
370 # Знаходимо компоненту за її ID 370 # Знаходимо компоненту за її ID
371 component = Component.query.get(component_id) 371 component = Component.query.get(component_id)
372 if not component: 372 if not component:
373 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" />'
374 # remove menu items 374 # remove menu items
375 component_name = component.name 375 component_name = component.name
376 # file_path = "components/menu.yml" 376 # file_path = "components/menu.yml"
377 # remove_from_yaml_file(file_path, component_name) 377 # remove_from_yaml_file(file_path, component_name)
378 requests.get(f"{k2.domain}api/add-to-menu") 378 requests.get(f"{k2.domain}api/add-to-menu")
379 # remove routes 379 # remove routes
380 file_path = 'routes.py' 380 file_path = 'routes.py'
381 with open(file_path, 'r') as file: 381 with open(file_path, 'r') as file:
382 lines = file.readlines() 382 lines = file.readlines()
383 383
384 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]
385 with open(file_path, 'w') as file: 385 with open(file_path, 'w') as file:
386 file.writelines(updated_lines) 386 file.writelines(updated_lines)
387 387
388 component.installed = False 388 component.installed = False
389 db.session.commit() 389 db.session.commit()
390 390
391 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" />'
392 392
393 393
394 @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET']) 394 @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET'])
395 def add_dependencies(component_id): 395 def add_dependencies(component_id):
396 # Знаходимо компоненту за її ID 396 # Знаходимо компоненту за її ID
397 component = Component.query.get(component_id) 397 component = Component.query.get(component_id)
398 if not component: 398 if not component:
399 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" />'
400 400
401 file_path = 'routes.py' 401 file_path = 'routes.py'
402 code = component.dependencies 402 code = component.dependencies
403 # Відкриття файлу у режимі дозапису 403 # Відкриття файлу у режимі дозапису
404 with open(file_path, 'a') as file: 404 with open(file_path, 'a') as file:
405 # Запис нового коду у файл 405 # Запис нового коду у файл
406 file.write(code) 406 file.write(code)
407 407
408 # Оновлюємо статус компоненти 408 # Оновлюємо статус компоненти
409 component.installed = True 409 component.installed = True
410 db.session.commit() 410 db.session.commit()
411 411
412 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" />'
413 413
414 414
415 @components_bp.route('/remove-component/<string:component_id>') 415 @components_bp.route('/remove-component/<string:component_id>')
416 def remove_component(component_id): 416 def remove_component(component_id):
417 # Шлях до головної папки проекту 417 # Шлях до головної папки проекту
418 project_folder = 'components' 418 project_folder = 'components'
419 component = Component.query.get(component_id) 419 component = Component.query.get(component_id)
420 # Назва репозиторія 420 # Назва репозиторія
421 repository_name = component.name 421 repository_name = component.name
422 # Шлях до папки репозиторія в межах проекту 422 # Шлях до папки репозиторія в межах проекту
423 repository_folder = os.path.join(project_folder, repository_name) 423 repository_folder = os.path.join(project_folder, repository_name)
424 try: 424 try:
425 # Перевірка наявності папки репозиторія 425 # Перевірка наявності папки репозиторія
426 if os.path.exists(repository_folder): 426 if os.path.exists(repository_folder):
427 # Видалення папки репозиторія 427 # Видалення папки репозиторія
428 shutil.rmtree(repository_folder) 428 shutil.rmtree(repository_folder)
429 # Видаляємо компоненту з бази 429 # Видаляємо компоненту з бази
430 if component: 430 if component:
431 db.session.delete(component) 431 db.session.delete(component)
432 db.session.commit() 432 db.session.commit()
433 433
434 # Повертаємо повідомлення про успішне видалення 434 # Повертаємо повідомлення про успішне видалення
435 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" />'
436 except Exception as e: 436 except Exception as e:
437 # Повертаємо повідомлення про помилку видалення 437 # Повертаємо повідомлення про помилку видалення
438 return 'Error removing component: ' + str(e) 438 return 'Error removing component: ' + str(e)
439 439
440 440
441 441
442 # @components_bp.route('/component/add') 442 # @components_bp.route('/component/add')
443 # def component_add(): 443 # def component_add():
444 # # components for install 444 # # components for install
445 # try: 445 # try:
446 # # GET-requests to API 446 # # GET-requests to API
447 # response = requests.get(f'{k2.update_domain}api/components') 447 # response = requests.get(f'{k2.update_domain}api/components')
448 # json_data = response.json() 448 # json_data = response.json()
449 # for item in json_data: 449 # for item in json_data:
450 # item['button'] = f"{k2.domain}/install_components/{item['id']}" 450 # item['button'] = f"{k2.domain}/install_components/{item['id']}"
451 # 451 #
452 # except: 452 # except:
453 # json_data = None 453 # json_data = None
454 # return jsonify(json_data) 454 # return jsonify(json_data)
455 # 455 #
456 # 456 #
457 # @components_bp.route('/component/list') 457 # @components_bp.route('/component/list')
458 # def component_list(): 458 # def component_list():
459 # # Встановлені компоненти 459 # # Встановлені компоненти
460 # component_list = [] 460 # component_list = []
461 # components = Component.query.all() 461 # components = Component.query.all()
462 # for component in components: 462 # for component in components:
463 # component_dict = {} 463 # component_dict = {}
464 # component_dict['name'] = component.name 464 # component_dict['name'] = component.name
465 # component_dict['id'] = component.id 465 # component_dict['id'] = component.id
466 # component_dict['description'] = component.description 466 # component_dict['description'] = component.description
467 # component_dict['version'] = component.version 467 # component_dict['version'] = component.version
468 # component_dict['button_off'] =f"{k2.domain}/remove_dependencies/{component.id}" 468 # component_dict['button_off'] =f"{k2.domain}/remove_dependencies/{component.id}"
469 # component_dict['button_on'] = f"{k2.domain}/add_dependencies/{component.id}" 469 # component_dict['button_on'] = f"{k2.domain}/add_dependencies/{component.id}"
470 # component_dict['button_del'] = f"{k2.domain}/remove-component/{component.id}" 470 # component_dict['button_del'] = f"{k2.domain}/remove-component/{component.id}"
471 # component_list.append(component_dict) 471 # component_list.append(component_dict)
472 # return jsonify(component_list) 472 # return jsonify(component_list)
473 473
474 474
475 # menu 475 # menu
476 @components_bp.route('/api/add-to-menu', methods=['GET']) 476 @components_bp.route('/api/add-to-menu', methods=['GET'])
477 def add_to_menu(): 477 def add_to_menu():
478 data = [] 478 data = []
479 response = requests.get(f"{k2.domain}/menu-admin-items") 479 response = requests.get(f"{k2.domain}/menu-admin-items")
480 data.append(response.json()[0]) 480 data.append(response.json()[0])
481 prev_menu = response.json()[0]['title'] 481 prev_menu = response.json()[0]['title']
482 for item in response.json()[0]['children']: 482 for item in response.json()[0]['children']:
483 name_menu = 'k2itm'+ item['to'].replace('/','-') 483 name_menu = 'k2itm'+ item['to'].replace('/','-')
484 caption_menu = item['title'] 484 caption_menu = item['title']
485 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu) 485 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu)
486 components = Component.query.all() 486 components = Component.query.all()
487 components_names = [component.name for component in components] 487 components_names = [component.name for component in components]
488 for components_names in components_names: 488 for components_names in components_names:
489 response = requests.get(f"{k2.domain}{components_names}/menu-admin-items") 489 response = requests.get(f"{k2.domain}{components_names}/menu-admin-items")
490 if response.status_code == 200: 490 if response.status_code == 200:
491 data.append(response.json()[0]) 491 data.append(response.json()[0])
492 #prev_menu = 492 #prev_menu =
493 prev_menu = response.json()[0]['title'] 493 prev_menu = response.json()[0]['title']
494 for item in response.json()[0]['children']: 494 for item in response.json()[0]['children']:
495 name_menu = 'k2itm'+ item['to'].replace('/','-') 495 name_menu = 'k2itm'+ item['to'].replace('/','-')
496 caption_menu = item['title'] 496 caption_menu = item['title']
497 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu) 497 add_menu_with_permissions_db(name_menu, prev_menu, caption_menu)
498 else: 498 else:
499 continue 499 continue
500 # add component_name key for menu items 500 # add component_name key for menu items
501 #for item in data: 501 #for item in data:
502 # item['component_name'] = components_names 502 # item['component_name'] = components_names
503 #k2.menu = data 503 #k2.menu = data
504 return data 504 return data
505 505
506 506
507 507
508 508
509 @components_bp.route('/api/main-menu/') 509 @components_bp.route('/api/main-menu/')
510 @login_required 510 @login_required
511 def get_admin_menu(): 511 def get_admin_menu():
512 components = Component.query.all() 512 components = Component.query.all()
513 components_names = [component.name for component in components] 513 components_names = [component.name for component in components]
514 if 'k2site' in components_names: 514 if 'k2site' in components_names:
515 role_id = current_user.get_role_id() 515 role_id = current_user.get_role_id()
516 filter_menu = [] 516 filter_menu = []
517 response = requests.get(f"{k2.domain}api/add-to-menu") 517 response = requests.get(f"{k2.domain}api/add-to-menu")
518 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)
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 components_version = [{component.name: component.version} for component in components]
591 591
592 return render_template('dashboard-add.html', 592 return render_template('dashboard-add.html',
593 component_server=filtered_components, search_query=search_query, components_names=components_names, components_version=components_version ) 593 component_server=filtered_components, search_query=search_query, components_names=components_names, components_version=components_version )
594 594
595 595
596 596
597 @components_bp.route('/component-list') 597 @components_bp.route('/component-list')
598 @login_required 598 @login_required
599 def component_list_dasb(): 599 def component_list_dasb():
600 components = Component.query.all() 600 components = Component.query.all()
601 601
602 return render_template('dashboard-list.html', components=components) 602 return render_template('dashboard-list.html', components=components)
603 603
604 604
605 605
606 606
607 @components_bp.route('/menu-admin-items') 607 @components_bp.route('/menu-admin-items')
608 def menu_items(): 608 def menu_items():
609 menu = [ 609 menu = [
610 { 610 {
611 "title": 'Add components', 611 "title": 'Add components',
612 "icon": {"icon": 'mdi-account-circle-outline'}, 612 "icon": {"icon": 'mdi-account-circle-outline'},
613 "children": [ 613 "children": [
614 {'title': 'Install new components', 'to': '/component-add'}, 614 {'title': 'Install new components', 'to': '/component-add'},
615 {'title': 'Installed components', 'to': '/component-list'}, 615 {'title': 'Installed components', 'to': '/component-list'},
616 616
617 ], 617 ],
618 }] 618 }]
619 return menu 619 return menu
620 620
621 621
622 622
623 623
624 624
625 625
626 626
627 627
languages/babel_translation_directories.yml
1 babel_translation_directories: languages;components/k2site/k2site/languages;components/k2test/k2test/languages 1 babel_translation_directories: languages;components/k2test/k2test/languages;components/k2site/k2site/languages
2 2
1 alembic==1.11.1 1 alembic==1.11.1
2 Babel==2.12.1 2 Babel==2.12.1
3 bcrypt==4.0.1 3 bcrypt==4.0.1
4 bidict==0.22.1 4 bidict==0.22.1
5 blinker==1.6.2 5 blinker==1.6.2
6 certifi==2023.5.7 6 certifi==2023.5.7
7 charset-normalizer==3.1.0 7 charset-normalizer==3.1.0
8 click==8.1.3 8 click==8.1.3
9 colorama==0.4.6 9 colorama==0.4.6
10 dnspython==2.3.0 10 dnspython==2.3.0
11 email-validator==2.0.0.post2 11 email-validator==2.0.0.post2
12 Flask==2.3.2 12 Flask==2.3.2
13 flask-babel==3.1.0 13 flask-babel==3.1.0
14 Flask-Bcrypt==1.0.1 14 Flask-Bcrypt==1.0.1
15 Flask-Cors==3.0.10 15 Flask-Cors==3.0.10
16 Flask-JWT-Extended==4.5.2 16 Flask-JWT-Extended==4.5.2
17 Flask-Login==0.6.2 17 Flask-Login==0.6.2
18 Flask-Migrate==4.0.4 18 Flask-Migrate==4.0.4
19 Flask-MySQLdb==1.0.1 19 Flask-MySQLdb==1.0.1
20 Flask-SQLAlchemy==3.0.3 20 Flask-SQLAlchemy==3.0.3
21 flask-staticdirs==1.0.1 21 flask-staticdirs==1.0.1
22 Flask-WTF==1.1.1 22 Flask-WTF==1.1.1
23 greenlet==2.0.2 23 greenlet==2.0.2
24 gunicorn==20.1.0
24 idna==3.4 25 idna==3.4
25 itsdangerous==2.1.2 26 itsdangerous==2.1.2
26 Jinja2==3.1.2 27 Jinja2==3.1.2
27 jsonify==0.5 28 jsonify==0.5
28 Mako==1.2.4 29 Mako==1.2.4
29 MarkupSafe==2.1.2 30 MarkupSafe==2.1.2
30 mysql==0.0.3 31 mysql==0.0.3
31 mysql-connector==2.2.9 32 mysql-connector==2.2.9
32 mysql-connector-python==8.0.33 33 mysql-connector-python==8.0.33
33 mysqlclient==2.1.1 34 mysqlclient==2.1.1
34 peppercorn==0.6 35 peppercorn==0.6
35 protobuf==3.20.3 36 protobuf==3.20.3
36 PyJWT==2.7.0 37 PyJWT==2.7.0
37 python-engineio==4.4.1 38 python-engineio==4.4.1
38 python-socketio==5.8.0 39 python-socketio==5.8.0
39 pytz==2023.3 40 pytz==2023.3
40 PyYAML==6.0 41 PyYAML==6.0
41 requests==2.31.0 42 requests==2.31.0
42 six==1.16.0 43 six==1.16.0
43 SQLAlchemy==2.0.15 44 SQLAlchemy==2.0.15
44 typing_extensions==4.6.2 45 typing_extensions==4.6.2
45 urllib3==2.0.2 46 urllib3==2.0.3
46 Werkzeug==2.3.4 47 Werkzeug==2.3.4
47 WTForms==3.0.1 48 WTForms==3.0.1
48 49
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')
9 7
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 %} 54 {% for component_upd_ver in components_version %}
55 {% for key, value in component_upd_ver.items() %} 55 {% for key, value in component_upd_ver.items() %}
56 {% if key == component.name and value < component.latest_version %} 56 {% if key == component.name and value < component.latest_version %}
57 <p class="update_avaible"> Update avaible</p> 57 <p class="text-warning"> Update avaible</p>
58 {% endif %} 58 {% endif %}
59 {% endfor %} 59 {% endfor %}
60 {% endfor %} 60 {% endfor %}
61 61
62 {% if component.name in components_names %} 62 {% if component.name in components_names %}
63 <button type="button" class="btn btn-success">Installed</button> 63 <button type="button" class="btn btn-success">Installed</button>
64 {% else %} 64 {% else %}
65 <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>
66 {% endif %} 66 {% endif %}
67 </div> 67 </div>
68 </div> 68 </div>
69 {% endfor %} 69 {% endfor %}
70 {% else %} 70 {% else %}
71 <div class="col"> 71 <div class="col">
72 <p>No components available.</p> 72 <p>No components available.</p>
73 </div> 73 </div>
74 {% endif %} 74 {% endif %}
75 </div> 75 </div>
76 </div> 76 </div>
77 77
78 {% endblock %} 78 {% endblock %}
79 79
80 </div> 80 </div>
81 81