mirror of
https://github.com/DarrenOfficial/dpaste.git
synced 2024-12-19 00:09:21 +11:00
Add support to set a lexer with a given filename. Closes issue #63.
This allows third-party API utils to set the lexer automatically based on the open filename.
This commit is contained in:
parent
fbe6aeedb7
commit
3bc2eb0c84
3 changed files with 102 additions and 6 deletions
26
docs/api.rst
26
docs/api.rst
|
@ -62,6 +62,32 @@ values. Default: ``2592000``. In the default configuration valid values are:
|
|||
* 604800
|
||||
* 2592000
|
||||
|
||||
``filename`` (optional)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Can also be set via GET. A filename which we use to determine a lexer, if
|
||||
``lexer`` is not set. In case we can't determine a file, the lexer will fallback
|
||||
to ``plain`` code (no highlighting). A given ``lexer`` will overwrite any
|
||||
filename! Example::
|
||||
|
||||
{
|
||||
"url": "https://dpaste.de/xsWd",
|
||||
"lexer": "",
|
||||
"filename": "python",
|
||||
"conent": "The text body of the snippet."
|
||||
}
|
||||
|
||||
This will create a ``python`` highlighted snippet. However in this example::
|
||||
|
||||
{
|
||||
"url": "https://dpaste.de/xsWd",
|
||||
"lexer": "php",
|
||||
"filename": "python",
|
||||
"conent": "The text body of the snippet."
|
||||
}
|
||||
|
||||
Since the lexer is set too, we will create a ``php`` highlighted snippet.
|
||||
|
||||
.. hint:: You need to adjust the setting ``DPASTE_BASE_URL`` which is used
|
||||
to generate the full qualified URL in the API response. See :doc:`settings`.
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
from django.core.urlresolvers import reverse
|
||||
from django.test.client import Client
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from ..models import Snippet
|
||||
from ..highlight import PLAIN_CODE
|
||||
|
||||
class SnippetAPITestCase(TestCase):
|
||||
|
||||
|
@ -188,3 +188,53 @@ class SnippetAPITestCase(TestCase):
|
|||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(Snippet.objects.count(), 1)
|
||||
self.assertTrue(Snippet.objects.all()[0].expires)
|
||||
|
||||
def test_filename_not_given(self):
|
||||
"""
|
||||
No lexer and no filename given returns a BadRequest.
|
||||
"""
|
||||
response = self.client.post(self.api_url, {
|
||||
'content': u"Hello Wörld.\n\tGood Bye",
|
||||
'lexer': '',
|
||||
'filename': ''
|
||||
})
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_filename_given(self):
|
||||
"""
|
||||
No lexer and a Python filename will set a 'python' lexer.
|
||||
"""
|
||||
response = self.client.post(self.api_url, {
|
||||
'content': u"Hello Wörld.\n\tGood Bye",
|
||||
'lexer': '',
|
||||
'filename': 'helloworld.py'
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(Snippet.objects.count(), 1)
|
||||
self.assertEqual(Snippet.objects.all()[0].lexer, 'python')
|
||||
|
||||
def test_awkward_filename_given(self):
|
||||
"""
|
||||
A unknown filename will create a 'plain' code snippet.
|
||||
"""
|
||||
response = self.client.post(self.api_url, {
|
||||
'content': u"Hello Wörld.\n\tGood Bye",
|
||||
'lexer': '',
|
||||
'filename': 'helloworld.helloworld'
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(Snippet.objects.count(), 1)
|
||||
self.assertEqual(Snippet.objects.all()[0].lexer, PLAIN_CODE)
|
||||
|
||||
def test_filename_and_lexer_given(self):
|
||||
"""
|
||||
A given lexer will overwrite whats the filename guessing.
|
||||
"""
|
||||
response = self.client.post(self.api_url, {
|
||||
'content': u"Hello Wörld.\n\tGood Bye",
|
||||
'lexer': 'php',
|
||||
'filename': 'helloworld.py'
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(Snippet.objects.count(), 1)
|
||||
self.assertEqual(Snippet.objects.all()[0].lexer, 'php')
|
||||
|
|
|
@ -16,10 +16,13 @@ from django.views.defaults import (page_not_found as django_page_not_found,
|
|||
server_error as django_server_error)
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from pygments.lexers import get_lexer_for_filename
|
||||
from pygments.util import ClassNotFound
|
||||
|
||||
from dpaste.forms import SnippetForm, get_expire_values, EXPIRE_CHOICES
|
||||
from dpaste.models import Snippet, ONETIME_LIMIT
|
||||
from dpaste.highlight import LEXER_WORDWRAP, LEXER_LIST
|
||||
from dpaste.highlight import LEXER_DEFAULT, LEXER_KEYS
|
||||
from dpaste.highlight import (LEXER_DEFAULT, LEXER_KEYS, LEXER_WORDWRAP,
|
||||
LEXER_LIST, PLAIN_CODE)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Snippet Handling
|
||||
|
@ -285,15 +288,32 @@ FORMAT_MAPPING = {
|
|||
def snippet_api(request):
|
||||
content = request.POST.get('content', '').strip()
|
||||
lexer = request.REQUEST.get('lexer', LEXER_DEFAULT).strip()
|
||||
filename = request.REQUEST.get('filename', '').strip()
|
||||
expires = request.REQUEST.get('expires', '').strip()
|
||||
format = request.REQUEST.get('format', 'default').strip()
|
||||
|
||||
if not content:
|
||||
return HttpResponseBadRequest('No content given')
|
||||
|
||||
if not lexer in LEXER_KEYS:
|
||||
return HttpResponseBadRequest('Invalid lexer given. Valid lexers are: %s' %
|
||||
', '.join(LEXER_KEYS))
|
||||
# We need at least a lexer or a filename
|
||||
if not lexer and not filename:
|
||||
return HttpResponseBadRequest('No lexer or filename given. Unable to '
|
||||
'determine a highlight. Valid lexers are: %s' % ', '.join(LEXER_KEYS))
|
||||
|
||||
# A lexer is given, check if its valid at all
|
||||
if lexer and lexer not in LEXER_KEYS:
|
||||
return HttpResponseBadRequest('Invalid lexer "%s" given. Valid lexers are: %s' % (
|
||||
lexer, ', '.join(LEXER_KEYS)))
|
||||
|
||||
# No lexer is given, but we have a filename, try to get the lexer out of it.
|
||||
# In case Pygments cannot determine the lexer of the filename, we fallback
|
||||
# to 'plain' code.
|
||||
if not lexer and filename:
|
||||
try:
|
||||
lexer_cls = get_lexer_for_filename(filename)
|
||||
lexer = lexer_cls.aliases[0]
|
||||
except (ClassNotFound, IndexError):
|
||||
lexer = PLAIN_CODE
|
||||
|
||||
if expires:
|
||||
expire_options = [str(i) for i in dict(EXPIRE_CHOICES).keys()]
|
||||
|
|
Loading…
Reference in a new issue