Add support for last_seen

Change-Id: I01f2735b9d72d41b99427a39dbb1e31246a1c531
This commit is contained in:
James E. Blair 2016-02-07 08:19:42 -08:00
parent 068e83b9ed
commit 4a18f6a6f8
9 changed files with 104 additions and 15 deletions

View File

@ -41,10 +41,24 @@ commentlinks:
# the global help text, and pressing the key anywhere in Gertty will
# discard the current display stack and replace it with the results of
# the query.
#
# NB: "recentlyseen:24 hours" does not just return changes seen in the
# last 24 hours -- it returns changes seen within 24 hours of the most
# recently seen change. So you can take the weekend off and pick up
# where you were.
dashboards:
- name: "My changes"
query: "owner:self status:open"
key: "f2"
- name: "Incoming reviews"
query: "is:open is:reviewer"
key: "f3"
- name: "Starred changes"
query: "is:starred"
key: "f4"
- name: "Recently seen changes"
query: "recentlyseen:24 hours"
key: "f5"
# Reviewkeys are hotkeys that perform immediate reviews within the
# change screen. Any pending comments or review messages will be

View File

@ -84,6 +84,11 @@ hide-comments:
# the global help text, and pressing the key anywhere in Gertty will
# discard the current display stack and replace it with the results of
# the query.
#
# NB: "recentlyseen:24 hours" does not just return changes seen in the
# last 24 hours -- it returns changes seen within 24 hours of the most
# recently seen change. So you can take the weekend off and pick up
# where you were.
dashboards:
- name: "My changes"
query: "owner:self status:open"
@ -91,6 +96,12 @@ dashboards:
- name: "Incoming reviews"
query: "is:open is:reviewer"
key: "f3"
- name: "Starred changes"
query: "is:starred"
key: "f4"
- name: "Recently seen changes"
query: "recentlyseen:24 hours"
key: "f5"
# Reviewkeys are hotkeys that perform immediate reviews within the
# change screen. Any pending comments or review messages will be

View File

@ -190,10 +190,24 @@ commentlinks:
# the global help text, and pressing the key anywhere in Gertty will
# discard the current display stack and replace it with the results of
# the query.
#
# NB: "recentlyseen:24 hours" does not just return changes seen in the
# last 24 hours -- it returns changes seen within 24 hours of the most
# recently seen change. So you can take the weekend off and pick up
# where you were.
dashboards:
- name: "My changes"
query: "owner:self status:open"
key: "f2"
- name: "Incoming reviews"
query: "is:open is:reviewer"
key: "f3"
- name: "Starred changes"
query: "is:starred"
key: "f4"
- name: "Recently seen changes"
query: "recentlyseen:24 hours"
key: "f5"
# Reviewkeys are hotkeys that perform immediate reviews within the
# change screen. Any pending comments or review messages will be

View File

@ -0,0 +1,26 @@
"""add last_seen column to change
Revision ID: 37a702b7f58e
Revises: 3610c2543e07
Create Date: 2016-02-06 09:09:38.728225
"""
# revision identifiers, used by Alembic.
revision = '37a702b7f58e'
down_revision = '3610c2543e07'
import warnings
from alembic import op
import sqlalchemy as sa
def upgrade():
with warnings.catch_warnings():
warnings.simplefilter("ignore")
op.add_column('change', sa.Column('last_seen', sa.DateTime, index=True))
def downgrade():
pass

View File

@ -81,6 +81,7 @@ change_table = Table(
Column('pending_starred', Boolean, index=True, nullable=False),
Column('pending_status', Boolean, index=True, nullable=False),
Column('pending_status_message', Text),
Column('last_seen', DateTime, index=True),
)
change_conflict_table = Table(
'change_conflict', metadata,

View File

@ -67,7 +67,7 @@ class SearchCompiler(object):
if __name__ == '__main__':
class Dummy(object):
pass
query = 'status:open limit:50 age:2months'
query = 'recentlyseen:24 hours'
lexer = tokenizer.SearchTokenizer()
lexer.input(query)
while True:

View File

@ -22,6 +22,23 @@ import gertty.db
import gertty.search
from gertty.search.tokenizer import tokens # NOQA
def age_to_delta(delta, unit):
if unit in ['seconds', 'second', 'sec', 's']:
pass
elif unit in ['minutes', 'minute', 'min', 'm']:
delta = delta * 60
elif unit in ['hours', 'hour', 'hr', 'h']:
delta = delta * 60 * 60
elif unit in ['days', 'day', 'd']:
delta = delta * 60 * 60 * 24
elif unit in ['weeks', 'week', 'w']:
delta = delta * 60 * 60 * 24 * 7
elif unit in ['months', 'month', 'mon']:
delta = delta * 60 * 60 * 24 * 30
elif unit in ['years', 'year', 'y']:
delta = delta * 60 * 60 * 24 * 365
return delta
def SearchParser():
precedence = ( # NOQA
('left', 'NOT', 'NEG'),
@ -60,6 +77,7 @@ def SearchParser():
def p_term(p):
'''term : age_term
| recentlyseen_term
| change_term
| owner_term
| reviewer_term
@ -91,22 +109,20 @@ def SearchParser():
now = datetime.datetime.utcnow()
delta = p[2]
unit = p[3]
if unit in ['seconds', 'second', 'sec', 's']:
pass
elif unit in ['minutes', 'minute', 'min', 'm']:
delta = delta * 60
elif unit in ['hours', 'hour', 'hr', 'h']:
delta = delta * 60 * 60
elif unit in ['days', 'day', 'd']:
delta = delta * 60 * 60 * 24
elif unit in ['weeks', 'week', 'w']:
delta = delta * 60 * 60 * 24 * 7
elif unit in ['months', 'month', 'mon']:
delta = delta * 60 * 60 * 24 * 30
elif unit in ['years', 'year', 'y']:
delta = delta * 60 * 60 * 24 * 365
delta = age_to_delta(delta, unit)
p[0] = gertty.db.change_table.c.updated < (now-datetime.timedelta(seconds=delta))
def p_recentlyseen_term(p):
'''recentlyseen_term : OP_RECENTLYSEEN NUMBER string'''
# A gertty extension
now = datetime.datetime.utcnow()
delta = p[2]
unit = p[3]
delta = age_to_delta(delta, unit)
s = select([func.datetime(func.max(gertty.db.change_table.c.last_seen), '-%s seconds' % delta)],
correlate=False)
p[0] = gertty.db.change_table.c.last_seen >= s
def p_change_term(p):
'''change_term : OP_CHANGE CHANGE_ID
| OP_CHANGE NUMBER'''

View File

@ -17,6 +17,7 @@ import six
operators = {
'age': 'OP_AGE',
'recentlyseen': 'OP_RECENTLYSEEN', # Gertty extension
'change': 'OP_CHANGE',
'owner': 'OP_OWNER',
#'OP_OWNERIN', # needs local group membership

View File

@ -445,6 +445,7 @@ class ChangeView(urwid.WidgetWrap):
self.message_rows = {}
self.last_revision_key = None
self.hide_comments = True
self.marked_seen = False
self.change_id_label = mywid.TextButton(u'', on_press=self.searchChangeId)
self.owner_label = mywid.TextButton(u'', on_press=self.searchOwner)
self.project_label = mywid.TextButton(u'', on_press=self.searchProject)
@ -550,6 +551,11 @@ class ChangeView(urwid.WidgetWrap):
def refresh(self):
with self.app.db.getSession() as session:
change = session.getChange(self.change_key)
# When we first open the change, update its last_seen
# time.
if not self.marked_seen:
change.last_seen = datetime.datetime.utcnow()
self.marked_seen = True
self.topic = change.topic or ''
self.pending_status_message = change.pending_status_message or ''
reviewed = hidden = starred = held = ''