Skip to content

Instantly share code, notes, and snippets.

@Arachnid
Created March 29, 2010 16:05
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save Arachnid/348025 to your computer and use it in GitHub Desktop.
Save Arachnid/348025 to your computer and use it in GitHub Desktop.
application: filehangar
version: live
runtime: python
api_version: 1
handlers:
- url: /remote_api
script: $PYTHON_LIB/google/appengine/ext/remote_api/handler.py
login: admin
- url: /_ah/queue/deferred
script: $PYTHON_LIB/google/appengine/ext/deferred/deferred.py
login: admin
- url: /static
static_dir: static
- url: /.*
script: handler.py
from google.appengine.api import users
from google.appengine.ext import blobstore
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext.webapp import template
from google.appengine.ext.webapp import util
import os
class FileInfo(db.Model):
blob = blobstore.BlobReferenceProperty(required=True)
uploaded_by = db.UserProperty(required=True)
uploaded_at = db.DateTimeProperty(required=True, auto_now_add=True)
class BaseHandler(webapp.RequestHandler):
def render_template(self, file, template_args):
path = os.path.join(os.path.dirname(__file__), "templates", file)
self.response.out.write(template.render(path, template_args))
class FileUploadFormHandler(BaseHandler):
@util.login_required
def get(self):
self.render_template("upload.html", {
'logout_url': users.create_logout_url('/'),
})
class FileUploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
blob_info = self.get_uploads()[0]
if not users.get_current_user():
blob_info.delete()
self.redirect(users.create_login_url("/"))
return
file_info = FileInfo(blob=blob_info.key(),
uploaded_by=users.get_current_user())
db.put(file_info)
self.redirect("/file/%d/success" % (file_info.key().id(),))
class AjaxSuccessHandler(BaseHandler):
def get(self, file_id):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('%s/file/%s' % (self.request.host_url, file_id))
class FileInfoHandler(BaseHandler):
def get(self, file_id):
file_info = FileInfo.get_by_id(long(file_id))
if not file_info:
self.error(404)
return
self.render_template("info.html", {
'file_info': file_info,
'logout_url': users.create_logout_url('/'),
})
class FileDownloadHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, file_id):
file_info = FileInfo.get_by_id(long(file_id))
if not file_info or not file_info.blob:
self.error(404)
return
self.send_blob(file_info.blob, save_as=True)
class GenerateUploadUrlHandler(BaseHandler):
@util.login_required
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write(blobstore.create_upload_url('/upload'))
application = webapp.WSGIApplication([
('/', FileUploadFormHandler),
('/upload', FileUploadHandler),
('/generate_upload_url', GenerateUploadUrlHandler),
('/file/([0-9]+)', FileInfoHandler),
('/file/([0-9]+)/download', FileDownloadHandler),
('/file/([0-9]+)/success', AjaxSuccessHandler),
])
def main():
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
<html>
<head>
<title>File Hangar: File information</title>
</head>
<body>
<p style="float: right"><a href="{{logout_url}}">Log Out</a></p>
<h1>File information</h1>
<table>
<tr><th>Filename</th><td>{{file_info.blob.filename}}</td></tr>
<tr><th>Size</th><td>{{file_info.blob.size}} bytes</td></tr>
<tr><th>Uploaded</th><td>{{file_info.uploaded_at}}</td></tr>
<tr><th>Uploaded by</th><td>{{file_info.uploaded_by}}</td></tr>
<tr><th>Content Type</th><td>{{file_info.blob.content_type}}</td></tr>
</table>
<p><a href="/file/{{file_info.key.id}}/download">Download this file</a></p>
</body>
</html>
<html>
<head>
<title>File Hangar: Upload file</title>
<style type="text/css">@import url(/static/css/plupload.queue.css);</style>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("jquery", "1.4");
</script>
<script type="text/javascript" src="/static/plupload/gears_init.js"></script>
<script type="text/javascript" src="/static/plupload/plupload.full.min.js"></script>
<script type="text/javascript" src="/static/plupload/jquery.plupload.queue.min.js"></script>
<script type="text/javascript">
$(function() {
uploader = $("#uploader").pluploadQueue({
runtimes: 'flash,html5,gears,html4',
use_query_string: false,
multipart: true,
flash_swf_url: '/static/plupload/plupload.flash.swf',
filters: [{title:'dmgs', extensions:'dmg'}],
}).pluploadQueue();
uploader.bind('UploadFile', function(up, file) {
$.ajax({
url: '/generate_upload_url',
async: false,
success: function(data) {
up.settings.url = data;
},
});
});
});
</script>
</head>
<body>
<p style="float: right"><a href="{{logout_url}}">Log Out</a></p>
<h1>Upload a file to App Engine File Hangar</h1>
<form>
<div id="uploader">
</div>
</form>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment