• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2#
3# Copyright 2014 Google Inc. All Rights Reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17"""This application produces formatted listings for Google Cloud
18   Storage buckets.
19
20It takes a bucket name in the URL path and does an HTTP GET on the
21corresponding Google Cloud Storage URL to obtain a listing of the bucket
22contents. For example, if this app is invoked with the URI
23http://bucket-list.appspot.com/foo, it would remove the bucket name 'foo',
24append it to the Google Cloud Storage service URI and send a GET request to
25the resulting URI. The bucket listing is returned in an XML document, which is
26prepended with a reference to an XSLT style sheet for human readable
27presentation.
28
29More information about using Google App Engine apps and service accounts to
30call Google APIs can be found here:
31
32<https://developers.google.com/accounts/docs/OAuth2ServiceAccount>
33<http://code.google.com/appengine/docs/python/appidentity/overview.html>
34"""
35
36__author__ = 'marccohen@google.com (Marc Cohen)'
37
38import httplib2
39import logging
40import os
41import pickle
42import re
43
44from google.appengine.api import memcache
45from google.appengine.ext import webapp
46from google.appengine.ext.webapp import template
47from google.appengine.ext.webapp.util import run_wsgi_app
48from oauth2client.contrib.appengine import AppAssertionCredentials
49
50# Constants for the XSL stylesheet and the Google Cloud Storage URI.
51XSL = '\n<?xml-stylesheet href="/listing.xsl" type="text/xsl"?>\n';
52URI = 'http://commondatastorage.googleapis.com'
53
54# Obtain service account credentials and authorize HTTP connection.
55credentials = AppAssertionCredentials(
56    scope='https://www.googleapis.com/auth/devstorage.read_write')
57http = credentials.authorize(httplib2.Http(memcache))
58
59
60class MainHandler(webapp.RequestHandler):
61
62  def get(self):
63    try:
64      # Derive desired bucket name from path after domain name.
65      bucket = self.request.path
66      if bucket[-1] == '/':
67        # Trim final slash, if necessary.
68        bucket = bucket[:-1]
69      # Send HTTP request to Google Cloud Storage to obtain bucket listing.
70      resp, content = http.request(URI + bucket, "GET")
71      if resp.status != 200:
72        # If error getting bucket listing, raise exception.
73        err = 'Error: ' + str(resp.status) + ', bucket: ' + bucket + \
74              ', response: ' + str(content)
75        raise Exception(err)
76      # Edit returned bucket listing XML to insert a reference to our style
77      # sheet for nice formatting and send results to client.
78      content = re.sub('(<ListBucketResult)', XSL + '\\1', content)
79      self.response.headers['Content-Type'] = 'text/xml'
80      self.response.out.write(content)
81    except Exception as e:
82      self.response.headers['Content-Type'] = 'text/plain'
83      self.response.set_status(404)
84      self.response.out.write(str(e))
85
86
87def main():
88  application = webapp.WSGIApplication(
89      [
90       ('.*', MainHandler),
91      ],
92      debug=True)
93  run_wsgi_app(application)
94
95
96if __name__ == '__main__':
97  main()
98