Merge "Selectively refresh screen"
This commit is contained in:
commit
428ef2d029
@ -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,
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user