summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/lib/templatetags/templatetags/month_number_to_name.py7
-rw-r--r--app/notes/admin.py1
-rw-r--r--app/notes/build.py68
-rw-r--r--app/notes/models.py77
-rw-r--r--app/notes/urls.py8
-rw-r--r--app/notes/views.py38
6 files changed, 183 insertions, 16 deletions
diff --git a/app/lib/templatetags/templatetags/month_number_to_name.py b/app/lib/templatetags/templatetags/month_number_to_name.py
new file mode 100644
index 0000000..69bd7e6
--- /dev/null
+++ b/app/lib/templatetags/templatetags/month_number_to_name.py
@@ -0,0 +1,7 @@
+import calendar
+from django import template
+register = template.Library()
+
+@register.filter
+def month_number_to_name(month_number):
+ return calendar.month_name[int(month_number)]
diff --git a/app/notes/admin.py b/app/notes/admin.py
index 03b8b37..17660c9 100644
--- a/app/notes/admin.py
+++ b/app/notes/admin.py
@@ -18,6 +18,7 @@ class NoteAdmin(OSMGeoAdmin):
fieldsets = (
('Note', {
'fields': (
+ 'title',
'body_markdown',
('twitter_send', 'slug'),
'point'
diff --git a/app/notes/build.py b/app/notes/build.py
new file mode 100644
index 0000000..44226f9
--- /dev/null
+++ b/app/notes/build.py
@@ -0,0 +1,68 @@
+from builder.base import *
+from .models import Note
+
+
+class BuildNotes(Build):
+ def build(self):
+ self.build_archive()
+ self.build_archive_year()
+ self.build_archive_month()
+ self.build_detail_pages()
+
+ def queryset(self):
+ return Note.objects.all()
+
+ def get_model(self):
+ return get_model('notes', 'note')
+
+ def build_detail_pages(self):
+ '''
+ Grab all the notes, render them to a template string and write that out to the filesystem
+ '''
+ for entry in self.queryset():
+ c = Context({'object': entry, 'MEDIA_URL': settings.BAKED_MEDIA_URL, 'IMAGES_URL': settings.BAKED_IMAGES_URL})
+ t = render_to_string('details/note.html', c).encode('utf-8')
+ path = 'notes/%s/' % (entry.date_created.strftime("%Y/%m").lower())
+ self.write_file(path, t, 'html', entry.slug)
+ s = render_to_string('details/note.txt', c).encode('utf-8')
+ self.write_file(path, s, 'txt', entry.slug)
+
+ def build_archive(self):
+ path = 'notes/'
+ c = Context({
+ 'object_list': self.queryset(),
+ 'MEDIA_URL': settings.BAKED_MEDIA_URL,
+ 'IMAGES_URL': settings.BAKED_IMAGES_URL
+ })
+ t = render_to_string('archives/notes.html', c).encode('utf-8')
+ self.write_file(path, t)
+
+ def build_archive_year(self):
+ note = self.get_model()
+ years = note.objects.dates('date_created', 'year')
+ for year in years:
+ year = year.strftime('%Y')
+ qs = note.objects.filter(date_created__year=year).order_by('-date_created')
+ c = Context({
+ 'year': year,
+ 'object_list': qs
+ })
+ t = render_to_string('archives/notes_date.html', c).encode('utf-8')
+ fpath = 'notes/%s/' % (year)
+ self.write_file(fpath, t)
+
+ def build_archive_month(self):
+ note = self.get_model()
+ months = note.objects.dates('date_created', 'month')
+ for m in months:
+ year = m.strftime('%Y')
+ month = m.strftime('%m')
+ qs = note.objects.filter(date_created__year=year, date_created__month=month).order_by('-date_created')
+ c = Context({
+ 'month': month,
+ 'year': year,
+ 'object_list': qs,
+ })
+ t = render_to_string('archives/notes_date.html', c).encode('utf-8')
+ fpath = 'notes/%s/%s/' % (year, month)
+ self.write_file(fpath, t)
diff --git a/app/notes/models.py b/app/notes/models.py
index 35680af..0a9e5c6 100644
--- a/app/notes/models.py
+++ b/app/notes/models.py
@@ -1,6 +1,16 @@
+'''
+TODO:
+
+2) test urlize with markdown links
+3) parse out markdown wrapped links for twitter
+4) CSS
+6) Write JavaScript to automatically place map on current location
+'''
+
import datetime
from django.contrib.gis.db import models
from django.template.defaultfilters import slugify
+from django.utils.html import urlize
from django import forms
from django.db.models.signals import post_save
from django.dispatch import receiver
@@ -11,20 +21,24 @@ from twython import Twython
# http://freewisdom.org/projects/python-markdown/
import markdown
+
def twitter_truncate(txt):
- try:
- return txt.split("|")[0]
- except:
- return txt
+ return txt.split("|")[0]
+
class Note(models.Model):
+ title = models.CharField(max_length=250, null=True, blank=True)
slug = models.SlugField(unique_for_date='date_created', blank=True)
date_created = models.DateTimeField('Date', blank=True)
date_last_updated = models.DateTimeField('Date', blank=True)
point = models.PointField()
location = models.ForeignKey(Location, null=True, blank=True)
+ city_name = models.CharField(max_length=250, null=True, blank=True)
+ state_name = models.CharField(max_length=250, null=True, blank=True)
+ country_name = models.CharField(max_length=150, null=True, blank=True)
body_html = models.TextField(blank=True)
body_markdown = models.CharField('Note', max_length=450)
+ twitter_text = models.CharField('Twitter text', max_length=450, null=True, blank=True)
twitter_id = models.CharField('twitter_id', max_length=450)
twitter_send = models.BooleanField("send to twitter?", default=False)
twitter_sent = models.BooleanField(default=False, blank=True)
@@ -33,7 +47,7 @@ class Note(models.Model):
return self.slug
def get_absolute_url(self):
- return '/notes/%s/%s' % (self.date_created.strftime("%Y/%b").lower(), self.slug)
+ return '/notes/%s/%s' % (self.date_created.strftime("%Y/%m").lower(), self.slug)
@property
def state(self):
@@ -50,38 +64,69 @@ class Note(models.Model):
@property
def longitude(self):
'''Get the site's longitude.'''
- return self.point.x
+ return round(self.point.x, 2)
@property
def latitude(self):
'''Get the site's latitude.'''
- return self.point.y
+ return round(self.point.y, 2)
+
+ @property
+ def get_previous_published(self):
+ return self.get_previous_by_date_created()
+
+ @property
+ def get_next_published(self):
+ return self.get_next_by_date_created()
+
+ def link_twitter_names(self):
+ opts = {'username_include_symbol': True}
+ from twitter_text.autolink import Autolink
+ return Autolink(self.body_html).auto_link_usernames_or_lists(opts)
def save(self):
- self.body_html = markdown.markdown(self.body_markdown, extensions=['extra'], safe_mode=False)
+ self.body_html = markdown.markdown(urlize(self.body_markdown, 45), extensions=['extra'], safe_mode=False)
self.date_last_updated = datetime.datetime.now()
if not self.date_created:
self.date_created = datetime.datetime.now()
if not self.slug:
self.slug = slugify(self.body_markdown)[:20]
- 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.twitter_text:
+ self.twitter_text = twitter_truncate(self.body_markdown)
super(Note, self).save()
+import requests
+import json
@receiver(post_save, sender=Note)
def post_save_events(sender, instance, **kwargs):
+ #if kwargs["created"]:
+ try:
+ l = Location.objects.filter(geometry__contains=instance.point).get()
+ instance.location = l
+ instance.city_name = l.name
+ instance.state_name = l.state.name
+ instance.country_name = l.state.country.name
+ except Location.DoesNotExist:
+ r_str = 'http://nominatim.openstreetmap.org/reverse?format=json&lat=%s&lon=%s&zoom=18' % (instance.latitude, instance.longitude)
+ response = requests.get(r_str)
+ data = json.loads(response.text)
+ adr = data.get('address', {})
+ instance.city_name = adr.get('hamlet') or adr.get('village') or adr.get('town') or adr.get('city')
+ instance.state_name = adr.get('state')
+ instance.country_name = adr.get('country')
if instance.twitter_send and not instance.twitter_sent:
t = Twython(settings.TWITTER_API_KEY, settings.TWITTER_API_SECRET, settings.TWITTER_ACCESS_TOKEN, settings.TWITTER_ACCESS_SECRET)
geo = t.reverse_geocode(lat=instance.latitude, lon=instance.longitude, accuracy=1500, granularity="city")
geo_id = geo['result']['places'][0]['id']
- status = t.update_status(status=instance.body_markdown, place_id=geo_id)
+ status = t.update_status(status=instance.twitter_text, place_id=geo_id)
instance.twitter_id = status['id']
instance.twitter_sent = True
- instance.save()
+ post_save.disconnect(post_save_events, sender=Note)
+ instance.save()
+ post_save.connect(post_save_events, sender=Note)
+
def write_note(sender, instance, **kwargs):
- if created:
- pass
+ if kwargs["created"]:
+ pass
diff --git a/app/notes/urls.py b/app/notes/urls.py
new file mode 100644
index 0000000..9018553
--- /dev/null
+++ b/app/notes/urls.py
@@ -0,0 +1,8 @@
+from django.conf.urls import patterns, url
+
+urlpatterns = patterns('',
+ url(r'(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+)$', 'notes.views.entry_detail'),
+ url(r'(?P<year>\d{4})/(?P<month>\d{2})/$', 'notes.views.date_list', name="notes_by_month"),
+ url(r'(?P<year>\d{4})/$', 'notes.views.date_list', name="notes_by_year"),
+ url(r'^$', 'notes.views.entry_list', name="notes_archive"),
+)
diff --git a/app/notes/views.py b/app/notes/views.py
new file mode 100644
index 0000000..2542293
--- /dev/null
+++ b/app/notes/views.py
@@ -0,0 +1,38 @@
+from django.shortcuts import render_to_response, get_object_or_404
+from django.template import RequestContext
+from notes.models import Note
+
+
+def entry_detail(request, year, month, slug):
+ context = {
+ 'object': get_object_or_404(Note, slug__exact=slug),
+ }
+ return render_to_response(
+ 'details/note.html',
+ context,
+ context_instance=RequestContext(request)
+ )
+
+
+def date_list(request, year, month=None):
+ if month:
+ qs = Note.objects.filter(date_created__year=year, date_created__month=month)
+ else:
+ qs = Note.objects.filter(date_created__year=year)
+ context = {
+ 'year': year,
+ 'month': month,
+ 'object_list': qs,
+ }
+ return render_to_response(
+ "archives/notes_date.html",
+ context,
+ context_instance=RequestContext(request)
+ )
+
+
+def entry_list(request):
+ context = {
+ 'object_list': Note.objects.all().order_by('-date_created').select_related(),
+ }
+ return render_to_response("archives/notes.html", context, context_instance=RequestContext(request))