forked from robertkrimen/gist-it
-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.py
137 lines (113 loc) · 4.98 KB
/
app.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
#!/usr/bin/python
import logging
import new
import os
import pickle
import cgi
import sys
import traceback
import urlparse
import types
import wsgiref.handlers
import re
import posixpath
import urllib
from google.appengine.api import urlfetch
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext.webapp import template
_LOCAL_ = os.environ[ 'SERVER_SOFTWARE' ].startswith( 'Development' )
_DEBUG_ = False or _LOCAL_
_CACHE_ = False
sys.path.append( 'pyl' )
from versioned_memcache import memcache
import jinja2 as jinja2_
jinja2 = jinja2_.Environment( loader=jinja2_.FileSystemLoader( 'jinja2-assets' ) )
import gist_it
'''
Filter lines from the content, based on the start and end line indexes
'''
def filter_lines(content, start_line = 0, end_line = 0):
if (start_line == 0 and end_line == 0):
return content
if (end_line == 0):
return '\n'.join(content.splitlines()[start_line:])
return '\n'.join(content.splitlines()[start_line:end_line])
def render_gist_html( base, gist, document ):
result = jinja2.get_template( 'gist.jinja.html' ).render( cgi = cgi, base = base, gist = gist, document = document )
return result
def render_gist_js( base, gist, gist_html ):
result = jinja2.get_template( 'gist.jinja.js' ).render( base = base, gist = gist, gist_html = gist_html )
return result
def render_gist_js_callback( callback, gist, gist_html ):
return "%s( '%s', '%s' );" % ( callback, gist_html.encode( 'string_escape' ), gist.raw_path )
class RequestHandler( webapp.RequestHandler ):
def url_for( self, *arguments ):
parse = urlparse.urlparse( self.request.url )
path = ''
if len( arguments ):
path = posixpath.join( *arguments )
return str( urlparse.urlunparse( ( parse.scheme, parse.netloc, path, '', '', '' ) ) )
def render_template( self, template_name, **arguments ):
self.response.out.write( jinja2.get_template( template_name ).render( dispatch=self, **arguments ) )
class dispatch_index( RequestHandler ):
def get( self ):
self.render_template( 'index.jinja.html' )
class dispatch_gist_it( RequestHandler ):
def get( self, location ):
base = self.url_for()
location = urllib.unquote( location )
match = gist_it.Gist.match( location )
self.response.headers['Content-Type'] = 'text/plain';
if not match:
self.response.set_status( 404 )
self.response.out.write( self.response.http_status_message( 404 ) )
self.response.out.write( "\n" )
return
else:
gist = gist_it.Gist.parse( location )
if not gist:
self.response.set_status( 500 )
self.response.out.write( "Unable to parse \"%s\": Not a valid repository path?" % ( location ) )
self.response.out.write( "\n" )
return
if _CACHE_ and self.request.get( 'flush' ):
self.response.out.write( memcache.delete( memcache_key ) )
return
memcache_key = gist.raw_url
data = memcache.get( memcache_key )
if data is None or not _CACHE_:
# For below, see: http://stackoverflow.com/questions/2826238/does-google-appengine-cache-external-requests
response = urlfetch.fetch( gist.raw_url, headers = { 'Cache-Control': 'max-age=300' } )
if response.status_code != 200:
if response.status_code == 403:
self.response.set_status( response.status_code )
elif response.status_code == 404:
self.response.set_status( response.status_code )
else:
self.response.set_status( 500 )
self.response.out.write( "Unable to fetch \"%s\": (%i)" % ( gist.raw_url, response.status_code ) )
return
else:
gist_html = str( render_gist_html( base, gist, filter_lines(response.content, gist.start_line, gist.end_line) ) ).strip()
callback = self.request.get( 'callback' );
if callback != '':
result = render_gist_js_callback( callback, gist, gist_html )
else:
result = render_gist_js( base, gist, gist_html )
result = str( result ).strip()
data = result
if _CACHE_:
memcache.add( memcache_key, data, 60 * 60 * 24 )
self.response.headers['Content-Type'] = 'text/javascript';
self.response.out.write( data )
wsgi_application = webapp.WSGIApplication( [
( r'/', dispatch_index ),
( r'/xyzzy/(.*)', dispatch_gist_it ),
( r'(.*)', dispatch_gist_it ),
], debug=_DEBUG_ )
def main():
run_wsgi_app( wsgi_application )
if __name__ == '__main__':
main()