from functools import lru_cache from mimetypes import common_types, types_map import pygments from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import get_object_or_404, render from django.template import RequestContext, loader from django.urls import reverse from django.views.decorators.csrf import csrf_exempt from pygments.formatters import HtmlFormatter from pygments.lexers import get_lexer_by_name, get_lexer_for_filename from tabulate import tabulate from paste.models import Paste from webtools import settings NON_STANDARD_TYPES_INV = {value: key for key, value in common_types.items()} STANDARD_TYPES_INV = {value: key for key, value in types_map.items()} HARDCODED_TYPES_INV = {"text/plain": ".txt"} TYPES_INV = NON_STANDARD_TYPES_INV | STANDARD_TYPES_INV | HARDCODED_TYPES_INV def get_files(request): """Get one or multiple files from either a multipart/form-data or raw request body with a Content-Type header.""" if request.FILES: return request.FILES content_type = request.headers.get("content-type", "") ext = TYPES_INV.get(content_type, "") return {"request" + ext: request} @csrf_exempt def index(request): """Displays form.""" if request.method == "GET": return render(request, "paste/index.html") if request.headers.get("Expect") == "100-continue": return HttpResponse("") pastes = [] for filename, the_file in get_files(request).items(): paste = Paste( filename=filename.split("/")[-1].split("\\")[-1], content=the_file.read().decode("UTF-8"), ) paste.choose_slug() paste.compute_size() paste.save() pastes.append( ( request.build_absolute_uri( reverse("short_paste", kwargs={"slug": paste.slug}) ), paste.size, paste.filename, ) ) if not pastes: return HttpResponse("error: Please provide a file.") return HttpResponse( tabulate(pastes, headers=("URL", "size", "filename"), tablefmt="github") + "\n", content_type="text/plain", ) def show(request, slug): """Display paste.""" paste = get_object_or_404(Paste, slug=slug) paste.incr_viewcount() if "html" in request.headers["accept"]: return HttpResponse(pygmentize(paste.filename, paste.content)) else: return HttpResponse(paste.content, content_type="text/plain") @lru_cache(1024) def pygmentize(filename, filecontents): try: lexer = get_lexer_for_filename(filename) except pygments.util.ClassNotFound: lexer = get_lexer_by_name(settings.PASTE["default_language"]) formatter = HtmlFormatter(style="emacs") data = {} data["filename"] = filename data["highlighted"] = pygments.highlight(filecontents, lexer, formatter) return loader.render_to_string("paste/show-pygments.html", data)