-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathbin.py
99 lines (88 loc) · 3.67 KB
/
bin.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
import wsgiref.handlers
from django.utils import simplejson
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from google.appengine.api import urlfetch
from models import Bin, Post
import urllib
import re
import hashlib
from cgi import FieldStorage
import logging
from google.appengine.api.labs import taskqueue
class NotFound(Exception): pass
class BinHandler(webapp.RequestHandler):
def get(self):
path = self.request.path
if path[-1] == '/':
self.redirect(path[:-1])
path, feed = re.subn(r'^(.+)\/feed$', r'\1', path)
bin = self._get_bin(path)
if self.request.query_string:
self._record_post(bin, True)
self.redirect('/%s' % bin.name)
else:
posts = bin.post_set.order('-created').fetch(50)
self.response.out.write(template.render('templates/bin.%s' % ('atom' if feed else 'html'),
{'bin':bin, 'posts':posts, 'request':self.request}))
def post(self):
bin = self._get_bin(self.request.path)
post = self._record_post(bin)
# TODO: This should maybe be a header thing
if 'http://' in self.request.query_string:
params = dict(self.request.POST.items())
params['_url'] = self.request.query_string
urlfetch.fetch(url='http://hookah.progrium.com/dispatch',
payload=urllib.urlencode(params), method='POST')
taskqueue.add(url='/tasks/newpost', params={'ip': post.remote_addr, 'size': post.size, 'bin': bin.name})
self.response.set_status(201)
self.response.headers['Location'] = str("/%s" % bin.name)
self.response.out.write('<html><head><meta http-equiv="refresh" content="0;url=/%s" /></head><body>201 Created. Redirecting...</body></html>' % bin.name)
def head(self):
bin = self._get_bin(self.request.path)
if self.request.query_string:
self._record_post(bin, True)
else:
self._record_post(bin)
def handle_exception(self, exception, debug_mode):
if isinstance(exception, NotFound):
self.error(404)
else:
super(BinHandler, self).handle_exception(exception, debug_mode)
def _record_post(self, bin, use_get=False):
post = Post(bin=bin, remote_addr=self.request.remote_addr)
post.headers = dict(self.request.headers)
try:
post.body = self.request.body
except UnicodeDecodeError:
#post.body_binary = self.request.body
pass
post.query_string = self.request.query_string
post.form_data = []
data_source = self.request.GET if use_get else self.request.POST
post.size = len(post.body) if post.body else 0
for k,v in data_source.items():
if isinstance(v, FieldStorage):
file_body = v.file.read()
post.form_data.append([k, {
'file_name': v.filename,
'file_extension': v.filename.split('.')[-1],
'file_digest': hashlib.md5(file_body).hexdigest(),
'file_size': round(len(file_body) / 1024.0, 1),
}])
post.size += len(file_body)
else:
post.form_data.append([k,v])
post.put()
return post
def _get_bin(self, path):
name = path[1:].split('/')[0]
bin = Bin.all().filter('name =', name).get()
if bin:
return bin
else:
raise NotFound()
if __name__ == '__main__':
wsgiref.handlers.CGIHandler().run(webapp.WSGIApplication([
('/.*', BinHandler),
], debug=True))