Skip to content

Instantly share code, notes, and snippets.

@dlanger
Created August 1, 2013 15:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dlanger/6132351 to your computer and use it in GitHub Desktop.
Save dlanger/6132351 to your computer and use it in GitHub Desktop.
#!/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 owner@example.com:
python api_sample.py
--create
--server=shortlinks.example.com
--hmac=foobar
--email=owner@example.com
--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 owner@example.com:
python api_sample.py
--hash
--server=shortlinks.example.com
--hmac=foobar
--email=owner@example.com
--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