diff options
Diffstat (limited to 'WebKitTools/QueueStatusServer')
| -rw-r--r-- | WebKitTools/QueueStatusServer/app.yaml | 11 | ||||
| -rw-r--r-- | WebKitTools/QueueStatusServer/filters/__init__.py | 1 | ||||
| -rw-r--r-- | WebKitTools/QueueStatusServer/filters/webkit_extras.py | 44 | ||||
| -rw-r--r-- | WebKitTools/QueueStatusServer/index.html | 29 | ||||
| -rw-r--r-- | WebKitTools/QueueStatusServer/index.yaml | 24 | ||||
| -rw-r--r-- | WebKitTools/QueueStatusServer/queue_status.py | 177 | ||||
| -rw-r--r-- | WebKitTools/QueueStatusServer/status_bubble.html | 36 | ||||
| -rw-r--r-- | WebKitTools/QueueStatusServer/stylesheets/main.css | 26 | ||||
| -rw-r--r-- | WebKitTools/QueueStatusServer/update_status.html | 17 |
9 files changed, 365 insertions, 0 deletions
diff --git a/WebKitTools/QueueStatusServer/app.yaml b/WebKitTools/QueueStatusServer/app.yaml new file mode 100644 index 0000000..2756112 --- /dev/null +++ b/WebKitTools/QueueStatusServer/app.yaml @@ -0,0 +1,11 @@ +application: webkit-commit-queue +version: 1 +runtime: python +api_version: 1 + +handlers: +- url: /stylesheets + static_dir: stylesheets + +- url: /.* + script: queue_status.py diff --git a/WebKitTools/QueueStatusServer/filters/__init__.py b/WebKitTools/QueueStatusServer/filters/__init__.py new file mode 100644 index 0000000..ef65bee --- /dev/null +++ b/WebKitTools/QueueStatusServer/filters/__init__.py @@ -0,0 +1 @@ +# Required for Python to search this directory for module files diff --git a/WebKitTools/QueueStatusServer/filters/webkit_extras.py b/WebKitTools/QueueStatusServer/filters/webkit_extras.py new file mode 100644 index 0000000..6a08727 --- /dev/null +++ b/WebKitTools/QueueStatusServer/filters/webkit_extras.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 django.template.defaultfilters import stringfilter +from google.appengine.ext import webapp + +import re + +bug_regexp = re.compile(r"bug (?P<bug_id>\d+)") +patch_regexp = re.compile(r"patch (?P<patch_id>\d+)") + +@stringfilter +def webkit_linkify(value): + value = bug_regexp.sub(r'<a href="http://webkit.org/b/\g<bug_id>">bug \g<bug_id></a>', value) + value = patch_regexp.sub(r'<a href="https://bugs.webkit.org/attachment.cgi?id=\g<patch_id>&action=prettypatch">patch \g<patch_id></a>', value) + return value + +register = webapp.template.create_template_register() +register.filter(webkit_linkify) diff --git a/WebKitTools/QueueStatusServer/index.html b/WebKitTools/QueueStatusServer/index.html new file mode 100644 index 0000000..fbd51fb --- /dev/null +++ b/WebKitTools/QueueStatusServer/index.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> + <title>WebKit Commit Queue Status</title> + <link type="text/css" rel="stylesheet" href="/stylesheets/main.css" /> +</head> +<body> + <center> + <div id="current_status"> + {{ last_status.message|force_escape|urlize|webkit_linkify|safe }} + <div id="last_status_date">As of {{ last_status.date|timesince }} ago</div> + </div> + + <table id="recent_status_table"> + <tr> + <th colspan=2>Recent Status</th> + </tr> + {% for recent_status in recent_statuses %} + <tr> + <td class='status_date'>{{ recent_status.date|timesince }} ago</td> + <td class="recent_status">{{ recent_status.message|force_escape|urlize|webkit_linkify|safe }}</td> + </tr> + {% endfor %} + </table> + + <div id="footer"><a href="https://bugs.webkit.org/buglist.cgi?query_format=advanced&bug_status=UNCONFIRMED&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED&field0-0-0=flagtypes.name&type0-0-0=equals&value0-0-0=commit-queue%2B">queued bugs</a> | <a href="http://trac.webkit.org/wiki/CommitQueue">documentation</a> | <a href="http://webkit.org/">webkit.org</a></div> + </center> +</body> +</html> diff --git a/WebKitTools/QueueStatusServer/index.yaml b/WebKitTools/QueueStatusServer/index.yaml new file mode 100644 index 0000000..bf11262 --- /dev/null +++ b/WebKitTools/QueueStatusServer/index.yaml @@ -0,0 +1,24 @@ +indexes: + +# AUTOGENERATED + +# This index.yaml is automatically updated whenever the dev_appserver +# detects that a new type of query is run. If you want to manage the +# index.yaml file manually, remove the above marker line (the line +# saying "# AUTOGENERATED"). If you want to manage some indexes +# manually, move them above the marker line. The index.yaml file is +# automatically uploaded to the admin console when you next deploy +# your application using appcfg.py. + +- kind: QueueStatus + properties: + - name: active_patch_id + - name: queue_name + - name: date + direction: desc + +- kind: QueueStatus + properties: + - name: queue_name + - name: date + direction: desc diff --git a/WebKitTools/QueueStatusServer/queue_status.py b/WebKitTools/QueueStatusServer/queue_status.py new file mode 100644 index 0000000..65197bb --- /dev/null +++ b/WebKitTools/QueueStatusServer/queue_status.py @@ -0,0 +1,177 @@ +# 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 cgi +import os + +# Request a modern Django +from google.appengine.dist import use_library +use_library('django', '1.1') + +from google.appengine.ext.webapp import template +from google.appengine.api import users +from google.appengine.ext import webapp, db +from google.appengine.ext.webapp.util import run_wsgi_app + +webapp.template.register_template_library('filters.webkit_extras') + + +class QueueStatus(db.Model): + author = db.UserProperty() + queue_name = db.StringProperty() + active_bug_id = db.IntegerProperty() + active_patch_id = db.IntegerProperty() + message = db.StringProperty(multiline=True) + date = db.DateTimeProperty(auto_now_add=True) + results_file = db.BlobProperty() + + +class MainPage(webapp.RequestHandler): + def get(self): + statuses_query = QueueStatus.all().filter('queue_name =', 'commit-queue').order('-date') + statuses = statuses_query.fetch(6) + if not statuses: + return self.response.out.write("No status to report.") + template_values = { + 'last_status' : statuses[0], + 'recent_statuses' : statuses[1:], + } + self.response.out.write(template.render('index.html', template_values)) + + +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) + + +class StatusSummary(object): + def _status_to_code(self, status): + code_names = { + "Pass": "pass", + "Pending": "pending", + "Fail": "fail", + "Error": "error", + } + return code_names.get(status, "none") + + def _queue_name_to_code(self, queue_name): + code_names = { + "style-queue": "style", + } + return code_names[queue_name] + + queues = [ + "style-queue", + ] + + def __init__(self): + self._summary = {} + + def summarize(self, attachment_id): + if self._summary.get(attachment_id): + return self._summary.get(attachment_id) + + attachment_summary = {} + for queue in self.queues: + statuses = QueueStatus.all().filter('queue_name =', queue).filter('active_patch_id =', attachment_id).order('-date').fetch(1) + status_code = self._status_to_code(statuses[0].message if statuses else None) + queue_code = self._queue_name_to_code(queue) + attachment_summary[queue_code] = status_code + + self._summary[attachment_id] = attachment_summary + return attachment_summary + + +class StatusBubble(webapp.RequestHandler): + def get(self, attachment_id): + status_summary = StatusSummary() + template_values = { + "queue_status" : status_summary.summarize(int(attachment_id)), + } + self.response.out.write(template.render('status_bubble.html', template_values)) + + +class UpdateStatus(webapp.RequestHandler): + def get(self): + self.response.out.write(template.render('update_status.html', None)) + + 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 + + def post(self): + queue_status = QueueStatus() + + if users.get_current_user(): + queue_status.author = users.get_current_user() + + queue_name = self.request.get('queue_name') + queue_status.queue_name = queue_name + queue_status.active_bug_id = self._int_from_request('bug_id') + queue_status.active_patch_id = self._int_from_request('patch_id') + queue_status.message = self.request.get('status') + results_file = self.request.get("results_file") + queue_status.results_file = db.Blob(results_file) + queue_status.put() + self.redirect('/') + + +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" + self.response.out.write(status.results_file) + + +routes = [ + ('/', MainPage), + ('/update-status', UpdateStatus), + (r'/patch-status/(.*)/(.*)', PatchStatus), + (r'/status-bubble/(.*)', StatusBubble), + (r'/results/(.*)', ShowResults) +] + +application = webapp.WSGIApplication(routes, debug=True) + +def main(): + run_wsgi_app(application) + +if __name__ == "__main__": + main() diff --git a/WebKitTools/QueueStatusServer/status_bubble.html b/WebKitTools/QueueStatusServer/status_bubble.html new file mode 100644 index 0000000..f8959d9 --- /dev/null +++ b/WebKitTools/QueueStatusServer/status_bubble.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html> +<head> +<style> +body { + font-family: Verdana, sans-serif; + margin: 0px; + padding: 0px; +} +.status { + display: block; + float: left; + margin: 1px; + padding: 1px 2px; + border-radius: 5px; + border: 1px solid #AAA; + font-size: 11px; +} +.pass { + background-color: #8FDF5F; + border: 1px solid #4F8530; +} +.fail { + background-color: #E98080; + border: 1px solid #A77272; +} +.pending { + background-color: #FFFC6C; + border: 1px solid #C5C56D; +} +</style> +</head> +<body>{% for key, value in queue_status.items %} +<div class="status {{value}}" title="{{key}}: {{value}}">{{key}}</div>{% endfor %} +</body> +</html> diff --git a/WebKitTools/QueueStatusServer/stylesheets/main.css b/WebKitTools/QueueStatusServer/stylesheets/main.css new file mode 100644 index 0000000..55d3694 --- /dev/null +++ b/WebKitTools/QueueStatusServer/stylesheets/main.css @@ -0,0 +1,26 @@ +body { + font-family: Verdana, Helvetica, sans-serif; +} + +#current_status { + padding: 5px; + font-size: larger; +} + +#last_status_date { + font-size: small; +} + +.recent_status { + padding-left: 10px; +} + +#recent_status_table { + font-size: small; + margin: 10px; +} + +#footer { + font-size: small; + padding-top: 10px; +} diff --git a/WebKitTools/QueueStatusServer/update_status.html b/WebKitTools/QueueStatusServer/update_status.html new file mode 100644 index 0000000..9343c60 --- /dev/null +++ b/WebKitTools/QueueStatusServer/update_status.html @@ -0,0 +1,17 @@ +<form name="update_status" enctype="multipart/form-data" method="post"> +Update status for a queue: <input name="queue_name"> + <div> + Active Bug Id: + <input name="bug_id"> + </div> + <div> + Active Patch Id: + <input name="patch_id"> + </div> + <div> + Status Text:<br> + <textarea name="status" rows="3" cols="60"></textarea> + </div> + <div>Results file: <input type="file" name="results_file"></div> + <div><input type="submit" value="Add Status"></div> +</form> |
