From b9dea63ea0f2876c58d723e412bd7f37fe8e03b8 Mon Sep 17 00:00:00 2001
From: Brian Moe <brian.moe@ligo.org>
Date: Wed, 3 Jul 2013 10:54:14 -0500
Subject: [PATCH] User modifiable gpstime window for event neighbors.

---
 gracedb/models.py                     |  7 +--
 gracedb/urls.py                       |  1 +
 gracedb/views.py                      | 27 ++++++++++
 templates/gracedb/event_detail.html   | 75 +++++++++++----------------
 templates/gracedb/neighbors_frag.html | 55 ++++++++++++++++++++
 5 files changed, 118 insertions(+), 47 deletions(-)
 create mode 100644 templates/gracedb/neighbors_frag.html

diff --git a/gracedb/models.py b/gracedb/models.py
index 35b6c2472..522a3b6a0 100644
--- a/gracedb/models.py
+++ b/gracedb/models.py
@@ -77,7 +77,7 @@ class Event(models.Model):
         ("MBTA", "MBTAOnline"),
         ("HWINJ", "HardwareInjection"),
     )
-    DEFAULT_EVENT_NEIGHBORHOOD = (5,5)
+    DEFAULT_EVENT_NEIGHBORHOOD = (-5,5)
 
     submitter = models.ForeignKey(DjangoUser)
     created = models.DateTimeField(auto_now_add=True)
@@ -151,10 +151,11 @@ class Event(models.Model):
         else:
             nearby = Event.objects.exclude(group__name='Test')
 
-        delta, delta2 = neighborhood or self.DEFAULT_EVENT_NEIGHBORHOOD
+        delta1, delta2 = neighborhood or self.DEFAULT_EVENT_NEIGHBORHOOD
 
-        nearby = nearby.filter(gpstime__range=(self.gpstime-delta, self.gpstime+delta2))
+        nearby = nearby.filter(gpstime__range=(self.gpstime+delta1, self.gpstime+delta2))
         nearby = nearby.exclude(id=self.id)
+        nearby = nearby.distinct()
         nearby = nearby.order_by('gpstime')
         return nearby
 
diff --git a/gracedb/urls.py b/gracedb/urls.py
index 959ceb7a0..0636ffce0 100644
--- a/gracedb/urls.py
+++ b/gracedb/urls.py
@@ -12,6 +12,7 @@ urlpatterns = patterns('gracedb.views',
     url (r'^view/(?P<graceid>[GEHT]\d+)', 'view', name="view"),
     url (r'^voevent/(?P<graceid>[GEHT]\d+)', 'voevent', name="voevent"),
     url (r'^skyalert/(?P<graceid>[GEHT]\d+)', 'skyalert', name="skyalert"),
+    url (r'^neighbors/(?P<graceid>[GEHT]\d+)/\(?(?P<delta1>[-+]?\d+)(,(?P<delta2>[-+]?\d+)\)?)?', 'neighbors', name="neighbors"),
     url (r'^(?P<graceid>[GEHT]\d+)$', 'view', name="view2"),
     url (r'^(?P<graceid>[GEHT]\d+)/files/(?P<filename>.*)$', download, name="file"),
     url (r'^(?P<graceid>[GEHT]\d+)/log/(?P<num>([\d]*|preview))$', 'logentry', name="logentry"),
diff --git a/gracedb/views.py b/gracedb/views.py
index 5a4a5c992..b9e0ee222 100644
--- a/gracedb/views.py
+++ b/gracedb/views.py
@@ -576,6 +576,32 @@ def ping(request):
         response['Content-length'] = len(ack)
     return response
 
+def neighbors(request, graceid, delta1, delta2=None):
+    context = {}
+    try:
+        delta1 = long(delta1)
+
+        if delta2 is None:
+            delta2 = delta1
+            delta1 = -delta1
+        else:
+            delta2 = long(delta2)
+
+    except ValueError: pass
+    except: pass
+
+    try:
+        event = Event.getByGraceid(graceid)
+    except Event.DoesNotExist:
+        raise Http404
+    context['nearby'] = [(e.gpstime - event.gpstime, e)
+                            for e in event.neighbors((delta1,delta2))]
+    context['neighbor_delta'] = "[%+d,%+d]" % (delta1, delta2)
+    return render_to_response(
+        'gracedb/neighbors_frag.html',
+        context,
+        context_instance=RequestContext(request))
+
 def view(request, graceid):
     context = {}
     try:
@@ -590,6 +616,7 @@ def view(request, graceid):
     context['skyalert_authorized'] = skyalert_authorized(request)
     context['blessed_tags'] = settings.BLESSED_TAGS
     context['single_inspiral_events'] = list(a.singleinspiral_set.all())
+    context['neighbor_delta'] = "[%+d,%+d]" % (-5,5)
     return render_to_response(
         [ 'gracedb/event_detail_{0}.html'.format(a.analysisType),
           'gracedb/event_detail.html'],
diff --git a/templates/gracedb/event_detail.html b/templates/gracedb/event_detail.html
index 1f6b9d6a3..cb3f96897 100644
--- a/templates/gracedb/event_detail.html
+++ b/templates/gracedb/event_detail.html
@@ -372,49 +372,36 @@
 {% endblock %}
 </div>
 
-{% if nearby %}
-    <div id="neighbors" class="content-area">
-    <h3>Neighbors</h3>
-    <table class="event">
-        <tr>
-                <th valign="top">UID</th>
-                <th>Labels</th>
-                <th>Group</th>
-                <th>Type</th>
-                <th>Instruments</th>
-                <th>
-                    {{ "ngps"|timeselect:"gps" }}
-                    Event Time
-                </th>
-                <th>FAR (Hz)</th>
-                <th>Links</th>
-                <th>
-                    {{"ncreated"|timeselect:"utc" }}
-                    Submitted
-                </th>
-        </tr>
-        {% for delta, object in nearby %}
-        <tr class={% cycle 'odd' 'even' %}>
-            <td><a href="{% url view object.graceid %}">{{ object.graceid }}</a></td>
-            <td>
-                 {% for labelling in object.labelling_set.all %}
-                    <span onmouseover="tooltip.show(tooltiptext('{{labelling.label.name}}', '{{labelling.creator.name}}', '{{labelling.created|utc}}'));" onmouseout="tooltip.hide();"  style="color: {{labelling.label.defaultColor}}">{{ labelling.label.name }}</span>
-                 {% endfor %}
-            </td>
-            <td>{{ object.group.name }} </td>
-            <td>{{ object.get_analysisType_display }} </td>
-            <td>{{ object.instruments }}</td>
-            <td>{% if object.gpstime%}
-                    {{ object.gpstime|multiTime:"ngps" }}
-                {% endif %}</td>
-            <td>{{ object.far|scientific }}</td>
-            <td><a href="{{ object.weburl }}">Data</a></td>
-            <td>{{ object.created|multiTime:"ncreated" }}</td>
-        </tr>
-        {% endfor %}
-    </table>
-    </div>
-{% endif %}
+<!-- Neighbors Support refresh_neighbors() function -->
+<script type="text/javascript">
+    var refresh_neighbors= function() { alert("NOT SET YET"); };
+    require(["dojo/dom", "dojo/html", "dojo/request", "dojo/domReady!"],
+        function (dom, html, request) {
+            refresh_neighbors = function(delta) {
+                delta = delta.replace(/[ [\]]/g, "");
+                if (delta.match(/^-?\d+$/) == null & delta.match(/^[-+]?\d+,[-+]?\d+$/) == null) {
+                    alert("Bad neighborhood specified.")
+                    return;
+                }
+                var neighborUrlPattern = "{% url neighbors object.graceid "000" %}"
+                var neighbor_div = dom.byId("neighbors");
+                neighborUrl = neighborUrlPattern.replace("000", delta);
+                request(neighborUrl).then(
+                    function(text){
+                        html.set(neighbor_div, text, {parseContent:true} );
+                    },
+                    function(error){
+                        inbox = '<input value="" size="6" onchange="refresh_neighbors(this.value)">'
+                        html.set(neighbor_div, inbox+"<br>Failed to find neighbors.<br>"+error);
+                    });
+            };
+        // refresh_neighbors("5");
+    });
+    require(["dijit/InlineEditBox", "dijit/form/NumberSpinner", "dijit/form/TextBox"]);
+
+</script>
+
+{% include "gracedb/neighbors_frag.html" %}
 
 <div id="pane_holder" class="content-area">
     {# XXX Hacky #}
@@ -491,7 +478,7 @@
                         <tr class="{% cycle 'odd' 'even'%}">
                            <td>{{log.N}}</td>
                            <td>{{log.created|multiTime:"logtime"}}</td>
-			   <td>{{log.issuer.first_name}} {{log.issuer.last_name}}</td>
+                           <td>{{log.issuer.first_name}} {{log.issuer.last_name}}</td>
                            <td>{{log.comment|sanitize}}
                                {% if log.fileurl %}
                                 <a href="{{log.fileurl}}">{{log.filename}}</a>
diff --git a/templates/gracedb/neighbors_frag.html b/templates/gracedb/neighbors_frag.html
new file mode 100644
index 000000000..40b12aec3
--- /dev/null
+++ b/templates/gracedb/neighbors_frag.html
@@ -0,0 +1,55 @@
+{% load timeutil %}
+{% load scientific %}
+<div id="neighbors" class="content-area">
+<h3>Neighbors &nbsp;
+    <span data-dojo-type="dijit/InlineEditBox"
+        data-dojo-props="editor:'dijit/form/TextBox', editorParams:{constraints:{places:0} }" width="100px" 
+        title="window"
+        onchange="refresh_neighbors(this.value)">{{neighbor_delta}}</span></h3>
+
+{% if nearby %}
+
+<table class="event">
+    <tr>
+            <th valign="top">UID</th>
+            <th>Labels</th>
+            <th>Group</th>
+            <th>Type</th>
+            <th>Instruments</th>
+            <th>
+                {{ "ngps"|timeselect:"gps" }}
+                Event Time
+            </th>
+            <th>&Delta;gpstime</th>
+            <th>FAR (Hz)</th>
+            <th>Links</th>
+            <th>
+                {{"ncreated"|timeselect:"utc" }}
+                Submitted
+            </th>
+    </tr>
+    {% for delta, object in nearby %}
+    <tr class={% cycle 'odd' 'even' %}>
+        <td><a href="{% url view object.graceid %}">{{ object.graceid }}</a></td>
+        <td>
+             {% for labelling in object.labelling_set.all %}
+                <span onmouseover="tooltip.show(tooltiptext('{{labelling.label.name}}', '{{labelling.creator.name}}', '{{labelling.created|utc}}'));" onmouseout="tooltip.hide();"  style="color: {{labelling.label.defaultColor}}">{{ labelling.label.name }}</span>
+             {% endfor %}
+        </td>
+        <td>{{ object.group.name }} </td>
+        <td>{{ object.get_analysisType_display }} </td>
+        <td>{{ object.instruments }}</td>
+        <td>{% if object.gpstime%}
+                {{ object.gpstime|multiTime:"ngps" }}
+            {% endif %}</td>
+        <td>{{ delta }}</td>
+        <td>{{ object.far|scientific }}</td>
+        <td><a href="{{ object.weburl }}">Data</a></td>
+        <td>{{ object.created|multiTime:"ncreated" }}</td>
+    </tr>
+    {% endfor %}
+</table>
+{% else %}
+<h4>No neighbors in range.</h4>
+{% endif %}
+</div>
-- 
GitLab