diff --git a/gertty/db.py b/gertty/db.py index e98ade2..773889b 100644 --- a/gertty/db.py +++ b/gertty/db.py @@ -602,6 +602,9 @@ class DatabaseSession(object): def getPendingMessages(self): return self.session().query(Message).filter_by(pending=True).all() + def getPendingTopics(self): + return self.session().query(Change).filter_by(pending_topic=True).all() + def getAccountByID(self, id, name=None, username=None, email=None): try: account = self.session().query(Account).filter_by(id=id).one() diff --git a/gertty/keymap.py b/gertty/keymap.py index 803627b..50da3d4 100644 --- a/gertty/keymap.py +++ b/gertty/keymap.py @@ -46,6 +46,7 @@ NEXT_CHANGE = 'next change' PREV_CHANGE = 'previous change' TOGGLE_HIDDEN_COMMENTS = 'toggle hidden comments' REFRESH = 'refresh' +EDIT_TOPIC = 'edit topic' # Project list screen: TOGGLE_LIST_REVIEWED = 'toggle list reviewed' TOGGLE_LIST_SUBSCRIBED = 'toggle list subscribed' @@ -83,6 +84,7 @@ DEFAULT_KEYMAP = { PREV_CHANGE: 'p', TOGGLE_HIDDEN_COMMENTS: 't', REFRESH: 'ctrl r', + EDIT_TOPIC: 'ctrl t', TOGGLE_LIST_REVIEWED: 'l', TOGGLE_LIST_SUBSCRIBED: 'L', diff --git a/gertty/sync.py b/gertty/sync.py index ec3e108..d958bd5 100644 --- a/gertty/sync.py +++ b/gertty/sync.py @@ -531,9 +531,30 @@ class UploadReviewsTask(Task): def run(self, sync): app = sync.app with app.db.getSession() as session: + for c in session.getPendingTopics(): + sync.submitTask(SetTopicTask(c.key, self.priority)) for m in session.getPendingMessages(): sync.submitTask(UploadReviewTask(m.key, self.priority)) +class SetTopicTask(Task): + def __init__(self, change_key, priority=NORMAL_PRIORITY): + super(SetTopicTask, self).__init__(priority) + self.change_key = change_key + + def __repr__(self): + return '<SetTopicTask %s>' % (self.change_key,) + + def run(self, sync): + app = sync.app + with app.db.getSession() as session: + change = session.getChange(self.change_key) + data = dict(topic=change.topic) + change.pending_topic = False + # Inside db session for rollback + sync.put('changes/%s/topic' % (change.id,), + data) + sync.submitTask(SyncChangeTask(change.id, priority=self.priority)) + class UploadReviewTask(Task): def __init__(self, message_key, priority=NORMAL_PRIORITY): super(UploadReviewTask, self).__init__(priority) @@ -667,6 +688,17 @@ class Sync(object): 'User-Agent': self.user_agent}) self.log.debug('Received: %s' % (r.text,)) + def put(self, path, data): + url = self.url(path) + self.log.debug('PUT: %s' % (url,)) + self.log.debug('data: %s' % (data,)) + r = self.session.put(url, data=json.dumps(data).encode('utf8'), + verify=self.app.config.verify_ssl, + auth=self.auth, + headers = {'Content-Type': 'application/json;charset=UTF-8', + 'User-Agent': self.user_agent}) + self.log.debug('Received: %s' % (r.text,)) + def syncSubscribedProjects(self): keys = [] with self.app.db.getSession() as session: diff --git a/gertty/view/change.py b/gertty/view/change.py index 7f5ed6c..cce3937 100644 --- a/gertty/view/change.py +++ b/gertty/view/change.py @@ -25,6 +25,31 @@ from gertty.view import side_diff as view_side_diff from gertty.view import unified_diff as view_unified_diff import gertty.view +class EditTopicDialog(mywid.ButtonDialog): + signals = ['save', 'cancel'] + def __init__(self, app, topic): + self.app = app + save_button = mywid.FixedButton('Search') + cancel_button = mywid.FixedButton('Cancel') + urwid.connect_signal(save_button, 'click', + lambda button:self._emit('save')) + urwid.connect_signal(cancel_button, 'click', + lambda button:self._emit('cancel')) + super(EditTopicDialog, self).__init__("Edit Topic", + "Edit the change topic.", + entry_prompt="Topic: ", + entry_text=topic, + buttons=[save_button, + cancel_button]) + + def keypress(self, size, key): + r = super(EditTopicDialog, self).keypress(size, key) + commands = self.app.config.keymap.getCommands(r) + if keymap.ACTIVATE in commands: + self._emit('save') + return None + return r + class ReviewDialog(urwid.WidgetWrap): signals = ['save', 'cancel'] def __init__(self, revision_row): @@ -322,6 +347,8 @@ class ChangeView(urwid.WidgetWrap): "Cherry-pick the most recent revision onto the local repo"), (key(keymap.REFRESH), "Refresh this change"), + (key(keymap.EDIT_TOPIC), + "Edit the topic of this change"), ] for k in self.app.config.reviewkeys.values(): @@ -418,6 +445,7 @@ class ChangeView(urwid.WidgetWrap): change_info = [] with self.app.db.getSession() as session: change = session.getChange(self.change_key) + self.topic = change.topic or '' if change.reviewed: reviewed = ' (reviewed)' else: @@ -435,7 +463,7 @@ class ChangeView(urwid.WidgetWrap): self.owner_label.set_text(('change-data', change.owner.name)) self.project_label.set_text(('change-data', change.project.name)) self.branch_label.set_text(('change-data', change.branch)) - self.topic_label.set_text(('change-data', change.topic or '')) + self.topic_label.set_text(('change-data', self.topic)) self.created_label.set_text(('change-data', str(change.created))) self.updated_label.set_text(('change-data', str(change.updated))) self.status_label.set_text(('change-data', change.status)) @@ -692,6 +720,9 @@ class ChangeView(urwid.WidgetWrap): sync.SyncChangeTask(self.change_rest_id, priority=sync.HIGH_PRIORITY)) self.app.status.update() return None + if keymap.EDIT_TOPIC in commands: + self.editTopic() + return None if r in self.app.config.reviewkeys: self.reviewKey(self.app.config.reviewkeys[r]) return None @@ -704,6 +735,27 @@ class ChangeView(urwid.WidgetWrap): screen = view_side_diff.SideDiffView(self.app, revision_key) self.app.changeScreen(screen) + def editTopic(self): + dialog = EditTopicDialog(self.app, self.topic) + urwid.connect_signal(dialog, 'save', + lambda button: self.closeEditTopic(dialog, True)) + urwid.connect_signal(dialog, 'cancel', + lambda button: self.closeEditTopic(dialog, False)) + self.app.popup(dialog) + + def closeEditTopic(self, dialog, save): + if save: + change_key = None + with self.app.db.getSession() as session: + change = session.getChange(self.change_key) + change.topic = dialog.entry.edit_text + change.pending_topic = True + change_key = change.key + self.app.sync.submitTask( + sync.SetTopicTask(change_key, sync.HIGH_PRIORITY)) + self.app.backScreen() + self.refresh() + def reviewKey(self, reviewkey): approvals = {} for a in reviewkey['approvals']: