239 lines
9.0 KiB
Python
239 lines
9.0 KiB
Python
import hashlib
|
||
import os
|
||
import sqlite3
|
||
import time
|
||
from threading import Lock
|
||
|
||
import telebot
|
||
|
||
from backend_flask import app
|
||
from config import DB_PATH
|
||
|
||
# Lock for database operations
|
||
db_lock = Lock()
|
||
|
||
|
||
def init_db():
|
||
try:
|
||
# 1️⃣ Проверяем и создаём каталог, если его нет
|
||
db_dir = os.path.dirname(DB_PATH)
|
||
if not os.path.exists(db_dir):
|
||
os.makedirs(db_dir, exist_ok=True) # Создаём каталог рекурсивно
|
||
|
||
# 2️⃣ Проверяем, существует ли файл базы данных
|
||
db_exists = os.path.exists(DB_PATH)
|
||
|
||
# 3️⃣ Открываем соединение, если файла нет, он создастся автоматически
|
||
with db_lock:
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
|
||
# 4️⃣ Если базы не было, создаём таблицы
|
||
if not db_exists:
|
||
cursor.execute('''CREATE TABLE events (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
hash TEXT UNIQUE,
|
||
data TEXT,
|
||
delivered BOOLEAN)''')
|
||
|
||
cursor.execute('''CREATE TABLE subscriptions (
|
||
chat_id INTEGER,
|
||
region_id TEXT,
|
||
username TEXT,
|
||
active BOOLEAN DEFAULT TRUE,
|
||
skip BOOLEAN DEFAULT FALSE,
|
||
disaster_only BOOLEAN DEFAULT FALSE,
|
||
UNIQUE(chat_id, region_id))''')
|
||
|
||
cursor.execute('''CREATE TABLE whitelist (
|
||
chat_id INTEGER PRIMARY KEY,
|
||
username TEXT,
|
||
user_email TEXT)''')
|
||
|
||
cursor.execute('''CREATE TABLE admins (
|
||
chat_id INTEGER PRIMARY KEY,
|
||
username TEXT)''')
|
||
|
||
cursor.execute('''CREATE TABLE regions (
|
||
region_id TEXT PRIMARY KEY,
|
||
region_name TEXT,
|
||
active BOOLEAN DEFAULT TRUE)''')
|
||
|
||
cursor.execute('''CREATE TABLE user_events (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
chat_id INTEGER,
|
||
username TEXT,
|
||
action TEXT,
|
||
timestamp TEXT)''')
|
||
|
||
# Добавляем тестовые данные (если их нет)
|
||
cursor.execute('''INSERT OR IGNORE INTO regions (region_id, region_name) VALUES
|
||
('01', 'Адыгея'),
|
||
('02', 'Башкортостан (Уфа)'),
|
||
('04', 'Алтай'),
|
||
('19', 'Республика Хакасия')''')
|
||
|
||
conn.commit()
|
||
app.logger.info("✅ Database created and initialized successfully.")
|
||
else:
|
||
app.logger.info("✅ Database already exists. Skipping initialization.")
|
||
|
||
except Exception as e:
|
||
app.logger.error(f"❌ Error initializing database: {e}")
|
||
finally:
|
||
if 'conn' in locals(): # Проверяем, была ли создана переменная conn
|
||
conn.close()
|
||
|
||
|
||
def hash_data(data):
|
||
return hashlib.sha256(str(data).encode('utf-8')).hexdigest()
|
||
|
||
|
||
def is_whitelisted(chat_id):
|
||
with db_lock:
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
query = 'SELECT COUNT(*) FROM whitelist WHERE chat_id = ?'
|
||
telebot.logger.debug(f"Executing query: {query} with chat_id={chat_id}")
|
||
cursor.execute(query, (chat_id,))
|
||
count = cursor.fetchone()[0]
|
||
conn.close()
|
||
return count > 0
|
||
|
||
|
||
def add_to_whitelist(chat_id, username):
|
||
with db_lock:
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
query = 'INSERT OR IGNORE INTO whitelist (chat_id, username) VALUES (?, ?)'
|
||
telebot.logger.info(f"Executing query: {query} with chat_id={chat_id}, username={username}")
|
||
try:
|
||
cursor.execute(query, (chat_id, username))
|
||
conn.commit()
|
||
except Exception as e:
|
||
telebot.logger.error(f"Error during add to whitelist: {e}")
|
||
finally:
|
||
conn.close()
|
||
|
||
|
||
def rundeck_add_to_whitelist(chat_id, username, user_email):
|
||
with db_lock:
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
|
||
# Проверка существования chat_id
|
||
check_query = 'SELECT COUNT(*) FROM whitelist WHERE chat_id = ?'
|
||
cursor.execute(check_query, (chat_id,))
|
||
count = cursor.fetchone()[0]
|
||
|
||
if count > 0:
|
||
conn.close()
|
||
return False # Пользователь уже существует
|
||
|
||
# Вставка нового пользователя
|
||
insert_query = 'INSERT INTO whitelist (chat_id, username, user_email) VALUES (?, ?, ?)'
|
||
telebot.logger.info(
|
||
f"Rundeck executing query: {insert_query} with chat_id={chat_id}, username={username}, email={user_email}")
|
||
cursor.execute(insert_query, (chat_id, username, user_email))
|
||
conn.commit()
|
||
conn.close()
|
||
return True # Успешное добавление
|
||
|
||
|
||
def remove_from_whitelist(chat_id):
|
||
with db_lock:
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
query = 'DELETE FROM whitelist WHERE chat_id = ?'
|
||
telebot.logger.info(f"Executing query: {query} with chat_id={chat_id}")
|
||
cursor.execute(query, (chat_id,))
|
||
conn.commit()
|
||
conn.close()
|
||
|
||
|
||
def get_admins():
|
||
with db_lock:
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
cursor.execute('SELECT chat_id FROM admins')
|
||
admins = cursor.fetchall()
|
||
admins = [i[0] for i in admins]
|
||
conn.close()
|
||
return admins
|
||
|
||
|
||
def get_sorted_regions():
|
||
with db_lock:
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
cursor.execute('SELECT region_id, region_name FROM regions WHERE active = TRUE')
|
||
regions = cursor.fetchall()
|
||
conn.close()
|
||
# Сортируем регионы по числовому значению region_id
|
||
regions.sort(key=lambda x: int(x[0]))
|
||
return regions
|
||
|
||
|
||
def region_exists(region_id):
|
||
with db_lock:
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
cursor.execute('SELECT COUNT(*) FROM regions WHERE region_id = ? AND active = TRUE', (region_id,))
|
||
count = cursor.fetchone()[0]
|
||
conn.close()
|
||
return count > 0
|
||
|
||
|
||
def get_user_subscribed_regions(chat_id):
|
||
with db_lock:
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
cursor.execute('''
|
||
SELECT regions.region_id, regions.region_name
|
||
FROM subscriptions
|
||
JOIN regions ON subscriptions.region_id = regions.region_id
|
||
WHERE subscriptions.chat_id = ? AND subscriptions.active = TRUE AND subscriptions.skip = FALSE
|
||
ORDER BY regions.region_id
|
||
''', (chat_id,))
|
||
regions = cursor.fetchall()
|
||
conn.close()
|
||
# Сортируем регионы по числовому значению region_id
|
||
regions.sort(key=lambda x: int(x[0]))
|
||
return regions
|
||
|
||
|
||
def is_subscribed(chat_id, region_id):
|
||
with db_lock:
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
cursor.execute('''
|
||
SELECT COUNT(*)
|
||
FROM subscriptions
|
||
WHERE chat_id = ? AND region_id = ? AND active = TRUE AND skip = FALSE
|
||
''', (chat_id, region_id))
|
||
count = cursor.fetchone()[0]
|
||
conn.close()
|
||
return count > 0
|
||
|
||
|
||
def format_regions_list(regions):
|
||
return '\n'.join([f"{region_id} - {region_name}" for region_id, region_name in regions])
|
||
|
||
|
||
def log_user_event(chat_id, username, action):
|
||
timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
|
||
try:
|
||
with db_lock:
|
||
conn = sqlite3.connect(DB_PATH)
|
||
cursor = conn.cursor()
|
||
query = 'INSERT INTO user_events (chat_id, username, action, timestamp) VALUES (?, ?, ?, ?)'
|
||
telebot.logger.debug(
|
||
f"Executing query: {query} with chat_id={chat_id}, username={username}, action={action}, timestamp={timestamp}")
|
||
cursor.execute(query, (chat_id, username, action, timestamp))
|
||
conn.commit()
|
||
telebot.logger.info(f"User event logged: {chat_id} ({username}) - {action} at {timestamp}.")
|
||
except Exception as e:
|
||
telebot.logger.error(f"Error logging user event: {e}")
|
||
finally:
|
||
conn.close()
|