Browse Source

Add support for searching for hashtags

Also for setting hashtags in change lists using the process mark.
Editing hashtags on individual change screens was already supported.
Selecting hashtags on a change screen will now perform a search for
that tag.

Change-Id: Icc23e10bbf22fbe9b1d958758ec6ceb3286e795b
changes/88/778088/1
James E. Blair 8 months ago
parent
commit
c134a8c6f1
  1. 4
      gertty/search/__init__.py
  2. 8
      gertty/search/parser.py
  3. 1
      gertty/search/tokenizer.py
  4. 16
      gertty/view/change.py
  5. 30
      gertty/view/change_list.py

4
gertty/search/__init__.py

@ -60,6 +60,10 @@ class SearchCompiler(object):
result = and_(gertty.db.change_table.c.account_key == gertty.db.account_table.c.key,
result)
tables.remove(gertty.db.account_table)
if gertty.db.hashtag_table in tables:
result = and_(gertty.db.hashtag_table.c.change_key == gertty.db.change_table.c.key,
result)
tables.remove(gertty.db.hashtag_table)
if gertty.db.file_table in tables:
# We only want to look at files for the most recent
# revision.

8
gertty/search/parser.py

@ -87,6 +87,7 @@ def SearchParser():
| project_key_term
| branch_term
| topic_term
| hashtag_term
| ref_term
| label_term
| message_term
@ -203,6 +204,13 @@ def SearchParser():
p[0] = and_(gertty.db.change_table.c.topic.isnot(None),
gertty.db.change_table.c.topic == p[2])
def p_hashtag_term(p):
'''hashtag_term : OP_HASHTAG string'''
if p[2].startswith('^'):
p[0] = func.matches(p[2], gertty.db.hashtag_table.c.name)
else:
p[0] = gertty.db.hashtag_table.c.name == p[2]
def p_ref_term(p):
'''ref_term : OP_REF string'''
if p[2].startswith('^'):

1
gertty/search/tokenizer.py

@ -29,6 +29,7 @@ operators = {
'_project_key': 'OP_PROJECT_KEY', # internal gertty use only
'branch': 'OP_BRANCH',
'topic': 'OP_TOPIC',
'hashtag': 'OP_HASHTAG',
'ref': 'OP_REF',
#'tr': 'OP_TR', # needs trackingids
#'bug': 'OP_BUG', # needs trackingids

16
gertty/view/change.py

@ -595,7 +595,7 @@ class ChangeView(urwid.WidgetWrap):
self.project_label = mywid.TextButton(u'', on_press=self.searchProject)
self.branch_label = urwid.Text(u'', wrap='clip')
self.topic_label = mywid.TextButton(u'', on_press=self.searchTopic)
self.hashtags_label = urwid.Text(u'', wrap='clip')
self.hashtags_label = mywid.HyperText(u'')
self.created_label = urwid.Text(u'', wrap='clip')
self.updated_label = urwid.Text(u'', wrap='clip')
self.status_label = urwid.Text(u'', wrap='clip')
@ -735,7 +735,16 @@ class ChangeView(urwid.WidgetWrap):
self.project_label.text.set_text(('change-data', change.project.name))
self.branch_label.set_text(('change-data', change.branch))
self.topic_label.text.set_text(('change-data', self.topic))
self.hashtags_label.set_text(('change-data', ' '.join([x.name for x in change.hashtags])))
hashtag_buttons = []
for x in change.hashtags:
if hashtag_buttons:
hashtag_buttons.append(' ')
link = mywid.Link(x.name, 'change-data', 'focused-change-data')
urwid.connect_signal(
link, 'selected',
lambda link, x=x: self.searchHashtags(x.name))
hashtag_buttons.append(link)
self.hashtags_label.set_text(('change-data', hashtag_buttons or u''))
self.created_label.set_text(('change-data', str(self.app.time(change.created))))
self.updated_label.set_text(('change-data', str(self.app.time(change.updated))))
stat = change.wip and 'WIP' or change.status
@ -1300,6 +1309,9 @@ class ChangeView(urwid.WidgetWrap):
if self.topic:
self.app.doSearch("status:open topic:%s" % (self.topic,))
def searchHashtags(self, name):
self.app.doSearch("status:open hashtag:%s" % (name,))
def reviewKey(self, reviewkey):
approvals = {}
for a in reviewkey['approvals']:

30
gertty/view/change_list.py

@ -362,6 +362,8 @@ class ChangeListView(urwid.WidgetWrap, mywid.Searchable):
"Abandon the marked changes"),
(keymap.EDIT_TOPIC,
"Set the topic of the marked changes"),
(keymap.EDIT_HASHTAGS,
"Edit the hashtags of this change"),
(keymap.RESTORE_CHANGE,
"Restore the marked changes"),
(keymap.REFRESH,
@ -755,6 +757,9 @@ class ChangeListView(urwid.WidgetWrap, mywid.Searchable):
if keymap.EDIT_TOPIC in commands:
self.editTopic()
return True
if keymap.EDIT_HASHTAGS in commands:
self.editHashtags()
return None
if keymap.REFRESH in commands:
if self.project_key:
self.app.sync.submitTask(
@ -880,6 +885,31 @@ class ChangeListView(urwid.WidgetWrap, mywid.Searchable):
self.app.backScreen()
self.refresh()
def editHashtags(self):
dialog = view_change.EditHashtagsDialog(self.app, '')
urwid.connect_signal(dialog, 'save',
lambda button: self.closeEditHashtags(dialog, True))
urwid.connect_signal(dialog, 'cancel',
lambda button: self.closeEditHashtags(dialog, False))
self.app.popup(dialog)
def closeEditHashtags(self, dialog, save):
if save:
rows = [row for row in self.change_rows.values() if row.mark]
if not rows:
pos = self.listbox.focus_position
rows = [self.listbox.body[pos]]
change_keys = [row.change_key for row in rows]
with self.app.db.getSession() as session:
for change_key in change_keys:
change = session.getChange(change_key)
change.setHashtags([x.strip() for x in dialog.entry.edit_text.split(',')])
change.pending_hashtags = True
self.app.sync.submitTask(
sync.SetHashtagsTask(change_key, sync.HIGH_PRIORITY))
self.app.backScreen()
self.refresh()
def abandonChange(self):
dialog = mywid.TextEditDialog(u'Abandon Change', u'Abandon message:',
u'Abandon Change', u'')

Loading…
Cancel
Save