Readonly public API
parent
a7852c8042
commit
27cf162939
87
migrate.py
87
migrate.py
|
@ -1,5 +1,7 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
from django.utils.encoding import force_unicode
|
||||||
|
|
||||||
import MySQLdb
|
import MySQLdb
|
||||||
|
|
||||||
from django.contrib.auth.models import User
|
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.models import Tag, TaggedItem
|
||||||
from taggit.utils import parse_tags
|
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()
|
cursor = conn.cursor()
|
||||||
|
|
||||||
def i():
|
def i():
|
||||||
|
@ -99,7 +101,7 @@ def snipts():
|
||||||
public=public,
|
public=public,
|
||||||
created=created,
|
created=created,
|
||||||
)
|
)
|
||||||
for t in parse_tags(tags):
|
for t in parse_tag_input(tags):
|
||||||
snipt.tags.add(t)
|
snipt.tags.add(t)
|
||||||
snipt.save()
|
snipt.save()
|
||||||
|
|
||||||
|
@ -133,3 +135,84 @@ def comments():
|
||||||
print "Couldn't get snipt " + str(snipt_id)
|
print "Couldn't get snipt " + str(snipt_id)
|
||||||
|
|
||||||
print 'Done with comments'
|
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-taggit
|
||||||
django-postmark
|
django-postmark
|
||||||
johnny-cache
|
johnny-cache
|
||||||
|
lxml
|
||||||
python-memcached
|
python-memcached
|
||||||
|
pyyaml
|
||||||
South
|
South
|
||||||
|
uuid
|
||||||
Werkzeug
|
Werkzeug
|
||||||
|
|
|
@ -58,11 +58,11 @@ INSTALLED_APPS = (
|
||||||
'django.contrib.sites',
|
'django.contrib.sites',
|
||||||
'django.contrib.redirects',
|
'django.contrib.redirects',
|
||||||
|
|
||||||
'api',
|
|
||||||
'compressor',
|
'compressor',
|
||||||
'django_bcrypt',
|
'django_bcrypt',
|
||||||
'south',
|
'south',
|
||||||
'taggit',
|
'taggit',
|
||||||
|
'tastypie',
|
||||||
|
|
||||||
'snipts',
|
'snipts',
|
||||||
)
|
)
|
||||||
|
|
|
@ -9,8 +9,7 @@ class CommentInline(admin.TabularInline):
|
||||||
allow_add = False
|
allow_add = False
|
||||||
|
|
||||||
class SniptAdmin(admin.ModelAdmin):
|
class SniptAdmin(admin.ModelAdmin):
|
||||||
# TODO: Make user readonly
|
readonly_fields = ('user',)
|
||||||
#readonly_fields = ('user',)
|
|
||||||
list_display = ('title', 'slug', 'user', 'lexer', 'public', 'created', 'modified',)
|
list_display = ('title', 'slug', 'user', 'lexer', 'public', 'created', 'modified',)
|
||||||
search_fields = ('title', 'user__username', 'tags', 'lexer', 'id',)
|
search_fields = ('title', 'user__username', 'tags', 'lexer', 'id',)
|
||||||
ordering = ('created',)
|
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.contrib.auth.models import User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from taggit.managers import TaggableManager
|
from taggit.managers import TaggableManager
|
||||||
|
|
||||||
class Snipt(models.Model):
|
class Snipt(models.Model):
|
||||||
"""An individual code snippet."""
|
"""An individual Snipt."""
|
||||||
|
|
||||||
user = models.ForeignKey(User)
|
user = models.ForeignKey(User)
|
||||||
|
|
||||||
title = models.CharField(max_length=255)
|
title = models.CharField(max_length=255)
|
||||||
slug = models.SlugField()
|
slug = models.SlugField(blank=True)
|
||||||
tags = TaggableManager()
|
tags = TaggableManager()
|
||||||
|
|
||||||
lexer = models.CharField(max_length=50)
|
lexer = models.CharField(max_length=50)
|
||||||
|
@ -23,8 +24,14 @@ class Snipt(models.Model):
|
||||||
created = models.DateTimeField(auto_now_add=False, editable=False)
|
created = models.DateTimeField(auto_now_add=False, editable=False)
|
||||||
modified = models.DateTimeField(auto_now=True, 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):
|
def __unicode__(self):
|
||||||
return u'%s' %(self.title)
|
return self.title
|
||||||
|
|
||||||
class Comment(models.Model):
|
class Comment(models.Model):
|
||||||
"""A comment on a Snipt"""
|
"""A comment on a Snipt"""
|
||||||
|
@ -37,3 +44,6 @@ class Comment(models.Model):
|
||||||
# TODO Set auto_now_add back to True for production!
|
# TODO Set auto_now_add back to True for production!
|
||||||
created = models.DateTimeField(auto_now_add=False, editable=False)
|
created = models.DateTimeField(auto_now_add=False, editable=False)
|
||||||
modified = models.DateTimeField(auto_now=True, 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 views import home
|
||||||
|
|
||||||
|
from snipts.api import SniptResource
|
||||||
|
|
||||||
|
snipt_resource = SniptResource()
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
url(r'^admin/', include(admin.site.urls)),
|
url(r'^admin/', include(admin.site.urls)),
|
||||||
|
@ -14,7 +18,7 @@ urlpatterns = patterns('',
|
||||||
url(r'^404/$', direct_to_template, {'template': '404.html'}),
|
url(r'^404/$', direct_to_template, {'template': '404.html'}),
|
||||||
url(r'^500/$', direct_to_template, {'template': '500.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),
|
url(r'^$', home),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue