wip refactoring: reactions, storages isolated

This commit is contained in:
2022-07-21 14:58:50 +03:00
parent edcefadeab
commit 6cb5061ce5
43 changed files with 1674 additions and 1779 deletions

View File

@@ -1,18 +1,19 @@
from orm.rbac import Operation, Resource, Permission, Role, RoleStorage
from orm.community import Community, CommunitySubscription
from orm.user import User, UserRating, UserRole, UserStorage
from orm.topic import Topic, TopicSubscription, TopicStorage
from orm.rbac import Operation, Resource, Permission, Role
from storages.roles import RoleStorage
from orm.community import Community
from orm.user import User, UserRating
from orm.topic import Topic, TopicFollower
from orm.notification import Notification
from orm.shout import Shout, ShoutAuthor, ShoutTopic, ShoutRating, ShoutViewByDay,\
ShoutRatingStorage, ShoutViewStorage, ShoutCommentsSubscription
from orm.shout import Shout
from orm.reaction import Reaction
from storages.topics import TopicStorage
from storages.users import UserStorage
from storages.viewed import ViewedStorage
from orm.base import Base, engine, local_session
from orm.comment import Comment, CommentRating #, CommentRatingStorage
from orm.proposal import Proposal, ProposalRating #, ProposalRatingStorage
__all__ = ["User", "Role", "Community", "Operation", \
"Permission", "Shout", "Topic", "TopicSubscription", \
"Notification", "ShoutRating", "Comment", "CommentRating", \
"UserRating", "Proposal", "ProposalRating"]
__all__ = ["User", "Role", "Operation", "Permission", \
"Community", "Shout", "Topic", "TopicFollower", \
"Notification", "Reaction", "UserRating"]
Base.metadata.create_all(engine)
Operation.init_table()
@@ -22,10 +23,7 @@ Community.init_table()
Role.init_table()
with local_session() as session:
ShoutRatingStorage.init(session)
# CommentRatingStorage.init(session)
# ProposalRatingStorage.init(session)
ShoutViewStorage.init(session)
ViewedStorage.init(session)
RoleStorage.init(session)
UserStorage.init(session)
TopicStorage.init(session)

View File

@@ -1,30 +0,0 @@
from typing import List
from datetime import datetime
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Boolean
from sqlalchemy.orm import relationship
from orm.base import Base
class CommentRating(Base):
__tablename__ = "comment_rating"
id = None
comment_id = Column(ForeignKey('comment.id'), primary_key = True)
createdBy = Column(ForeignKey('user.slug'), primary_key = True)
createdAt: str = Column(DateTime, nullable=False, default = datetime.now, comment="Timestamp")
value = Column(Integer)
class Comment(Base):
__tablename__ = 'comment'
body: str = Column(String, nullable=False, comment="Comment Body")
createdAt = Column(DateTime, nullable=False, default = datetime.now, comment="Created at")
createdBy: str = Column(ForeignKey("user.slug"), nullable=False, comment="Sender")
updatedAt = Column(DateTime, nullable=True, comment="Updated at")
updatedBy = Column(ForeignKey("user.slug"), nullable=True, comment="Last Editor")
deletedAt = Column(DateTime, nullable=True, comment="Deleted at")
deletedBy = Column(ForeignKey("user.slug"), nullable=True, comment="Deleted by")
shout = Column(ForeignKey("shout.slug"), nullable=False)
replyTo: int = Column(ForeignKey("comment.id"), nullable=True, comment="comment ID")
ratings = relationship(CommentRating, foreign_keys=CommentRating.comment_id)
oid: str = Column(String, nullable=True)

View File

@@ -1,14 +1,12 @@
from datetime import datetime
from enum import unique
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime
from sqlalchemy.orm import relationship, backref
from sqlalchemy import Column, String, ForeignKey, DateTime
from orm.base import Base, local_session
class CommunitySubscription(Base):
__tablename__ = 'community_subscription'
class CommunityFollower(Base):
__tablename__ = 'community_followers'
id = None
subscriber = Column(ForeignKey('user.slug'), primary_key = True)
follower = Column(ForeignKey('user.slug'), primary_key = True)
community = Column(ForeignKey('community.slug'), primary_key = True)
createdAt: str = Column(DateTime, nullable=False, default = datetime.now, comment="Created at")
@@ -21,7 +19,7 @@ class Community(Base):
desc: str = Column(String, nullable=False, default='')
pic: str = Column(String, nullable=False, default='')
createdAt: str = Column(DateTime, nullable=False, default = datetime.now, comment="Created at")
createdBy: str = Column(ForeignKey("user.slug"), nullable=False, comment="Creator")
createdBy: str = Column(ForeignKey("user.slug"), nullable=False, comment="Author")
@staticmethod
def init_table():

View File

@@ -1,4 +1,4 @@
from sqlalchemy import Column, Integer, String, ForeignKey, JSON as JSONType
from sqlalchemy import Column, String, JSON as JSONType
from orm.base import Base
class Notification(Base):
@@ -6,4 +6,6 @@ class Notification(Base):
kind: str = Column(String, unique = True, primary_key = True)
template: str = Column(String, nullable = False)
variables: JSONType = Column(JSONType, nullable = True) # [ <var1>, .. ]
variables: JSONType = Column(JSONType, nullable = True) # [ <var1>, .. ]
# FIXME looks like frontend code

View File

@@ -1,33 +0,0 @@
from typing import List
from datetime import datetime
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime
from sqlalchemy.orm import relationship
from orm import Permission
from orm.base import Base
class ProposalRating(Base):
__tablename__ = "proposal_rating"
id = None
proposal_id = Column(ForeignKey('proposal.id'), primary_key = True)
createdBy = Column(ForeignKey('user.slug'), primary_key = True)
createdAt: str = Column(DateTime, nullable=False, default = datetime.now, comment="Timestamp")
value = Column(Integer)
class Proposal(Base):
__tablename__ = 'proposal'
shout: str = Column(String, ForeignKey("shout.slug"), nullable=False, comment="Shout")
range: str = Column(String, nullable=True, comment="Range in format <start index>:<end>")
body: str = Column(String, nullable=False, comment="Body")
createdBy: int = Column(Integer, ForeignKey("user.id"), nullable=False, comment="Author")
createdAt: str = Column(DateTime, nullable=False, comment="Created at")
updatedAt: str = Column(DateTime, nullable=True, comment="Updated at")
acceptedAt: str = Column(DateTime, nullable=True, comment="Accepted at")
acceptedBy: str = Column(Integer, ForeignKey("user.id"), nullable=True, comment="Accepted by")
declinedAt: str = Column(DateTime, nullable=True, comment="Declined at")
declinedBy: str = Column(Integer, ForeignKey("user.id"), nullable=True, comment="Declined by")
ratings = relationship(ProposalRating, foreign_keys=ProposalRating.proposal_id)
deletedAt: str = Column(DateTime, nullable=True, comment="Deleted at")
# TODO: debug, logix

View File

@@ -1,11 +1,6 @@
import warnings
from typing import Type
import asyncio
from sqlalchemy import String, Integer, Column, ForeignKey, UniqueConstraint, TypeDecorator
from sqlalchemy.orm import relationship, selectinload
from sqlalchemy import String, Column, ForeignKey, UniqueConstraint, TypeDecorator
from sqlalchemy.orm import relationship
from orm.base import Base, REGISTRY, engine, local_session
from orm.community import Community
@@ -88,34 +83,6 @@ class Permission(Base):
operation_id: int = Column(ForeignKey("operation.id", ondelete="CASCADE"), nullable=False, comment="Operation")
resource_id: int = Column(ForeignKey("resource.id", ondelete="CASCADE"), nullable=False, comment="Resource")
class RoleStorage:
roles = {}
lock = asyncio.Lock()
@staticmethod
def init(session):
self = RoleStorage
roles = session.query(Role).\
options(selectinload(Role.permissions)).all()
self.roles = dict([(role.id, role) for role in roles])
@staticmethod
async def get_role(id):
self = RoleStorage
async with self.lock:
return self.roles.get(id)
@staticmethod
async def add_role(role):
self = RoleStorage
async with self.lock:
self.roles[id] = role
@staticmethod
async def del_role(id):
self = RoleStorage
async with self.lock:
del self.roles[id]
if __name__ == '__main__':
Base.metadata.create_all(engine)

51
orm/reaction.py Normal file
View File

@@ -0,0 +1,51 @@
from datetime import datetime
from sqlalchemy import Column, String, ForeignKey, DateTime
from orm.base import Base, local_session
import enum
from sqlalchemy import Enum
from storages.viewed import ViewedStorage
class ReactionKind(enum.Enum):
AGREE = 1 # +1
DISAGREE = 2 # -1
PROOF = 3 # +1
DISPROOF = 4 # -1
ASK = 5 # +0
PROPOSE = 6 # +0
QOUTE = 7 # +0
COMMENT = 8 # +0
ACCEPT = 9 # +1
REJECT = 0 # -1
LIKE = 11 # +1
DISLIKE = 12 # -1
# TYPE = <reaction index> # rating change guess
class Reaction(Base):
__tablename__ = 'reaction'
body: str = Column(String, nullable=True, comment="Reaction Body")
createdAt = Column(DateTime, nullable=False, default = datetime.now, comment="Created at")
createdBy: str = Column(ForeignKey("user.slug"), nullable=False, comment="Sender")
updatedAt = Column(DateTime, nullable=True, comment="Updated at")
updatedBy = Column(ForeignKey("user.slug"), nullable=True, comment="Last Editor")
deletedAt = Column(DateTime, nullable=True, comment="Deleted at")
deletedBy = Column(ForeignKey("user.slug"), nullable=True, comment="Deleted by")
shout = Column(ForeignKey("shout.slug"), nullable=False)
replyTo: int = Column(ForeignKey("reaction.id"), nullable=True, comment="Reply to reaction ID")
range: str = Column(String, nullable=True, comment="Range in format <start index>:<end>")
kind: int = Column(Enum(ReactionKind), nullable=False, comment="Reaction kind")
oid: str = Column(String, nullable=True, comment="Old ID")
@property
async def stat(self) -> dict:
reacted = 0
try:
with local_session() as session:
reacted = session.query(Reaction).filter(Reaction.replyTo == self.id).count()
except Exception as e:
print(e)
return {
"viewed": await ViewedStorage.get_reaction(self.slug),
"reacted": reacted
}

View File

@@ -1,24 +1,22 @@
from typing import List
from datetime import datetime, timedelta
from sqlalchemy import Table, Column, Integer, String, ForeignKey, DateTime, Boolean, func
from datetime import datetime
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Boolean
from sqlalchemy.orm import relationship
from sqlalchemy.orm.attributes import flag_modified
from orm import Permission, User, Topic, TopicSubscription
from orm.comment import Comment
from orm.base import Base, local_session
from orm.user import User
from orm.topic import Topic, ShoutTopic
from orm.reaction import Reaction
from storages.reactions import ReactionsStorage
from storages.viewed import ViewedStorage
from orm.base import Base
from functools import reduce
import asyncio
class ShoutCommentsSubscription(Base):
__tablename__ = "shout_comments_subscription"
class ShoutReactionsFollower(Base):
__tablename__ = "shout_reactions_followers"
id = None
subscriber = Column(ForeignKey('user.slug'), primary_key = True)
follower = Column(ForeignKey('user.slug'), primary_key = True)
shout = Column(ForeignKey('shout.slug'), primary_key = True)
createdAt: str = Column(DateTime, nullable=False, default = datetime.now, comment="Created at")
auto = Column(Boolean, nullable=False, default = False)
createdAt: str = Column(DateTime, nullable=False, default = datetime.now, comment="Created at")
deletedAt: str = Column(DateTime, nullable=True)
class ShoutAuthor(Base):
@@ -28,300 +26,13 @@ class ShoutAuthor(Base):
shout = Column(ForeignKey('shout.slug'), primary_key = True)
user = Column(ForeignKey('user.slug'), primary_key = True)
class ShoutViewer(Base):
__tablename__ = "shout_viewer"
class ShoutAllowed(Base):
__tablename__ = "shout_allowed"
id = None
shout = Column(ForeignKey('shout.slug'), primary_key = True)
user = Column(ForeignKey('user.id'), primary_key = True)
class ShoutTopic(Base):
__tablename__ = 'shout_topic'
id = None
shout = Column(ForeignKey('shout.slug'), primary_key = True)
topic = Column(ForeignKey('topic.slug'), primary_key = True)
class ShoutRating(Base):
__tablename__ = "shout_rating"
id = None
rater = Column(ForeignKey('user.slug'), primary_key = True)
shout = Column(ForeignKey('shout.slug'), primary_key = True)
ts = Column(DateTime, nullable=False, default = datetime.now, comment="Timestamp")
value = Column(Integer)
class ShoutRatingStorage:
ratings = []
lock = asyncio.Lock()
@staticmethod
def init(session):
ShoutRatingStorage.ratings = session.query(ShoutRating).all()
@staticmethod
async def get_total_rating(shout_slug):
async with ShoutRatingStorage.lock:
shout_ratings = list(filter(lambda x: x.shout == shout_slug, ShoutRatingStorage.ratings))
return reduce((lambda x, y: x + y.value), shout_ratings, 0)
@staticmethod
async def get_ratings(shout_slug):
async with ShoutRatingStorage.lock:
shout_ratings = list(filter(lambda x: x.shout == shout_slug, ShoutRatingStorage.ratings))
return shout_ratings
@staticmethod
async def update_rating(new_rating):
async with ShoutRatingStorage.lock:
rating = next((x for x in ShoutRatingStorage.ratings \
if x.rater == new_rating.rater and x.shout == new_rating.shout), None)
if rating:
rating.value = new_rating.value
rating.ts = new_rating.ts
else:
ShoutRatingStorage.ratings.append(new_rating)
class ShoutViewByDay(Base):
__tablename__ = "shout_view_by_day"
id = None
shout = Column(ForeignKey('shout.slug'), primary_key = True)
day = Column(DateTime, primary_key = True, default = datetime.now)
value = Column(Integer)
class ShoutViewStorage:
view_by_shout = {}
this_day_views = {}
to_flush = []
period = 30*60 #sec
lock = asyncio.Lock()
@staticmethod
def init(session):
self = ShoutViewStorage
views = session.query(ShoutViewByDay).all()
for view in views:
shout = view.shout
value = view.value
old_value = self.view_by_shout.get(shout, 0)
self.view_by_shout[shout] = old_value + value;
if not shout in self.this_day_views:
self.this_day_views[shout] = view
this_day_view = self.this_day_views[shout]
if this_day_view.day < view.day:
self.this_day_views[shout] = view
@staticmethod
async def get_view(shout_slug):
self = ShoutViewStorage
async with self.lock:
return self.view_by_shout.get(shout_slug, 0)
@staticmethod
async def inc_view(shout_slug):
self = ShoutViewStorage
async with self.lock:
this_day_view = self.this_day_views.get(shout_slug)
day_start = datetime.now().replace(hour = 0, minute = 0, second = 0)
if not this_day_view or this_day_view.day < day_start:
if this_day_view and getattr(this_day_view, "modified", False):
self.to_flush.append(this_day_view)
this_day_view = ShoutViewByDay.create(shout = shout_slug, value = 1)
self.this_day_views[shout_slug] = this_day_view
else:
this_day_view.value = this_day_view.value + 1
this_day_view.modified = True
old_value = self.view_by_shout.get(shout_slug, 0)
self.view_by_shout[shout_slug] = old_value + 1;
@staticmethod
async def flush_changes(session):
self = ShoutViewStorage
async with self.lock:
for view in self.this_day_views.values():
if getattr(view, "modified", False):
session.add(view)
flag_modified(view, "value")
view.modified = False
for view in self.to_flush:
session.add(view)
self.to_flush.clear()
session.commit()
@staticmethod
async def worker():
print("[shout.views] worker start")
while True:
try:
print("[shout.views] worker flush changes")
with local_session() as session:
await ShoutViewStorage.flush_changes(session)
except Exception as err:
print("[shout.views] worker error: %s" % (err))
await asyncio.sleep(ShoutViewStorage.period)
class TopicStat:
shouts_by_topic = {}
authors_by_topic = {}
subs_by_topic = {}
views_by_topic = {}
lock = asyncio.Lock()
period = 30*60 #sec
@staticmethod
async def load_stat(session):
self = TopicStat
self.shouts_by_topic = {}
self.authors_by_topic = {}
self.subs_by_topic = {}
self.views_by_topic = {}
shout_topics = session.query(ShoutTopic)
for shout_topic in shout_topics:
topic = shout_topic.topic
shout = shout_topic.shout
if topic in self.shouts_by_topic:
self.shouts_by_topic[topic].append(shout)
else:
self.shouts_by_topic[topic] = [shout]
authors = await ShoutAuthorStorage.get_authors(shout)
if topic in self.authors_by_topic:
self.authors_by_topic[topic].update(authors)
else:
self.authors_by_topic[topic] = set(authors)
old_views = self.views_by_topic.get(topic, 0)
self.views_by_topic[topic] = old_views + await ShoutViewStorage.get_view(shout)
subs = session.query(TopicSubscription)
for sub in subs:
topic = sub.topic
user = sub.subscriber
if topic in self.subs_by_topic:
self.subs_by_topic[topic].append(user)
else:
self.subs_by_topic[topic] = [user]
@staticmethod
async def get_shouts(topic):
self = TopicStat
async with self.lock:
return self.shouts_by_topic.get(topic, [])
@staticmethod
async def get_stat(topic):
self = TopicStat
async with self.lock:
shouts = self.shouts_by_topic.get(topic, [])
subs = self.subs_by_topic.get(topic, [])
authors = self.authors_by_topic.get(topic, [])
views = self.views_by_topic.get(topic, 0)
return {
"shouts" : len(shouts),
"authors" : len(authors),
"subscriptions" : len(subs),
"views" : views
}
@staticmethod
async def worker():
self = TopicStat
print("[topic.stats] worker start")
while True:
try:
print("[topic.stats] worker load stat")
with local_session() as session:
async with self.lock:
await self.load_stat(session)
except Exception as err:
print("[topic.stats] worker error: %s" % (err))
await asyncio.sleep(self.period)
class ShoutAuthorStorage:
authors_by_shout = {}
lock = asyncio.Lock()
period = 30*60 #sec
@staticmethod
async def load(session):
self = ShoutAuthorStorage
authors = session.query(ShoutAuthor)
for author in authors:
user = author.user
shout = author.shout
if shout in self.authors_by_shout:
self.authors_by_shout[shout].append(user)
else:
self.authors_by_shout[shout] = [user]
@staticmethod
async def get_authors(shout):
self = ShoutAuthorStorage
async with self.lock:
return self.authors_by_shout.get(shout, [])
@staticmethod
async def worker():
self = ShoutAuthorStorage
print("[shout.authors] worker start")
while True:
try:
print("[shout.authors] worker load stat")
with local_session() as session:
async with self.lock:
await self.load(session)
except Exception as err:
print("[shout.authors] worker error: %s" % (err))
await asyncio.sleep(self.period)
class CommentStat:
stat_by_topic = {}
lock = asyncio.Lock()
period = 30*60 #sec
@staticmethod
async def load(session):
self = CommentStat
stats = session.query(Comment.shout, func.count(Comment.id).label("count")).\
group_by(Comment.shout)
self.stat_by_topic = dict([(stat.shout, stat.count) for stat in stats])
@staticmethod
async def get_stat(shout):
self = CommentStat
async with self.lock:
return self.stat_by_topic.get(shout, 0)
@staticmethod
async def worker():
self = CommentStat
print("[comment.stats] worker start")
while True:
try:
print("[comment.stats] worker load stat")
with local_session() as session:
async with self.lock:
await self.load(session)
except Exception as err:
print("[comment.stats] worker error: %s" % (err))
await asyncio.sleep(self.period)
class Shout(Base):
__tablename__ = 'shout'
@@ -340,19 +51,18 @@ class Shout(Base):
cover: str = Column(String, nullable = True)
title: str = Column(String, nullable = True)
subtitle: str = Column(String, nullable = True)
comments = relationship(Comment)
layout: str = Column(String, nullable = True)
authors = relationship(lambda: User, secondary=ShoutAuthor.__tablename__) # NOTE: multiple authors
reactions = relationship(lambda: Reaction)
authors = relationship(lambda: User, secondary=ShoutAuthor.__tablename__)
topics = relationship(lambda: Topic, secondary=ShoutTopic.__tablename__)
mainTopic = Column(ForeignKey("topic.slug"), nullable=True)
visibleFor = relationship(lambda: User, secondary=ShoutViewer.__tablename__)
visibleFor = relationship(lambda: User, secondary=ShoutAllowed.__tablename__)
draft: bool = Column(Boolean, default=True)
oid: str = Column(String, nullable=True)
@property
async def stat(self):
async def stat(self) -> dict:
return {
"views": await ShoutViewStorage.get_view(self.slug),
"comments": await CommentStat.get_stat(self.slug),
"ratings": await ShoutRatingStorage.get_total_rating(self.slug)
"viewed": await ViewedStorage.get_shout(self.slug),
"reacted": await ReactionsStorage.by_shout(self.slug)
}

View File

@@ -1,15 +1,18 @@
from datetime import datetime
from sqlalchemy import Table, Column, Integer, String, ForeignKey, DateTime, JSON as JSONType
from sqlalchemy.orm import relationship
from sqlalchemy import Column, String, ForeignKey, DateTime, JSON as JSONType
from orm.base import Base
import asyncio
class TopicSubscription(Base):
__tablename__ = "topic_subscription"
class ShoutTopic(Base):
__tablename__ = 'shout_topic'
id = None
subscriber = Column(ForeignKey('user.slug'), primary_key = True)
shout = Column(ForeignKey('shout.slug'), primary_key = True)
topic = Column(ForeignKey('topic.slug'), primary_key = True)
class TopicFollower(Base):
__tablename__ = "topic_followers"
id = None
follower = Column(ForeignKey('user.slug'), primary_key = True)
topic = Column(ForeignKey('topic.slug'), primary_key = True)
createdAt: str = Column(DateTime, nullable=False, default = datetime.now, comment="Created at")
@@ -26,47 +29,3 @@ class Topic(Base):
community = Column(ForeignKey("community.slug"), nullable=False, comment="Community")
oid: str = Column(String, nullable=True, comment="Old ID")
class TopicStorage:
topics = {}
lock = asyncio.Lock()
@staticmethod
def init(session):
self = TopicStorage
topics = session.query(Topic)
self.topics = dict([(topic.slug, topic) for topic in topics])
for topic in self.topics.values():
self.load_parents(topic)
@staticmethod
def load_parents(topic):
self = TopicStorage
parents = []
for parent in self.topics.values():
if topic.slug in parent.children:
parents.append(parent.slug)
topic.parents = parents
return topic
@staticmethod
async def get_topics(slugs):
self = TopicStorage
async with self.lock:
if not slugs:
return self.topics.values()
topics = filter(lambda topic: topic.slug in slugs, self.topics.values())
return list(topics)
@staticmethod
async def get_topics_by_community(community):
self = TopicStorage
async with self.lock:
topics = filter(lambda topic: topic.community == community, self.topics.values())
return list(topics)
@staticmethod
async def add_topic(topic):
self = TopicStorage
async with self.lock:
self.topics[topic.slug] = topic
self.load_parents(topic)

View File

@@ -1,14 +1,9 @@
from typing import List
from datetime import datetime
from sqlalchemy import Table, Column, Integer, String, ForeignKey, Boolean, DateTime, JSON as JSONType
from sqlalchemy.orm import relationship, selectinload
from sqlalchemy import Column, Integer, String, ForeignKey, Boolean, DateTime, JSON as JSONType
from sqlalchemy.orm import relationship
from orm.base import Base, local_session
from orm.rbac import Role, RoleStorage
from orm.topic import Topic
import asyncio
from orm.rbac import Role
from storages.roles import RoleStorage
class UserNotifications(Base):
__tablename__ = 'user_notifications'
@@ -33,21 +28,14 @@ class UserRole(Base):
user_id = Column(ForeignKey('user.id'), primary_key = True)
role_id = Column(ForeignKey('role.id'), primary_key = True)
class AuthorSubscription(Base):
__tablename__ = "author_subscription"
class AuthorFollower(Base):
__tablename__ = "author_follower"
id = None
subscriber = Column(ForeignKey('user.slug'), primary_key = True)
follower = Column(ForeignKey('user.slug'), primary_key = True)
author = Column(ForeignKey('user.slug'), primary_key = True)
createdAt = Column(DateTime, nullable=False, default = datetime.now, comment="Created at")
class EmailSubscription(Base):
__tablename__ = "email_subscription"
id = None
email = Column(String, primary_key = True)
createdAt = Column(DateTime, nullable=False, default = datetime.now, comment="Created at")
class User(Base):
__tablename__ = "user"
@@ -95,43 +83,6 @@ class User(Base):
scope[p.resource_id].add(p.operation_id)
return scope
class UserStorage:
users = {}
lock = asyncio.Lock()
@staticmethod
def init(session):
self = UserStorage
users = session.query(User).\
options(selectinload(User.roles)).all()
self.users = dict([(user.id, user) for user in users])
@staticmethod
async def get_user(id):
self = UserStorage
async with self.lock:
return self.users.get(id)
@staticmethod
async def get_user_by_slug(slug):
self = UserStorage
async with self.lock:
for user in self.users.values():
if user.slug == slug:
return user
@staticmethod
async def add_user(user):
self = UserStorage
async with self.lock:
self.users[user.id] = user
@staticmethod
async def del_user(id):
self = UserStorage
async with self.lock:
del self.users[id]
if __name__ == "__main__":
print(User.get_permission(user_id=1))