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 logging
import os
import Queue
import sys
import threading
import webbrowser
@ -227,7 +228,12 @@ class App(object):
widget = self.loop.widget
while isinstance(widget, urwid.Overlay):
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,
relative_width=50, relative_height=25,

View File

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

View File

@ -14,6 +14,7 @@
# under the License.
import datetime
import logging
import urwid
@ -415,6 +416,7 @@ class ChangeView(urwid.WidgetWrap):
def __init__(self, app, change_key):
super(ChangeView, self).__init__(urwid.Pile([]))
self.log = logging.getLogger('gertty.view.change')
self.app = app
self.change_key = change_key
self.revision_rows = {}
@ -497,7 +499,15 @@ class ChangeView(urwid.WidgetWrap):
if not succeeded:
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 = []
with self.app.db.getSession() as session:
change = session.getChange(self.change_key)

View File

@ -14,6 +14,7 @@
# under the License.
import datetime
import logging
import urwid
from gertty import keymap
@ -115,8 +116,10 @@ class ChangeListView(urwid.WidgetWrap):
"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([]))
self.log = logging.getLogger('gertty.view.change_list')
self.app = app
self.query = query
self.query_desc = query_desc or query
@ -124,7 +127,8 @@ class ChangeListView(urwid.WidgetWrap):
self.change_rows = {}
self.listbox = urwid.ListBox(urwid.SimpleFocusListWalker([]))
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.sort_by = 'number'
self.reverse = False
@ -138,7 +142,20 @@ class ChangeListView(urwid.WidgetWrap):
self._w.contents.append((self.listbox, ('weight', 1)))
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())
with self.app.db.getSession() as session:
lst = session.getChanges(self.query, self.unreviewed,

View File

@ -20,6 +20,7 @@ import urwid
from gertty import keymap
from gertty import mywid
from gertty import gitrepo
from gertty import sync
class PatchsetDialog(urwid.WidgetWrap):
signals = ['ok', 'cancel']
@ -340,9 +341,17 @@ class BaseDiffView(urwid.WidgetWrap):
def makeFileHeader(self, diff, comment_lists):
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
pass
return
def keypress(self, size, key):
old_focus = self.listbox.focus

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
import logging
import urwid
from gertty import keymap
@ -82,6 +83,7 @@ class ProjectListView(urwid.WidgetWrap):
def __init__(self, app):
super(ProjectListView, self).__init__(urwid.Pile([]))
self.log = logging.getLogger('gertty.view.project_list')
self.app = app
self.unreviewed = True
self.subscribed = True
@ -95,7 +97,17 @@ class ProjectListView(urwid.WidgetWrap):
self._w.contents.append((self.listbox, ('weight', 1)))
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:
self.title = u'Subscribed projects'
if self.unreviewed:
@ -134,7 +146,7 @@ class ProjectListView(urwid.WidgetWrap):
self.app.changeScreen(view_change_list.ChangeListView(
self.app,
"_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):
r = super(ProjectListView, self).keypress(size, key)