diff options
author | Ben Murdoch <benm@google.com> | 2011-05-05 14:36:32 +0100 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-05-10 15:38:30 +0100 |
commit | f05b935882198ccf7d81675736e3aeb089c5113a (patch) | |
tree | 4ea0ca838d9ef1b15cf17ddb3928efb427c7e5a1 /Tools/QueueStatusServer/handlers | |
parent | 60fbdcc62bced8db2cb1fd233cc4d1e4ea17db1b (diff) | |
download | external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.zip external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.tar.gz external_webkit-f05b935882198ccf7d81675736e3aeb089c5113a.tar.bz2 |
Merge WebKit at r74534: Initial merge by git.
Change-Id: I6ccd1154fa1b19c2ec2a66878eb675738735f1eb
Diffstat (limited to 'Tools/QueueStatusServer/handlers')
19 files changed, 1045 insertions, 0 deletions
diff --git a/Tools/QueueStatusServer/handlers/__init__.py b/Tools/QueueStatusServer/handlers/__init__.py new file mode 100644 index 0000000..296e173 --- /dev/null +++ b/Tools/QueueStatusServer/handlers/__init__.py @@ -0,0 +1,3 @@ +# Required for Python to search this directory for module files + +from handlers.updatebase import UpdateBase diff --git a/Tools/QueueStatusServer/handlers/dashboard.py b/Tools/QueueStatusServer/handlers/dashboard.py new file mode 100644 index 0000000..660c595 --- /dev/null +++ b/Tools/QueueStatusServer/handlers/dashboard.py @@ -0,0 +1,64 @@ +# Copyright (C) 2009 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import operator + +from google.appengine.ext import webapp +from google.appengine.ext.webapp import template + +from model.attachment import Attachment +from model.queues import Queue + + +class Dashboard(webapp.RequestHandler): + # We may want to sort these? + _ordered_queues = Queue.all() + _header_names = [queue.short_name() for queue in _ordered_queues] + + def _build_bubble(self, attachment, queue): + queue_status = attachment.status_for_queue(queue) + bubble = { + "status_class": attachment.state_from_queue_status(queue_status) if queue_status else "none", + "status_date": queue_status.date if queue_status else None, + } + return bubble + + def _build_row(self, attachment): + row = { + "bug_id": attachment.bug_id(), + "attachment_id": attachment.id, + "bubbles": [self._build_bubble(attachment, queue) for queue in self._ordered_queues], + } + return row + + def get(self): + template_values = { + "headers": self._header_names, + "rows": [self._build_row(attachment) for attachment in Attachment.recent(limit=25)], + } + self.response.out.write(template.render("templates/dashboard.html", template_values)) diff --git a/Tools/QueueStatusServer/handlers/gc.py b/Tools/QueueStatusServer/handlers/gc.py new file mode 100644 index 0000000..d04ee4d --- /dev/null +++ b/Tools/QueueStatusServer/handlers/gc.py @@ -0,0 +1,44 @@ +# Copyright (C) 2009 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from google.appengine.ext import webapp + +from model.queuestatus import QueueStatus + + +class GC(webapp.RequestHandler): + def get(self): + statuses = QueueStatus.all().order("-date") + seen_queues = set() + for status in statuses: + if status.active_patch_id or status.active_bug_id: + continue + if status.queue_name in seen_queues: + status.delete() + seen_queues.add(status.queue_name) + self.response.out.write("Done!") diff --git a/Tools/QueueStatusServer/handlers/nextpatch.py b/Tools/QueueStatusServer/handlers/nextpatch.py new file mode 100644 index 0000000..5f6d71d --- /dev/null +++ b/Tools/QueueStatusServer/handlers/nextpatch.py @@ -0,0 +1,59 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from datetime import datetime + +from google.appengine.ext import db +from google.appengine.ext import webapp + +from model.queues import Queue + + +class NextPatch(webapp.RequestHandler): + # FIXME: This should probably be a post, or an explict lock_patch + # since GET requests shouldn't really modify the datastore. + def get(self, queue_name): + queue = Queue.queue_with_name(queue_name) + if not queue: + self.error(404) + return + # FIXME: Patch assignment should probably move into Queue. + patch_id = db.run_in_transaction(self._assign_patch, queue.active_work_items().key(), queue.work_items().item_ids) + if not patch_id: + self.error(404) + return + self.response.out.write(patch_id) + + @staticmethod + def _assign_patch(key, work_item_ids): + now = datetime.now() + active_work_items = db.get(key) + active_work_items.deactivate_expired(now) + next_item = active_work_items.next_item(work_item_ids, now) + active_work_items.put() + return next_item diff --git a/Tools/QueueStatusServer/handlers/patch.py b/Tools/QueueStatusServer/handlers/patch.py new file mode 100644 index 0000000..3219212 --- /dev/null +++ b/Tools/QueueStatusServer/handlers/patch.py @@ -0,0 +1,53 @@ +# Copyright (C) 2009 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from google.appengine.ext import webapp +from google.appengine.ext.webapp import template + +from model.queuestatus import QueueStatus + + +class Patch(webapp.RequestHandler): + def get(self, attachment_id_string): + attachment_id = int(attachment_id_string) + statuses = QueueStatus.all().filter("active_patch_id =", attachment_id).order("-date") + + bug_id = None + queue_status = {} + for status in statuses: + bug_id = status.active_bug_id # Should be the same for every status. + per_queue_statuses = queue_status.get(status.queue_name, []) + per_queue_statuses.append(status) + queue_status[status.queue_name] = per_queue_statuses + + template_values = { + "attachment_id" : attachment_id, + "bug_id" : bug_id, + "queue_status" : queue_status, + } + self.response.out.write(template.render("templates/patch.html", template_values)) diff --git a/Tools/QueueStatusServer/handlers/patchstatus.py b/Tools/QueueStatusServer/handlers/patchstatus.py new file mode 100644 index 0000000..1a5422e --- /dev/null +++ b/Tools/QueueStatusServer/handlers/patchstatus.py @@ -0,0 +1,40 @@ +# Copyright (C) 2009 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from google.appengine.ext import webapp + +from model.queuestatus import QueueStatus + + +class PatchStatus(webapp.RequestHandler): + def get(self, queue_name, attachment_id): + statuses = QueueStatus.all().filter('queue_name =', queue_name).filter('active_patch_id =', int(attachment_id)).order('-date').fetch(1) + if not statuses: + self.error(404) + return + self.response.out.write(statuses[0].message) diff --git a/Tools/QueueStatusServer/handlers/queuestatus.py b/Tools/QueueStatusServer/handlers/queuestatus.py new file mode 100644 index 0000000..54c0fdd --- /dev/null +++ b/Tools/QueueStatusServer/handlers/queuestatus.py @@ -0,0 +1,72 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import itertools + +from google.appengine.ext import webapp +from google.appengine.ext.webapp import template + +from model.queues import Queue +from model import queuestatus + + +class QueueStatus(webapp.RequestHandler): + def _rows_for_work_items(self, queue): + queued_items = queue.work_items() + active_items = queue.active_work_items() + if not queued_items: + return [] + rows = [] + for item_id in queued_items.item_ids: + rows.append({ + "attachment_id": item_id, + "bug_id": 1, + "lock_time": active_items and active_items.time_for_item(item_id), + }) + return rows + + def _grouping_key_for_status(self, status): + return "%s-%s" % (status.active_patch_id, status.bot_id) + + def _build_status_groups(self, statuses): + return [list(group) for key, group in itertools.groupby(statuses, self._grouping_key_for_status)] + + def get(self, queue_name): + queue_name = queue_name.lower() + queue = Queue.queue_with_name(queue_name) + if not queue: + self.error(404) + return + + statuses = queuestatus.QueueStatus.all().filter("queue_name =", queue.name()).order("-date").fetch(15) + template_values = { + "display_queue_name": queue.display_name(), + "work_item_rows": self._rows_for_work_items(queue), + "status_groups": self._build_status_groups(statuses), + } + self.response.out.write(template.render("templates/queuestatus.html", template_values)) diff --git a/Tools/QueueStatusServer/handlers/queuestatus_unittest.py b/Tools/QueueStatusServer/handlers/queuestatus_unittest.py new file mode 100644 index 0000000..a5ae844 --- /dev/null +++ b/Tools/QueueStatusServer/handlers/queuestatus_unittest.py @@ -0,0 +1,62 @@ +# Copyright (C) 2010 Google, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Research in Motion Ltd. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import unittest + +from handlers.queuestatus import QueueStatus +from model.queues import Queue + + +class MockStatus(object): + def __init__(self, patch_id, bot_id): + self.active_patch_id = patch_id + self.bot_id = bot_id + + +class QueueStatusTest(unittest.TestCase): + def test_build_status_groups(self): + queue_status = QueueStatus() + statuses = [ + MockStatus(1, "foo"), + MockStatus(1, "foo"), + MockStatus(2, "foo"), + MockStatus(1, "foo"), + MockStatus(1, "bar"), + MockStatus(1, "foo"), + ] + groups = queue_status._build_status_groups(statuses) + self.assertEqual(len(groups), 5) + self.assertEqual(groups[0], statuses[0:2]) + self.assertEqual(groups[1], statuses[2:3]) + self.assertEqual(groups[2], statuses[3:4]) + self.assertEqual(groups[3], statuses[4:5]) + self.assertEqual(groups[4], statuses[5:6]) + + +if __name__ == '__main__': + unittest.main() diff --git a/Tools/QueueStatusServer/handlers/recentstatus.py b/Tools/QueueStatusServer/handlers/recentstatus.py new file mode 100644 index 0000000..fddc93a --- /dev/null +++ b/Tools/QueueStatusServer/handlers/recentstatus.py @@ -0,0 +1,94 @@ +# Copyright (C) 2009 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import datetime + +from google.appengine.ext import webapp +from google.appengine.ext.webapp import template + +from model.queues import Queue +from model.queuestatus import QueueStatus +from model.workitems import WorkItems + + +class QueueBubble(object): + """View support class for recentstatus.html""" + def __init__(self, queue): + self._queue = queue + self._work_items = queue.work_items() + self._last_status = QueueStatus.all().filter("queue_name =", queue.name()).order("-date").get() + + # FIXME: name and display_name should be replaced by a .queue() accessor. + def name(self): + return self._queue.name() + + def display_name(self): + return self._queue.display_name() + + def _last_status_date(self): + if not self._last_status: + return None + return self._last_status.date + + def last_heard_from(self): + if not self._work_items: + return self._last_status_date() + return max(self._last_status_date(), self._work_items.date) + + def is_alive(self): + if not self.last_heard_from(): + return False + return self.last_heard_from() > (datetime.datetime.now() - datetime.timedelta(minutes=30)) + + def status_class(self): + if not self.is_alive(): + return "dead" + if self.pending_items_count() > 1: + return "behind" + return "alive" + + def status_text(self): + if not self._work_items: + return "Offline" + if not self._work_items.item_ids: + return "Idle" + return self._last_status.message + + def pending_items_count(self): + if not self._work_items: + return 0 + return len(self._work_items.item_ids) + + +class QueuesOverview(webapp.RequestHandler): + + def get(self): + template_values = { + "queues": [QueueBubble(queue) for queue in Queue.all()], + } + self.response.out.write(template.render("templates/recentstatus.html", template_values)) diff --git a/Tools/QueueStatusServer/handlers/releasepatch.py b/Tools/QueueStatusServer/handlers/releasepatch.py new file mode 100644 index 0000000..0e46e69 --- /dev/null +++ b/Tools/QueueStatusServer/handlers/releasepatch.py @@ -0,0 +1,62 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from google.appengine.ext import webapp, db +from google.appengine.ext.webapp import template + +from handlers.updatebase import UpdateBase +from model.attachment import Attachment +from model.queues import Queue + + +class ReleasePatch(UpdateBase): + def get(self): + self.response.out.write(template.render("templates/releasepatch.html", None)) + + def post(self): + queue_name = self.request.get("queue_name") + # FIXME: This queue lookup should be shared between handlers. + queue = Queue.queue_with_name(queue_name) + if not queue: + self.error(404) + return + + attachment_id = self._int_from_request("attachment_id") + attachment = Attachment(attachment_id) + last_status = attachment.status_for_queue(queue) + + # Ideally we should use a transaction for the calls to + # WorkItems and ActiveWorkItems. + + # Only remove it from the queue if the last message is not a retry request. + # Allow removing it from the queue even if there is no last_status for easier testing. + if not last_status or not last_status.is_retry_request(): + queue.work_items().remove_work_item(attachment_id) + + # Always release the lock on the item. + queue.active_work_items().expire_item(attachment_id) diff --git a/Tools/QueueStatusServer/handlers/showresults.py b/Tools/QueueStatusServer/handlers/showresults.py new file mode 100644 index 0000000..e4cb71b --- /dev/null +++ b/Tools/QueueStatusServer/handlers/showresults.py @@ -0,0 +1,41 @@ +# Copyright (C) 2009 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from google.appengine.ext import webapp + +from model.queuestatus import QueueStatus + + +class ShowResults(webapp.RequestHandler): + def get(self, status_id): + status = QueueStatus.get_by_id(int(status_id)) + if not status: + self.error(404) + return + self.response.headers["Content-Type"] = "text/plain; charset=utf-8" + self.response.out.write(status.results_file) diff --git a/Tools/QueueStatusServer/handlers/statusbubble.py b/Tools/QueueStatusServer/handlers/statusbubble.py new file mode 100644 index 0000000..5690484 --- /dev/null +++ b/Tools/QueueStatusServer/handlers/statusbubble.py @@ -0,0 +1,59 @@ +# Copyright (C) 2009 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import operator + +from google.appengine.ext import webapp +from google.appengine.ext.webapp import template + +from model.attachment import Attachment +from model.workitems import WorkItems +from model.queues import Queue + + +class StatusBubble(webapp.RequestHandler): + _queues_to_display = [queue for queue in Queue.all() if queue.is_ews()] + + def _build_bubble(self, queue, attachment): + queue_status = attachment.status_for_queue(queue) + bubble = { + "name": queue.short_name().lower(), + "attachment_id": attachment.id, + "queue_position": attachment.position_in_queue(queue), + "state": attachment.state_from_queue_status(queue_status) if queue_status else "none", + "status": queue_status, + } + return bubble + + def get(self, attachment_id): + attachment = Attachment(int(attachment_id)) + bubbles = [self._build_bubble(queue, attachment) for queue in self._queues_to_display] + template_values = { + "bubbles": bubbles, + } + self.response.out.write(template.render("templates/statusbubble.html", template_values)) diff --git a/Tools/QueueStatusServer/handlers/statusbubble_unittest.py b/Tools/QueueStatusServer/handlers/statusbubble_unittest.py new file mode 100644 index 0000000..3ffbdaf --- /dev/null +++ b/Tools/QueueStatusServer/handlers/statusbubble_unittest.py @@ -0,0 +1,62 @@ +# Copyright (C) 2010 Google, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Research in Motion Ltd. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import unittest + + +from handlers.statusbubble import StatusBubble +from model.queues import Queue + + +class MockAttachment(object): + def __init__(self): + self.id = 1 + + def status_for_queue(self, queue): + return None + + def position_in_queue(self, queue): + return 1 + + +class StatusBubbleTest(unittest.TestCase): + def test_build_bubble(self): + bubble = StatusBubble() + queue = Queue("mac-ews") + attachment = MockAttachment() + bubble_dict = bubble._build_bubble(queue, attachment) + # FIXME: assertDictEqual (in Python 2.7) would be better to use here. + self.assertEqual(bubble_dict["name"], "mac") + self.assertEqual(bubble_dict["attachment_id"], 1) + self.assertEqual(bubble_dict["queue_position"], 1) + self.assertEqual(bubble_dict["state"], "none") + self.assertEqual(bubble_dict["status"], None) + + +if __name__ == '__main__': + unittest.main() diff --git a/Tools/QueueStatusServer/handlers/submittoews.py b/Tools/QueueStatusServer/handlers/submittoews.py new file mode 100644 index 0000000..3ba4373 --- /dev/null +++ b/Tools/QueueStatusServer/handlers/submittoews.py @@ -0,0 +1,64 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from google.appengine.ext import webapp, db +from google.appengine.ext.webapp import template + +from handlers.updatebase import UpdateBase +from model.attachment import Attachment +from model.queues import Queue + + +class SubmitToEWS(UpdateBase): + def get(self): + self.response.out.write(template.render("templates/submittoews.html", None)) + + def _should_add_to_ews_queue(self, queue, attachment): + # This assert() is here to make sure we're not submitting to the commit-queue. + # The commit-queue clients check each patch anyway, but there is not sense + # in adding things to the commit-queue when they won't be processed by it. + assert(queue.is_ews()) + latest_status = attachment.status_for_queue(queue) + if not latest_status: + return True + # Only ever re-submit to the EWS if the EWS specifically requested a retry. + # This allows us to restart the EWS feeder queue, without all r? patches + # being retried as a result of that restart! + # In some future version we might add a "force" button to allow the user + # to override this restriction. + return latest_status.is_retry_request() + + def _add_attachment_to_ews_queues(self, attachment): + for queue in Queue.all_ews(): # all_ews() currently includes the style-queue + if self._should_add_to_ews_queue(queue, attachment): + queue.work_items().add_work_item(attachment.id) + + def post(self): + attachment_id = self._int_from_request("attachment_id") + attachment = Attachment(attachment_id) + self._add_attachment_to_ews_queues(attachment) diff --git a/Tools/QueueStatusServer/handlers/svnrevision.py b/Tools/QueueStatusServer/handlers/svnrevision.py new file mode 100644 index 0000000..36eab33 --- /dev/null +++ b/Tools/QueueStatusServer/handlers/svnrevision.py @@ -0,0 +1,40 @@ +# Copyright (C) 2009 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from google.appengine.ext import webapp + +import model + + +class SVNRevision(webapp.RequestHandler): + def get(self, svn_revision_number): + svn_revisions = model.SVNRevision.all().filter('number =', int(svn_revision_number)).order('-date').fetch(1) + if not svn_revisions: + self.error(404) + return + self.response.out.write(svn_revisions[0].to_xml()) diff --git a/Tools/QueueStatusServer/handlers/updatebase.py b/Tools/QueueStatusServer/handlers/updatebase.py new file mode 100644 index 0000000..b087e83 --- /dev/null +++ b/Tools/QueueStatusServer/handlers/updatebase.py @@ -0,0 +1,41 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from google.appengine.api import users +from google.appengine.ext import webapp, db + + +class UpdateBase(webapp.RequestHandler): + def _int_from_request(self, name): + string_value = self.request.get(name) + try: + int_value = int(string_value) + return int_value + except ValueError, TypeError: + pass + return None diff --git a/Tools/QueueStatusServer/handlers/updatestatus.py b/Tools/QueueStatusServer/handlers/updatestatus.py new file mode 100644 index 0000000..7301101 --- /dev/null +++ b/Tools/QueueStatusServer/handlers/updatestatus.py @@ -0,0 +1,66 @@ +# Copyright (C) 2009 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from google.appengine.api import users +from google.appengine.ext import webapp, db +from google.appengine.ext.webapp import template + +from handlers.updatebase import UpdateBase +from model.attachment import Attachment +from model.queuestatus import QueueStatus + + +class UpdateStatus(UpdateBase): + def get(self): + self.response.out.write(template.render("templates/updatestatus.html", None)) + + def _queue_status_from_request(self): + queue_status = QueueStatus() + + # FIXME: I think this can be removed, no one uses it. + if users.get_current_user(): + queue_status.author = users.get_current_user() + + bug_id = self._int_from_request("bug_id") + patch_id = self._int_from_request("patch_id") + queue_name = self.request.get("queue_name") + bot_id = self.request.get("bot_id") + queue_status.queue_name = queue_name + queue_status.bot_id = bot_id + queue_status.active_bug_id = bug_id + queue_status.active_patch_id = patch_id + queue_status.message = self.request.get("status") + results_file = self.request.get("results_file") + queue_status.results_file = db.Blob(str(results_file)) + return queue_status + + def post(self): + queue_status = self._queue_status_from_request() + queue_status.put() + Attachment.dirty(queue_status.active_patch_id) + self.response.out.write(queue_status.key().id()) diff --git a/Tools/QueueStatusServer/handlers/updatesvnrevision.py b/Tools/QueueStatusServer/handlers/updatesvnrevision.py new file mode 100644 index 0000000..075982a --- /dev/null +++ b/Tools/QueueStatusServer/handlers/updatesvnrevision.py @@ -0,0 +1,53 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from google.appengine.ext import webapp, db +from google.appengine.ext.webapp import template + +import handlers +import model + + +class UpdateSVNRevision(handlers.UpdateBase): + def get(self): + self.response.out.write(template.render("templates/updatesvnrevision.html", None)) + + def post(self): + svn_revision_number = self._int_from_request("number") + + svn_revisions = model.SVNRevision.all().filter('number =', svn_revision_number).order('-date').fetch(1) + svn_revision = None + if svn_revisions: + svn_revision = svn_revisions[0] + else: + svn_revision = model.SVNRevision() + svn_revision.number = svn_revision_number + svn_revision.broken_bots.append(self.request.get("broken_bot")) + svn_revision.put() + + self.response.out.write(svn_revision.key().id()) diff --git a/Tools/QueueStatusServer/handlers/updateworkitems.py b/Tools/QueueStatusServer/handlers/updateworkitems.py new file mode 100644 index 0000000..16a9d49 --- /dev/null +++ b/Tools/QueueStatusServer/handlers/updateworkitems.py @@ -0,0 +1,66 @@ +# Copyright (C) 2010 Google Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from google.appengine.ext import webapp, db +from google.appengine.ext.webapp import template + +from handlers.updatebase import UpdateBase +from model.queues import Queue +from model.workitems import WorkItems + +from datetime import datetime + + +class UpdateWorkItems(UpdateBase): + def get(self): + self.response.out.write(template.render("templates/updateworkitems.html", None)) + + def _parse_work_items_string(self, items_string): + # Our parsing could be much more robust. + item_strings = items_string.split(" ") if items_string else [] + return map(int, item_strings) + + def _work_items_from_request(self): + queue_name = self.request.get("queue_name") + queue = Queue.queue_with_name(queue_name) + if not queue: + self.response.out.write("\"%s\" is not in queues %s" % (queue_name, Queue.all())) + return None + + items_string = self.request.get("work_items") + work_items = queue.work_items() + work_items.item_ids = self._parse_work_items_string(items_string) + work_items.date = datetime.now() + return work_items + + def post(self): + work_items = self._work_items_from_request() + if not work_items: + self.response.set_status(500) + return + work_items.put() |