Readonly public API

master
Nick Sergeant 2011-10-01 13:23:05 -04:00
parent a7852c8042
commit 27cf162939
7 changed files with 116 additions and 9 deletions

View File

@ -1,5 +1,7 @@
#!/usr/bin/python
from django.utils.encoding import force_unicode
import MySQLdb
from django.contrib.auth.models import User
@ -8,7 +10,7 @@ from snipts.models import Comment, Snipt
from taggit.models import Tag, TaggedItem
from taggit.utils import parse_tags
conn = MySQLdb.connect(host='localhost', user='root', passwd='root', db='sniptold')
conn = MySQLdb.connect(host='localhost', user='root', passwd='', db='sniptold')
cursor = conn.cursor()
def i():
@ -99,7 +101,7 @@ def snipts():
public=public,
created=created,
)
for t in parse_tags(tags):
for t in parse_tag_input(tags):
snipt.tags.add(t)
snipt.save()
@ -133,3 +135,84 @@ def comments():
print "Couldn't get snipt " + str(snipt_id)
print 'Done with comments'
def parse_tag_input(input):
"""
Parses tag input, with multiple word input being activated and
delineated by commas and double quotes. Quotes take precedence, so
they may contain commas.
Returns a sorted list of unique tag names.
"""
if not input:
return []
input = force_unicode(input)
# Special case - if there are no commas or double quotes in the
# input, we don't *do* a recall... I mean, we know we only need to
# split on spaces.
if u',' not in input and u'"' not in input:
words = list(set(split_strip(input, u' ')))
words.sort()
return words
words = []
buffer = []
# Defer splitting of non-quoted sections until we know if there are
# any unquoted commas.
to_be_split = []
saw_loose_comma = False
open_quote = False
i = iter(input)
try:
while 1:
c = i.next()
if c == u'"':
if buffer:
to_be_split.append(u''.join(buffer))
buffer = []
# Find the matching quote
open_quote = True
c = i.next()
while c != u'"':
buffer.append(c)
c = i.next()
if buffer:
word = u''.join(buffer).strip()
if word:
words.append(word)
buffer = []
open_quote = False
else:
if not saw_loose_comma and c == u',':
saw_loose_comma = True
buffer.append(c)
except StopIteration:
# If we were parsing an open quote which was never closed treat
# the buffer as unquoted.
if buffer:
if open_quote and u',' in buffer:
saw_loose_comma = True
to_be_split.append(u''.join(buffer))
if to_be_split:
if saw_loose_comma:
delimiter = u','
else:
delimiter = u' '
for chunk in to_be_split:
words.extend(split_strip(chunk, delimiter))
words = list(set(words))
words.sort()
return words
def split_strip(input, delimiter=u','):
"""
Splits ``input`` on ``delimiter``, stripping each resulting string
and returning a list of non-empty strings.
"""
if not input:
return []
words = [w.strip() for w in input.split(delimiter)]
return [w for w in words if w]

View File

@ -20,6 +20,9 @@ BeautifulSoup
django-taggit
django-postmark
johnny-cache
lxml
python-memcached
pyyaml
South
uuid
Werkzeug

View File

@ -58,11 +58,11 @@ INSTALLED_APPS = (
'django.contrib.sites',
'django.contrib.redirects',
'api',
'compressor',
'django_bcrypt',
'south',
'taggit',
'tastypie',
'snipts',
)

View File

@ -9,8 +9,7 @@ class CommentInline(admin.TabularInline):
allow_add = False
class SniptAdmin(admin.ModelAdmin):
# TODO: Make user readonly
#readonly_fields = ('user',)
readonly_fields = ('user',)
list_display = ('title', 'slug', 'user', 'lexer', 'public', 'created', 'modified',)
search_fields = ('title', 'user__username', 'tags', 'lexer', 'id',)
ordering = ('created',)

8
snipts/api.py Normal file
View File

@ -0,0 +1,8 @@
from tastypie.resources import ModelResource
from snipts.models import Snipt
class SniptResource(ModelResource):
class Meta:
queryset = Snipt.objects.all()
resource_name = 'snipt'

View File

@ -1,15 +1,16 @@
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
from django.db import models
from taggit.managers import TaggableManager
class Snipt(models.Model):
"""An individual code snippet."""
"""An individual Snipt."""
user = models.ForeignKey(User)
title = models.CharField(max_length=255)
slug = models.SlugField()
slug = models.SlugField(blank=True)
tags = TaggableManager()
lexer = models.CharField(max_length=50)
@ -23,8 +24,14 @@ class Snipt(models.Model):
created = models.DateTimeField(auto_now_add=False, editable=False)
modified = models.DateTimeField(auto_now=True, editable=False)
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)[:50]
return super(Entry, self).save(*args, **kwargs)
def __unicode__(self):
return u'%s' %(self.title)
return self.title
class Comment(models.Model):
"""A comment on a Snipt"""
@ -37,3 +44,6 @@ class Comment(models.Model):
# TODO Set auto_now_add back to True for production!
created = models.DateTimeField(auto_now_add=False, editable=False)
modified = models.DateTimeField(auto_now=True, editable=False)
def __unicode__(self):
return u'%s on %s' %(self.user, self.snipt)

View File

@ -6,6 +6,10 @@ admin.autodiscover()
from views import home
from snipts.api import SniptResource
snipt_resource = SniptResource()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
@ -14,7 +18,7 @@ urlpatterns = patterns('',
url(r'^404/$', direct_to_template, {'template': '404.html'}),
url(r'^500/$', direct_to_template, {'template': '500.html'}),
url(r'^api/', include('api.urls')),
url(r'^api/', include(snipt_resource.urls)),
url(r'^$', home),
)