Added a proper job_detail page that display information, and reloads itself.
authorJean-Michel Nirgal Vourgère <jmv@nirgal.com>
Wed, 10 Nov 2010 22:59:24 +0000 (22:59 +0000)
committerJean-Michel Nirgal Vourgère <jmv@nirgal.com>
Wed, 10 Nov 2010 22:59:24 +0000 (22:59 +0000)
Improved error message on jobrunner not running problems.

bin/djais/urls.py
bin/djais/views.py
bin/jobrunner.py
html_templates/job.html [new file with mode: 0644]
html_templates/jobs.html

index 3f1d1aa5c7fe0bcc10d7aa52afc60b179a9d5737..2b55a94e309c88dab9e74a093347b167418bee56 100644 (file)
@@ -30,7 +30,8 @@ urlpatterns = patterns('',
     (r'^user/(?P<login>[a-zA-Z0-9_]+)/change_password$', 'ais.djais.views.user_change_password'),
     (r'^user/(?P<login>[a-zA-Z0-9_]+)/delete$', 'ais.djais.views.user_delete'),
     (r'^job/$', 'ais.djais.views.jobs_index'),
-    (r'^job/(?P<jobid>[A-Z0-9]+)$', 'ais.djais.views.job_get'),
+    (r'^job/(?P<jobid>[A-Z0-9]+)/$', 'ais.djais.views.job_detail'),
+    (r'^job/(?P<jobid>[A-Z0-9]+)/download$', 'ais.djais.views.job_get'),
     (r'^source/$', 'ais.djais.views.sources_index'),
     (r'^source/stats$', 'ais.djais.views.sources_stats'),
     (r'^news/(?P<page>\d*)$', 'ais.djais.views.news'),
index 33363ffe6f0510454e4b7f04907d832de0f7a5f2..d9dce9d012e0ab33b62cfcc3b1c558d07ea0c286 100644 (file)
@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
 
+#TODO
 #from __future__ import division
+#Normalize 403 errors
 
 import os
 from datetime import *
@@ -416,8 +418,10 @@ def vessel_history(request, strmmsi, format=None):
             job.command = command
             job.extension = u'kmz'
             job.save()
-            request.user.info('Request queued as job %s' % job.id)
-            jobrunner.wakeup_daemon()
+            #request.user.info('Request queued as job %s' % job.id)
+            if not jobrunner.wakeup_daemon():
+                return HttpResponseServerError(jobrunner.DAEMON_WAKEUP_ERROR)
+            return HttpResponseRedirect('/job/%s/' % job.id)
         else:
             value = kml_to_kmz(format_boat_track(nmea_iterator))
             response = HttpResponse(value, mimetype="application/vnd.google-earth.kml")
@@ -432,8 +436,10 @@ def vessel_history(request, strmmsi, format=None):
             job.command = command
             job.extension = u'kmz'
             job.save()
-            request.user.info('Request queued as job %s' % job.id)
-            jobrunner.wakeup_daemon()
+            #request.user.info('Request queued as job %s' % job.id)
+            if not jobrunner.wakeup_daemon():
+                return HttpResponseServerError(jobrunner.DAEMON_WAKEUP_ERROR)
+            return HttpResponseRedirect('/job/%s/' % job.id)
         else:
             value = kml_to_kmz(format_boat_intime(nmea_iterator))
             response = HttpResponse(value, mimetype="application/vnd.google-earth.kml")
@@ -448,8 +454,10 @@ def vessel_history(request, strmmsi, format=None):
             job.command = command
             job.extension = u'csv'
             job.save()
-            request.user.info('Request queued as job %s' % job.id)
-            jobrunner.wakeup_daemon()
+            #request.user.info('Request queued as job %s' % job.id)
+            if not jobrunner.wakeup_daemon():
+                return HttpResponseServerError(jobrunner.DAEMON_WAKEUP_ERROR)
+            return HttpResponseRedirect('/job/%s/' % job.id)
         else:
             value = StringIO()
             output = csv.writer(value)
@@ -671,6 +679,21 @@ def jobs_index(request):
         jobs = request.user.job_set.filter(archive_time__isnull=True)
     return render_to_response('jobs.html', {'jobs': jobs, 'archive': show_archive }, RequestContext(request))
 
+@http_authenticate(auth, 'ais')
+def job_detail(request, jobid):
+    job = get_object_or_404(Job, id=jobid)
+    if job.user != request.user:
+        return HttpResponseForbidden('403 Forbidden')
+    response = render_to_response('job.html', {'job': job}, RequestContext(request))
+    if not job.finish_time:
+        response['Refresh'] = 5
+    elif not job.archive_time:
+        # finished but not archived:
+        response['Refresh'] = '0;url=https://ais.nirgal.com/job/%s/download' % job.id
+        job.archive_time = datetime.utcnow()
+        job.save()
+    return response
+
 @http_authenticate(auth, 'ais')
 def job_get(request, jobid):
     job = get_object_or_404(Job, id=jobid)
index 038a2b34189f47380ecd4d72d6a185040d54843c..065808beed8f0f802037d88c781754f1c7189d7b 100755 (executable)
@@ -2,6 +2,7 @@
 
 __all__ = [ \
     'wakeup_daemon',
+    'DAEMON_WAKEUP_ERROR',
     ]
 
 import sys
@@ -16,8 +17,17 @@ SOCK_FILENAME = '/var/run/ais/jobrunner.wakeup'
 
 def wakeup_daemon():
     client = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
-    client.connect(SOCK_FILENAME)
-    client.send('')
+    try:
+        client.connect(SOCK_FILENAME)
+        client.send('')
+        return True
+    except:
+        return False
+
+DAEMON_WAKEUP_ERROR = """
+Your job has been queued, but there was an error contacting the task
+scheduler. Please repport the error.
+"""
 
 def runjob():
     """
@@ -59,7 +69,7 @@ def runjob():
     dbcommit()
     logging.info('Job complete: result=%s', returncode)
 
-    sqlexec(u"INSERT INTO user_message (user_id, user_message_category_id, txt) VALUES(%(user_id)s, 'info', %(msg)s)", {'user_id':user_id, 'msg':('Your <a href="/job/%(jobid)s">job %(jobid)s</a> is complete.' % {'jobid': jobid}) })
+    sqlexec(u"INSERT INTO user_message (user_id, user_message_category_id, txt) VALUES(%(user_id)s, 'info', %(msg)s)", {'user_id':user_id, 'msg':('Your <a href="/job/%(jobid)s/download">job %(jobid)s</a> is complete.' % {'jobid': jobid}) })
     dbcommit()
 
     return 2
diff --git a/html_templates/job.html b/html_templates/job.html
new file mode 100644 (file)
index 0000000..1262f08
--- /dev/null
@@ -0,0 +1,29 @@
+{% extends "base.html" %}
+
+{% block tab_active_job %} id=tabactive{% endblock %}
+
+{% block breadcrumbs %}
+{{ block.super }}
+/ {{ job.id }}
+{% endblock %}
+
+{% block content %}
+
+<h3>Job {{ job.id }}</h3>
+<tt>{{ job.nice_command }}</tt><br>
+{% if job.finish_time %}
+Status: <b>Completed</b> at {{ job.finish_time|date:"Y-m-d H:i:s" }} UTC in {{ job.process_time }}<br>
+Result: {% if job.result %}<b>Error {{ job.result }}</b>{% else %}<b>Success</b><br>
+<a href="/job/{{ job.id }}/download" class=button>download</a>{% endif %}<br>
+{% else %}
+    {% if job.start_time %}
+    Status: <b>Running</b> since {{ job.start_time }}.<br>
+    Pid: {{ job.pid }}<br>
+    {% else %}
+    Status: <b>Queued</b> since {{ job.queue_time }}.<br>
+    Position in jobs queue: {{ job.queue_rank }}<br>
+    {% endif %}
+{% endif %}
+
+
+{% endblock %}
index 85835410da49e156b6dcef02e7a2b4ef10089aec..581683689df32cfb10489f30f0df31b608377a92 100644 (file)
@@ -19,7 +19,7 @@
 {% if job.finish_time %}
 Status: <b>Completed</b> at {{ job.finish_time|date:"Y-m-d H:i:s" }} UTC in {{ job.process_time }}<br>
 Result: {% if job.result %}<b>Error {{ job.result }}</b>{% else %}<b>Success</b><br>
-<a href="/job/{{ job.id }}" class=button>download</a>{% endif %}<br>
+<a href="/job/{{ job.id }}/download" class=button>download</a>{% endif %}<br>
 {% else %}
     {% if job.start_time %}
     Status:<b>Running</b> since {{ job.start_time }}.<br>