Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrating sample. #108

Merged
merged 1 commit into from
Sep 23, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions appengine/storage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## Google App Engine using Cloud Storage

This sample demonstrates how to use cloud storage from Google App Engine
Empty file added appengine/storage/__init__.py
Empty file.
19 changes: 19 additions & 0 deletions appengine/storage/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
runtime: python27
threadsafe: yes
api_version: 1

handlers:
- url: /
static_files: index.html
upload: index.html

- url: /favicon.ico
static_files: favicon.ico
upload: favicon.ico

- url: .*
script: main.app

libraries:
- name: jinja2
version: latest
16 changes: 16 additions & 0 deletions appengine/storage/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<html>
<head>
<script type="text/javascript">
function getList() {
var bucket_name = self.document.getElementById("bucket_name").value;
location.pathname = bucket_name;
}
</script>
</head>
<body>
<h1>Google Cloud Storage Bucket Lister</h1>
bucket name:
<input id="bucket_name" type="text"/>
<button onclick="getList()">list</button>
</body>
<html>
21 changes: 21 additions & 0 deletions appengine/storage/listing.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<html>
<body>
<h2><a href="http://developer.google.com/storage">Google Cloud Storage</a> Content Listing for Bucket <i>{{ bucket_name }}</i></h2>
<table border="1" cellpadding="5">
<tr bgcolor="#9acd32">
<th>Object Name</th>
<th>Modification Time</th>
<th>Hash</th>
<th>Size</th>
</tr>
{% for obj in items %}
<tr>
<td>{{ obj['name'] }}</td>
<td>{{ obj['media']['timeCreated'] }}</td>
<td>{{ obj['media']['hash'] }}</td>
<td>{{ obj['media']['length'] }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
122 changes: 122 additions & 0 deletions appengine/storage/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#!/usr/bin/env python

# Copyright 2015 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Present formatted listings for Google Cloud Storage buckets.
This Google App Engine application takes a bucket name in the URL path and uses
the Google Cloud Storage JSON API and Google's Python client library to list
the bucket's contents.
For example, if this app is invoked with the URI
http://bucket-list.appspot.com/foo, it would extract the bucket name 'foo' and
issue a request to GCS for its contents. The app formats the listing into an
XML document, which is prepended with a reference to an XSLT style sheet for
human readable presentation.
For more information:
Google APIs Client Library for Python:
<https://code.google.com/p/google-api-python-client/>
Google Cloud Storage JSON API:
<https://developers.google.com/storage/docs/json_api/>
Using OAuth 2.0 for Server to Server Applications:
<https://developers.google.com/accounts/docs/OAuth2ServiceAccount>
App Identity Python API Overview:
<https://code.google.com/appengine/docs/python/appidentity/overview.html>
"""

import os

from apiclient.discovery import build as build_service
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import login_required
import httplib2
import jinja2
from oauth2client.client import OAuth2WebServerFlow

# NOTE: You must provide a client ID and secret with access to the GCS JSON
# API.
# You can acquire a client ID and secret from the Google Developers Console.
# <https://developers.google.com/console#:access>
CLIENT_ID = ''
CLIENT_SECRET = ''
SCOPE = 'https://www.googleapis.com/auth/devstorage.read_only'
USER_AGENT = 'app-engine-bucket-lister'

# Since we don't plan to use all object attributes, we pass a fields argument
# to specify what the server should return.
FIELDS = 'items(name,media(timeCreated,hash,length))'


def GetBucketName(path):
bucket = path[1:] # Trim the preceding slash
if bucket[-1] == '/':
# Trim final slash, if necessary.
bucket = bucket[:-1]
return bucket


class MainHandler(webapp.RequestHandler):
@login_required
def get(self):
callback = self.request.host_url + '/oauth2callback'
flow = OAuth2WebServerFlow(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=callback,
access_type='online',
scope=SCOPE,
user_agent=USER_AGENT)

bucket = GetBucketName(self.request.path)
step2_url = flow.step1_get_authorize_url()
# Add state to remember which bucket to list.
self.redirect(step2_url + '&state=%s' % bucket)


class AuthHandler(webapp.RequestHandler):
@login_required
def get(self):
callback = self.request.host_url + '/oauth2callback'
flow = OAuth2WebServerFlow(
client_id=CLIENT_ID,
client_secret=CLIENT_SECRET,
redirect_uri=callback,
scope=SCOPE,
user_agent=USER_AGENT)

# Exchange the code (in self.request.params) for an access token.
credentials = flow.step2_exchange(self.request.params)
http = credentials.authorize(httplib2.Http())

bucket = self.request.get('state')
storage = build_service('storage', 'v1beta1', http=http)
list_response = storage.objects().list(bucket=bucket,
fields=FIELDS).execute()
template_values = {
'items': list_response['items'], 'bucket_name': bucket}

# We use a templating engine to format our output. For more
# information:
# <http://jinja.pocoo.org/docs/>
jinja_env = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
template = jinja_env.get_template('listing.html')
self.response.out.write(template.render(template_values))


app = webapp.WSGIApplication(
[
('/oauth2callback', AuthHandler),
('/..*', MainHandler)
],
debug=True)