summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2017-03-25 08:19:23 +0100
committerJon Bergli Heier <snakebite@jvnv.net>2017-03-25 08:19:23 +0100
commit5123d1a3b48920db78e5ec638d0b1c6a1d513380 (patch)
tree30049bddbe5234fe31c392b09decc7ca320f5991
parent56fc383a95d77556de570f571b7a78b468b47e1c (diff)
Added python 3 compatibility.
We're now using the six module and some helper functions to deal with str, unicode and bytes. This is tested on python 2.7 and 3.6.
-rw-r--r--pastepy.py51
1 files changed, 36 insertions, 15 deletions
diff --git a/pastepy.py b/pastepy.py
index 8c715fa..32a2f74 100644
--- a/pastepy.py
+++ b/pastepy.py
@@ -21,9 +21,22 @@ 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
@@ -89,7 +102,7 @@ class Paste(object):
'title': settings.pastebin_name,
'header': settings.pastebin_name,
'lexers': self.lexers,
- 'nick': c['nick'].value if 'nick' in c else 'Anonymous',
+ '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,
@@ -97,27 +110,30 @@ class Paste(object):
def preview(self, mp):
try:
- lexername, text = self.get_formatted(mp['syntax'].value.decode('utf-8'), mp['text'].value.decode('utf-8'))
+ 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': mp['nick'].value.decode('utf-8') or 'Anoynmous',
+ 'nick': nick,
'date': '%s UTC' % datetime.datetime.utcnow().ctime(),
'syntax': lexername,
- 'pastetitle': mp['title'].value.decode('utf-8') or 'Untitled',
+ 'pastetitle': title,
'text': text,
'rendered': (lexername or '').startswith('Rendered '),
})
def add_paste(self, mp):
- nick = mp['nick'].value.decode('utf-8') or None
- syntax = mp['syntax'].value.decode('utf-8') or None
- title = mp['title'].value.decode('utf-8') or None
- text = mp['text'].value.decode('utf-8').replace('\r', '') or None
+ 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))
@@ -131,13 +147,18 @@ class Paste(object):
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.output()))
+ headers.append(('Set-Cookie', c['nick'].OutputString()))
+ headers.append(('Set-Cookie', c['syntax'].OutputString()))
self.start_response('302 Found', headers)
return []
@@ -169,7 +190,7 @@ class Paste(object):
self.start_response('404 Not Found', [])
return []
try:
- lexername, text = self.get_formatted(paste.syntax, paste.text if type(paste.text) == unicode else paste.text.decode('utf-8'))
+ 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)
@@ -185,10 +206,10 @@ class Paste(object):
'header': '%s &ndash; View paste' % settings.pastebin_name,
'hash': hash,
'date': '%s UTC' % paste.date.ctime(),
- 'nick': paste.nick or 'Anonymous',
+ 'nick': b2t(paste.nick or 'Anonymous'),
'syntax': cache.syntax_name,
- 'pastetitle': paste.title or 'Untitled',
- 'text': cache.text,
+ 'pastetitle': b2t(paste.title or 'Untitled'),
+ 'text': b2t(cache.text),
'rendered': (cache.syntax_name or '').startswith('Rendered '),
})
@@ -202,11 +223,11 @@ class Paste(object):
session.close()
self.start_response('200 OK', [('Content-Type', 'text/plain; charset=UTF-8')])
- return [paste.text.encode('utf-8')]
+ return [t2b(paste.text)]
def highlight_stylesheet(self):
self.start_response('200 OK', [('Content-Type', 'text/css')])
- return [self.formatter.get_style_defs()]
+ return [t2b(self.formatter.get_style_defs())]
def static(self):
filename = settings.static_root + os.path.sep + self.path[1]