From 89cf27562fa5afdc7bd7a0d5636fcfcf02d9c0d9 Mon Sep 17 00:00:00 2001 From: Deimos Date: Thu, 13 Sep 2018 22:44:31 -0600 Subject: [PATCH] Add weights to comment tags This gives each comment tag a "weight" value, which is a float. This weight can be set for each user to affect their future comment tags, and if a user doesn't have a weight set it uses a global default value that's set in the INI file. This global default is set to 1.0 for development purposes, since that should make it so that a single tag will have an effect. It should probably be set lower initially in production so that single users can't cause tag effects. --- ...825165870d9_add_weights_to_comment_tags.py | 29 +++++++++++++++++++ tildes/development.ini | 2 ++ tildes/production.ini.example | 1 + tildes/tildes/models/comment/comment.py | 9 ++++++ tildes/tildes/models/comment/comment_tag.py | 8 +++-- tildes/tildes/models/user/user.py | 2 ++ .../tildes/templates/macros/comments.jinja2 | 6 ++-- tildes/tildes/views/api/web/comment.py | 6 +++- 8 files changed, 57 insertions(+), 6 deletions(-) create mode 100644 tildes/alembic/versions/b825165870d9_add_weights_to_comment_tags.py diff --git a/tildes/alembic/versions/b825165870d9_add_weights_to_comment_tags.py b/tildes/alembic/versions/b825165870d9_add_weights_to_comment_tags.py new file mode 100644 index 0000000..90c64c3 --- /dev/null +++ b/tildes/alembic/versions/b825165870d9_add_weights_to_comment_tags.py @@ -0,0 +1,29 @@ +"""Add weights to comment tags + +Revision ID: b825165870d9 +Revises: 6ede05a0ea23 +Create Date: 2018-09-14 03:06:51.144073 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = "b825165870d9" +down_revision = "6ede05a0ea23" +branch_labels = None +depends_on = None + + +def upgrade(): + op.add_column( + "comment_tags", + sa.Column("weight", sa.REAL(), server_default=sa.text("1.0"), nullable=False), + ) + op.add_column("users", sa.Column("comment_tag_weight", sa.REAL(), nullable=True)) + + +def downgrade(): + op.drop_column("users", "comment_tag_weight") + op.drop_column("comment_tags", "weight") diff --git a/tildes/development.ini b/tildes/development.ini index 68d64fe..20bbe49 100644 --- a/tildes/development.ini +++ b/tildes/development.ini @@ -36,6 +36,8 @@ redis.sessions.timeout = 600 sqlalchemy.url = postgresql+psycopg2://tildes:@:6432/tildes +tildes.default_user_comment_tag_weight = 1.0 + webassets.auto_build = false webassets.base_dir = %(here)s/static webassets.base_url = / diff --git a/tildes/production.ini.example b/tildes/production.ini.example index 9212449..f6280c3 100644 --- a/tildes/production.ini.example +++ b/tildes/production.ini.example @@ -20,6 +20,7 @@ redis.sessions.timeout = 3600 sqlalchemy.url = postgresql+psycopg2://tildes:@:6432/tildes +tildes.default_user_comment_tag_weight = 1.0 tildes.welcome_message_sender = Deimos webassets.auto_build = false diff --git a/tildes/tildes/models/comment/comment.py b/tildes/tildes/models/comment/comment.py index 8da0d4b..1283cc7 100644 --- a/tildes/tildes/models/comment/comment.py +++ b/tildes/tildes/models/comment/comment.py @@ -238,6 +238,15 @@ class Comment(DatabaseModel): """Counter for number of times each tag is on this comment.""" return Counter([tag.name for tag in self.tags]) + @property + def tag_weights(self) -> Counter: + """Counter with cumulative weights of each tag on this comment.""" + weights: Counter = Counter() + for tag in self.tags: + weights[tag.name] += tag.weight + + return weights + def tags_by_user(self, user: User) -> Sequence[str]: """Return list of tag names that a user has applied to this comment.""" return [tag.name for tag in self.tags if tag.user_id == user.user_id] diff --git a/tildes/tildes/models/comment/comment_tag.py b/tildes/tildes/models/comment/comment_tag.py index a1c5c3e..9783fe4 100644 --- a/tildes/tildes/models/comment/comment_tag.py +++ b/tildes/tildes/models/comment/comment_tag.py @@ -5,7 +5,7 @@ from datetime import datetime -from sqlalchemy import Column, ForeignKey, Integer, TIMESTAMP +from sqlalchemy import Column, ForeignKey, Integer, REAL, TIMESTAMP from sqlalchemy.dialects.postgresql import ENUM from sqlalchemy.orm import backref, relationship from sqlalchemy.sql.expression import text @@ -33,15 +33,19 @@ class CommentTag(DatabaseModel): created_time: datetime = Column( TIMESTAMP(timezone=True), nullable=False, server_default=text("NOW()") ) + weight: float = Column(REAL, nullable=False, server_default=text("1.0")) comment: Comment = relationship(Comment, backref=backref("tags", lazy=False)) user: User = relationship(User, lazy=False, innerjoin=True) - def __init__(self, comment: Comment, user: User, tag: CommentTagOption) -> None: + def __init__( + self, comment: Comment, user: User, tag: CommentTagOption, weight: float + ) -> None: """Add a new tag to a comment.""" self.comment_id = comment.comment_id self.user_id = user.user_id self.tag = tag + self.weight = weight @property def name(self) -> str: diff --git a/tildes/tildes/models/user/user.py b/tildes/tildes/models/user/user.py index 929835e..007dca8 100644 --- a/tildes/tildes/models/user/user.py +++ b/tildes/tildes/models/user/user.py @@ -22,6 +22,7 @@ from sqlalchemy import ( Column, ForeignKey, Integer, + REAL, Text, TIMESTAMP, ) @@ -100,6 +101,7 @@ class User(DatabaseModel): _filtered_topic_tags: List[Ltree] = Column( "filtered_topic_tags", ArrayOfLtree, nullable=False, server_default="{}" ) + comment_tag_weight: Optional[float] = Column(REAL) @hybrid_property def filtered_topic_tags(self) -> List[str]: diff --git a/tildes/tildes/templates/macros/comments.jinja2 b/tildes/tildes/templates/macros/comments.jinja2 index 6798e52..afa24b1 100644 --- a/tildes/tildes/templates/macros/comments.jinja2 +++ b/tildes/tildes/templates/macros/comments.jinja2 @@ -98,13 +98,13 @@ {% if comment.tag_counts and request.has_permission("view_tags", comment) %}