summaryrefslogtreecommitdiffstats
path: root/WebKitTools/QueueStatusServer
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2009-12-15 10:12:09 +0000
committerSteve Block <steveblock@google.com>2009-12-17 17:41:10 +0000
commit643ca7872b450ea4efacab6188849e5aac2ba161 (patch)
tree6982576c228bcd1a7efe98afed544d840751094c /WebKitTools/QueueStatusServer
parentd026980fde6eb3b01c1fe49441174e89cd1be298 (diff)
downloadexternal_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.zip
external_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.tar.gz
external_webkit-643ca7872b450ea4efacab6188849e5aac2ba161.tar.bz2
Merge webkit.org at r51976 : Initial merge by git.
Change-Id: Ib0e7e2f0fb4bee5a186610272edf3186f0986b43
Diffstat (limited to 'WebKitTools/QueueStatusServer')
-rw-r--r--WebKitTools/QueueStatusServer/app.yaml11
-rw-r--r--WebKitTools/QueueStatusServer/filters/__init__.py1
-rw-r--r--WebKitTools/QueueStatusServer/filters/webkit_extras.py44
-rw-r--r--WebKitTools/QueueStatusServer/index.html29
-rw-r--r--WebKitTools/QueueStatusServer/index.yaml24
-rw-r--r--WebKitTools/QueueStatusServer/queue_status.py177
-rw-r--r--WebKitTools/QueueStatusServer/status_bubble.html36
-rw-r--r--WebKitTools/QueueStatusServer/stylesheets/main.css26
-rw-r--r--WebKitTools/QueueStatusServer/update_status.html17
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>