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``)
|
* **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.
|
Initialized the Google plugin with the required scopes.
|
||||||
|
|
||||||
|
@ -42,11 +42,25 @@ class GooglePlugin(Plugin):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.credentials = {}
|
self._scopes = scopes or []
|
||||||
|
|
||||||
for scope in scopes:
|
scopes = ' '.join(sorted(self._scopes))
|
||||||
self.credentials[scope] = get_credentials(scope)
|
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:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,8 @@
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import datetime
|
import datetime
|
||||||
import httplib2
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from apiclient import discovery
|
|
||||||
|
|
||||||
from platypush.plugins import action
|
from platypush.plugins import action
|
||||||
from platypush.plugins.google import GooglePlugin
|
from platypush.plugins.google import GooglePlugin
|
||||||
from platypush.plugins.calendar import CalendarInterface
|
from platypush.plugins.calendar import CalendarInterface
|
||||||
|
@ -33,7 +30,7 @@ class GoogleCalendarPlugin(GooglePlugin, CalendarInterface):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
now = datetime.datetime.utcnow().isoformat() + 'Z'
|
now = datetime.datetime.utcnow().isoformat() + 'Z'
|
||||||
service = self._get_service()
|
service = self.get_service('calendar', 'v3')
|
||||||
result = service.events().list(calendarId='primary', timeMin=now,
|
result = service.events().list(calendarId='primary', timeMin=now,
|
||||||
maxResults=max_results, singleEvents=True,
|
maxResults=max_results, singleEvents=True,
|
||||||
orderBy='startTime').execute()
|
orderBy='startTime').execute()
|
||||||
|
@ -42,14 +39,5 @@ class GoogleCalendarPlugin(GooglePlugin, CalendarInterface):
|
||||||
return events
|
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:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
|
@ -8,21 +8,19 @@ from oauth2client import tools
|
||||||
from oauth2client.file import Storage
|
from oauth2client.file import Storage
|
||||||
|
|
||||||
|
|
||||||
def get_credentials_filename(scope):
|
def get_credentials_filename(*scopes):
|
||||||
from platypush.config import Config
|
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(
|
credentials_dir = os.path.join(
|
||||||
Config.get('workdir'), 'credentials', 'google')
|
Config.get('workdir'), 'credentials', 'google')
|
||||||
|
|
||||||
if not os.path.exists(credentials_dir):
|
os.makedirs(credentials_dir, exist_ok=True)
|
||||||
os.makedirs(credentials_dir)
|
|
||||||
|
|
||||||
return os.path.join(credentials_dir, scope_name + '.json')
|
return os.path.join(credentials_dir, scope_name + '.json')
|
||||||
|
|
||||||
|
|
||||||
def get_credentials(scope):
|
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):
|
if not os.path.exists(credentials_file):
|
||||||
raise RuntimeError(('Credentials file {} not found. Generate it through:\n' +
|
raise RuntimeError(('Credentials file {} not found. Generate it through:\n' +
|
||||||
'\tpython -m platypush.plugins.google.credentials "{}" ' +
|
'\tpython -m platypush.plugins.google.credentials "{}" ' +
|
||||||
|
@ -43,7 +41,7 @@ def get_credentials(scope):
|
||||||
|
|
||||||
|
|
||||||
def generate_credentials(client_secret_path, 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)
|
store = Storage(credentials_file)
|
||||||
|
|
||||||
flow = client.flow_from_clientsecrets(client_secret_path, scope)
|
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 \
|
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(
|
client_secret_path = os.path.expanduser(
|
||||||
sys.argv.pop(1) if len(sys.argv) > 1
|
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)
|
msg.add_header('Content-Disposition', 'attachment', filename=filename)
|
||||||
message.attach(msg)
|
message.attach(msg)
|
||||||
|
|
||||||
service = self._get_service()
|
service = self.get_service('gmail', 'v1')
|
||||||
body = { 'raw': base64.urlsafe_b64encode(message.as_bytes()).decode() }
|
body = { 'raw': base64.urlsafe_b64encode(message.as_bytes()).decode() }
|
||||||
message = (service.users().messages().send(
|
message = (service.users().messages().send(
|
||||||
userId='me', body=body).execute())
|
userId='me', body=body).execute())
|
||||||
|
@ -100,18 +100,10 @@ class GoogleMailPlugin(GooglePlugin):
|
||||||
"""
|
"""
|
||||||
Returns the available labels on the GMail account
|
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()
|
results = service.users().labels().list(userId='me').execute()
|
||||||
labels = results.get('labels', [])
|
labels = results.get('labels', [])
|
||||||
return 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:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,8 @@
|
||||||
|
|
||||||
import base64
|
import base64
|
||||||
import datetime
|
import datetime
|
||||||
import httplib2
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from apiclient import discovery
|
|
||||||
|
|
||||||
from platypush.plugins import action
|
from platypush.plugins import action
|
||||||
from platypush.plugins.google import GooglePlugin
|
from platypush.plugins.google import GooglePlugin
|
||||||
from platypush.plugins.calendar import CalendarInterface
|
from platypush.plugins.calendar import CalendarInterface
|
||||||
|
@ -62,7 +59,7 @@ class GoogleYoutubePlugin(GooglePlugin, CalendarInterface):
|
||||||
if isinstance(types, list):
|
if isinstance(types, list):
|
||||||
types = ','.join(types)
|
types = ','.join(types)
|
||||||
|
|
||||||
service = self._get_service()
|
service = self.get_service('youtube', 'v3')
|
||||||
result = service.search().list(part=parts, q=query, type=types,
|
result = service.search().list(part=parts, q=query, type=types,
|
||||||
maxResults=max_results,
|
maxResults=max_results,
|
||||||
**kwargs).execute()
|
**kwargs).execute()
|
||||||
|
@ -71,14 +68,4 @@ class GoogleYoutubePlugin(GooglePlugin, CalendarInterface):
|
||||||
return events
|
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:
|
# vim:sw=4:ts=4:et:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue