Split events/notifications into two tables
This commit is contained in:
parent
937890bd65
commit
cde30a81b0
|
@ -19,7 +19,6 @@ from sqlalchemy.orm import sessionmaker, Session as BaseSession, relationship
|
|||
Session = sessionmaker()
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
class Tracker(Base):
|
||||
__tablename__ = 'tracker'
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
"""Split event table in two
|
||||
|
||||
Revision ID: 6169a5600336
|
||||
Revises: 132ee194cefe
|
||||
Create Date: 2017-11-09 18:45:13.828939
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '6169a5600336'
|
||||
down_revision = '132ee194cefe'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import sessionmaker, Session as BaseSession, relationship
|
||||
|
||||
Session = sessionmaker()
|
||||
Base = declarative_base()
|
||||
|
||||
class User(Base):
|
||||
__tablename__ = 'user'
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
|
||||
class Ticket(Base):
|
||||
__tablename__ = 'ticket'
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
submitter_id = sa.Column(sa.Integer, sa.ForeignKey("user.id"), nullable=False)
|
||||
|
||||
class TicketComment(Base):
|
||||
__tablename__ = 'ticket_comment'
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
submitter_id = sa.Column(sa.Integer, sa.ForeignKey("user.id"), nullable=False)
|
||||
|
||||
class Event(Base):
|
||||
__tablename__ = 'event'
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
created = sa.Column(sa.DateTime, nullable=False)
|
||||
user_id = sa.Column(sa.Integer, sa.ForeignKey("user.id"), nullable=False)
|
||||
ticket_id = sa.Column(sa.Integer, sa.ForeignKey("ticket.id"), nullable=False)
|
||||
ticket = sa.orm.relationship("Ticket")
|
||||
comment_id = sa.Column(sa.Integer, sa.ForeignKey("ticket_comment.id"))
|
||||
comment = sa.orm.relationship("TicketComment")
|
||||
|
||||
class EventNotification(Base):
|
||||
__tablename__ = 'event_notification'
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
created = sa.Column(sa.DateTime, nullable=False)
|
||||
event_id = sa.Column(sa.Integer, sa.ForeignKey("event.id"), nullable=False)
|
||||
user_id = sa.Column(sa.Integer, sa.ForeignKey("user.id"), nullable=False)
|
||||
|
||||
def upgrade():
|
||||
bind = op.get_bind()
|
||||
session = Session(bind=bind)
|
||||
op.create_table('event_notification',
|
||||
sa.Column('id', sa.Integer, primary_key=True),
|
||||
sa.Column('created', sa.DateTime, nullable=False),
|
||||
sa.Column('event_id', sa.Integer, sa.ForeignKey("event.id"), nullable=False),
|
||||
sa.Column('user_id', sa.Integer, sa.ForeignKey("user.id"), nullable=False))
|
||||
session.commit()
|
||||
# NOTE: This does not clear out duplicate events. ¯\_(ツ)_/¯
|
||||
for event in session.query(Event).all():
|
||||
notification = EventNotification()
|
||||
notification.created = event.created
|
||||
notification.event_id = event.id
|
||||
notification.user_id = event.user_id
|
||||
if event.comment:
|
||||
event.user_id = event.comment.submitter_id
|
||||
else:
|
||||
event.user_id = event.ticket.submitter_id
|
||||
session.add(notification)
|
||||
session.commit()
|
||||
|
||||
def downgrade():
|
||||
op.drop_table('event_notifications')
|
|
@ -1,6 +1,6 @@
|
|||
from flask import Blueprint, render_template
|
||||
from flask_login import current_user
|
||||
from todosrht.types import Tracker, Event, EventType
|
||||
from todosrht.types import Tracker, Event, EventNotification, EventType
|
||||
|
||||
html = Blueprint('html', __name__)
|
||||
|
||||
|
@ -12,10 +12,10 @@ def index():
|
|||
your_trackers = (Tracker.query
|
||||
.filter(Tracker.owner_id == current_user.id)
|
||||
.order_by(Tracker.updated.desc())).all()
|
||||
events = (Event.query
|
||||
.filter(Event.user_id == current_user.id)
|
||||
.order_by(Event.created.desc())
|
||||
.limit(10)).all()
|
||||
events = [e.event for e in (EventNotification.query
|
||||
.filter(EventNotification.user_id == current_user.id)
|
||||
.order_by(EventNotification.created.desc())
|
||||
.limit(10)).all()]
|
||||
return render_template("dashboard.html",
|
||||
your_trackers=your_trackers,
|
||||
events=events,
|
||||
|
|
|
@ -4,8 +4,9 @@ from flask import Blueprint, render_template, request, url_for, abort, redirect
|
|||
from flask import session
|
||||
from flask_login import current_user
|
||||
from todosrht.decorators import loginrequired
|
||||
from todosrht.types import Tracker, User, Ticket, TicketStatus, TicketAccess, TicketSeen
|
||||
from todosrht.types import TicketComment, TicketResolution, Event, EventType
|
||||
from todosrht.types import Tracker, User, Ticket, TicketStatus, TicketAccess
|
||||
from todosrht.types import TicketComment, TicketResolution, TicketSeen
|
||||
from todosrht.types import Event, EventType, EventNotification
|
||||
from todosrht.blueprints.tracker import get_access, get_tracker
|
||||
from todosrht.email import notify
|
||||
from srht.config import cfg
|
||||
|
@ -145,26 +146,32 @@ def ticket_comment_POST(owner, name, ticket_id):
|
|||
resolution=resolution.name if resolution else None,
|
||||
ticket_url=ticket_url.replace("%7E", "~")) # hack
|
||||
|
||||
def _add_event(sub):
|
||||
event = Event()
|
||||
event.event_type = 0
|
||||
event.user_id = sub.user_id
|
||||
event.ticket_id = ticket.id
|
||||
if comment:
|
||||
event.event_type |= EventType.comment
|
||||
event.comment_id = comment.id
|
||||
if ticket.status != old_status or ticket.resolution != old_resolution:
|
||||
event.event_type |= EventType.status_change
|
||||
event.old_status = old_status
|
||||
event.old_resolution = old_resolution
|
||||
event.new_status = ticket.status
|
||||
event.new_resolution = ticket.resolution
|
||||
db.session.add(event)
|
||||
event = Event()
|
||||
event.event_type = 0
|
||||
event.user_id = current_user.id
|
||||
event.ticket_id = ticket.id
|
||||
if comment:
|
||||
event.event_type |= EventType.comment
|
||||
event.comment_id = comment.id
|
||||
if ticket.status != old_status or ticket.resolution != old_resolution:
|
||||
event.event_type |= EventType.status_change
|
||||
event.old_status = old_status
|
||||
event.old_resolution = old_resolution
|
||||
event.new_status = ticket.status
|
||||
event.new_resolution = ticket.resolution
|
||||
db.session.add(event)
|
||||
db.session.flush()
|
||||
|
||||
def _add_notification(sub):
|
||||
notification = EventNotification()
|
||||
notification.user_id = sub.user_id
|
||||
notification.event_id = event.id
|
||||
db.session.add(notification)
|
||||
|
||||
updated_users = set()
|
||||
for sub in tracker.subscriptions:
|
||||
updated_users.update([sub.user_id])
|
||||
_add_event(sub)
|
||||
_add_notification(sub)
|
||||
if sub.user_id == current_user.id:
|
||||
subscribed = True
|
||||
continue
|
||||
|
@ -173,7 +180,7 @@ def ticket_comment_POST(owner, name, ticket_id):
|
|||
for sub in ticket.subscriptions:
|
||||
if sub.user_id in updated_users:
|
||||
continue
|
||||
_add_event(sub)
|
||||
_add_notification(sub)
|
||||
if sub.user_id == current_user.id:
|
||||
subscribed = True
|
||||
continue
|
||||
|
@ -184,7 +191,7 @@ def ticket_comment_POST(owner, name, ticket_id):
|
|||
sub.ticket_id = ticket.id
|
||||
sub.user_id = user.id
|
||||
db.session.add(sub)
|
||||
_add_event(sub)
|
||||
_add_notification(sub)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ from todosrht.decorators import loginrequired
|
|||
from todosrht.email import notify
|
||||
from todosrht.types import Tracker, User, Ticket, TicketStatus, TicketAccess
|
||||
from todosrht.types import TicketComment, TicketResolution, TicketSubscription
|
||||
from todosrht.types import TicketSeen, Event, EventType
|
||||
from todosrht.types import TicketSeen, Event, EventType, EventNotification
|
||||
from srht.config import cfg
|
||||
from srht.database import db
|
||||
from srht.validation import Validation
|
||||
|
@ -240,6 +240,12 @@ def tracker_submit_POST(owner, name):
|
|||
tracker.updated = datetime.utcnow()
|
||||
# TODO: Handle unique constraint failure (contention) and retry?
|
||||
db.session.flush()
|
||||
event = Event()
|
||||
event.event_type = EventType.created
|
||||
event.user_id = current_user.id
|
||||
event.ticket_id = ticket.id
|
||||
db.session.add(event)
|
||||
db.session.flush()
|
||||
|
||||
ticket_url = url_for("ticket.ticket_GET",
|
||||
owner="~" + tracker.owner.username,
|
||||
|
@ -247,11 +253,10 @@ def tracker_submit_POST(owner, name):
|
|||
ticket_id=ticket.scoped_id)
|
||||
|
||||
for sub in tracker.subscriptions:
|
||||
event = Event()
|
||||
event.event_type = EventType.created
|
||||
event.user_id = sub.user_id
|
||||
event.ticket_id = ticket.id
|
||||
db.session.add(event)
|
||||
notification = EventNotification()
|
||||
notification.user_id = sub.user_id
|
||||
notification.event_id = event.id
|
||||
db.session.add(notification)
|
||||
|
||||
if sub.user_id == ticket.submitter_id:
|
||||
subscribed = True
|
||||
|
|
|
@ -6,4 +6,4 @@ from .ticketseen import TicketSeen
|
|||
from .ticket import Ticket
|
||||
from .ticketsubscription import TicketSubscription
|
||||
from .ticketcomment import TicketComment
|
||||
from .event import Event, EventType
|
||||
from .event import Event, EventType, EventNotification
|
||||
|
|
|
@ -37,3 +37,17 @@ class Event(Base):
|
|||
|
||||
def __repr__(self):
|
||||
return '<Event {}>'.format(self.id)
|
||||
|
||||
class EventNotification(Base):
|
||||
__tablename__ = 'event_notification'
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
created = sa.Column(sa.DateTime, nullable=False)
|
||||
|
||||
event_id = sa.Column(sa.Integer, sa.ForeignKey("event.id"), nullable=False)
|
||||
event = sa.orm.relationship("Event", backref=sa.orm.backref("notifications"))
|
||||
|
||||
user_id = sa.Column(sa.Integer, sa.ForeignKey("user.id"), nullable=False)
|
||||
user = sa.orm.relationship("User", backref=sa.orm.backref("notifications"))
|
||||
|
||||
def __repr__(self):
|
||||
return '<EventNotification {} {}>'.format(self.id, self.user.username)
|
||||
|
|
Loading…
Reference in New Issue