Files
forum-scrapper/Programm/Database/image_table.py
Bacruru Sakaguchi 1ddfe375e5 feat(core): add recursive loading and analyzer tools
Add recursive thread loading method to load threads with all messages and images from the database.

Add support for image captions in the database schema and Image model.

Introduce new analyzer tools for thread management:
- Load thread names from database
- Group threads by similarity
- Merge thread groups

Update main menu to include new Analyzer submenu and options to process threads without downloading images.
2026-02-18 18:19:33 +00:00

187 lines
5.9 KiB
Python
Executable File

"""
Image table class for database operations.
This module provides the ImageTable class that handles image-specific
database operations for storing and retrieving Image objects.
"""
import sqlite3
from typing import Optional
from ..Datamodel.Image import Image
class ImageTable:
"""
Table class for managing image data in the database.
Attributes:
connection: SQLite database connection
cursor: Database cursor for executing queries
"""
def __init__(self, connection: sqlite3.Connection):
"""
Initialize the image table with a database connection.
Args:
connection: SQLite database connection
"""
self.connection = connection
self.cursor = self.connection.cursor()
def create(self):
"""Create the images table if it doesn't exist."""
self.cursor.execute('''
CREATE TABLE IF NOT EXISTS images (
id INTEGER PRIMARY KEY AUTOINCREMENT,
message_id TEXT NOT NULL,
url TEXT NOT NULL,
name TEXT NOT NULL,
type INTEGER NOT NULL,
width INTEGER NOT NULL,
height INTEGER NOT NULL,
size INTEGER NOT NULL,
duration TEXT,
caption TEXT,
data BLOB,
FOREIGN KEY (message_id) REFERENCES messages (id) ON DELETE CASCADE
)
''')
self.connection.commit()
def exists(self, image_url: str) -> bool:
"""
Check if an image exists in the database.
Args:
image_url: Image URL to check
Returns:
True if image exists, False otherwise
"""
self.cursor.execute('SELECT 1 FROM images WHERE url = ?', (image_url,))
return self.cursor.fetchone() is not None
def save(self, image: Image) -> bool:
"""
Save an image to the database.
Args:
image: Image object to save
message_id: Message ID that this image belongs to
Returns:
True if image was saved, False if it already exists
"""
# Check if image exists
if self.exists(image.url):
# Load existing image to check if it has data
existing_image = self.load(image.url, include_data=False)
# If existing image has no data but new image has data, update it
if existing_image and existing_image.data is None and image.data is not None:
self.cursor.execute('''
UPDATE images
SET message_id = ?, url = ?, name = ?, type = ?, width = ?, height = ?, size = ?, duration = ?, caption = ?, data = ?
WHERE url = ?
''', (
image.ref_id,
image.url,
image.name,
image.type,
image.width,
image.height,
image.size,
image.duration,
image.caption,
image.data,
image.url
))
self.connection.commit()
return True
else:
# Image exists with data, skip
return False
# Image doesn't exist, insert it
self.cursor.execute('''
INSERT INTO images (message_id, url, name, type, width, height, size, duration, caption, data)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
''', (
image.ref_id,
image.url,
image.name,
image.type,
image.width,
image.height,
image.size,
image.duration,
image.caption,
image.data
))
self.connection.commit()
return True
def load(self, image_url: str, include_data: bool = True) -> Optional[Image]:
"""
Load an image from the database by URL.
Args:
image_url: Image URL to load
include_data: Whether to include the blob data in the loaded image (default: True)
Returns:
Image object if found, None otherwise
"""
# Conditionally select data column based on include_blob parameter
if include_data:
self.cursor.execute('''
SELECT message_id, url, name, type, width, height, size, duration, caption, data
FROM images WHERE url = ?
''', (image_url,))
else:
self.cursor.execute('''
SELECT message_id, url, name, type, width, height, size, duration, caption
FROM images WHERE url = ?
''', (image_url,))
row = self.cursor.fetchone()
if row is None:
return None
# Conditionally include data based on include_blob parameter
if include_data:
return Image(
ref_id=row[0],
url=row[1],
name=row[2],
type=row[3],
width=row[4],
height=row[5],
size=row[6],
duration=row[7],
caption=row[8],
data=row[9]
)
else:
return Image(
ref_id=row[0],
url=row[1],
name=row[2],
type=row[3],
width=row[4],
height=row[5],
size=row[6],
duration=row[7],
caption=row[8],
data=None
)
def commit(self):
"""Commit pending changes to the database."""
self.connection.commit()
def close(self):
"""Close the cursor."""
self.cursor.close()