summaryrefslogtreecommitdiff
path: root/app/blog
diff options
context:
space:
mode:
authorluxagraf <sng@luxagraf.net>2015-11-04 22:09:58 -0500
committerluxagraf <sng@luxagraf.net>2015-11-04 22:09:58 -0500
commit2311ea934932cf791a83f6c6264063a26468e98c (patch)
tree078381535dc2a1d6ee3dcbf8460b552748ce85ba /app/blog
parent24b760797fd26e80c1738c614408b02b50284d4d (diff)
refactored blog app and renamed to jrnl
Diffstat (limited to 'app/blog')
-rw-r--r--app/blog/__init__.py0
-rw-r--r--app/blog/admin.py92
-rw-r--r--app/blog/fields.py7
-rw-r--r--app/blog/models.py241
-rw-r--r--app/blog/urls.py44
-rw-r--r--app/blog/views.py89
-rw-r--r--app/blog/widgets.py32
7 files changed, 0 insertions, 505 deletions
diff --git a/app/blog/__init__.py b/app/blog/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/app/blog/__init__.py
+++ /dev/null
diff --git a/app/blog/admin.py b/app/blog/admin.py
deleted file mode 100644
index 15a7512..0000000
--- a/app/blog/admin.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from django.contrib import admin
-from django import forms
-from django.contrib.gis.admin import OSMGeoAdmin
-
-from .widgets import AdminImageWidget
-from .models import Entry, EntryAside, PostImage, HomepageCurrator
-
-
-class EntryAsideInline(admin.TabularInline):
- model = EntryAside
- extra = 1
-
-
-class EntryAsideAdmin(admin.ModelAdmin):
- pass
-
-
-class BlogEntryForm(forms.ModelForm):
- class Meta:
- model = Entry
- fields = '__all__'
- widgets = {
- 'body_markdown': forms.Textarea(attrs={'rows': 50, 'cols': 100}),
- }
-
-
-class EntryAdmin(OSMGeoAdmin):
- form = BlogEntryForm
- inlines = [EntryAsideInline]
-
- def formfield_for_dbfield(self, db_field, **kwargs):
- if db_field.name == 'thumbnail' or db_field.name == 'image':
- field = forms.FileField(widget=AdminImageWidget)
- else:
- field = super(EntryAdmin, self).formfield_for_dbfield(db_field, **kwargs)
- return field
-
- list_display = ('title', 'pub_date', 'template_name', 'status', 'region', 'location', 'photo_gallery')
- search_fields = ['title', 'body_markdown']
- prepopulated_fields = {"slug": ('title',)}
- list_filter = ('pub_date', 'enable_comments', 'status', 'location__state__country__lux_region')
- fieldsets = (
- ('Entry', {
- 'fields': (
- 'title',
- 'body_markdown',
- ('pub_date', 'status'),
- 'slug',
- 'point'
- ),
- 'classes': (
- 'show',
- 'extrapretty',
- 'wide'
- )
- }
- ),
- ('Formatting data', {
- 'fields': (
- 'dek',
- 'meta_description',
- ('image', 'thumbnail'),
- 'template_name',
- 'enable_comments',
- ),
- }),
- )
- # options for OSM map Using custom ESRI topo map
- default_lon = -9285175
- default_lat = 4025046
- default_zoom = 6
- units = True
- scrollable = False
- map_width = 700
- map_height = 425
- map_template = 'gis/admin/osm.html'
- openlayers_url = '/static/admin/js/OpenLayers.js'
-
-
-class PostImageAdmin(admin.ModelAdmin):
- list_display = ('title', 'post_image')
-
-
-class HomepageCurratorAdmin(admin.ModelAdmin):
- filter_horizontal = ('entry_list',)
- pass
-
-
-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
deleted file mode 100644
index 8df2f5e..0000000
--- a/app/blog/fields.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from django import forms
-
-from .widgets import AdminImageWidget
-
-
-class FileUploadForm(forms.ModelForm):
- upload = forms.FileField(widget=AdminImageWidget)
diff --git a/app/blog/models.py b/app/blog/models.py
deleted file mode 100644
index 17f9f49..0000000
--- a/app/blog/models.py
+++ /dev/null
@@ -1,241 +0,0 @@
-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
-
-
-def get_upload_path(self, filename):
- return "images/post-images/%s/%s" % (datetime.datetime.today().strftime("%Y"), filename)
-
-
-def get_tn_path(self, filename):
- return "images/post-thumbnail/%s/%s" % (datetime.datetime.today().strftime("%Y"), filename)
-
-
-def image_url_replace(s):
- s = s.replace('[[base_url]]', settings.IMAGES_URL)
- return s
-
-
-def extract_images(s):
- soup = BeautifulSoup(s)
- imgs = []
- for img in soup.find_all('img'):
- 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")))
-
- def __unicode__(self):
- return self.title
-
- def post_image(self):
- return format_html('<img src="%s%s" alt="%s" class="postpic"/>' % (
- settings.IMAGES_URL,
- self.image.url.split('images')[1].split('/', 1)[1],
- self.title)
- )
-
- post_image.allow_tags = True
-
-
-class Entry(models.Model):
- title = models.CharField(max_length=200)
- slug = models.SlugField(unique_for_date='pub_date')
- body_html = models.TextField(blank=True)
- body_markdown = models.TextField()
- dek = models.TextField(null=True, blank=True)
- pub_date = models.DateTimeField('Date published')
- enable_comments = models.BooleanField(default=False)
- point = models.PointField(null=True, blank=True)
- location = models.ForeignKey(Location, null=True, blank=True)
- PUB_STATUS = (
- (0, 'Draft'),
- (1, 'Published'),
- )
- status = models.IntegerField(choices=PUB_STATUS, default=0)
- photo_gallery = models.ForeignKey(PhotoGallery, blank=True, null=True, verbose_name='photo set')
- image = models.FileField(upload_to=get_upload_path, null=True, blank=True, help_text="should be 205px high")
- thumbnail = models.FileField(upload_to=get_tn_path, null=True, blank=True, help_text="should be 160 wide")
- meta_description = models.CharField(max_length=256, null=True, blank=True)
- TEMPLATES = (
- (0, 'single'),
- (1, 'double'),
- (2, 'single-dark'),
- (3, 'double-dark'),
- (4, 'bigimg'),
- (5, 'bigimg-dark'),
- )
- template_name = models.IntegerField(choices=TEMPLATES, default=0)
-
- class Meta:
- ordering = ('-pub_date',)
- get_latest_by = 'pub_date'
- verbose_name_plural = 'entries'
-
- def __str__(self):
- return self.title
-
- def get_absolute_url(self):
- return "/jrnl/%s/%s" % (self.pub_date.strftime("%Y/%m").lower(), self.slug)
-
- def get_absolute_url_old(self):
- return "/%s/%s/" % (self.pub_date.strftime("%Y/%b/%d").lower(), self.slug)
-
- def comment_period_open(self):
- return self.enable_comments and datetime.datetime.today() - datetime.timedelta(30) <= self.pub_date
-
- def get_thumbnail_url(self):
- image_dir, img = self.thumbnail.url.split('post-thumbnail/')[1].split('/')
- return '%spost-thumbnail/%s/%s' % (settings.IMAGES_URL, image_dir, img)
-
- def get_image_url(self):
- image_dir, img = self.image.url.split('post-images/')[1].split('/')
- return '%spost-images/%s/%s' % (settings.IMAGES_URL, image_dir, img)
-
- 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 '/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]
- img = os.path.splitext(img)[0]
- return '/media/images/home-images/hero%s_sm.jpg' % (img)
-
- def get_images(self):
- return extract_images(self.body_html)
-
- @property
- def state(self):
- return self.location.state
-
- @property
- def country(self):
- return self.location.state.country
-
- @property
- def region(self):
- return self.location.state.country.lux_region
-
- @property
- def longitude(self):
- '''Get the site's longitude.'''
- return self.point.x
-
- @property
- def latitude(self):
- '''Get the site's latitude.'''
- return self.point.y
-
- @property
- def get_previous_published(self):
- return self.get_previous_by_pub_date(status__exact=1)
-
- @property
- def get_next_published(self):
- return self.get_next_by_pub_date(status__exact=1)
-
- def save(self):
- md = image_url_replace(self.body_markdown)
- self.body_html = markdown.markdown(md, extensions=['extra'], safe_mode=False)
- self.dek == markdown.markdown(self.dek, safe_mode=False)
- 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))
- super(Entry, self).save()
-
-
-class EntryAside(models.Model):
- title = models.CharField(max_length=200)
- 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")
-
-
-class BlogSitemap(Sitemap):
- changefreq = "never"
- priority = 1.0
- protocol = "https"
-
- def items(self):
- return Entry.objects.filter(status=1)
-
- def lastmod(self, obj):
- return obj.pub_date
-
-
-class LatestFull(Feed):
- title = "Luxagraf: Topographical Writings"
- link = "/writing/"
- description = "Latest postings to luxagraf.net"
- description_template = 'feeds/blog_description.html'
-
- def items(self):
- return Entry.objects.filter(status__exact=1).order_by('-pub_date')[:10]
-
-
-import urllib.request
-import urllib.parse
-import urllib.error
-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
- '''
- email_notification = True
-
- def moderate(self, comment, content_object, request):
- 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
- return True
-
-moderator.register(Entry, EntryModerator)
-
-
-@receiver(comment_was_posted, sender=Comment)
-def cache_gravatar(sender, comment, **kwargs):
- gravatar_exists = has_gravatar(comment.email)
- grav_dir = settings.IMAGES_ROOT + '/gravcache/'
- if gravatar_exists:
- url = get_gravatar_url(comment.email, size=60)
- if not os.path.isdir(grav_dir):
- os.makedirs(grav_dir)
- local_grav = '%s/%s.jpg' % (grav_dir, calculate_gravatar_hash(comment.email))
- urllib.request.urlretrieve(url, local_grav)
diff --git a/app/blog/urls.py b/app/blog/urls.py
deleted file mode 100644
index d8fa395..0000000
--- a/app/blog/urls.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from django.conf.urls import url
-from django.views.generic.base import RedirectView
-
-from . import views
-
-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
deleted file mode 100644
index 7dd755b..0000000
--- a/app/blog/views.py
+++ /dev/null
@@ -1,89 +0,0 @@
-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 .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):
- # 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 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
deleted file mode 100644
index 030437b..0000000
--- a/app/blog/widgets.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import os
-
-from django.contrib.admin.widgets import AdminFileWidget
-from django.utils.safestring import mark_safe
-from django.conf import settings
-
-
-def thumbnail(image_path):
- absolute_url = os.path.join(settings.IMAGES_URL, image_path[7:])
- print(absolute_url)
- return '<img style="max-width: 400px" src="%s" alt="%s" />' % (absolute_url, image_path)
-
-
-class AdminImageWidget(AdminFileWidget):
- """
- A FileField Widget that displays an image instead of a file path
- if the current file is an image.
- """
- def render(self, name, value, attrs=None):
- output = []
- file_name = str(value)
- help_text = ''
- if file_name:
- file_path = '%s' % (file_name)
- if attrs['id'] == 'id_thumbnail':
- help_text = '160 wide'
- if attrs['id'] == 'id_image':
- help_text = '205px high'
- output.append('<span>%s</span><a target="_blank" href="%s">%s</a>' % (help_text, file_path, thumbnail(file_name)))
-
- output.append(super(AdminFileWidget, self).render(name, value, attrs))
- return mark_safe(''.join(output))