From fdb951576ff642d160bd66cba82179fa2ca247d7 Mon Sep 17 00:00:00 2001 From: luxagraf Date: Mon, 8 Feb 2016 12:53:07 -0500 Subject: redid notes to make them self-contained and local --- app/notes/admin.py | 34 +++++++++---- app/notes/migrations/0001_initial.py | 63 +++++++++++++++++++++++++ app/notes/migrations/0002_auto_20160208_1107.py | 20 ++++++++ app/notes/migrations/0003_auto_20160208_1120.py | 33 +++++++++++++ app/notes/migrations/__init__.py | 0 app/notes/models.py | 58 +++++++++++++++++++++++ app/notes/urls.py | 28 ++++++++++- app/notes/views.py | 33 ++++++++++++- app/utils/widgets.py | 7 ++- config/base_urls.py | 5 +- design/templates/admin/notes/change_form.html | 19 ++++++++ design/templates/archives/notes.html | 6 +-- design/templates/details/note.html | 6 +-- 13 files changed, 291 insertions(+), 21 deletions(-) create mode 100644 app/notes/migrations/0001_initial.py create mode 100644 app/notes/migrations/0002_auto_20160208_1107.py create mode 100644 app/notes/migrations/0003_auto_20160208_1120.py create mode 100644 app/notes/migrations/__init__.py create mode 100644 design/templates/admin/notes/change_form.html 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 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,14 +1,29 @@ from django.conf.urls import url +from django.views.generic.base import RedirectView from . import views app_name = "notes" urlpatterns = [ + url( + r'(?P\d{4})/(?P\d{2})/(?P[-\w]+).txt$', + views.NoteDetailViewTXT.as_view(), + name="detail-txt" + ), + url( + r'(?P\d{4})/(?P\d{2})/(?P[-\w]+).amp$', + views.NoteDetailViewAMP.as_view(), + name="detail-amp" + ), url( r'(?P\d{4})/(?P\d{2})/(?P[-\w]+)$', - views.entry_detail + views.NoteDetailView.as_view(), + name="detail" ), + + + url( r'(?P\d{4})/(?P\d{2})/$', views.date_list, @@ -19,6 +34,17 @@ urlpatterns = [ views.date_list, name="notes_by_year" ), + url( + r'(?P\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, 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 %} + Get Location + {{block.super}} +{% endblock %} +{% block object-tools-items %} +
  • + Get Location +
  • +
  • + {% trans "History" %} +
  • + {% if has_absolute_url %} +
  • + {% trans "View on site" %} +
  • + {% 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 @@

    {{object.title|safe|amp|smartypants}}

    - {{object.render|safe|amp|smartypants|urlizetrunc:45 }} + {{object.body_html|safe|amp|smartypants|urlizetrunc:45 }}
    @@ -24,11 +24,11 @@