Add oauth2client as a completely separate library.

Reviewed in http://codereview.appspot.com/4630079/
diff --git a/MANIFEST_oauth2client.in b/MANIFEST_oauth2client.in
new file mode 100644
index 0000000..1e189f3
--- /dev/null
+++ b/MANIFEST_oauth2client.in
@@ -0,0 +1,7 @@
+recursive-include httplib2 *.py
+recursive-include simplejson *.py *.c
+recursive-include samples *.py *.png *.html *.yaml *.json
+include setup_utils.py
+include gflags.py
+include gflags_validators.py
+include README
diff --git a/Makefile b/Makefile
index e88e4d1..6c08a9a 100644
--- a/Makefile
+++ b/Makefile
@@ -30,3 +30,32 @@
 	wget "http://support.googlecode.com/svn/trunk/scripts/googlecode_upload.py" -O googlecode_upload.py
 	python googlecode_upload.py --summary="Version $(shell python setup.py --version)" --project=google-api-python-client snapshot/dist/*.tar.gz
 	python googlecode_upload.py --summary="Version $(shell python setup.py --version)" --project=google-api-python-client snapshot/dist/*.zip
+
+
+.PHONY: oauth2_prerelease
+oauth2_prerelease:
+	-sudo rm -rf dist/
+	-sudo rm -rf snapshot/
+	mkdir snapshot
+	python expand-symlinks.py --source=oauth2client --dest=snapshot/oauth2client
+	python expand-symlinks.py --source=samples/oauth2/dailymotion --dest=snapshot/samples/dailymotion
+	python expand-symlinks.py --source=samples/appengine_with_decorator --dest=snapshot/samples/appengine_with_decorator
+	python expand-symlinks.py --source=samples/appengine_with_decorator2 --dest=snapshot/samples/appengine_with_decorator2
+	python expand-symlinks.py --source=samples/appengine --dest=snapshot/samples/appengine
+	cp setup_oauth2client.py snapshot/setup.py
+	cp setup_utils.py snapshot/setup_utils.py
+	cp MANIFEST_oauth2client.in snapshot/MANIFEST.in
+	cp README_oauth2client snapshot/README
+	cd snapshot; python setup.py clean
+	cd snapshot; python setup.py sdist --formats=gztar,zip
+
+.PHONY: oauth2_release
+oauth2_release: oauth2_prerelease
+	@echo "This target will upload a new release to PyPi and code.google.com hosting."
+	@echo "Are you sure you want to proceed? (yes/no)"
+	@read yn; [ "yes" == $$yn ]
+	@echo "Here we go..."
+	cd snapshot; python setup.py sdist --formats=gztar,zip register upload
+	wget "http://support.googlecode.com/svn/trunk/scripts/googlecode_upload.py" -O googlecode_upload.py
+	python googlecode_upload.py --summary="Version $(shell python setup.py --version)" --project=google-api-python-client snapshot/dist/*.tar.gz
+	python googlecode_upload.py --summary="Version $(shell python setup.py --version)" --project=google-api-python-client snapshot/dist/*.zip
diff --git a/README_oauth2client b/README_oauth2client
new file mode 100644
index 0000000..857613b
--- /dev/null
+++ b/README_oauth2client
@@ -0,0 +1,31 @@
+This is a client library for accessing resources protected by OAuth 2.0.
+
+
+Installation
+============
+
+To install, simply say
+
+   $ python setup.py install
+
+If you want to do a "mock install" and simply extend your PYTHONPATH
+for the current shell to include this folder and the packages in it, do
+
+   $ source setpath.sh
+
+from the root of the project directory.
+
+
+
+Third Party Libraries
+=====================
+
+These libraries will be installed when you install the client library:
+
+http://code.google.com/p/httplib2
+http://code.google.com/p/python-gflags
+
+Depending on your version of Python, these libraries may also be installed:
+
+http://pypi.python.org/pypi/simplejson/
+
diff --git a/expand-symlinks.py b/expand-symlinks.py
index 29535d6..73d2bdd 100644
--- a/expand-symlinks.py
+++ b/expand-symlinks.py
@@ -1,3 +1,45 @@
+#!/usr/bin/python2.4
+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2010 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.
+
+"""Copy files from source to dest expanding symlinks along the way.
+"""
+
 from distutils.dir_util import copy_tree
 
-copy_tree('.', 'snapshot', verbose=True)
+import gflags
+import sys
+
+
+FLAGS = gflags.FLAGS
+
+gflags.DEFINE_string('source', '.', 'Directory name to copy from.')
+gflags.DEFINE_string('dest', 'snapshot', 'Directory name to copy to.')
+
+
+def main(argv):
+  # Let the gflags module process the command-line arguments
+  try:
+    argv = FLAGS(argv)
+  except gflags.FlagsError, e:
+    print '%s\\nUsage: %s ARGS\\n%s' % (e, argv[0], FLAGS)
+    sys.exit(1)
+
+  copy_tree(FLAGS.source, FLAGS.dest, verbose=True)
+
+
+if __name__ == '__main__':
+  main(sys.argv)
diff --git a/samples/appengine/main.py b/samples/appengine/main.py
index 087a136..184f5fa 100755
--- a/samples/appengine/main.py
+++ b/samples/appengine/main.py
@@ -36,6 +36,16 @@
 from google.appengine.ext.webapp.util import login_required
 
 
+FLOW = OAuth2WebServerFlow(
+    # Visit https://code.google.com/apis/console to
+    # generate your client_id, client_secret and to
+    # register your redirect_uri.
+    client_id='<YOUR CLIENT ID HERE>',
+    client_secret='<YOUR CLIENT SECRET HERE>',
+    scope='https://www.googleapis.com/auth/buzz',
+    user_agent='buzz-cmdline-sample/1.0')
+
+
 class Credentials(db.Model):
   credentials = CredentialsProperty()
 
@@ -49,20 +59,9 @@
         Credentials, user.user_id(), 'credentials').get()
 
     if credentials is None or credentials.invalid == True:
-      flow = OAuth2WebServerFlow(
-          # Visit https://code.google.com/apis/console to
-          # generate your client_id, client_secret and to
-          # register your redirect_uri.
-          client_id='<YOUR CLIENT ID HERE>',
-          client_secret='<YOUR CLIENT SECRET HERE>',
-          scope='https://www.googleapis.com/auth/buzz',
-          user_agent='buzz-cmdline-sample/1.0',
-          domain='anonymous',
-          xoauth_displayname='Google App Engine Example App')
-
-      callback = self.request.relative_url('/auth_return')
-      authorize_url = flow.step1_get_authorize_url(callback)
-      memcache.set(user.user_id(), pickle.dumps(flow))
+      callback = self.request.relative_url('/oauth2callback')
+      authorize_url = FLOW.step1_get_authorize_url(callback)
+      memcache.set(user.user_id(), pickle.dumps(FLOW))
       self.redirect(authorize_url)
     else:
       http = httplib2.Http()
@@ -99,7 +98,7 @@
   application = webapp.WSGIApplication(
       [
       ('/', MainHandler),
-      ('/auth_return', OAuthHandler)
+      ('/oauth2callback', OAuthHandler)
       ],
       debug=True)
   util.run_wsgi_app(application)
diff --git a/samples/oauth2/dailymotion/apiclient b/samples/oauth2/dailymotion/apiclient
deleted file mode 120000
index f53af07..0000000
--- a/samples/oauth2/dailymotion/apiclient
+++ /dev/null
@@ -1 +0,0 @@
-../../../apiclient/
\ No newline at end of file
diff --git a/samples/oauth2/dailymotion/main.py b/samples/oauth2/dailymotion/main.py
index c904e3b..1b75239 100644
--- a/samples/oauth2/dailymotion/main.py
+++ b/samples/oauth2/dailymotion/main.py
@@ -23,7 +23,6 @@
 import os
 import pickle
 
-from apiclient.discovery import build
 from oauth2client.appengine import CredentialsProperty
 from oauth2client.appengine import StorageByKeyName
 from oauth2client.client import OAuth2WebServerFlow
@@ -36,6 +35,16 @@
 from google.appengine.ext.webapp.util import login_required
 
 
+FLOW = OAuth2WebServerFlow(
+    client_id='2ad565600216d25d9cde',
+    client_secret='03b56df2949a520be6049ff98b89813f17b467dc',
+    scope='read',
+    user_agent='oauth2client-sample/1.0',
+    auth_uri='https://api.dailymotion.com/oauth/authorize',
+    token_uri='https://api.dailymotion.com/oauth/token'
+    )
+
+
 class Credentials(db.Model):
   credentials = CredentialsProperty()
 
@@ -49,37 +58,23 @@
         Credentials, user.user_id(), 'credentials').get()
 
     if credentials is None or credentials.invalid == True:
-      flow = OAuth2WebServerFlow(
-          client_id='2ad565600216d25d9cde',
-          client_secret='03b56df2949a520be6049ff98b89813f17b467dc',
-          scope='read',
-          user_agent='oauth2client-sample/1.0',
-          auth_uri='https://api.dailymotion.com/oauth/authorize',
-          token_uri='https://api.dailymotion.com/oauth/token'
-          )
-
       callback = self.request.relative_url('/auth_return')
-      authorize_url = flow.step1_get_authorize_url(callback)
-      memcache.set(user.user_id(), pickle.dumps(flow))
+      authorize_url = FLOW.step1_get_authorize_url(callback)
+      memcache.set(user.user_id(), pickle.dumps(FLOW))
       self.redirect(authorize_url)
     else:
       http = httplib2.Http()
-
-      resp, content1 = http.request('https://api.dailymotion.com/me?access_token=%s' %
-                   credentials.access_token)
-
       http = credentials.authorize(http)
-      resp, content2 = http.request('https://api.dailymotion.com/me')
+
+      resp, content = http.request('https://api.dailymotion.com/me')
 
       path = os.path.join(os.path.dirname(__file__), 'welcome.html')
       logout = users.create_logout_url('/')
-      self.response.out.write(
-          template.render(
-              path, {
-                  'content1': content1,
-                  'content2': content2,
-                  'logout': logout
-                  }))
+      variables = {
+          'content': content,
+          'logout': logout
+          }
+      self.response.out.write(template.render(path, variables))
 
 
 class OAuthHandler(webapp.RequestHandler):
diff --git a/samples/oauth2/dailymotion/welcome.html b/samples/oauth2/dailymotion/welcome.html
index 06fcb95..f86902f 100644
--- a/samples/oauth2/dailymotion/welcome.html
+++ b/samples/oauth2/dailymotion/welcome.html
@@ -8,9 +8,7 @@
   </head>
   <body>
     <p><a href="{{ logout }}">Logout</a></p>
-    <h2>First request with access_token in query parameter:</h2>
-    <pre>{{ content1 }} </pre>
-    <h2>Second request with access_token in header:</h2>
-    <pre>{{ content2 }} </pre>
+    <h2>Response body:</h2>
+    <pre>{{ content }} </pre>
   </body>
 </html>
diff --git a/samples/oauth2/django_sample/buzz/views.py b/samples/oauth2/django_sample/buzz/views.py
index c942aaf..9a051ea 100644
--- a/samples/oauth2/django_sample/buzz/views.py
+++ b/samples/oauth2/django_sample/buzz/views.py
@@ -16,22 +16,21 @@
 from django.shortcuts import render_to_response
 
 STEP2_URI = 'http://localhost:8000/auth_return'
-
+FLOW = OAuth2WebServerFlow(
+    client_id='837647042410.apps.googleusercontent.com',
+    client_secret='+SWwMCL9d8gWtzPRa1lXw5R8',
+    scope='https://www.googleapis.com/auth/buzz',
+    user_agent='buzz-django-sample/1.0',
+    )
 
 @login_required
 def index(request):
   storage = Storage(CredentialsModel, 'id', request.user, 'credential')
   credential = storage.get()
   if credential is None or credential.invalid == True:
-    flow = OAuth2WebServerFlow(
-        client_id='837647042410.apps.googleusercontent.com',
-        client_secret='+SWwMCL9d8gWtzPRa1lXw5R8',
-        scope='https://www.googleapis.com/auth/buzz',
-        user_agent='buzz-django-sample/1.0',
-        )
 
-    authorize_url = flow.step1_get_authorize_url(STEP2_URI)
-    f = FlowModel(id=request.user, flow=flow)
+    authorize_url = FLOW.step1_get_authorize_url(STEP2_URI)
+    f = FlowModel(id=request.user, flow=FLOW)
     f.save()
     return HttpResponseRedirect(authorize_url)
   else:
diff --git a/setpath.sh b/setpath.sh
index 45826d6..8fb8f1b 100644
--- a/setpath.sh
+++ b/setpath.sh
@@ -1 +1 @@
-export PYTHONPATH=`pwd`:$PYTHONPATH
+export PYTHONPATH=`pwd`:${PYTHONPATH}
diff --git a/setup.py b/setup.py
index 58827dc..db17fcb 100644
--- a/setup.py
+++ b/setup.py
@@ -79,7 +79,7 @@
       scripts=['bin/enable-app-engine-project'],
       license="Apache 2.0",
       keywords="google api client",
-      classifiers=['Development Status :: 3 - Alpha',
+      classifiers=['Development Status :: 4 - Beta',
                    'Intended Audience :: Developers',
                    'License :: OSI Approved :: Apache Software License',
                    'Operating System :: POSIX',