3 # Copyright (C) 2012 FinalsClub Foundation
11 from apiclient.discovery import build
12 from apiclient.http import MediaFileUpload
13 from django.conf import settings
14 from oauth2client.client import flow_from_clientsecrets
16 from karmaworld.apps.notes.models import DriveAuth, Note
18 CLIENT_SECRET = os.path.join(settings.DJANGO_ROOT, \
19 'secret/client_secrets.json')
20 #from credentials import GOOGLE_USER # FIXME
22 from secrets.drive import GOOGLE_USER
24 GOOGLE_USER = 'admin@karmanotes.org' # FIXME
26 EXT_TO_MIME = {'.docx': 'application/msword'}
29 """ Create an oauth2 autentication object with our preferred details """
31 'https://www.googleapis.com/auth/drive',
32 'https://www.googleapis.com/auth/drive.file',
33 'https://www.googleapis.com/auth/userinfo.email',
34 'https://www.googleapis.com/auth/userinfo.profile',
37 flow = flow_from_clientsecrets(CLIENT_SECRET, ' '.join(scopes), \
38 redirect_uri='http://localhost:8000/oauth2callback')
39 flow.params['access_type'] = 'offline'
40 flow.params['approval_prompt'] = 'force'
41 flow.params['user_id'] = GOOGLE_USER
46 """ Use an oauth2client flow object to generate the web url to create a new
47 auth that can be then stored """
49 print flow.step1_get_authorize_url()
52 def accept_auth(code):
53 """ Callback endpoint for accepting the post `authorize()` google drive
54 response, and generate a credentials object
55 :code: An authentication token from a WEB oauth dialog
56 returns a oauth2client credentials object """
58 creds = flow.step2_exchange(code)
62 def build_api_service(creds):
63 http = httplib2.Http()
64 http = creds.authorize(http)
65 return build('drive', 'v2', http=http), http
68 def check_and_refresh(creds, auth):
69 """ Check a Credentials object's expiration token
70 if it is out of date, refresh the token and save
71 :creds: a Credentials object
72 :auth: a DriveAuth that backs the cred object
73 :returns: updated creds and auth objects
75 if creds.token_expiry < datetime.datetime.utcnow():
76 # if we are passed the token expiry,
77 # refresh the creds and store them
78 http = httplib2.Http()
79 http = creds.authorize(http)
81 auth.credentials = creds.to_json()
86 def convert_with_google_drive(note):
87 """ Upload a local note and download HTML
89 :note: a File model instance # FIXME
91 # TODO: set the permission of the file to permissive so we can use the
92 # gdrive_url to serve files directly to users
94 # Get file_type and encoding of uploaded file
95 # i.e: file_type = 'text/plain', encoding = None
96 (file_type, encoding) = mimetypes.guess_type(note.note_file.path)
98 # If mimetype cannot be guessed
99 # Check against known issues, then
100 # finally, Raise Exception
101 # Extract file extension and compare it to EXT_TO_MIME dict
110 if file_type != None:
111 media = MediaFileUpload(note.note_file.path, mimetype=file_type,
112 chunksize=1024*1024, resumable=True)
115 media = MediaFileUpload(note.note_file.path,
116 chunksize=1024*1024, resumable=True)
118 auth = DriveAuth.objects.filter(email=GOOGLE_USER).all()[0]
119 creds = auth.transform_to_cred()
122 creds, auth = check_and_refresh(creds, auth)
124 service, http = build_api_service(creds)
126 # get the file extension
127 filename, extension = os.path.splitext(note.note_file.path)
129 if extension.lower() in ['.pdf', '.jpg', '.png']:
130 # include OCR on ocr-able files
131 file_dict = service.files().insert(body=resource, media_body=media, convert=True, ocr=True).execute()
133 file_dict = service.files().insert(body=resource, media_body=media, convert=True).execute()
135 if u'exportLinks' not in file_dict:
137 # get the doc from gdrive
139 file_dict = service.files().get(fileId=file_dict[u'id']).execute()
142 # get the converted filetype urls
144 download_urls['html'] = file_dict[u'exportLinks']['text/html']
145 download_urls['text'] = file_dict[u'exportLinks']['text/plain']
149 for download_type, download_url in download_urls.items():
150 print "\n%s -- %s" % (download_type, download_urls)
151 resp, content = http.request(download_url, "GET")
154 if resp.status in [200]:
155 print "\t downloaded!"
156 # save to the File.property resulting field
157 content_dict[download_type] = content
159 print "\t Download failed: %s" % resp.status
161 # Get a new copy of the file from the database with the new metadata from filemeta
162 new_note = Note.objects.get(id=note.id)
164 # set the .odt as the download from google link
165 new_note.gdrive_url = file_dict[u'exportLinks']['application/vnd.oasis.opendocument.text']
166 new_note.html = content_dict['html']
167 new_note.text = content_dict['text']
169 # Finally, save whatever data we got back from google