CoolFace
Apppublic

AlexRitter66/Gazetta-control

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
app.py128 linesDownload Raw Back to root
1import streamlit as st2import sqlite33import fitz  # PyMuPDF4from PIL import Image5from google import genai6import os7import json # Добавили для безопасной работы с ответами нейросети8 9# --- НАСТРОЙКИ СТРАНИЦЫ ---10st.set_page_config(page_title="PRO-Корректор 2.0", page_icon="🗞️", layout="wide")11 12# Получаем секретный ключ из настроек сервера13API_KEY = os.environ.get("GEMINI_API_KEY")14 15# --- БАЗА ДАННЫХ ---16def init_db():17    # Конструкция "with" гарантирует, что база закроется, даже если будет сбой18    with sqlite3.connect('database.db') as conn:19        cursor = conn.cursor()20        cursor.execute('''CREATE TABLE IF NOT EXISTS access_keys 21                          (key_string TEXT PRIMARY KEY, key_type TEXT, is_active BOOLEAN DEFAULT 1, tg_id INTEGER)''')22        conn.commit()23 24def check_key(key_string):25    with sqlite3.connect('database.db') as conn:26        cursor = conn.cursor()27        cursor.execute("SELECT key_type FROM access_keys WHERE key_string = ? AND is_active = 1", (key_string,))28        result = cursor.fetchone()29    return result[0] if result else None30 31# --- ИНТЕРФЕЙС ---32st.title("🗞️ PRO-Корректор: Нейро-редактор газетных полос")33st.markdown("Добро пожаловать в систему автоматического анализа верстки и текстов.")34 35init_db()36 37if "access_granted" not in st.session_state:38    st.session_state.access_granted = False39    st.session_state.key_type = None40 41# Экран авторизации42if not st.session_state.access_granted:43    st.subheader("🔒 Вход в систему")44    user_key = st.text_input("Введите ваш ключ доступа (TRIAL или PREMIUM):", type="password")45    46    if st.button("Войти"):47        if user_key.strip() == "":48            st.warning("⚠️ Пожалуйста, введите ключ.")49        else:50            key_type = check_key(user_key.strip())51            if key_type:52                st.session_state.access_granted = True53                st.session_state.key_type = key_type54                st.success(f"✅ Доступ разрешен! Режим: {key_type.upper()}")55                st.rerun()56            else:57                st.error("❌ Неверный ключ или срок его действия истек.")58 59# Основной рабочий экран60else:61    st.sidebar.success(f"🔑 Активный режим: {st.session_state.key_type.upper()}")62    if st.sidebar.button("Выйти"):63        st.session_state.access_granted = False64        st.rerun()65 66    if not API_KEY:67        st.error("⚠️ Системная ошибка: API-ключ не найден в настройках сервера. Обратитесь к администратору.")68    else:69        st.subheader("📄 Анализ полосы")70        uploaded_file = st.file_uploader("Загрузите полосу газеты (PDF, JPG, PNG)", type=["pdf", "jpg", "jpeg", "png"])71 72        if uploaded_file:73            if st.button("🚀 Начать проверку"):74                with st.spinner("Анализирую макет..."):75                    doc = None # Объявляем заранее для безопасного закрытия76                    try:77                        # Инициализация Gemini API скрытым ключом78                        client = genai.Client(api_key=API_KEY)79                        80                        # Подготовка изображения81                        if uploaded_file.name.lower().endswith('.pdf'):82                            doc = fitz.open(stream=uploaded_file.read(), filetype="pdf")83                            page = doc.load_page(0)84                            pix = page.get_pixmap(matrix=fitz.Matrix(2, 2))85                            img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)86                        else:87                            img = Image.open(uploaded_file)88                        89                        st.image(img, caption="Загруженная полоса", use_container_width=True)90 91                        # Обновленный промпт с жестким указанием структуры JSON92                        prompt = """93                        Ты - профессиональный военный журналист и выпускающий редактор.94                        Проанализируй эту газетную полосу и выдай структурированный JSON.95                        Отвечай ТОЛЬКО кодом, без приветствий и лишнего текста, строго в таком формате:96                        {97                          "Critical": "описание грубых ошибок (смысл, заголовки, фото)",98                          "Layout": "описание ошибок верстки (висячие строки, выравнивание)",99                          "Grammar": "описание орфографии и стилистики"100                        }101                        """102                        103                        response = client.models.generate_content(104                            model='gemini-2.5-flash',105                            contents=[img, prompt]106                        )107                        108                        # Очистка ответа от Markdown-мусора (если нейросеть всё же добавит ```json)109                        raw_text = response.text.strip()110                        if raw_text.startswith("```"):111                            raw_text = raw_text.split("\n", 1)[-1]112                            if raw_text.endswith("```"):113                                raw_text = raw_text.rsplit("\n", 1)[0]114                        115                        st.subheader("📊 Результаты проверки:")116                        try:117                            parsed_json = json.loads(raw_text)118                            st.json(parsed_json)119                        except json.JSONDecodeError:120                            # Запасной вариант: если JSON не получился, выводим как обычный текст121                            st.write(raw_text)122                        123                    except Exception as e:124                        st.error(f"⚠️ Ошибка при анализе: {e}")125                    finally:126                        # Защита от утечки оперативной памяти сервера127                        if doc is not None:128                            doc.close()