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.py | 292 ------------------------------------------------------------- 1 file changed, 292 deletions(-) delete mode 100644 pastepy.py (limited to 'pastepy.py') diff --git a/pastepy.py b/pastepy.py deleted file mode 100644 index 96d3f40..0000000 --- a/pastepy.py +++ /dev/null @@ -1,292 +0,0 @@ -import cgi -try: - from http.cookies import SimpleCookie -except ImportError: - from Cookie import SimpleCookie -import datetime -import db -import mimetypes -import os -import random - -import settings - -import jinja2 -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 -import six - -base62_alphabet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' - -def b2t(s): - '''Convert binary types to text types.''' - if isinstance(s, six.binary_type): - return s.decode('utf-8') - return s - -def t2b(s): - '''Convert text types to binary types.''' - if isinstance(s, six.text_type): - return s.encode('utf-8') - return s - -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, '%s' % (line, t)
-			line += 1
-		yield 0, '
' - -class Paste(object): - def __init__(self): - lexers = dict([(x[0], x[1][0]) for x in get_all_lexers()]) - self.lexers = [] - removed = [] - for cat, ls in settings.categories: - for l in ls: - removed.append(l) - self.lexers.append((cat, [(x, lexers[x]) for x in ls])) - for l in removed: - try: - del lexers[l] - except KeyError: - pass - rendered = [] - if has_markdown: - rendered.append(('Rendered markdown', 'md-render')) - if len(rendered): - self.lexers.append(('Rendered', rendered)) - self.lexers.append(('Others' if settings.categories else 'Syntax', sorted(lexers.items(), key = lambda l: l[0].lower()))) - self.formatter = CustomHtmlFormatter(linenos = 'table', lineanchors = 'line', anchorlinenos = True) - - random.seed() - - self.template_env = jinja2.Environment(loader = jinja2.FileSystemLoader('templates')) - - def render_template(self, name, args): - template = self.template_env.get_template(name) - data = template.render(**args).encode('utf-8') - self.start_response('200 OK', [('Content-Type', 'text/html; charset=UTF-8'), ('Content-Length', str(len(data)))]) - return [data] - - def message(self, msg, title = 'Message'): - return self.render_template('message.html', { - 'title': '%s – %s' % (settings.pastebin_name, title), - 'header': title, - 'text': msg, - }) - - def paste(self): - c = SimpleCookie(self.environ['HTTP_COOKIE'] if 'HTTP_COOKIE' in self.environ else None) - if self.environ['REQUEST_METHOD'] == 'POST': - mp = cgi.FieldStorage(fp = self.environ['wsgi.input'], environ = self.environ, keep_blank_values = True) - if mp['type'].value == 'Preview': - return self.preview(mp) - elif mp['type'].value == 'Paste': - return self.add_paste(mp) - else: - return self.message('Invalid type "%s".' % mp['type'].value, 'Error') - return self.render_template('paste.html', { - 'title': settings.pastebin_name, - 'header': settings.pastebin_name, - 'lexers': self.lexers, - 'nick': b2t(c['nick'].value if 'nick' in c else 'Anonymous'), - 'syntax': c['syntax'].value if 'syntax' in c else settings.default, - 'remember_me': 'nick' in c, - 'remember_syntax': 'syntax' in c, - }) - - def preview(self, mp): - try: - lexername, text = self.get_formatted(mp['syntax'].value, mp['text'].value) - except UnknownSyntaxError: - return self.message('Could not find lexer "%s".' % mp['syntax'].value, 'Error') - - # These values to be unicode in py2; in py3 they will be str which is OK. - nick = b2t(mp['nick'].value or 'Anonymous') - title = b2t(mp['title'].value or 'Untitled') - return self.render_template('view.html', { - 'title': settings.pastebin_name, - 'header': '%s – Preview' % settings.pastebin_name, - 'hash': None, - 'nick': nick, - 'date': '%s UTC' % datetime.datetime.utcnow().ctime(), - 'syntax': lexername, - 'pastetitle': title, - 'text': text, - 'rendered': (lexername or '').startswith('Rendered '), - }) - - def add_paste(self, mp): - nick = b2t(mp['nick'].value or None) - syntax = b2t(mp['syntax'].value or None) - title = b2t(mp['title'].value or None) - text = b2t(mp['text'].value.replace('\r', '') or None) - - hash = ''.join(random.choice(base62_alphabet) for x in range(5)) - - try: - session = db.Session() - paste = db.Paste(hash, nick, datetime.datetime.utcnow(), syntax, title, text, self.environ['REMOTE_ADDR']) - session.add(paste) - session.commit() - finally: - session.close() - - headers = [('Location', '/view/%s' % hash)] - c = SimpleCookie() - if six.PY2: - # In py2 we need nick to be a str, or non-ascii characters will fail with UnicodeDecodeError. - # In py3 it must be a str or we will get garbage in the cookie value. - nick = t2b(nick) - c['nick'] = nick - dt = (datetime.datetime.utcnow() + datetime.timedelta(days = 30)) if 'remember_me' in mp else datetime.datetime.utcfromtimestamp(0) - c['nick']['expires'] = dt.strftime('%a, %d-%b-%y %H:%M:%S GMT') - c['syntax'] = syntax - dt = (datetime.datetime.utcnow() + datetime.timedelta(days = 30)) if 'remember_syntax' in mp else datetime.datetime.utcfromtimestamp(0) - c['syntax']['expires'] = dt.strftime('%a, %d-%b-%y %H:%M:%S GMT') - headers.append(('Set-Cookie', c['nick'].OutputString())) - headers.append(('Set-Cookie', c['syntax'].OutputString())) - self.start_response('302 Found', headers) - return [] - - def get_formatted(self, syntax, text): - if syntax == 'md-render' and has_markdown: - text = markdown.markdown(text, extensions = settings.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, self.formatter) - return (lexername, text) - - def view(self): - hash = self.path[1] - - try: - session = db.Session() - try: - cache = session.query(db.Cache).filter_by(paste_hash = hash).one() - paste = cache.paste - except db.NoResultFound: # No cache found, generate it. - try: - paste = session.query(db.Paste).filter_by(hash = hash).one() - except db.NoResultFound: - self.start_response('404 Not Found', []) - return [] - try: - lexername, text = self.get_formatted(paste.syntax, paste.text) - except UnknownSyntaxError: - return self.message('Could not find the lexer "%s".' % paste.syntax, 'Error') - cache = db.Cache(hash, lexername, text) - session.add(cache) - session.commit() - # Workaround for attribute refresh. - paste = cache.paste - finally: - session.close() - - return self.render_template('view.html', { - 'title': '%s – View paste – %s' % (settings.pastebin_name, paste.title or 'Untitled'), - 'header': '%s – View paste' % settings.pastebin_name, - 'hash': hash, - 'date': '%s UTC' % paste.date.ctime(), - 'nick': b2t(paste.nick or 'Anonymous'), - 'syntax': cache.syntax_name, - 'pastetitle': b2t(paste.title or 'Untitled'), - 'text': b2t(cache.text), - 'rendered': (cache.syntax_name or '').startswith('Rendered '), - }) - - def raw(self): - hash = self.path[1] - - try: - session = db.Session() - paste = session.query(db.Paste).filter_by(hash = hash).one() - except db.NoResultFound: - self.start_response('404 Not Found', []) - return [] - finally: - session.close() - - self.start_response('200 OK', [('Content-Type', 'text/plain; charset=UTF-8')]) - return [t2b(paste.text)] - - def full(self): - hash = self.path[1] - - try: - session = db.Session() - try: - cache = session.query(db.Cache).filter_by(paste_hash = hash).one() - paste = cache.paste - except db.NoResultFound: - try: - paste = session.query(db.Paste).filter_by(hash = hash).one() - except db.NoResultFound: - self.start_response('404 Not Found', []) - return [] - try: - lexername, text = self.get_formatted(paste.syntax, paste.text) - except UnknownSyntaxError: - return self.message('Could not find the lexer "%s".' % paste.syntax, 'Error') - cache = db.Cache(hash, lexername, text) - session.add(cache) - session.commit() - # Workaround for attribute refresh. - paste = cache.paste - finally: - session.close() - - return self.render_template('full.html', { - 'title': '%s – %s' % (settings.pastebin_name, paste.title or 'Untitled'), - 'text': b2t(cache.text), - 'rendered': (cache.syntax_name or '').startswith('Rendered '), - }) - - def highlight_stylesheet(self): - self.start_response('200 OK', [('Content-Type', 'text/css')]) - return [t2b(self.formatter.get_style_defs())] - - def static(self): - filename = settings.static_root + os.path.sep + self.path[1] - if not self.path[1] in ('paste.css', 'edit.js', 'view.js') or not os.path.exists(filename): - self.start_response('404 Not Found', [('Content-Type', 'text/html; charset=UTF-8'), ('Location', '/')]) - return ['asdf'] - self.start_response('200 OK', [('Content-Type', mimetypes.guess_type(filename)[0] or 'text/plain; charset=UTF-8')]) - return open(filename, 'rb') - - def __call__(self, environ, start_response): - self.environ = environ - self.start_response = start_response - - path = self.environ['PATH_INFO'].split('/')[1:] - module = path[0] or 'paste' - if module in ('list', 'paste', 'view', 'raw', 'full', 'static', 'highlight_stylesheet'): - self.path = path - return getattr(self, module)() - else: - return self.message('Invalid module requested.', 'Error') - -if __name__ == '__main__': - from wsgiref.simple_server import make_server - httpd = make_server('', 8000, Paste()) - httpd.serve_forever() - -# vim: noet ts=4 -- cgit v1.2.3