Files
agenzia/src/database.py
T
David Frassi 51c56a6f30 Initial commit
2026-06-17 01:26:44 +02:00

240 lines
8.7 KiB
Python

import datetime
from sqlalchemy import create_engine, Column, Integer, String, Boolean, DateTime, Text
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class Media(Base):
__tablename__ = 'media'
id = Column(Integer, primary_key=True)
file_path = Column(String, unique=True, nullable=False)
file_type = Column(String) # 'image' or 'audio'
artist_id = Column(String)
is_used = Column(Boolean, default=False)
description = Column(Text)
source_url = Column(String)
thumbnail_path = Column(String) # NUOVO
created_at = Column(DateTime, default=datetime.datetime.utcnow)
last_used_at = Column(DateTime)
class Draft(Base):
__tablename__ = 'drafts'
id = Column(Integer, primary_key=True)
artist_id = Column(String)
title = Column(String)
caption = Column(Text)
hashtags = Column(Text)
image_path = Column(String)
image_paths = Column(Text) # JSON list of local paths
image_url = Column(String) # NUOVA COLONNA PER ANTEPRIMA DIRETTA
video_url = Column(String)
video_path = Column(String) # NUOVO
audio_analysis = Column(Text)
focus_points = Column(Text) # NUOVO: Coordinate JSON per la regia AI
status = Column(String, default='pending') # pending, approved, published
created_at = Column(DateTime, default=datetime.datetime.utcnow)
class Database:
def __init__(self, db_url="sqlite:///data/redazione.db"):
self.engine = create_engine(db_url)
Base.metadata.create_all(self.engine)
self.Session = sessionmaker(bind=self.engine)
def add_media(self, file_path, file_type, artist_id, description=None, source_url=None, thumbnail_path=None):
session = self.Session()
try:
media = session.query(Media).filter_by(file_path=file_path).first()
if not media:
media = Media(
file_path=file_path,
file_type=file_type,
artist_id=artist_id,
description=description,
source_url=source_url,
thumbnail_path=thumbnail_path
)
session.add(media)
session.commit()
elif thumbnail_path and not media.thumbnail_path:
media.thumbnail_path = thumbnail_path
session.commit()
return media
finally:
session.close()
def get_unused_image(self, artist_id):
from sqlalchemy.sql.expression import func
session = self.Session()
try:
return session.query(Media).filter_by(
artist_id=artist_id,
file_type='image',
is_used=False
).order_by(func.random()).first()
finally:
session.close()
def get_media_by_artist(self, artist_id, file_type):
session = self.Session()
try:
return session.query(Media).filter_by(
artist_id=artist_id,
file_type=file_type
).first()
finally:
session.close()
def get_audio_for_artist(self, artist_id):
return self.get_media_by_artist(artist_id, 'audio')
def mark_as_used(self, media_id):
session = self.Session()
try:
media = session.query(Media).get(media_id)
if media:
media.is_used = True
media.last_used_at = datetime.datetime.utcnow()
session.commit()
finally:
session.close()
def get_audio_for_artist(self, artist_id):
# We assume one main audio track per session or the latest added
session = self.Session()
try:
return session.query(Media).filter_by(
artist_id=artist_id,
file_type='audio'
).order_by(Media.created_at.desc()).first()
finally:
session.close()
def save_draft(self, artist_id, title, caption, hashtags, image_path, audio_analysis, image_url=None, video_url=None, image_paths=None, video_path=None, focus_points=None):
session = self.Session()
try:
draft = Draft(
artist_id=artist_id,
title=title,
caption=caption,
hashtags=hashtags,
image_path=image_path,
image_paths=image_paths,
image_url=image_url,
video_url=video_url,
video_path=video_path,
audio_analysis=audio_analysis,
focus_points=focus_points # SALVATAGGIO
)
session.add(draft)
session.commit()
return draft.id
finally:
session.close()
def get_recent_media(self, artist_id, limit=10):
session = self.Session()
try:
return session.query(Media).filter(
Media.artist_id == artist_id,
Media.file_type.in_(['image', 'video'])
).order_by(Media.created_at.desc()).limit(limit).all()
finally:
session.close()
def get_mixed_assets(self, artist_id, total=12):
from sqlalchemy.sql.expression import func
session = self.Session()
try:
# 1. Seleziona una copertina (preferibilmente immagine mai usata)
cover = session.query(Media).filter_by(
artist_id=artist_id,
file_type='image',
is_used=False
).order_by(func.random()).first()
if not cover:
cover = session.query(Media).filter_by(
artist_id=artist_id,
file_type='image'
).order_by(func.random()).first()
if not cover:
# Se proprio non ci sono immagini, prendi un video come cover
cover = session.query(Media).filter_by(
artist_id=artist_id,
file_type='video'
).order_by(func.random()).first()
if not cover:
return []
# 2. Seleziona un mix di altre immagini e video
others = session.query(Media).filter(
Media.artist_id == artist_id,
Media.file_type.in_(['image', 'video']),
Media.id != cover.id
).order_by(func.random()).limit(total - 1).all()
return [cover] + others
finally:
session.close()
def get_pending_drafts(self, artist_id=None):
session = self.Session()
try:
query = session.query(Draft).filter_by(status='pending')
if artist_id:
query = query.filter_by(artist_id=artist_id)
return query.all()
finally:
session.close()
def get_media_by_path(self, file_path):
session = self.Session()
try:
return session.query(Media).filter_by(file_path=file_path).first()
finally:
session.close()
def delete_draft(self, draft_id):
session = self.Session()
try:
draft = session.query(Draft).filter_by(id=draft_id).first()
if draft:
session.delete(draft)
session.commit()
finally:
session.close()
def update_draft(self, draft_id, title=None, caption=None, hashtags=None, image_path=None, status=None, audio_analysis=None, video_url=None, video_path=None, image_paths=None, focus_points=None):
session = self.Session()
try:
draft = session.query(Draft).get(draft_id)
if draft:
if title is not None: draft.title = title
if caption is not None: draft.caption = caption
if hashtags is not None: draft.hashtags = hashtags
if image_path is not None: draft.image_path = image_path
if status is not None: draft.status = status
if audio_analysis is not None: draft.audio_analysis = audio_analysis
if video_url is not None: draft.video_url = video_url
if video_path is not None: draft.video_path = video_path
if image_paths is not None: draft.image_paths = image_paths
if focus_points is not None: draft.focus_points = focus_points # AGGIORNAMENTO
session.commit()
return True
return False
finally:
session.close()
def mark_as_published(self, draft_id):
session = self.Session()
try:
draft = session.query(Draft).filter_by(id=draft_id).first()
if draft:
draft.status = 'published'
session.commit()
finally:
session.close()