summaryrefslogtreecommitdiff
path: root/pygerrit/events.py
diff options
context:
space:
mode:
Diffstat (limited to 'pygerrit/events.py')
-rw-r--r--pygerrit/events.py331
1 files changed, 331 insertions, 0 deletions
diff --git a/pygerrit/events.py b/pygerrit/events.py
new file mode 100644
index 0000000..c6563cd
--- /dev/null
+++ b/pygerrit/events.py
@@ -0,0 +1,331 @@
+# The MIT License
+#
+# Copyright 2011 Sony Ericsson Mobile Communications. All rights reserved.
+# Copyright 2012 Sony Mobile Communications. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+""" Gerrit event classes. """
+
+import json
+import logging
+
+from .error import GerritError
+from .models import Account, Approval, Change, Patchset, RefUpdate
+
+
+class GerritEventFactory(object):
+
+ """ Gerrit event factory. """
+
+ _events = {}
+
+ @classmethod
+ def register(cls, name):
+ """ Decorator to register the event identified by `name`.
+
+ Return the decorated class.
+
+ Raise GerritError if the event is already registered.
+
+ """
+
+ def decorate(klazz):
+ """ Decorator. """
+ if name in cls._events:
+ raise GerritError("Duplicate event: %s" % name)
+ cls._events[name] = [klazz.__module__, klazz.__name__]
+ klazz.name = name
+ return klazz
+ return decorate
+
+ @classmethod
+ def create(cls, data):
+ """ Create a new event instance.
+
+ 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:
+ name = 'unhandled-event'
+ event = cls._events[name]
+ module_name = event[0]
+ class_name = event[1]
+ module = __import__(module_name, fromlist=[module_name])
+ klazz = getattr(module, class_name)
+ return klazz(json_data)
+
+
+class GerritEvent(object):
+
+ """ Gerrit event base class. """
+
+ 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 __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")
+class PatchsetCreatedEvent(GerritEvent):
+
+ """ Gerrit "patchset-created" event. """
+
+ def __init__(self, json_data):
+ super(PatchsetCreatedEvent, self).__init__(json_data)
+ try:
+ self.change = Change(json_data["change"])
+ self.patchset = Patchset(json_data["patchSet"])
+ self.uploader = Account(json_data["uploader"])
+ 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):
+
+ """ Gerrit "draft-published" event. """
+
+ def __init__(self, json_data):
+ super(DraftPublishedEvent, self).__init__(json_data)
+ try:
+ self.change = Change(json_data["change"])
+ self.patchset = Patchset(json_data["patchSet"])
+ self.uploader = Account(json_data["uploader"])
+ 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):
+
+ """ Gerrit "comment-added" event. """
+
+ def __init__(self, json_data):
+ super(CommentAddedEvent, self).__init__(json_data)
+ try:
+ self.change = Change(json_data["change"])
+ self.patchset = Patchset(json_data["patchSet"])
+ self.author = Account(json_data["author"])
+ self.approvals = []
+ if "approvals" in json_data:
+ for approval in json_data["approvals"]:
+ self.approvals.append(Approval(approval))
+ self.comment = json_data["comment"]
+ 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):
+
+ """ Gerrit "change-merged" event. """
+
+ def __init__(self, json_data):
+ super(ChangeMergedEvent, self).__init__(json_data)
+ try:
+ self.change = Change(json_data["change"])
+ self.patchset = Patchset(json_data["patchSet"])
+ self.submitter = Account(json_data["submitter"])
+ 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"])
+ if 'reason' in json_data:
+ 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):
+
+ """ Gerrit "change-abandoned" event. """
+
+ def __init__(self, json_data):
+ super(ChangeAbandonedEvent, self).__init__(json_data)
+ try:
+ self.change = Change(json_data["change"])
+ self.abandoner = Account(json_data["abandoner"])
+ if 'reason' in json_data:
+ self.reason = json_data["reason"]
+ except KeyError as e:
+ raise GerritError("ChangeAbandonedEvent: %s" % e)
+
+ def __repr__(self):
+ return u"<ChangeAbandonedEvent>: %s %s" % (self.change,
+ self.abandoner)
+
+
+@GerritEventFactory.register("change-restored")
+class ChangeRestoredEvent(GerritEvent):
+
+ """ Gerrit "change-restored" event. """
+
+ def __init__(self, json_data):
+ super(ChangeRestoredEvent, self).__init__(json_data)
+ try:
+ self.change = Change(json_data["change"])
+ self.restorer = Account(json_data["restorer"])
+ if 'reason' in json_data:
+ self.reason = json_data["reason"]
+ except KeyError as e:
+ raise GerritError("ChangeRestoredEvent: %s" % e)
+
+ def __repr__(self):
+ return u"<ChangeRestoredEvent>: %s %s" % (self.change,
+ self.restorer)
+
+
+@GerritEventFactory.register("ref-updated")
+class RefUpdatedEvent(GerritEvent):
+
+ """ Gerrit "ref-updated" event. """
+
+ def __init__(self, json_data):
+ 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)