Publish date goodness.

master
Nick Sergeant 2012-05-27 14:51:21 -04:00
parent 39e5178747
commit 16d8279fc7
8 changed files with 165 additions and 21 deletions

View File

@ -105,11 +105,14 @@
$('label.blog-post input', window.site.$main_edit).on('change', function() { $('label.blog-post input', window.site.$main_edit).on('change', function() {
var $checkbox = $(this); var $checkbox = $(this);
var $label = $checkbox.parent(); var $label = $checkbox.parent();
var $publish_date = $label.siblings('label.publish-date');
if ($checkbox.attr('checked')) { if ($checkbox.attr('checked')) {
$label.removeClass('is-not-blog-post').addClass('is-blog-post'); $label.removeClass('is-not-blog-post').addClass('is-blog-post');
$publish_date.show();
} else { } else {
$label.addClass('is-not-blog-post').removeClass('is-blog-post'); $label.addClass('is-not-blog-post').removeClass('is-blog-post');
$publish_date.hide();
} }
return false; return false;
}).trigger('change'); }).trigger('change');
@ -331,6 +334,7 @@
'lexer_name': $('select[name="lexer"] option:selected').text(), 'lexer_name': $('select[name="lexer"] option:selected').text(),
'code': window.editor.getSession().getValue(), 'code': window.editor.getSession().getValue(),
'blog_post': $('label.blog-post input').is(':checked'), 'blog_post': $('label.blog-post input').is(':checked'),
'publish_date': $('label.publish-date input').val(),
'public': $('label.public input').is(':checked') 'public': $('label.public input').is(':checked')
}, {'silent': true}); }, {'silent': true});
@ -392,6 +396,7 @@
var $h1 = $('header h1 a', $el); var $h1 = $('header h1 a', $el);
var $public = $('div.public', $el); var $public = $('div.public', $el);
var $blog_post = $('div.blog-post', $el); var $blog_post = $('div.blog-post', $el);
var $publish_date = $('div.publish-date', $el);
var $user = $('li.author a', $el); var $user = $('li.author a', $el);
var is_public = $public.text() === 'True' ? true : false; var is_public = $public.text() === 'True' ? true : false;
@ -425,6 +430,7 @@
slug: $('div.slug', $el).text(), slug: $('div.slug', $el).text(),
stylized: $('div.stylized', $el).text(), stylized: $('div.stylized', $el).text(),
tags: tags, tags: tags,
publish_date: $publish_date.text(),
tags_list: $('div.tags-list', $el).text(), tags_list: $('div.tags-list', $el).text(),
title: $h1.text(), title: $h1.text(),
user: { user: {

View File

@ -14,6 +14,7 @@ django-templatetag-sugar
gunicorn gunicorn
johnny-cache johnny-cache
lxml lxml
parsedatetime
psycopg2 psycopg2
Pygments Pygments
pysolr pysolr

View File

@ -5,7 +5,7 @@ from snipts.models import Favorite, Snipt
class SniptAdmin(admin.ModelAdmin): class SniptAdmin(admin.ModelAdmin):
readonly_fields = ('user',) readonly_fields = ('user',)
list_display = ('title', 'slug', 'user', 'lexer', 'public', 'blog_post', 'created', 'modified',) list_display = ('title', 'slug', 'user', 'lexer', 'public', 'blog_post', 'created', 'modified', 'publish_date',)
search_fields = ('title', 'user__username', 'lexer', 'id', 'key',) search_fields = ('title', 'user__username', 'lexer', 'id', 'key',)
ordering = ('-created',) ordering = ('-created',)
prepopulated_fields = {'slug': ('title',)} prepopulated_fields = {'slug': ('title',)}

View File

@ -1,9 +1,10 @@
from taggit.utils import edit_string_for_tags, parse_tags from taggit.utils import edit_string_for_tags, parse_tags
from tastypie.authentication import ApiKeyAuthentication from tastypie.authentication import ApiKeyAuthentication
from tastypie.authorization import Authorization from tastypie.authorization import Authorization
from tastypie.validation import Validation from django.template.defaultfilters import date
from tastypie.resources import ModelResource from tastypie.resources import ModelResource
from django.contrib.auth.models import User from django.contrib.auth.models import User
from tastypie.validation import Validation
from tastypie.models import create_api_key from tastypie.models import create_api_key
from snipts.models import Favorite, Snipt from snipts.models import Favorite, Snipt
from haystack.query import SearchQuerySet from haystack.query import SearchQuerySet
@ -13,7 +14,10 @@ from taggit.models import Tag
from django.db import models from django.db import models
from tastypie import fields from tastypie import fields
import hashlib import datetime, hashlib, time
import parsedatetime.parsedatetime as pdt
import parsedatetime.parsedatetime_consts as pdc
models.signals.post_save.connect(create_api_key, sender=User) models.signals.post_save.connect(create_api_key, sender=User)
@ -156,7 +160,7 @@ class PrivateSniptResource(ModelResource):
queryset = Snipt.objects.all().order_by('-created') queryset = Snipt.objects.all().order_by('-created')
resource_name = 'snipt' resource_name = 'snipt'
fields = ['id', 'title', 'slug', 'lexer', 'code', 'line_count', 'stylized', fields = ['id', 'title', 'slug', 'lexer', 'code', 'line_count', 'stylized',
'key', 'public', 'blog_post', 'created', 'modified',] 'key', 'public', 'blog_post', 'created', 'modified', 'publish_date',]
validation = Validation() validation = Validation()
include_absolute_url = True include_absolute_url = True
detail_allowed_methods = ['get', 'patch', 'put', 'delete'] detail_allowed_methods = ['get', 'patch', 'put', 'delete']
@ -172,12 +176,18 @@ class PrivateSniptResource(ModelResource):
def dehydrate(self, bundle): def dehydrate(self, bundle):
bundle.data['embed_url'] = bundle.obj.get_embed_url() bundle.data['embed_url'] = bundle.obj.get_embed_url()
bundle.data['tags_list'] = edit_string_for_tags(bundle.obj.tags.all()) bundle.data['tags_list'] = edit_string_for_tags(bundle.obj.tags.all())
if bundle.data['publish_date']:
bundle.data['publish_date'] = date(bundle.data['publish_date'], 'M d, Y \\a\\t h:i A')
return bundle return bundle
def obj_create(self, bundle, request=None, **kwargs): def obj_create(self, bundle, request=None, **kwargs):
bundle.data['tags_list'] = bundle.data.get('tags') bundle.data['tags_list'] = bundle.data.get('tags')
bundle.data['tags'] = '' bundle.data['tags'] = ''
bundle = self._clean_publish_date(bundle)
return super(PrivateSniptResource, self).obj_create(bundle, request, return super(PrivateSniptResource, self).obj_create(bundle, request,
user=request.user, **kwargs) user=request.user, **kwargs)
@ -189,9 +199,30 @@ class PrivateSniptResource(ModelResource):
bundle.data['tags_list'] = '' bundle.data['tags_list'] = ''
bundle.data['tags'] = '' bundle.data['tags'] = ''
bundle = self._clean_publish_date(bundle)
return super(PrivateSniptResource, self).obj_update(bundle, request, return super(PrivateSniptResource, self).obj_update(bundle, request,
user=request.user, **kwargs) user=request.user, **kwargs)
def _clean_publish_date(self, bundle):
if bundle.data['blog_post'] and not bundle.data['publish_date']:
bundle.data['publish_date'] = datetime.datetime.now()
elif bundle.data['blog_post']:
c = pdc.Constants()
p = pdt.Calendar(c)
publish_date, result = p.parse(bundle.data['publish_date'])
if result != 0:
publish_date = time.strftime("%Y-%m-%d %H:%M:%S", publish_date)
else:
publish_date = datetime.datetime.now()
bundle.data['publish_date'] = publish_date
elif not bundle.data['blog_post']:
bundle.data['publish_date'] = None
return bundle
def build_filters(self, filters=None): def build_filters(self, filters=None):
if filters is None: if filters is None:
filters = {} filters = {}

View File

@ -0,0 +1,100 @@
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Snipt.publish_date'
db.add_column('snipts_snipt', 'publish_date', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True), keep_default=False)
def backwards(self, orm):
# Deleting field 'Snipt.publish_date'
db.delete_column('snipts_snipt', 'publish_date')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'snipts.favorite': {
'Meta': {'object_name': 'Favorite'},
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'snipt': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['snipts.Snipt']"}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
},
'snipts.snipt': {
'Meta': {'object_name': 'Snipt'},
'blog_post': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'code': ('django.db.models.fields.TextField', [], {}),
'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'custom_slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'embedded': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'key': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'lexer': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'line_count': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True', 'blank': 'True'}),
'modified': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'publish_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'db_index': 'True', 'max_length': '255', 'blank': 'True'}),
'stylized': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
},
'taggit.tag': {
'Meta': {'object_name': 'Tag'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'})
},
'taggit.taggeditem': {
'Meta': {'object_name': 'TaggedItem'},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_tagged_items'", 'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'object_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True'}),
'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'taggit_taggeditem_items'", 'to': "orm['taggit.Tag']"})
}
}
complete_apps = ['snipts']

View File

@ -21,25 +21,26 @@ site = Site.objects.all()[0]
class Snipt(models.Model): class Snipt(models.Model):
"""An individual Snipt.""" """An individual Snipt."""
user = models.ForeignKey(User, blank=True, null=True) user = models.ForeignKey(User, blank=True, null=True)
title = models.CharField(max_length=255) title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255, blank=True) slug = models.SlugField(max_length=255, blank=True)
custom_slug = models.SlugField(max_length=255, blank=True) custom_slug = models.SlugField(max_length=255, blank=True)
tags = TaggableManager() tags = TaggableManager()
lexer = models.CharField(max_length=50) lexer = models.CharField(max_length=50)
code = models.TextField() code = models.TextField()
stylized = models.TextField(blank=True, null=True) stylized = models.TextField(blank=True, null=True)
embedded = models.TextField(blank=True, null=True) embedded = models.TextField(blank=True, null=True)
line_count = models.IntegerField(blank=True, null=True, default=None) line_count = models.IntegerField(blank=True, null=True, default=None)
key = models.CharField(max_length=100, blank=True, null=True) key = models.CharField(max_length=100, blank=True, null=True)
public = models.BooleanField(default=False) public = models.BooleanField(default=False)
blog_post = models.BooleanField(default=False) blog_post = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True, editable=False) created = models.DateTimeField(auto_now_add=True, editable=False)
modified = models.DateTimeField(auto_now=True, editable=False) modified = models.DateTimeField(auto_now=True, editable=False)
publish_date = models.DateTimeField(blank=True, null=True)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):

View File

@ -25,7 +25,7 @@
<header> <header>
<h2>&nbsp;</h2> <h2>&nbsp;</h2>
<h1> <h1>
<input type="text" id="snipt_title" value="<% if (snipt.title != 'Untitled') { %><%= snipt.title %><% } %>" /> <input type="text" id="snipt_title" placeholder="Title" value="<% if (snipt.title != 'Untitled') { %><%= snipt.title %><% } %>" />
</h1> </h1>
</header> </header>
<section class="code"> <section class="code">
@ -54,9 +54,13 @@
<input type="checkbox" <% if (snipt.blog_post) { %>checked="checked"<% } %> name="" value="" /> <input type="checkbox" <% if (snipt.blog_post) { %>checked="checked"<% } %> name="" value="" />
<span>Blog post</span> <span>Blog post</span>
</label> </label>
<label class="publish-date hidden">
<span>Publish date</span>
<input type="text" placeholder="now, 8pm, tomorrow, 12/25/07, etc." value="<%= snipt.publish_date %>" />
</label>
<label class="tags"> <label class="tags">
<span>Tags</span> <span>Tags</span>
<textarea><%= snipt.tags_list %></textarea> <textarea placeholder='tag-1, "tag 2", tag3, etc.'><%= snipt.tags_list %></textarea>
</label> </label>
</div> </div>
</aside> </aside>

View File

@ -105,6 +105,7 @@
<div class="hide modified">{{ snipt.modified|date:"Y-m-d\TH:i:s" }}</div> <div class="hide modified">{{ snipt.modified|date:"Y-m-d\TH:i:s" }}</div>
<div class="hide public">{{ snipt.public }}</div> <div class="hide public">{{ snipt.public }}</div>
<div class="hide blog-post">{{ snipt.blog_post }}</div> <div class="hide blog-post">{{ snipt.blog_post }}</div>
<div class="hide publish-date">{{ snipt.publish_date|date:"M d, Y \a\t h:i A" }}</div>
{% if snipt.user == request.user %} {% if snipt.user == request.user %}
<div class="hide resource-uri">/api/private/snipt/{{ snipt.pk }}/</div> <div class="hide resource-uri">/api/private/snipt/{{ snipt.pk }}/</div>
{% else %} {% else %}