Merge "Support search by story number"

This commit is contained in:
Jenkins 2016-11-23 01:32:11 +00:00 committed by Gerrit Code Review
commit 7ad9f9c4ec
2 changed files with 32 additions and 49 deletions

View File

@ -243,7 +243,7 @@ class ProjectCache(object):
del self.projects[project.key] del self.projects[project.key]
class App(object): class App(object):
simple_change_search = re.compile('^(\d+|I[a-fA-F0-9]{40})$') simple_story_search = re.compile('^(\d+)$')
def __init__(self, server=None, palette='default', def __init__(self, server=None, palette='default',
keymap='default', debug=False, verbose=False, keymap='default', debug=False, verbose=False,
@ -519,77 +519,64 @@ class App(object):
self.popup(dialog, min_width=76, min_height=len(lines)+4) self.popup(dialog, min_width=76, min_height=len(lines)+4)
#storyboard #storyboard
def _syncOneChangeFromQuery(self, query): def _syncOneStoryFromQuery(self, query):
number = changeid = restid = None story = None
if query.startswith("change:"): if query.startswith("story:"):
number = query.split(':')[1].strip() story = int(query.split(':')[1].strip())
try: if not story:
number = int(number)
except ValueError:
number = None
changeid = query.split(':')[1].strip()
if not (number or changeid):
return return
with self.db.getSession() as session: with self.db.getSession() as session:
if number: stories = []
changes = [session.getChangeByNumber(number)] if story:
elif changeid: stories = [session.getStoryByID(story)]
changes = session.getChangesByChangeID(changeid) story_keys = [s.key for s in stories if s]
change_keys = [c.key for c in changes if c] if not story_keys:
restids = [c.id for c in changes if c]
if not change_keys:
if self.sync.offline: if self.sync.offline:
raise Exception('Can not sync change while offline.') raise Exception('Can not sync story while offline.')
dialog = mywid.SystemMessage("Syncing change...") dialog = mywid.SystemMessage("Syncing story...")
self.popup(dialog, width=40, height=6) self.popup(dialog, width=40, height=6)
self.loop.draw_screen() self.loop.draw_screen()
try: try:
task = sync.SyncChangeByNumberTask(number or changeid, sync.HIGH_PRIORITY) task = sync.SyncStoryByIDTask(story, sync.HIGH_PRIORITY)
self.sync.submitTask(task) self.sync.submitTask(task)
succeeded = task.wait(300) succeeded = task.wait(300)
if not succeeded: if not succeeded:
raise Exception('Unable to find change.') raise Exception('Unable to find story.')
for subtask in task.tasks: for subtask in task.tasks:
succeeded = subtask.wait(300) succeeded = subtask.wait(300)
if not succeeded: if not succeeded:
raise Exception('Unable to sync change.') raise Exception('Unable to sync story.')
finally: finally:
# Remove "syncing..." popup # Remove "syncing..." popup
self.backScreen() self.backScreen()
with self.db.getSession() as session: with self.db.getSession() as session:
if number: if story:
changes = [session.getChangeByNumber(number)] stories = [session.getStoryByID(story)]
elif changeid: story_keys = [s.key for s in stories if s]
changes = session.getChangesByChangeID(changeid) if not story_keys:
change_keys = [c.key for c in changes if c] raise Exception('Story is not in local database.')
elif restids:
for restid in restids:
task = sync.SyncChangeTask(restid, sync.HIGH_PRIORITY)
self.sync.submitTask(task)
if not change_keys:
raise Exception('Change is not in local database.')
def doSearch(self, query): def doSearch(self, query):
self.log.debug("Search query: %s" % query) self.log.debug("Search query: %s" % query)
try: try:
self._syncOneChangeFromQuery(query) self._syncOneStoryFromQuery(query)
except Exception as e: except Exception as e:
return self.error(e.message) return self.error(e.message)
with self.db.getSession() as session: with self.db.getSession() as session:
try: try:
changes = session.getChanges(query) stories = session.getStories(query, False)
except boartty.search.SearchSyntaxError as e: except boartty.search.SearchSyntaxError as e:
return self.error(e.message) return self.error(e.message)
except sqlalchemy.exc.OperationalError as e: except sqlalchemy.exc.OperationalError as e:
return self.error(e.message) return self.error(e.message)
except Exception as e: except Exception as e:
return self.error(str(e)) return self.error(str(e))
change_key = None story_key = None
if len(changes) == 1: if len(stories) == 1:
change_key = changes[0].key story_key = stories[0].key
try: try:
if change_key: if story_key:
view = view_change.ChangeView(self, change_key) view = view_story.StoryView(self, story_key)
else: else:
view = view_story_list.StoryListView(self, query) view = view_story_list.StoryListView(self, query)
self.changeScreen(view) self.changeScreen(view)
@ -607,8 +594,8 @@ class App(object):
def _searchDialog(self, dialog): def _searchDialog(self, dialog):
self.backScreen() self.backScreen()
query = dialog.entry.edit_text.strip() query = dialog.entry.edit_text.strip()
if self.simple_change_search.match(query): if self.simple_story_search.match(query):
query = 'change:%s' % query query = 'story:%s' % query
else: else:
result = self.parseInternalURL(query) result = self.parseInternalURL(query)
if result is not None: if result is not None:

View File

@ -125,12 +125,8 @@ def SearchParser():
p[0] = boartty.db.story_table.c.last_seen >= s p[0] = boartty.db.story_table.c.last_seen >= s
def p_story_term(p): def p_story_term(p):
'''story_term : OP_STORY STORY_ID '''story_term : OP_STORY NUMBER'''
| OP_STORY NUMBER''' p[0] = boartty.db.story_table.c.id == p[2]
if type(p[2]) == int:
p[0] = boartty.db.story_table.c.number == p[2]
else:
p[0] = boartty.db.story_table.c.story_id == p[2]
def p_owner_term(p): def p_owner_term(p):
'''owner_term : OP_OWNER string''' '''owner_term : OP_OWNER string'''