diff options
Diffstat (limited to 'app/notes')
-rw-r--r-- | app/notes/admin.py | 1 | ||||
-rw-r--r-- | app/notes/build.py | 68 | ||||
-rw-r--r-- | app/notes/models.py | 77 | ||||
-rw-r--r-- | app/notes/urls.py | 8 | ||||
-rw-r--r-- | app/notes/views.py | 38 |
5 files changed, 176 insertions, 16 deletions
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)) |