summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/books/admin.py2
-rw-r--r--app/books/models.py13
-rw-r--r--app/jrnl/models.py10
-rw-r--r--app/jrnl/views.py1
-rw-r--r--app/links/admin.py3
-rw-r--r--app/links/models.py18
-rw-r--r--app/locations/admin.py7
-rw-r--r--app/locations/models.py20
-rw-r--r--app/photos/admin.py2
-rw-r--r--app/photos/models.py17
-rw-r--r--app/photos/static/image-preview.js13
-rw-r--r--app/photos/views.py10
-rw-r--r--app/sightings/admin.py4
-rw-r--r--app/sightings/models.py20
-rw-r--r--app/sketches/admin.py2
-rw-r--r--app/sketches/models.py12
-rw-r--r--app/utils/static/next-prev-links.js80
-rw-r--r--app/utils/urls.py12
-rw-r--r--app/utils/views.py13
-rw-r--r--config/base_urls.py1
-rw-r--r--design/templates/archives/sightings.html2
21 files changed, 208 insertions, 54 deletions
diff --git a/app/books/admin.py b/app/books/admin.py
index 1896067..29a885f 100644
--- a/app/books/admin.py
+++ b/app/books/admin.py
@@ -7,6 +7,8 @@ class BookAdmin(admin.ModelAdmin):
search_fields = ['title', 'body_markdown']
list_filter = ('rating', 'read_date')
+ class Media:
+ js = ('next-prev-links.js',)
class BookHighlightAdmin(admin.ModelAdmin):
list_display = ('book', 'page', 'date_added')
diff --git a/app/books/models.py b/app/books/models.py
index f888480..ebd3a2a 100644
--- a/app/books/models.py
+++ b/app/books/models.py
@@ -56,6 +56,19 @@ class Book(models.Model):
def ratings_range(cls):
return range(1, 6)
+ @property
+ def get_previous_admin_url(self):
+ n = self.get_previous_by_pub_date()
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[n.id] )
+
+ @property
+ def get_next_admin_url(self):
+ model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name)
+ try:
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[self.get_next_by_pub_date().pk] )
+ except model.DoesNotExist:
+ return ''
+
def admin_thumbnail(self):
return force_text('<a href=""><img src="%s" width="100" style="width:100px"></a>' % (self.get_image_url()))
admin_thumbnail.allow_tags = True
diff --git a/app/jrnl/models.py b/app/jrnl/models.py
index d0b9120..b9018bf 100644
--- a/app/jrnl/models.py
+++ b/app/jrnl/models.py
@@ -5,6 +5,7 @@ import re
from django.contrib.gis.db import models
from django.utils.html import format_html
from django.urls import reverse
+from django.apps import apps
from django.template.loader import render_to_string
from django.conf import settings
from django.template import Context
@@ -156,7 +157,7 @@ class Entry(models.Model):
@property
def get_previous_admin_url(self):
n = self.get_previous_by_pub_date()
- return "/admin/jrnl/entry/%s/change/" % n.pk
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[n.id] )
@property
@@ -165,8 +166,11 @@ class Entry(models.Model):
@property
def get_next_admin_url(self):
- n = self.get_next_by_pub_date()
- return "/admin/jrnl/entry/%s/change/" % n.pk
+ model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name)
+ try:
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[self.get_next_by_pub_date().pk] )
+ except model.DoesNotExist:
+ return ''
def save(self):
if self.pk:
diff --git a/app/jrnl/views.py b/app/jrnl/views.py
index 59fff7a..7cf0bb9 100644
--- a/app/jrnl/views.py
+++ b/app/jrnl/views.py
@@ -1,3 +1,4 @@
+import simplejson
from django.views.generic import ListView
from django.views.generic.detail import DetailView
from django.views.generic.dates import YearArchiveView, MonthArchiveView
diff --git a/app/links/admin.py b/app/links/admin.py
index c1c0bdb..1811b3f 100644
--- a/app/links/admin.py
+++ b/app/links/admin.py
@@ -33,4 +33,7 @@ class LinkAdmin(admin.ModelAdmin):
}),
)
+ class Media:
+ js = ('next-prev-links.js',)
+
admin.site.register(Link, LinkAdmin)
diff --git a/app/links/models.py b/app/links/models.py
index 4954a29..cdbe680 100644
--- a/app/links/models.py
+++ b/app/links/models.py
@@ -4,6 +4,7 @@ from django.template.defaultfilters import striptags
from django.urls import reverse
from django.utils.encoding import force_text
from django.utils.html import format_html
+from django.apps import apps
from django.db import models
from django.utils import timezone
from django.core.mail import EmailMessage
@@ -69,6 +70,23 @@ class Link(models.Model):
return format_html('<a href="%s">Visit Site</a>' % (self.url))
admin_link.short_description = 'Link'
+ @property
+ def get_next_published(self):
+ return self.get_next_by_pub_date(status__exact=1)
+
+ @property
+ def get_previous_admin_url(self):
+ n = self.get_previous_by_pub_date()
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[n.id] )
+
+ @property
+ def get_next_admin_url(self):
+ model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name)
+ try:
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[self.get_next_by_pub_date().pk] )
+ except model.DoesNotExist:
+ return ''
+
@receiver(post_save, sender=Link)
def post_save_events(sender, update_fields, created, instance, **kwargs):
diff --git a/app/locations/admin.py b/app/locations/admin.py
index c3419b1..4a52778 100644
--- a/app/locations/admin.py
+++ b/app/locations/admin.py
@@ -3,6 +3,7 @@ from django.contrib.gis.admin import OSMGeoAdmin
from locations.models import Region, Country, Location, State, Route, CheckIn
from utils.widgets import OLAdminBase
+from utils.util import get_latlon
class RegionAdmin(OSMGeoAdmin):
list_display = ('name', 'slug')
@@ -183,8 +184,7 @@ class LocationAdmin(OSMGeoAdmin):
}),
)
# options for OSM map Using custom ESRI topo map
- default_lon = -9285175
- default_lat = 4025046
+ default_lat, default_lon = get_latlon()
default_zoom = 6
units = True
scrollable = False
@@ -193,6 +193,9 @@ class LocationAdmin(OSMGeoAdmin):
map_template = 'gis/admin/osm.html'
openlayers_url = '/static/admin/js/OpenLayers.js'
+ class Media:
+ js = ('next-prev-links.js',)
+
admin.site.register(Location, LocationAdmin)
diff --git a/app/locations/models.py b/app/locations/models.py
index e9c79e5..f9a3e5b 100644
--- a/app/locations/models.py
+++ b/app/locations/models.py
@@ -1,5 +1,7 @@
import json
import requests
+from django.urls import reverse
+from django.apps import apps
from django.contrib.gis.geos import GEOSGeometry, fromstr, MultiPolygon
from django.contrib.gis.db import models
from django.contrib.sitemaps import Sitemap
@@ -117,9 +119,13 @@ class Location(models.Model):
state = models.ForeignKey(State, on_delete=models.CASCADE)
name = models.CharField(max_length=50, )
slug = models.SlugField()
- pub_date = models.DateTimeField('Date published', null=True)
+ pub_date = models.DateTimeField('Date published')
geometry = models.MultiPolygonField(srid=4326)
+ class Meta:
+ ordering = ('-pub_date',)
+ get_latest_by = 'pub_date'
+
def __str__(self):
return self.name
@@ -129,6 +135,18 @@ class Location(models.Model):
else:
return self.state.country
+ @property
+ def get_previous_admin_url(self):
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[self.get_previous_by_pub_date().id] )
+
+ @property
+ def get_next_admin_url(self):
+ model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name)
+ try:
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[self.get_next_by_pub_date().pk] )
+ except model.DoesNotExist:
+ return ''
+
def get_absolute_url(self):
return "/locations/%s/%s/%s/" % (self.state.country.slug, self.state.slug, self.slug)
diff --git a/app/photos/admin.py b/app/photos/admin.py
index d0f28d7..a052169 100644
--- a/app/photos/admin.py
+++ b/app/photos/admin.py
@@ -52,7 +52,7 @@ class LuxImageAdmin(OSMGeoAdmin):
)
class Media:
- js = ('image-preview.js','next-prev-links.js')
+ js = ('image-preview.js',)
admin.site.register(LuxImage, LuxImageAdmin)
diff --git a/app/photos/models.py b/app/photos/models.py
index d68cd09..91ac15d 100644
--- a/app/photos/models.py
+++ b/app/photos/models.py
@@ -145,18 +145,21 @@ class LuxImage(models.Model):
return self.get_previous_by_pub_date()
@property
- def get_previous_admin_url(self):
- n = self.get_previous_by_pub_date()
- return "/admin/photos/luximage/%s/change/" % n.pk
-
- @property
def get_next_published(self):
return self.get_next_by_pub_date()
@property
+ def get_previous_admin_url(self):
+ n = self.get_previous_by_pub_date()
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[n.id] )
+
+ @property
def get_next_admin_url(self):
- n = self.get_next_by_pub_date()
- return "/admin/photos/luximage/%s/change/" % n.pk
+ model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name)
+ try:
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[self.get_next_by_pub_date().pk] )
+ except model.DoesNotExist:
+ return ''
@property
def is_portait(self):
diff --git a/app/photos/static/image-preview.js b/app/photos/static/image-preview.js
index 13445f2..aac9c0b 100644
--- a/app/photos/static/image-preview.js
+++ b/app/photos/static/image-preview.js
@@ -1,7 +1,7 @@
function build_image_preview () {
- var style = document.createElement('style');
var url = window.location.href
var cur = url.split('/')[6];
+ if (cur) {
var container = document.createElement("div");
container.className = "form-row field-image";
var wrapper = document.createElement("div");
@@ -9,13 +9,14 @@ function build_image_preview () {
label.textContent = "Image:";
var pwrap = document.createElement("p");
var img = document.createElement("img");
+
var request = new XMLHttpRequest();
- request.open('GET', '/photos/data/admin/preview/'+cur+'/', true);
+ request.open('GET', '/photos/luximage/data/admin/preview/'+cur+'/', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
- resp = request.responseText;
+ var data = JSON.parse(request.responseText);
//console.log(resp);
- img.src = resp;
+ img.src = data['url'];
} else {
console.log("server error");
}
@@ -24,6 +25,7 @@ function build_image_preview () {
console.log("error on request");
};
request.send();
+
pwrap.appendChild(img);
wrapper.appendChild(label);
wrapper.appendChild(pwrap);
@@ -31,6 +33,9 @@ function build_image_preview () {
parent = document.getElementById("luximage_form");
node = parent.children[1].children[0];
node.parentNode.insertBefore(container, node.previousSibling);
+ } else {
+ return;
+ }
}
document.addEventListener("DOMContentLoaded", function(event) {
build_image_preview();
diff --git a/app/photos/views.py b/app/photos/views.py
index fd32828..c0daf4d 100644
--- a/app/photos/views.py
+++ b/app/photos/views.py
@@ -69,14 +69,16 @@ def photo_json(request, slug):
p = PhotoGallery.objects.filter(set_slug=slug)
return HttpResponse(serializers.serialize('json', p), mimetype='application/json')
+import simplejson
def photo_preview_json(request, pk):
p = LuxImage.objects.get(pk=pk)
- data = ()
+ data = {}
data['url'] = p.get_admin_image()
- data['prev'] = p.get_previous_admin_url()
- data['next'] = p.get_next_admin_url()
- return HttpResponse(serializers.serialize('json', data), mimetype='application/json')
+ data['prev'] = p.get_previous_admin_url
+ data['next'] = p.get_next_admin_url
+ data = simplejson.dumps(data)
+ return HttpResponse(data)
def gallery_list_by_area(request, slug, page):
diff --git a/app/sightings/admin.py b/app/sightings/admin.py
index 9cd0fef..433d465 100644
--- a/app/sightings/admin.py
+++ b/app/sightings/admin.py
@@ -46,3 +46,7 @@ class SightingAdmin(OSMGeoAdmin):
map_height = 425
map_template = 'gis/admin/osm.html'
openlayers_url = '/static/admin/js/OpenLayers.js'
+
+ class Media:
+ js = ('next-prev-links.js',)
+
diff --git a/app/sightings/models.py b/app/sightings/models.py
index 96e0b5e..792c52b 100644
--- a/app/sightings/models.py
+++ b/app/sightings/models.py
@@ -1,5 +1,6 @@
import datetime
from django.urls import reverse
+from django.apps import apps
from django.template.defaultfilters import slugify
from django.contrib.gis.db import models
from django.contrib.auth.models import User
@@ -82,14 +83,14 @@ class Sighting(models.Model):
ap = models.ForeignKey(AP, on_delete=models.CASCADE)
point = models.PointField(blank=True)
location = models.ForeignKey(Location, on_delete=models.CASCADE, blank=True)
- date = models.DateTimeField('Date', default=timezone.now)
+ pub_date = models.DateTimeField('Date', default=timezone.now)
seen_by = models.ManyToManyField(User)
images = models.ManyToManyField(LuxImage, blank=True)
#audio = models.ManyToManyField(BirdAudio, blank=True)
class Meta:
- ordering = ["-date", ]
- get_latest_by = "date"
+ ordering = ["-pub_date", ]
+ get_latest_by = "pub_date"
@property
def state(self):
@@ -113,6 +114,19 @@ class Sighting(models.Model):
'''Get the site's latitude.'''
return self.point.y
+ @property
+ def get_previous_admin_url(self):
+ n = self.get_previous_by_pub_date()
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[n.id] )
+
+ @property
+ def get_next_admin_url(self):
+ model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name)
+ try:
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[self.get_next_by_pub_date().pk] )
+ except model.DoesNotExist:
+ return ''
+
def get_small_image(self):
for img in self.images.all():
for size in img.sizes.all():
diff --git a/app/sketches/admin.py b/app/sketches/admin.py
index 41715aa..07a2e6a 100644
--- a/app/sketches/admin.py
+++ b/app/sketches/admin.py
@@ -34,7 +34,7 @@ class SketchAdmin(OLAdminBase):
default_zoom = 10
class Media:
- js = ('image-loader.js',)
+ js = ('image-loader.js', 'next-prev-links.js')
diff --git a/app/sketches/models.py b/app/sketches/models.py
index c7d28a5..2d7f9ac 100644
--- a/app/sketches/models.py
+++ b/app/sketches/models.py
@@ -58,6 +58,18 @@ class Sketch(models.Model):
def get_next_published(self):
return self.get_next_by_pub_date()
+ @property
+ def get_previous_admin_url(self):
+ n = self.get_previous_by_pub_date()
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[n.id] )
+
+ @property
+ def get_next_admin_url(self):
+ model = apps.get_model(app_label=self._meta.app_label, model_name=self._meta.model_name)
+ try:
+ return reverse('admin:%s_%s_change' %(self._meta.app_label, self._meta.model_name), args=[self.get_next_by_pub_date().pk] )
+ except model.DoesNotExist:
+ return ''
def save(self, *args, **kwargs):
md = render_images(self.body_markdown)
diff --git a/app/utils/static/next-prev-links.js b/app/utils/static/next-prev-links.js
index 7af1b66..82a1dd8 100644
--- a/app/utils/static/next-prev-links.js
+++ b/app/utils/static/next-prev-links.js
@@ -1,33 +1,59 @@
function build_next_prev() {
+
var url = window.location.href
- var style = document.createElement('style');
- style.type = 'text/css';
- style.innerHTML = '.np-container {padding-left: 0;} .prev, .next {display: inline-block; margin-right: .5em;} .prev:after { content: "|"; margin-left:.5em;} .prev a:before {content: "\u00AB"; margin-right: 3px;} .next a:after{content: "\u00BB"; margin-left: 3px;}';
- document.getElementsByTagName('head')[0].appendChild(style);
var cur = Number(url.split('/')[6]);
- var base_url = url.split(cur)[0];
- var next = cur+1;
- var prev = cur-1;
- var container = document.createElement("ul");
- var next_li = document.createElement("li");
- var next_link = document.createElement("a");
- var prev_li = document.createElement("li");
- var prev_link = document.createElement("a");
- prev_li.className = "prev";
- next_li.className = "next";
- container.className = "np-container";
- next_link.href = base_url + next + "/change/";
- next_link.textContent = "Next";
- prev_link.href = base_url + prev + "/change/";
- prev_link.textContent = "Prev";
- next_li.appendChild(next_link);
- prev_li.appendChild(prev_link);
- container.appendChild(prev_li);
- container.appendChild(next_li);
- console.log(container);
- Array.from(document.getElementsByClassName('object-tools')).forEach(function(item) {
- item.parentNode.insertBefore(container, item.nextSibling);
- })
+ var app = url.split('/')[4];
+ var model = url.split('/')[5];
+ if (cur) {
+ var style = document.createElement('style');
+ style.type = 'text/css';
+ style.innerHTML = '.np-container {padding-left: 0;} .prev, .next {display: inline-block; margin-right: .5em;} .prev:after { content: "|"; margin-left:.5em;} .prev a:before {content: "\u00AB"; margin-right: 3px;} .next a:after{content: "\u00BB"; margin-left: 3px;}';
+ document.getElementsByTagName('head')[0].appendChild(style);
+
+ json_url = '/admin/data/'+app+'/'+model+'/'+cur+'/';
+ console.log(json_url);
+
+ var container = document.createElement("ul");
+ var next_li = document.createElement("li");
+ var next_link = document.createElement("a");
+ var prev_li = document.createElement("li");
+ var prev_link = document.createElement("a");
+ prev_li.className = "prev";
+ next_li.className = "next";
+ container.className = "np-container";
+ next_link.textContent = "Next";
+ prev_link.textContent = "Prev";
+
+ var request = new XMLHttpRequest();
+ request.open('GET', json_url, true);
+ request.onload = function() {
+ if (request.status >= 200 && request.status < 400) {
+ var data = JSON.parse(request.responseText);
+ next_link.href = data['next'];
+ prev_link.href = data['prev'];
+ if (data['next'] != '') {
+ next_li.appendChild(next_link);
+ }
+ if (data['prev']) {
+ prev_li.appendChild(prev_link);
+ }
+ } else {
+ console.log("server error");
+ }
+ };
+ request.onerror = function() {
+ console.log("error on request");
+ };
+ request.send();
+ container.appendChild(prev_li);
+ container.appendChild(next_li);
+ //console.log(container);
+ Array.from(document.getElementsByClassName('object-tools')).forEach(function(item) {
+ item.parentNode.insertBefore(container, item.nextSibling);
+ })
+ } else {
+ return;
+ }
};
document.addEventListener("DOMContentLoaded", function(event) {
build_next_prev();
diff --git a/app/utils/urls.py b/app/utils/urls.py
new file mode 100644
index 0000000..7c37c5d
--- /dev/null
+++ b/app/utils/urls.py
@@ -0,0 +1,12 @@
+from django.urls import path
+
+from . import views
+
+
+urlpatterns = [
+ path(
+ r'<str:app>/<str:model>/<int:pk>/',
+ views.nav_json,
+ name="admin_links"
+ ),
+]
diff --git a/app/utils/views.py b/app/utils/views.py
index 0b96111..6ebf44d 100644
--- a/app/utils/views.py
+++ b/app/utils/views.py
@@ -1,4 +1,6 @@
from itertools import chain
+import json
+from django.http import Http404, HttpResponse
from django.views.generic import ListView
from photos.models import LuxImage, LuxVideo
from django.shortcuts import render_to_response
@@ -53,3 +55,14 @@ class TagAutocomplete(autocomplete.Select2QuerySetView):
qs = qs.filter(name__istartswith=self.q)
return qs
+
+from django.apps import apps
+
+def nav_json(request, app, model, pk):
+ model = apps.get_model(app_label=app, model_name=model)
+ p = model.objects.get(pk=pk)
+ data = {}
+ data['prev'] = p.get_previous_admin_url
+ data['next'] = p.get_next_admin_url
+ data = json.dumps(data)
+ return HttpResponse(data)
diff --git a/config/base_urls.py b/config/base_urls.py
index 9493d2f..fd7d6a7 100644
--- a/config/base_urls.py
+++ b/config/base_urls.py
@@ -34,6 +34,7 @@ sitemaps = {
urlpatterns = [
path(r'tag-autocomplete/', TagAutocomplete.as_view(), name='tag-autocomplete'),
re_path(r'^admin/build/.*', builder.views.do_build),
+ path(r'admin/data/', include('utils.urls')),
path(r'admin/', admin.site.urls),
path(r'luximages/insert/', utils.views.insert_image),
path(r'sitemap.xml', sitemap, {'sitemaps': sitemaps}),
diff --git a/design/templates/archives/sightings.html b/design/templates/archives/sightings.html
index 89e31ce..e9d4610 100644
--- a/design/templates/archives/sightings.html
+++ b/design/templates/archives/sightings.html
@@ -28,7 +28,7 @@
</figure>
</div>
<h3 class="post--title"><a href="{{object.ap.get_absolute_url}}" title="{%if object.title_keywords%}{{object.title_keywords}}{%else%}{{object.ap}}{%endif%}">{{object.ap|safe|smartypants|widont}}</a> (<span class="sci">{{object.ap.scientific_name}}</span>)</h3>
- <time class="post--date" datetime="{{object.date|date:'c'}}">Seen: {{object.date|date:"F"}} <span>{{object.date|date:"j, Y"}}</span></time>
+ <time class="post--date" datetime="{{object.pub_date|date:'c'}}">Seen: {{object.pub_date|date:"F"}} <span>{{object.pub_date|date:"j, Y"}}</span></time>
<p>
<span class="sighting location place post--location" itemscope itemtype="http://schema.org/Place">Loc:
{% if object.country.name == "United States" %}<span class="p-locality locality">{{object.location.name|smartypants|safe}}</span>, {{object.state.name}}, <span class="p-country-name">U.S.</span>{%else%}<span class="p-region">{{object.location.name|smartypants|safe}}</span>, {{object.country.name}}</a>{%endif%}