diff options
-rw-r--r-- | app/blog/admin.py | 5 | ||||
-rw-r--r-- | app/blog/fields.py | 3 | ||||
-rw-r--r-- | app/blog/models.py | 26 | ||||
-rwxr-xr-x | app/blog/parse.py | 56 | ||||
-rw-r--r-- | app/blog/urls.py | 59 | ||||
-rw-r--r-- | app/blog/views.py | 184 | ||||
-rw-r--r-- | app/blog/widgets.py | 1 | ||||
-rw-r--r-- | config/base_urls.py | 8 | ||||
-rw-r--r-- | design/templates/archives/writing_date.html | 6 |
9 files changed, 158 insertions, 190 deletions
diff --git a/app/blog/admin.py b/app/blog/admin.py index 34c858d..15a7512 100644 --- a/app/blog/admin.py +++ b/app/blog/admin.py @@ -1,7 +1,8 @@ from django.contrib import admin from django import forms -from blog.widgets import AdminImageWidget from django.contrib.gis.admin import OSMGeoAdmin + +from .widgets import AdminImageWidget from .models import Entry, EntryAside, PostImage, HomepageCurrator @@ -79,6 +80,7 @@ class EntryAdmin(OSMGeoAdmin): class PostImageAdmin(admin.ModelAdmin): list_display = ('title', 'post_image') + class HomepageCurratorAdmin(admin.ModelAdmin): filter_horizontal = ('entry_list',) pass @@ -88,4 +90,3 @@ admin.site.register(PostImage, PostImageAdmin) admin.site.register(EntryAside, EntryAsideAdmin) admin.site.register(Entry, EntryAdmin) admin.site.register(HomepageCurrator, HomepageCurratorAdmin) - diff --git a/app/blog/fields.py b/app/blog/fields.py index 6239297..8df2f5e 100644 --- a/app/blog/fields.py +++ b/app/blog/fields.py @@ -1,5 +1,6 @@ from django import forms -from blog.widgets import AdminImageWidget + +from .widgets import AdminImageWidget class FileUploadForm(forms.ModelForm): diff --git a/app/blog/models.py b/app/blog/models.py index ed0bb40..17f9f49 100644 --- a/app/blog/models.py +++ b/app/blog/models.py @@ -1,15 +1,20 @@ import datetime +import os + from django.contrib.gis.db import models from django.utils.html import format_html from django.conf import settings from django.contrib.syndication.views import Feed from django.contrib.sitemaps import Sitemap from django import forms + # http://freewisdom.org/projects/python-markdown/ import markdown +from bs4 import BeautifulSoup + from photos.models import PhotoGallery from locations.models import Location -from bs4 import BeautifulSoup + def get_upload_path(self, filename): return "images/post-images/%s/%s" % (datetime.datetime.today().strftime("%Y"), filename) @@ -23,6 +28,7 @@ def image_url_replace(s): s = s.replace('[[base_url]]', settings.IMAGES_URL) return s + def extract_images(s): soup = BeautifulSoup(s) imgs = [] @@ -30,6 +36,7 @@ def extract_images(s): imgs.append(img['src']) return imgs + class PostImage(models.Model): title = models.CharField(max_length=100) image = models.ImageField(upload_to="%s/%s" % (settings.IMAGES_ROOT, datetime.datetime.today().strftime("%Y"))) @@ -103,16 +110,15 @@ class Entry(models.Model): def get_image_wide_url(self): img = self.image.url.split('post-images/')[1].split('/')[1] - #return '%shome-images/%s' % (settings.IMAGES_URL, img) + # return '%shome-images/%s' % (settings.IMAGES_URL, img) return '/media/images/home-images/%s' % (img) def get_image_hero_url(self): img = self.image.url.split('post-images/')[1].split('/')[1] return '/media/images/home-images/hero%s' % (img) - + def get_image_hero_url_sm(self): img = self.image.url.split('post-images/')[1].split('/')[1] - import os img = os.path.splitext(img)[0] return '/media/images/home-images/hero%s_sm.jpg' % (img) @@ -165,13 +171,14 @@ class EntryAside(models.Model): body = models.TextField(null=True, blank=True) entry = models.ForeignKey(Entry) + class HomepageCurrator(models.Model): alt_text = models.CharField(max_length=200) image_base_url = models.CharField(max_length=200) tag_line = models.CharField(max_length=200) banner = models.ForeignKey(Entry, related_name="banner") entry_list = models.ManyToManyField(Entry) - template_name = models.CharField(max_length=200,help_text="full path") + template_name = models.CharField(max_length=200, help_text="full path") class BlogSitemap(Sitemap): @@ -196,18 +203,16 @@ class LatestFull(Feed): return Entry.objects.filter(status__exact=1).order_by('-pub_date')[:10] -import os -import io import urllib.request import urllib.parse import urllib.error -import shutil -from django_gravatar.helpers import get_gravatar_url, has_gravatar, get_gravatar_profile_url, calculate_gravatar_hash +from django_gravatar.helpers import get_gravatar_url, has_gravatar, calculate_gravatar_hash from django.dispatch import receiver from django_comments.signals import comment_was_posted from django_comments.models import Comment from django_comments.moderation import CommentModerator, moderator + class EntryModerator(CommentModerator): ''' Moderate everything except people with multiple approvals @@ -218,11 +223,12 @@ class EntryModerator(CommentModerator): previous_approvals = Comment.objects.filter(user_email=comment.email, is_public=True).count() if previous_approvals > 2: return False - #do entry build right here so it goes to live site + # do entry build right here so it goes to live site return True moderator.register(Entry, EntryModerator) + @receiver(comment_was_posted, sender=Comment) def cache_gravatar(sender, comment, **kwargs): gravatar_exists = has_gravatar(comment.email) diff --git a/app/blog/parse.py b/app/blog/parse.py deleted file mode 100755 index a1e3056..0000000 --- a/app/blog/parse.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/python -import os -import datetime -from dateutil.parser import parse as dateparser -from os.path import abspath, dirname -from django.core.exceptions import ObjectDoesNotExist -from blog.models import Entry - -from django.conf import settings - - -def parse_file(filepath): - data = {} - contents = open(filepath).read() - raw = contents.splitlines() - for line in raw[1:]: - if line == '---': - break - else: - k, v = line.split(':', 1) - data[k.strip()] = v.strip() - body = "\n".join(line.strip() for line in raw[1:]) - data["body_markdown"] = body.split('---')[1] - return data - -""" - now I need a function to query the db for the title and date - if there's no entry then it's new and we add it and publish - What about edits though? Crap, edits. That means we need to check lastmod - and that's notoriously inaccurate. damn. -from blog.parse import * -crawl_dir() - -""" - - -def crawl_dir(): - file_root = settings.POSTS_DIR - file_list = os.listdir(file_root) - file_list = filter(lambda item: not (item.startswith('README') or item.startswith('updategithub.php') or item.startswith('.') or item.endswith('~')), file_list) - for f in file_list: - fpath = file_root + "/" + f - last_mod = datetime.datetime.fromtimestamp(os.path.getmtime(fpath)) - last_run = datetime.datetime.fromtimestamp(os.path.getmtime(abspath(dirname(__file__)) + '/last_run')) - if last_mod > last_run: - print "needs an update" - data = parse_file(fpath) - date = dateparser(data['pub_date']) - try: - row = Entry.objects.get(title=str(data['title']), pub_date=date) - print row.title, date - except ObjectDoesNotExist: - print data['title'] + str(date) + " = not found" - last_mod_dump = open(abspath(dirname(__file__)) + '/last_run', 'w') - print last_mod_dump - print >> last_mod_dump, str(datetime.datetime.now()) diff --git a/app/blog/urls.py b/app/blog/urls.py index eb69873..d8fa395 100644 --- a/app/blog/urls.py +++ b/app/blog/urls.py @@ -1,21 +1,44 @@ -from django.conf.urls import * +from django.conf.urls import url from django.views.generic.base import RedirectView -""" -urlpatterns = patterns('', - (r'(?P<slug>[-\w]+)/(?P<page>\d+)/$', 'blog.views.entry_list_by_area'), - (r'(?P<page>\d+)/$', 'blog.views.entry_list'), - (r'(?P<slug>[-\w]+)/$', RedirectView.as_view(url="/writing/%(slug)s/1/")), - (r'', RedirectView.as_view(url="/writing/1/")), -) -""" +from . import views -urlpatterns = patterns('', - url(r'(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+)$', 'blog.views.entry_detail'), - url(r'(?P<year>\d{4})/(?P<month>\d{2})/$', 'blog.views.date_list', name="blog_by_month"), - url(r'(?P<year>\d{4})/$', 'blog.views.date_list', name="blog_by_year"), - (r'(?P<slug>[-\w]+)/(?P<page>\d+)/$', 'blog.views.entry_list_by_area'), - (r'(?P<page>\d+)/$', 'blog.views.entry_list'), - url(r'(?P<slug>[-\w]+)/$', RedirectView.as_view(url="/jrnl/%(slug)s/1/")), - url(r'', RedirectView.as_view(url="/jrnl/1/")), -) +urlpatterns = [ + url( + regex=r'(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+)$', + view=views.EntryDetailView.as_view(), + name="detail" + ), + url( + regex=r'^(?P<year>[0-9]{4})/(?P<month>[0-9]+)/$', + view=views.EntryMonthArchiveView.as_view(month_format='%m'), + name="list_month" + ), + url( + regex=r'(?P<year>\d{4})/$', + view=views.EntryYearArchiveView.as_view(), + name="list_year" + ), + url( + regex=r'(?P<slug>[-\w]+)/(?P<page>\d+)/$', + view=views.EntryCountryList.as_view(), + name="list_country" + ), + url( + regex=r'(?P<page>\d+)/$', + view=views.EntryList.as_view(), + name="list" + ), + # redirect /slug/ to /slug/1/ for live server + url( + regex=r'(?P<slug>[-\w]+)/$', + view=RedirectView.as_view(url="/jrnl/%(slug)s/1/"), + name="live_location_redirect" + ), + # redirect / to /1/ for live server + url( + regex=r'', + view=RedirectView.as_view(url="/jrnl/1/"), + name="live_redirect" + ), +] diff --git a/app/blog/views.py b/app/blog/views.py index c360ef3..7dd755b 100644 --- a/app/blog/views.py +++ b/app/blog/views.py @@ -1,103 +1,89 @@ -from django.shortcuts import render_to_response, get_object_or_404 -from django.template import RequestContext -from django.http import Http404 +from django.views.generic import ListView +from django.views.generic.detail import DetailView +from django.views.generic.dates import YearArchiveView, MonthArchiveView + from django.conf import settings -# from django.views.generic import ListView - -from blog.models import Entry, HomepageCurrator -from locations.models import Region, Country -from photos.models import Photo - - -def home(request): - obj = HomepageCurrator.objects.get(pk=1) - template = obj.template_name - recent = Entry.objects.filter(status__exact=1)[:4] - context = { - 'IMAGES_URL': settings.IMAGES_URL, - 'homepage': obj, - 'recent': recent, - } - return render_to_response(template, context, context_instance=RequestContext(request)) - - -def entry_detail(request, year, month, slug): - obj = get_object_or_404(Entry, slug__exact=slug) - photos = {} - # if obj.photo_gallery: - # photos = Photo.objects.filter(set__exact=obj.get().photo_gallery.id)[:9] - extra = {'photos': photos, } - return render_to_response('details/entry.html', {'object': obj, 'photos': photos}, context_instance=RequestContext(request)) - -""" -List of all writing -class BlogEntryListView(ListView): - template_name="archives/writing.html" - model = Entry + +from .models import Entry, HomepageCurrator + +from locations.models import Country + + +class EntryList(ListView): + """ + Return a list of Entries in reverse chronological order + """ + context_object_name = 'object_list' + queryset = Entry.objects.filter(status__exact=1).order_by('-pub_date').select_related() + template_name = "archives/writing.html" + + def dispatch(self, request, *args, **kwargs): + request.page_url = '/jrnl/%d/' + request.page = int(self.kwargs['page']) + return super(EntryList, self).dispatch(request, *args, **kwargs) + + +class EntryCountryList(ListView): + """ + Return a list of Entries by Country in reverse chronological order + """ + context_object_name = 'object_list' + template_name = "archives/writing.html" + + def dispatch(self, request, *args, **kwargs): + request.page_url = '/jrnl/' + self.kwargs['slug'] + '/%d/' + request.page = int(self.kwargs['page']) + return super(EntryCountryList, self).dispatch(request, *args, **kwargs) + def get_context_data(self, **kwargs): - context = super(BlogEntryListView, self).get_context_data(**kwargs) - context.update({ - 'page': self.kwargs['page'] - }) - self.request.page_url = '/writing/%d/' - self.request.page = self.kwargs['page'] + # Call the base implementation first to get a context + context = super(EntryCountryList, self).get_context_data(**kwargs) + context['region'] = Country.objects.get(slug__exact=self.kwargs['slug']) return context -""" - -def date_list(request, year, month=None): - import datetime - if month: - month_name = datetime.datetime.strptime(month,'%m').strftime('%B') - context = { - 'object_list': Entry.objects.filter(status__exact=1, pub_date__year=year, pub_date__month=month).order_by('pub_date'), - 'type': 'monthly', - 'year': year, - 'month': month_name - } - else: - context = { - 'object_list': Entry.objects.filter(status__exact=1, pub_date__year=year).order_by('-pub_date'), - 'type': 'year', - 'year': year, - } - return render_to_response("archives/writing_date.html", context, context_instance=RequestContext(request)) - - -def entry_list(request, page): - request.page_url = '/jrnl/%d/' - request.page = int(page) - try: - is_build = request.POST['builder'] - extra_context={ - 'page':page, - 'MEDIA_URL': settings.BAKED_MEDIA_URL - } - except: - extra_context={'page':page} - context = { - 'object_list': Entry.objects.filter(status__exact=1).order_by('-pub_date').select_related(), - 'page': page - } - return render_to_response("archives/writing.html", context, context_instance=RequestContext(request)) - - -def entry_list_by_area(request, slug, page): - """ Grabs entries by region or country""" - request.page_url = '/jrnl/' + slug + '/%d/' - request.page = int(page) - try: - region = Region.objects.get(slug__exact=slug) - qs = Entry.objects.filter(status__exact=1, location__state__country__lux_region=region.id).order_by('-pub_date') - except: - region = Country.objects.get(slug__exact=slug) - qs = Entry.objects.filter( - status__exact=1, location__state__country=region).order_by('-pub_date') - if not region: - raise Http404 - context = { - 'region': region, - 'object_list': qs, - 'page': page - } - return render_to_response("archives/writing.html", context, context_instance=RequestContext(request)) + def get_queryset(self): + country = Country.objects.get(slug__exact=self.kwargs['slug']) + return Entry.objects.filter( + status__exact=1, + location__state__country=country + ).order_by('-pub_date') + + +class EntryYearArchiveView(YearArchiveView): + queryset = Entry.objects.filter(status__exact=1).select_related() + date_field = "pub_date" + make_object_list = True + allow_future = True + template_name = "archives/writing_date.html" + + +class EntryMonthArchiveView(MonthArchiveView): + queryset = Entry.objects.filter(status__exact=1).select_related() + date_field = "pub_date" + allow_future = True + template_name = "archives/writing_date.html" + + +class EntryDetailView(DetailView): + model = Entry + template_name = "details/entry.html" + slug_field = "slug" + + +class HomepageList(ListView): + """ + Return a main entry and list of Entries in reverse chronological order + """ + context_object_name = 'recent' + queryset = Entry.objects.filter(status__exact=1)[:4] + + def get_template_names(self): + obj = HomepageCurrator.objects.get(pk=1) + return ['%s' % obj.template_name] + + def get_context_data(self, **kwargs): + # Call the base implementation first to get a context + context = super(HomepageList, self).get_context_data(**kwargs) + context['homepage'] = HomepageCurrator.objects.get(pk=1) + context['IMAGES_URL'] = settings.IMAGES_URL + return context diff --git a/app/blog/widgets.py b/app/blog/widgets.py index 9295641..030437b 100644 --- a/app/blog/widgets.py +++ b/app/blog/widgets.py @@ -1,4 +1,5 @@ import os + from django.contrib.admin.widgets import AdminFileWidget from django.utils.safestring import mark_safe from django.conf import settings diff --git a/config/base_urls.py b/config/base_urls.py index c59e522..c533d44 100644 --- a/config/base_urls.py +++ b/config/base_urls.py @@ -4,6 +4,7 @@ from django.views.generic import TemplateView from django.conf import settings from blog.models import BlogSitemap, LatestFull +from blog.views import HomepageList from locations.models import WritingbyCountrySitemap from links.models import LatestLinks from photos.models import PhotoGallerySitemap @@ -11,6 +12,7 @@ from src.models import SrcSitemap from figments.models import FigmentSitemap from projects.models.base import ProjectSitemap + admin.autodiscover() @@ -69,7 +71,11 @@ urlpatterns += patterns('', #about #(r'^about/$', 'blog.views.about'), #'blog.views.home'), #homepage - (r'^$', 'blog.views.home'), + url( + regex=r'^$', + view=HomepageList.as_view(), + name="homepage" + ), #pages (r'^(?P<slug>[-\w]+)/?$', 'pages.views.page'), diff --git a/design/templates/archives/writing_date.html b/design/templates/archives/writing_date.html index dabe255..7385e81 100644 --- a/design/templates/archives/writing_date.html +++ b/design/templates/archives/writing_date.html @@ -8,11 +8,11 @@ {% block primary %}<ul class="bl" id="breadcrumbs" itemscope itemtype="http://data-vocabulary.org/Breadcrumb"> <li><a href="/" title="luxagraf homepage" itemprop="url"><span itemprop="title">Home</span></a> → </li> <li><a href="/jrnl/" title="See all Journal Entries" itemprop="url"><span itemprop="title">Journal</span></a> →</li> - <li>{% if type == 'year' %}{{year}}{%else%}<a href="/jrnl/{{year}}/">{{year}}</a> →{%endif%}</li> - {% if type == 'monthly' %}<li>{{month}}</li>{% endif %} + <li>{% if not month %}{{year|date:"Y"}}{%else%}<a href="/jrnl/{{month|date:"Y"}}/">{{month|date:"Y"}}</a> →{%endif%}</li> + {% if month %}<li>{{month|date:"F"}}</li>{% endif %} </ul> <main role="main" id="writing-archive" class="archive"> - <h1>{% if type == 'year' %}{{year}}, on luxagraf{%else%} Archive: {{month}} {{year}} {% endif %}</h1>{% if type == 'year' %} + <h1>{% if not month %}{{year|date:"Y"}}, on luxagraf{%else%} Archive: {{month|date:"F Y"}}{% endif %}</h1>{% if not month %} <ul class="date-archive">{% regroup object_list by pub_date.month as entries_by_month %}{% for entries in entries_by_month %} <li class="dater"><span>{{ entries.list.0.pub_date|date:"F Y" }}</span> <ul>{% for post in entries.list %} |