Files
Python-Shannon/core/database.py
Poidevin, Antoine (ITOP CM) - AF 6a4ccc3376
All checks were successful
Build & Deploy Shannon / 🏗️ Build & Deploy Shannon (push) Successful in 3m1s
feat: add interactive exploration of Shannon's capacity formula with Plotly graphs
- Implemented bandwidth sensitivity and power sensitivity plots.
- Created a contour map for bit rate multiplying factors.
- Added input parameters for C/N and bandwidth with validation.
- Displayed computed results and sensitivity analysis metrics.
- Integrated interactive graphs for user exploration.
- Included background information section for user guidance.
2026-02-20 10:33:09 +01:00

108 lines
3.2 KiB
Python

"""
Database module for managing user contributions.
Uses parameterized queries (no SQL injection) and context managers.
"""
import sqlite3
import os
from datetime import datetime
DB_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "data")
def _get_db_path(db_name: str) -> str:
os.makedirs(DB_DIR, exist_ok=True)
return os.path.join(DB_DIR, db_name)
def _init_db(db_path: str):
with sqlite3.connect(db_path) as conn:
conn.execute(
"""CREATE TABLE IF NOT EXISTS contributions (
num INTEGER PRIMARY KEY,
name TEXT NOT NULL,
title TEXT NOT NULL,
keywords TEXT,
text TEXT NOT NULL,
date TEXT NOT NULL,
password TEXT DEFAULT ''
)"""
)
def write_contribution(
db_name: str, name: str, title: str, keywords: str, text: str, password: str = ""
) -> int:
"""Write a new contribution. Returns the new contribution ID."""
db_path = _get_db_path(db_name)
_init_db(db_path)
with sqlite3.connect(db_path) as conn:
cursor = conn.cursor()
cursor.execute("SELECT COALESCE(MAX(num), 0) FROM contributions")
next_id = cursor.fetchone()[0] + 1
cursor.execute(
"INSERT INTO contributions (num, name, title, keywords, text, date, password) "
"VALUES (?, ?, ?, ?, ?, ?, ?)",
(next_id, name, title, keywords, text, datetime.now().strftime("%Y-%m-%d"), password),
)
return next_id
def search_contributions(
db_name: str,
name_filter: str = "",
title_filter: str = "",
keywords_filter: str = "",
content_filter: str = "",
limit: int = 50,
) -> list[dict]:
"""Search contributions with optional filters. Returns list of dicts."""
db_path = _get_db_path(db_name)
if not os.path.isfile(db_path):
return []
_init_db(db_path)
with sqlite3.connect(db_path) as conn:
conn.row_factory = sqlite3.Row
cursor = conn.cursor()
cursor.execute(
"""SELECT num, name, title, keywords, text, date, password
FROM contributions
WHERE name LIKE ? AND title LIKE ? AND keywords LIKE ? AND text LIKE ?
ORDER BY num DESC
LIMIT ?""",
(
f"%{name_filter}%",
f"%{title_filter}%",
f"%{keywords_filter}%",
f"%{content_filter}%",
limit,
),
)
return [dict(row) for row in cursor.fetchall()]
def delete_contribution(db_name: str, num: int, password: str) -> bool:
"""Delete a contribution if the password matches. Returns True on success."""
db_path = _get_db_path(db_name)
if not os.path.isfile(db_path):
return False
with sqlite3.connect(db_path) as conn:
cursor = conn.cursor()
cursor.execute(
"SELECT password FROM contributions WHERE num = ?", (num,)
)
row = cursor.fetchone()
if row is None:
return False
if row[0] != password:
return False
cursor.execute("DELETE FROM contributions WHERE num = ?", (num,))
return True