summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/notes/admin.py34
-rw-r--r--app/notes/migrations/0001_initial.py63
-rw-r--r--app/notes/migrations/0002_auto_20160208_1107.py20
-rw-r--r--app/notes/migrations/0003_auto_20160208_1120.py33
-rw-r--r--app/notes/migrations/__init__.py0
-rw-r--r--app/notes/models.py58
-rw-r--r--app/notes/urls.py28
-rw-r--r--app/notes/views.py33
-rw-r--r--app/utils/widgets.py7
-rw-r--r--config/base_urls.py5
-rw-r--r--design/templates/admin/notes/change_form.html19
-rw-r--r--design/templates/archives/notes.html6
-rw-r--r--design/templates/details/note.html6
13 files changed, 291 insertions, 21 deletions
diff --git a/app/notes/admin.py b/app/notes/admin.py
index 794e882..3e15be2 100644
--- a/app/notes/admin.py
+++ b/app/notes/admin.py
@@ -1,19 +1,37 @@
from django.contrib import admin
from django.contrib.gis.admin import OSMGeoAdmin
-from notes.models import Note
-from django import forms
+from notes.models import Note, LuxNote
+from utils.widgets import AdminImageWidget, LGEntryForm, LGEntryFormSmall, OLAdminBase
-class NoteModelForm(forms.ModelForm):
- body_markdown = forms.CharField(widget=forms.Textarea(attrs={'maxlength': 40000, 'rows': 20, 'cols': 75}), label='Note')
- class Meta:
- model = Note
- fields = '__all__'
+class LuxNoteAdmin(OLAdminBase):
+ form = LGEntryFormSmall
+ prepopulated_fields = {"slug": ('title',)}
+ list_display = ('slug', 'pub_date', 'location')
+ fieldsets = (
+ ('Note', {
+ 'fields': (
+ ('title', 'slug'),
+ 'body_markdown',
+ 'pub_date',
+ 'point'
+ ),
+ 'classes': (
+ 'show',
+ 'extrapretty',
+ 'wide'
+ )
+ }
+ ),
+ )
+
+
+admin.site.register(LuxNote, LuxNoteAdmin)
class NoteAdmin(OSMGeoAdmin):
- form = NoteModelForm
+ form = LGEntryForm
list_display = ('slug', 'date_created', 'location', 'twitter_id')
list_filter = ('location',)
prepopulated_fields = {"slug": ('title',)}
diff --git a/app/notes/migrations/0001_initial.py b/app/notes/migrations/0001_initial.py
new file mode 100644
index 0000000..cf8396a
--- /dev/null
+++ b/app/notes/migrations/0001_initial.py
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-02-08 10:57
+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):
+
+ initial = True
+
+ dependencies = [
+ ('locations', '__first__'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='LuxNote',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(blank=True, max_length=250, null=True)),
+ ('slug', models.SlugField(blank=True, unique_for_date='date_created')),
+ ('date_created', models.DateTimeField(editable=False)),
+ ('date_last_updated', models.DateTimeField(blank=True, verbose_name='Date')),
+ ('body_html', models.TextField(blank=True)),
+ ('body_markdown', models.TextField(verbose_name='Note')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Note',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('title', models.CharField(blank=True, max_length=250, null=True)),
+ ('slug', models.SlugField(blank=True, unique_for_date='date_created')),
+ ('date_created', models.DateTimeField(blank=True, verbose_name='Date')),
+ ('date_last_updated', models.DateTimeField(blank=True, verbose_name='Date')),
+ ('point', django.contrib.gis.db.models.fields.PointField(srid=4326)),
+ ('city_name', models.CharField(blank=True, max_length=250, null=True)),
+ ('state_name', models.CharField(blank=True, max_length=250, null=True)),
+ ('country_name', models.CharField(blank=True, max_length=150, null=True)),
+ ('body_html', models.TextField(blank=True)),
+ ('body_markdown', models.TextField(verbose_name='Note')),
+ ('twitter_text', models.CharField(blank=True, max_length=450, null=True, verbose_name='Twitter text')),
+ ('twitter_id', models.CharField(max_length=450, verbose_name='twitter_id')),
+ ('twitter_send', models.BooleanField(default=False, verbose_name='send to twitter?')),
+ ('twitter_sent', models.BooleanField(default=False)),
+ ('location', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='locations.Location')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='OriginNoteForReplies',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('date_created', models.DateTimeField()),
+ ('profile_image', models.CharField(blank=True, max_length=450, null=True)),
+ ('screen_name', models.CharField(blank=True, max_length=75, null=True)),
+ ('body_html', models.TextField(blank=True)),
+ ('remote_url', models.CharField(blank=True, max_length=450, null=True)),
+ ],
+ ),
+ ]
diff --git a/app/notes/migrations/0002_auto_20160208_1107.py b/app/notes/migrations/0002_auto_20160208_1107.py
new file mode 100644
index 0000000..3333a34
--- /dev/null
+++ b/app/notes/migrations/0002_auto_20160208_1107.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-02-08 11:07
+from __future__ import unicode_literals
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('notes', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.RenameField(
+ model_name='luxnote',
+ old_name='date_created',
+ new_name='pub_date',
+ ),
+ ]
diff --git a/app/notes/migrations/0003_auto_20160208_1120.py b/app/notes/migrations/0003_auto_20160208_1120.py
new file mode 100644
index 0000000..ccdf46f
--- /dev/null
+++ b/app/notes/migrations/0003_auto_20160208_1120.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9 on 2016-02-08 11:20
+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 = [
+ ('locations', '__first__'),
+ ('notes', '0002_auto_20160208_1107'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='luxnote',
+ name='location',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='locations.Location'),
+ ),
+ migrations.AddField(
+ model_name='luxnote',
+ name='point',
+ field=django.contrib.gis.db.models.fields.PointField(blank=True, null=True, srid=4326),
+ ),
+ migrations.AlterField(
+ model_name='luxnote',
+ name='slug',
+ field=models.SlugField(blank=True, unique_for_date='pub_date'),
+ ),
+ ]
diff --git a/app/notes/migrations/__init__.py b/app/notes/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/notes/migrations/__init__.py
diff --git a/app/notes/models.py b/app/notes/models.py
index 6d5e805..775c78c 100644
--- a/app/notes/models.py
+++ b/app/notes/models.py
@@ -3,6 +3,7 @@ import datetime
from django.contrib.gis.db import models
from django.template.defaultfilters import slugify
from django.utils.html import urlize
+from django.utils import timezone
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.conf import settings
@@ -14,10 +15,67 @@ from twython import Twython
import markdown
#from twitter_text.autolink import Autolink
+from utils.widgets import markdown_to_html
+from daily.models import CheckIn
+
+
def twitter_truncate(txt):
return txt.split("|")[0]
+class LuxNote(models.Model):
+ title = models.CharField(max_length=250, null=True, blank=True)
+ slug = models.SlugField(unique_for_date='pub_date', blank=True)
+ pub_date = models.DateTimeField(default=timezone.now)
+ date_last_updated = models.DateTimeField('Date', blank=True)
+ body_html = models.TextField(blank=True)
+ body_markdown = models.TextField('Note')
+ point = models.PointField(blank=True, null=True)
+ location = models.ForeignKey(Location, blank=True, null=True)
+
+ def __str__(self):
+ return self.title
+
+ def get_absolute_url(self):
+ return reverse("notes:detail", kwargs={"year": self.pub_date.year, "month": self.pub_date.strftime("%m"), "slug": self.slug})
+
+ @property
+ def region(self):
+ return self.location.state.country.lux_region
+
+ @property
+ def longitude(self):
+ '''Get the site's longitude.'''
+ return round(self.point.x, 2)
+
+ @property
+ def latitude(self):
+ '''Get the site's latitude.'''
+ return round(self.point.y, 2)
+
+ @property
+ def get_previous_published(self):
+ return self.get_previous_by_pub_date()
+
+ @property
+ def get_next_published(self):
+ return self.get_next_by_pub_date()
+
+
+ def save(self, *args, **kwargs):
+ self.body_html = markdown_to_html(self.body_markdown)
+ if not self.point:
+ self.point = CheckIn.objects.latest().point
+ try:
+ self.location = Location.objects.filter(geometry__contains=self.point).get()
+ except Location.DoesNotExist:
+ raise forms.ValidationError("There is no location associated with that point, add it: %sadmin/locations/location/add/" % (settings.BASE_URL))
+ if not self.id:
+ self.pub_date= timezone.now()
+ self.date_last_updated = timezone.now()
+ super(LuxNote, self).save()
+
+
class Note(models.Model):
title = models.CharField(max_length=250, null=True, blank=True)
slug = models.SlugField(unique_for_date='date_created', blank=True)
diff --git a/app/notes/urls.py b/app/notes/urls.py
index 3f46915..00a8cce 100644
--- a/app/notes/urls.py
+++ b/app/notes/urls.py
@@ -1,4 +1,5 @@
from django.conf.urls import url
+from django.views.generic.base import RedirectView
from . import views
@@ -6,9 +7,23 @@ app_name = "notes"
urlpatterns = [
url(
+ r'(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+).txt$',
+ views.NoteDetailViewTXT.as_view(),
+ name="detail-txt"
+ ),
+ url(
+ r'(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+).amp$',
+ views.NoteDetailViewAMP.as_view(),
+ name="detail-amp"
+ ),
+ url(
r'(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+)$',
- views.entry_detail
+ views.NoteDetailView.as_view(),
+ name="detail"
),
+
+
+
url(
r'(?P<year>\d{4})/(?P<month>\d{2})/$',
views.date_list,
@@ -20,6 +35,17 @@ urlpatterns = [
name="notes_by_year"
),
url(
+ r'(?P<page>\d+)/$',
+ views.NoteList.as_view(),
+ name="list"
+ ),
+ # redirect / to /1/ for live server
+ url(
+ r'',
+ RedirectView.as_view(url="/field-notes/1/", permanent=False),
+ name="live_redirect"
+ ),
+ url(
r'^$',
views.entry_list,
name="notes_archive"
diff --git a/app/notes/views.py b/app/notes/views.py
index e89087e..b8bc04e 100644
--- a/app/notes/views.py
+++ b/app/notes/views.py
@@ -1,6 +1,37 @@
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
-from notes.models import Note
+from django.views.generic.detail import DetailView
+
+from utils.views import PaginatedListView
+
+from notes.models import LuxNote, Note
+
+
+class NoteList(PaginatedListView):
+ """
+ Return a list of Notes in reverse chronological order
+ """
+ queryset = LuxNote.objects.all().order_by('-pub_date')
+ template_name = "archives/notes.html"
+
+
+class NoteDetailView(DetailView):
+ model = LuxNote
+ template_name = "details/note.html"
+ slug_field = "slug"
+
+
+class NoteDetailViewTXT(NoteDetailView):
+ template_name = "details/entry.txt"
+
+
+class NoteDetailViewAMP(NoteDetailView):
+ template_name = "details/entry.amp"
+
+
+"""
+Legacy Notes views
+"""
def entry_detail(request, year, month, slug):
diff --git a/app/utils/widgets.py b/app/utils/widgets.py
index 6d6a334..290c7ab 100644
--- a/app/utils/widgets.py
+++ b/app/utils/widgets.py
@@ -90,10 +90,15 @@ class AdminImageWidget(AdminFileWidget):
class LGEntryForm(forms.ModelForm):
class Meta:
widgets = {
- 'body_markdown': forms.Textarea(attrs={'rows': 50, 'cols': 100}),
+ 'body_markdown': forms.Textarea(attrs={'rows': 40, 'cols': 100}),
}
+class LGEntryFormSmall(forms.ModelForm):
+ class Meta:
+ widgets = {
+ 'body_markdown': forms.Textarea(attrs={'rows': 12, 'cols': 100}),
+ }
class OLAdminBase(OSMGeoAdmin):
default_lon = -9285175
default_lat = 4025046
diff --git a/config/base_urls.py b/config/base_urls.py
index b5ee0db..122dfd1 100644
--- a/config/base_urls.py
+++ b/config/base_urls.py
@@ -46,10 +46,7 @@ urlpatterns += [
url(r'^expenses/', include('expenses.urls', namespace='expenses')),
url(r'^photos/', include('photos.urls')),
url(r'^books/', include('books.urls')),
- url(
- r'^field-notes/',
- include('notes.urls', namespace='notes')
- ),
+ url(r'^field-notes/', include('notes.urls')),
url(
r'^birds/',
include('birds.urls', namespace='birds')
diff --git a/design/templates/admin/notes/change_form.html b/design/templates/admin/notes/change_form.html
new file mode 100644
index 0000000..3d97a4f
--- /dev/null
+++ b/design/templates/admin/notes/change_form.html
@@ -0,0 +1,19 @@
+{% extends "admin/change_form.html" %}
+{% load i18n admin_urls %}
+{% block content %}
+ <a class="btn" onclick="geoFindMe();" href="javascript:void(0);" class="historylink">Get Location</a>
+ {{block.super}}
+{% endblock %}
+{% block object-tools-items %}
+ <li>
+ <a onclick="geoFindMe();" href="javascript:void(0);" class="historylink">Get Location</a>
+ </li>
+ <li>
+ <a href="{% url opts|admin_urlname:'history' original.pk|admin_urlquote %}" class="historylink">{% trans "History" %}</a>
+ </li>
+ {% if has_absolute_url %}
+ <li>
+ <a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% trans "View on site" %}</a>
+ </li>
+ {% endif %}
+{% endblock %}
diff --git a/design/templates/archives/notes.html b/design/templates/archives/notes.html
index 4ee5269..ed2a7be 100644
--- a/design/templates/archives/notes.html
+++ b/design/templates/archives/notes.html
@@ -16,7 +16,7 @@
<article class="h-entry">
<h2 class="p-name note--title">{{object.title|safe|amp|smartypants}}</h2>
<div class="e-content">
- {{object.render|safe|amp|smartypants|urlizetrunc:45 }}
+ {{object.body_html|safe|amp|smartypants|urlizetrunc:45 }}
</div>
<span class="p-author h-card">
<data class="p-name" value="Scott Gilbertson"></data>
@@ -24,11 +24,11 @@
</span>
<footer>
<p class="note--date">
- <a class="u-url" href="{{object.get_absolute_url}}" rel="bookmark"><time class="dt-published" datetime="{{object.date_created|html5_datetime}}">{{object.date_created|date:"F j, Y"}}</time></a>
+ <a class="u-url" href="{{object.get_absolute_url}}" rel="bookmark"><time class="dt-published" datetime="{{object.pub_date|html5_datetime}}">{{object.pub_date|date:"F j, Y"}}</time></a>
</p>{% if object.location %}
<p class="p-location h-adr note--location bl" itemprop="geo" itemscope itemtype="http://data-vocabulary.org/Geo">
<span class="p-locality">{{object.location.name|smartypants|safe}}</span>,
- <span class="p-region">{{object.state_name}}</span>,
+ <span class="p-region">{{object.location.state.name}}</span>,
<span class="p-country-name">{{object.location.state.country.name}}</span>
<data class="p-latitude" value="{{object.latitude}}"></data>
<data class="p-longitude" value="{{object.longitude}}"></data>
diff --git a/design/templates/details/note.html b/design/templates/details/note.html
index 87a1e25..269d82a 100644
--- a/design/templates/details/note.html
+++ b/design/templates/details/note.html
@@ -20,7 +20,7 @@
<article class="h-entry">
<h1 class="p-name note--title hide">{{object.title|safe|amp|smartypants}}</h1>
<div class="e-content">
- {{object.render|safe|amp|smartypants|urlizetrunc:45 }}
+ {{object.body_html|safe|amp|smartypants}}
</div>
<span class="p-author h-card">
<data class="p-name" value="Scott Gilbertson"></data>
@@ -28,11 +28,11 @@
</span>
<footer class="note--footer">
<p class="note--date">
- <a class="u-url" href="{{object.get_absolute_url}}" rel="bookmark"><time class="dt-published" datetime="{{object.date_created|html5_datetime}}">{{object.date_created|date:"F j, Y"}}</time></a>
+ <a class="u-url" href="{{object.get_absolute_url}}" rel="bookmark"><time class="dt-published" datetime="{{object.pub_date|html5_datetime}}">{{object.pub_date|date:"F j, Y"}}</time></a>
</p>{% if object.location %}
<p class="p-location h-adr note--location bl" itemprop="geo" itemscope itemtype="http://data-vocabulary.org/Geo">
<span class="p-locality">{{object.location.name|smartypants|safe}}</span>,
- <span class="p-region">{{object.state_name}}</span>,
+ <span class="p-region">{{object.location.state}}</span>,
<span class="p-country-name">{{object.location.state.country.name}}</span>
<data class="p-latitude" value="{{object.latitude}}"></data>
<data class="p-longitude" value="{{object.longitude}}"></data>