summaryrefslogtreecommitdiff
path: root/pastepy.py
diff options
context:
space:
mode:
Diffstat (limited to 'pastepy.py')
-rw-r--r--pastepy.py292
1 files changed, 0 insertions, 292 deletions
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, '<pre>'
- line = 1
- for i, t in source:
- yield i, '<span id="codeline-%d">%s</span>' % (line, t)
- line += 1
- yield 0, '</pre>'
-
-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 &ndash; %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 &ndash; 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 &ndash; View paste &ndash; %s' % (settings.pastebin_name, paste.title or 'Untitled'),
- 'header': '%s &ndash; 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 &ndash; %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 ['<a href="/">asdf</a>']
- 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