implement post metadata import and views. implemented series paging and reader view.

This commit is contained in:
Bryan Van Deusen
2026-01-22 22:19:11 -05:00
parent f41acb40f6
commit a05aee5a07
16 changed files with 2298 additions and 8 deletions
+63
View File
@@ -101,6 +101,69 @@ class ImportBatch(db.Model):
completed_at = db.Column(db.DateTime, nullable=True)
class PostMetadata(db.Model):
"""
Stores metadata about posts from external platforms (Patreon, SubscribeStar, HentaiFoundry).
Links to a Tag with kind='post' (format: post:platform:artist:id).
"""
__tablename__ = "post_metadata"
id = db.Column(db.Integer, primary_key=True)
# Link to the post tag (post:platform:artist:id)
tag_id = db.Column(db.Integer, db.ForeignKey("tag.id", ondelete="CASCADE"), nullable=False, unique=True)
tag = db.relationship("Tag", backref=db.backref("post_metadata", uselist=False))
# Platform identification
platform = db.Column(db.String(64), nullable=False) # patreon, subscribestar, hentaifoundry
post_id = db.Column(db.String(64), nullable=False) # Original post ID on platform
artist = db.Column(db.String(255), nullable=True)
# Content
title = db.Column(db.String(512), nullable=True)
description = db.Column(db.Text, nullable=True) # May contain HTML
source_url = db.Column(db.String(1024), nullable=True) # Link to original post
# Statistics
attachment_count = db.Column(db.Integer, default=0) # Number of images in post
# Timestamps
published_at = db.Column(db.DateTime, nullable=True) # Original publish date
created_at = db.Column(db.DateTime, default=db.func.now())
updated_at = db.Column(db.DateTime, default=db.func.now(), onupdate=db.func.now())
class SeriesPage(db.Model):
"""
Links images to series tags with page numbers for ordered reading.
An image can only belong to one series at a time.
"""
__tablename__ = "series_page"
id = db.Column(db.Integer, primary_key=True)
# Link to the series tag (must be kind='series')
series_tag_id = db.Column(db.Integer, db.ForeignKey("tag.id", ondelete="CASCADE"), nullable=False)
series_tag = db.relationship("Tag", backref=db.backref("series_pages", lazy="dynamic"))
# Link to the image (unique - image can only be in one series)
image_id = db.Column(db.Integer, db.ForeignKey("image_record.id", ondelete="CASCADE"), nullable=False, unique=True)
image = db.relationship("ImageRecord", backref=db.backref("series_page", uselist=False))
# Page number within the series
page_number = db.Column(db.Integer, nullable=False)
# Timestamps
created_at = db.Column(db.DateTime, default=db.func.now())
updated_at = db.Column(db.DateTime, default=db.func.now(), onupdate=db.func.now())
__table_args__ = (
# Each page number must be unique within a series
db.UniqueConstraint('series_tag_id', 'page_number', name='uq_series_page_number'),
db.Index('ix_series_page_series_tag', 'series_tag_id'),
)
class ImportTask(db.Model):
"""
Tracks the state of each file being processed through the import pipeline.