mirror of
https://github.com/infinition/Bjorn.git
synced 2025-12-13 16:14:57 +00:00
BREAKING CHANGE: Complete refactor of architecture to prepare BJORN V2 release, APIs, assets, and UI, webapp, logics, attacks, a lot of new features...
This commit is contained in:
141
web_utils/comment_utils.py
Normal file
141
web_utils/comment_utils.py
Normal file
@@ -0,0 +1,141 @@
|
||||
# web_utils/comment_utils.py
|
||||
"""
|
||||
Comment and status message management utilities.
|
||||
Handles status comments/messages displayed in the UI.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import json
|
||||
import re
|
||||
import traceback
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
import logging
|
||||
from logger import Logger
|
||||
logger = Logger(name="comment_utils.py", level=logging.DEBUG)
|
||||
class CommentUtils:
|
||||
"""Utilities for managing comments and status messages."""
|
||||
|
||||
def __init__(self, shared_data):
|
||||
self.logger = logger
|
||||
self.shared_data = shared_data
|
||||
|
||||
def get_sections(self, handler):
|
||||
"""Get list of comment sections (statuses) from DB."""
|
||||
try:
|
||||
rows = self.shared_data.db.query("SELECT DISTINCT status FROM comments ORDER BY status;")
|
||||
sections = [r["status"] for r in rows]
|
||||
|
||||
handler.send_response(200)
|
||||
handler.send_header('Content-Type', 'application/json')
|
||||
handler.end_headers()
|
||||
response = json.dumps({'status': 'success', 'sections': sections})
|
||||
handler.wfile.write(response.encode('utf-8'))
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error in get_sections: {e}")
|
||||
handler.send_response(500)
|
||||
handler.send_header('Content-Type', 'application/json')
|
||||
handler.end_headers()
|
||||
error_response = json.dumps({'status': 'error', 'message': str(e)})
|
||||
handler.wfile.write(error_response.encode('utf-8'))
|
||||
|
||||
def get_comments(self, handler):
|
||||
"""Get comments for a specific section from DB."""
|
||||
try:
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
query_components = parse_qs(urlparse(handler.path).query)
|
||||
section = query_components.get('section', [None])[0]
|
||||
if not section:
|
||||
raise ValueError('Section parameter is required')
|
||||
|
||||
rows = self.shared_data.db.query(
|
||||
"SELECT text FROM comments WHERE status=? ORDER BY id;",
|
||||
(section,)
|
||||
)
|
||||
comments = [r["text"] for r in rows]
|
||||
|
||||
handler.send_response(200)
|
||||
handler.send_header('Content-Type', 'application/json')
|
||||
handler.end_headers()
|
||||
response = json.dumps({'status': 'success', 'comments': comments})
|
||||
handler.wfile.write(response.encode('utf-8'))
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error in get_comments: {e}")
|
||||
handler.send_response(500)
|
||||
handler.send_header('Content-Type', 'application/json')
|
||||
handler.end_headers()
|
||||
error_response = json.dumps({'status': 'error', 'message': str(e)})
|
||||
handler.wfile.write(error_response.encode('utf-8'))
|
||||
|
||||
def save_comments(self, data):
|
||||
"""Save comment list for a section to DB (replaces existing)."""
|
||||
try:
|
||||
section = data.get('section')
|
||||
comments = data.get('comments')
|
||||
lang = data.get('lang', 'fr')
|
||||
theme = data.get('theme', section or 'general')
|
||||
weight = int(data.get('weight', 1))
|
||||
|
||||
if not section or comments is None:
|
||||
return {'status': 'error', 'message': 'Section and comments are required'}
|
||||
|
||||
if not isinstance(comments, list):
|
||||
return {'status': 'error', 'message': 'Comments must be a list of strings'}
|
||||
|
||||
# Replace section content
|
||||
with self.shared_data.db.transaction(immediate=True):
|
||||
self.shared_data.db.execute("DELETE FROM comments WHERE status=? AND lang=?", (section, lang))
|
||||
rows = []
|
||||
for txt in comments:
|
||||
t = str(txt).strip()
|
||||
if not t:
|
||||
continue
|
||||
rows.append((t, section, theme, lang, weight))
|
||||
if rows:
|
||||
self.shared_data.db.insert_comments(rows)
|
||||
|
||||
return {'status': 'success', 'message': 'Comments saved successfully'}
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error in save_comments: {e}")
|
||||
return {'status': 'error', 'message': str(e)}
|
||||
|
||||
def restore_default_comments(self, data=None):
|
||||
"""Restore default comments from JSON file to DB."""
|
||||
try:
|
||||
inserted = self.shared_data.db.import_comments_from_json(
|
||||
self.shared_data.default_comments_file,
|
||||
lang=(data.get('lang') if isinstance(data, dict) else None) or 'fr',
|
||||
clear_existing=True
|
||||
)
|
||||
return {
|
||||
'status': 'success',
|
||||
'message': f'Comments restored ({inserted} entries).'
|
||||
}
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error in restore_default_comments: {e}")
|
||||
self.logger.error(traceback.format_exc())
|
||||
return {'status': 'error', 'message': str(e)}
|
||||
|
||||
def delete_comment_section(self, data):
|
||||
"""Delete a comment section and its associated comments from DB."""
|
||||
try:
|
||||
section_name = data.get('section')
|
||||
lang = data.get('lang', 'fr')
|
||||
|
||||
if not section_name:
|
||||
return {'status': 'error', 'message': "Section name is required."}
|
||||
|
||||
if not re.match(r'^[\w\-\s]+$', section_name):
|
||||
return {'status': 'error', 'message': "Invalid section name."}
|
||||
|
||||
count = self.shared_data.db.execute(
|
||||
"DELETE FROM comments WHERE status=? AND lang=?;",
|
||||
(section_name, lang)
|
||||
)
|
||||
if count == 0:
|
||||
return {'status': 'error', 'message': f"Section '{section_name}' not found for lang='{lang}'."}
|
||||
|
||||
return {'status': 'success', 'message': 'Section deleted successfully.'}
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error in delete_comment_section: {e}")
|
||||
self.logger.error(traceback.format_exc())
|
||||
return {'status': 'error', 'message': str(e)}
|
||||
Reference in New Issue
Block a user