Commit 821570955a9bcc49053ed16df3d4b7d1da58c785
1 parent
0fd7982778
Exists in
master
add get menu-items
Showing 14 changed files with 120 additions and 18 deletions Side-by-side Diff
- __pycache__/main.cpython-310.pyc
- __pycache__/routes.cpython-310.pyc
- components/k2test/__pycache__/__init__.cpython-310.pyc
- components/k2test/k2test/__pycache__/__init__.cpython-310.pyc
- components/k2test/k2test/__pycache__/views.cpython-310.pyc
- components/k2test/k2test/views.py
- components/k2test/menu_items.yml
- components/menu.yml
- db/database.db
- k2/__pycache__/k2cfg.cpython-310.pyc
- k2/__pycache__/k2inst.cpython-310.pyc
- k2/k2cfg.py
- k2/k2inst.py
- main.py
__pycache__/main.cpython-310.pyc
No preview for this file type
__pycache__/routes.cpython-310.pyc
No preview for this file type
components/k2test/__pycache__/__init__.cpython-310.pyc
No preview for this file type
components/k2test/k2test/__pycache__/__init__.cpython-310.pyc
No preview for this file type
components/k2test/k2test/__pycache__/views.cpython-310.pyc
No preview for this file type
components/k2test/k2test/views.py
| ... | ... | @@ -32,4 +32,29 @@ |
| 32 | 32 | @k2test.route('/new4') |
| 33 | 33 | def new_component4(): |
| 34 | 34 | return 'сторінка 4' |
| 35 | + | |
| 36 | + | |
| 37 | +@k2test.route('/menu-items') | |
| 38 | +def menu_items(): | |
| 39 | + data = [ | |
| 40 | + { | |
| 41 | + 'url': {'name': 'new2'}, | |
| 42 | + 'icon': 'mdi-chart-timeline-variant', | |
| 43 | + 'title': 'Тест 2', | |
| 44 | + 'category': 'Тестова компонента', | |
| 45 | + }, | |
| 46 | + { | |
| 47 | + 'url': {'name': 'new3'}, | |
| 48 | + 'icon': 'mdi-chart-timeline-variant', | |
| 49 | + 'title': 'Тест 3', | |
| 50 | + 'category': 'Тестова компонента', | |
| 51 | + }, | |
| 52 | + { | |
| 53 | + 'url': {'name': 'new4'}, | |
| 54 | + 'icon': 'mdi-chart-timeline-variant', | |
| 55 | + 'title': 'Тест 4', | |
| 56 | + 'category': 'Тестова компонента', | |
| 57 | + }, | |
| 58 | + ] | |
| 59 | + return data |
components/k2test/menu_items.yml
| 1 | +- url: | |
| 2 | + name: new2 | |
| 3 | + icon: mdi-chart-timeline-variant | |
| 4 | + title: Тест 2 | |
| 5 | + category: Тестова компонента | |
| 6 | +- url: | |
| 7 | + name: new3 | |
| 8 | + icon: mdi-chart-timeline-variant | |
| 9 | + title: Тест 3 | |
| 10 | + category: Тестова компонента | |
| 11 | +- url: | |
| 12 | + name: new4 | |
| 13 | + icon: mdi-chart-timeline-variant | |
| 14 | + title: Тест 4 | |
| 15 | + category: Тестова компонента |
components/menu.yml
| 1 | +- category: dashboards | |
| 2 | + icon: mdi-chart-timeline-variant | |
| 3 | + id: 1 | |
| 4 | + title: Analytics Dashboard | |
| 5 | + url: | |
| 6 | + name: dashboards-analytics | |
| 7 | +- category: dashboards | |
| 8 | + icon: mdi-cart-outline | |
| 9 | + id: 2 | |
| 10 | + title: CRM Dashboard | |
| 11 | + url: | |
| 12 | + name: dashboards-crm | |
| 13 | +- category: "\u0422\u0435\u0441\u0442\u043E\u0432\u0430 \u043A\u043E\u043C\u043F\u043E\ | |
| 14 | + \u043D\u0435\u043D\u0442\u0430" | |
| 15 | + icon: mdi-chart-timeline-variant | |
| 16 | + id: 3 | |
| 17 | + title: "\u0422\u0435\u0441\u0442 2" | |
| 18 | + url: | |
| 19 | + name: new2 | |
| 20 | +- category: "\u0422\u0435\u0441\u0442\u043E\u0432\u0430 \u043A\u043E\u043C\u043F\u043E\ | |
| 21 | + \u043D\u0435\u043D\u0442\u0430" | |
| 22 | + icon: mdi-chart-timeline-variant | |
| 23 | + id: 4 | |
| 24 | + title: "\u0422\u0435\u0441\u0442 3" | |
| 25 | + url: | |
| 26 | + name: new3 | |
| 27 | +- category: "\u0422\u0435\u0441\u0442\u043E\u0432\u0430 \u043A\u043E\u043C\u043F\u043E\ | |
| 28 | + \u043D\u0435\u043D\u0442\u0430" | |
| 29 | + icon: mdi-chart-timeline-variant | |
| 30 | + id: 5 | |
| 31 | + title: "\u0422\u0435\u0441\u0442 4" | |
| 32 | + url: | |
| 33 | + name: new4 |
db/database.db
No preview for this file type
k2/__pycache__/k2cfg.cpython-310.pyc
No preview for this file type
k2/__pycache__/k2inst.cpython-310.pyc
No preview for this file type
k2/k2cfg.py
| ... | ... | @@ -53,16 +53,22 @@ |
| 53 | 53 | |
| 54 | 54 | with open('languages/babel_translation_directories.yml', 'w') as f: |
| 55 | 55 | yaml.dump(data, f) |
| 56 | + @classmethod | |
| 57 | + def search_menu_elenents(cls): | |
| 58 | + with open('components/menu.yml', 'r') as f: | |
| 59 | + yaml_data = yaml.load(f, Loader=yaml.FullLoader) | |
| 60 | + cls.menu = yaml_data | |
| 56 | 61 | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 57 | 65 | # load database settings from yml file |
| 58 | 66 | def init_db_uri(self): |
| 59 | 67 | with open('db/db.yml', 'r') as f: |
| 60 | 68 | db_config = yaml.load(f, Loader=yaml.FullLoader) |
| 61 | 69 | return db_config |
| 62 | 70 | |
| 63 | - # creating a connection string | |
| 64 | - | |
| 65 | - | |
| 71 | + # creating a connection | |
| 66 | 72 | def init_db(self, app): |
| 67 | 73 | db_config = self.init_db_uri() |
| 68 | 74 | db_uri = f"mysql+{db_config['driver']}://{db_config['user']}:{db_config['password']}@{db_config['host']}/{db_config['dbname']}" |
k2/k2inst.py
| ... | ... | @@ -51,12 +51,26 @@ |
| 51 | 51 | @wraps(view_func) |
| 52 | 52 | def decorated_view(*args, **kwargs): |
| 53 | 53 | if 'username' not in session: |
| 54 | - return redirect(url_for('first_login')) | |
| 54 | + return redirect(url_for('components.first_login')) | |
| 55 | 55 | return view_func(*args, **kwargs) |
| 56 | - | |
| 57 | 56 | return decorated_view |
| 58 | 57 | |
| 58 | +def append_to_yaml_file(file_path, data): | |
| 59 | + with open(file_path, 'r') as f: | |
| 60 | + existing_data = yaml.safe_load(f) or [] | |
| 59 | 61 | |
| 62 | + if not existing_data: | |
| 63 | + start_id = 1 | |
| 64 | + else: | |
| 65 | + start_id = max(item.get('id', 0) for item in existing_data) + 1 | |
| 66 | + | |
| 67 | + for i, item in enumerate(data, start=start_id): | |
| 68 | + item['id'] = i | |
| 69 | + existing_data.append(item) | |
| 70 | + | |
| 71 | + with open(file_path, 'w') as f: | |
| 72 | + yaml.dump(existing_data, f, default_flow_style=False) | |
| 73 | + | |
| 60 | 74 | @components_bp.route('/api/languages', methods=['GET']) |
| 61 | 75 | def find_language(): |
| 62 | 76 | components = Component.query.all() |
| ... | ... | @@ -91,7 +105,7 @@ |
| 91 | 105 | @components_bp.route('/logout') |
| 92 | 106 | def logout(): |
| 93 | 107 | session.pop('username', None) # Видалення ім'я користувача з сесії |
| 94 | - return redirect(url_for('first_login')) | |
| 108 | + return redirect(url_for('components.first_login')) | |
| 95 | 109 | |
| 96 | 110 | @components_bp.route('/change_language/<lang>') |
| 97 | 111 | def change_language(lang): |
| 98 | 112 | |
| ... | ... | @@ -131,10 +145,9 @@ |
| 131 | 145 | |
| 132 | 146 | return render_template('dashboard.html', components=components, |
| 133 | 147 | components_names=components_names, component_server=filtered_components, |
| 134 | - search_query=search_query, language=current_language ) | |
| 148 | + search_query=search_query, language=k2.menu ) | |
| 135 | 149 | |
| 136 | 150 | @components_bp.route('/show_components/<string:component_id>') |
| 137 | -@first_login_required | |
| 138 | 151 | def show_components(component_id): |
| 139 | 152 | response = requests.get('http://127.0.0.1:8001/api/components') |
| 140 | 153 | json_data = response.json() |
| ... | ... | @@ -142,7 +155,6 @@ |
| 142 | 155 | return render_template('component-info.html', selected_component=selected_component) |
| 143 | 156 | |
| 144 | 157 | @components_bp.route('/install_components_git/<string:component_id>') |
| 145 | -@first_login_required | |
| 146 | 158 | def install_components_git(component_id): |
| 147 | 159 | # Шлях до головної папки проекту |
| 148 | 160 | project_folder = 'components' |
| ... | ... | @@ -208,7 +220,6 @@ |
| 208 | 220 | return 'Error installing : ' + str(e) |
| 209 | 221 | |
| 210 | 222 | @components_bp.route('/install_components/<string:component_id>') |
| 211 | -@first_login_required | |
| 212 | 223 | def install_component_from_archive(component_id): |
| 213 | 224 | # Шлях до головної папки проекту |
| 214 | 225 | project_folder = 'components' |
| ... | ... | @@ -256,7 +267,7 @@ |
| 256 | 267 | file.write(code) |
| 257 | 268 | file.write('\n') |
| 258 | 269 | |
| 259 | - # Оновити базу даних з встановленою компонентою | |
| 270 | + #Update database with the installed component | |
| 260 | 271 | component = Component.query.filter_by(name=selected_component['name']).first() |
| 261 | 272 | if not component: |
| 262 | 273 | component = Component( |
| 263 | 274 | |
| 264 | 275 | |
| ... | ... | @@ -275,8 +286,23 @@ |
| 275 | 286 | component.installed = True |
| 276 | 287 | |
| 277 | 288 | db.session.commit() |
| 289 | + # add menu items | |
| 290 | + file_path_input = f"components/{selected_component['name']}/menu_items.yml" | |
| 291 | + if os.path.exists(file_path_input): | |
| 292 | + with open(file_path_input, 'r', encoding='utf-8') as file: | |
| 293 | + data = yaml.safe_load(file) | |
| 294 | + else: | |
| 295 | + data = { | |
| 296 | + 'url': {'name': 'error'}, | |
| 297 | + 'icon': 'error', | |
| 298 | + 'title': f"{selected_component['name']}--error", | |
| 299 | + 'category': 'error', | |
| 300 | + } | |
| 278 | 301 | |
| 302 | + file_path = 'components/menu.yml' | |
| 303 | + append_to_yaml_file(file_path, data) | |
| 279 | 304 | |
| 305 | + #add language folders | |
| 280 | 306 | k2.search_babel_translation_directories() |
| 281 | 307 | |
| 282 | 308 | return f'''Component installed successfully: {selected_component["name"]} v{version} {k2.babel_translation_directories}, |
| ... | ... | @@ -287,7 +313,6 @@ |
| 287 | 313 | return f'Error installing component: {str(e)}' |
| 288 | 314 | |
| 289 | 315 | @components_bp.route('/install-requirments/<string:selected_component_name>', methods=['GET']) |
| 290 | -@first_login_required | |
| 291 | 316 | def install_requirments(selected_component_name): |
| 292 | 317 | requirements_file = os.path.join('components', selected_component_name, "requirements.txt") |
| 293 | 318 | if os.path.isfile(requirements_file): |
| ... | ... | @@ -299,7 +324,6 @@ |
| 299 | 324 | |
| 300 | 325 | |
| 301 | 326 | @components_bp.route('/install-requirments-components') |
| 302 | -@first_login_required | |
| 303 | 327 | def install_requirements_components(): |
| 304 | 328 | # Откриття файлу requirements_components.txt |
| 305 | 329 | requirements_file = 'requirements_components.txt' |
| ... | ... | @@ -319,7 +343,6 @@ |
| 319 | 343 | |
| 320 | 344 | |
| 321 | 345 | @components_bp.route('/remove_dependencies/<string:component_id>', methods=['GET']) |
| 322 | -@first_login_required | |
| 323 | 346 | def remove_dependencies(component_id): |
| 324 | 347 | # Знаходимо компоненту за її ID |
| 325 | 348 | component = Component.query.get(component_id) |
| ... | ... | @@ -347,7 +370,6 @@ |
| 347 | 370 | return 'Component successfully turn off <meta http-equiv="refresh" content="1;url=/dashboard" />' |
| 348 | 371 | |
| 349 | 372 | @components_bp.route('/add_dependencies/<string:component_id>', methods=['GET']) |
| 350 | -@first_login_required | |
| 351 | 373 | def add_dependencies(component_id): |
| 352 | 374 | |
| 353 | 375 | # Знаходимо компоненту за її ID |
| ... | ... | @@ -369,7 +391,6 @@ |
| 369 | 391 | return 'Dependencies added successfully <meta http-equiv="refresh" content="1;url=/dashboard" />' |
| 370 | 392 | |
| 371 | 393 | @components_bp.route('/remove-component/<string:component_id>') |
| 372 | -@first_login_required | |
| 373 | 394 | def remove_component(component_id): |
| 374 | 395 | # Шлях до головної папки проекту |
| 375 | 396 | project_folder = 'components' |
main.py
| ... | ... | @@ -7,7 +7,7 @@ |
| 7 | 7 | # configure flask app |
| 8 | 8 | app = Flask(__name__) |
| 9 | 9 | app.config['SECRET_KEY'] = k2.secret_key |
| 10 | -app.config.from_object(k2) | |
| 10 | +#app.config.from_object(k2) | |
| 11 | 11 | |
| 12 | 12 | # init db |
| 13 | 13 | k2().init_db(app) |
| ... | ... | @@ -18,6 +18,9 @@ |
| 18 | 18 | app.config['BABEL_TRANSLATION_DIRECTORIES'] = k2.babel_translation_directories |
| 19 | 19 | babel = Babel(app) |
| 20 | 20 | babel.init_app(app, locale_selector=k2.get_locale) |
| 21 | + | |
| 22 | +#menu | |
| 23 | +k2.search_menu_elenents() | |
| 21 | 24 | |
| 22 | 25 | # flask routing |
| 23 | 26 | from routes import * |