Created
August 1, 2013 15:19
-
-
Save dlanger/6132351 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python2.4 | |
# | |
# Copyright 2008 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. | |
"""Example script. | |
Connects to an installation of Google Short Links and submits an | |
API request. | |
Example commands: | |
Get the details of the short link 'foo': | |
python api_sample.py | |
--details | |
--server=shortlinks.example.com | |
--hmac=foobar | |
--email=anything | |
--url=anything | |
--shortcut_name=foo | |
Create a new short link 'bar' that points to www.google.com and | |
is owned by [email protected]: | |
python api_sample.py | |
--create | |
--server=shortlinks.example.com | |
--hmac=foobar | |
[email protected] | |
--url=http://www.google.com | |
--shortcut_name=bar | |
Create a new public HASHED short link that points to www.google.com and | |
is owned by [email protected]: | |
python api_sample.py | |
--hash | |
--server=shortlinks.example.com | |
--hmac=foobar | |
[email protected] | |
--url=http://www.google.com | |
--shortcut_name=anything | |
--is_public | |
""" | |
import base64 | |
import datetime | |
import hmac | |
import optparse | |
import sha | |
import sys | |
import time | |
import urllib | |
import urllib2 | |
def make_request_uri(hostname, api_method, secret, **parameters): | |
"""Constructs a signed api request. | |
Contains a miniature implementation of an oauth signing mechanism. | |
Not complete, but enough for this use case. | |
Args: | |
hostname: the name of the domain that short links is installed at | |
api_method: the api method to be called, like get_or_create_hash | |
secret: the api (hmac) secret to be used | |
parameters: additional arguments that should be passed to the api-method | |
Returns: | |
A signed URL that the short links server would understand. | |
""" | |
# What is the url (without parameters)? | |
base_url = 'http://%s/js/%s' % (hostname.lower(), api_method) | |
# What is the base query string? | |
parameters['oauth_signature_method'] = 'HMAC-SHA1' | |
parameters['timestamp'] = str( | |
time.mktime(datetime.datetime.now().timetuple())) | |
param_array = [(k, v) for k, v in parameters.items()] | |
param_array.sort() | |
keyvals = ['%s=%s' % (urllib.quote(a, ''), urllib.quote(str(b), '')) | |
for a, b in param_array] | |
unsecaped = '&'.join(keyvals) | |
signature_base_string = 'GET&%s&%s' % ( | |
urllib.quote(base_url, ''), urllib.quote(unsecaped, '')) | |
# Create oauth secret | |
signature = urllib.quote(base64.b64encode( | |
hmac.new(secret, signature_base_string, sha).digest()), '') | |
# Return the result | |
return '%s?%s&oauth_signature=%s' % (base_url, unsecaped, signature) | |
def parse_options(argv): | |
"""Creates a parser that can evaluate commandline options.""" | |
parser = optparse.OptionParser(usage='%prog [options] [-- diff_options]') | |
group = parser.add_option_group('Server options') | |
group.add_option('-s', '--server', dest='server', | |
metavar='SERVER', default=None, | |
help='The name of the server we connect to, ' | |
'like shortlinks.example.com') | |
group.add_option('-H', '--hmac', dest='hmac', | |
metavar='SECRET', default=None, | |
help='The HMAC secret that provides API access') | |
group = parser.add_option_group('Available commands') | |
group.add_option('--hash', '--get_or_create_hash', action='store_const', | |
const='get_or_create_hash', | |
dest='action', help='Get or create a hashed short link') | |
group.add_option('--details', '--get_details', action='store_const', | |
const='get_details', | |
dest='action', help='Get the details of a short link') | |
group.add_option('--create', '--get_or_create_shortlink', | |
action='store_const', | |
const='get_or_create_shortlink', | |
dest='action', help='Get or create a regular short link') | |
group = parser.add_option_group('Command details') | |
group.add_option('-e', '--email', dest='email', | |
metavar='EMAIL', default=None, | |
help='Email of the owner of a short link') | |
group.add_option('-u', '--url', dest='url', | |
metavar='URL', default=None, | |
help='Url of a short link') | |
group.add_option('-n', '--shortcut_name', dest='shortcut_name', | |
metavar='SHORTCUT_NAME', default=None, | |
help='Name of the short link') | |
group.add_option('--public', '--is_public', dest='is_public', | |
action='store_true', metavar='IS_PUBLIC', default=False, | |
help='Set to create a public short link') | |
group.add_option('--dryrun', dest='dryrun', action='store_true', | |
metavar='DRYRUN', default=False, | |
help='Only perform a dry run, do not submit the action') | |
return parser.parse_args(argv) | |
def main(): | |
options = parse_options(sys.argv[1:])[0] | |
for field in ('server', 'action', 'hmac', 'email', 'url', 'shortcut_name'): | |
if getattr(options, field, None) is None: | |
print '%s not set' % field | |
return | |
request_url = make_request_uri( | |
options.server, | |
options.action, | |
options.hmac, | |
user=options.email, | |
url=options.url, | |
shortcut=options.shortcut_name, | |
is_public=str(options.is_public).lower()) | |
if options.dryrun: | |
print 'Request URL is %s' % request_url | |
else: | |
print 'Connecting to %s...' % options.server | |
print '(full request url is %s )' % request_url | |
response = urllib2.urlopen(request_url) | |
print 'result: %s' % response.read() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment