Remove TicketSeen

Has a fair amount of complexity for not much gain.
writable-api 0.66.0
Ignas Kiela 8 months ago committed by Drew DeVault
parent d75f0e5a29
commit 03f8983945
  1. 28
  2. 30
  3. 6
  4. 9
  5. 4
  6. 19
  7. 1
  8. 1
  9. 25

@ -3,35 +3,9 @@ from tests.factories import TrackerFactory, TicketFactory, UserFactory
from tests.factories import ParticipantFactory
from tests.utils import logged_in_as
from import get_or_create_subscription
from todosrht.types import TicketSeen, TicketSubscription
from todosrht.types import TicketSubscription
from todosrht.urls import ticket_url
def test_mark_seen(client):
ticket = TicketFactory()
user = UserFactory()
url = ticket_url(ticket)
query = TicketSeen.query.filter_by(user=user, ticket=ticket)
assert query.count() == 0
# Created on first visit
with logged_in_as(user):
response = client.get(url)
assert response.status_code == 200
first_time =
# Updated on second visit
with logged_in_as(user):
response = client.get(url)
assert response.status_code == 200
second_time =
assert second_time > first_time
def test_get_or_create_subscription():
participant1 = ParticipantFactory()
participant2 = ParticipantFactory()

@ -0,0 +1,30 @@
"""Remove TicketSeen
Revision ID: e3427af07c4e
Revises: 368579bcc610
Create Date: 2021-12-18 19:43:57.634789
# revision identifiers, used by Alembic.
revision = 'e3427af07c4e'
down_revision = '368579bcc610'
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql
def upgrade():
def downgrade():
sa.Column('user_id', sa.INTEGER(), autoincrement=False, nullable=False),
sa.Column('ticket_id', sa.INTEGER(), autoincrement=False, nullable=False),
sa.Column('last_view', postgresql.TIMESTAMP(), server_default=sa.text('now()'), autoincrement=False, nullable=False),
sa.ForeignKeyConstraint(['ticket_id'], [''], name='ticket_seen_ticket_id_fkey', ondelete='CASCADE'),
sa.ForeignKeyConstraint(['user_id'], [''], name='ticket_seen_user_id_fkey'),
sa.PrimaryKeyConstraint('user_id', 'ticket_id', name='ticket_seen_pkey')

@ -8,7 +8,7 @@ from srht.validation import Validation
from todosrht.access import get_tracker, get_ticket
from todosrht.filters import render_markup
from import find_usernames
from import add_comment, mark_seen, assign, unassign
from import add_comment, assign, unassign
from import get_participant_for_user
from todosrht.trackers import get_recent_users
from todosrht.types import Event, EventType, Label, TicketLabel
@ -87,10 +87,6 @@ def ticket_GET(owner, name, ticket_id):
if not ticket:
if current_user:
mark_seen(ticket, current_user)
ctx = get_ticket_context(ticket, tracker, access)
return render_template("ticket.html", **ctx)

@ -9,7 +9,6 @@ from todosrht.color import color_from_hex, color_to_hex, get_text_color
from todosrht.color import valid_hex_color_code
from todosrht.filters import render_markup
from import apply_search
from import get_last_seen_times
from import get_participant_for_user, submit_ticket
from todosrht.types import Event, Label, TicketLabel
from todosrht.types import TicketSubscription, Participant
@ -107,13 +106,6 @@ def return_tracker(tracker, access, **kwargs):
tickets, pagination = paginate_query(tickets, results_per_page=25)
# Find which tickets were seen by the user since last update
seen_ticket_ids = []
if current_user:
seen_times = get_last_seen_times(current_user, tickets)
seen_ticket_ids = [ for t in tickets
if in seen_times and seen_times[] >= t.updated]
if "another" in kwargs:
another = kwargs["another"]
del kwargs["another"]
@ -121,7 +113,6 @@ def return_tracker(tracker, access, **kwargs):
return render_template("tracker.html",
tracker=tracker, another=another, tickets=tickets,
access=access, is_subscribed=is_subscribed, search=terms,
tracker_subscribe=tracker_subscribe, **pagination, **kwargs)

@ -241,11 +241,7 @@
<div class="comments" aria-label="Comments">
<span class="icon_count">
{% if in seen_ticket_ids or ticket.comment_count == 0 %}
{% else %}
{% endif %}
{{ ticket.comment_count }}
<span class="commentlabel">

@ -7,7 +7,7 @@ from srht.database import db
from import notify, format_lines
from todosrht.types import Event, EventType, EventNotification
from todosrht.types import TicketComment, TicketStatus, TicketSubscription
from todosrht.types import TicketSeen, TicketAssignee, User, Ticket, Tracker
from todosrht.types import TicketAssignee, User, Ticket, Tracker
from todosrht.types import Participant, ParticipantType
from todosrht.urls import ticket_url
from sqlalchemy import func, or_, and_
@ -335,17 +335,6 @@ def add_comment(submitter, ticket,
return event
def mark_seen(ticket, user):
"""Mark the ticket as seen by user."""
seen = TicketSeen.query.filter_by(user=user, ticket=ticket).one_or_none()
if seen:
seen.update() # Updates last_view time
seen = TicketSeen(,
return seen
def get_or_create_subscription(ticket, participant):
If participant is subscribed to ticket or tracker, returns that
@ -445,12 +434,6 @@ def unassign(ticket, assignee, assigner):
event.by_participant_id =
def get_last_seen_times(user, tickets):
"""Fetches last times the user has seen each of the given tickets."""
return dict(db.session.query(TicketSeen.ticket_id, TicketSeen.last_view)
.filter(TicketSeen.ticket_id.in_([ for t in tickets]))
.filter(TicketSeen.user == user))
def get_comment_count(ticket_id):
"""Returns the number of comments on a given ticket."""
return (

@ -19,7 +19,6 @@ from todosrht.types.participant import Participant, ParticipantType
from todosrht.types.ticket import Ticket
from todosrht.types.ticketassignee import TicketAssignee
from todosrht.types.ticketcomment import TicketComment
from todosrht.types.ticketseen import TicketSeen
from todosrht.types.ticketsubscription import TicketSubscription
from todosrht.types.tracker import Tracker, Visibility
from todosrht.types.useraccess import UserAccess

@ -46,7 +46,6 @@ class Ticket(Base):
view_list = sa.orm.relationship("TicketSeen", viewonly=True)
labels = sa.orm.relationship("Label",
secondary="ticket_label", order_by="",

@ -1,25 +0,0 @@
import sqlalchemy as sa
import sqlalchemy_utils as sau
from srht.database import Base
from datetime import datetime
class TicketSeen(Base):
"""Stores the last time a user viewed this ticket. Calculates if comments have been seen."""
__tablename__ = 'ticket_seen'
user_id = sa.Column(sa.Integer,
user = sa.orm.relationship("User")
ticket_id = sa.Column(sa.Integer,
sa.ForeignKey('', ondelete="CASCADE"),
ticket = sa.orm.relationship("Ticket", lazy="joined")
last_view = sa.Column(sa.DateTime,
def update(self):
self.last_view = datetime.utcnow()