diff options
| author | David Pursehouse <david.pursehouse@sonymobile.com> | 2013-09-13 19:03:24 +0900 |
|---|---|---|
| committer | David Pursehouse <david.pursehouse@sonymobile.com> | 2013-09-13 19:03:37 +0900 |
| commit | 87b68fc2db307fe4e294abd913bcee80ecb9cb7f (patch) | |
| tree | 70f1f534633cb128c780cc1b29ef685fe255798e /pygerrit/events.py | |
| parent | 8571778ed4ebd1ebacba2334d8b6b19fbcd5a2b9 (diff) | |
| parent | ae41ccac316c6bd45ec4af0146219212bbb08c87 (diff) | |
| download | pygerrit-87b68fc2db307fe4e294abd913bcee80ecb9cb7f.tar.gz | |
Merge branch 'master' into internal
* master:
Bump version to 0.1.1
Add changelog
Fix #10: Allow to manually specify ssh username and port
Completely refactor the stream event handling
Add missing __repr__ methods on ErrorEvent and UnhandledEvent
Fix initialisation of error event
Fix #11: correct handling of `identityfile` in the ssh config
Allow example script to continue if errors are received
Fix #9: Add a bit more detail in the documentation
Fix #8: Support the "topic-changed" stream event
Fix #7: Support the "reviewer-added" stream event
Fix #6: Support the "merge-failed" stream event
Fix #5: Move json parsing and error handling into the event factory
Improved logging in the example script
Fix #3: Don't treat unhandled event types as errors
Fix #4: Keep event's raw json data in the event object
Add __repr__ methods on event and model classes
Remove redundant `exec_command` method
Fix #2: Establish SSH connection in a thread-safe way
Fix #1: Use select.select() instead of select.poll()
Change-Id: Ib91384b16acca30bfc5aadcdc1131c8bdecef583
Diffstat (limited to 'pygerrit/events.py')
| -rw-r--r-- | pygerrit/events.py | 168 |
1 files changed, 152 insertions, 16 deletions
diff --git a/pygerrit/events.py b/pygerrit/events.py index 8a5c21f..ebbb327 100644 --- a/pygerrit/events.py +++ b/pygerrit/events.py @@ -23,6 +23,9 @@ """ Gerrit event classes. """ +import json +import logging + from .error import GerritError from .models import Account, Approval, Change, Patchset, RefUpdate @@ -53,19 +56,27 @@ class GerritEventFactory(object): return decorate @classmethod - def create(cls, json_data): + def create(cls, data): """ Create a new event instance. - Return an instance of the `GerritEvent` subclass from `json_data` - Raise GerritError if `json_data` does not contain a `type` key, or - no corresponding event is registered. + Return an instance of the `GerritEvent` subclass after converting + `data` to json. + + Raise GerritError if json parsed from `data` does not contain a `type` + key. """ + try: + json_data = json.loads(data) + except ValueError as err: + logging.debug("Failed to load json data: %s: [%s]", str(err), data) + json_data = json.loads(ErrorEvent.error_json(err)) + if not "type" in json_data: raise GerritError("`type` not in json_data") name = json_data["type"] if not name in cls._events: - raise GerritError("Unknown event: %s" % name) + name = 'unhandled-event' event = cls._events[name] module_name = event[0] class_name = event[1] @@ -78,11 +89,39 @@ class GerritEvent(object): """ Gerrit event base class. """ - def __init__(self): - pass + def __init__(self, json_data): + self.json = json_data + + +@GerritEventFactory.register("unhandled-event") +class UnhandledEvent(GerritEvent): + + """ Unknown event type received in json data from Gerrit's event stream. """ + + def __init__(self, json_data): + super(UnhandledEvent, self).__init__(json_data) + + def __repr__(self): + return u"<UnhandledEvent>" + + +@GerritEventFactory.register("error-event") +class ErrorEvent(GerritEvent): + + """ Error occurred when processing json data from Gerrit's event stream. """ - def __str__(self): - return u"%s" % self.name # pylint: disable=no-member + def __init__(self, json_data): + super(ErrorEvent, self).__init__(json_data) + self.error = json_data["error"] + + @classmethod + def error_json(cls, error): + """ Return a json string for the `error`. """ + return '{"type":"error-event",' \ + '"error":"%s"}' % str(error) + + def __repr__(self): + return u"<ErrorEvent: %s>" % self.error @GerritEventFactory.register("patchset-created") @@ -91,7 +130,7 @@ class PatchsetCreatedEvent(GerritEvent): """ Gerrit "patchset-created" event. """ def __init__(self, json_data): - super(PatchsetCreatedEvent, self).__init__() + super(PatchsetCreatedEvent, self).__init__(json_data) try: self.change = Change(json_data["change"]) self.patchset = Patchset(json_data["patchSet"]) @@ -99,6 +138,11 @@ class PatchsetCreatedEvent(GerritEvent): except KeyError as e: raise GerritError("PatchsetCreatedEvent: %s" % e) + def __repr__(self): + return u"<PatchsetCreatedEvent>: %s %s %s" % (self.change, + self.patchset, + self.uploader) + @GerritEventFactory.register("draft-published") class DraftPublishedEvent(GerritEvent): @@ -106,7 +150,7 @@ class DraftPublishedEvent(GerritEvent): """ Gerrit "draft-published" event. """ def __init__(self, json_data): - super(DraftPublishedEvent, self).__init__() + super(DraftPublishedEvent, self).__init__(json_data) try: self.change = Change(json_data["change"]) self.patchset = Patchset(json_data["patchSet"]) @@ -114,6 +158,11 @@ class DraftPublishedEvent(GerritEvent): except KeyError as e: raise GerritError("DraftPublishedEvent: %s" % e) + def __repr__(self): + return u"<DraftPublishedEvent>: %s %s %s" % (self.change, + self.patchset, + self.uploader) + @GerritEventFactory.register("comment-added") class CommentAddedEvent(GerritEvent): @@ -121,7 +170,7 @@ class CommentAddedEvent(GerritEvent): """ Gerrit "comment-added" event. """ def __init__(self, json_data): - super(CommentAddedEvent, self).__init__() + super(CommentAddedEvent, self).__init__(json_data) try: self.change = Change(json_data["change"]) self.patchset = Patchset(json_data["patchSet"]) @@ -134,6 +183,11 @@ class CommentAddedEvent(GerritEvent): except (KeyError, ValueError) as e: raise GerritError("CommentAddedEvent: %s" % e) + def __repr__(self): + return u"<CommentAddedEvent>: %s %s %s" % (self.change, + self.patchset, + self.author) + @GerritEventFactory.register("change-merged") class ChangeMergedEvent(GerritEvent): @@ -141,7 +195,7 @@ class ChangeMergedEvent(GerritEvent): """ Gerrit "change-merged" event. """ def __init__(self, json_data): - super(ChangeMergedEvent, self).__init__() + super(ChangeMergedEvent, self).__init__(json_data) try: self.change = Change(json_data["change"]) self.patchset = Patchset(json_data["patchSet"]) @@ -149,6 +203,32 @@ class ChangeMergedEvent(GerritEvent): except KeyError as e: raise GerritError("ChangeMergedEvent: %s" % e) + def __repr__(self): + return u"<ChangeMergedEvent>: %s %s %s" % (self.change, + self.patchset, + self.submitter) + + +@GerritEventFactory.register("merge-failed") +class MergeFailedEvent(GerritEvent): + + """ Gerrit "merge-failed" event. """ + + def __init__(self, json_data): + super(MergeFailedEvent, self).__init__(json_data) + try: + self.change = Change(json_data["change"]) + self.patchset = Patchset(json_data["patchSet"]) + self.submitter = Account(json_data["submitter"]) + self.reason = json_data["reason"] + except KeyError as e: + raise GerritError("MergeFailedEvent: %s" % e) + + def __repr__(self): + return u"<MergeFailedEvent>: %s %s %s" % (self.change, + self.patchset, + self.submitter) + @GerritEventFactory.register("change-abandoned") class ChangeAbandonedEvent(GerritEvent): @@ -156,7 +236,7 @@ class ChangeAbandonedEvent(GerritEvent): """ Gerrit "change-abandoned" event. """ def __init__(self, json_data): - super(ChangeAbandonedEvent, self).__init__() + super(ChangeAbandonedEvent, self).__init__(json_data) try: self.change = Change(json_data["change"]) self.patchset = Patchset.from_json(json_data) @@ -165,6 +245,11 @@ class ChangeAbandonedEvent(GerritEvent): except KeyError as e: raise GerritError("ChangeAbandonedEvent: %s" % e) + def __repr__(self): + return u"<ChangeAbandonedEvent>: %s %s %s" % (self.change, + self.patchset, + self.abandoner) + @GerritEventFactory.register("change-restored") class ChangeRestoredEvent(GerritEvent): @@ -172,7 +257,7 @@ class ChangeRestoredEvent(GerritEvent): """ Gerrit "change-restored" event. """ def __init__(self, json_data): - super(ChangeRestoredEvent, self).__init__() + super(ChangeRestoredEvent, self).__init__(json_data) try: self.change = Change(json_data["change"]) self.patchset = Patchset.from_json(json_data) @@ -181,6 +266,11 @@ class ChangeRestoredEvent(GerritEvent): except KeyError as e: raise GerritError("ChangeRestoredEvent: %s" % e) + def __repr__(self): + return u"<ChangeRestoredEvent>: %s %s %s" % (self.change, + self.patchset, + self.restorer) + @GerritEventFactory.register("ref-updated") class RefUpdatedEvent(GerritEvent): @@ -188,9 +278,55 @@ class RefUpdatedEvent(GerritEvent): """ Gerrit "ref-updated" event. """ def __init__(self, json_data): - super(RefUpdatedEvent, self).__init__() + super(RefUpdatedEvent, self).__init__(json_data) try: self.ref_update = RefUpdate(json_data["refUpdate"]) self.submitter = Account.from_json(json_data, "submitter") except KeyError as e: raise GerritError("RefUpdatedEvent: %s" % e) + + def __repr__(self): + return u"<RefUpdatedEvent>: %s %s" % (self.ref_update, self.submitter) + + +@GerritEventFactory.register("reviewer-added") +class ReviewerAddedEvent(GerritEvent): + + """ Gerrit "reviewer-added" event. """ + + def __init__(self, json_data): + super(ReviewerAddedEvent, self).__init__(json_data) + try: + self.change = Change(json_data["change"]) + self.patchset = Patchset.from_json(json_data) + self.reviewer = Account(json_data["reviewer"]) + except KeyError as e: + raise GerritError("ReviewerAddedEvent: %s" % e) + + def __repr__(self): + return u"<ReviewerAddedEvent>: %s %s %s" % (self.change, + self.patchset, + self.reviewer) + + +@GerritEventFactory.register("topic-changed") +class TopicChangedEvent(GerritEvent): + + """ Gerrit "topic-changed" event. """ + + def __init__(self, json_data): + super(TopicChangedEvent, self).__init__(json_data) + try: + self.change = Change(json_data["change"]) + self.changer = Account(json_data["changer"]) + if "oldTopic" in json_data: + self.oldtopic = json_data["oldTopic"] + else: + self.oldtopic = "" + except KeyError as e: + raise GerritError("TopicChangedEvent: %s" % e) + + def __repr__(self): + return u"<TopicChangedEvent>: %s %s [%s]" % (self.change, + self.changer, + self.oldtopic) |
