Readonly public API
parent
a7852c8042
commit
27cf162939
87
migrate.py
87
migrate.py
|
@ -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]
|
||||
|
|
|
@ -20,6 +20,9 @@ BeautifulSoup
|
|||
django-taggit
|
||||
django-postmark
|
||||
johnny-cache
|
||||
lxml
|
||||
python-memcached
|
||||
pyyaml
|
||||
South
|
||||
uuid
|
||||
Werkzeug
|
||||
|
|
|
@ -58,11 +58,11 @@ INSTALLED_APPS = (
|
|||
'django.contrib.sites',
|
||||
'django.contrib.redirects',
|
||||
|
||||
'api',
|
||||
'compressor',
|
||||
'django_bcrypt',
|
||||
'south',
|
||||
'taggit',
|
||||
'tastypie',
|
||||
|
||||
'snipts',
|
||||
)
|
||||
|
|
|
@ -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',)
|
||||
|
|
|
@ -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'
|
|
@ -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)
|
||||
|
|
6
urls.py
6
urls.py
|
@ -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),
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue