From c57494ae405ffbdd8ec45f74ef04ea85895f1bf7 Mon Sep 17 00:00:00 2001 From: Jon Bergli Heier Date: Fri, 15 Mar 2019 18:45:47 +0100 Subject: Port application to flask --- pastepy/pastepy.py | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 pastepy/pastepy.py (limited to 'pastepy/pastepy.py') diff --git a/pastepy/pastepy.py b/pastepy/pastepy.py new file mode 100644 index 0000000..750d8fe --- /dev/null +++ b/pastepy/pastepy.py @@ -0,0 +1,169 @@ +import datetime +import random + +from flask import Blueprint, current_app, render_template, request, session, redirect, url_for +try: + import markdown + has_markdown = True +except ImportError: + has_markdown = False +import pygments +from pygments import highlight +from pygments.lexers import get_all_lexers, get_lexer_by_name +from pygments.formatters import HtmlFormatter + +from . import db + +app = Blueprint(__name__, 'pastepy') + +base62_alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' + +class PasteError(Exception): pass +class UnknownSyntaxError(PasteError): pass + +class CustomHtmlFormatter(HtmlFormatter): + def wrap(self, source, outfile): + yield 0, '
'
+        line = 1
+        for i, t in source:
+            yield i, '{}'.format(i, t)
+            line += 1
+        yield 0, '
' + +def init_lexers(): + all_lexers = dict([(x[0], x[1][0]) for x in get_all_lexers()]) + lexers = [] + removed = [] + for cat, ls in current_app.config['CATEGORIES']: + for l in ls: + removed.append(l) + lexers.append((cat, [(x, all_lexers[x]) for x in ls if x in all_lexers])) + for l in removed: + try: + del all_lexers[l] + except KeyError: + pass + rendered = [] + if has_markdown: + rendered.append(('Rendered markdown', 'md-render')) + if len(rendered): + lexers.append(('Rendered', rendered)) + lexers.append(('Others' if current_app.config['CATEGORIES'] else 'Syntax', sorted(all_lexers.items(), key = lambda l: l[0].lower()))) + + current_app.config['LEXERS'] = lexers + current_app.config['FORMATTER'] = CustomHtmlFormatter(linenos='table', lineanchors='line', anchorlinenos=True) + +init_lexers() + +@app.route('/') +@app.route('/paste') +def paste(): + context = { + 'title': current_app.config['PASTEBIN_NAME'], + 'header': current_app.config['PASTEBIN_NAME'], + } + return render_template('paste.html', **context) + +def get_formatted(syntax, text): + if syntax == 'md-render' and has_markdown: + text = markdown.markdown(text, extensions=current_app.config['MARKDOWN_EXTENSIONS']) + lexername = 'Rendered markdown' + else: + try: + lex = get_lexer_by_name(syntax or 'text') + except pygments.util.ClassNotFound: + raise UnknownSyntaxError(syntax) + lexername = lex.name + text = highlight(text, lex, current_app.config['FORMATTER']) + return (lexername, text) + +def add_paste(): + nick = request.form.get('nick') + syntax = request.form.get('syntax') + title = request.form.get('title') + text = request.form.get('text').replace('\r', '') + + with db.session_scope() as db_session: + paste_hash = ''.join(random.choice(base62_alphabet) for x in range(5)) + paste = db.Paste(paste_hash, nick, datetime.datetime.utcnow(), syntax, title, text, request.remote_addr) + db_session.add(paste) + + if 'remember_me' in request.form: + session['nick'] = nick + else: + session.pop('nick', None) + if 'remember_syntax' in request.form: + session['syntax'] = syntax + else: + session.pop('syntax', None) + return redirect(url_for('.view_paste', paste_hash=paste_hash)) + +def render_preview(): + try: + lexername, text = get_formatted(request.form['syntax'], request.form['text']) + except UnknownSyntaxError: + abort(500, 'Could not find lexer "{}".'.format(request.form['syntax'])) + + nick = request.form['nick'] or 'Anonymous' + title = request.form['title'] or 'Untitled' + return render_template('view.html', + title='Preview', + hash=None, + nick=nick, + date='{} UTC'.format(datetime.datetime.utcnow().ctime()), + syntax=lexername, + pastetitle=title, + text=text, + rendered=(lexername or '').startswith('Rendered '), + ) + +@app.route('/paste', methods=['POST']) +def post_paste(): + if request.form['type'] == 'Preview': + return render_preview() + if request.form['type'] == 'Paste': + return add_paste() + abort(404) + +@app.route('/view/') +@app.route('/full/', endpoint='view_full') +def view_paste(paste_hash): + with db.session_scope() as db_session: + try: + cache = db_session.query(db.Cache).filter_by(paste_hash=paste_hash).one() + paste = cache.paste + except db.NoResultFound: + try: + paste = db_session.query(db.Paste).filter_by(hash=paste_hash).one() + except db.NoResultFound: + abort(404) + try: + lexername, text = get_formatted(paste.syntax, paste.text) + except UnknownSyntaxError: + abort(500, 'Could not find the lexer "{}"'.format(paste.syntax)) + cache = db.Cache(paste_hash, lexername, text) + db_session.add(cache) + template = 'full.html' if request.endpoint.endswith('.view_full') else 'view.html' + return render_template(template, + title='View paste \u2013 {}'.format(current_app.config['PASTEBIN_NAME'], paste.title or 'Untitled'), + hash=paste_hash, + date='{} UTC'.format(paste.date.ctime()), + nick=paste.nick or 'Anonymous', + syntax=cache.syntax_name, + pastetitle=paste.title or 'Untitled', + text=cache.text, + rendered=(cache.syntax_name or '').startswith('Rendered '), + ) + +@app.route('/highlight_stylesheet') +def highlight_stylesheet(): + return current_app.config['FORMATTER'].get_style_defs(), 200, {'Content-Type': 'text/css'} + +@app.route('/raw/') +def raw(paste_hash): + with db.session_scope() as db_session: + try: + paste = db_session.query(db.Paste).filter_by(hash=paste_hash).one() + except db.NoResultFound: + abort(404) + return paste.text, 200, {'Content-Type': 'text/plain'} -- cgit v1.2.3