incubator-allura-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From brond...@apache.org
Subject [2/2] git commit: [#5701] Added task manager to list and view MonQ tasks
Date Mon, 11 Feb 2013 19:59:56 GMT
Updated Branches:
  refs/heads/master 73a74278f -> 1c6e48200


[#5701] Added task manager to list and view MonQ tasks

Signed-off-by: Cory Johns <johnsca@geek.net>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/a8408197
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/a8408197
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/a8408197

Branch: refs/heads/master
Commit: a84081976d80dc818c9a4613fc9262fab2560b88
Parents: 73a7427
Author: Cory Johns <johnsca@geek.net>
Authored: Wed Feb 6 21:29:28 2013 +0000
Committer: Dave Brondsema <dbrondsema@geek.net>
Committed: Mon Feb 11 19:59:41 2013 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/site_admin.py           |   72 +++++++-
 Allura/allura/lib/app_globals.py                  |   10 +-
 Allura/allura/templates/site_admin.html           |   13 +-
 Allura/allura/templates/site_admin_task_list.html |   91 +++++++++
 Allura/allura/templates/site_admin_task_view.html |  153 ++++++++++++++++
 5 files changed, 329 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a8408197/Allura/allura/controllers/site_admin.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/site_admin.py b/Allura/allura/controllers/site_admin.py
index 8bb4f0d..b0d0cd5 100644
--- a/Allura/allura/controllers/site_admin.py
+++ b/Allura/allura/controllers/site_admin.py
@@ -1,3 +1,4 @@
+import re
 import logging
 from datetime import datetime, timedelta
 from collections import defaultdict
@@ -6,7 +7,9 @@ from tg import expose, validate, flash, config, request
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from ming.orm import session
 import pymongo
-from pylons import c, g
+import bson
+import tg
+from pylons import c, g, request
 from formencode import validators
 
 from allura.lib import helpers as h
@@ -27,6 +30,9 @@ class W:
 
 class SiteAdminController(object):
 
+    def __init__(self):
+        self.task_manager = TaskManagerController()
+
     def _check_security(self):
         with h.push_context(config.get('site_admin_project', 'allura'),
                             neighborhood=config.get('site_admin_project_nbhd', 'Projects')):
@@ -68,6 +74,7 @@ class SiteAdminController(object):
             stats=stats[:int(limit)])
 
     @expose('jinja:allura:templates/site_admin_api_tickets.html')
+    @without_trailing_slash
     def api_tickets(self, **data):
         import json
         import dateutil.parser
@@ -151,6 +158,7 @@ class SiteAdminController(object):
         return False
 
     @expose('jinja:allura:templates/site_admin_add_subscribers.html')
+    @without_trailing_slash
     def add_subscribers(self, **data):
         if request.method == 'POST':
             url = data['artifact_url']
@@ -174,6 +182,7 @@ class SiteAdminController(object):
         return data
 
     @expose('jinja:allura:templates/site_admin_new_projects.html')
+    @without_trailing_slash
     @validate(dict(page=validators.Int(if_empty=0),
                    limit=validators.Int(if_empty=100)))
     def new_projects(self, page=0, limit=100, **kwargs):
@@ -194,6 +203,7 @@ class SiteAdminController(object):
         }
 
     @expose('jinja:allura:templates/site_admin_reclone_repo.html')
+    @without_trailing_slash
     @validate(dict(prefix=validators.NotEmpty(),
                    shortname=validators.NotEmpty(),
                    mount_point=validators.NotEmpty()))
@@ -230,3 +240,63 @@ class SiteAdminController(object):
             shortname = ''
             mount_point = ''
         return dict(prefix=prefix, shortname=shortname, mount_point=mount_point)
+
+class TaskManagerController(object):
+
+    def _check_security(self):
+        with h.push_context(config.get('site_admin_project', 'allura'),
+                            neighborhood=config.get('site_admin_project_nbhd', 'Projects')):
+            require_access(c.project, 'admin')
+
+    @expose('jinja:allura:templates/site_admin_task_list.html')
+    @without_trailing_slash
+    def index(self, page_num=1, hours=1, state=None, task_name=None, host=None):
+        now = datetime.utcnow()
+        try:
+            page_num = int(page_num)
+        except ValueError as e:
+            page_num = 1
+        try:
+            hours = int(hours)
+        except ValueError as e:
+            hours = 1
+        start_dt = now - timedelta(hours=(page_num-1)*hours)
+        end_dt = now - timedelta(hours=page_num*hours)
+        start = bson.ObjectId.from_datetime(start_dt)
+        end = bson.ObjectId.from_datetime(end_dt)
+        query = {'_id': {'$lt': start, '$gt': end}}
+        if state:
+            query['state'] = state
+        if task_name:
+            query['task_name'] = re.compile(re.escape(task_name))
+        if host:
+            query['process'] = re.compile(re.escape(host))
+
+        tasks = list(M.monq_model.MonQTask.query.find(query).sort('_id', -1))
+        for task in tasks:
+            task.project = M.Project.query.get(_id=task.context.project_id)
+            task.user = M.User.query.get(_id=task.context.user_id)
+        newer_url = tg.url(params=dict(request.params, page_num=page_num - 1)).lstrip('/')
+        older_url = tg.url(params=dict(request.params, page_num=page_num + 1)).lstrip('/')
+        return dict(
+                tasks=tasks,
+                page_num=page_num,
+                hours=hours,
+                newer_url=newer_url,
+                older_url=older_url,
+                window_start=start_dt,
+                window_end=end_dt,
+            )
+
+    @expose('jinja:allura:templates/site_admin_task_view.html')
+    @without_trailing_slash
+    def view(self, task_id):
+        try:
+            task = M.monq_model.MonQTask.query.get(_id=bson.ObjectId(task_id))
+        except bson.InvalidId as e:
+            task = None
+        if task:
+            task.project = M.Project.query.get(_id=task.context.project_id)
+            task.app_config = M.AppConfig.query.get(_id=task.context.app_config_id)
+            task.user = M.User.query.get(_id=task.context.user_id)
+        return dict(task=task)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a8408197/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 736c297..14522aa 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -272,6 +272,12 @@ class Globals(object):
         return Credentials.get()
 
     def handle_paging(self, limit, page, default=50):
+        limit = self.manage_paging_preference(limit, default)
+        page = max(int(page), 0)
+        start = page * int(limit)
+        return (limit, page, start)
+
+    def manage_paging_preference(self, limit, default=50):
         if limit:
             if c.user in (None, M.User.anonymous()):
                 session['results_per_page'] = int(limit)
@@ -283,9 +289,7 @@ class Globals(object):
                 limit = 'results_per_page' in session and session['results_per_page'] or
default
             else:
                 limit = c.user.get_pref('results_per_page') or default
-        page = max(int(page), 0)
-        start = page * int(limit)
-        return (limit, page, start)
+        return limit
 
     def document_class(self, neighborhood):
         classes = ''

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a8408197/Allura/allura/templates/site_admin.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/site_admin.html b/Allura/allura/templates/site_admin.html
index 25ccc18..d15daf1 100644
--- a/Allura/allura/templates/site_admin.html
+++ b/Allura/allura/templates/site_admin.html
@@ -15,12 +15,13 @@
 <div id="sidebar">
   <div>&nbsp;</div>
   <ul>
-    <li class="{{page=='index' and 'active' or ''}}"><a href="."><b data-icon="{{g.icons['admin'].char}}"
class="ico {{g.icons['admin'].css}}"></b>Home</a></li>
-    <li class="{{page=='stats' and 'active' or ''}}"><a href="stats"><b data-icon="{{g.icons['stats'].char}}"
class="ico {{g.icons['stats'].css}}"></b>Stats</a></li>
-    <li class="{{page=='api_tickets' and 'active' or ''}}"><a href="api_tickets"><b
data-icon="{{g.icons['admin'].char}}" class="ico {{g.icons['admin'].css}}"></b>API
Tickets</a></li>
-    <li class="{{page=='add_subscribers' and 'active' or ''}}"><a href="add_subscribers"><b
data-icon="{{g.icons['admin'].char}}" class="ico {{g.icons['admin'].css}}"></b>Add
Subscribers</a></li>
-    <li class="{{page=='new_projects' and 'active' or ''}}"><a href="new_projects"><b
data-icon="{{g.icons['admin'].char}}" class="ico {{g.icons['admin'].css}}"></b>New
Projects</a></li>
-    <li class="{{page=='reclone_repo' and 'active' or ''}}"><a href="reclone_repo"><b
data-icon="{{g.icons['admin'].char}}" class="ico {{g.icons['admin'].css}}"></b>Reclone
repo</a></li>
+    <li class="{{page=='index' and 'active' or ''}}"><a href="{{sidebar_rel}}."><b
data-icon="{{g.icons['admin'].char}}" class="ico {{g.icons['admin'].css}}"></b>Home</a></li>
+    <li class="{{page=='stats' and 'active' or ''}}"><a href="{{sidebar_rel}}stats"><b
data-icon="{{g.icons['stats'].char}}" class="ico {{g.icons['stats'].css}}"></b>Stats</a></li>
+    <li class="{{page=='api_tickets' and 'active' or ''}}"><a href="{{sidebar_rel}}api_tickets"><b
data-icon="{{g.icons['admin'].char}}" class="ico {{g.icons['admin'].css}}"></b>API
Tickets</a></li>
+    <li class="{{page=='add_subscribers' and 'active' or ''}}"><a href="{{sidebar_rel}}add_subscribers"><b
data-icon="{{g.icons['admin'].char}}" class="ico {{g.icons['admin'].css}}"></b>Add
Subscribers</a></li>
+    <li class="{{page=='new_projects' and 'active' or ''}}"><a href="{{sidebar_rel}}new_projects"><b
data-icon="{{g.icons['admin'].char}}" class="ico {{g.icons['admin'].css}}"></b>New
Projects</a></li>
+    <li class="{{page=='reclone_repo' and 'active' or ''}}"><a href="{{sidebar_rel}}reclone_repo"><b
data-icon="{{g.icons['admin'].char}}" class="ico {{g.icons['admin'].css}}"></b>Reclone
Repo</a></li>
+    <li class="{{page=='task_manager' and 'active' or ''}}"><a href="{{sidebar_rel}}task_manager"><b
data-icon="{{g.icons['stats'].char}}" class="ico {{g.icons['stats'].css}}"></b>Task
Manager</a></li>
 
   </ul>
 </div>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a8408197/Allura/allura/templates/site_admin_task_list.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/site_admin_task_list.html b/Allura/allura/templates/site_admin_task_list.html
new file mode 100644
index 0000000..20dc2d7
--- /dev/null
+++ b/Allura/allura/templates/site_admin_task_list.html
@@ -0,0 +1,91 @@
+{% set page="task_manager" %}
+{% extends 'allura:templates/site_admin.html' %}
+
+{% block extra_css %}
+<style type="text/css">
+    .paging {
+        float: right;
+        margin: 1em;
+    }
+    .paging-window {
+        margin: 1em;
+    }
+    .empty {
+        text-align: center;
+        font-style: italic;
+    }
+    #task_search_form {
+        margin-left: 1em;
+    }
+    #task_search_form label {
+        display: inline-block;
+        width: 6em;
+    }
+    #task_search_form input[type="submit"] {
+        float: none;
+    }
+    #task_list {
+        overflow: auto;
+        clear: both;
+    }
+</style>
+{% endblock %}
+
+{% macro _paging() %}
+<div class="paging">
+    {% if page_num > 3 -%}
+    <a class="newest" title="Newest" href="{{ newest_url }}">&lt;&lt;</a>&nbsp;
+    {%- endif -%}
+    {%- if page_num > 1 -%}
+    <a class="newer" title="Newer" href="{{ newer_url }}">&lt;</a>&nbsp;&hellip;&nbsp;
+    {%- endif -%}
+    <a class="newer" title="Older" href="{{ older_url }}">&gt;</a>
+</div>
+{% endmacro %}
+
+{% block content %}
+<h2>Task Manager</h2>
+<form method="GET" id="task_search_form">
+    <label>State:</label> <input name="state" value="{{ request.params.state
}}" /><br/>
+    <label>Task Name:</label> <input name="task_name" value="{{ request.params.task_name
}}" /><br/>
+    <label>Host:</label> <input name="host" value="{{ request.params.host
}}" />
+    <input type="submit" />
+    <input type="hidden" name="page_num" value="{{ page_num }}" />
+    <input type="hidden" name="hours" value="{{ hours }}" />
+</form>
+{{ _paging() }}
+<div class="paging-window">
+    Showing tasks from {{ window_start.strftime('%Y/%m/%d %H:%M:%S') }} to {{ window_end.strftime('%Y/%m/%d
%H:%M:%S') }}...
+</div>
+<div id="task_list">
+    <table>
+      <thead>
+          <tr>
+              <th>Task Name</th>
+              <th>State</th>
+              <th>Project</th>
+              <th>User</th>
+              <th>Time Queued</th>
+              <th>Time Started</th>
+              <th>Process</th>
+          </tr>
+      </thead>
+      {% for task in tasks %}
+          <tr>
+              <td><a href="task_manager/view/{{task._id}}">{{task.task_name}}</a></td>
+              <td>{{task.state}}</td>
+              <td>{{task.project.shortname if task.project}}</td>
+              <td>{{task.user.username if task.user}}</td>
+              <td>{{task.time_queue.strftime('%Y/%m/%d %H:%M:%S') if task.time_queue}}</td>
+              <td>{{task.time_start.strftime('%Y/%m/%d %H:%M:%S') if task.time_start}}</td>
+              <td>{{task.process if task.process}}</td>
+          </tr>
+      {% else %}
+         <tr>
+             <td class="empty" colspan="7" >No tasks found</td>
+        </tr>
+      {% endfor %}
+    </table>
+</div>
+{{ _paging() }}
+{% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/a8408197/Allura/allura/templates/site_admin_task_view.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/site_admin_task_view.html b/Allura/allura/templates/site_admin_task_view.html
new file mode 100644
index 0000000..2b1abee
--- /dev/null
+++ b/Allura/allura/templates/site_admin_task_view.html
@@ -0,0 +1,153 @@
+{% set page = 'task_manager' %}
+{% set sidebar_rel = '../../' %}
+{% extends 'allura:templates/site_admin.html' %}
+
+{% block extra_css %}
+<style type="text/css">
+    #task_details {
+        table-layout: fixed;
+        word-wrap: break-word;
+        border-collapse: separate;
+        border-spacing: 4px;
+    }
+    #task_details th,
+    #task_details td {
+        border: 0;
+    }
+    #task_details .first-column-headers {
+        width: 50px;
+    }
+    #task_details .first-column {
+        width: 225px;
+    }
+    #task_details .spacer {
+        width: 1px;
+    }
+    #task_details .second-column-headers {
+        width: 100px;
+    }
+    #task_details th {
+        background: #e5e5e5;
+        background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ffffff),
color-stop(100%, #e5e5e5));
+        background-image: -webkit-linear-gradient(#ffffff, #e5e5e5);
+        background-image: -moz-linear-gradient(#ffffff, #e5e5e5);
+        background-image: -o-linear-gradient(#ffffff, #e5e5e5);
+        background-image: -ms-linear-gradient(#ffffff, #e5e5e5);
+        background-image: linear-gradient(#ffffff, #e5e5e5);
+        text-shadow: #fff 0 1px 0;
+        border: 1px solid #aaa;
+        border-radius: 3px;
+    }
+    #task_details th.side-header {
+        text-align: right;
+        vertical-align: top;
+        padding: 4px 10px;
+        border-top-right-radius: 0;
+        border-bottom-right-radius: 0;
+    }
+    #task_details td.second-column {
+        border: 0;
+    }
+</style>
+{% endblock %}
+
+{% block content %}
+{% if not task %}
+    Task not found
+{% else %}
+    <h2>Task Details</h2>
+    <table id="task_details">
+        <tr>
+            <td class="first-column-headers"></td>
+            <th class="first-column">Name</th>
+            <td class="spacer"></td>
+            <td class="second-column-headers"></td>
+            <th class="second-column">State</th>
+        </tr>
+        <tr>
+            <td class="first-column-headers"></td>
+            <td>{{ task.task_name }}</td>
+            <td class="spacer"></td>
+            <td class="second-column-headers"></td>
+            <td>{{ task.state }}</td>
+        </tr>
+        <tr>
+            <td class="first-column-headers"></td>
+            <th class="first-column">ID</th>
+            <td class="spacer"></td>
+            <td class="second-column-headers"></td>
+            <th class="second-column">Process</th>
+        </tr>
+        <tr>
+            <td class="first-column-headers"></td>
+            <td>{{ task._id }}</td>
+            <td class="spacer"></td>
+            <td class="second-column-headers"></td>
+            <td>{{ task.process if task.process }}</td>
+        </tr>
+        <tr>
+            <td class="first-column-headers"></td>
+            <th>Context</th>
+            <td class="spacer"></td>
+            <td class="second-column-headers"></td>
+            <th>Time</th>
+        </tr>
+        <tr>
+            <th class="side-header">Project</th>
+            <td>{{ task.project.shortname if task.project }}</td>
+            <td class="spacer"></td>
+            <th class="second-column-headers side-header">Queued</th>
+            <td>{{ task.time_queue.strftime('%Y/%m/%d %H:%M:%S') if task.time_queue
}}</td>
+        </tr>
+        <tr>
+            <th class="side-header">Mount</th>
+            <td>{{ task.app_config.options.mount_point if task.app_config }}</td>
+            <td class="spacer"></td>
+            <th class="second-column-headers side-header">Started</th>
+            <td>{{ task.time_start.strftime('%Y/%m/%d %H:%M:%S') if task.time_start
}}</td>
+        </tr>
+        <tr>
+            <th class="side-header">User</th>
+            <td>{{ task.user.username if task.user }}</td>
+            <td class="spacer"></td>
+            <th class="second-column-headers side-header">Stopped</th>
+            <td>{{ task.time_stop.strftime('%Y/%m/%d %H:%M:%S') if task.time_stop }}</td>
+        </tr>
+        <tr>
+            <td class="first-column-headers"></td>
+            <th>Args</th>
+            <td class="spacer"></td>
+            <td class="second-column-headers"></td>
+            <th>Keyword Args</th>
+        </tr>
+        {% if task.args|length > task.kwargs|length %}
+            {% set indexes = range(task.args|length) %}
+        {% else %}
+            {% set indexes = range(task.kwargs|length) %}
+        {% endif %}
+        {% set kwargs = task.kwargs.items() %}
+        {% for i in indexes %}
+        <tr>
+            <td class="first-column-headers"></td>
+            <td>{{ (task.args[i] or '')|truncate }}</td>
+            <td class="spacer"></td>
+            {% if kwargs[i] %}
+            <th class="second-column-headers side-header">{{ kwargs[i][0] }}</th>
+            <td>{{ (kwargs[i][1] or '')|truncate }}</td>
+            {% else %}
+            <td class="second-column-headers"></td>
+            <td></td>
+            {% endif %}
+        </tr>
+        {% endfor %}
+        <tr>
+            <td class="first-column-headers"></td>
+            <th colspan="4">Result</th>
+        </tr>
+        <tr>
+            <td class="first-column-headers"></td>
+            <td colspan="4"><pre>{{ task.result }}</pre></td>
+        </tr>
+    </table>
+{% endif %}
+{% endblock %}


Mime
View raw message