aboutsummaryrefslogtreecommitdiff
path: root/deprecated/cwp/bartlett/server.py
diff options
context:
space:
mode:
Diffstat (limited to 'deprecated/cwp/bartlett/server.py')
-rwxr-xr-xdeprecated/cwp/bartlett/server.py153
1 files changed, 153 insertions, 0 deletions
diff --git a/deprecated/cwp/bartlett/server.py b/deprecated/cwp/bartlett/server.py
new file mode 100755
index 00000000..8fb7d61e
--- /dev/null
+++ b/deprecated/cwp/bartlett/server.py
@@ -0,0 +1,153 @@
+#!/usr/bin/python2
+# Copyright 2012 Google Inc. All Rights Reserved.
+# Author: mrdmnd@ (Matt Redmond)
+# Based off of code in //depot/google3/experimental/mobile_gwp
+"""Code to transport profile data between a user's machine and the CWP servers.
+ Pages:
+ "/": the main page for the app, left blank so that users cannot access
+ the file upload but left in the code for debugging purposes
+ "/upload": Updates the datastore with a new file. the upload depends on
+ the format which is templated on the main page ("/")
+ input includes:
+ profile_data: the zipped file containing profile data
+ board: the architecture we ran on
+ chromeos_version: the chromeos_version
+ "/serve": Lists all of the files in the datastore. Each line is a new entry
+ in the datastore. The format is key~date, where key is the entry's
+ key in the datastore and date is the file upload time and date.
+ (Authentication Required)
+ "/serve/([^/]+)?": For downloading a file of profile data, ([^/]+)? means
+ any character sequence so to download the file go to
+ '/serve/$key' where $key is the datastore key of the file
+ you want to download.
+ (Authentication Required)
+ "/del/([^/]+)?": For deleting an entry in the datastore. To use go to
+ '/del/$key' where $key is the datastore key of the entry
+ you want to be deleted form the datastore.
+ (Authentication Required)
+ TODO: Add more extensive logging"""
+
+import cgi
+import logging
+import md5
+import urllib
+
+from google.appengine.api import users
+from google.appengine.ext import db
+from google.appengine.ext import webapp
+from google.appengine.ext.webapp.util import run_wsgi_app
+
+logging.getLogger().setLevel(logging.DEBUG)
+
+
+class FileEntry(db.Model):
+ profile_data = db.BlobProperty() # The profile data
+ date = db.DateTimeProperty(auto_now_add=True) # Date it was uploaded
+ data_md5 = db.ByteStringProperty() # md5 of the profile data
+ board = db.StringProperty() # board arch
+ chromeos_version = db.StringProperty() # ChromeOS version
+
+
+class MainPage(webapp.RequestHandler):
+ """Main page only used as the form template, not actually displayed."""
+
+ def get(self, response=''): # pylint: disable-msg=C6409
+ if response:
+ self.response.out.write('<html><body>')
+ self.response.out.write("""<br>
+ <form action="/upload" enctype="multipart/form-data" method="post">
+ <div><label>Profile Data:</label></div>
+ <div><input type="file" name="profile_data"/></div>
+ <div><label>Board</label></div>
+ <div><input type="text" name="board"/></div>
+ <div><label>ChromeOS Version</label></div>
+ <div><input type="text" name="chromeos_version"></div>
+ <div><input type="submit" value="send" name="submit"></div>
+ </form>
+ </body>
+ </html>""")
+
+
+class Upload(webapp.RequestHandler):
+ """Handler for uploading data to the datastore, accessible by anyone."""
+
+ def post(self): # pylint: disable-msg=C6409
+ """Takes input based on the main page's form."""
+ getfile = FileEntry()
+ f1 = self.request.get('profile_data')
+ getfile.profile_data = db.Blob(f1)
+ getfile.data_md5 = md5.new(f1).hexdigest()
+ getfile.board = self.request.get('board')
+ getfile.chromeos_version = self.request.get('chromeos_version')
+ getfile.put()
+ self.response.out.write(getfile.key())
+ #self.redirect('/')
+
+
+class ServeHandler(webapp.RequestHandler):
+ """Given the entry's key in the database, output the profile data file. Only
+ accessible from @google.com accounts."""
+
+ def get(self, resource): # pylint: disable-msg=C6409
+ if Authenticate(self):
+ file_key = str(urllib.unquote(resource))
+ request = db.get(file_key)
+ self.response.out.write(request.profile_data)
+
+
+class ListAll(webapp.RequestHandler):
+ """Displays all files uploaded. Only accessible by @google.com accounts."""
+
+ def get(self): # pylint: disable-msg=C6409
+ """Displays all information in FileEntry, ~ delimited."""
+ if Authenticate(self):
+ query_str = 'SELECT * FROM FileEntry ORDER BY date ASC'
+ query = db.GqlQuery(query_str)
+ delimiter = '~'
+
+ for item in query:
+ display_list = [item.key(), item.date, item.data_md5, item.board,
+ item.chromeos_version]
+ str_list = [cgi.escape(str(i)) for i in display_list]
+ self.response.out.write(delimiter.join(str_list) + '</br>')
+
+
+class DelEntries(webapp.RequestHandler):
+ """Deletes entries. Only accessible from @google.com accounts."""
+
+ def get(self, resource): # pylint: disable-msg=C6409
+ """A specific entry is deleted, when the key is given."""
+ if Authenticate(self):
+ fkey = str(urllib.unquote(resource))
+ request = db.get(fkey)
+ if request:
+ db.delete(fkey)
+
+
+def Authenticate(webpage):
+ """Some urls are only accessible if logged in with a @google.com account."""
+ user = users.get_current_user()
+ if user is None:
+ webpage.redirect(users.create_login_url(webpage.request.uri))
+ elif user.email().endswith('@google.com'):
+ return True
+ else:
+ webpage.response.out.write('Not Authenticated')
+ return False
+
+
+def main():
+ application = webapp.WSGIApplication(
+ [
+ ('/', MainPage),
+ ('/upload', Upload),
+ ('/serve/([^/]+)?', ServeHandler),
+ ('/serve', ListAll),
+ ('/del/([^/]+)?', DelEntries),
+ ],
+ debug=False)
+ run_wsgi_app(application)
+
+
+if __name__ == '__main__':
+ main()