Merge pull request #410 from danoscarmike/master

Add notification of maintenance mode
diff --git a/googleapiclient/errors.py b/googleapiclient/errors.py
index 6a741f8..bab1418 100644
--- a/googleapiclient/errors.py
+++ b/googleapiclient/errors.py
@@ -46,6 +46,7 @@
         raise TypeError("HTTP content should be bytes")
     self.content = content
     self.uri = uri
+    self.error_details = ''
 
   def _get_reason(self):
     """Calculate the reason for the error from the response content."""
@@ -54,9 +55,13 @@
       data = json.loads(self.content.decode('utf-8'))
       if isinstance(data, dict):
         reason = data['error']['message']
+        if 'details' in data['error']:
+            self.error_details = data['error']['details']
       elif isinstance(data, list) and len(data) > 0:
         first_error = data[0]
         reason = first_error['error']['message']
+        if 'details' in first_error['error']:
+            self.error_details = first_error['error']['details']
     except (ValueError, KeyError, TypeError):
       pass
     if reason is None:
@@ -64,7 +69,11 @@
     return reason
 
   def __repr__(self):
-    if self.uri:
+    reason = self._get_reason()
+    if self.error_details:
+      return '<HttpError %s when requesting %s returned "%s". Details: "%s">' % \
+             (self.resp.status, self.uri, reason.strip(), self.error_details)
+    elif self.uri:
       return '<HttpError %s when requesting %s returned "%s">' % (
           self.resp.status, self.uri, self._get_reason().strip())
     else:
diff --git a/samples/django_sample/Makefile b/samples/django_sample/Makefile
new file mode 100644
index 0000000..35d29f0
--- /dev/null
+++ b/samples/django_sample/Makefile
@@ -0,0 +1,21 @@
+pip: 
+	@pip install -r requirements.txt
+
+
+syncdb:
+	@python manage.py syncdb
+
+
+run: 
+	@python manage.py runserver 0.0.0.0:8000
+
+
+setup: pip syncdb run
+
+
+shell: 
+	@python manage.py shell
+
+
+test:
+	@python manage.py test
diff --git a/samples/django_sample/manage.py b/samples/django_sample/manage.py
index b2f07f1..4146caa 100755
--- a/samples/django_sample/manage.py
+++ b/samples/django_sample/manage.py
@@ -2,7 +2,7 @@
 from __future__ import absolute_import
 from django.core.management import execute_manager
 try:
-    from . import settings # Assumed to be in the same directory.
+    import settings # Assumed to be in the same directory.
 except ImportError:
     import sys
     sys.stderr.write("""Error: Can't find the file 'settings.py' in the
diff --git a/samples/django_sample/plus/models.py b/samples/django_sample/plus/models.py
index 6b9f762..46a0225 100644
--- a/samples/django_sample/plus/models.py
+++ b/samples/django_sample/plus/models.py
@@ -1,12 +1,8 @@
-import pickle
-import base64
-
 from django.contrib import admin
 from django.contrib.auth.models import User
 from django.db import models
 
-from oauth2client.contrib.django_orm import FlowField
-from oauth2client.contrib.django_orm import CredentialsField
+from oauth2client.contrib.django_util.models import CredentialsField
 
 
 class CredentialsModel(models.Model):
@@ -16,6 +12,3 @@
 
 class CredentialsAdmin(admin.ModelAdmin):
     pass
-
-
-admin.site.register(CredentialsModel, CredentialsAdmin)
diff --git a/samples/django_sample/plus/views.py b/samples/django_sample/plus/views.py
index 979c2b0..bc45461 100644
--- a/samples/django_sample/plus/views.py
+++ b/samples/django_sample/plus/views.py
@@ -4,8 +4,6 @@
 
 from googleapiclient.discovery import build
 from django.contrib.auth.decorators import login_required
-from django.core.urlresolvers import reverse
-from django.http import HttpResponse
 from django.http import HttpResponseBadRequest
 from django.http import HttpResponseRedirect
 from django.shortcuts import render
@@ -13,23 +11,22 @@
 from django_sample import settings
 from oauth2client.contrib import xsrfutil
 from oauth2client.client import flow_from_clientsecrets
-from oauth2client.contrib.django_orm import Storage
+from oauth2client.contrib.django_util.storage import DjangoORMStorage
 
 # CLIENT_SECRETS, name of a file containing the OAuth 2.0 information for this
 # application, including client_id and client_secret, which are found
 # on the API Access tab on the Google APIs
 # Console <http://code.google.com/apis/console>
-CLIENT_SECRETS = os.path.join(os.path.dirname(__file__), '..', 'client_secrets.json')
 
 FLOW = flow_from_clientsecrets(
-    CLIENT_SECRETS,
+    settings.GOOGLE_OAUTH2_CLIENT_SECRETS_JSON,
     scope='https://www.googleapis.com/auth/plus.me',
     redirect_uri='http://localhost:8000/oauth2callback')
 
 
 @login_required
 def index(request):
-  storage = Storage(CredentialsModel, 'id', request.user, 'credential')
+  storage = DjangoORMStorage(CredentialsModel, 'id', request.user, 'credential')
   credential = storage.get()
   if credential is None or credential.invalid == True:
     FLOW.params['state'] = xsrfutil.generate_token(settings.SECRET_KEY,
@@ -56,6 +53,6 @@
                                  request.user):
     return  HttpResponseBadRequest()
   credential = FLOW.step2_exchange(request.REQUEST)
-  storage = Storage(CredentialsModel, 'id', request.user, 'credential')
+  storage = DjangoORMStorage(CredentialsModel, 'id', request.user, 'credential')
   storage.put(credential)
   return HttpResponseRedirect("/")
diff --git a/samples/django_sample/requirements.txt b/samples/django_sample/requirements.txt
new file mode 100644
index 0000000..01ff083
--- /dev/null
+++ b/samples/django_sample/requirements.txt
@@ -0,0 +1,11 @@
+Django==1.3
+google-api-python-client==1.6.2
+httplib2==0.10.3
+jsonpickle==0.9.4
+oauth2client==4.1.2
+pyasn1==0.2.3
+pyasn1-modules==0.0.9
+pytz==2017.2
+rsa==3.4.2
+six==1.10.0
+uritemplate==3.0.0
diff --git a/samples/django_sample/settings.py b/samples/django_sample/settings.py
index ceb4b29..76a16a8 100644
--- a/samples/django_sample/settings.py
+++ b/samples/django_sample/settings.py
@@ -79,5 +79,7 @@
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.sites',
-    'django_sample.plus'
+    'plus'
 )
+
+GOOGLE_OAUTH2_CLIENT_SECRETS_JSON = 'client_secrets.json'
diff --git a/tests/test_errors.py b/tests/test_errors.py
index 8a58030..e4d2f09 100644
--- a/tests/test_errors.py
+++ b/tests/test_errors.py
@@ -41,7 +41,8 @@
    }
   ],
   "code": 400,
-  "message": "country is required"
+  "message": "country is required",
+  "details": "error details"
  }
 }
 """
@@ -61,7 +62,7 @@
         {'status':'400', 'content-type': 'application/json'},
         reason='Failed')
     error = HttpError(resp, content, uri='http://example.org')
-    self.assertEqual(str(error), '<HttpError 400 when requesting http://example.org returned "country is required">')
+    self.assertEqual(str(error), '<HttpError 400 when requesting http://example.org returned "country is required". Details: "error details">')
 
   def test_bad_json_body(self):
     """Test handling of bodies with invalid json."""