From ef2fbc67a923e4d39f0497943c11dc1eaeb74f5d Mon Sep 17 00:00:00 2001 From: luxagraf Date: Wed, 6 Sep 2017 19:28:47 -0600 Subject: updated bird and jrnl admins to make maps and photos better --- app/birds/admin.py | 22 ++++--------- app/birds/migrations/0007_auto_20170821_1415.py | 36 +++++++++++++++++++++ app/birds/migrations/0008_auto_20170821_1418.py | 20 ++++++++++++ app/birds/migrations/0009_auto_20170821_1429.py | 20 ++++++++++++ app/birds/migrations/0010_auto_20170906_2100.py | 25 ++++++++++++++ app/jrnl/admin.py | 8 +++-- app/photos/forms.py | 30 +++++++++++------ app/utils/util.py | 15 +++++++++ app/utils/widgets.py | 1 + design/sass/_birds.scss | 43 ++++++++++++++++++++++++- design/templates/archives/birds.html | 10 +++++- design/templates/details/bird.html | 20 +++++++----- 12 files changed, 213 insertions(+), 37 deletions(-) create mode 100644 app/birds/migrations/0007_auto_20170821_1415.py create mode 100644 app/birds/migrations/0008_auto_20170821_1418.py create mode 100644 app/birds/migrations/0009_auto_20170821_1429.py create mode 100644 app/birds/migrations/0010_auto_20170906_2100.py create mode 100644 app/utils/util.py diff --git a/app/birds/admin.py b/app/birds/admin.py index aa2aabb..b5c6a7e 100644 --- a/app/birds/admin.py +++ b/app/birds/admin.py @@ -1,22 +1,9 @@ from django.contrib import admin from django.contrib.gis.admin import OSMGeoAdmin from birds.models import BirdSighting, BirdAudio, BirdClass, Bird -from django.contrib.gis.geos import GEOSGeometry from photos.forms import GalleryForm -from daily.models import CheckIn - - -def convertll(lat, lon): - pnt = GEOSGeometry('POINT({0} {1})'.format(lon, lat), srid=4326) - pnt.transform(3857) - return pnt.y, pnt.x - - -def get_latlon(): - loc = CheckIn.objects.latest() - lat_converted, lon_converted = convertll(loc.lat, loc.lon) - return lat_converted, lon_converted +from utils.util import get_latlon class BirdClassAdmin(admin.ModelAdmin): @@ -31,9 +18,14 @@ class BirdAdmin(admin.ModelAdmin): list_display = ('pk', 'common_name', 'scientific_name', 'code', 'bird_class') list_filter = ('bird_class',) +class GalleryFormPlus(GalleryForm): + def __init__(self, *args, **kwargs): + super(GalleryFormPlus, self).__init__(*args, **kwargs) + self.base_fields['seen_by'].widget = CustomSelectMultiple() + class BirdSightingAdmin(OSMGeoAdmin): - form = GalleryForm + form = GalleryFormPlus list_filter = ( ) list_display = ('bird', 'location') diff --git a/app/birds/migrations/0007_auto_20170821_1415.py b/app/birds/migrations/0007_auto_20170821_1415.py new file mode 100644 index 0000000..a51776c --- /dev/null +++ b/app/birds/migrations/0007_auto_20170821_1415.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-08-21 14:15 +from __future__ import unicode_literals + +import django.contrib.gis.db.models.fields +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('photos', '0018_auto_20161130_1218'), + ('birds', '0006_auto_20170714_2224'), + ] + + operations = [ + migrations.AlterModelOptions( + name='birdsighting', + options={'get_latest_by': 'date', 'verbose_name_plural': 'Bird Sighting'}, + ), + migrations.RemoveField( + model_name='birdsighting', + name='images', + ), + migrations.AddField( + model_name='birdsighting', + name='image', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='photos.LuxImage'), + ), + migrations.AlterField( + model_name='birdsighting', + name='point', + field=django.contrib.gis.db.models.fields.PointField(blank=True, srid=4326), + ), + ] diff --git a/app/birds/migrations/0008_auto_20170821_1418.py b/app/birds/migrations/0008_auto_20170821_1418.py new file mode 100644 index 0000000..e5c80a4 --- /dev/null +++ b/app/birds/migrations/0008_auto_20170821_1418.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-08-21 14:18 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('birds', '0007_auto_20170821_1415'), + ] + + operations = [ + migrations.RenameField( + model_name='birdsighting', + old_name='image', + new_name='images', + ), + ] diff --git a/app/birds/migrations/0009_auto_20170821_1429.py b/app/birds/migrations/0009_auto_20170821_1429.py new file mode 100644 index 0000000..840d7d3 --- /dev/null +++ b/app/birds/migrations/0009_auto_20170821_1429.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-08-21 14:29 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('birds', '0008_auto_20170821_1418'), + ] + + operations = [ + migrations.RenameField( + model_name='birdsighting', + old_name='images', + new_name='image', + ), + ] diff --git a/app/birds/migrations/0010_auto_20170906_2100.py b/app/birds/migrations/0010_auto_20170906_2100.py new file mode 100644 index 0000000..aada189 --- /dev/null +++ b/app/birds/migrations/0010_auto_20170906_2100.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9 on 2017-09-06 21:00 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('photos', '0018_auto_20161130_1218'), + ('birds', '0009_auto_20170821_1429'), + ] + + operations = [ + migrations.RemoveField( + model_name='birdsighting', + name='image', + ), + migrations.AddField( + model_name='birdsighting', + name='images', + field=models.ManyToManyField(blank=True, to='photos.LuxImage'), + ), + ] diff --git a/app/jrnl/admin.py b/app/jrnl/admin.py index e71b733..e2b6c0b 100644 --- a/app/jrnl/admin.py +++ b/app/jrnl/admin.py @@ -6,6 +6,7 @@ from utils.widgets import AdminImageWidget, LGEntryForm from .models import Entry, HomepageCurrator from photos.forms import GalleryForm +from utils.util import get_latlon @admin.register(Entry) @@ -51,9 +52,10 @@ class EntryAdmin(OSMGeoAdmin): }), ) # options for OSM map Using custom ESRI topo map - default_lon = -9285175 - default_lat = 4025046 - default_zoom = 6 + lat, lon = get_latlon() + default_lon = lon + default_lat = lat + default_zoom = 10 units = True scrollable = False map_width = 700 diff --git a/app/photos/forms.py b/app/photos/forms.py index 9fd5529..97359e0 100644 --- a/app/photos/forms.py +++ b/app/photos/forms.py @@ -34,20 +34,32 @@ class GalleryForm(forms.ModelForm): def __init__(self, *args, **kwargs): super(GalleryForm, self).__init__(*args, **kwargs) + self.fields['images'].choices = [(image.id, mark_safe('%sqq%sqq%s' % (image.title, image.get_image_by_size('tn'), image.pk))) for image in LuxImage.objects.all()] + self.fields['images'].allow_tags = True - images = LuxImage.objects.all()[:100] - items = [] - for image in images: - items.append( - (image.pk, mark_safe('%sqq%sqq%s' % (image.title, image.get_image_by_size('tn'), image.pk))) - ) - +from django.utils.safestring import mark_safe + +class ImageChoiceField(forms.ModelMultipleChoiceField): + + def label_from_instance(self, obj): + + return mark_safe('%sqq%sqq%s' % (obj.title, obj.get_image_by_size('tn'), obj.pk)) - self.fields['images'].choices = items - self.fields['images'].allow_tags = True +class FKGalleryForm(forms.ModelForm): + class Meta: + fields = '__all__' + widgets = { + 'image': ImageChoiceField(queryset=LuxImage.objects.all()), + } + + def __init__(self, *args, **kwargs): + super(FKGalleryForm, self).__init__(*args, **kwargs) + self.fields['image'].choices = [(o.id, str(o.image.url)) for o in LuxImage.objects.all()] + self.fields['image'].allow_tags = True + class UploadZipForm(forms.Form): """ Handles the uploading of a gallery of photos packed in a .zip file diff --git a/app/utils/util.py b/app/utils/util.py new file mode 100644 index 0000000..3da6d06 --- /dev/null +++ b/app/utils/util.py @@ -0,0 +1,15 @@ +from daily.models import CheckIn +from django.contrib.gis.geos import GEOSGeometry + + +def convertll(lat, lon): + pnt = GEOSGeometry('POINT({0} {1})'.format(lon, lat), srid=4326) + pnt.transform(3857) + return pnt.y, pnt.x + + +def get_latlon(): + loc = CheckIn.objects.latest() + lat_converted, lon_converted = convertll(loc.lat, loc.lon) + return lat_converted, lon_converted + diff --git a/app/utils/widgets.py b/app/utils/widgets.py index 8e390d5..240820a 100644 --- a/app/utils/widgets.py +++ b/app/utils/widgets.py @@ -5,6 +5,7 @@ from django.contrib.admin.widgets import AdminFileWidget from django.contrib.gis.admin import OSMGeoAdmin from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ +from django.forms.widgets import SelectMultiple from django.conf import settings import markdown diff --git a/design/sass/_birds.scss b/design/sass/_birds.scss index d8a736e..81149ff 100644 --- a/design/sass/_birds.scss +++ b/design/sass/_birds.scss @@ -6,7 +6,7 @@ display: none !important; } -#birds { +#birds, .birds { .post--title { @include fontsize(18); a { @@ -21,6 +21,42 @@ } small { display: block;} } + .post--image { + position: relative; + width: 100%; + figcaption { + opacity: 0; + @include fancy-sans; + @include fontsize(13); + position: absolute; + bottom: 0; + text-align: left; + width: 99%; + background: rgba(0, 0, 0, 0.75); + padding: .5em 0 .5em .5em; + margin-bottom: .5em; + color: #ccc; + + a { + color: #ccc; + } + } + img { + max-width: 100%; + width: 100%; + padding: 0; + background: none; + } + .picfull { + margin: 0; + } + } + .post--image:hover figcaption { + -webkit-transition: opacity .25s ease-in; + -moz-transition: opacity .25s ease-in; + transition: opacity .25s ease-in; + opacity: 1; + } } .sci { @@ -49,6 +85,11 @@ @include constrain_narrow; } } + #endnode { + @include fancy-sans; + @include fontsize(14); + margin-top: 2em; + } } diff --git a/design/templates/archives/birds.html b/design/templates/archives/birds.html index 32a7aa1..db7c860 100644 --- a/design/templates/archives/birds.html +++ b/design/templates/archives/birds.html @@ -17,7 +17,15 @@

Birds seen {% if region %}in {%if region.name == 'United States'%}the United States{%else%}{{region.name|title|smartypants|safe}}{%endif%}{%else%} by {{user}}{%endif%}

{% for object in object_list %}
- {{ object.title }} +{% load get_image_by_size %} +{% load get_image_width %} +
+ +{{object.image.alt}} photographed by {% if object.image.photo_credit_source %}{{object.image.photo_credit_source}}{%else%}luxagraf{%endif%} + +{% if object.image.photo_credit_source %}
photo by {{object.image.photo_credit_source}}
{%endif%} +

{{object.bird|safe|smartypants|widont}} ({{object.bird.scientific_name}})

diff --git a/design/templates/details/bird.html b/design/templates/details/bird.html index 5140c96..43877fe 100644 --- a/design/templates/details/bird.html +++ b/design/templates/details/bird.html @@ -12,20 +12,24 @@

{{object.common_name}}

{{object.scientific_name}}

Family {{object.bird_class.scientific_name}} ({{object.bird_class}})

-{% for image in sighting.images.all %} -{{image.alt}} ({{sighting.bird.scientific_name}}) photographed by {% if image.photo_credit_source %}{{image.photo_credit_source}}{%else%}Scott Gilbertson{%endif%} -{%endfor%} - +{% load get_image_by_size %} +{% load get_image_width %} +
+
+{{sighting.image.alt}} photographed by {% if sighting.image.photo_credit_source %}{{sighting.image.photo_credit_source}}{%else%}luxagraf{%endif%} +{% if sighting.image.photo_credit_source %}
photo by {{sighting.image.photo_credit_source}}
{%endif%} +
+
+{%if recording %}
Audio recorded by {{recording.recorder}} on {{recording.pub_date|date:"F j, Y"}} in {{recording.location}}. © {{recording.copyright}}
- -

Seen at {{sighting.location}}, {{sighting.location.comma_name}} in {{sighting.date|date:"M Y"}} by {% for person in sighting.seen_by.all %}{{person}}{%if forloop.last %}{%else%}{% if forloop.revcounter == 2 %}, and {%else%}, {%endif%}{%endif%}{%endfor%}

+{%endif%} +

Seen at {{sighting.location}}, {{sighting.location.comma_name}} in {{sighting.date|date:"M Y"}} by {% for person in sighting.seen_by.all %}{% if person.username == "luxagraf"%}Scott{%else%}{{person.username|capfirst}}{%endif%}{%if forloop.last %}{%else%}{% if forloop.revcounter == 2 %}, and {%else%}, {%endif%}{%endif%}{%endfor%}

{% if recording.audio %} {%endif%}
-- cgit v1.2.3