gallery.accords-library.com/server/szurubooru/model/post.py

389 lines
11 KiB
Python
Raw Permalink Normal View History

from typing import List
import sqlalchemy as sa
2020-05-04 09:20:23 +00:00
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.hybrid import hybrid_property
2020-05-04 09:20:23 +00:00
from sqlalchemy.ext.orderinglist import ordering_list
2016-04-17 10:55:07 +00:00
from szurubooru.model.base import Base
from szurubooru.model.comment import Comment
from szurubooru.model.pool import PoolPost
2016-04-22 16:36:12 +00:00
class PostFeature(Base):
__tablename__ = "post_feature"
2016-04-22 16:36:12 +00:00
post_feature_id = sa.Column("id", sa.Integer, primary_key=True)
post_id = sa.Column(
"post_id",
sa.Integer,
sa.ForeignKey("post.id"),
nullable=False,
index=True,
)
user_id = sa.Column(
"user_id",
sa.Integer,
sa.ForeignKey("user.id"),
nullable=False,
index=True,
)
time = sa.Column("time", sa.DateTime, nullable=False)
2016-04-22 16:36:12 +00:00
post = sa.orm.relationship("Post") # type: Post
user = sa.orm.relationship(
"User",
backref=sa.orm.backref("post_features", cascade="all, delete-orphan"),
)
2016-04-22 16:36:12 +00:00
2016-04-22 16:36:12 +00:00
class PostScore(Base):
__tablename__ = "post_score"
2016-04-22 16:36:12 +00:00
post_id = sa.Column(
"post_id",
sa.Integer,
sa.ForeignKey("post.id"),
primary_key=True,
nullable=False,
index=True,
)
user_id = sa.Column(
"user_id",
sa.Integer,
sa.ForeignKey("user.id"),
primary_key=True,
nullable=False,
index=True,
)
time = sa.Column("time", sa.DateTime, nullable=False)
score = sa.Column("score", sa.Integer, nullable=False)
2016-04-22 16:36:12 +00:00
post = sa.orm.relationship("Post")
user = sa.orm.relationship(
"User",
backref=sa.orm.backref("post_scores", cascade="all, delete-orphan"),
)
2016-04-22 16:36:12 +00:00
2016-04-22 16:36:12 +00:00
class PostFavorite(Base):
__tablename__ = "post_favorite"
2016-04-22 16:36:12 +00:00
post_id = sa.Column(
"post_id",
sa.Integer,
sa.ForeignKey("post.id"),
primary_key=True,
nullable=False,
index=True,
)
user_id = sa.Column(
"user_id",
sa.Integer,
sa.ForeignKey("user.id"),
primary_key=True,
nullable=False,
index=True,
)
time = sa.Column("time", sa.DateTime, nullable=False)
2016-04-22 16:36:12 +00:00
post = sa.orm.relationship("Post")
user = sa.orm.relationship(
"User",
backref=sa.orm.backref("post_favorites", cascade="all, delete-orphan"),
)
2016-04-22 16:36:12 +00:00
2016-04-22 16:36:12 +00:00
class PostNote(Base):
__tablename__ = "post_note"
2016-04-22 16:36:12 +00:00
post_note_id = sa.Column("id", sa.Integer, primary_key=True)
post_id = sa.Column(
"post_id",
sa.Integer,
sa.ForeignKey("post.id"),
nullable=False,
index=True,
)
polygon = sa.Column("polygon", sa.PickleType, nullable=False)
text = sa.Column("text", sa.UnicodeText, nullable=False)
2016-04-22 16:36:12 +00:00
post = sa.orm.relationship("Post")
2016-04-22 16:36:12 +00:00
2016-04-17 10:55:07 +00:00
class PostRelation(Base):
__tablename__ = "post_relation"
2016-04-17 10:55:07 +00:00
parent_id = sa.Column(
"parent_id",
sa.Integer,
sa.ForeignKey("post.id"),
primary_key=True,
nullable=False,
index=True,
)
child_id = sa.Column(
"child_id",
sa.Integer,
sa.ForeignKey("post.id"),
primary_key=True,
nullable=False,
index=True,
)
2016-04-17 10:55:07 +00:00
def __init__(self, parent_id: int, child_id: int) -> None:
2016-04-17 10:55:07 +00:00
self.parent_id = parent_id
self.child_id = child_id
2016-04-17 10:55:07 +00:00
class PostTag(Base):
__tablename__ = "post_tag"
2016-04-17 10:55:07 +00:00
post_id = sa.Column(
"post_id",
sa.Integer,
sa.ForeignKey("post.id"),
primary_key=True,
nullable=False,
index=True,
)
tag_id = sa.Column(
"tag_id",
sa.Integer,
sa.ForeignKey("tag.id"),
primary_key=True,
nullable=False,
index=True,
)
2016-04-17 10:55:07 +00:00
def __init__(self, post_id: int, tag_id: int) -> None:
2016-04-17 10:55:07 +00:00
self.post_id = post_id
self.tag_id = tag_id
2016-04-17 10:55:07 +00:00
class PostSignature(Base):
__tablename__ = "post_signature"
post_id = sa.Column(
"post_id",
sa.Integer,
sa.ForeignKey("post.id"),
primary_key=True,
nullable=False,
index=True,
)
signature = sa.Column("signature", sa.LargeBinary, nullable=False)
words = sa.Column(
"words",
sa.dialects.postgresql.ARRAY(sa.Integer, dimensions=1),
nullable=False,
index=True,
)
post = sa.orm.relationship("Post")
2016-04-17 10:55:07 +00:00
class Post(Base):
__tablename__ = "post"
2016-04-17 10:55:07 +00:00
SAFETY_SAFE = "safe"
SAFETY_SKETCHY = "sketchy"
SAFETY_UNSAFE = "unsafe"
TYPE_IMAGE = "image"
TYPE_ANIMATION = "animation"
TYPE_VIDEO = "video"
TYPE_FLASH = "flash"
2016-04-17 10:55:07 +00:00
FLAG_LOOP = "loop"
FLAG_SOUND = "sound"
2016-04-30 21:17:08 +00:00
# basic meta
post_id = sa.Column("id", sa.Integer, primary_key=True)
user_id = sa.Column(
"user_id",
sa.Integer,
sa.ForeignKey("user.id", ondelete="SET NULL"),
2016-08-15 16:36:14 +00:00
nullable=True,
index=True,
)
version = sa.Column("version", sa.Integer, default=1, nullable=False)
creation_time = sa.Column("creation_time", sa.DateTime, nullable=False)
last_edit_time = sa.Column("last_edit_time", sa.DateTime)
safety = sa.Column("safety", sa.Unicode(32), nullable=False)
source = sa.Column("source", sa.Unicode(2048))
flags_string = sa.Column("flags", sa.Unicode(32), default="")
2016-04-30 21:17:08 +00:00
# content description
type = sa.Column("type", sa.Unicode(32), nullable=False)
checksum = sa.Column("checksum", sa.Unicode(64), nullable=False)
checksum_md5 = sa.Column("checksum_md5", sa.Unicode(32))
file_size = sa.Column("file_size", sa.BigInteger)
canvas_width = sa.Column("image_width", sa.Integer)
canvas_height = sa.Column("image_height", sa.Integer)
mime_type = sa.Column("mime-type", sa.Unicode(32), nullable=False)
2016-04-17 10:55:07 +00:00
2016-04-30 21:17:08 +00:00
# foreign tables
user = sa.orm.relationship("User")
tags = sa.orm.relationship("Tag", backref="posts", secondary="post_tag")
signature = sa.orm.relationship(
"PostSignature",
uselist=False,
cascade="all, delete, delete-orphan",
lazy="joined",
)
relations = sa.orm.relationship(
"Post",
secondary="post_relation",
2016-04-17 10:55:07 +00:00
primaryjoin=post_id == PostRelation.parent_id,
secondaryjoin=post_id == PostRelation.child_id,
lazy="joined",
backref="related_by",
)
features = sa.orm.relationship(
"PostFeature", cascade="all, delete-orphan", lazy="joined"
)
scores = sa.orm.relationship(
"PostScore", cascade="all, delete-orphan", lazy="joined"
)
favorited_by = sa.orm.relationship(
"PostFavorite", cascade="all, delete-orphan", lazy="joined"
)
notes = sa.orm.relationship(
"PostNote", cascade="all, delete-orphan", lazy="joined"
)
comments = sa.orm.relationship("Comment", cascade="all, delete-orphan")
2020-05-04 09:20:23 +00:00
_pools = sa.orm.relationship(
"PoolPost",
cascade="all,delete-orphan",
lazy="select",
order_by="PoolPost.order",
back_populates="post",
)
pools = association_proxy("_pools", "pool")
2016-04-30 21:17:08 +00:00
# dynamic columns
tag_count = sa.orm.column_property(
sa.sql.expression.select(
[sa.sql.expression.func.count(PostTag.tag_id)]
)
.where(PostTag.post_id == post_id)
.correlate_except(PostTag)
)
2016-04-17 10:55:07 +00:00
canvas_area = sa.orm.column_property(canvas_width * canvas_height)
canvas_aspect_ratio = sa.orm.column_property(
sa.sql.expression.func.cast(canvas_width, sa.Float)
/ sa.sql.expression.func.cast(canvas_height, sa.Float)
)
2016-05-07 19:42:03 +00:00
2016-04-22 18:58:04 +00:00
@property
def is_featured(self) -> bool:
2017-04-24 21:30:53 +00:00
featured_post = (
sa.orm.object_session(self)
.query(PostFeature)
.order_by(PostFeature.time.desc())
.first()
)
2016-04-22 18:58:04 +00:00
return featured_post and featured_post.post_id == self.post_id
@hybrid_property
def flags(self) -> List[str]:
return sorted([x for x in self.flags_string.split(",") if x])
@flags.setter
def flags(self, data: List[str]) -> None:
self.flags_string = ",".join([x for x in data if x])
score = sa.orm.column_property(
sa.sql.expression.select(
[
sa.sql.expression.func.coalesce(
sa.sql.expression.func.sum(PostScore.score), 0
)
]
)
.where(PostScore.post_id == post_id)
.correlate_except(PostScore)
)
2016-04-24 14:34:06 +00:00
favorite_count = sa.orm.column_property(
sa.sql.expression.select(
[sa.sql.expression.func.count(PostFavorite.post_id)]
)
.where(PostFavorite.post_id == post_id)
.correlate_except(PostFavorite)
)
2016-04-28 17:04:44 +00:00
last_favorite_time = sa.orm.column_property(
sa.sql.expression.select(
[sa.sql.expression.func.max(PostFavorite.time)]
)
.where(PostFavorite.post_id == post_id)
.correlate_except(PostFavorite)
)
2016-04-28 17:04:44 +00:00
feature_count = sa.orm.column_property(
sa.sql.expression.select(
[sa.sql.expression.func.count(PostFeature.post_id)]
)
.where(PostFeature.post_id == post_id)
.correlate_except(PostFeature)
)
2016-04-24 14:34:06 +00:00
last_feature_time = sa.orm.column_property(
sa.sql.expression.select(
[sa.sql.expression.func.max(PostFeature.time)]
)
.where(PostFeature.post_id == post_id)
.correlate_except(PostFeature)
)
2016-04-24 14:34:06 +00:00
comment_count = sa.orm.column_property(
sa.sql.expression.select(
[sa.sql.expression.func.count(Comment.post_id)]
)
.where(Comment.post_id == post_id)
.correlate_except(Comment)
)
2016-05-07 19:42:03 +00:00
last_comment_creation_time = sa.orm.column_property(
sa.sql.expression.select(
[sa.sql.expression.func.max(Comment.creation_time)]
)
.where(Comment.post_id == post_id)
.correlate_except(Comment)
)
2016-05-07 19:42:03 +00:00
last_comment_edit_time = sa.orm.column_property(
sa.sql.expression.select(
[sa.sql.expression.func.max(Comment.last_edit_time)]
)
.where(Comment.post_id == post_id)
.correlate_except(Comment)
)
2016-05-07 19:42:03 +00:00
note_count = sa.orm.column_property(
sa.sql.expression.select(
[sa.sql.expression.func.count(PostNote.post_id)]
)
.where(PostNote.post_id == post_id)
.correlate_except(PostNote)
)
2016-06-13 18:08:39 +00:00
relation_count = sa.orm.column_property(
sa.sql.expression.select(
[sa.sql.expression.func.count(PostRelation.child_id)]
)
.where(
(PostRelation.parent_id == post_id)
| (PostRelation.child_id == post_id)
)
.correlate_except(PostRelation)
)
__mapper_args__ = {
"version_id_col": version,
"version_id_generator": False,
}