-
Notifications
You must be signed in to change notification settings - Fork 70
/
sprunge.py
159 lines (136 loc) · 4.49 KB
/
sprunge.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import logging
import random
import urllib
import webapp2
from pygments import highlight
from pygments.formatters import HtmlFormatter
import pygments.lexers
import cloudstorage as gcs
from google.appengine.api.app_identity import get_default_gcs_bucket_name
from google.appengine.ext import blobstore, db
from google.appengine.ext.webapp import blobstore_handlers
URL = 'http://sprunge.us'
POST = 'sprunge'
def new_id():
nid = ''
symbols = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
while len(nid) < 4:
n = random.randint(0, 35)
nid = nid + symbols[n:n + 1]
return nid
def help():
form = (
'data:text/html,<form action="{0}" method="POST" accept-charset="UTF-8">'
'<textarea name="{1}" cols="80" rows="24"></textarea>'
'<br><button type="submit">{1}</button></form>'.format(URL, POST)
)
return """
<style> a {{ text-decoration: none }} </style>
<pre>
sprunge(1) SPRUNGE sprunge(1)
NAME
sprunge: command line pastebin.
SYNOPSIS
<command> | curl -F '{0}=<-' {1}
DESCRIPTION
add <a href='{3}'>?<lang></a> to resulting url for line numbers and syntax highlighting
use <a href='{2}'>this form</a> to paste from a browser
EXAMPLES
~$ cat bin/ching | curl -F '{0}=<-' {1}
{1}/aXZI
~$ firefox {1}/aXZI?py#n-7
SEE ALSO
http://github.com/rupa/sprunge
</pre>""".format(POST, URL, form, 'http://pygments.org/docs/lexers/')
def make_blob(nid, data):
filename = '/{0}/{1}'.format(get_default_gcs_bucket_name(), nid)
with gcs.open(
filename, 'w', content_type='text/plain; charset=UTF-8'
) as fh:
fh.write(data.encode('utf-8'))
blobstore_filename = '/gs{0}'.format(filename)
return blobstore.create_gs_key(blobstore_filename)
class Sprunge(db.Model):
name = db.StringProperty()
content = db.TextProperty()
date = db.DateTimeProperty(auto_now_add=True)
blob = db.StringProperty()
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.out.write('''
<html>
<body>
{0}
</body>
</html>
'''.format(help()))
def post(self):
nid = new_id()
while Sprunge.gql('WHERE name = :1', nid).get():
nid = new_id()
s = Sprunge()
s.name = nid
key = make_blob(nid, self.request.get(POST))
s.blob = key
try:
s.put()
except Exception as ex:
self.response.out.write('{0}\n'.format(ex))
logging.error(ex)
return
self.response.out.write('{0}/{1}\n'.format(URL, nid))
class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, resource):
resource = str(urllib.unquote(resource))
c = Sprunge.gql('WHERE name = :1', resource).get()
if not c:
self.response.out.write('{0} not found.'.format(resource))
return
# See if we need to migrate to Blobstore.
try:
data = c.blob
except AttributeError:
data = c.content
else:
if c.blob:
data = blobstore.BlobReader(c.blob).read()
else:
data = c.content
# migrate
logging.info(
'Migrating {0} from Datastore to Blobstore.'
.format(resource)
)
key = make_blob(resource, data)
c.blob = key
c.content = ''
try:
c.put()
except Exception as ex:
logging.error(ex)
syntax = self.request.query_string
if not syntax:
self.response.headers['Content-Type'] = 'text/plain; charset=UTF-8'
self.response.out.write(data + '\n')
return
try:
lexer = pygments.lexers.get_lexer_by_name(syntax)
except:
lexer = pygments.lexers.TextLexer()
self.response.headers['Content-Type'] = 'text/html; charset=UTF-8'
self.response.out.write(highlight(
data,
lexer,
HtmlFormatter(
full=True,
style='borland',
lineanchors='n',
linenos='inline',
encoding='latin-1' # weird, but this works and utf-8 does not.
)
))
app = webapp2.WSGIApplication([
('/', MainHandler),
('/([^/]+)?', ServeHandler)],
debug=False,
)