diff --git a/migration/tables/comments.py b/migration/tables/comments.py index 4be7335f..b7c79bc0 100644 --- a/migration/tables/comments.py +++ b/migration/tables/comments.py @@ -4,10 +4,11 @@ from dateutil.parser import parse as date_parse from base.orm import local_session from migration.html2text import html2text -from orm import Reaction, User -from orm.reaction import ReactionKind +from orm.user import User +from orm.topic import TopicFollower +from orm.reaction import Reaction, ReactionKind from services.stat.reacted import ReactedStorage - +from orm.shout import ShoutReactionsFollower ts = datetime.now() @@ -74,8 +75,42 @@ async def migrate(entry, storage): # creating reaction from old comment reaction = Reaction.create(**reaction_dict) + session.add(reaction) await ReactedStorage.react(reaction) + # creating shout's reactions following for reaction author + following1 = session.query( + ShoutReactionsFollower + ).where( + ShoutReactionsFollower.follower == reaction_dict["createdBy"] + ).filter( + ShoutReactionsFollower.shout == reaction.shout + ).first() + if not following1: + following1 = ShoutReactionsFollower.create( + follower=reaction_dict["createdBy"], + shout=reaction.shout, + auto=True + ) + session.add(following1) + + # creating topics followings for reaction author + for t in shout_dict["topics"]: + tf = session.query( + TopicFollower + ).where( + TopicFollower.follower == reaction_dict["createdBy"] + ).filter( + TopicFollower.topic == t + ).first() + if not tf: + topic_following = TopicFollower.create( + follower=reaction_dict["createdBy"], + topic=t, + auto=True + ) + session.add(topic_following) + reaction_dict["id"] = reaction.id for comment_rating_old in entry.get("ratings", []): rater = ( @@ -83,18 +118,13 @@ async def migrate(entry, storage): .filter(User.oid == comment_rating_old["createdBy"]) .first() ) - reactedBy = ( - rater - if rater - else session.query(User).filter(User.slug == "noname").first() - ) re_reaction_dict = { "shout": reaction_dict["shout"], "replyTo": reaction.id, "kind": ReactionKind.LIKE if comment_rating_old["value"] > 0 else ReactionKind.DISLIKE, - "createdBy": reactedBy.slug if reactedBy else "discours", + "createdBy": rater.slug if rater else "discours", } cts = comment_rating_old.get("createdAt") if cts: @@ -102,11 +132,27 @@ async def migrate(entry, storage): try: # creating reaction from old rating rr = Reaction.create(**re_reaction_dict) + following2 = session.query( + ShoutReactionsFollower + ).where( + ShoutReactionsFollower.follower == re_reaction_dict['createdBy'] + ).filter( + ShoutReactionsFollower.shout == rr.shout + ).first() + if not following2: + following2 = ShoutReactionsFollower.create( + follower=re_reaction_dict['createdBy'], + shout=rr.shout, + auto=True + ) + session.add(following2) + session.add(rr) await ReactedStorage.react(rr) except Exception as e: print("[migration] comment rating error: %r" % re_reaction_dict) raise e + session.commit() else: print( "[migration] error: cannot find shout for comment %r" @@ -126,6 +172,15 @@ def migrate_2stage(rr, old_new_id): comment = session.query(Reaction).filter(Reaction.id == new_id).first() comment.replyTo = old_new_id.get(reply_oid) session.add(comment) + + srf = session.query(ShoutReactionsFollower).where( + ShoutReactionsFollower.shout == comment.shout + ).filter( + ShoutReactionsFollower.follower == comment.createdBy + ).first() + if not srf: + srf = ShoutReactionsFollower.create(shout=comment.shout, follower=comment.createdBy, auto=True) + session.add(srf) session.commit() if not rr["body"]: raise Exception(rr) diff --git a/migration/tables/content_items.py b/migration/tables/content_items.py index ff42eae3..8546568f 100644 --- a/migration/tables/content_items.py +++ b/migration/tables/content_items.py @@ -8,7 +8,7 @@ from base.orm import local_session from migration.extract import prepare_html_body from orm.community import Community from orm.reaction import Reaction, ReactionKind -from orm.shout import Shout, ShoutTopic, User +from orm.shout import Shout, ShoutTopic, User, ShoutReactionsFollower from orm.topic import TopicFollower from services.stat.reacted import ReactedStorage from services.stat.viewed import ViewedByDay @@ -115,12 +115,8 @@ async def migrate(entry, storage): category = entry["category"] mainTopic = topics_by_oid.get(category) if mainTopic: - r["mainTopic"] = storage["replacements"].get( - mainTopic["slug"], mainTopic["slug"] - ) - topic_oids = [ - category, - ] + r["mainTopic"] = storage["replacements"].get(mainTopic["slug"], mainTopic["slug"]) + topic_oids = [category, ] topic_oids.extend(entry.get("tags", [])) for oid in topic_oids: if oid in storage["topics"]["by_oid"]: @@ -137,7 +133,6 @@ async def migrate(entry, storage): r["body"] = prepare_html_body(entry) # save shout to db - s = object() shout_dict = r.copy() user = None @@ -167,18 +162,29 @@ async def migrate(entry, storage): storage["users"]["by_oid"][entry["_id"]] = userdata if not user: raise Exception("could not get a user") - shout_dict["authors"] = [ - user, - ] - - # TODO: subscribe shout user on shout topics + shout_dict["authors"] = [user, ] try: s = Shout.create(**shout_dict) with local_session() as session: topics = session.query(ShoutTopic).where(ShoutTopic.shout == s.slug).all() for tpc in topics: - TopicFollower.create(topic=tpc.slug, follower=userslug) + tf = session.query(TopicFollower).where(TopicFollower.follower == + userslug).filter(TopicFollower.topic == + tpc.slug).first() + if not tf: + tf = TopicFollower.create(topic=tpc.slug, follower=userslug, auto=True) + session.add(tf) await TopicStorage.update_topic(tpc.slug) + + srf = session.query(ShoutReactionsFollower).where( + ShoutReactionsFollower.shout == s.slug + ).filter( + ShoutReactionsFollower.follower == userslug + ).first() + if not srf: + srf = ShoutReactionsFollower.create(shout=s.slug, follower=userslug, auto=True) + session.add(srf) + session.commit() except IntegrityError as e: with local_session() as session: s = session.query(Shout).filter(Shout.slug == shout_dict["slug"]).first() diff --git a/migration/tables/users.py b/migration/tables/users.py index 8631454f..53f1da57 100644 --- a/migration/tables/users.py +++ b/migration/tables/users.py @@ -3,7 +3,7 @@ from sqlalchemy.exc import IntegrityError from base.orm import local_session from migration.html2text import html2text -from orm import User, UserRating +from orm.user import User, UserRating, AuthorFollower def migrate(entry): @@ -118,6 +118,13 @@ def migrate_2stage(entry, id_map): with local_session() as session: try: user_rating = UserRating.create(**user_rating_dict) + if user_rating_dict['value'] > 0: + af = AuthorFollower.create( + author=user_rating_dict['user'], + follower=user_rating_dict['rater'], + auto=True + ) + session.add(af) session.add(user_rating) session.commit() except IntegrityError: diff --git a/orm/community.py b/orm/community.py index 90ba6a8e..c3c80837 100644 --- a/orm/community.py +++ b/orm/community.py @@ -1,6 +1,6 @@ from datetime import datetime -from sqlalchemy import Column, String, ForeignKey, DateTime +from sqlalchemy import Column, String, ForeignKey, DateTime, Boolean from base.orm import Base, local_session @@ -14,6 +14,7 @@ class CommunityFollower(Base): createdAt = Column( DateTime, nullable=False, default=datetime.now, comment="Created at" ) + auto = Column(Boolean, nullable=False, default=False) class Community(Base): diff --git a/orm/shout.py b/orm/shout.py index f4620bf0..ef117074 100644 --- a/orm/shout.py +++ b/orm/shout.py @@ -46,29 +46,25 @@ class Shout(Base): id = None # type: ignore slug = Column(String, primary_key=True) - community = Column( - Integer, ForeignKey("community.id"), nullable=False, comment="Community" - ) + community = Column(Integer, ForeignKey("community.id"), nullable=False, comment="Community") body = Column(String, nullable=False, comment="Body") - createdAt = Column( - DateTime, nullable=False, default=datetime.now, comment="Created at" - ) - updatedAt = Column(DateTime, nullable=True, comment="Updated at") - replyTo = Column(ForeignKey("shout.slug"), nullable=True) - versionOf = Column(ForeignKey("shout.slug"), nullable=True) - tags = Column(String, nullable=True) - publishedBy = Column(ForeignKey("user.id"), nullable=True) - publishedAt = Column(DateTime, nullable=True) - cover = Column(String, nullable=True) title = Column(String, nullable=True) subtitle = Column(String, nullable=True) layout = Column(String, nullable=True) - reactions = relationship(lambda: Reaction) + mainTopic = Column(ForeignKey("topic.slug"), nullable=True) + cover = Column(String, nullable=True) authors = relationship(lambda: User, secondary=ShoutAuthor.__tablename__) topics = relationship(lambda: Topic, secondary=ShoutTopic.__tablename__) - mainTopic = Column(ForeignKey("topic.slug"), nullable=True) + reactions = relationship(lambda: Reaction) visibleFor = relationship(lambda: User, secondary=ShoutAllowed.__tablename__) - draft = Column(Boolean, default=True) + + createdAt = Column(DateTime, nullable=False, default=datetime.now, comment="Created at") + updatedAt = Column(DateTime, nullable=True, comment="Updated at") + publishedAt = Column(DateTime, nullable=True) + + versionOf = Column(ForeignKey("shout.slug"), nullable=True) + draft = Column(Boolean, default=False) + lang = Column(String, default='ru') oid = Column(String, nullable=True) @property diff --git a/orm/topic.py b/orm/topic.py index 69094606..060451d0 100644 --- a/orm/topic.py +++ b/orm/topic.py @@ -1,6 +1,6 @@ from datetime import datetime -from sqlalchemy import Column, String, ForeignKey, DateTime, JSON as JSONType +from sqlalchemy import Column, Boolean, String, ForeignKey, DateTime, JSON as JSONType from base.orm import Base @@ -22,6 +22,7 @@ class TopicFollower(Base): createdAt = Column( DateTime, nullable=False, default=datetime.now, comment="Created at" ) + auto = Column(Boolean, nullable=False, default=False) class Topic(Base): diff --git a/orm/user.py b/orm/user.py index 764cc539..d6dd4c81 100644 --- a/orm/user.py +++ b/orm/user.py @@ -50,6 +50,7 @@ class AuthorFollower(Base): createdAt = Column( DateTime, nullable=False, default=datetime.now, comment="Created at" ) + auto = Column(Boolean, nullable=False, default=False) class User(Base): diff --git a/resolvers/community.py b/resolvers/community.py index e1bc41bb..e4f40263 100644 --- a/resolvers/community.py +++ b/resolvers/community.py @@ -93,7 +93,10 @@ async def get_communities(_, info): def community_follow(user, slug): - CommunityFollower.create(follower=user.slug, community=slug) + with local_session() as session: + cf = CommunityFollower.create(follower=user.slug, community=slug) + session.add(cf) + session.commit() def community_unfollow(user, slug): diff --git a/resolvers/profile.py b/resolvers/profile.py index 7df3d910..6df879b9 100644 --- a/resolvers/profile.py +++ b/resolvers/profile.py @@ -165,7 +165,10 @@ async def rate_user(_, info, slug, value): # for mutation.field("follow") def author_follow(user, slug): - AuthorFollower.create(follower=user.slug, author=slug) + with local_session() as session: + af = AuthorFollower.create(follower=user.slug, author=slug) + session.add(af) + session.commit() # for mutation.field("unfollow") diff --git a/resolvers/reactions.py b/resolvers/reactions.py index e59437c9..5bcba0f7 100644 --- a/resolvers/reactions.py +++ b/resolvers/reactions.py @@ -14,25 +14,22 @@ from services.stat.reacted import ReactedStorage def reactions_follow(user, slug, auto=False): with local_session() as session: - fw = ( + following = ( session.query(ShoutReactionsFollower) .filter( ShoutReactionsFollower.follower == user.slug, - ShoutReactionsFollower.shout == slug, + ShoutReactionsFollower.shout == slug ) .first() ) - if auto and fw: - return - elif not auto and fw: - if bool(fw.deletedAt): - fw.deletedAt = None - fw.auto = False - session.commit() - return - # print("[resolvers.reactions] was followed before") - - ShoutReactionsFollower.create(follower=user.slug, shout=slug, auto=auto) + if not following: + following = ShoutReactionsFollower.create( + follower=user.slug, + shout=slug, + auto=auto + ) + session.add(following) + session.commit() def reactions_unfollow(user, slug): @@ -45,14 +42,9 @@ def reactions_unfollow(user, slug): ) .first() ) - if not following: - # print("[resolvers.reactions] was not followed", slug) - return - if following.auto: - following.deletedAt = datetime.now() - else: + if following: session.delete(following) - session.commit() + session.commit() @mutation.field("createReaction") diff --git a/resolvers/topics.py b/resolvers/topics.py index b25a69a8..de7693db 100644 --- a/resolvers/topics.py +++ b/resolvers/topics.py @@ -50,20 +50,23 @@ async def create_topic(_, _info, inp): @login_required async def update_topic(_, _info, inp): slug = inp["slug"] - session = local_session() - topic = session.query(Topic).filter(Topic.slug == slug).first() - if not topic: - return {"error": "topic not found"} - topic.update(**inp) - session.commit() - session.close() - await TopicStorage.update_topic(topic.slug) - return {"topic": topic} + with local_session() as session: + topic = session.query(Topic).filter(Topic.slug == slug).first() + if not topic: + return {"error": "topic not found"} + else: + topic.update(**inp) + session.commit() + await TopicStorage.update_topic(topic.slug) + return {"topic": topic} async def topic_follow(user, slug): - TopicFollower.create(topic=slug, follower=user.slug) - await TopicStorage.update_topic(slug) + with local_session() as session: + following = TopicFollower.create(topic=slug, follower=user.slug) + session.add(following) + session.commit() + await TopicStorage.update_topic(slug) async def topic_unfollow(user, slug): diff --git a/resolvers/zine.py b/resolvers/zine.py index ac5a1616..61d5ec83 100644 --- a/resolvers/zine.py +++ b/resolvers/zine.py @@ -112,7 +112,7 @@ async def get_search_results(_, _info, query, offset, limit): for s in shouts: for a in s.authors: a.caption = await ShoutAuthorStorage.get_author_caption(s.slug, a.slug) - s.stat.relevance = 1 # FIXME + s.stat.relevance = 1 # FIXME: expecting search engine rated relevance return shouts