__author__ = 'keaj'

from __future__ import unicode_literals

import base64
import httplib2
import json
import os
import re

from apiclient import discovery
from oauth2client import client


class NoSuchBook(Exception):
    pass


class GoogleBooksService(object):
    def __init__(self):
        super(GoogleBooksService, self).__init__()
        self._credentials = None
        self.loadCredentialsAndAuthorize()

    def loadCredentialsAndAuthorize(self):
        try:
            key = base64.b64decode(os.environ['GBOOKS_PK'])
            credinfo = json.loads(os.environ['BOOK_SERVICE'])

        except KeyError as e:
            with open('config/apiconfig.settings','r') as f:
                apisettings = f.readlines()
                for n in apisettings:
                    k,v=n.split('=',1)
                    os.environ[k]=v
            with open('config/google_api_key','r') as rsa:
                os.environ['GBOOKS_PK']=base64.b64encode(rsa.read())
            key = base64.b64decode(os.environ['GBOOKS_PK'])
            credinfo = json.loads(os.environ['BOOK_SERVICE'])

        scope = [
                'https://www.googleapis.com/auth/books',
                 ]
        self._credentials = client.SignedJwtAssertionCredentials(
            credinfo['web']['client_email'], key, scope,
            private_key_password='notasecret')
        http = httplib2.Http()
        self._httpClient = self._credentials.authorize(http)
        self._service = discovery.build('books', 'v1', http=self._httpClient)

    def recordToSerializable(self, record):
        try:
            record = record['items'][0]
        except KeyError:
            raise NoSuchBook
        qdict = {}
        volumeInfo = record['volumeInfo']
        #how to handle it if publisher and title are missing?
        qdict['publisher']=volumeInfo['publisher']
        author = "&".join([authors for authors in volumeInfo['authors']])
        qdict['author']=author
        title = volumeInfo['title']
        subt = ""
        try:
            subt = volumeInfo['subtitle']
        except KeyError:
            pass
            #swallow the exception
        title = ":".join([title,subt]) if subt else title
        qdict['title']=title
        date = volumeInfo['publishedDate'].encode('utf-8')
        if re.match(r'[0-9]{4}-[0-9]{2}-[0-9]{2}',date):
            qdict['publish_date'] = date.split('-')[0]
        else:
            qdict['publish_date']=int(volumeInfo['publishedDate'])
        for a in volumeInfo['industryIdentifiers'] :
            if a['type']=='ISBN_13':
                qdict['isbn_13']=a['identifier']
            elif a['type']=='ISBN_10':
                qdict['isbn_10']=a['identifier']
        qdict['description']=volumeInfo.get('description',"")
        qdict['genre'] = "&".join([a for a in record['volumeInfo']['categories']])
        return qdict

    def getByISBN(self, isbn):
        isbn = isbn.replace("-", '')
        if self._service:
            bookrecord = self._service.volumes().list(q="isbn:%s" % isbn).execute()
            return self.recordToSerializable(bookrecord)

@@ -1678,26 +1678,8 @@
 ook%0A
-        qdict = %7B%7D
 %0A   
@@ -1729,61 +1729,534 @@
     
-#how to handle it if publisher and title are missing?
+requiredFields = ('industryIndentifiers','title')%0A        if any(field not in volumeInfo for field in requiredFields):%0A            # yes, some records are missing these!%0A            # we'll treat them as flat-out broken.%0A            raise NoSuchBook%0A        if set('ISBN_10','ISBN_13').isdisjoint(%0A                set(identifier%5B'type'%5D%0A                for identifier in volumeInfo%5B'industryIdentifiers'%5D)):%0A            # just in case there are industryIdentifiers but no ISBNs%0A            raise NoSuchBook%0A%0A        qdict = %7B%7D
 %0A   
@@ -2281,33 +2281,37 @@
 her'%5D=volumeInfo
-%5B
+.get(
 'publisher'%5D%0A   
@@ -2305,17 +2305,20 @@
 blisher'
-%5D
+,'')
 %0A       
@@ -2370,17 +2370,21 @@
 lumeInfo
-%5B
+.get(
 'authors
@@ -2384,17 +2384,20 @@
 authors'
-%5D
+,%5B%5D)
 %5D)%0A     
@@ -2476,43 +2476,8 @@
 bt =
- %22%22%0A        try:%0A            subt =
  vol
@@ -2483,17 +2483,21 @@
 lumeInfo
-%5B
+.get(
 'subtitl
@@ -2502,86 +2502,12 @@
 tle'
-%5D%0A        except KeyError:%0A            pass%0A            #swallow the exception
+,'')
 %0A   
@@ -2521,16 +2521,17 @@
 tle = %22:
+ 
 %22.join(%5B
@@ -2587,24 +2587,71 @@
 tle'%5D=title%0A
+%0A        if 'publishedDate' in volumeInfo:%0A    
         date
@@ -2684,25 +2684,13 @@
 te'%5D
-.encode('utf-8')%0A
+%0A    
     
@@ -2758,131 +2758,373 @@
     
-qdict%5B'publish_date'%5D = date.split('-')%5B0%5D%0A        else:%0A            qdict%5B'publish_date'%5D=int(volumeInfo%5B'publish
+    cleanedDate = date.split('-')%5B0%5D%0A            elif re.match(r'%5B0-9%5D%7B4%7D-%5B0-9%5D%7B2%7D', date):%0A                cleanedDate = date.split('-')%5B0%5D%0A            elif re.match(r'%5B0-9%5D%7B4%7D', date):%0A                cleanedDate = date%0A            else:%0A                raise ValueError('Unsupported publish date type: %25s' %25 date)%0A            qdict%5B'publish_date'%5D = clean
 edDate
-'%5D)
+%0A
 %0A   
@@ -3170,17 +3170,16 @@
 ifiers'%5D
- 
 :%0A      
@@ -3408,16 +3408,59 @@
 on',%22%22)%0A
+        if 'categories' in volumeInfo:%0A    
         
@@ -3497,24 +3497,16 @@
 or a in 
-record%5B'
 volumeIn
@@ -3507,18 +3507,16 @@
 lumeInfo
-'%5D
 %5B'catego

deal with missing or badly formatted data