initial-draft

This commit is contained in:
2023-11-24 01:58:55 +03:00
parent 7304735041
commit ec20a4ebcd
22 changed files with 996 additions and 0 deletions

46
orm/author.py Normal file
View File

@@ -0,0 +1,46 @@
import time
from sqlalchemy import JSON as JSONType
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from services.db import Base
class AuthorRating(Base):
__tablename__ = "author_rating"
id = None # type: ignore
rater = Column(ForeignKey("author.id"), primary_key=True, index=True)
author = Column(ForeignKey("author.id"), primary_key=True, index=True)
value = Column(Integer)
class AuthorFollower(Base):
__tablename__ = "author_follower"
id = None # type: ignore
follower = Column(ForeignKey("author.id"), primary_key=True, index=True)
author = Column(ForeignKey("author.id"), primary_key=True, index=True)
created_at = Column(Integer, nullable=False, default=lambda: int(time.time()))
auto = Column(Boolean, nullable=False, default=False)
class Author(Base):
__tablename__ = "author"
user = Column(String, unique=True) # unbounded link with authorizer's User type
name = Column(String, nullable=True, comment="Display name")
slug = Column(String, unique=True, comment="Author's slug")
bio = Column(String, nullable=True, comment="Bio") # status description
about = Column(String, nullable=True, comment="About") # long and formatted
pic = Column(String, nullable=True, comment="Picture")
links = Column(JSONType, nullable=True, comment="Links")
ratings = relationship(AuthorRating, foreign_keys=AuthorRating.author)
created_at = Column(Integer, nullable=False, default=lambda: int(time.time()))
last_seen = Column(Integer, nullable=False, default=lambda: int(time.time()))
updated_at = Column(Integer, nullable=False, default=lambda: int(time.time()))
deleted_at = Column(Integer, nullable=True, comment="Deleted at")

25
orm/collection.py Normal file
View File

@@ -0,0 +1,25 @@
import time
from sqlalchemy import Column, ForeignKey, Integer, String
from services.db import Base
class ShoutCollection(Base):
__tablename__ = "shout_collection"
id = None # type: ignore
shout = Column(ForeignKey("shout.id"), primary_key=True)
collection = Column(ForeignKey("collection.id"), primary_key=True)
class Collection(Base):
__tablename__ = "collection"
slug = Column(String, unique=True)
title = Column(String, nullable=False, comment="Title")
body = Column(String, nullable=True, comment="Body")
pic = Column(String, nullable=True, comment="Picture")
created_at = Column(Integer, default=lambda: int(time.time()))
created_by = Column(ForeignKey("author.id"), comment="Created By")
publishedAt = Column(Integer, default=lambda: int(time.time()))

41
orm/community.py Normal file
View File

@@ -0,0 +1,41 @@
import time
from sqlalchemy import Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from orm.author import Author
from services.db import Base, local_session
class CommunityAuthor(Base):
__tablename__ = "community_author"
id = None # type: ignore
follower = Column(ForeignKey("author.id"), primary_key=True)
community = Column(ForeignKey("community.id"), primary_key=True)
joined_at = Column(Integer, nullable=False, default=lambda: int(time.time()))
role = Column(String, nullable=False)
class Community(Base):
__tablename__ = "community"
name = Column(String, nullable=False)
slug = Column(String, nullable=False, unique=True)
desc = Column(String, nullable=False, default="")
pic = Column(String, nullable=False, default="")
created_at = Column(Integer, nullable=False, default=lambda: int(time.time()))
authors = relationship(lambda: Author, secondary=CommunityAuthor.__tablename__)
@staticmethod
def init_table():
with local_session("orm.community") as session:
d = session.query(Community).filter(Community.slug == "discours").first()
if not d:
d = Community(name="Дискурс", slug="discours")
session.add(d)
session.commit()
print("[orm.community] created community %s" % d.slug)
Community.default_community = d
print("[orm.community] default community is %s" % d.slug)

32
orm/notification.py Normal file
View File

@@ -0,0 +1,32 @@
from enum import Enum as Enumeration
import time
from sqlalchemy import Boolean, Column, Enum, Integer
from sqlalchemy.dialects.postgresql import JSONB
from services.db import Base
class NotificationEntity(Enumeration):
REACTION = 1
SHOUT = 2
FOLLOWER = 3
class NotificationAction(Enumeration):
CREATE = 1
UPDATE = 2
DELETE = 3
SEEN = 4
FOLLOW = 5
UNFOLLOW = 6
class Notification(Base):
__tablename__ = "notification"
created_at = Column(Integer, default=lambda: int(time.time()))
seen = Column(Boolean, nullable=False, default=False, index=True)
entity = Column(Enum(NotificationEntity), nullable=False)
action = Column(Enum(NotificationAction), nullable=False)
payload = Column(JSONB, nullable=True)
# occurrences = Column(Integer, default=1)

41
orm/reaction.py Normal file
View File

@@ -0,0 +1,41 @@
import time
from enum import Enum as Enumeration
from sqlalchemy import Column, Enum, ForeignKey, Integer, String
from services.db import Base
class ReactionKind(Enumeration):
AGREE = 1 # +1
DISAGREE = 2 # -1
PROOF = 3 # +1
DISPROOF = 4 # -1
ASK = 5 # +0
PROPOSE = 6 # +0
QUOTE = 7 # +0 bookmark
COMMENT = 8 # +0
ACCEPT = 9 # +1
REJECT = 0 # -1
LIKE = 11 # +1
DISLIKE = 12 # -1
REMARK = 13 # 0
FOOTNOTE = 14 # 0
# TYPE = <reaction index> # rating diff
class Reaction(Base):
__tablename__ = "reaction"
body = Column(String, nullable=True, comment="Reaction Body")
created_at = Column(Integer, nullable=False, default=lambda: int(time.time()))
created_by = Column(ForeignKey("author.id"), nullable=False, index=True)
updated_at = Column(Integer, nullable=True, comment="Updated at")
deleted_at = Column(Integer, nullable=True, comment="Deleted at")
deleted_by = Column(ForeignKey("author.id"), nullable=True, index=True)
shout = Column(ForeignKey("shout.id"), nullable=False, index=True)
reply_to = Column(ForeignKey("reaction.id"), nullable=True)
range = Column(String, nullable=True, comment="<start index>:<end>")
kind = Column(Enum(ReactionKind), nullable=False)
oid = Column(String)

86
orm/shout.py Normal file
View File

@@ -0,0 +1,86 @@
import time
from enum import Enum as Enumeration
from sqlalchemy import JSON, Boolean, Column, Enum, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from orm.author import Author
from orm.community import Community
from orm.reaction import Reaction
from orm.topic import Topic
from services.db import Base
class ShoutTopic(Base):
__tablename__ = "shout_topic"
id = None # type: ignore
shout = Column(ForeignKey("shout.id"), primary_key=True, index=True)
topic = Column(ForeignKey("topic.id"), primary_key=True, index=True)
class ShoutReactionsFollower(Base):
__tablename__ = "shout_reactions_followers"
id = None # type: ignore
follower = Column(ForeignKey("author.id"), primary_key=True, index=True)
shout = Column(ForeignKey("shout.id"), primary_key=True, index=True)
auto = Column(Boolean, nullable=False, default=False)
created_at = Column(Integer, nullable=False, default=lambda: int(time.time()))
deleted_at = Column(Integer, nullable=True)
class ShoutAuthor(Base):
__tablename__ = "shout_author"
id = None # type: ignore
shout = Column(ForeignKey("shout.id"), primary_key=True, index=True)
author = Column(ForeignKey("author.id"), primary_key=True, index=True)
caption = Column(String, nullable=True, default="")
class ShoutCommunity(Base):
__tablename__ = "shout_community"
id = None # type: ignore
shout = Column(ForeignKey("shout.id"), primary_key=True, index=True)
community = Column(ForeignKey("community.id"), primary_key=True, index=True)
class ShoutVisibility(Enumeration):
AUTHORS = 0
COMMUNITY = 1
PUBLIC = 2
class Shout(Base):
__tablename__ = "shout"
created_at = Column(Integer, nullable=False, default=lambda: int(time.time()))
updated_at = Column(Integer, nullable=True)
published_at = Column(Integer, nullable=True)
deleted_at = Column(Integer, nullable=True)
deleted_by = Column(ForeignKey("author.id"), nullable=True)
body = Column(String, nullable=False, comment="Body")
slug = Column(String, unique=True)
cover = Column(String, nullable=True, comment="Cover image url")
lead = Column(String, nullable=True)
description = Column(String, nullable=True)
title = Column(String, nullable=True)
subtitle = Column(String, nullable=True)
layout = Column(String, nullable=True)
media = Column(JSON, nullable=True)
authors = relationship(lambda: Author, secondary="shout_author")
topics = relationship(lambda: Topic, secondary="shout_topic")
communities = relationship(lambda: Community, secondary="shout_community")
reactions = relationship(lambda: Reaction)
visibility = Column(Enum(ShoutVisibility), default=ShoutVisibility.AUTHORS)
lang = Column(String, nullable=False, default="ru", comment="Language")
version_of = Column(ForeignKey("shout.id"), nullable=True)
oid = Column(String, nullable=True)

26
orm/topic.py Normal file
View File

@@ -0,0 +1,26 @@
import time
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from services.db import Base
class TopicFollower(Base):
__tablename__ = "topic_followers"
id = None # type: ignore
follower = Column(ForeignKey("author.id"), primary_key=True, index=True)
topic = Column(ForeignKey("topic.id"), primary_key=True, index=True)
created_at = Column(Integer, nullable=False, default=lambda: int(time.time()))
auto = Column(Boolean, nullable=False, default=False)
class Topic(Base):
__tablename__ = "topic"
slug = Column(String, unique=True)
title = Column(String, nullable=False, comment="Title")
body = Column(String, nullable=True, comment="Body")
pic = Column(String, nullable=True, comment="Picture")
community = Column(ForeignKey("community.id"), default=1)
oid = Column(String, nullable=True, comment="Old ID")

30
orm/user.py Normal file
View File

@@ -0,0 +1,30 @@
import time
from sqlalchemy import JSON, Boolean, Column, Integer, String
from services.db import Base
class User(Base):
__tablename__ = "authorizer_users"
id = Column(String, primary_key=True, unique=True, nullable=False, default=None)
key = Column(String)
email = Column(String, unique=True)
email_verified_at = Column(Integer)
family_name = Column(String)
gender = Column(String)
given_name = Column(String)
is_multi_factor_auth_enabled = Column(Boolean)
middle_name = Column(String)
nickname = Column(String)
password = Column(String)
phone_number = Column(String, unique=True)
phone_number_verified_at = Column(Integer)
# preferred_username = Column(String, nullable=False)
picture = Column(String)
revoked_timestamp = Column(Integer)
roles = Column(JSON)
signup_methods = Column(String, default="magic_link_login")
created_at = Column(Integer, default=lambda: int(time.time()))
updated_at = Column(Integer, default=lambda: int(time.time()))