# modules/admin.py """ Простая веб-админка для управления парсером """ from flask import Flask, render_template_string, request, redirect, url_for, flash, jsonify import logging from datetime import datetime, timedelta class AdminPanel: """Простая веб-админка""" def __init__(self, config, storage): self.config = config self.storage = storage self.app = Flask(__name__) self.app.secret_key = 'morele-parser-secret-key' self._setup_routes() def _setup_routes(self): """Настройка маршрутов""" @self.app.route('/') def index(): """Главная страница""" categories = self.storage.get_active_categories() stats = self.storage.get_parsing_stats(7) # За неделю return render_template_string(self.INDEX_TEMPLATE, categories=categories, stats=stats) @self.app.route('/categories') def categories(): """Страница управления категориями""" categories = self.storage.get_active_categories() return render_template_string(self.CATEGORIES_TEMPLATE, categories=categories) @self.app.route('/add_category', methods=['POST']) def add_category(): """Добавление категории""" name = request.form.get('name') url = request.form.get('url') if name and url: try: self.storage.add_category(name, url) flash('Категория добавлена успешно', 'success') except Exception as e: flash(f'Ошибка при добавлении категории: {e}', 'error') else: flash('Заполните все поля', 'error') return redirect(url_for('categories')) @self.app.route('/deactivate_category/') def deactivate_category(category_id): """Деактивация категории""" try: self.storage.deactivate_category(category_id) flash('Категория деактивирована', 'success') except Exception as e: flash(f'Ошибка: {e}', 'error') return redirect(url_for('categories')) @self.app.route('/products') def products(): """Страница товаров""" page = int(request.args.get('page', 1)) per_page = 50 # Здесь можно добавить пагинацию products = self.storage.get_products_for_feed()[:per_page] return render_template_string(self.PRODUCTS_TEMPLATE, products=products) @self.app.route('/api/stats') def api_stats(): """API для получения статистики""" stats = self.storage.get_parsing_stats(30) return jsonify(stats) def run(self, host='127.0.0.1', port=5000): """Запуск админки""" self.app.run(host=host, port=port, debug=False) # HTML шаблоны INDEX_TEMPLATE = ''' Morele.net Parser - Админка

🔍 Morele.net Parser - Админка

📊 Статистика

{{ categories|length }}
Активных категорий
{{ stats|length }}
Сессий парсинга за неделю

📋 Последние сессии парсинга

{% if stats %} {% for stat in stats[:10] %} {% endfor %}
Дата Категория Найдено Новых Обновлено Ошибок
{{ stat.completed_at }} {{ stat.category_url }} {{ stat.products_found }} {{ stat.products_new }} {{ stat.products_updated }} {{ stat.errors_count }}
{% else %}

Пока нет данных о парсинге

{% endif %}
''' CATEGORIES_TEMPLATE = ''' Категории - Morele.net Parser

📁 Управление категориями

{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %}
{{ message }}
{% endfor %} {% endif %} {% endwith %}

➕ Добавить категорию

📋 Список категорий

{% if categories %} {% for category in categories %} {% endfor %}
ID Название URL Дата добавления Действия
{{ category.id }} {{ category.name }} {{ category.url[:50] }}... {{ category.created_at }} Деактивировать
{% else %}

Пока нет добавленных категорий. Добавьте первую категорию выше.

{% endif %}
''' PRODUCTS_TEMPLATE = ''' Товары - Morele.net Parser

📋 Список товаров

{% if products %}

Показано товаров: {{ products|length }}

{% for product in products %} {% endfor %}
Изображение Название (UA) Цена (PLN) Наличие Категория Обновлено Ссылка
{% if product.local_images %} Product image {% else %}
{% endif %}
{{ product.title_ua }} {{ "%.2f"|format(product.price) }} PLN {{ product.availability }} {{ product.category }} {{ product.updated_at[:16] }} Открыть
{% else %}

Пока нет товаров. Запустите парсинг для получения товаров.

{% endif %}
'''