Skip to content

Commit

Permalink
Merge comment notification types
Browse files Browse the repository at this point in the history
  • Loading branch information
jace committed Sep 17, 2020
1 parent 2580582 commit 5a2c5f6
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 55 deletions.
17 changes: 16 additions & 1 deletion funnel/models/commentvote.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class COMMENT_STATE(LabeledEnum): # NOQA: N801


# What is this Voteset or Commentset attached to?
# TODO: Deprecated, doesn't help as much as we thought it would
class SET_TYPE: # NOQA: N801
PROJECT = 0
PROPOSAL = 2
Expand Down Expand Up @@ -112,7 +113,12 @@ class Commentset(UuidMixin, BaseMixin, db.Model):
settype = db.Column('type', db.Integer, nullable=True)
count = db.Column(db.Integer, default=0, nullable=False)

__roles__ = {'all': {'read': {'settype', 'count'}}}
__roles__ = {
'all': {
'read': {'settype', 'count', 'project', 'proposal'},
'call': {'url_for'},
}
}

__datasets__ = {
'primary': {'settype', 'count'},
Expand All @@ -123,6 +129,7 @@ def __init__(self, **kwargs):
super(Commentset, self).__init__(**kwargs)
self.count = 0

@with_roles(read={'all'})
@property
def parent(self):
# FIXME: Move this to a CommentMixin that uses a registry, like EmailAddress
Expand All @@ -133,6 +140,14 @@ def parent(self):
parent = self.proposal
return parent

@with_roles(read={'all'})
@property
def parent_type(self):
parent = self.parent
if parent:
return parent.__tablename__
return None

def permissions(self, user, inherited=None):
perms = super().permissions(user, inherited)
if user is not None:
Expand Down
33 changes: 7 additions & 26 deletions funnel/models/notification_types.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from baseframe import __
from funnel.models.moderation import CommentModeratorReport

from .commentvote import Comment
from .commentvote import Comment, Commentset
from .notification import Notification, notification_categories
from .organization_membership import OrganizationMembership
from .project import Project
Expand All @@ -17,8 +17,7 @@
'NewUpdateNotification',
'CommentReportReceivedNotification',
'CommentReplyNotification',
'ProjectCommentNotification',
'ProposalCommentNotification',
'NewCommentNotification',
'ProposalReceivedNotification',
'ProposalSubmittedNotification',
'RegistrationCancellationNotification',
Expand Down Expand Up @@ -161,35 +160,17 @@ class CommentReplyNotification(Notification):
roles = ['replied_to_commenter']


class ProjectCommentNotification(DocumentHasProfile, Notification):
"""Notification of comments on a project."""
class NewCommentNotification(Notification):
"""Notification of new comment."""

__mapper_args__ = {'polymorphic_identity': 'comment_project'}
__mapper_args__ = {'polymorphic_identity': 'comment_new'}

category = notification_categories.project_crew
title = __("When my project receives a comment")
title = __("When my project or proposal receives a comment")
exclude_actor = True

document_model = Project
fragment_model = Comment
# Note: These roles must be available on Comment, not Proposal. Roles come from
# fragment if present, document if not.
roles = ['replied_to_commenter', 'document_subscriber']


class ProposalCommentNotification(DocumentHasProject, Notification):
"""Notification of comments on a proposal."""

__mapper_args__ = {'polymorphic_identity': 'comment_proposal'}

category = notification_categories.participant
title = __("When my proposal receives a comment")
exclude_actor = True

document_model = Proposal
document_model = Commentset
fragment_model = Comment
# Note: These roles must be available on Comment, not Proposal. Roles come from
# fragment if present, document if not.
roles = ['replied_to_commenter', 'document_subscriber']


Expand Down
19 changes: 5 additions & 14 deletions funnel/views/commentvote.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@
CommentReplyNotification,
CommentReportReceivedNotification,
Commentset,
Project,
ProjectCommentNotification,
NewCommentNotification,
Proposal,
ProposalCommentNotification,
Voteset,
db,
)
Expand All @@ -37,15 +35,6 @@
ProposalComment = namedtuple('ProposalComment', ['proposal', 'comment'])


def comment_notification_type(comment):
# FIXME: Move this into a CommentMixin model
parent = comment.commentset.parent
if isinstance(parent, Project):
return ProjectCommentNotification(document=parent, fragment=comment)
if isinstance(parent, Proposal):
return ProposalCommentNotification(document=parent, fragment=comment)


@Comment.views('url')
def comment_url(obj):
url = None
Expand Down Expand Up @@ -166,7 +155,9 @@ def new_comment(self):
comment.voteset.vote(current_auth.user) # Vote for your own comment
db.session.add(comment)
db.session.commit()
dispatch_notification(comment_notification_type(comment))
dispatch_notification(
NewCommentNotification(document=comment.commentset, fragment=comment)
)
return {
'status': 'ok',
'message': _("Your comment has been posted"),
Expand Down Expand Up @@ -235,7 +226,7 @@ def reply(self):
CommentReplyNotification(
document=comment.in_reply_to, fragment=comment
),
comment_notification_type(comment),
NewCommentNotification(document=comment.commentset, fragment=comment),
)
return {
'status': 'ok',
Expand Down
32 changes: 18 additions & 14 deletions funnel/views/notifications/commentvote_notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
from ...models import (
CommentReplyNotification,
CommentReportReceivedNotification,
ProjectCommentNotification,
ProposalCommentNotification,
NewCommentNotification,
)
from ..helpers import shortlink
from ..notification import RenderNotification
Expand Down Expand Up @@ -48,8 +47,7 @@ def sms(self):


@CommentReplyNotification.renderer
@ProjectCommentNotification.renderer
@ProposalCommentNotification.renderer
@NewCommentNotification.renderer
class CommentNotification(RenderNotification):
"""Render comment notifications for various document types."""

Expand All @@ -74,34 +72,40 @@ def commenters(self):
user_ids.add(comment.user.uuid)
return users

@property
def document_type(self):
if self.notification.document_type == 'comment':
return 'comment'
return self.document.parent_type

def document_comments_url(self, **kwargs):
"""URL to comments view on the document."""
if self.notification.document_type == 'project':
return self.document.url_for('comments', **kwargs)
if self.notification.document_type == 'proposal':
return self.document.url_for('view', **kwargs) + '#comments'
if self.document_type == 'project':
return self.document.parent.url_for('comments', **kwargs)
if self.document_type == 'proposal':
return self.document.parent.url_for('view', **kwargs) + '#comments'
return self.document.url_for('view', **kwargs)

def activity_template_standalone(self, comment=None):
"""Activity template for standalone use, such as email subject."""
if comment is None:
comment = self.comment
if self.notification.document_type == 'comment':
if self.document_type == 'comment':
return _("{actor} replied to your comment")
if self.notification.document_type == 'project':
if self.document_type == 'project':
return _("{actor} commented on your project")
if self.notification.document_type == 'proposal':
if self.document_type == 'proposal':
return _("{actor} commented on your proposal")

def activity_template_inline(self, comment=None):
"""Activity template for inline use with other content, like SMS with URL."""
if comment is None:
comment = self.comment
if self.notification.document_type == 'comment':
if self.document_type == 'comment':
return _("{actor} replied to your comment:")
if self.notification.document_type == 'project':
if self.document_type == 'project':
return _("{actor} commented on your project:")
if self.notification.document_type == 'proposal':
if self.document_type == 'proposal':
return _("{actor} commented on your proposal:")

def activity_html(self, comment=None):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""Merge comment notification types
Revision ID: 1bd91b02ced3
Revises: 4845fd12dbfd
Create Date: 2020-09-18 02:44:20.827703
"""

from alembic import op
from sqlalchemy.dialects import postgresql
from sqlalchemy.sql import column, table
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '1bd91b02ced3'
down_revision = '4845fd12dbfd'
branch_labels = None
depends_on = None


notification = table(
'notification',
column('eventid', postgresql.UUID()),
column('id', postgresql.UUID()),
column('type', sa.Unicode()),
column('document_uuid', postgresql.UUID()),
column('fragment_uuid', postgresql.UUID()),
)

project = table(
'project',
column('id', sa.Integer()),
column('uuid', postgresql.UUID()),
column('commentset_id', sa.Integer()),
)

proposal = table(
'proposal',
column('id', sa.Integer()),
column('uuid', postgresql.UUID()),
column('commentset_id', sa.Integer()),
)

commentset = table(
'commentset',
column('id', sa.Integer()),
column('uuid', postgresql.UUID()),
)


def upgrade():
op.execute(
notification.update()
.values(type='comment_new', document_uuid=commentset.c.uuid)
.where(notification.c.type == 'comment_project')
.where(notification.c.document_uuid == project.c.uuid)
.where(project.c.commentset_id == commentset.c.id)
)

op.execute(
notification.update()
.values(type='comment_new', document_uuid=commentset.c.uuid)
.where(notification.c.type == 'comment_proposal')
.where(notification.c.document_uuid == proposal.c.uuid)
.where(proposal.c.commentset_id == commentset.c.id)
)


def downgrade():
op.execute(
notification.update()
.values(type='comment_proposal', document_uuid=proposal.c.uuid)
.where(notification.c.type == 'comment_new')
.where(notification.c.document_uuid == commentset.c.uuid)
.where(proposal.c.commentset_id == commentset.c.id)
)

op.execute(
notification.update()
.values(type='comment_project', document_uuid=project.c.uuid)
.where(notification.c.type == 'comment_new')
.where(notification.c.document_uuid == commentset.c.uuid)
.where(project.c.commentset_id == commentset.c.id)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Update comment notification preferences
Revision ID: 3847982f1472
Revises: 1bd91b02ced3
Create Date: 2020-09-18 03:27:44.871342
"""

from alembic import op
from sqlalchemy.sql import column, table

# revision identifiers, used by Alembic.
revision = '3847982f1472'
down_revision = '1bd91b02ced3'
branch_labels = None
depends_on = None

notification_preferences = table(
'notification_preferences',
column('notification_type'),
)


def upgrade():
op.execute(
notification_preferences.update()
.values(notification_type='comment_new')
.where(notification_preferences.c.notification_type == 'comment_project')
)

op.execute(
notification_preferences.delete().where(
notification_preferences.c.notification_type == 'comment_proposal'
)
)


def downgrade():
op.execute(
notification_preferences.update()
.values(notification_type='comment_project')
.where(notification_preferences.c.notification_type == 'comment_new')
)

0 comments on commit 5a2c5f6

Please sign in to comment.