diff options
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/blogpost/models.py | 8 | ||||
| -rw-r--r-- | examples/blogpost/urls.py | 11 | ||||
| -rw-r--r-- | examples/blogpost/views.py | 46 | ||||
| -rw-r--r-- | examples/pygments_api/forms.py | 21 | ||||
| -rw-r--r-- | examples/pygments_api/urls.py | 2 | ||||
| -rw-r--r-- | examples/pygments_api/views.py | 51 | ||||
| -rw-r--r-- | examples/urls.py | 1 |
7 files changed, 58 insertions, 82 deletions
diff --git a/examples/blogpost/models.py b/examples/blogpost/models.py index 1690245c..e1968415 100644 --- a/examples/blogpost/models.py +++ b/examples/blogpost/models.py @@ -30,13 +30,7 @@ class BlogPost(models.Model): @models.permalink def comments_url(self): """Link to a resource which lists all comments for this blog post.""" - return ('blogpost.views.CommentList', (), {'blogpost_id': self.key}) - - @property - @models.permalink - def comment_url(self): - """Link to a resource which can create a comment for this blog post.""" - return ('blogpost.views.CommentCreator', (), {'blogpost_id': self.key}) + return ('blogpost.views.CommentRoot', (), {'blogpost_id': self.key}) def __unicode__(self): return self.title diff --git a/examples/blogpost/urls.py b/examples/blogpost/urls.py index eccbae15..ee209b3e 100644 --- a/examples/blogpost/urls.py +++ b/examples/blogpost/urls.py @@ -1,11 +1,8 @@ from django.conf.urls.defaults import patterns urlpatterns = patterns('blogpost.views', - (r'^$', 'RootResource'), - (r'^blog-posts/$', 'BlogPostList'), - (r'^blog-post/$', 'BlogPostCreator'), - (r'^blog-post/(?P<key>[^/]+)/$', 'BlogPostInstance'), - (r'^blog-post/(?P<blogpost_id>[^/]+)/comments/$', 'CommentList'), - (r'^blog-post/(?P<blogpost_id>[^/]+)/comment/$', 'CommentCreator'), - (r'^blog-post/(?P<blogpost>[^/]+)/comments/(?P<id>[^/]+)/$', 'CommentInstance'), + (r'^$', 'BlogPostRoot'), + (r'^(?P<key>[^/]+)/$', 'BlogPostInstance'), + (r'^(?P<blogpost_id>[^/]+)/comments/$', 'CommentRoot'), + (r'^(?P<blogpost>[^/]+)/comments/(?P<id>[^/]+)/$', 'CommentInstance'), ) diff --git a/examples/blogpost/views.py b/examples/blogpost/views.py index 05e795fa..c5be2544 100644 --- a/examples/blogpost/views.py +++ b/examples/blogpost/views.py @@ -1,34 +1,15 @@ from flywheel.response import Response, status from flywheel.resource import Resource -from flywheel.modelresource import ModelResource, QueryModelResource +from flywheel.modelresource import ModelResource, RootModelResource from blogpost.models import BlogPost, Comment -##### Root Resource ##### - -class RootResource(Resource): - """This is the top level resource for the API. - All the sub-resources are discoverable from here.""" - allowed_methods = ('GET',) - - def get(self, request, *args, **kwargs): - return Response(status.HTTP_200_OK, - {'blog-posts': self.reverse(BlogPostList), - 'blog-post': self.reverse(BlogPostCreator)}) - - -##### Blog Post Resources ##### - BLOG_POST_FIELDS = ('created', 'title', 'slug', 'content', 'absolute_url', 'comment_url', 'comments_url') +COMMENT_FIELDS = ('username', 'comment', 'created', 'rating', 'absolute_url', 'blogpost_url') -class BlogPostList(QueryModelResource): - """A resource which lists all existing blog posts.""" - allowed_methods = ('GET', ) - model = BlogPost - fields = BLOG_POST_FIELDS -class BlogPostCreator(ModelResource): - """A resource with which blog posts may be created.""" - allowed_methods = ('POST',) +class BlogPostRoot(RootModelResource): + """A resource with which lists all existing blog posts and creates new blog posts.""" + allowed_methods = ('GET', 'POST',) model = BlogPost fields = BLOG_POST_FIELDS @@ -38,20 +19,9 @@ class BlogPostInstance(ModelResource): model = BlogPost fields = BLOG_POST_FIELDS - -##### Comment Resources ##### - -COMMENT_FIELDS = ('username', 'comment', 'created', 'rating', 'absolute_url', 'blogpost_url') - -class CommentList(QueryModelResource): - """A resource which lists all existing comments for a given blog post.""" - allowed_methods = ('GET', ) - model = Comment - fields = COMMENT_FIELDS - -class CommentCreator(ModelResource): - """A resource with which blog comments may be created for a given blog post.""" - allowed_methods = ('POST',) +class CommentRoot(RootModelResource): + """A resource which lists all existing comments for a given blog post, and creates new blog comments for a given blog post.""" + allowed_methods = ('GET', 'POST',) model = Comment fields = COMMENT_FIELDS diff --git a/examples/pygments_api/forms.py b/examples/pygments_api/forms.py index dc9927e2..8488db06 100644 --- a/examples/pygments_api/forms.py +++ b/examples/pygments_api/forms.py @@ -3,23 +3,26 @@ from django import forms from pygments.lexers import get_all_lexers from pygments.styles import get_all_styles -import httplib2 as httplib - - LEXER_CHOICES = sorted([(item[1][0], item[0]) for item in get_all_lexers()]) STYLE_CHOICES = sorted((item, item) for item in list(get_all_styles())) - class PygmentsForm(forms.Form): """A simple form with some of the most important pygments settings. The code to be highlighted can be specified either in a text field, or by URL. We do some additional form validation to ensure clients see helpful error responses.""" - code = forms.CharField(widget=forms.Textarea, label='Code Text', max_length=1000000, + code = forms.CharField(widget=forms.Textarea, + label='Code Text', + max_length=1000000, help_text='(Copy and paste the code text here.)') - title = forms.CharField(required=False, help_text='(Optional)', max_length=100) - linenos = forms.BooleanField(label='Show Line Numbers', required=False) - lexer = forms.ChoiceField(choices=LEXER_CHOICES, initial='python') - style = forms.ChoiceField(choices=STYLE_CHOICES, initial='friendly') + title = forms.CharField(required=False, + help_text='(Optional)', + max_length=100) + linenos = forms.BooleanField(label='Show Line Numbers', + required=False) + lexer = forms.ChoiceField(choices=LEXER_CHOICES, + initial='python') + style = forms.ChoiceField(choices=STYLE_CHOICES, + initial='friendly') diff --git a/examples/pygments_api/urls.py b/examples/pygments_api/urls.py index 39bcf668..f96f4518 100644 --- a/examples/pygments_api/urls.py +++ b/examples/pygments_api/urls.py @@ -2,5 +2,5 @@ from django.conf.urls.defaults import patterns urlpatterns = patterns('pygments_api.views', (r'^$', 'PygmentsRoot'), - (r'^([a-zA-Z0-9]+)/$', 'PygmentsInstance'), + (r'^([a-zA-Z0-9-]+)/$', 'PygmentsInstance'), ) diff --git a/examples/pygments_api/views.py b/examples/pygments_api/views.py index 4493a822..96322115 100644 --- a/examples/pygments_api/views.py +++ b/examples/pygments_api/views.py @@ -11,10 +11,19 @@ from pygments import highlight from forms import PygmentsForm import os -import hashlib +import uuid +import operator # We need somewhere to store the code that we highlight HIGHLIGHTED_CODE_DIR = os.path.join(settings.MEDIA_ROOT, 'pygments') +MAX_FILES = 5 + +def remove_oldest_files(dir, max_files): + """Remove the oldest files in a directory 'dir', leaving at most 'max_files' remaining""" + filepaths = [os.path.join(dir, file) for file in os.listdir(dir)] + ctime_sorted_paths = [item[0] for item in sorted([(path, os.path.getctime(path)) for path in filepaths], + key=operator.itemgetter(1), reverse=True)] + [os.remove(path) for path in ctime_sorted_paths[max_files:]] class HTMLEmitter(BaseEmitter): @@ -24,38 +33,42 @@ class HTMLEmitter(BaseEmitter): class PygmentsRoot(Resource): """This example demonstrates a simple RESTful Web API aound the awesome pygments library. - This top level resource is used to create highlighted code snippets.""" + This top level resource is used to create highlighted code snippets, and to list all the existing code snippets.""" form = PygmentsForm - allowed_methods = anon_allowed_methods = ('POST',) + allowed_methods = anon_allowed_methods = ('GET', 'POST',) + + def get(self, request, auth): + """Return a list of all currently existing snippets.""" + unique_ids = sorted(os.listdir(HIGHLIGHTED_CODE_DIR)) + return [self.reverse(PygmentsInstance, unique_id) for unique_id in unique_ids] def post(self, request, auth, content): - # Generate a unique id by hashing the input - input_str = ''.join(['%s%s' % (key, content[key]) for key in sorted(content.keys())]) - hash = hashlib.md5() - hash.update(input_str) - unique_id = hash.hexdigest() + """Create a new highlighed snippet and return it's location. + For the purposes of the sandbox example, also ensure we delete the oldest snippets if we have > MAX_FILES.""" + unique_id = str(uuid.uuid1()) pathname = os.path.join(HIGHLIGHTED_CODE_DIR, unique_id) - if not os.path.exists(pathname): - # We only need to generate the file if it doesn't already exist. - options = {'title': content['title']} if content['title'] else {} - linenos = 'table' if content['linenos'] else False - lexer = get_lexer_by_name(content['lexer']) - formatter = HtmlFormatter(style=content['style'], linenos=linenos, full=True, **options) - - with open(pathname, 'w') as outfile: - highlight(content['code'], lexer, formatter, outfile) - + lexer = get_lexer_by_name(content['lexer']) + linenos = 'table' if content['linenos'] else False + options = {'title': content['title']} if content['title'] else {} + formatter = HtmlFormatter(style=content['style'], linenos=linenos, full=True, **options) + + with open(pathname, 'w') as outfile: + highlight(content['code'], lexer, formatter, outfile) + + remove_oldest_files(HIGHLIGHTED_CODE_DIR, MAX_FILES) + return Response(status.HTTP_201_CREATED, headers={'Location': self.reverse(PygmentsInstance, unique_id)}) class PygmentsInstance(Resource): """Simply return the stored highlighted HTML file with the correct mime type. - This Resource only emits HTML and uses a standard HTML emitter rather than FlyWheel's DocumentingHTMLEmitter class.""" + This Resource only emits HTML and uses a standard HTML emitter rather than the emitters.DocumentingHTMLEmitter class.""" allowed_methods = anon_allowed_methods = ('GET',) emitters = (HTMLEmitter,) def get(self, request, auth, unique_id): + """Return the highlighted snippet.""" pathname = os.path.join(HIGHLIGHTED_CODE_DIR, unique_id) if not os.path.exists(pathname): return Resource(status.HTTP_404_NOT_FOUND) diff --git a/examples/urls.py b/examples/urls.py index 48af39de..b1dec13d 100644 --- a/examples/urls.py +++ b/examples/urls.py @@ -7,7 +7,6 @@ urlpatterns = patterns('', (r'^pygments-example/', include('pygments_api.urls')), (r'^blog-post-example/', include('blogpost.urls')), (r'^object-store-example/', include('objectstore.urls')), - (r'^testarchive-example/', include('testarchive.urls')), (r'^accounts/login/$', 'django.contrib.auth.views.login'), (r'^accounts/logout/$', 'django.contrib.auth.views.logout'), (r'^admin/doc/', include('django.contrib.admindocs.urls')), |
