mirror of
https://github.com/DarrenOfficial/dpaste.git
synced 2024-11-15 08:02:54 +11:00
Refactored settings to use AppConfig
This commit is contained in:
parent
053808f2bf
commit
3bd3a83fdd
8 changed files with 267 additions and 158 deletions
207
dpaste/apps.py
207
dpaste/apps.py
|
@ -1,6 +1,209 @@
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig, apps
|
||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
class dpasteAppConfig(AppConfig):
|
class dpasteAppConfig(AppConfig):
|
||||||
name = 'dpaste'
|
name = 'dpaste'
|
||||||
verbose_name = 'dpaste'
|
verbose_name = 'dpaste'
|
||||||
|
|
||||||
|
# Integer. Length of the random slug for each new snippet. In the rare
|
||||||
|
# case an existing slug is generated again, the length will increase by
|
||||||
|
# one more character.
|
||||||
|
SLUG_LENGTH = 4
|
||||||
|
|
||||||
|
# String. A string of characters which are used to create the random slug.
|
||||||
|
SLUG_CHOICES = 'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ1234567890'
|
||||||
|
|
||||||
|
# String. The lexer key that is pre-selected in the dropdown. Note that
|
||||||
|
# this is only used if the user has not saved a snippet before, otherwise
|
||||||
|
LEXER_DEFAULT = 'python'
|
||||||
|
|
||||||
|
# Integer. Maximum number of bytes per snippet.
|
||||||
|
MAX_CONTENT_LENGTH = 250 * 1024 * 1024
|
||||||
|
|
||||||
|
# A tuple of seconds and a descriptive string used in the lexer
|
||||||
|
# expiration dropdown. Example::
|
||||||
|
#
|
||||||
|
# from django.utils.translation import ugettext_lazy as _
|
||||||
|
# DPASTE_EXPIRE_CHOICES = (
|
||||||
|
# (3600, _('In one hour')),
|
||||||
|
# (3600 * 24 * 7, _('In one week')),
|
||||||
|
# (3600 * 24 * 30, _('In one month')),
|
||||||
|
# (3600 * 24 * 30 * 12 * 100, _('100 Years')),
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
|
||||||
|
# **Infinite snippets** are supported. You can keep snippets forever when
|
||||||
|
# you set the choice key to ``never``. The management command will ignore
|
||||||
|
# these snippets::
|
||||||
|
#
|
||||||
|
# from django.utils.translation import ugettext_lazy as _
|
||||||
|
# DPASTE_EXPIRE_CHOICES = (
|
||||||
|
# (3600, _('In one hour')),
|
||||||
|
# ('never', _('Never')),
|
||||||
|
# )
|
||||||
|
EXPIRE_CHOICES = (
|
||||||
|
('onetime', _('One-Time snippet')),
|
||||||
|
(3600, _('In one hour')),
|
||||||
|
(3600 * 24 * 7, _('In one week')),
|
||||||
|
(3600 * 24 * 30, _('In one month')),
|
||||||
|
('never', _('Never')),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Default value for ``EXPIRE_CHOICES``
|
||||||
|
EXPIRE_DEFAULT = 3600 * 24 * 7
|
||||||
|
|
||||||
|
# **One-Time snippets** are supported. One-Time snippets are automatically
|
||||||
|
# deleted once a defined view count has reached (Default: ``2``). To
|
||||||
|
# enable one-time snippets you have to add a choice ``onetime`` to the
|
||||||
|
# expire choices::
|
||||||
|
#
|
||||||
|
# from django.utils.translation import ugettext_lazy as _
|
||||||
|
# DPASTE_EXPIRE_CHOICES = (
|
||||||
|
# ('onetime', _('One-Time snippet')),
|
||||||
|
# (3600, _('In one hour')),
|
||||||
|
# (3600 * 24 * 7, _('In one week')),
|
||||||
|
# (3600 * 24 * 30, _('In one month')),
|
||||||
|
# )
|
||||||
|
#
|
||||||
|
# You can also set the maximum view count after what the snippet gets
|
||||||
|
# deleted. The default is ``2``. One view is from the author, one view
|
||||||
|
# is from another user.
|
||||||
|
ONETIME_LIMIT = 2
|
||||||
|
|
||||||
|
# Lexers which have wordwrap enabled by default
|
||||||
|
LEXER_WORDWRAP = ('rst',)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def BASE_URL(self, request=None):
|
||||||
|
"""
|
||||||
|
String. The full qualified hostname and path to the dpaste instance.
|
||||||
|
This is used to generate a link in the API response. If the "Sites"
|
||||||
|
framework is installed, it uses the current Site domain. Otherwise
|
||||||
|
it falls back to 'https://dpaste.de'
|
||||||
|
"""
|
||||||
|
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)
|
||||||
|
return 'https://dpaste.de'
|
||||||
|
|
||||||
|
|
||||||
|
# Key names of the default text and code lexer.
|
||||||
|
PLAIN_TEXT_SYMBOL = '_text'
|
||||||
|
PLAIN_CODE_SYMBOL = '_code'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def TEXT_FORMATTER(self):
|
||||||
|
"""
|
||||||
|
Choices list with all "Text" lexer. Prepend keys with an underscore
|
||||||
|
so they don't accidentally clash with a Pygments Lexer name.
|
||||||
|
|
||||||
|
Each list contains a lexer tuple of:
|
||||||
|
|
||||||
|
(Lexer key,
|
||||||
|
Lexer Display Name,
|
||||||
|
Lexer Highlight Class)
|
||||||
|
|
||||||
|
If the Highlight Class is not given, PygmentsHighlighter is used.
|
||||||
|
"""
|
||||||
|
from dpaste.highlight import (
|
||||||
|
PlainTextHighlighter,
|
||||||
|
MarkdownHighlighter,
|
||||||
|
RestructuredTextHighlighter
|
||||||
|
)
|
||||||
|
return [
|
||||||
|
(self.PLAIN_TEXT_SYMBOL, 'Plain Text', PlainTextHighlighter),
|
||||||
|
('_markdown', 'Markdown', MarkdownHighlighter),
|
||||||
|
('_rst', 'reStructuredText', RestructuredTextHighlighter),
|
||||||
|
]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def CODE_FORMATTER(self):
|
||||||
|
"""
|
||||||
|
Choices list with all "Code" Lexer. Each list
|
||||||
|
contains a lexer tuple of:
|
||||||
|
|
||||||
|
(Lexer key,
|
||||||
|
Lexer Display Name,
|
||||||
|
Lexer Highlight Class)
|
||||||
|
|
||||||
|
If the Highlight Class is not given, PygmentsHighlighter is used.
|
||||||
|
"""
|
||||||
|
from dpaste.highlight import (
|
||||||
|
PlainCodeHighlighter,
|
||||||
|
SolidityHighlighter
|
||||||
|
)
|
||||||
|
return [
|
||||||
|
(self.PLAIN_CODE_SYMBOL, 'Plain Code', PlainCodeHighlighter),
|
||||||
|
('abap', 'ABAP'),
|
||||||
|
('apacheconf', 'ApacheConf'),
|
||||||
|
('applescript', 'AppleScript'),
|
||||||
|
('as', 'ActionScript'),
|
||||||
|
('bash', 'Bash'),
|
||||||
|
('bbcode', 'BBCode'),
|
||||||
|
('c', 'C'),
|
||||||
|
('cpp', 'C++'),
|
||||||
|
('clojure', 'Clojure'),
|
||||||
|
('cobol', 'COBOL'),
|
||||||
|
('css', 'CSS'),
|
||||||
|
('cuda', 'CUDA'),
|
||||||
|
('dart', 'Dart'),
|
||||||
|
('delphi', 'Delphi'),
|
||||||
|
('diff', 'Diff'),
|
||||||
|
('django', 'Django'),
|
||||||
|
('erlang', 'Erlang'),
|
||||||
|
('fortran', 'Fortran'),
|
||||||
|
('go', 'Go'),
|
||||||
|
('groovy', 'Groovy'),
|
||||||
|
('haml', 'Haml'),
|
||||||
|
('haskell', 'Haskell'),
|
||||||
|
('html', 'HTML'),
|
||||||
|
('http', 'HTTP'),
|
||||||
|
('ini', 'INI'),
|
||||||
|
('irc', 'IRC'),
|
||||||
|
('java', 'Java'),
|
||||||
|
('js', 'JavaScript'),
|
||||||
|
('json', 'JSON'),
|
||||||
|
('lua', 'Lua'),
|
||||||
|
('make', 'Makefile'),
|
||||||
|
('mako', 'Mako'),
|
||||||
|
('mason', 'Mason'),
|
||||||
|
('matlab', 'Matlab'),
|
||||||
|
('modula2', 'Modula'),
|
||||||
|
('monkey', 'Monkey'),
|
||||||
|
('mysql', 'MySQL'),
|
||||||
|
('numpy', 'NumPy'),
|
||||||
|
('objc', 'Obj-C'),
|
||||||
|
('ocaml', 'OCaml'),
|
||||||
|
('perl', 'Perl'),
|
||||||
|
('php', 'PHP'),
|
||||||
|
('postscript', 'PostScript'),
|
||||||
|
('powershell', 'PowerShell'),
|
||||||
|
('prolog', 'Prolog'),
|
||||||
|
('properties', 'Properties'),
|
||||||
|
('puppet', 'Puppet'),
|
||||||
|
('python', 'Python'), # Default lexer
|
||||||
|
('r', 'R'),
|
||||||
|
('rb', 'Ruby'),
|
||||||
|
('rst', 'reStructuredText'),
|
||||||
|
('rust', 'Rust'),
|
||||||
|
('sass', 'Sass'),
|
||||||
|
('scala', 'Scala'),
|
||||||
|
('scheme', 'Scheme'),
|
||||||
|
('scilab', 'Scilab'),
|
||||||
|
('scss', 'SCSS'),
|
||||||
|
('smalltalk', 'Smalltalk'),
|
||||||
|
('smarty', 'Smarty'),
|
||||||
|
('solidity', 'Solidity', SolidityHighlighter),
|
||||||
|
('sql', 'SQL'),
|
||||||
|
('tcl', 'Tcl'),
|
||||||
|
('tcsh', 'Tcsh'),
|
||||||
|
('tex', 'TeX'),
|
||||||
|
('vb.net', 'VB.net'),
|
||||||
|
('vim', 'VimL'),
|
||||||
|
('xml', 'XML'),
|
||||||
|
('xquery', 'XQuery'),
|
||||||
|
('xslt', 'XSLT'),
|
||||||
|
('yaml', 'YAML'),
|
||||||
|
]
|
||||||
|
|
|
@ -1,22 +1,13 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.conf import settings
|
from django.apps import apps
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from .highlight import LEXER_DEFAULT, LEXER_KEYS, LEXER_CHOICES
|
from .highlight import LEXER_CHOICES, LEXER_DEFAULT, LEXER_KEYS
|
||||||
from .models import Snippet
|
from .models import Snippet
|
||||||
|
|
||||||
EXPIRE_CHOICES = getattr(settings, 'DPASTE_EXPIRE_CHOICES', (
|
config = apps.get_app_config('dpaste')
|
||||||
('onetime', _('One-Time snippet')),
|
|
||||||
(3600, _('In one hour')),
|
|
||||||
(3600 * 24 * 7, _('In one week')),
|
|
||||||
(3600 * 24 * 30, _('In one month')),
|
|
||||||
('never', _('Never')),
|
|
||||||
))
|
|
||||||
|
|
||||||
EXPIRE_DEFAULT = getattr(settings, 'DPASTE_EXPIRE_DEFAULT', 3600)
|
|
||||||
MAX_CONTENT_LENGTH = getattr(settings, 'DPASTE_MAX_CONTENT_LENGTH', 250*1024*1024)
|
|
||||||
|
|
||||||
|
|
||||||
def get_expire_values(expires):
|
def get_expire_values(expires):
|
||||||
|
@ -28,7 +19,7 @@ def get_expire_values(expires):
|
||||||
expires = None
|
expires = None
|
||||||
else:
|
else:
|
||||||
expire_type = Snippet.EXPIRE_TIME
|
expire_type = Snippet.EXPIRE_TIME
|
||||||
expires = expires and expires or EXPIRE_DEFAULT
|
expires = expires and expires or config.EXPIRE_DEFAULT
|
||||||
expires = datetime.datetime.now() + datetime.timedelta(seconds=int(expires))
|
expires = datetime.datetime.now() + datetime.timedelta(seconds=int(expires))
|
||||||
return expires, expire_type
|
return expires, expire_type
|
||||||
|
|
||||||
|
@ -37,7 +28,7 @@ class SnippetForm(forms.ModelForm):
|
||||||
content = forms.CharField(
|
content = forms.CharField(
|
||||||
label=_('Content'),
|
label=_('Content'),
|
||||||
widget=forms.Textarea(attrs={'placeholder': _('Awesome code goes here...')}),
|
widget=forms.Textarea(attrs={'placeholder': _('Awesome code goes here...')}),
|
||||||
max_length=MAX_CONTENT_LENGTH,
|
max_length=config.MAX_CONTENT_LENGTH,
|
||||||
strip=False
|
strip=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,8 +40,8 @@ class SnippetForm(forms.ModelForm):
|
||||||
|
|
||||||
expires = forms.ChoiceField(
|
expires = forms.ChoiceField(
|
||||||
label=_('Expires'),
|
label=_('Expires'),
|
||||||
choices=EXPIRE_CHOICES,
|
choices=config.EXPIRE_CHOICES,
|
||||||
initial=EXPIRE_DEFAULT
|
initial=config.EXPIRE_DEFAULT
|
||||||
)
|
)
|
||||||
|
|
||||||
# Honeypot field
|
# Honeypot field
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
from django.conf import settings
|
from django.apps import apps
|
||||||
from django.template.defaultfilters import escape, linebreaksbr
|
from django.template.defaultfilters import escape, linebreaksbr
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
|
@ -12,7 +12,7 @@ from pygments.lexers.python import PythonLexer
|
||||||
from pygments.util import ClassNotFound
|
from pygments.util import ClassNotFound
|
||||||
|
|
||||||
logger = getLogger(__file__)
|
logger = getLogger(__file__)
|
||||||
|
config = apps.get_app_config('dpaste')
|
||||||
|
|
||||||
class NakedHtmlFormatter(HtmlFormatter):
|
class NakedHtmlFormatter(HtmlFormatter):
|
||||||
"""Pygments HTML formatter with no further HTML tags."""
|
"""Pygments HTML formatter with no further HTML tags."""
|
||||||
|
@ -37,7 +37,7 @@ class Highlighter(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_lexer_display_name(lexer_name, fallback=_('(Deprecated Lexer)')):
|
def get_lexer_display_name(lexer_name, fallback=_('(Deprecated Lexer)')):
|
||||||
for l in TEXT_FORMATTER + CODE_FORMATTER:
|
for l in config.TEXT_FORMATTER + config.CODE_FORMATTER:
|
||||||
if l[0] == lexer_name:
|
if l[0] == lexer_name:
|
||||||
return l[1]
|
return l[1]
|
||||||
return fallback
|
return fallback
|
||||||
|
@ -111,7 +111,7 @@ class PlainCodeHighlighter(Highlighter):
|
||||||
|
|
||||||
class PygmentsHighlighter(Highlighter):
|
class PygmentsHighlighter(Highlighter):
|
||||||
"""
|
"""
|
||||||
Highlight code string with Pygments. The lexer is automaticially
|
Highlight code string with Pygments. The lexer is automatically
|
||||||
determined by the lexer name.
|
determined by the lexer name.
|
||||||
"""
|
"""
|
||||||
formatter = NakedHtmlFormatter()
|
formatter = NakedHtmlFormatter()
|
||||||
|
@ -149,7 +149,7 @@ def get_highlighter_class(lexer_name):
|
||||||
If no suitable highlighter is found, return the generic
|
If no suitable highlighter is found, return the generic
|
||||||
PlainCode Highlighter.
|
PlainCode Highlighter.
|
||||||
"""
|
"""
|
||||||
for c in TEXT_FORMATTER + CODE_FORMATTER:
|
for c in config.TEXT_FORMATTER + config.CODE_FORMATTER:
|
||||||
if c[0] == lexer_name:
|
if c[0] == lexer_name:
|
||||||
if len(c) == 3:
|
if len(c) == 3:
|
||||||
return c[2]
|
return c[2]
|
||||||
|
@ -161,113 +161,19 @@ def get_highlighter_class(lexer_name):
|
||||||
# Lexer List
|
# Lexer List
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
# Lexer list. Each list contains a lexer tuple of:
|
# Generate a list of Form choices of all lexer.
|
||||||
#
|
|
||||||
# (Lexer key,
|
|
||||||
# Lexer Display Name,
|
|
||||||
# Lexer Highlight Class)
|
|
||||||
#
|
|
||||||
# If the Highlight Class is not given, PygmentsHighlighter is used.
|
|
||||||
|
|
||||||
# Default Highlight Types
|
|
||||||
PLAIN_TEXT = '_text' # lexer name whats rendered as text (paragraphs)
|
|
||||||
PLAIN_CODE = '_code' # lexer name of code with no hihglighting
|
|
||||||
|
|
||||||
TEXT_FORMATTER = [
|
|
||||||
(PLAIN_TEXT, 'Plain Text', PlainTextHighlighter),
|
|
||||||
('_markdown', 'Markdown', MarkdownHighlighter),
|
|
||||||
('_rst', 'reStructuredText', RestructuredTextHighlighter),
|
|
||||||
#('_textile', 'Textile', MarkdownHighlighter),
|
|
||||||
]
|
|
||||||
|
|
||||||
CODE_FORMATTER = [
|
|
||||||
(PLAIN_CODE, 'Plain Code', PlainCodeHighlighter),
|
|
||||||
('abap', 'ABAP'),
|
|
||||||
('apacheconf', 'ApacheConf'),
|
|
||||||
('applescript', 'AppleScript'),
|
|
||||||
('as', 'ActionScript'),
|
|
||||||
('bash', 'Bash'),
|
|
||||||
('bbcode', 'BBCode'),
|
|
||||||
('c', 'C'),
|
|
||||||
('cpp', 'C++'),
|
|
||||||
('clojure', 'Clojure'),
|
|
||||||
('cobol', 'COBOL'),
|
|
||||||
('css', 'CSS'),
|
|
||||||
('cuda', 'CUDA'),
|
|
||||||
('dart', 'Dart'),
|
|
||||||
('delphi', 'Delphi'),
|
|
||||||
('diff', 'Diff'),
|
|
||||||
('django', 'Django'),
|
|
||||||
('erlang', 'Erlang'),
|
|
||||||
('fortran', 'Fortran'),
|
|
||||||
('go', 'Go'),
|
|
||||||
('groovy', 'Groovy'),
|
|
||||||
('haml', 'Haml'),
|
|
||||||
('haskell', 'Haskell'),
|
|
||||||
('html', 'HTML'),
|
|
||||||
('http', 'HTTP'),
|
|
||||||
('ini', 'INI'),
|
|
||||||
('irc', 'IRC'),
|
|
||||||
('java', 'Java'),
|
|
||||||
('js', 'JavaScript'),
|
|
||||||
('json', 'JSON'),
|
|
||||||
('lua', 'Lua'),
|
|
||||||
('make', 'Makefile'),
|
|
||||||
('mako', 'Mako'),
|
|
||||||
('mason', 'Mason'),
|
|
||||||
('matlab', 'Matlab'),
|
|
||||||
('modula2', 'Modula'),
|
|
||||||
('monkey', 'Monkey'),
|
|
||||||
('mysql', 'MySQL'),
|
|
||||||
('numpy', 'NumPy'),
|
|
||||||
('objc', 'Obj-C'),
|
|
||||||
('ocaml', 'OCaml'),
|
|
||||||
('perl', 'Perl'),
|
|
||||||
('php', 'PHP'),
|
|
||||||
('postscript', 'PostScript'),
|
|
||||||
('powershell', 'PowerShell'),
|
|
||||||
('prolog', 'Prolog'),
|
|
||||||
('properties', 'Properties'),
|
|
||||||
('puppet', 'Puppet'),
|
|
||||||
('python', 'Python'),
|
|
||||||
('r', 'R'),
|
|
||||||
('rb', 'Ruby'),
|
|
||||||
('rst', 'reStructuredText'),
|
|
||||||
('rust', 'Rust'),
|
|
||||||
('sass', 'Sass'),
|
|
||||||
('scala', 'Scala'),
|
|
||||||
('scheme', 'Scheme'),
|
|
||||||
('scilab', 'Scilab'),
|
|
||||||
('scss', 'SCSS'),
|
|
||||||
('smalltalk', 'Smalltalk'),
|
|
||||||
('smarty', 'Smarty'),
|
|
||||||
('solidity', 'Solidity', SolidityHighlighter),
|
|
||||||
('sql', 'SQL'),
|
|
||||||
('tcl', 'Tcl'),
|
|
||||||
('tcsh', 'Tcsh'),
|
|
||||||
('tex', 'TeX'),
|
|
||||||
('vb.net', 'VB.net'),
|
|
||||||
('vim', 'VimL'),
|
|
||||||
('xml', 'XML'),
|
|
||||||
('xquery', 'XQuery'),
|
|
||||||
('xslt', 'XSLT'),
|
|
||||||
('yaml', 'YAML'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# Generat a list of Form choices of all lexer.
|
|
||||||
LEXER_CHOICES = (
|
LEXER_CHOICES = (
|
||||||
(_('Text'), [i[:2] for i in TEXT_FORMATTER]),
|
(_('Text'), [i[:2] for i in config.TEXT_FORMATTER]),
|
||||||
(_('Code'), [i[:2] for i in CODE_FORMATTER])
|
(_('Code'), [i[:2] for i in config.CODE_FORMATTER])
|
||||||
)
|
)
|
||||||
|
|
||||||
# List of all Lexer Keys
|
# List of all Lexer Keys
|
||||||
LEXER_KEYS = [i[0] for i in TEXT_FORMATTER] + [i[0] for i in 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
|
# The default lexer which we fallback in case of
|
||||||
# an error or if not supplied in an API call.
|
# an error or if not supplied in an API call.
|
||||||
LEXER_DEFAULT = getattr(settings, 'DPASTE_LEXER_DEFAULT', 'python')
|
LEXER_DEFAULT = config.LEXER_DEFAULT
|
||||||
|
|
||||||
# Lexers which have wordwrap enabled by default
|
# Lexers which have wordwrap enabled by default
|
||||||
LEXER_WORDWRAP = getattr(settings, 'DPASTE_LEXER_WORDWRAP',
|
LEXER_WORDWRAP = config.LEXER_WORDWRAP
|
||||||
('rst',)
|
|
||||||
)
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
from logging import getLogger
|
||||||
from random import SystemRandom
|
from random import SystemRandom
|
||||||
|
|
||||||
from django.conf import settings
|
from django.apps import apps
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
@ -8,15 +9,19 @@ from six import python_2_unicode_compatible
|
||||||
|
|
||||||
from dpaste import highlight
|
from dpaste import highlight
|
||||||
|
|
||||||
|
config = apps.get_app_config('dpaste')
|
||||||
|
logger = getLogger(__file__)
|
||||||
R = SystemRandom()
|
R = SystemRandom()
|
||||||
ONETIME_LIMIT = getattr(settings, 'DPASTE_ONETIME_LIMIT', 2)
|
|
||||||
|
|
||||||
|
|
||||||
def generate_secret_id(length=None, alphabet=None, tries=0):
|
def generate_secret_id(length=None, tries=0):
|
||||||
length = length or getattr(settings, 'DPASTE_SLUG_LENGTH', 4)
|
if tries >= 10000:
|
||||||
alphabet = alphabet or getattr(settings, 'DPASTE_SLUG_CHOICES',
|
m = 'Tried to often to generate a unique slug. Inceease the slug length.'
|
||||||
'abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ1234567890')
|
logger.critical(m)
|
||||||
secret_id = ''.join([R.choice(alphabet) for i in range(length)])
|
raise Exception(m)
|
||||||
|
|
||||||
|
secret_id = ''.join([R.choice(config.SLUG_CHOICES)
|
||||||
|
for i in range(config.SLUG_LENGTH)])
|
||||||
|
|
||||||
# Check if this slug already exists, if not, return this new slug
|
# Check if this slug already exists, if not, return this new slug
|
||||||
try:
|
try:
|
||||||
|
@ -84,5 +89,6 @@ class Snippet(models.Model):
|
||||||
@property
|
@property
|
||||||
def remaining_views(self):
|
def remaining_views(self):
|
||||||
if self.expire_type == self.EXPIRE_ONETIME:
|
if self.expire_type == self.EXPIRE_ONETIME:
|
||||||
remaining = ONETIME_LIMIT - self.view_count
|
|
||||||
|
remaining = config.ONETIME_LIMIT - self.view_count
|
||||||
return remaining > 0 and remaining or 0
|
return remaining > 0 and remaining or 0
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
from django.urls import reverse
|
from django.apps import apps
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.test.client import Client
|
from django.test.client import Client
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
from ..highlight import PLAIN_CODE
|
|
||||||
from ..models import Snippet
|
from ..models import Snippet
|
||||||
|
|
||||||
|
config = apps.get_app_config('dpaste')
|
||||||
|
|
||||||
|
|
||||||
class SnippetAPITestCase(TestCase):
|
class SnippetAPITestCase(TestCase):
|
||||||
|
|
||||||
|
@ -224,7 +226,7 @@ class SnippetAPITestCase(TestCase):
|
||||||
})
|
})
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertEqual(Snippet.objects.count(), 1)
|
self.assertEqual(Snippet.objects.count(), 1)
|
||||||
self.assertEqual(Snippet.objects.all()[0].lexer, PLAIN_CODE)
|
self.assertEqual(Snippet.objects.all()[0].lexer, config.PLAIN_CODE_SYMBOL)
|
||||||
|
|
||||||
def test_filename_and_lexer_given(self):
|
def test_filename_and_lexer_given(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -4,8 +4,8 @@ from textwrap import dedent
|
||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from dpaste.highlight import PLAIN_CODE, PygmentsHighlighter, \
|
from dpaste.highlight import PlainCodeHighlighter, PygmentsHighlighter, \
|
||||||
PlainCodeHighlighter, RestructuredTextHighlighter
|
RestructuredTextHighlighter
|
||||||
|
|
||||||
|
|
||||||
class HighlightAPITestCase(TestCase):
|
class HighlightAPITestCase(TestCase):
|
||||||
|
|
|
@ -2,16 +2,17 @@
|
||||||
|
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from django.apps import apps
|
||||||
from django.core import management
|
from django.core import management
|
||||||
from django.urls import reverse
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.test.client import Client
|
from django.test.client import Client
|
||||||
from django.test.utils import override_settings
|
from django.urls import reverse
|
||||||
|
|
||||||
from ..forms import EXPIRE_DEFAULT
|
from ..highlight import PygmentsHighlighter
|
||||||
from ..highlight import LEXER_DEFAULT, PLAIN_CODE, PLAIN_TEXT, PygmentsHighlighter
|
|
||||||
from ..models import Snippet
|
from ..models import Snippet
|
||||||
|
|
||||||
|
config = apps.get_app_config('dpaste')
|
||||||
|
|
||||||
|
|
||||||
class SnippetTestCase(TestCase):
|
class SnippetTestCase(TestCase):
|
||||||
|
|
||||||
|
@ -22,8 +23,8 @@ class SnippetTestCase(TestCase):
|
||||||
def valid_form_data(self, **kwargs):
|
def valid_form_data(self, **kwargs):
|
||||||
data = {
|
data = {
|
||||||
'content': u"Hello Wörld.\n\tGood Bye",
|
'content': u"Hello Wörld.\n\tGood Bye",
|
||||||
'lexer': LEXER_DEFAULT,
|
'lexer': config.LEXER_DEFAULT,
|
||||||
'expires': EXPIRE_DEFAULT,
|
'expires': config.EXPIRE_DEFAULT,
|
||||||
}
|
}
|
||||||
if kwargs:
|
if kwargs:
|
||||||
data.update(kwargs)
|
data.update(kwargs)
|
||||||
|
@ -216,13 +217,15 @@ class SnippetTestCase(TestCase):
|
||||||
|
|
||||||
def test_xss_text_lexer(self):
|
def test_xss_text_lexer(self):
|
||||||
# Simple 'text' lexer
|
# Simple 'text' lexer
|
||||||
data = self.valid_form_data(content=self.XSS_ORIGINAL, lexer=PLAIN_TEXT)
|
data = self.valid_form_data(content=self.XSS_ORIGINAL,
|
||||||
|
lexer=config.PLAIN_TEXT_SYMBOL)
|
||||||
response = self.client.post(self.new_url, data, follow=True)
|
response = self.client.post(self.new_url, data, follow=True)
|
||||||
self.assertContains(response, self.XSS_ESCAPED)
|
self.assertContains(response, self.XSS_ESCAPED)
|
||||||
|
|
||||||
def test_xss_code_lexer(self):
|
def test_xss_code_lexer(self):
|
||||||
# Simple 'code' lexer
|
# Simple 'code' lexer
|
||||||
data = self.valid_form_data(content=self.XSS_ORIGINAL, lexer=PLAIN_CODE)
|
data = self.valid_form_data(content=self.XSS_ORIGINAL,
|
||||||
|
lexer=config.PLAIN_CODE_SYMBOL)
|
||||||
response = self.client.post(self.new_url, data, follow=True)
|
response = self.client.post(self.new_url, data, follow=True)
|
||||||
self.assertContains(response, self.XSS_ESCAPED)
|
self.assertContains(response, self.XSS_ESCAPED)
|
||||||
|
|
||||||
|
@ -313,7 +316,6 @@ class SnippetTestCase(TestCase):
|
||||||
PygmentsHighlighter().highlight('code', 'doesnotexist')
|
PygmentsHighlighter().highlight('code', 'doesnotexist')
|
||||||
|
|
||||||
|
|
||||||
@override_settings(DPASTE_SLUG_LENGTH=1)
|
|
||||||
def test_random_slug_generation(self):
|
def test_random_slug_generation(self):
|
||||||
"""
|
"""
|
||||||
Set the max length of a slug to 1, so we wont have more than 60
|
Set the max length of a slug to 1, so we wont have more than 60
|
||||||
|
|
|
@ -2,7 +2,7 @@ import datetime
|
||||||
import difflib
|
import difflib
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from django.conf import settings
|
from django.apps import apps
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.http import (Http404, HttpResponse, HttpResponseBadRequest,
|
from django.http import (Http404, HttpResponse, HttpResponseBadRequest,
|
||||||
HttpResponseRedirect)
|
HttpResponseRedirect)
|
||||||
|
@ -18,9 +18,11 @@ from pygments.lexers import get_lexer_for_filename
|
||||||
from pygments.util import ClassNotFound
|
from pygments.util import ClassNotFound
|
||||||
|
|
||||||
from dpaste import highlight
|
from dpaste import highlight
|
||||||
from dpaste.forms import EXPIRE_CHOICES, SnippetForm, get_expire_values
|
from dpaste.forms import SnippetForm, get_expire_values
|
||||||
from dpaste.highlight import PygmentsHighlighter
|
from dpaste.highlight import PygmentsHighlighter
|
||||||
from dpaste.models import ONETIME_LIMIT, Snippet
|
from dpaste.models import Snippet
|
||||||
|
|
||||||
|
config = apps.get_app_config('dpaste')
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
@ -78,7 +80,7 @@ class SnippetDetailView(SnippetView, DetailView):
|
||||||
|
|
||||||
# One-Time snippet get deleted if the view count matches our limit
|
# One-Time snippet get deleted if the view count matches our limit
|
||||||
if snippet.expire_type == Snippet.EXPIRE_ONETIME \
|
if snippet.expire_type == Snippet.EXPIRE_ONETIME \
|
||||||
and snippet.view_count >= ONETIME_LIMIT:
|
and snippet.view_count >= config.ONETIME_LIMIT:
|
||||||
snippet.delete()
|
snippet.delete()
|
||||||
raise Http404()
|
raise Http404()
|
||||||
|
|
||||||
|
@ -201,30 +203,27 @@ class AboutView(TemplateView):
|
||||||
|
|
||||||
def _format_default(s):
|
def _format_default(s):
|
||||||
"""The default response is the snippet URL wrapped in quotes."""
|
"""The default response is the snippet URL wrapped in quotes."""
|
||||||
return '"%s%s"' % (BASE_URL, s.get_absolute_url())
|
return '"%s%s"' % (config.BASE_URL, s.get_absolute_url())
|
||||||
|
|
||||||
def _format_url(s):
|
def _format_url(s):
|
||||||
"""The `url` format returns the snippet URL, no quotes, but a linebreak after."""
|
"""The `url` format returns the snippet URL, no quotes, but a linebreak after."""
|
||||||
return '%s%s\n' % (BASE_URL, s.get_absolute_url())
|
return '%s%s\n' % (config.BASE_URL, s.get_absolute_url())
|
||||||
|
|
||||||
def _format_json(s):
|
def _format_json(s):
|
||||||
"""The `json` format export."""
|
"""The `json` format export."""
|
||||||
return json.dumps({
|
return json.dumps({
|
||||||
'url': '%s%s' % (BASE_URL, s.get_absolute_url()),
|
'url': '%s%s' % (config.BASE_URL, s.get_absolute_url()),
|
||||||
'content': s.content,
|
'content': s.content,
|
||||||
'lexer': s.lexer,
|
'lexer': s.lexer,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
BASE_URL = getattr(settings, 'DPASTE_BASE_URL', 'https://dpaste.de')
|
|
||||||
|
|
||||||
FORMAT_MAPPING = {
|
FORMAT_MAPPING = {
|
||||||
'default': _format_default,
|
'default': _format_default,
|
||||||
'url': _format_url,
|
'url': _format_url,
|
||||||
'json': _format_json,
|
'json': _format_json,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class APIView(View):
|
class APIView(View):
|
||||||
"""
|
"""
|
||||||
API View
|
API View
|
||||||
|
@ -257,10 +256,10 @@ class APIView(View):
|
||||||
lexer_cls = get_lexer_for_filename(filename)
|
lexer_cls = get_lexer_for_filename(filename)
|
||||||
lexer = lexer_cls.aliases[0]
|
lexer = lexer_cls.aliases[0]
|
||||||
except (ClassNotFound, IndexError):
|
except (ClassNotFound, IndexError):
|
||||||
lexer = highlight.PLAIN_CODE
|
lexer = config.PLAIN_CODE_SYMBOL
|
||||||
|
|
||||||
if expires:
|
if expires:
|
||||||
expire_options = [str(i) for i in dict(EXPIRE_CHOICES).keys()]
|
expire_options = [str(i) for i in dict(config.EXPIRE_CHOICES).keys()]
|
||||||
if not expires in expire_options:
|
if not expires in expire_options:
|
||||||
return HttpResponseBadRequest('Invalid expire choice "{}" given. '
|
return HttpResponseBadRequest('Invalid expire choice "{}" given. '
|
||||||
'Valid values are: {}'.format(expires, ', '.join(expire_options)))
|
'Valid values are: {}'.format(expires, ', '.join(expire_options)))
|
||||||
|
|
Loading…
Reference in a new issue