black
This commit is contained in:
parent
f1a87fb77b
commit
a539d9096f
|
@ -2,6 +2,7 @@ from django.contrib import admin
|
|||
|
||||
from .models import Paste
|
||||
|
||||
|
||||
@admin.register(Paste)
|
||||
class PasteAdmin(admin.ModelAdmin):
|
||||
list_display = ('paste_time', 'slug', 'title', 'viewcount')
|
||||
list_display = ("paste_time", "slug", "title", "viewcount")
|
||||
|
|
|
@ -3,8 +3,9 @@ from django.conf import settings
|
|||
|
||||
def app_details(request):
|
||||
"""Passes settings details to the templates."""
|
||||
return {'APP_NAME': settings.APP_NAME,
|
||||
'APP_VERSION': settings.APP_VERSION,
|
||||
'DISPLAY_NAME': settings.DISPLAY_NAME,
|
||||
'PASTE': settings.PASTE,
|
||||
return {
|
||||
"APP_NAME": settings.APP_NAME,
|
||||
"APP_VERSION": settings.APP_VERSION,
|
||||
"DISPLAY_NAME": settings.DISPLAY_NAME,
|
||||
"PASTE": settings.PASTE,
|
||||
}
|
||||
|
|
|
@ -6,23 +6,31 @@ from .models import Paste, Language, EXPIRE_CHOICES
|
|||
|
||||
class PasteForm(ModelForm):
|
||||
"""Paste model form."""
|
||||
content = CharField(max_length=settings.PASTE['max_characters'],
|
||||
strip=False,
|
||||
widget=forms.Textarea)
|
||||
|
||||
content = CharField(
|
||||
max_length=settings.PASTE["max_characters"], strip=False, widget=forms.Textarea
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = Paste
|
||||
fields = ['language', 'title', 'password', 'content', 'lifetime',
|
||||
'lifecount', 'private']
|
||||
fields = [
|
||||
"language",
|
||||
"title",
|
||||
"password",
|
||||
"content",
|
||||
"lifetime",
|
||||
"lifecount",
|
||||
"private",
|
||||
]
|
||||
|
||||
def save(self, commit=True):
|
||||
"""Overwrites save method."""
|
||||
paste = super(PasteForm, self).save(commit=False)
|
||||
paste.compute_size()
|
||||
if not self.cleaned_data['title']:
|
||||
paste.title = 'no title'
|
||||
if self.cleaned_data['password']:
|
||||
paste.set_password(self.cleaned_data['password'])
|
||||
if not self.cleaned_data["title"]:
|
||||
paste.title = "no title"
|
||||
if self.cleaned_data["password"]:
|
||||
paste.set_password(self.cleaned_data["password"])
|
||||
if commit:
|
||||
paste.save()
|
||||
return paste
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
from django.contrib.sessions.middleware import SessionMiddleware as DjangoSessionMiddleware
|
||||
from django.contrib.sessions.middleware import (
|
||||
SessionMiddleware as DjangoSessionMiddleware,
|
||||
)
|
||||
|
||||
|
||||
class SessionMiddleware(DjangoSessionMiddleware):
|
||||
def process_request(self, request):
|
||||
if 'admin' in request.path:
|
||||
if "admin" in request.path:
|
||||
session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
|
||||
request.session = self.SessionStore(session_key)
|
||||
else:
|
||||
request.session = {}
|
||||
|
||||
def process_response(self, request, response):
|
||||
if 'admin' in request.path:
|
||||
if "admin" in request.path:
|
||||
return super().process_response(request, response)
|
||||
else:
|
||||
return response
|
||||
|
|
|
@ -10,37 +10,81 @@ class Migration(migrations.Migration):
|
|||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Language',
|
||||
name="Language",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=200, unique=True)),
|
||||
('slug', models.SlugField(max_length=200, unique=True)),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=200, unique=True)),
|
||||
("slug", models.SlugField(max_length=200, unique=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Paste',
|
||||
name="Paste",
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('slug', models.SlugField(editable=False, unique=True)),
|
||||
('title', models.CharField(blank=True, max_length=200)),
|
||||
('content', models.TextField(validators=[django.core.validators.MaxLengthValidator(100000)])),
|
||||
('size', models.IntegerField(default=0, editable=False)),
|
||||
('paste_time', models.DateTimeField(default=datetime.datetime.now, editable=False)),
|
||||
('paste_ip', models.GenericIPAddressField(editable=False)),
|
||||
('paste_agent', models.CharField(editable=False, max_length=200)),
|
||||
('lifetime', models.IntegerField(choices=[(0, 'Never expire'), (5, '5 minutes'), (30, '30 minutes'), (60, '1 hour'), (1440, '1 day'), (10080, '1 week')], default=0)),
|
||||
('lifecount', models.IntegerField(default=0)),
|
||||
('viewcount', models.IntegerField(default=0, editable=False)),
|
||||
('expired', models.BooleanField(default=False, editable=False)),
|
||||
('private', models.BooleanField(default=False)),
|
||||
('password', models.CharField(blank=True, max_length=128)),
|
||||
('salt', models.CharField(blank=True, max_length=36)),
|
||||
('language', models.ForeignKey(default=13, null=True, on_delete=django.db.models.deletion.SET_NULL, to='paste.Language')),
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("slug", models.SlugField(editable=False, unique=True)),
|
||||
("title", models.CharField(blank=True, max_length=200)),
|
||||
(
|
||||
"content",
|
||||
models.TextField(
|
||||
validators=[django.core.validators.MaxLengthValidator(100000)]
|
||||
),
|
||||
),
|
||||
("size", models.IntegerField(default=0, editable=False)),
|
||||
(
|
||||
"paste_time",
|
||||
models.DateTimeField(default=datetime.datetime.now, editable=False),
|
||||
),
|
||||
("paste_ip", models.GenericIPAddressField(editable=False)),
|
||||
("paste_agent", models.CharField(editable=False, max_length=200)),
|
||||
(
|
||||
"lifetime",
|
||||
models.IntegerField(
|
||||
choices=[
|
||||
(0, "Never expire"),
|
||||
(5, "5 minutes"),
|
||||
(30, "30 minutes"),
|
||||
(60, "1 hour"),
|
||||
(1440, "1 day"),
|
||||
(10080, "1 week"),
|
||||
],
|
||||
default=0,
|
||||
),
|
||||
),
|
||||
("lifecount", models.IntegerField(default=0)),
|
||||
("viewcount", models.IntegerField(default=0, editable=False)),
|
||||
("expired", models.BooleanField(default=False, editable=False)),
|
||||
("private", models.BooleanField(default=False)),
|
||||
("password", models.CharField(blank=True, max_length=128)),
|
||||
("salt", models.CharField(blank=True, max_length=36)),
|
||||
(
|
||||
"language",
|
||||
models.ForeignKey(
|
||||
default=13,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="paste.Language",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
|
@ -7,31 +7,40 @@ import django.db.models.deletion
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('paste', '0001_initial'),
|
||||
("paste", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='paste',
|
||||
name='paste_agent',
|
||||
migrations.RemoveField(model_name="paste", name="paste_agent",),
|
||||
migrations.RemoveField(model_name="paste", name="paste_ip",),
|
||||
migrations.AlterField(
|
||||
model_name="paste",
|
||||
name="language",
|
||||
field=models.ForeignKey(
|
||||
default=14,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="paste.Language",
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='paste',
|
||||
name='paste_ip',
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='paste',
|
||||
name='language',
|
||||
field=models.ForeignKey(default=14, null=True, on_delete=django.db.models.deletion.SET_NULL, to='paste.Language'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='paste',
|
||||
name='lifecount',
|
||||
model_name="paste",
|
||||
name="lifecount",
|
||||
field=models.IntegerField(blank=True, default=0),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='paste',
|
||||
name='lifetime',
|
||||
field=models.IntegerField(choices=[(0, 'Never expire'), (60, '1 hour'), (1440, '1 day'), (10080, '1 week'), (302400, '1 month'), (3679200, '1 year')], default=3679200),
|
||||
model_name="paste",
|
||||
name="lifetime",
|
||||
field=models.IntegerField(
|
||||
choices=[
|
||||
(0, "Never expire"),
|
||||
(60, "1 hour"),
|
||||
(1440, "1 day"),
|
||||
(10080, "1 week"),
|
||||
(302400, "1 month"),
|
||||
(3679200, "1 year"),
|
||||
],
|
||||
default=3679200,
|
||||
),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -9,17 +9,18 @@ import uuid
|
|||
|
||||
|
||||
EXPIRE_CHOICES = (
|
||||
(0, _('Never expire')),
|
||||
(60, _('1 hour')),
|
||||
(60 * 24, _('1 day')),
|
||||
(60 * 24 * 7, _('1 week')),
|
||||
(60 * 24 * 7 * 30, _('1 month')),
|
||||
(60 * 24 * 7 * 365, _('1 year')),
|
||||
(0, _("Never expire")),
|
||||
(60, _("1 hour")),
|
||||
(60 * 24, _("1 day")),
|
||||
(60 * 24 * 7, _("1 week")),
|
||||
(60 * 24 * 7 * 30, _("1 month")),
|
||||
(60 * 24 * 7 * 365, _("1 year")),
|
||||
)
|
||||
|
||||
|
||||
class Language(models.Model):
|
||||
"""Language object."""
|
||||
|
||||
name = models.CharField(max_length=200, unique=True)
|
||||
slug = models.SlugField(max_length=200, unique=True)
|
||||
|
||||
|
@ -28,7 +29,8 @@ class Language(models.Model):
|
|||
language = cls.objects.filter(name__icontains=name).first()
|
||||
if not language:
|
||||
language = cls.objects.filter(
|
||||
name__iexact=settings.PASTE['default_language']).first()
|
||||
name__iexact=settings.PASTE["default_language"]
|
||||
).first()
|
||||
return language
|
||||
|
||||
def __unicode__(self):
|
||||
|
@ -41,15 +43,20 @@ class Language(models.Model):
|
|||
|
||||
class Paste(models.Model):
|
||||
"""Paste object."""
|
||||
language = models.ForeignKey(Language, default=14, on_delete=models.SET_NULL, null=True)
|
||||
|
||||
language = models.ForeignKey(
|
||||
Language, default=14, on_delete=models.SET_NULL, null=True
|
||||
)
|
||||
slug = models.SlugField(unique=True, editable=False)
|
||||
title = models.CharField(max_length=200, blank=True)
|
||||
content = models.TextField(validators=[MaxLengthValidator(
|
||||
settings.PASTE['max_characters'])])
|
||||
content = models.TextField(
|
||||
validators=[MaxLengthValidator(settings.PASTE["max_characters"])]
|
||||
)
|
||||
size = models.IntegerField(default=0, editable=False)
|
||||
paste_time = models.DateTimeField(default=datetime.now, editable=False)
|
||||
lifetime = models.IntegerField(default=settings.PASTE['default_lifetime'],
|
||||
choices=EXPIRE_CHOICES)
|
||||
lifetime = models.IntegerField(
|
||||
default=settings.PASTE["default_lifetime"], choices=EXPIRE_CHOICES
|
||||
)
|
||||
lifecount = models.IntegerField(default=0, blank=True)
|
||||
viewcount = models.IntegerField(default=0, editable=False)
|
||||
expired = models.BooleanField(default=False, editable=False)
|
||||
|
@ -126,6 +133,5 @@ class Paste(models.Model):
|
|||
return self.slug
|
||||
|
||||
def __str__(self):
|
||||
excerpt = repr(self.content[:100]) + (
|
||||
'...' if len(self.content) > 100 else '')
|
||||
excerpt = repr(self.content[:100]) + ("..." if len(self.content) > 100 else "")
|
||||
return "{} - {} - {}".format(self.slug, self.title, excerpt)
|
||||
|
|
|
@ -9,27 +9,27 @@ from paste.tools import cache_exists, cache_fetch, cache_store
|
|||
|
||||
def render_pygments(request, paste, data):
|
||||
"""Renders Pygments template."""
|
||||
key = paste.slug+'_pygments.cache'
|
||||
key = paste.slug + "_pygments.cache"
|
||||
if cache_exists(key):
|
||||
highlighted_content = cache_fetch(key)
|
||||
else:
|
||||
lexer = get_lexer_by_name(paste.language.slug)
|
||||
formatter = HtmlFormatter(style='emacs')
|
||||
formatter = HtmlFormatter(style="emacs")
|
||||
highlighted_content = highlight(paste.content, lexer, formatter)
|
||||
cache_store(key, highlighted_content)
|
||||
data['paste'] = paste
|
||||
data['highlighted'] = highlighted_content
|
||||
rendered = loader.render_to_string('paste/show-pygments.html', data, request)
|
||||
data["paste"] = paste
|
||||
data["highlighted"] = highlighted_content
|
||||
rendered = loader.render_to_string("paste/show-pygments.html", data, request)
|
||||
return HttpResponse(rendered)
|
||||
|
||||
|
||||
def render_form(request, paste, data):
|
||||
"""Renders Form template."""
|
||||
data['paste'] = paste
|
||||
rendered = loader.render_to_string('paste/show-form.html', data, request)
|
||||
data["paste"] = paste
|
||||
rendered = loader.render_to_string("paste/show-form.html", data, request)
|
||||
return HttpResponse(rendered)
|
||||
|
||||
|
||||
def render_raw(request, paste, data):
|
||||
"""Renders RAW content."""
|
||||
return HttpResponse(paste.content, content_type='text/plain')
|
||||
return HttpResponse(paste.content, content_type="text/plain")
|
||||
|
|
|
@ -2,12 +2,14 @@ from django import template
|
|||
|
||||
register = template.Library()
|
||||
|
||||
@register.filter(name='add_class')
|
||||
|
||||
@register.filter(name="add_class")
|
||||
def add_class(value, arg):
|
||||
value.field.widget.attrs.update({"class": arg})
|
||||
return value
|
||||
|
||||
@register.filter(name='placeholder')
|
||||
|
||||
@register.filter(name="placeholder")
|
||||
def placeholder(value, arg):
|
||||
value.field.widget.attrs.update({"placeholder": arg})
|
||||
return value
|
||||
|
|
|
@ -8,7 +8,7 @@ from .models import Paste
|
|||
|
||||
def random_id(model):
|
||||
"""Returns a short uuid for the slug of the given model."""
|
||||
uuid = random.choice('0123456789') + shortuuid.uuid()
|
||||
uuid = random.choice("0123456789") + shortuuid.uuid()
|
||||
for i in range(3, len(uuid)):
|
||||
potential_uuid = uuid[:i]
|
||||
if not model.objects.filter(slug=potential_uuid):
|
||||
|
@ -28,11 +28,11 @@ def cache_exists(key):
|
|||
|
||||
def cache_store(key, value):
|
||||
"""Store cache value for key."""
|
||||
with open(cache_get_filepath(key), 'w') as cache_file:
|
||||
with open(cache_get_filepath(key), "w") as cache_file:
|
||||
cache_file.write(value)
|
||||
|
||||
|
||||
def cache_fetch(key):
|
||||
"""Fetch cache value for key."""
|
||||
with open(cache_get_filepath(key), 'r') as cache_file:
|
||||
with open(cache_get_filepath(key), "r") as cache_file:
|
||||
return cache_file.read()
|
||||
|
|
|
@ -5,9 +5,13 @@ from webtools import settings
|
|||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.index, name='index'),
|
||||
url(r'^history$', views.history, name='history'),
|
||||
url(r'^static/(?P<path>.*)', serve, {'document_root': settings.STATIC_ROOT}),
|
||||
url(r'^paste/(?P<slug>[a-zA-Z0-9]+)/(?P<renderer>[a-z]+)?$', views.show, name='paste'),
|
||||
url(r'^(?P<slug>[0-9][a-zA-Z0-9]+)$', views.show, name='short_paste'),
|
||||
url(r"^$", views.index, name="index"),
|
||||
url(r"^history$", views.history, name="history"),
|
||||
url(r"^static/(?P<path>.*)", serve, {"document_root": settings.STATIC_ROOT}),
|
||||
url(
|
||||
r"^paste/(?P<slug>[a-zA-Z0-9]+)/(?P<renderer>[a-z]+)?$",
|
||||
views.show,
|
||||
name="paste",
|
||||
),
|
||||
url(r"^(?P<slug>[0-9][a-zA-Z0-9]+)$", views.show, name="short_paste"),
|
||||
]
|
||||
|
|
|
@ -12,74 +12,86 @@ from webtools import settings
|
|||
@csrf_exempt
|
||||
def index(request):
|
||||
"""Displays form."""
|
||||
data = {'menu': 'index',
|
||||
'max_characters': settings.PASTE['max_characters']}
|
||||
if request.method == 'POST':
|
||||
data = {"menu": "index", "max_characters": settings.PASTE["max_characters"]}
|
||||
if request.method == "POST":
|
||||
paste = Paste(slug=random_id(Paste))
|
||||
if request.FILES:
|
||||
for language_name, any_file in request.FILES.items():
|
||||
break
|
||||
language = Language.by_name(language_name)
|
||||
form = PasteForm({'language': language.id,
|
||||
'title': any_file.name,
|
||||
'private': settings.PASTE['private_by_default'],
|
||||
'lifetime': settings.PASTE['default_lifetime'],
|
||||
'content': any_file.read().decode()
|
||||
}, instance=paste)
|
||||
form = PasteForm(
|
||||
{
|
||||
"language": language.id,
|
||||
"title": any_file.name,
|
||||
"private": settings.PASTE["private_by_default"],
|
||||
"lifetime": settings.PASTE["default_lifetime"],
|
||||
"content": any_file.read().decode(),
|
||||
},
|
||||
instance=paste,
|
||||
)
|
||||
else:
|
||||
form = PasteForm(request.POST, instance=paste)
|
||||
if not form.is_valid():
|
||||
data['form'] = form
|
||||
return render(request, 'paste/index.html', data)
|
||||
data["form"] = form
|
||||
return render(request, "paste/index.html", data)
|
||||
form.save() # Some logic added to overrided method, see forms.py
|
||||
location = request.build_absolute_uri(
|
||||
reverse('short_paste', kwargs={'slug': paste.slug}))
|
||||
return HttpResponseRedirect(location, content=location + "\n",
|
||||
content_type='text/plain')
|
||||
data['form'] = PasteForm(initial={
|
||||
'private': settings.PASTE['private_by_default'],
|
||||
'lifetime': settings.PASTE['default_lifetime'],
|
||||
'language': Language.by_name(settings.PASTE['default_language']).id})
|
||||
data['absolute_index_url'] = request.build_absolute_uri(reverse('index'))
|
||||
return render(request, 'paste/index.html', data)
|
||||
reverse("short_paste", kwargs={"slug": paste.slug})
|
||||
)
|
||||
return HttpResponseRedirect(
|
||||
location, content=location + "\n", content_type="text/plain"
|
||||
)
|
||||
data["form"] = PasteForm(
|
||||
initial={
|
||||
"private": settings.PASTE["private_by_default"],
|
||||
"lifetime": settings.PASTE["default_lifetime"],
|
||||
"language": Language.by_name(settings.PASTE["default_language"]).id,
|
||||
}
|
||||
)
|
||||
data["absolute_index_url"] = request.build_absolute_uri(reverse("index"))
|
||||
return render(request, "paste/index.html", data)
|
||||
|
||||
|
||||
def show(request, slug, renderer='pygments'):
|
||||
def show(request, slug, renderer="pygments"):
|
||||
"""Display paste."""
|
||||
# Fetching object
|
||||
paste = get_object_or_404(Paste, slug=slug)
|
||||
data = {'title': paste.title,'slug': slug}
|
||||
data = {"title": paste.title, "slug": slug}
|
||||
# Handling expiration
|
||||
if paste.is_expired():
|
||||
return render(request, 'paste/expired.html')
|
||||
return render(request, "paste/expired.html")
|
||||
# Handling passwords
|
||||
if paste.password:
|
||||
if 'password' in request.POST:
|
||||
password = request.POST['password']
|
||||
elif 'password' in request.COOKIES:
|
||||
password = request.COOKIES['password']
|
||||
if "password" in request.POST:
|
||||
password = request.POST["password"]
|
||||
elif "password" in request.COOKIES:
|
||||
password = request.COOKIES["password"]
|
||||
else:
|
||||
password = None
|
||||
if not paste.pwd_match(password):
|
||||
return render(request, 'paste/locked.html', data)
|
||||
return render(request, "paste/locked.html", data)
|
||||
# Before rendering actions
|
||||
paste.incr_viewcount()
|
||||
# Handling rendering modes
|
||||
if not renderer or renderer not in settings.PASTE['enabled_renderers']:
|
||||
renderer = settings.PASTE['default_renderer']
|
||||
data['current_renderer'] = renderer
|
||||
data['renderers'] = settings.PASTE['enabled_renderers']
|
||||
render_method = getattr(renderers, 'render_%s' % renderer)
|
||||
if not renderer or renderer not in settings.PASTE["enabled_renderers"]:
|
||||
renderer = settings.PASTE["default_renderer"]
|
||||
data["current_renderer"] = renderer
|
||||
data["renderers"] = settings.PASTE["enabled_renderers"]
|
||||
render_method = getattr(renderers, "render_%s" % renderer)
|
||||
response = render_method(request, paste, data)
|
||||
|
||||
# Responding
|
||||
if 'password' in request.POST:
|
||||
response.set_cookie('password', request.POST['password'])
|
||||
if "password" in request.POST:
|
||||
response.set_cookie("password", request.POST["password"])
|
||||
return response
|
||||
|
||||
|
||||
def history(request):
|
||||
"""Display last 25 public non-expired pastes."""
|
||||
pastes = Paste.objects.filter(private=False, expired=False).order_by('-pk')[:25]
|
||||
data = {'pastes': pastes, 'menu': 'history', 'default_renderer': settings.PASTE['default_renderer']}
|
||||
return render(request, 'paste/history.html', data)
|
||||
pastes = Paste.objects.filter(private=False, expired=False).order_by("-pk")[:25]
|
||||
data = {
|
||||
"pastes": pastes,
|
||||
"menu": "history",
|
||||
"default_renderer": settings.PASTE["default_renderer"],
|
||||
}
|
||||
return render(request, "paste/history.html", data)
|
||||
|
|
Loading…
Reference in New Issue