Changeset 64787 in webkit


Ignore:
Timestamp:
Aug 5, 2010 2:28:51 PM (14 years ago)
Author:
eric@webkit.org
Message:

2010-05-23 Eric Seidel <eric@webkit.org>

Reviewed by Adam Barth.

QueueStatusServer needs better queue-status pages
https://bugs.webkit.org/show_bug.cgi?id=39562

The primary goal of this patch is to display queue
positions somewhere on the site so that it's easier
for commit-queue users to know when their pach will
be landed. I also tried to improve the root page
to be more useful than the previous wall of status text.

  • QueueStatusServer/handlers/recentstatus.py:
  • QueueStatusServer/main.py:
  • QueueStatusServer/model/queues.py:
  • QueueStatusServer/templates/recentstatus.html:
Location:
trunk/WebKitTools
Files:
1 added
5 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/WebKitTools/ChangeLog

    r64786 r64787  
     12010-05-23  Eric Seidel  <eric@webkit.org>
     2
     3        Reviewed by Adam Barth.
     4
     5        QueueStatusServer needs better queue-status pages
     6        https://bugs.webkit.org/show_bug.cgi?id=39562
     7
     8        The primary goal of this patch is to display queue
     9        positions somewhere on the site so that it's easier
     10        for commit-queue users to know when their pach will
     11        be landed.  I also tried to improve the root page
     12        to be more useful than the previous wall of status text.
     13
     14        * QueueStatusServer/handlers/recentstatus.py:
     15        * QueueStatusServer/main.py:
     16        * QueueStatusServer/model/queues.py:
     17        * QueueStatusServer/templates/recentstatus.html:
     18
    1192010-08-05  Victor Wang  <victorw@chromium.org>
    220
  • trunk/WebKitTools/QueueStatusServer/handlers/queuestatus.py

    r64786 r64787  
    1 # Copyright (C) 2009 Google Inc. All rights reserved.
     1# Copyright (C) 2010 Google Inc. All rights reserved.
    22#
    33# Redistribution and use in source and binary forms, with or without
    44# modification, are permitted provided that the following conditions are
    55# met:
    6 # 
     6#
    77#     * Redistributions of source code must retain the above copyright
    88# notice, this list of conditions and the following disclaimer.
     
    1414# contributors may be used to endorse or promote products derived from
    1515# this software without specific prior written permission.
    16 # 
     16#
    1717# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    1818# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     
    3030from google.appengine.ext.webapp import template
    3131
    32 from model.queues import queues
    33 from model.queuestatus import QueueStatus
     32from model.queues import queues, display_name_for_queue
     33from model.workitems import WorkItems
    3434
    35 class RecentStatus(webapp.RequestHandler):
    36     def _title_case(self, string):
    37         words = string.split(" ")
    38         words = map(lambda word: word.capitalize(), words)
    39         return " ".join(words)
     35from model import queuestatus
    4036
    41     def _pretty_queue_name(self, queue_name):
    42         return self._title_case(queue_name.replace("-", " "))
    4337
    44     # We could change "/" to just redirect to /queue-status/commit-queue in the future
    45     # at which point we would not need a default value for queue_name here.
    46     def get(self, queue_name="commit-queue"):
    47         queue_status = {}
    48         for queue in queues:
    49             statuses = QueueStatus.all().filter("queue_name =", queue).order("-date").fetch(6)
    50             if not statuses:
    51                 continue
    52             queue_status[queue] = statuses
     38class QueueStatus(webapp.RequestHandler):
     39    def _rows_for_work_items(self, work_items):
     40        if not work_items:
     41            return []
     42        rows = []
     43        for item_id in work_items.item_ids:
     44            rows.append({
     45                "attachment_id": item_id,
     46                "bug_id": 1,
     47            })
     48        return rows
    5349
     50    def get(self, queue_name):
     51        work_items = WorkItems.all().filter("queue_name =", queue_name).get()
     52        statuses = queuestatus.QueueStatus.all().filter("queue_name =", queue_name).order("-date").fetch(6)
    5453        template_values = {
    55             "queue_status" : queue_status,
     54            "display_queue_name": display_name_for_queue(queue_name),
     55            "work_item_rows": self._rows_for_work_items(work_items),
     56            "statuses": statuses,
    5657        }
    57         self.response.out.write(template.render("templates/recentstatus.html", template_values))
     58        self.response.out.write(template.render("templates/queuestatus.html", template_values))
  • trunk/WebKitTools/QueueStatusServer/handlers/recentstatus.py

    r52429 r64787  
    2727# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2828
     29import datetime
     30
    2931from google.appengine.ext import webapp
    3032from google.appengine.ext.webapp import template
    3133
    32 from model.queues import queues
     34from model.queues import queues, display_name_for_queue
    3335from model.queuestatus import QueueStatus
     36from model.workitems import WorkItems
    3437
    35 class RecentStatus(webapp.RequestHandler):
    36     def _title_case(self, string):
    37         words = string.split(" ")
    38         words = map(lambda word: word.capitalize(), words)
    39         return " ".join(words)
    4038
    41     def _pretty_queue_name(self, queue_name):
    42         return self._title_case(queue_name.replace("-", " "))
     39class QueueBubble(object):
     40    """View support class for recentstatus.html"""
     41    def __init__(self, queue_name):
     42        self._queue_name = queue_name
     43        self._work_items = WorkItems.all().filter("queue_name =", queue_name).get()
     44        self._last_status = QueueStatus.all().filter("queue_name =", queue_name).order("-date").get()
    4345
    44     # We could change "/" to just redirect to /queue-status/commit-queue in the future
    45     # at which point we would not need a default value for queue_name here.
    46     def get(self, queue_name="commit-queue"):
    47         queue_status = {}
    48         for queue in queues:
    49             statuses = QueueStatus.all().filter("queue_name =", queue).order("-date").fetch(6)
    50             if not statuses:
    51                 continue
    52             queue_status[queue] = statuses
     46    def name(self):
     47        return self._queue_name
    5348
     49    def display_name(self):
     50        return display_name_for_queue(self._queue_name)
     51
     52    def _last_status_date(self):
     53        if not self._last_status:
     54            return None
     55        return self._last_status.date
     56
     57    def last_heard_from(self):
     58        if not self._work_items:
     59            return self._last_status_date()
     60        return max(self._last_status_date(), self._work_items.date)
     61
     62    def is_alive(self):
     63        if not self.last_heard_from():
     64            return False
     65        return self.last_heard_from() > (datetime.datetime.now() - datetime.timedelta(minutes=30))
     66
     67    def status_class(self):
     68        if not self.is_alive():
     69            return "dead"
     70        if self.pending_items_count() > 1:
     71            return "behind"
     72        return "alive"
     73
     74    def status_text(self):
     75        if not self._work_items:
     76            return "Offline"
     77        if not self._work_items.item_ids:
     78            return "Idle"
     79        return self._last_status.message
     80
     81    def pending_items_count(self):
     82        if not self._work_items:
     83            return 0
     84        return len(self._work_items.item_ids)
     85
     86
     87class QueuesOverview(webapp.RequestHandler):
     88
     89    def get(self):
    5490        template_values = {
    55             "queue_status" : queue_status,
     91            "queues": [QueueBubble(queue_name) for queue_name in queues],
    5692        }
    5793        self.response.out.write(template.render("templates/recentstatus.html", template_values))
  • trunk/WebKitTools/QueueStatusServer/main.py

    r59534 r64787  
    3838from handlers.patch import Patch
    3939from handlers.patchstatus import PatchStatus
    40 from handlers.recentstatus import RecentStatus
     40from handlers.queuestatus import QueueStatus
     41from handlers.recentstatus import QueuesOverview
    4142from handlers.showresults import ShowResults
    4243from handlers.statusbubble import StatusBubble
     
    5051
    5152routes = [
    52     ('/', RecentStatus),
     53    ('/', QueuesOverview),
    5354    ('/dashboard', Dashboard),
    5455    ('/gc', GC),
     
    5859    (r'/status-bubble/(.*)', StatusBubble),
    5960    (r'/svn-revision/(.*)', SVNRevision),
    60     (r'/queue-status/(.*)', RecentStatus),
     61    (r'/queue-status/(.*)', QueueStatus),
    6162    ('/update-status', UpdateStatus),
    6263    ('/update-work-items', UpdateWorkItems),
  • trunk/WebKitTools/QueueStatusServer/model/queues.py

    r59534 r64787  
    4242
    4343
     44# FIXME: We need some sort of Queue object.
     45def _title_case(string):
     46    words = string.split(" ")
     47    words = map(lambda word: word.capitalize(), words)
     48    return " ".join(words)
     49
     50
     51def display_name_for_queue(queue_name):
     52    # HACK: chromium-ews is incorrectly named.
     53    display_name = queue_name.replace("chromium-ews", "cr-linux-ews")
     54
     55    display_name = display_name.replace("-", " ")
     56    display_name = display_name.replace("cr", "chromium")
     57    display_name = _title_case(display_name)
     58    display_name = display_name.replace("Ews", "EWS")
     59    return display_name
     60
     61
    4462def name_with_underscores(dashed_name):
    4563    regexp = re.compile("-")
  • trunk/WebKitTools/QueueStatusServer/templates/recentstatus.html

    r52437 r64787  
    44<title>WebKit Queue Status</title>
    55<link type="text/css" rel="stylesheet" href="/stylesheets/dashboard.css" />
     6<style>
     7.queue_bubble {
     8    border: 1px solid black;
     9    margin-bottom: 10px;
     10    border-radius: 10px;
     11    padding: 5px;
     12}
     13.queue_name {
     14    float:left;
     15}
     16.last_heard_from {
     17    float: right;
     18}
     19.status_text {
     20    clear: both;
     21}
     22.alive {
     23    background-color: #8FDF5F;
     24}
     25.behind {
     26    background-color: #FFFC6C;
     27}
     28.dead {
     29    background-color: #E98080;
     30}
     31</style>
    632</head>
    733<body>
    8 <h1>WebKit Queue Status</h1>{% for queue_name, statuses in queue_status.items %}
    9 <div class="status-details">
    10   <h2>{{ queue_name }}</h2>
    11   <ul>{% for status in statuses %}
    12     <li>{% if status.active_bug_id %}
    13       <span class="status-bug">
    14         Patch {{ status.active_patch_id|force_escape|webkit_attachment_id|safe }} from bug
    15         {{ status.active_bug_id|force_escape|webkit_bug_id|safe }}:
    16       </span>{% endif %}
    17       <span class="status-message">{{ status.message|force_escape|urlize|webkit_linkify|safe }}</span>{% if status.results_file %}
    18       <span class="status-results">[{{ status.key.id|results_link|safe }}]</span>{% endif %}
    19       <span class="status-date">{{ status.date|timesince }} ago</span>
    20     </li>{% endfor %}
    21   </ul>
    22 </div>{% endfor %}
     34<h1>WebKit Queue Status</h1>
     35{% for queue in queues %}
     36<div class="queue_bubble {{ queue.status_class }}">
     37    <div class="queue_name">
     38        <a href="/queue-status/{{ queue.name }}">
     39        {{ queue.display_name }}
     40        </a>
     41    </div>
     42    {% if queue.last_heard_from %}
     43    <div class="last_heard_from">{{ queue.last_heard_from|timesince }} ago</div>
     44    {% endif %}
     45    <div class="status_text">
     46        Status: {{ queue.status_text|force_escape|urlize|webkit_linkify|safe }}
     47    </div>
     48    <div>
     49        {{ queue.pending_items_count }} pending
     50    </div>
     51</div>
     52{% endfor %}
    2353</body>
    2454</html>
Note: See TracChangeset for help on using the changeset viewer.