From c1c43dd51a00e36516ba9dc9a2e3fe8e4c0708ce Mon Sep 17 00:00:00 2001 From: Martin Mahner Date: Sun, 24 Nov 2013 19:18:56 +0100 Subject: [PATCH] A better API that supports more values. --- dpaste/forms.py | 6 ++--- dpaste/highlight.py | 2 ++ dpaste/tests/test_api.py | 39 +++++++++++++++++++++++++++++++- dpaste/views.py | 49 +++++++++++++++++++++++++++++++++------- 4 files changed, 84 insertions(+), 12 deletions(-) diff --git a/dpaste/forms.py b/dpaste/forms.py index 179890f..831ecfe 100644 --- a/dpaste/forms.py +++ b/dpaste/forms.py @@ -5,7 +5,7 @@ from django.conf import settings from django.utils.translation import ugettext_lazy as _ from dpaste.models import Snippet -from dpaste.highlight import LEXER_LIST, LEXER_DEFAULT +from dpaste.highlight import LEXER_LIST, LEXER_DEFAULT, LEXER_KEYS EXPIRE_CHOICES = ( (3600, _(u'In one hour')), @@ -56,11 +56,11 @@ class SnippetForm(forms.ModelForm): # Set the recently used lexer if we have any session_lexer = self.request.session.get('lexer') - if session_lexer and session_lexer in dict(LEXER_LIST).keys(): + if session_lexer and session_lexer in LEXER_KEYS: self.fields['lexer'].initial = session_lexer # if the lexer is given via GET, set it - if 'l' in request.GET and request.GET['l'] in dict(LEXER_LIST).keys(): + if 'l' in request.GET and request.GET['l'] in LEXERK_KEYS: self.fields['lexer'].initial = request.GET['l'] diff --git a/dpaste/highlight.py b/dpaste/highlight.py index 2db980d..80c3b01 100644 --- a/dpaste/highlight.py +++ b/dpaste/highlight.py @@ -92,6 +92,8 @@ LEXER_LIST = getattr(settings, 'DPASTE_LEXER_LIST', ( ('yaml', 'YAML'), )) +LEXER_KEYS = dict(LEXER_LIST).keys() + # The default lexer is python LEXER_DEFAULT = getattr(settings, 'DPASTE_LEXER_DEFAULT', 'python') diff --git a/dpaste/tests/test_api.py b/dpaste/tests/test_api.py index 0f5a44f..77b3a34 100644 --- a/dpaste/tests/test_api.py +++ b/dpaste/tests/test_api.py @@ -44,7 +44,7 @@ class SnippetAPITestCase(TestCase): self.assertEqual(response.status_code, 400) self.assertEqual(Snippet.objects.count(), 0) - def test_valid(self): + def test_default_response(self): """ A valid snippet, contains Unicode, tabs, spaces, linebreaks etc. """ @@ -65,3 +65,40 @@ class SnippetAPITestCase(TestCase): self.assertEqual(response.status_code, 200) self.assertContains(response, data['content']) + + def test_new_url_format(self): + """ + The 'new' url format is just the link with a linebreak. + """ + data = {'content': u"Hello Wörld.\n\tGood Bye", 'format': 'url'} + + response = self.client.post(self.api_url, data) + self.assertEqual(response.status_code, 200) + self.assertEqual(Snippet.objects.count(), 1) + + # Response is just the link starting with http(s) and ends with a linebreak + self.assertTrue(response.content.startswith('http')) + self.assertTrue(response.content.endswith('\n')) + + + def test_json_format(self): + """ + The 'new' url format is just the link with a linebreak. + """ + data = { + 'content': u"Hello Wörld.\n\tGood Bye", + 'format': 'json', + 'lexer': 'haskell' + } + + response = self.client.post(self.api_url, data) + self.assertEqual(response.status_code, 200) + self.assertEqual(Snippet.objects.count(), 1) + + from json import loads + json_data = loads(response.content) + + # Response is valid json, containing, content, lexer and url + self.assertEqual(json_data['content'], data['content']) + self.assertEqual(json_data['lexer'], data['lexer']) + self.assertTrue(json_data['url'].startswith('http')) diff --git a/dpaste/views.py b/dpaste/views.py index 5ac0254..537e3c4 100644 --- a/dpaste/views.py +++ b/dpaste/views.py @@ -2,11 +2,10 @@ import datetime import difflib import requests -from django.shortcuts import (render_to_response, get_object_or_404, - get_list_or_404) +from django.shortcuts import (render_to_response, get_object_or_404) from django.template.context import RequestContext from django.http import (Http404, HttpResponseRedirect, HttpResponseBadRequest, - HttpResponse, HttpResponseForbidden) + HttpResponse) from django.conf import settings from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned from django.utils.translation import ugettext_lazy as _ @@ -19,6 +18,7 @@ from django.views.defaults import (page_not_found as django_page_not_found, from dpaste.forms import SnippetForm from dpaste.models import Snippet from dpaste.highlight import LEXER_WORDWRAP, LEXER_LIST +from dpaste.highlight import LEXER_DEFAULT, LEXER_KEYS # ----------------------------------------------------------------------------- # Snippet Handling @@ -248,21 +248,54 @@ def about(request, template_name='dpaste/about.html'): # API Handling # ----------------------------------------------------------------------------- -def snippet_api(request, enclose_quotes=True): +BASE_URL = getattr(settings, 'DPASTE_BASE_URL', 'https://dpaste.de') + +def _format_default(s): + """The default response is the snippet URL wrapped in quotes.""" + return u'"%s%s"' % (BASE_URL, s.get_absolute_url()) + +def _format_url(s): + """The `url` format returns the snippet URL, no quotes, but a linebreak after.""" + return u'%s%s\n' % (BASE_URL, s.get_absolute_url()) + +def _format_json(s): + from json import dumps + """The `json` format export.""" + return dumps({ + 'url': u'%s%s' % (BASE_URL, s.get_absolute_url()), + 'content': s.content, + 'lexer': s.lexer, + }) + +FORMAT_MAPPING = { + 'default': _format_default, + 'url': _format_url, + 'json': _format_json, +} +def snippet_api(request): content = request.POST.get('content', '').strip() + lexer = request.POST.get('lexer', LEXER_DEFAULT).strip() + format = request.POST.get('format', 'default').strip() if not content: - return HttpResponseBadRequest() + return HttpResponseBadRequest('No content given') + + if not lexer in LEXER_KEYS: + return HttpResponseBadRequest('Invalid lexer given. Valid lexers are: %s' % + ', '.join(LEXER_KEYS)) s = Snippet.objects.create( content=content, + lexer=lexer, expires=datetime.datetime.now()+datetime.timedelta(seconds=60*60*24*30) ) s.save() - response = 'http://dpaste.de%s' % s.get_absolute_url() - if enclose_quotes: - return HttpResponse('"%s"' % response) + if not format in FORMAT_MAPPING: + response = _format_default(s) + else: + response = FORMAT_MAPPING[format](s) + return HttpResponse(response)