Merge "Selectively refresh screen"

This commit is contained in:
Jenkins 2014-11-19 23:37:08 +00:00 committed by Gerrit Code Review
commit 428ef2d029
6 changed files with 113 additions and 12 deletions

View File

@ -16,6 +16,7 @@
import argparse import argparse
import logging import logging
import os import os
import Queue
import sys import sys
import threading import threading
import webbrowser import webbrowser
@ -227,7 +228,12 @@ class App(object):
widget = self.loop.widget widget = self.loop.widget
while isinstance(widget, urwid.Overlay): while isinstance(widget, urwid.Overlay):
widget = widget.contents[0][0] widget = widget.contents[0][0]
widget.refresh() try:
while True:
event = self.sync.result_queue.get(0)
widget.refresh(event)
except Queue.Empty:
pass
def popup(self, widget, def popup(self, widget,
relative_width=50, relative_height=25, relative_width=50, relative_height=25,

View File

@ -78,6 +78,38 @@ class MultiQueue(object):
finally: finally:
self.condition.release() self.condition.release()
class UpdateEvent(object):
def updateRelatedChanges(self, session, change):
related_change_keys = set()
related_change_keys.add(change.key)
for revision in change.revisions:
parent = session.getRevisionByCommit(revision.parent)
if parent:
related_change_keys.add(parent.change.key)
for child in session.getRevisionsByParent(revision.commit):
related_change_keys.add(child.change.key)
self.related_change_keys = related_change_keys
class ProjectAddedEvent(UpdateEvent):
def __init__(self, project):
self.project_key = project.key
class ChangeAddedEvent(UpdateEvent):
def __init__(self, change):
self.project_key = change.project.key
self.change_key = change.key
self.related_change_keys = set()
self.review_flag_changed = True
self.status_changed = True
class ChangeUpdatedEvent(UpdateEvent):
def __init__(self, change):
self.project_key = change.project.key
self.change_key = change.key
self.related_change_keys = set()
self.review_flag_changed = False
self.status_changed = False
class Task(object): class Task(object):
def __init__(self, priority=NORMAL_PRIORITY): def __init__(self, priority=NORMAL_PRIORITY):
self.log = logging.getLogger('gertty.sync') self.log = logging.getLogger('gertty.sync')
@ -85,6 +117,7 @@ class Task(object):
self.succeeded = None self.succeeded = None
self.event = threading.Event() self.event = threading.Event()
self.tasks = [] self.tasks = []
self.results = []
def complete(self, success): def complete(self, success):
self.succeeded = success self.succeeded = success
@ -127,7 +160,9 @@ class SyncProjectListTask(Task):
for name in remote_keys-local_keys: for name in remote_keys-local_keys:
p = remote[name] p = remote[name]
session.createProject(name, description=p.get('description', '')) project = session.createProject(name,
description=p.get('description', ''))
self.results.append(ProjectAddedEvent(project))
class SyncSubscribedProjectBranchesTask(Task): class SyncSubscribedProjectBranchesTask(Task):
def __repr__(self): def __repr__(self):
@ -327,8 +362,14 @@ class SyncChangeTask(Task):
remote_change['subject'], created, remote_change['subject'], created,
updated, remote_change['status'], updated, remote_change['status'],
topic=remote_change.get('topic')) topic=remote_change.get('topic'))
result = ChangeAddedEvent(change)
else:
result = ChangeUpdatedEvent(change)
self.results.append(result)
change.owner = account change.owner = account
change.status = remote_change['status'] if change.status != remote_change['status']:
change.status = remote_change['status']
result.status_changed = True
change.subject = remote_change['subject'] change.subject = remote_change['subject']
change.updated = dateutil.parser.parse(remote_change['updated']) change.updated = dateutil.parser.parse(remote_change['updated'])
change.topic = remote_change.get('topic') change.topic = remote_change.get('topic')
@ -367,6 +408,7 @@ class SyncChangeTask(Task):
sync.submitTask(SyncChangeByCommitTask(revision.parent, self.priority)) sync.submitTask(SyncChangeByCommitTask(revision.parent, self.priority))
self.log.debug("Change %s revision %s needs parent commit %s synced" % self.log.debug("Change %s revision %s needs parent commit %s synced" %
(change.id, remote_revision['_number'], revision.parent)) (change.id, remote_revision['_number'], revision.parent))
result.updateRelatedChanges(session, change)
remote_comments_data = remote_revision['_gertty_remote_comments_data'] remote_comments_data = remote_revision['_gertty_remote_comments_data']
for remote_file, remote_comments in remote_comments_data.items(): for remote_file, remote_comments in remote_comments_data.items():
for remote_comment in remote_comments: for remote_comment in remote_comments:
@ -499,7 +541,9 @@ class SyncChangeTask(Task):
if not user_voted: if not user_voted:
# Only consider changing the reviewed state if we don't have a vote # Only consider changing the reviewed state if we don't have a vote
if new_revision or new_message: if new_revision or new_message:
change.reviewed = False if not change.reviewed:
change.reviewed = False
result.review_flag_changed = True
for url, refs in fetches.items(): for url, refs in fetches.items():
self.log.debug("Fetching from %s with refs %s", url, refs) self.log.debug("Fetching from %s with refs %s", url, refs)
try: try:
@ -781,6 +825,7 @@ class Sync(object):
self.app = app self.app = app
self.log = logging.getLogger('gertty.sync') self.log = logging.getLogger('gertty.sync')
self.queue = MultiQueue([HIGH_PRIORITY, NORMAL_PRIORITY, LOW_PRIORITY]) self.queue = MultiQueue([HIGH_PRIORITY, NORMAL_PRIORITY, LOW_PRIORITY])
self.result_queue = Queue.Queue()
self.session = requests.Session() self.session = requests.Session()
if self.app.config.auth_type == 'basic': if self.app.config.auth_type == 'basic':
authclass = requests.auth.HTTPBasicAuth authclass = requests.auth.HTTPBasicAuth
@ -838,6 +883,8 @@ class Sync(object):
self.app.status.update(error=True, refresh=False) self.app.status.update(error=True, refresh=False)
self.offline = False self.offline = False
self.app.status.update(offline=False, refresh=False) self.app.status.update(offline=False, refresh=False)
for r in task.results:
self.result_queue.put(r)
os.write(pipe, 'refresh\n') os.write(pipe, 'refresh\n')
return None return None

View File

@ -14,6 +14,7 @@
# under the License. # under the License.
import datetime import datetime
import logging
import urwid import urwid
@ -415,6 +416,7 @@ class ChangeView(urwid.WidgetWrap):
def __init__(self, app, change_key): def __init__(self, app, change_key):
super(ChangeView, self).__init__(urwid.Pile([])) super(ChangeView, self).__init__(urwid.Pile([]))
self.log = logging.getLogger('gertty.view.change')
self.app = app self.app = app
self.change_key = change_key self.change_key = change_key
self.revision_rows = {} self.revision_rows = {}
@ -497,7 +499,15 @@ class ChangeView(urwid.WidgetWrap):
if not succeeded: if not succeeded:
raise gertty.view.DisplayError("Git commits not present in local repository") raise gertty.view.DisplayError("Git commits not present in local repository")
def refresh(self): def refresh(self, event=None):
if event and not ((isinstance(event, sync.ChangeAddedEvent) and
self.change_key in event.related_change_keys)
or
(isinstance(event, sync.ChangeUpdatedEvent) and
self.change_key in event.related_change_keys)):
self.log.debug("Ignoring refresh change due to event %s" % (event,))
return
self.log.debug("Refreshing change due to event %s" % (event,))
change_info = [] change_info = []
with self.app.db.getSession() as session: with self.app.db.getSession() as session:
change = session.getChange(self.change_key) change = session.getChange(self.change_key)

View File

@ -14,6 +14,7 @@
# under the License. # under the License.
import datetime import datetime
import logging
import urwid import urwid
from gertty import keymap from gertty import keymap
@ -115,8 +116,10 @@ class ChangeListView(urwid.WidgetWrap):
"Reverse the sort") "Reverse the sort")
] ]
def __init__(self, app, query, query_desc=None, unreviewed=False): def __init__(self, app, query, query_desc=None, project_key=None,
unreviewed=False):
super(ChangeListView, self).__init__(urwid.Pile([])) super(ChangeListView, self).__init__(urwid.Pile([]))
self.log = logging.getLogger('gertty.view.change_list')
self.app = app self.app = app
self.query = query self.query = query
self.query_desc = query_desc or query self.query_desc = query_desc or query
@ -124,7 +127,8 @@ class ChangeListView(urwid.WidgetWrap):
self.change_rows = {} self.change_rows = {}
self.listbox = urwid.ListBox(urwid.SimpleFocusListWalker([])) self.listbox = urwid.ListBox(urwid.SimpleFocusListWalker([]))
self.display_owner = self.display_project = self.display_updated = True self.display_owner = self.display_project = self.display_updated = True
if '_project_key' in query: self.project_key = project_key
if project_key is not None:
self.display_project = False self.display_project = False
self.sort_by = 'number' self.sort_by = 'number'
self.reverse = False self.reverse = False
@ -138,7 +142,20 @@ class ChangeListView(urwid.WidgetWrap):
self._w.contents.append((self.listbox, ('weight', 1))) self._w.contents.append((self.listbox, ('weight', 1)))
self._w.set_focus(3) self._w.set_focus(3)
def refresh(self): def refresh(self, event=None):
if event and not (('_project_key' in self.query and
isinstance(event, sync.ChangeAddedEvent) and
self.project_key == event.project_key)
or
('_project_key' not in self.query and
isinstance(event, sync.ChangeAddedEvent))
or
(isinstance(event, sync.ChangeUpdatedEvent) and
event.change_key in self.change_rows.keys())):
self.log.debug("Ignoring refresh change list due to event %s" % (event,))
return
self.log.debug("Refreshing change list due to event %s" % (event,))
unseen_keys = set(self.change_rows.keys()) unseen_keys = set(self.change_rows.keys())
with self.app.db.getSession() as session: with self.app.db.getSession() as session:
lst = session.getChanges(self.query, self.unreviewed, lst = session.getChanges(self.query, self.unreviewed,

View File

@ -20,6 +20,7 @@ import urwid
from gertty import keymap from gertty import keymap
from gertty import mywid from gertty import mywid
from gertty import gitrepo from gertty import gitrepo
from gertty import sync
class PatchsetDialog(urwid.WidgetWrap): class PatchsetDialog(urwid.WidgetWrap):
signals = ['ok', 'cancel'] signals = ['ok', 'cancel']
@ -340,9 +341,17 @@ class BaseDiffView(urwid.WidgetWrap):
def makeFileHeader(self, diff, comment_lists): def makeFileHeader(self, diff, comment_lists):
raise NotImplementedError raise NotImplementedError
def refresh(self): def refresh(self, event=None):
if event and not ((isinstance(event, sync.ChangeAddedEvent) and
self.change_key in event.related_change_keys)
or
(isinstance(event, sync.ChangeUpdatedEvent) and
self.change_key in event.related_change_keys)):
#self.log.debug("Ignoring refresh diff due to event %s" % (event,))
return
#self.log.debug("Refreshing diff due to event %s" % (event,))
#TODO #TODO
pass return
def keypress(self, size, key): def keypress(self, size, key):
old_focus = self.listbox.focus old_focus = self.listbox.focus

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import logging
import urwid import urwid
from gertty import keymap from gertty import keymap
@ -82,6 +83,7 @@ class ProjectListView(urwid.WidgetWrap):
def __init__(self, app): def __init__(self, app):
super(ProjectListView, self).__init__(urwid.Pile([])) super(ProjectListView, self).__init__(urwid.Pile([]))
self.log = logging.getLogger('gertty.view.project_list')
self.app = app self.app = app
self.unreviewed = True self.unreviewed = True
self.subscribed = True self.subscribed = True
@ -95,7 +97,17 @@ class ProjectListView(urwid.WidgetWrap):
self._w.contents.append((self.listbox, ('weight', 1))) self._w.contents.append((self.listbox, ('weight', 1)))
self._w.set_focus(3) self._w.set_focus(3)
def refresh(self): def refresh(self, event=None):
if event and not (isinstance(event, sync.ProjectAddedEvent)
or
isinstance(event, sync.ChangeAddedEvent)
or
(isinstance(event, sync.ChangeUpdatedEvent) and
(event.status_changed or event.review_flag_changed))):
self.log.debug("Ignoring refresh project list due to event %s" % (event,))
return
self.log.debug("Refreshing project list due to event %s" % (event,))
if self.subscribed: if self.subscribed:
self.title = u'Subscribed projects' self.title = u'Subscribed projects'
if self.unreviewed: if self.unreviewed:
@ -134,7 +146,7 @@ class ProjectListView(urwid.WidgetWrap):
self.app.changeScreen(view_change_list.ChangeListView( self.app.changeScreen(view_change_list.ChangeListView(
self.app, self.app,
"_project_key:%s %s" % (project_key, self.app.config.project_change_list_query), "_project_key:%s %s" % (project_key, self.app.config.project_change_list_query),
project_name, unreviewed=True)) project_name, project_key=None, unreviewed=True))
def keypress(self, size, key): def keypress(self, size, key):
r = super(ProjectListView, self).keypress(size, key) r = super(ProjectListView, self).keypress(size, key)