Files
mikrotik-proxy-api/database.py
T

202 lines
6.4 KiB
Python
Raw Normal View History

2026-09-20 19:47:02 +03:00
import sqlite3
import os
DB_PATH = os.path.join(os.path.dirname(__file__), 'app_data.db')
def init_db():
conn = sqlite3.connect(DB_PATH)
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS address_list_items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ip TEXT UNIQUE NOT NULL,
list_name TEXT NOT NULL,
comment TEXT,
mikrotik_id TEXT,
enabled BOOLEAN DEFAULT TRUE,
last_sync DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS admins (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
password_hash TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS named_lists (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE NOT NULL
)
''')
# Миграция: добавляем существующие уникальные имена списков в новую таблицу
cursor.execute('SELECT DISTINCT list_name FROM address_list_items')
existing_lists = cursor.fetchall()
for row in existing_lists:
cursor.execute('INSERT OR IGNORE INTO named_lists (name) VALUES (?)', (row[0],))
# Если список пуст, создаем дефолтный
cursor.execute('SELECT COUNT(*) FROM named_lists')
if cursor.fetchone()[0] == 0:
cursor.execute('INSERT INTO named_lists (name) VALUES (?)', ('trusted',))
conn.commit()
conn.close()
def get_db_connection():
conn = sqlite3.connect(DB_PATH)
conn.row_factory = sqlite3.Row
return conn
def get_item_by_ip(ip):
conn = get_db_connection()
item = conn.execute('SELECT * FROM address_list_items WHERE ip = ?', (ip,)).fetchone()
conn.close()
return item
def get_all_items(list_name=None):
conn = get_db_connection()
if list_name:
items = conn.execute('SELECT * FROM address_list_items WHERE list_name = ?', (list_name,)).fetchall()
else:
items = conn.execute('SELECT * FROM address_list_items').fetchall()
conn.close()
return [dict(i) for i in items]
def add_item(ip, list_name, comment, mikrotik_id, enabled=True):
conn = get_db_connection()
try:
cursor = conn.cursor()
cursor.execute(
'INSERT INTO address_list_items (ip, list_name, comment, mikrotik_id, enabled) VALUES (?, ?, ?, ?, ?)',
(ip, list_name, comment, mikrotik_id, enabled)
)
conn.commit()
return True, cursor.lastrowid
except sqlite3.IntegrityError:
return False, "IP already exists"
finally:
conn.close()
def update_item_status(ip, enabled):
conn = get_db_connection()
conn.execute(
'UPDATE address_list_items SET enabled = ?, last_sync = CURRENT_TIMESTAMP WHERE ip = ?',
(enabled, ip)
)
conn.commit()
conn.close()
def update_mikrotik_id(ip, mikrotik_id):
conn = get_db_connection()
conn.execute(
'UPDATE address_list_items SET mikrotik_id = ? WHERE ip = ?',
(mikrotik_id, ip)
)
conn.commit()
conn.close()
def delete_item_by_ip(ip):
conn = get_db_connection()
conn.execute('DELETE FROM address_list_items WHERE ip = ?', (ip,))
conn.commit()
conn.close()
def delete_item_by_id(db_id):
conn = get_db_connection()
cursor = conn.cursor()
item = conn.execute('SELECT ip, mikrotik_id FROM address_list_items WHERE id = ?', (db_id,)).fetchone()
if item:
conn.execute('DELETE FROM address_list_items WHERE id = ?', (db_id,))
conn.commit()
conn.close()
return dict(item)
conn.close()
return None
def get_item_by_id(db_id):
conn = get_db_connection()
item = conn.execute('SELECT * FROM address_list_items WHERE id = ?', (db_id,)).fetchone()
conn.close()
return item
def get_unique_lists():
conn = get_db_connection()
lists = conn.execute('SELECT name FROM named_lists ORDER BY name').fetchall()
conn.close()
return [row['name'] for row in lists]
def get_named_lists_detailed():
conn = get_db_connection()
lists = conn.execute('SELECT * FROM named_lists ORDER BY name').fetchall()
conn.close()
return [dict(row) for row in lists]
def add_named_list(name):
conn = get_db_connection()
try:
conn.execute('INSERT INTO named_lists (name) VALUES (?)', (name,))
conn.commit()
return True, ""
except sqlite3.IntegrityError:
return False, "List already exists"
finally:
conn.close()
def delete_named_list(list_id):
conn = get_db_connection()
try:
# Проверяем, используются ли записи из этого списка
list_name_row = conn.execute('SELECT name FROM named_lists WHERE id = ?', (list_id,)).fetchone()
if not list_name_row:
return False, "Not found"
usage_count = conn.execute('SELECT COUNT(*) FROM address_list_items WHERE list_name = ?', (list_name_row['name'],)).fetchone()[0]
if usage_count > 0:
return False, f"Cannot delete: {usage_count} addresses are still in this list"
conn.execute('DELETE FROM named_lists WHERE id = ?', (list_id,))
conn.commit()
return True, ""
finally:
conn.close()
# --- Admin Operations ---
def get_admin(username):
conn = get_db_connection()
admin = conn.execute('SELECT * FROM admins WHERE username = ?', (username,)).fetchone()
conn.close()
return admin
def add_admin(username, password_hash):
conn = get_db_connection()
try:
conn.execute('INSERT INTO admins (username, password_hash) VALUES (?, ?)', (username, password_hash))
conn.commit()
return True
except sqlite3.IntegrityError:
return False
finally:
conn.close()
def update_admin(old_username, new_username, new_password_hash):
conn = get_db_connection()
try:
conn.execute(
'UPDATE admins SET username = ?, password_hash = ? WHERE username = ?',
(new_username, new_password_hash, old_username)
)
conn.commit()
return True
except Exception:
return False
finally:
conn.close()
if __name__ == '__main__':
init_db()
print("Database initialized.")