diff --git a/dpaste/__init__.py b/dpaste/__init__.py
index 6a76256..965b81d 100644
--- a/dpaste/__init__.py
+++ b/dpaste/__init__.py
@@ -1,9 +1,7 @@
VERSION = (3, 0, 'a', 1)
__version__ = '{major}.{minor}{rest}'.format(
- major=VERSION[0],
- minor=VERSION[1],
- rest=''.join(str(i) for i in VERSION[2:])
+ major=VERSION[0], minor=VERSION[1], rest=''.join(str(i) for i in VERSION[2:])
)
default_app_config = 'dpaste.apps.dpasteAppConfig'
diff --git a/dpaste/apps.py b/dpaste/apps.py
index 35303c2..171085f 100644
--- a/dpaste/apps.py
+++ b/dpaste/apps.py
@@ -96,10 +96,11 @@ class dpasteAppConfig(AppConfig):
from dpaste.highlight import (
PlainTextHighlighter,
MarkdownHighlighter,
- RestructuredTextHighlighter
+ RestructuredTextHighlighter,
)
+
return [
- (self.PLAIN_TEXT_SYMBOL, 'Plain Text', PlainTextHighlighter),
+ (self.PLAIN_TEXT_SYMBOL, 'Plain Text', PlainTextHighlighter),
('_markdown', 'Markdown', MarkdownHighlighter),
('_rst', 'reStructuredText', RestructuredTextHighlighter),
]
@@ -116,10 +117,8 @@ class dpasteAppConfig(AppConfig):
If the Highlight Class is not given, PygmentsHighlighter is used.
"""
- from dpaste.highlight import (
- PlainCodeHighlighter,
- SolidityHighlighter
- )
+ from dpaste.highlight import PlainCodeHighlighter, SolidityHighlighter
+
return [
(self.PLAIN_CODE_SYMBOL, 'Plain Code', PlainCodeHighlighter),
('abap', 'ABAP'),
@@ -204,6 +203,7 @@ class dpasteAppConfig(AppConfig):
"""
if apps.is_installed('django.contrib.sites'):
from django.contrib.sites.shortcuts import get_current_site
+
site = get_current_site(request)
if site:
return 'https://{0}'.format(site.domain)
diff --git a/dpaste/forms.py b/dpaste/forms.py
index 7c73d6a..4091a0b 100644
--- a/dpaste/forms.py
+++ b/dpaste/forms.py
@@ -29,34 +29,27 @@ class SnippetForm(forms.ModelForm):
label=_('Content'),
widget=forms.Textarea(attrs={'placeholder': _('Awesome code goes here...')}),
max_length=config.MAX_CONTENT_LENGTH,
- strip=False
+ strip=False,
)
lexer = forms.ChoiceField(
- label=_('Lexer'),
- initial=LEXER_DEFAULT,
- choices=LEXER_CHOICES
+ label=_('Lexer'), initial=LEXER_DEFAULT, choices=LEXER_CHOICES
)
expires = forms.ChoiceField(
- label=_('Expires'),
- choices=config.EXPIRE_CHOICES,
- initial=config.EXPIRE_DEFAULT
+ label=_('Expires'), choices=config.EXPIRE_CHOICES, initial=config.EXPIRE_DEFAULT
)
# Honeypot field
title = forms.CharField(
label=_('Title'),
required=False,
- widget=forms.TextInput(attrs={'autocomplete': 'off'})
+ widget=forms.TextInput(attrs={'autocomplete': 'off'}),
)
class Meta:
model = Snippet
- fields = (
- 'content',
- 'lexer',
- )
+ fields = ('content', 'lexer')
def __init__(self, request, *args, **kwargs):
super(SnippetForm, self).__init__(*args, **kwargs)
diff --git a/dpaste/highlight.py b/dpaste/highlight.py
index 3ad41ef..4e7a2b7 100644
--- a/dpaste/highlight.py
+++ b/dpaste/highlight.py
@@ -19,6 +19,7 @@ config = apps.get_app_config('dpaste')
# Highlight Code Snippets
# -----------------------------------------------------------------------------
+
class Highlighter(object):
template_name = 'dpaste/highlight/code.html'
@@ -47,6 +48,7 @@ class Highlighter(object):
class PlainTextHighlighter(Highlighter):
"""Plain Text. Just replace linebreaks."""
+
template_name = 'dpaste/highlight/text.html'
def highlight(self, code_string, **kwargs):
@@ -55,20 +57,33 @@ class PlainTextHighlighter(Highlighter):
class MarkdownHighlighter(PlainTextHighlighter):
"""Markdown"""
- extensions = ('tables', 'fenced-code', 'footnotes', 'autolink,',
- 'strikethrough', 'underline', 'quote', 'superscript',
- 'math')
+
+ extensions = (
+ 'tables',
+ 'fenced-code',
+ 'footnotes',
+ 'autolink,',
+ 'strikethrough',
+ 'underline',
+ 'quote',
+ 'superscript',
+ 'math',
+ )
render_flags = ('skip-html',)
def highlight(self, code_string, **kwargs):
import misaka
- return mark_safe(misaka.html(code_string,
- extensions=self.extensions,
- render_flags=self.render_flags))
+
+ return mark_safe(
+ misaka.html(
+ code_string, extensions=self.extensions, render_flags=self.render_flags
+ )
+ )
class RestructuredTextHighlighter(PlainTextHighlighter):
"""Restructured Text"""
+
rst_part_name = 'html_body'
publish_args = {
'writer_name': 'html5_polyglot',
@@ -78,11 +93,12 @@ class RestructuredTextHighlighter(PlainTextHighlighter):
'halt_level': 5,
'report_level': 2,
'warning_stream': '/dev/null',
- }
+ },
}
def highlight(self, code_string, **kwargs):
from docutils.core import publish_parts
+
self.publish_args['source'] = code_string
parts = publish_parts(**self.publish_args)
return mark_safe(parts[self.rst_part_name])
@@ -93,6 +109,7 @@ class RestructuredTextHighlighter(PlainTextHighlighter):
class NakedHtmlFormatter(HtmlFormatter):
"""Pygments HTML formatter with no further HTML tags."""
+
def wrap(self, source, outfile):
return self._wrap_code(source)
@@ -105,11 +122,14 @@ class PlainCodeHighlighter(Highlighter):
"""
Plain Code. No highlighting but Pygments like span tags around each line.
"""
+
def highlight(self, code_string, **kwargs):
- return '\n'.join([
- '{}'.format(escape(l) or '')
+ return '\n'.join(
+ [
+ '{}'.format(escape(l) or '')
for l in code_string.splitlines()
- ])
+ ]
+ )
class PygmentsHighlighter(Highlighter):
@@ -117,6 +137,7 @@ class PygmentsHighlighter(Highlighter):
Highlight code string with Pygments. The lexer is automatically
determined by the lexer name.
"""
+
formatter = NakedHtmlFormatter()
lexer = None
lexer_fallback = PythonLexer()
@@ -139,6 +160,7 @@ class SolidityHighlighter(PygmentsHighlighter):
# SolidityLexer does not necessarily need to be installed
# since its imported here and not used later.
from pygments_lexer_solidity import SolidityLexer
+
self.lexer = SolidityLexer()
@@ -167,12 +189,13 @@ def get_highlighter_class(lexer_name):
# Generate a list of Form choices of all lexer.
LEXER_CHOICES = (
(_('Text'), [i[:2] for i in config.TEXT_FORMATTER]),
- (_('Code'), [i[:2] for i in config.CODE_FORMATTER])
+ (_('Code'), [i[:2] for i in config.CODE_FORMATTER]),
)
# List of all Lexer Keys
-LEXER_KEYS = [i[0] for i in config.TEXT_FORMATTER] + \
- [i[0] for i in config.CODE_FORMATTER]
+LEXER_KEYS = [i[0] for i in config.TEXT_FORMATTER] + [
+ i[0] for i in config.CODE_FORMATTER
+]
# The default lexer which we fallback in case of
# an error or if not supplied in an API call.
diff --git a/dpaste/management/commands/cleanup_snippets.py b/dpaste/management/commands/cleanup_snippets.py
index b593034..50328e0 100644
--- a/dpaste/management/commands/cleanup_snippets.py
+++ b/dpaste/management/commands/cleanup_snippets.py
@@ -8,14 +8,15 @@ class Command(BaseCommand):
help = "Purges snippets that are expired"
def add_arguments(self, parser):
- parser.add_argument('--dry-run', action='store_true', dest='dry_run',
- help='Don\'t do anything.'),
+ parser.add_argument(
+ '--dry-run', action='store_true', dest='dry_run', help='Don\'t do anything.'
+ ),
def handle(self, *args, **options):
deleteable_snippets = Snippet.objects.filter(
expires__isnull=False,
expire_type=Snippet.EXPIRE_TIME,
- expires__lte=timezone.now()
+ expires__lte=timezone.now(),
)
if len(deleteable_snippets) == 0:
self.stdout.write(u"No snippets to delete.")
diff --git a/dpaste/models.py b/dpaste/models.py
index 57c0234..c27a716 100644
--- a/dpaste/models.py
+++ b/dpaste/models.py
@@ -16,11 +16,14 @@ R = SystemRandom()
def generate_secret_id(length):
if length > config.SLUG_LENGTH:
- logger.warning('Slug creation triggered a duplicate, '
- 'consider increasing the SLUG_LENGTH.')
+ logger.warning(
+ 'Slug creation triggered a duplicate, '
+ 'consider increasing the SLUG_LENGTH.'
+ )
- secret_id = ''.join([R.choice(config.SLUG_CHOICES)
- for i in range(length or config.SLUG_LENGTH)])
+ secret_id = ''.join(
+ [R.choice(config.SLUG_CHOICES) for i in range(length or config.SLUG_LENGTH)]
+ )
# Check if this slug already exists, if not, return this new slug
try:
@@ -30,7 +33,7 @@ def generate_secret_id(length):
# Otherwise create a new slug which is +1 character longer
# than the previous one.
- return generate_secret_id(length=length+1)
+ return generate_secret_id(length=length + 1)
@python_2_unicode_compatible
@@ -45,21 +48,24 @@ class Snippet(models.Model):
)
secret_id = models.CharField(
- _('Secret ID'), max_length=255, blank=True, null=True, unique=True)
+ _('Secret ID'), max_length=255, blank=True, null=True, unique=True
+ )
content = models.TextField(_('Content'))
- lexer = models.CharField(
- _('Lexer'), max_length=30, default=highlight.LEXER_DEFAULT)
- published = models.DateTimeField(
- _('Published'), auto_now_add=True)
+ lexer = models.CharField(_('Lexer'), max_length=30, default=highlight.LEXER_DEFAULT)
+ published = models.DateTimeField(_('Published'), auto_now_add=True)
expire_type = models.PositiveSmallIntegerField(
- _('Expire Type'), choices=EXPIRE_CHOICES, default=EXPIRE_CHOICES[0][0])
- expires = models.DateTimeField(
- _('Expires'), blank=True, null=True)
- view_count = models.PositiveIntegerField(
- _('View count'), default=0)
+ _('Expire Type'), choices=EXPIRE_CHOICES, default=EXPIRE_CHOICES[0][0]
+ )
+ expires = models.DateTimeField(_('Expires'), blank=True, null=True)
+ view_count = models.PositiveIntegerField(_('View count'), default=0)
parent = models.ForeignKey(
- 'self', null=True, blank=True, verbose_name=_('Parent Snippet'),
- related_name='children', on_delete=models.CASCADE)
+ 'self',
+ null=True,
+ blank=True,
+ verbose_name=_('Parent Snippet'),
+ related_name='children',
+ on_delete=models.CASCADE,
+ )
class Meta:
ordering = ('-published',)
diff --git a/dpaste/settings/base.py b/dpaste/settings/base.py
index 6f3079d..cca6712 100644
--- a/dpaste/settings/base.py
+++ b/dpaste/settings/base.py
@@ -49,9 +49,7 @@ USE_I18N = True
USE_L10N = False
LANGUAGE_CODE = 'en'
-LANGUAGES = (
- ('en', 'English'),
-)
+LANGUAGES = (('en', 'English'),)
# LOCALE_PATHS = (
# os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'locale')),
@@ -63,9 +61,7 @@ LANGUAGES = (
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
-STATICFILES_DIRS = (
- os.path.join(PROJECT_DIR, 'build'),
-)
+STATICFILES_DIRS = (os.path.join(PROJECT_DIR, 'build'),)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
@@ -107,9 +103,9 @@ TEMPLATES = [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.template.context_processors.i18n',
- ],
+ ]
},
- },
+ }
]
INSTALLED_APPS = [
@@ -146,16 +142,12 @@ CSP_STYLE_SRC = ("'self'", "'unsafe-inline'")
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
- 'filters': {
- 'require_debug_false': {
- '()': 'django.utils.log.RequireDebugFalse'
- }
- },
+ 'filters': {'require_debug_false': {'()': 'django.utils.log.RequireDebugFalse'}},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
- 'class': 'django.utils.log.AdminEmailHandler'
+ 'class': 'django.utils.log.AdminEmailHandler',
}
},
'loggers': {
@@ -163,6 +155,6 @@ LOGGING = {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
- },
- }
+ }
+ },
}
diff --git a/dpaste/settings/tests.py b/dpaste/settings/tests.py
index 5581728..eb8b89b 100644
--- a/dpaste/settings/tests.py
+++ b/dpaste/settings/tests.py
@@ -4,9 +4,4 @@ Settings for the test suite
from .base import *
-DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': ':memory:',
- }
-}
+DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}}
diff --git a/dpaste/tests/test_api.py b/dpaste/tests/test_api.py
index 08cdf61..a8f6579 100644
--- a/dpaste/tests/test_api.py
+++ b/dpaste/tests/test_api.py
@@ -11,7 +11,6 @@ config = apps.get_app_config('dpaste')
class SnippetAPITestCase(TestCase):
-
def setUp(self):
self.api_url = reverse('dpaste_api_create_snippet')
self.client = Client(enforce_csrf_checks=True)
@@ -84,7 +83,6 @@ class SnippetAPITestCase(TestCase):
self.assertTrue(content.startswith('http'))
self.assertTrue(content.endswith('\n'))
-
def test_json_format(self):
"""
The 'new' url format is just the link with a linebreak.
@@ -92,7 +90,7 @@ class SnippetAPITestCase(TestCase):
data = {
'content': u"Hello Wörld.\n\tGood Bye",
'format': 'json',
- 'lexer': 'haskell'
+ 'lexer': 'haskell',
}
response = self.client.post(self.api_url, data)
@@ -102,6 +100,7 @@ class SnippetAPITestCase(TestCase):
self.assertEqual(Snippet.objects.count(), 1)
from json import loads
+
json_data = loads(content)
# Response is valid json, containing, content, lexer and url
@@ -118,7 +117,7 @@ class SnippetAPITestCase(TestCase):
data = {
'content': u"Hello Wörld.\n\tGood Bye",
'format': 'broken-format',
- 'lexer': 'haskell'
+ 'lexer': 'haskell',
}
response = self.client.post(self.api_url, data)
@@ -129,26 +128,25 @@ class SnippetAPITestCase(TestCase):
"""
A broken lexer will fail loudly.
"""
- data = {
- 'content': u"Hello Wörld.\n\tGood Bye",
- 'lexer': 'foobar'
- }
+ data = {'content': u"Hello Wörld.\n\tGood Bye", 'lexer': 'foobar'}
response = self.client.post(self.api_url, data)
self.assertEqual(response.status_code, 400)
self.assertEqual(Snippet.objects.count(), 0)
def test_expire_choices_none_given(self):
# No expire choice given will set a default expiration of one month
- response = self.client.post(self.api_url, {
- 'content': u"Hello Wörld.\n\tGood Bye"})
+ response = self.client.post(
+ self.api_url, {'content': u"Hello Wörld.\n\tGood Bye"}
+ )
self.assertEqual(response.status_code, 200)
self.assertEqual(Snippet.objects.count(), 1)
self.assertTrue(Snippet.objects.all()[0].expires)
def test_expire_choices_invalid_given(self):
# A expire choice that does not exist returns a BadRequest
- response = self.client.post(self.api_url, {
- 'content': u"Hello Wörld.\n\tGood Bye", 'expires': 'foobar'})
+ response = self.client.post(
+ self.api_url, {'content': u"Hello Wörld.\n\tGood Bye", 'expires': 'foobar'}
+ )
self.assertEqual(response.status_code, 400)
self.assertEqual(Snippet.objects.count(), 0)
@@ -156,37 +154,45 @@ class SnippetAPITestCase(TestCase):
Test all the different expiration choices. We dont actually test
the deletion, since thats handled in the `test_snippet` section.
"""
+
def test_valid_expiration_choices_onetime(self):
- response = self.client.post(self.api_url, {
- 'content': u"Hello Wörld.\n\tGood Bye", 'expires': 'onetime'})
+ response = self.client.post(
+ self.api_url, {'content': u"Hello Wörld.\n\tGood Bye", 'expires': 'onetime'}
+ )
self.assertEqual(response.status_code, 200)
self.assertEqual(Snippet.objects.count(), 1)
self.assertEqual(Snippet.objects.all()[0].expire_type, Snippet.EXPIRE_ONETIME)
def test_valid_expiration_choices_never(self):
- response = self.client.post(self.api_url, {
- 'content': u"Hello Wörld.\n\tGood Bye", 'expires': 'never'})
+ response = self.client.post(
+ self.api_url, {'content': u"Hello Wörld.\n\tGood Bye", 'expires': 'never'}
+ )
self.assertEqual(response.status_code, 200)
self.assertEqual(Snippet.objects.count(), 1)
self.assertEqual(Snippet.objects.all()[0].expire_type, Snippet.EXPIRE_KEEP)
def test_valid_expiration_choices_hour(self):
- response = self.client.post(self.api_url, {
- 'content': u"Hello Wörld.\n\tGood Bye", 'expires': 3600})
+ response = self.client.post(
+ self.api_url, {'content': u"Hello Wörld.\n\tGood Bye", 'expires': 3600}
+ )
self.assertEqual(response.status_code, 200)
self.assertEqual(Snippet.objects.count(), 1)
self.assertTrue(Snippet.objects.all()[0].expires)
def test_valid_expiration_choices_week(self):
- response = self.client.post(self.api_url, {
- 'content': u"Hello Wörld.\n\tGood Bye", 'expires': 3600 * 24 * 7})
+ response = self.client.post(
+ self.api_url,
+ {'content': u"Hello Wörld.\n\tGood Bye", 'expires': 3600 * 24 * 7},
+ )
self.assertEqual(response.status_code, 200)
self.assertEqual(Snippet.objects.count(), 1)
self.assertTrue(Snippet.objects.all()[0].expires)
def test_valid_expiration_choices_month(self):
- response = self.client.post(self.api_url, {
- 'content': u"Hello Wörld.\n\tGood Bye", 'expires': 3600 * 24 * 30})
+ response = self.client.post(
+ self.api_url,
+ {'content': u"Hello Wörld.\n\tGood Bye", 'expires': 3600 * 24 * 30},
+ )
self.assertEqual(response.status_code, 200)
self.assertEqual(Snippet.objects.count(), 1)
self.assertTrue(Snippet.objects.all()[0].expires)
@@ -195,22 +201,24 @@ class SnippetAPITestCase(TestCase):
"""
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': ''
- })
+ 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'
- })
+ 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')
@@ -219,11 +227,14 @@ class SnippetAPITestCase(TestCase):
"""
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'
- })
+ 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, config.PLAIN_CODE_SYMBOL)
@@ -232,11 +243,14 @@ class SnippetAPITestCase(TestCase):
"""
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'
- })
+ 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')
@@ -248,5 +262,3 @@ class SnippetAPITestCase(TestCase):
content = ' one\n two\n three\n four'
self.client.post(self.api_url, {'content': content})
self.assertEqual(Snippet.objects.all()[0].content, content)
-
-
diff --git a/dpaste/tests/test_highlight.py b/dpaste/tests/test_highlight.py
index 50234ff..f093536 100644
--- a/dpaste/tests/test_highlight.py
+++ b/dpaste/tests/test_highlight.py
@@ -4,12 +4,14 @@ from textwrap import dedent
from django.test import TestCase
-from dpaste.highlight import PlainCodeHighlighter, PygmentsHighlighter, \
- RestructuredTextHighlighter
+from dpaste.highlight import (
+ PlainCodeHighlighter,
+ PygmentsHighlighter,
+ RestructuredTextHighlighter,
+)
class HighlightAPITestCase(TestCase):
-
def test_plain_code(self):
"""
PLAIN_CODE is not run through Pygments, test it separately.
@@ -32,15 +34,13 @@ class HighlightAPITestCase(TestCase):
"""
Whitespace on the first line is retained, also on subsequent lines.
"""
- input = (' vär=1\n'
- ' vär=2\n'
- ' vär=3\n'
- ' vär=4')
+ input = ' vär=1\n' ' vär=2\n' ' vär=3\n' ' vär=4'
expected = (
' vär=1\n'
' vär=2\n'
' vär=3\n'
- ' vär=4')
+ ' vär=4'
+ )
value = PlainCodeHighlighter().highlight(input)
self.assertEqual(value, expected)
@@ -67,15 +67,13 @@ class HighlightAPITestCase(TestCase):
"""
Whitespace on the first line is retained, also on subsequent lines.
"""
- input = (' var\n'
- ' var\n'
- ' var\n'
- ' var')
+ input = ' var\n' ' var\n' ' var\n' ' var'
expected = (
' var\n'
' var\n'
' var\n'
- ' var\n')
+ ' var\n'
+ )
value = PygmentsHighlighter().highlight(input, 'python')
self.assertEqual(value, expected)
@@ -84,12 +82,14 @@ class HighlightAPITestCase(TestCase):
rst Syntax thats not valid must not raise an exception (SystemMessage)
"""
# (SEVERE/4) Missing matching underline for section title overline.
- input = dedent("""
+ input = dedent(
+ """
=========================
Generate 15 random numbers
70 180 3 179 192 117 75 72 90 190 49 159 63 14 55
=========================
- """)
+ """
+ )
try:
RestructuredTextHighlighter().highlight(input)
except Exception as e:
diff --git a/dpaste/tests/test_snippet.py b/dpaste/tests/test_snippet.py
index f16bde5..2e82b94 100644
--- a/dpaste/tests/test_snippet.py
+++ b/dpaste/tests/test_snippet.py
@@ -15,7 +15,6 @@ config = apps.get_app_config('dpaste')
class SnippetTestCase(TestCase):
-
def setUp(self):
self.client = Client()
self.new_url = reverse('snippet_new')
@@ -132,7 +131,6 @@ class SnippetTestCase(TestCase):
self.assertEqual(response.status_code, 404)
self.assertEqual(Snippet.objects.count(), 0)
-
def test_snippet_notfound(self):
url = reverse('snippet_details', kwargs={'snippet_id': 'abcd'})
response = self.client.get(url, follow=True)
@@ -203,8 +201,12 @@ class SnippetTestCase(TestCase):
def test_raw(self):
data = self.valid_form_data()
self.client.post(self.new_url, data, follow=True)
- response = self.client.get(reverse('snippet_details_raw', kwargs={
- 'snippet_id': Snippet.objects.all()[0].secret_id}))
+ response = self.client.get(
+ reverse(
+ 'snippet_details_raw',
+ kwargs={'snippet_id': Snippet.objects.all()[0].secret_id},
+ )
+ )
self.assertEqual(response.status_code, 200)
self.assertContains(response, data['content'])
@@ -217,22 +219,23 @@ class SnippetTestCase(TestCase):
def test_xss_text_lexer(self):
# Simple 'text' lexer
- data = self.valid_form_data(content=self.XSS_ORIGINAL,
- lexer=config.PLAIN_TEXT_SYMBOL)
+ data = self.valid_form_data(
+ content=self.XSS_ORIGINAL, lexer=config.PLAIN_TEXT_SYMBOL
+ )
response = self.client.post(self.new_url, data, follow=True)
self.assertContains(response, self.XSS_ESCAPED)
def test_xss_code_lexer(self):
# Simple 'code' lexer
- data = self.valid_form_data(content=self.XSS_ORIGINAL,
- lexer=config.PLAIN_CODE_SYMBOL)
+ data = self.valid_form_data(
+ content=self.XSS_ORIGINAL, lexer=config.PLAIN_CODE_SYMBOL
+ )
response = self.client.post(self.new_url, data, follow=True)
self.assertContains(response, self.XSS_ESCAPED)
def test_xss_pygments_lexer(self):
# Pygments based lexer
- data = self.valid_form_data(content=self.XSS_ORIGINAL,
- lexer='python')
+ data = self.valid_form_data(content=self.XSS_ORIGINAL, lexer='python')
response = self.client.post(self.new_url, data, follow=True)
self.assertContains(response, self.XSS_ESCAPED)
@@ -253,8 +256,9 @@ class SnippetTestCase(TestCase):
def test_snippet_history_delete_all(self):
# Empty list, delete all raises no error
- response = self.client.post(reverse('snippet_history'),
- {'delete': 1}, follow=True)
+ response = self.client.post(
+ reverse('snippet_history'), {'delete': 1}, follow=True
+ )
self.assertEqual(response.status_code, 200)
self.assertEqual(Snippet.objects.count(), 0)
@@ -266,8 +270,9 @@ class SnippetTestCase(TestCase):
self.assertEqual(Snippet.objects.count(), 2)
# Delete all of them
- response = self.client.post(reverse('snippet_history'),
- {'delete': 1}, follow=True)
+ response = self.client.post(
+ reverse('snippet_history'), {'delete': 1}, follow=True
+ )
self.assertEqual(response.status_code, 200)
self.assertEqual(Snippet.objects.count(), 0)
@@ -315,7 +320,6 @@ class SnippetTestCase(TestCase):
PygmentsHighlighter().highlight('code', 'python')
PygmentsHighlighter().highlight('code', 'doesnotexist')
-
def test_random_slug_generation(self):
"""
Set the max length of a slug to 1, so we wont have more than 60
@@ -325,8 +329,9 @@ class SnippetTestCase(TestCase):
"""
for i in range(0, 100):
Snippet.objects.create(content='foobar')
- slug_list = Snippet.objects.values_list(
- 'secret_id', flat=True).order_by('published')
+ slug_list = Snippet.objects.values_list('secret_id', flat=True).order_by(
+ 'published'
+ )
self.assertEqual(len(set(slug_list)), 100)
def test_leading_white_is_retained_in_db(self):
diff --git a/dpaste/urls/dpaste.py b/dpaste/urls/dpaste.py
index b39564f..fb00e5d 100644
--- a/dpaste/urls/dpaste.py
+++ b/dpaste/urls/dpaste.py
@@ -7,18 +7,21 @@ from .. import views
L = getattr(settings, 'DPASTE_SLUG_LENGTH', 4)
urlpatterns = [
- url(r'^$',
- views.SnippetView.as_view(), name='snippet_new'),
-
- url(r'^about/$',
- TemplateView.as_view(template_name='dpaste/about.html'), name='dpaste_about'),
-
- url(r'^history/$',
- views.SnippetHistory.as_view(), name='snippet_history'),
-
- url(r'^(?P[a-zA-Z0-9]{%d,})/?$' % L,
- views.SnippetDetailView.as_view(), name='snippet_details'),
-
- url(r'^(?P[a-zA-Z0-9]{%d,})/raw/?$' % L,
- views.SnippetRawView.as_view(), name='snippet_details_raw'),
+ url(r'^$', views.SnippetView.as_view(), name='snippet_new'),
+ url(
+ r'^about/$',
+ TemplateView.as_view(template_name='dpaste/about.html'),
+ name='dpaste_about',
+ ),
+ url(r'^history/$', views.SnippetHistory.as_view(), name='snippet_history'),
+ url(
+ r'^(?P[a-zA-Z0-9]{%d,})/?$' % L,
+ views.SnippetDetailView.as_view(),
+ name='snippet_details',
+ ),
+ url(
+ r'^(?P[a-zA-Z0-9]{%d,})/raw/?$' % L,
+ views.SnippetRawView.as_view(),
+ name='snippet_details_raw',
+ ),
]
diff --git a/dpaste/urls/dpaste_api.py b/dpaste/urls/dpaste_api.py
index 6bd6990..650428f 100644
--- a/dpaste/urls/dpaste_api.py
+++ b/dpaste/urls/dpaste_api.py
@@ -4,5 +4,5 @@ from django.views.decorators.csrf import csrf_exempt
from ..views import APIView
urlpatterns = [
- url(r'^api/$', csrf_exempt(APIView.as_view()), name='dpaste_api_create_snippet'),
+ url(r'^api/$', csrf_exempt(APIView.as_view()), name='dpaste_api_create_snippet')
]
diff --git a/dpaste/views.py b/dpaste/views.py
index d348357..b036f5a 100644
--- a/dpaste/views.py
+++ b/dpaste/views.py
@@ -3,13 +3,19 @@ import difflib
import json
from django.apps import apps
-from django.http import Http404, HttpResponse, HttpResponseBadRequest, \
- HttpResponseRedirect
+from django.http import (
+ Http404,
+ HttpResponse,
+ HttpResponseBadRequest,
+ HttpResponseRedirect,
+)
from django.shortcuts import get_object_or_404
from django.urls import reverse
from django.utils.translation import ugettext
-from django.views.defaults import page_not_found as django_page_not_found, \
- server_error as django_server_error
+from django.views.defaults import (
+ page_not_found as django_page_not_found,
+ server_error as django_server_error,
+)
from django.views.generic import FormView
from django.views.generic.base import TemplateView, View
from django.views.generic.detail import DetailView
@@ -28,18 +34,18 @@ config = apps.get_app_config('dpaste')
# Snippet Handling
# -----------------------------------------------------------------------------
+
class SnippetView(FormView):
"""
Create a new snippet.
"""
+
form_class = SnippetForm
template_name = 'dpaste/new.html'
def get_form_kwargs(self):
kwargs = super(SnippetView, self).get_form_kwargs()
- kwargs.update({
- 'request': self.request,
- })
+ kwargs.update({'request': self.request})
return kwargs
def form_valid(self, form):
@@ -52,6 +58,7 @@ class SnippetDetailView(SnippetView, DetailView):
Details list view of a snippet. Handles the actual view, reply and
tree/diff view.
"""
+
queryset = Snippet.objects.all()
template_name = 'dpaste/details.html'
slug_url_kwarg = 'snippet_id'
@@ -78,8 +85,10 @@ class SnippetDetailView(SnippetView, DetailView):
snippet = self.get_object()
# One-Time snippet get deleted if the view count matches our limit
- if (snippet.expire_type == Snippet.EXPIRE_ONETIME and
- snippet.view_count >= config.ONETIME_LIMIT):
+ if (
+ snippet.expire_type == Snippet.EXPIRE_ONETIME
+ and snippet.view_count >= config.ONETIME_LIMIT
+ ):
snippet.delete()
raise Http404()
@@ -91,10 +100,7 @@ class SnippetDetailView(SnippetView, DetailView):
def get_initial(self):
snippet = self.get_object()
- return {
- 'content': snippet.content,
- 'lexer': snippet.lexer,
- }
+ return {'content': snippet.content, 'lexer': snippet.lexer}
def form_valid(self, form):
snippet = form.save(parent=self.get_object())
@@ -114,7 +120,7 @@ class SnippetDetailView(SnippetView, DetailView):
snippet.content.splitlines(),
ugettext('Previous Snippet'),
ugettext('Current Snippet'),
- n=1
+ n=1,
)
diff_code = '\n'.join(d).strip()
highlighted = PygmentsHighlighter().render(diff_code, 'diff')
@@ -126,10 +132,12 @@ class SnippetDetailView(SnippetView, DetailView):
self.object = self.get_object()
ctx = super(SnippetDetailView, self).get_context_data(**kwargs)
- ctx.update({
- 'wordwrap': self.object.lexer in highlight.LEXER_WORDWRAP,
- 'diff': self.get_snippet_diff(),
- })
+ ctx.update(
+ {
+ 'wordwrap': self.object.lexer in highlight.LEXER_WORDWRAP,
+ 'diff': self.get_snippet_diff(),
+ }
+ )
return ctx
@@ -137,6 +145,7 @@ class SnippetRawView(SnippetDetailView):
"""
Display the raw content of a snippet
"""
+
def render_to_response(self, context, **response_kwargs):
snippet = self.get_object()
response = HttpResponse(snippet.content)
@@ -150,6 +159,7 @@ class SnippetHistory(TemplateView):
Display the last `n` snippets created by this user (and saved in his
session).
"""
+
template_name = 'dpaste/history.html'
def get_user_snippets(self):
@@ -169,9 +179,7 @@ class SnippetHistory(TemplateView):
def get_context_data(self, **kwargs):
ctx = super(SnippetHistory, self).get_context_data(**kwargs)
- ctx.update({
- 'snippet_list': self.get_user_snippets(),
- })
+ ctx.update({'snippet_list': self.get_user_snippets()})
return ctx
@@ -184,6 +192,7 @@ class APIView(View):
"""
API View
"""
+
def _format_default(self, s):
"""
The default response is the snippet URL wrapped in quotes.
@@ -204,11 +213,13 @@ class APIView(View):
The `json` format export.
"""
base_url = config.get_base_url(request=self.request)
- return json.dumps({
- 'url': '{url}{path}'.format(url=base_url, path=s.get_absolute_url()),
- 'content': s.content,
- 'lexer': s.lexer,
- })
+ return json.dumps(
+ {
+ 'url': '{url}{path}'.format(url=base_url, path=s.get_absolute_url()),
+ 'content': s.content,
+ 'lexer': s.lexer,
+ }
+ )
def post(self, request, *args, **kwargs):
content = request.POST.get('content', '')
@@ -222,13 +233,18 @@ class APIView(View):
# 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(highlight.LEXER_KEYS))
+ return HttpResponseBadRequest(
+ 'No lexer or filename given. Unable to '
+ 'determine a highlight. Valid lexers are: %s'
+ % ', '.join(highlight.LEXER_KEYS)
+ )
# A lexer is given, check if its valid at all
if lexer and lexer not in highlight.LEXER_KEYS:
- return HttpResponseBadRequest('Invalid lexer "%s" given. Valid lexers are: %s' % (
- lexer, ', '.join(highlight.LEXER_KEYS)))
+ return HttpResponseBadRequest(
+ 'Invalid lexer "%s" given. Valid lexers are: %s'
+ % (lexer, ', '.join(highlight.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
@@ -245,17 +261,16 @@ class APIView(View):
if expires not in expire_options:
return HttpResponseBadRequest(
'Invalid expire choice "{}" given. Valid values are: {}'.format(
- expires, ', '.join(expire_options)))
+ expires, ', '.join(expire_options)
+ )
+ )
expires, expire_type = get_expire_values(expires)
else:
expires = datetime.datetime.now() + datetime.timedelta(seconds=60 * 60 * 24)
expire_type = Snippet.EXPIRE_TIME
snippet = Snippet.objects.create(
- content=content,
- lexer=lexer,
- expires=expires,
- expire_type=expire_type,
+ content=content, lexer=lexer, expires=expires, expire_type=expire_type
)
# Custom formatter for the API response
@@ -272,6 +287,7 @@ class APIView(View):
# handle them here.
# -----------------------------------------------------------------------------
+
def page_not_found(request, exception=None, template_name='dpaste/404.html'):
return django_page_not_found(request, exception, template_name=template_name)
diff --git a/dpaste/wsgi.py b/dpaste/wsgi.py
index 4470c5f..6602e2e 100644
--- a/dpaste/wsgi.py
+++ b/dpaste/wsgi.py
@@ -8,7 +8,9 @@ https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/
"""
import os
+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dpaste.settings.local")
from django.core.wsgi import get_wsgi_application
+
application = get_wsgi_application()