mirror of
https://github.com/pdxlocations/contact.git
synced 2026-05-09 23:04:26 +02:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b889711f63 | |||
| 361da1c078 |
+4
-1
@@ -7,4 +7,7 @@ client.db
|
|||||||
client.log
|
client.log
|
||||||
settings.log
|
settings.log
|
||||||
config.json
|
config.json
|
||||||
default_config.log
|
default_config.log
|
||||||
|
client.db-shm
|
||||||
|
client.db-wal
|
||||||
|
client.db.bk
|
||||||
+68
-41
@@ -1,17 +1,42 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
import time
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from utilities.utils import decimal_to_hex
|
from utilities.utils import decimal_to_hex
|
||||||
import ui.default_config as config
|
import ui.default_config as config
|
||||||
import globals
|
import globals
|
||||||
|
|
||||||
|
|
||||||
|
def get_db_connection():
|
||||||
|
"""Get a SQLite connection with optimized PRAGMA settings."""
|
||||||
|
db_connection = sqlite3.connect(config.db_file_path, check_same_thread=False)
|
||||||
|
db_cursor = db_connection.cursor()
|
||||||
|
|
||||||
|
# Check if journal_mode is already set to WAL
|
||||||
|
db_cursor.execute("PRAGMA journal_mode;")
|
||||||
|
current_journal_mode = db_cursor.fetchone()[0]
|
||||||
|
|
||||||
|
if current_journal_mode != "wal":
|
||||||
|
db_cursor.execute("PRAGMA journal_mode=WAL;")
|
||||||
|
|
||||||
|
# Apply remaining PRAGMA settings (these are fine to execute every time)
|
||||||
|
db_cursor.executescript("""
|
||||||
|
PRAGMA synchronous=NORMAL;
|
||||||
|
PRAGMA cache_size=-64000;
|
||||||
|
PRAGMA temp_store=MEMORY;
|
||||||
|
PRAGMA foreign_keys=ON;
|
||||||
|
""")
|
||||||
|
|
||||||
|
return db_connection
|
||||||
|
|
||||||
|
|
||||||
def get_table_name(channel):
|
def get_table_name(channel):
|
||||||
# Construct the table name
|
"""Returns a properly formatted and safe table name."""
|
||||||
table_name = f"{str(globals.myNodeNum)}_{channel}_messages"
|
safe_channel = re.sub(r'[^a-zA-Z0-9_]', '', str(channel))
|
||||||
quoted_table_name = f'"{table_name}"' # Quote the table name becuase we begin with numerics and contain spaces
|
table_name = f"{globals.myNodeNum}_{safe_channel}_messages"
|
||||||
return quoted_table_name
|
return f'"{table_name}"'
|
||||||
|
|
||||||
|
|
||||||
def save_message_to_db(channel, user_id, message_text):
|
def save_message_to_db(channel, user_id, message_text):
|
||||||
@@ -27,7 +52,7 @@ def save_message_to_db(channel, user_id, message_text):
|
|||||||
'''
|
'''
|
||||||
ensure_table_exists(quoted_table_name, schema)
|
ensure_table_exists(quoted_table_name, schema)
|
||||||
|
|
||||||
with sqlite3.connect(config.db_file_path) as db_connection:
|
with get_db_connection() as db_connection:
|
||||||
db_cursor = db_connection.cursor()
|
db_cursor = db_connection.cursor()
|
||||||
timestamp = int(time.time())
|
timestamp = int(time.time())
|
||||||
|
|
||||||
@@ -49,7 +74,7 @@ def save_message_to_db(channel, user_id, message_text):
|
|||||||
|
|
||||||
def update_ack_nak(channel, timestamp, message, ack):
|
def update_ack_nak(channel, timestamp, message, ack):
|
||||||
try:
|
try:
|
||||||
with sqlite3.connect(config.db_file_path) as db_connection:
|
with get_db_connection() as db_connection:
|
||||||
db_cursor = db_connection.cursor()
|
db_cursor = db_connection.cursor()
|
||||||
update_query = f"""
|
update_query = f"""
|
||||||
UPDATE {get_table_name(channel)}
|
UPDATE {get_table_name(channel)}
|
||||||
@@ -72,7 +97,7 @@ def update_ack_nak(channel, timestamp, message, ack):
|
|||||||
def load_messages_from_db():
|
def load_messages_from_db():
|
||||||
"""Load messages from the database for all channels and update globals.all_messages and globals.channel_list."""
|
"""Load messages from the database for all channels and update globals.all_messages and globals.channel_list."""
|
||||||
try:
|
try:
|
||||||
with sqlite3.connect(config.db_file_path) as db_connection:
|
with get_db_connection() as db_connection:
|
||||||
db_cursor = db_connection.cursor()
|
db_cursor = db_connection.cursor()
|
||||||
|
|
||||||
query = "SELECT name FROM sqlite_master WHERE type='table' AND name LIKE ?"
|
query = "SELECT name FROM sqlite_master WHERE type='table' AND name LIKE ?"
|
||||||
@@ -196,7 +221,7 @@ def update_node_info_in_db(user_id, long_name=None, short_name=None, hw_model=No
|
|||||||
try:
|
try:
|
||||||
ensure_node_table_exists() # Ensure the table exists before any operation
|
ensure_node_table_exists() # Ensure the table exists before any operation
|
||||||
|
|
||||||
with sqlite3.connect(config.db_file_path) as db_connection:
|
with get_db_connection() as db_connection:
|
||||||
db_cursor = db_connection.cursor()
|
db_cursor = db_connection.cursor()
|
||||||
table_name = f'"{globals.myNodeNum}_nodedb"' # Quote in case of numeric names
|
table_name = f'"{globals.myNodeNum}_nodedb"' # Quote in case of numeric names
|
||||||
|
|
||||||
@@ -223,16 +248,16 @@ def update_node_info_in_db(user_id, long_name=None, short_name=None, hw_model=No
|
|||||||
|
|
||||||
# Upsert logic
|
# Upsert logic
|
||||||
upsert_query = f'''
|
upsert_query = f'''
|
||||||
INSERT INTO {table_name} (user_id, long_name, short_name, hw_model, is_licensed, role, public_key, chat_archived)
|
INSERT INTO {table_name} (user_id, long_name, short_name, hw_model, is_licensed, role, public_key, chat_archived)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
ON CONFLICT(user_id) DO UPDATE SET
|
ON CONFLICT(user_id) DO UPDATE SET
|
||||||
long_name = excluded.long_name,
|
long_name = excluded.long_name,
|
||||||
short_name = excluded.short_name,
|
short_name = excluded.short_name,
|
||||||
hw_model = excluded.hw_model,
|
hw_model = excluded.hw_model,
|
||||||
is_licensed = excluded.is_licensed,
|
is_licensed = excluded.is_licensed,
|
||||||
role = excluded.role,
|
role = excluded.role,
|
||||||
public_key = excluded.public_key,
|
public_key = excluded.public_key,
|
||||||
chat_archived = excluded.chat_archived
|
chat_archived = COALESCE(excluded.chat_archived, chat_archived);
|
||||||
'''
|
'''
|
||||||
db_cursor.execute(upsert_query, (user_id, long_name, short_name, hw_model, is_licensed, role, public_key, chat_archived))
|
db_cursor.execute(upsert_query, (user_id, long_name, short_name, hw_model, is_licensed, role, public_key, chat_archived))
|
||||||
db_connection.commit()
|
db_connection.commit()
|
||||||
@@ -262,7 +287,7 @@ def ensure_node_table_exists():
|
|||||||
def ensure_table_exists(table_name, schema):
|
def ensure_table_exists(table_name, schema):
|
||||||
"""Ensure the given table exists in the database."""
|
"""Ensure the given table exists in the database."""
|
||||||
try:
|
try:
|
||||||
with sqlite3.connect(config.db_file_path) as db_connection:
|
with get_db_connection() as db_connection:
|
||||||
db_cursor = db_connection.cursor()
|
db_cursor = db_connection.cursor()
|
||||||
create_table_query = f"CREATE TABLE IF NOT EXISTS {table_name} ({schema})"
|
create_table_query = f"CREATE TABLE IF NOT EXISTS {table_name} ({schema})"
|
||||||
db_cursor.execute(create_table_query)
|
db_cursor.execute(create_table_query)
|
||||||
@@ -273,31 +298,32 @@ def ensure_table_exists(table_name, schema):
|
|||||||
logging.error(f"Unexpected error in ensure_table_exists({table_name}): {e}")
|
logging.error(f"Unexpected error in ensure_table_exists({table_name}): {e}")
|
||||||
|
|
||||||
|
|
||||||
|
name_cache = {}
|
||||||
|
|
||||||
def get_name_from_database(user_id, type="long"):
|
def get_name_from_database(user_id, type="long"):
|
||||||
"""
|
"""Retrieve a user's name from the node database with caching."""
|
||||||
Retrieve a user's name (long or short) from the node database.
|
# Check if we already cached both long and short names
|
||||||
|
if user_id in name_cache and type in name_cache[user_id]:
|
||||||
:param user_id: The user ID to look up.
|
return name_cache[user_id][type]
|
||||||
:param type: "long" for long name, "short" for short name.
|
|
||||||
:return: The retrieved name or the hex of the user id
|
|
||||||
"""
|
|
||||||
try:
|
try:
|
||||||
with sqlite3.connect(config.db_file_path) as db_connection:
|
with get_db_connection() as db_connection:
|
||||||
db_cursor = db_connection.cursor()
|
db_cursor = db_connection.cursor()
|
||||||
|
|
||||||
# Construct table name
|
|
||||||
table_name = f"{str(globals.myNodeNum)}_nodedb"
|
table_name = f"{str(globals.myNodeNum)}_nodedb"
|
||||||
nodeinfo_table = f'"{table_name}"' # Quote table name for safety
|
nodeinfo_table = f'"{table_name}"'
|
||||||
|
|
||||||
# Determine the correct column to fetch
|
|
||||||
column_name = "long_name" if type == "long" else "short_name"
|
|
||||||
|
|
||||||
# Query the database
|
# Fetch both long and short names in one query
|
||||||
query = f"SELECT {column_name} FROM {nodeinfo_table} WHERE user_id = ?"
|
db_cursor.execute(f"SELECT long_name, short_name FROM {nodeinfo_table} WHERE user_id = ?", (user_id,))
|
||||||
db_cursor.execute(query, (user_id,))
|
|
||||||
result = db_cursor.fetchone()
|
result = db_cursor.fetchone()
|
||||||
|
|
||||||
return result[0] if result else decimal_to_hex(user_id)
|
if result:
|
||||||
|
long_name, short_name = result or ("Unknown", "Unknown") # Handle empty result
|
||||||
|
name_cache[user_id] = {"long": long_name, "short": short_name}
|
||||||
|
return name_cache[user_id][type]
|
||||||
|
|
||||||
|
# If no result, store a fallback value in the cache to avoid future DB queries
|
||||||
|
name_cache[user_id] = {"long": decimal_to_hex(user_id), "short": decimal_to_hex(user_id)}
|
||||||
|
return name_cache[user_id][type]
|
||||||
|
|
||||||
except sqlite3.Error as e:
|
except sqlite3.Error as e:
|
||||||
logging.error(f"SQLite error in get_name_from_database: {e}")
|
logging.error(f"SQLite error in get_name_from_database: {e}")
|
||||||
@@ -306,10 +332,12 @@ def get_name_from_database(user_id, type="long"):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Unexpected error in get_name_from_database: {e}")
|
logging.error(f"Unexpected error in get_name_from_database: {e}")
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
|
|
||||||
|
|
||||||
def is_chat_archived(user_id):
|
def is_chat_archived(user_id):
|
||||||
|
"""Check if a chat is archived, returning 0 (False) if not found."""
|
||||||
try:
|
try:
|
||||||
with sqlite3.connect(config.db_file_path) as db_connection:
|
with get_db_connection() as db_connection:
|
||||||
db_cursor = db_connection.cursor()
|
db_cursor = db_connection.cursor()
|
||||||
table_name = f"{str(globals.myNodeNum)}_nodedb"
|
table_name = f"{str(globals.myNodeNum)}_nodedb"
|
||||||
nodeinfo_table = f'"{table_name}"'
|
nodeinfo_table = f'"{table_name}"'
|
||||||
@@ -321,9 +349,8 @@ def is_chat_archived(user_id):
|
|||||||
|
|
||||||
except sqlite3.Error as e:
|
except sqlite3.Error as e:
|
||||||
logging.error(f"SQLite error in is_chat_archived: {e}")
|
logging.error(f"SQLite error in is_chat_archived: {e}")
|
||||||
return "Unknown"
|
return 0
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error(f"Unexpected error in is_chat_archived: {e}")
|
logging.error(f"Unexpected error in is_chat_archived: {e}")
|
||||||
return "Unknown"
|
return 0
|
||||||
|
|
||||||
Reference in New Issue
Block a user