Refactored Google plugins with support multiple scopes and a simpler API and added Google Fit plugin
This commit is contained in:
parent
022262eb78
commit
55c0896b31
6 changed files with 84 additions and 50 deletions
|
@ -33,7 +33,7 @@ class GooglePlugin(Plugin):
|
|||
* **google-api-python-client** (``pip install google-api-python-client``)
|
||||
"""
|
||||
|
||||
def __init__(self, scopes, *args, **kwargs):
|
||||
def __init__(self, scopes=None, *args, **kwargs):
|
||||
"""
|
||||
Initialized the Google plugin with the required scopes.
|
||||
|
||||
|
@ -42,11 +42,25 @@ class GooglePlugin(Plugin):
|
|||
"""
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
self.credentials = {}
|
||||
self._scopes = scopes or []
|
||||
|
||||
for scope in scopes:
|
||||
self.credentials[scope] = get_credentials(scope)
|
||||
scopes = ' '.join(sorted(self._scopes))
|
||||
self.credentials = {
|
||||
scopes: get_credentials(scopes)
|
||||
}
|
||||
|
||||
|
||||
def get_service(self, service, version, scopes=None):
|
||||
import httplib2
|
||||
from apiclient import discovery
|
||||
|
||||
if scopes is None:
|
||||
scopes = getattr(self, 'scopes') if hasattr(self, 'scopes') else []
|
||||
|
||||
scopes = ' '.join(sorted(scopes))
|
||||
credentials = self.credentials[scopes]
|
||||
http = credentials.authorize(httplib2.Http())
|
||||
return discovery.build(service, version, http=http, cache_discovery=False)
|
||||
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
||||
|
||||
|
|
|
@ -4,11 +4,8 @@
|
|||
|
||||
import base64
|
||||
import datetime
|
||||
import httplib2
|
||||
import os
|
||||
|
||||
from apiclient import discovery
|
||||
|
||||
from platypush.plugins import action
|
||||
from platypush.plugins.google import GooglePlugin
|
||||
from platypush.plugins.calendar import CalendarInterface
|
||||
|
@ -33,7 +30,7 @@ class GoogleCalendarPlugin(GooglePlugin, CalendarInterface):
|
|||
"""
|
||||
|
||||
now = datetime.datetime.utcnow().isoformat() + 'Z'
|
||||
service = self._get_service()
|
||||
service = self.get_service('calendar', 'v3')
|
||||
result = service.events().list(calendarId='primary', timeMin=now,
|
||||
maxResults=max_results, singleEvents=True,
|
||||
orderBy='startTime').execute()
|
||||
|
@ -42,14 +39,5 @@ class GoogleCalendarPlugin(GooglePlugin, CalendarInterface):
|
|||
return events
|
||||
|
||||
|
||||
def _get_service(self, scope=None):
|
||||
if scope is None:
|
||||
scope = self.scopes[0]
|
||||
|
||||
credentials = self.credentials[scope]
|
||||
http = credentials.authorize(httplib2.Http())
|
||||
return discovery.build('calendar', 'v3', http=http, cache_discovery=False)
|
||||
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
||||
|
||||
|
|
|
@ -8,21 +8,19 @@ from oauth2client import tools
|
|||
from oauth2client.file import Storage
|
||||
|
||||
|
||||
def get_credentials_filename(scope):
|
||||
def get_credentials_filename(*scopes):
|
||||
from platypush.config import Config
|
||||
|
||||
scope_name = scope.split('/')[-1]
|
||||
scope_name = '-'.join([scope.split('/')[-1] for scope in scopes])
|
||||
credentials_dir = os.path.join(
|
||||
Config.get('workdir'), 'credentials', 'google')
|
||||
|
||||
if not os.path.exists(credentials_dir):
|
||||
os.makedirs(credentials_dir)
|
||||
|
||||
os.makedirs(credentials_dir, exist_ok=True)
|
||||
return os.path.join(credentials_dir, scope_name + '.json')
|
||||
|
||||
|
||||
def get_credentials(scope):
|
||||
credentials_file = get_credentials_filename(scope)
|
||||
credentials_file = get_credentials_filename(*sorted(scope.split(' ')))
|
||||
if not os.path.exists(credentials_file):
|
||||
raise RuntimeError(('Credentials file {} not found. Generate it through:\n' +
|
||||
'\tpython -m platypush.plugins.google.credentials "{}" ' +
|
||||
|
@ -43,7 +41,7 @@ def get_credentials(scope):
|
|||
|
||||
|
||||
def generate_credentials(client_secret_path, scope):
|
||||
credentials_file = get_credentials_filename(scope)
|
||||
credentials_file = get_credentials_filename(*sorted(scope.split(' ')))
|
||||
store = Storage(credentials_file)
|
||||
|
||||
flow = client.flow_from_clientsecrets(client_secret_path, scope)
|
||||
|
@ -62,7 +60,7 @@ def main():
|
|||
"""
|
||||
|
||||
scope = sys.argv.pop(1) if len(sys.argv) > 1 \
|
||||
else input('Comma separated list of OAuth scopes: ')
|
||||
else input('Space separated list of OAuth scopes: ')
|
||||
|
||||
client_secret_path = os.path.expanduser(
|
||||
sys.argv.pop(1) if len(sys.argv) > 1
|
||||
|
|
55
platypush/plugins/google/fit.py
Normal file
55
platypush/plugins/google/fit.py
Normal file
|
@ -0,0 +1,55 @@
|
|||
from apiclient import discovery
|
||||
|
||||
from platypush.plugins import action
|
||||
from platypush.plugins.google import GooglePlugin
|
||||
|
||||
|
||||
class GoogleFitPlugin(GooglePlugin):
|
||||
"""
|
||||
Google Fit plugin
|
||||
"""
|
||||
|
||||
scopes = ['https://www.googleapis.com/auth/fitness.activity.read',
|
||||
'https://www.googleapis.com/auth/fitness.body.read',
|
||||
'https://www.googleapis.com/auth/fitness.body_temperature.read',
|
||||
'https://www.googleapis.com/auth/fitness.location.read']
|
||||
|
||||
def __init__(self, user_id='me', *args, **kwargs):
|
||||
"""
|
||||
:param user_id: Default Google user_id (default: 'me', default
|
||||
configured account user)
|
||||
:type user_id: str or int
|
||||
"""
|
||||
|
||||
super().__init__(scopes=self.scopes, *args, **kwargs)
|
||||
self.user_id = user_id
|
||||
|
||||
|
||||
@action
|
||||
def get_data_sources(self, user_id=None):
|
||||
"""
|
||||
Get the available data sources for the specified user_id
|
||||
"""
|
||||
|
||||
service = self.get_service(service='fitness', version='v1')
|
||||
sources = service.users().dataSources(). \
|
||||
list(userId=user_id or self.user_id).execute()
|
||||
|
||||
return sources['dataSource']
|
||||
|
||||
@action
|
||||
def get_data(self, data_source_id, user_id=None):
|
||||
"""
|
||||
Get raw data for the specified data_source_id
|
||||
|
||||
:param data_source_id: Data source ID, see `get_data_sources`
|
||||
:type data_source_id: str
|
||||
"""
|
||||
|
||||
service = self.get_service(service='fitness', version='v1')
|
||||
return service.users().dataSources().dataPointChanges() \
|
||||
.list(dataSourceId=data_source_id, userId=user_id or self.user_id) \
|
||||
.execute().get('insertedDataPoint', [])
|
||||
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
|
@ -87,7 +87,7 @@ class GoogleMailPlugin(GooglePlugin):
|
|||
msg.add_header('Content-Disposition', 'attachment', filename=filename)
|
||||
message.attach(msg)
|
||||
|
||||
service = self._get_service()
|
||||
service = self.get_service('gmail', 'v1')
|
||||
body = { 'raw': base64.urlsafe_b64encode(message.as_bytes()).decode() }
|
||||
message = (service.users().messages().send(
|
||||
userId='me', body=body).execute())
|
||||
|
@ -100,18 +100,10 @@ class GoogleMailPlugin(GooglePlugin):
|
|||
"""
|
||||
Returns the available labels on the GMail account
|
||||
"""
|
||||
service = self._get_service()
|
||||
service = self.get_service('gmail', 'v1')
|
||||
results = service.users().labels().list(userId='me').execute()
|
||||
labels = results.get('labels', [])
|
||||
return labels
|
||||
|
||||
|
||||
def _get_service(self):
|
||||
scope = self.scopes[0]
|
||||
credentials = self.credentials[scope]
|
||||
http = credentials.authorize(httplib2.Http())
|
||||
return discovery.build('gmail', 'v1', http=http, cache_discovery=False)
|
||||
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
||||
|
||||
|
|
|
@ -4,11 +4,8 @@
|
|||
|
||||
import base64
|
||||
import datetime
|
||||
import httplib2
|
||||
import os
|
||||
|
||||
from apiclient import discovery
|
||||
|
||||
from platypush.plugins import action
|
||||
from platypush.plugins.google import GooglePlugin
|
||||
from platypush.plugins.calendar import CalendarInterface
|
||||
|
@ -62,7 +59,7 @@ class GoogleYoutubePlugin(GooglePlugin, CalendarInterface):
|
|||
if isinstance(types, list):
|
||||
types = ','.join(types)
|
||||
|
||||
service = self._get_service()
|
||||
service = self.get_service('youtube', 'v3')
|
||||
result = service.search().list(part=parts, q=query, type=types,
|
||||
maxResults=max_results,
|
||||
**kwargs).execute()
|
||||
|
@ -71,14 +68,4 @@ class GoogleYoutubePlugin(GooglePlugin, CalendarInterface):
|
|||
return events
|
||||
|
||||
|
||||
def _get_service(self, scope=None):
|
||||
if scope is None:
|
||||
scope = self.scopes[0]
|
||||
|
||||
credentials = self.credentials[scope]
|
||||
http = credentials.authorize(httplib2.Http())
|
||||
return discovery.build('youtube', 'v3', http=http, cache_discovery=False)
|
||||
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
||||
|
||||
|
|
Loading…
Reference in a new issue