diff --git a/.gitignore b/.gitignore index 4d5002226a..2c46d0bb00 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ dist/ package.sh .pypirc platypush/backend/http/static/resources/* +docs/build diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000..74f7fb94a4 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = platypush +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000000..bdf32d7a7d --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,192 @@ +import os +import sys + +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = 'platypush' +copyright = '2018, BlackLight' +author = 'BlackLight' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.intersphinx', + 'sphinx.ext.todo', + 'sphinx.ext.imgmath', + 'sphinx.ext.ifconfig', + 'sphinx.ext.viewcode', + 'sphinx.ext.githubpages', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +# html_theme = 'alabaster' +html_theme = 'nature' + +html_domain_indices = True + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'platypushdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'platypush.tex', 'platypush Documentation', + 'BlackLight', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'platypush', 'platypush Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'platypush', 'platypush Documentation', + author, 'platypush', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} + +# -- Options for todo extension ---------------------------------------------- + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + +sys.path.insert(0, os.path.abspath('../..')) + +def skip(app, what, name, obj, skip, options): + if name == "__init__": + return False + return skip + +def setup(app): + app.connect("autodoc-skip-member", skip) + diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000000..9800dafb69 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,16 @@ +Platypush +######### + +.. toctree:: + :maxdepth: 3 + :caption: Contents: + + plugins + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/docs/source/platypush/plugins/assistant.google.pushtotalk.rst b/docs/source/platypush/plugins/assistant.google.pushtotalk.rst new file mode 100644 index 0000000000..19f03e1449 --- /dev/null +++ b/docs/source/platypush/plugins/assistant.google.pushtotalk.rst @@ -0,0 +1,8 @@ +``platypush.plugins.assistant.google.pushtotalk`` +================================================= + +.. automodule:: platypush.plugins.assistant.google.pushtotalk + :members: + + + diff --git a/docs/source/platypush/plugins/assistant.google.rst b/docs/source/platypush/plugins/assistant.google.rst new file mode 100644 index 0000000000..9b55254037 --- /dev/null +++ b/docs/source/platypush/plugins/assistant.google.rst @@ -0,0 +1,6 @@ +``platypush.plugins.assistant.google`` +====================================== + +.. automodule:: platypush.plugins.assistant.google + :members: + diff --git a/docs/source/platypush/plugins/calendar.ical.rst b/docs/source/platypush/plugins/calendar.ical.rst new file mode 100644 index 0000000000..b9cdd19b60 --- /dev/null +++ b/docs/source/platypush/plugins/calendar.ical.rst @@ -0,0 +1,6 @@ +``platypush.plugins.calendar.ical`` +====================================== + +.. automodule:: platypush.plugins.calendar.ical + :members: + diff --git a/docs/source/platypush/plugins/calendar.rst b/docs/source/platypush/plugins/calendar.rst new file mode 100644 index 0000000000..75db801536 --- /dev/null +++ b/docs/source/platypush/plugins/calendar.rst @@ -0,0 +1,6 @@ +``platypush.plugins.calendar`` +============================== + +.. automodule:: platypush.plugins.calendar + :members: + diff --git a/docs/source/platypush/plugins/camera.pi.rst b/docs/source/platypush/plugins/camera.pi.rst new file mode 100644 index 0000000000..a08a575f8c --- /dev/null +++ b/docs/source/platypush/plugins/camera.pi.rst @@ -0,0 +1,6 @@ +``platypush.plugins.camera.pi`` +====================================== + +.. automodule:: platypush.plugins.camera.pi + :members: + diff --git a/docs/source/platypush/plugins/db.rst b/docs/source/platypush/plugins/db.rst new file mode 100644 index 0000000000..93b8401323 --- /dev/null +++ b/docs/source/platypush/plugins/db.rst @@ -0,0 +1,6 @@ +``platypush.plugins.db`` +======================== + +.. automodule:: platypush.plugins.db + :members: + diff --git a/docs/source/platypush/plugins/google.calendar.rst b/docs/source/platypush/plugins/google.calendar.rst new file mode 100644 index 0000000000..4b4f14ebec --- /dev/null +++ b/docs/source/platypush/plugins/google.calendar.rst @@ -0,0 +1,6 @@ +``platypush.plugins.google.calendar`` +===================================== + +.. automodule:: platypush.plugins.google.calendar + :members: + diff --git a/docs/source/platypush/plugins/google.mail.rst b/docs/source/platypush/plugins/google.mail.rst new file mode 100644 index 0000000000..1b894036fc --- /dev/null +++ b/docs/source/platypush/plugins/google.mail.rst @@ -0,0 +1,6 @@ +``platypush.plugins.google.mail`` +================================= + +.. automodule:: platypush.plugins.google.mail + :members: + diff --git a/docs/source/platypush/plugins/google.maps.rst b/docs/source/platypush/plugins/google.maps.rst new file mode 100644 index 0000000000..c283c29f5d --- /dev/null +++ b/docs/source/platypush/plugins/google.maps.rst @@ -0,0 +1,6 @@ +``platypush.plugins.google.maps`` +================================= + +.. automodule:: platypush.plugins.google.maps + :members: + diff --git a/docs/source/platypush/plugins/google.rst b/docs/source/platypush/plugins/google.rst new file mode 100644 index 0000000000..27e12194ce --- /dev/null +++ b/docs/source/platypush/plugins/google.rst @@ -0,0 +1,7 @@ +``platypush.plugins.google`` +============================ + +.. automodule:: platypush.plugins.google + :members: + + diff --git a/docs/source/platypush/plugins/gpio.rst b/docs/source/platypush/plugins/gpio.rst new file mode 100644 index 0000000000..8de28ec6a7 --- /dev/null +++ b/docs/source/platypush/plugins/gpio.rst @@ -0,0 +1,6 @@ +``platypush.plugins.gpio`` +========================== + +.. automodule:: platypush.plugins.gpio + :members: + diff --git a/docs/source/plugins.rst b/docs/source/plugins.rst new file mode 100644 index 0000000000..6946b7f34d --- /dev/null +++ b/docs/source/plugins.rst @@ -0,0 +1,19 @@ +Plugins +======= + +.. toctree:: + :maxdepth: 2 + :caption: Plugins: + + platypush/plugins/assistant.google.rst + platypush/plugins/assistant.google.pushtotalk.rst + platypush/plugins/calendar.rst + platypush/plugins/calendar.ical.rst + platypush/plugins/camera.pi.rst + platypush/plugins/db.rst + platypush/plugins/google.rst + platypush/plugins/google.calendar.rst + platypush/plugins/google.mail.rst + platypush/plugins/google.maps.rst + platypush/plugins/gpio.rst + diff --git a/platypush/plugins/assistant/google/__init__.py b/platypush/plugins/assistant/google/__init__.py index a3589284de..aa29242e34 100644 --- a/platypush/plugins/assistant/google/__init__.py +++ b/platypush/plugins/assistant/google/__init__.py @@ -1,15 +1,31 @@ +""" +.. moduleauthor:: Fabio Manganiello +""" + from platypush.context import get_backend from platypush.message.response import Response from platypush.plugins import Plugin class AssistantGooglePlugin(Plugin): + """ + Google assistant plugin. + It acts like a wrapper around the :mod:`platypush.backend.assistant.google` + backend to programmatically control the conversation status. + """ + def start_conversation(self): + """ + Programmatically start a conversation with the assistant + """ assistant = get_backend('assistant.google') assistant.start_conversation() return Response(output='', errors=[]) def stop_conversation(self): + """ + Programmatically stop a running conversation with the assistant + """ assistant = get_backend('assistant.google') assistant.stop_conversation() return Response(output='', errors=[]) diff --git a/platypush/plugins/assistant/google/pushtotalk.py b/platypush/plugins/assistant/google/pushtotalk.py index 41bedccc78..cd01b06e71 100644 --- a/platypush/plugins/assistant/google/pushtotalk.py +++ b/platypush/plugins/assistant/google/pushtotalk.py @@ -1,15 +1,31 @@ +""" +.. moduleauthor:: Fabio Manganiello +""" + from platypush.context import get_backend from platypush.message.response import Response from platypush.plugins import Plugin class AssistantGooglePushtotalkPlugin(Plugin): + """ + Plugin for the Google assistant pushtotalk API. It acts as a wrapper to + programmatically control a + :mod:`platypush.backend.assistant.google.pushtotalk` backend. + """ + def start_conversation(self): + """ + Programmatically start a conversation with the assistant + """ assistant = get_backend('assistant.google.pushtotalk') assistant.start_conversation() return Response(output='', errors=[]) def stop_conversation(self): + """ + Programmatically stop a running conversation with the assistant + """ assistant = get_backend('assistant.google.pushtotalk') assistant.stop_conversation() return Response(output='', errors=[]) diff --git a/platypush/plugins/calendar/__init__.py b/platypush/plugins/calendar/__init__.py index b82ea335da..760cbde291 100644 --- a/platypush/plugins/calendar/__init__.py +++ b/platypush/plugins/calendar/__init__.py @@ -1,3 +1,7 @@ +""" +.. moduleauthor:: Fabio Manganiello +""" + import dateutil.parser import importlib @@ -17,16 +21,21 @@ class CalendarInterface: class CalendarPlugin(Plugin, CalendarInterface): """ - The CalendarPlugin will allow you to keep track of multiple calendars - (Google or iCal URLs) and get joined events from all of them + The CalendarPlugin allows you to keep track of multiple calendars (Google or + iCal URLs) and get joined events from all of them. + + Requires: + * **dateutil** (``pip install python-dateutil``) """ def __init__(self, calendars=[], *args, **kwargs): """ - Example calendars format: + :param calendars: List of calendars to be queried. Supported types so far: Google Calendar and iCal URLs. + :type calendars: list - ``` - [ + Example format:: + + calendars = [ { "type": "platypush.plugins.google.calendar.GoogleCalendarPlugin" }, @@ -56,6 +65,45 @@ class CalendarPlugin(Plugin, CalendarInterface): def get_upcoming_events(self, max_results=10): + """ + Get a list of upcoming events merging all the available calendars. + + :param max_results: Maximum number of results to be returned (default: 10) + :type max_results: int + + :returns: platypush.message.Response -- Response object with the list of events in the Google calendar API format. + + Example:: + + output = [ + { + "id": "123456abcdef", + "kind": "calendar#event", + "status": "confirmed", + "htmlLink": "...", + "created": "2018-06-01T01:23:45.000Z", + "updated": "2018-06-01T01:23:45.000Z", + "creator": { + "email": "...", + "displayName": "...", + "self": true + }, + "organizer" { + "email": "...", + "displayName": "...", + "self": true + }, + "start": { + "dateTime": "2018-06-02T10:00:00.000Z", + }, + "end": { + "dateTime": "2018-06-02T12:00:00.000Z", + }, + }, + ... + ] + """ + events = [] for calendar in self.calendars: diff --git a/platypush/plugins/calendar/ical.py b/platypush/plugins/calendar/ical.py index 96b94265d8..1373355ce6 100644 --- a/platypush/plugins/calendar/ical.py +++ b/platypush/plugins/calendar/ical.py @@ -1,3 +1,7 @@ +""" +.. moduleauthor:: Fabio Manganiello +""" + import datetime import dateutil.parser import requests @@ -11,7 +15,15 @@ from platypush.plugins.calendar import CalendarInterface class IcalCalendarPlugin(Plugin, CalendarInterface): + """ + iCal calendars plugin. Interact with remote calendars in iCal format. + """ + def __init__(self, url, *args, **kwargs): + """ + :param url: iCal URL to parse + :type url: str + """ super().__init__(*args, **kwargs) self.url = url @@ -46,6 +58,11 @@ class IcalCalendarPlugin(Plugin, CalendarInterface): def get_upcoming_events(self, max_results=10, only_participating=True): + """ + Get the upcoming events. See + :func:`~platypush.plugins.calendar.CalendarPlugin.get_upcoming_events`. + """ + events = [] response = requests.get(self.url) diff --git a/platypush/plugins/camera/pi.py b/platypush/plugins/camera/pi.py index 4fb65aa819..7ed993d6bc 100644 --- a/platypush/plugins/camera/pi.py +++ b/platypush/plugins/camera/pi.py @@ -1,3 +1,7 @@ +""" +.. moduleauthor:: Fabio Manganiello +""" + from platypush.context import get_backend from platypush.message.response import Response @@ -5,17 +9,35 @@ from platypush.plugins import Plugin class CameraPiPlugin(Plugin): + """ + Plugin to control a Pi camera. + It acts as a wrapper around the :ref:`platypush.backend.camera.pi` backend + to programmatically control the status. + """ + def start_recording(self): + """ + Start recording + """ camera = get_backend('camera.pi') camera.send_camera_action(camera.CameraAction.START_RECORDING) return Response(output={'status':'ok'}) def stop_recording(self): + """ + Stop recording + """ camera = get_backend('camera.pi') camera.send_camera_action(camera.CameraAction.STOP_RECORDING) return Response(output={'status':'ok'}) def take_picture(self, image_file): + """ + Take a picture. + + :param image_file: Path where the output image will be stored. + :type image_file: str + """ camera = get_backend('camera.pi') camera.send_camera_action(camera.CameraAction.TAKE_PICTURE, image_file=image_file) return Response(output={'image_file':image_file}) diff --git a/platypush/plugins/db/__init__.py b/platypush/plugins/db/__init__.py index 5630ef7be1..b945523e2f 100644 --- a/platypush/plugins/db/__init__.py +++ b/platypush/plugins/db/__init__.py @@ -1,3 +1,7 @@ +""" +.. moduleauthor:: Fabio Manganiello +""" + from sqlalchemy import create_engine, Table, MetaData from platypush.message.response import Response @@ -5,20 +9,26 @@ from platypush.message.response import Response from .. import Plugin class DbPlugin(Plugin): - """ Database plugin. It allows you to programmatically select, insert, - update and delete records on a database backend through requests, - procedures and event hooks """ + """ + Database plugin. It allows you to programmatically select, insert, update + and delete records on a database backend through requests, procedures and + event hooks. + + Requires: + * **sqlalchemy** (``pip install sqlalchemy``) + + .. todo:: + Implement ``update`` and ``delete`` methods + """ engine = None def __init__(self, engine=None, *args, **kwargs): """ - Params: - engine -- Default SQLAlchemy connection engine string - (e.g. sqlite:///:memory: or mysql://user:pass@localhost/test) - that will be used. You can override this value in your statement actions - - args, kwargs -- Extra arguments for sqlalchemy.create_engine + :param engine: Default SQLAlchemy connection engine string (e.g. ``sqlite:///:memory:`` or ``mysql://user:pass@localhost/test``) that will be used. You can override the default engine in the db actions. + :type engine: str + :param args: Extra arguments that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html) + :param kwargs: Extra kwargs that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html) """ self.engine = self._get_engine(engine, *args, **kwargs) @@ -31,7 +41,23 @@ class DbPlugin(Plugin): return self.engine def execute(self, statement, engine=None, *args, **kwargs): - """ Executes a raw SQL statement """ + """ + Executes a raw SQL statement. + + .. warning:: + Avoid calling this method directly if possible. Use ``insert``, + ``update`` and ``delete`` methods instead if possible. Don't use this + method if you need to select records, use the ``select`` method + instead, as this method is mostly meant to execute raw SQL without + returning anything. + + :param statement: SQL to be executed + :type statement: str + :param engine: Engine to be used (default: default class engine) + :type engine: str + :param args: Extra arguments that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html) + :param kwargs: Extra kwargs that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html) + """ engine = self._get_engine(engine, *args, **kwargs) @@ -43,7 +69,45 @@ class DbPlugin(Plugin): def select(self, query, engine=None, *args, **kwargs): - """ Returns rows (as a list of dicts) given a query """ + """ + Returns rows (as a list of hashes) given a query. + + :param query: SQL to be executed + :type query: str + :param engine: Engine to be used (default: default class engine) + :type engine: str + :param args: Extra arguments that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html) + :param kwargs: Extra kwargs that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html) + :returns: List of hashes representing the result rows. + + Example: + + Request:: + + { + "type": "request", + "target": "your_host", + "action": "db.select", + "args": { + "engine": "sqlite:///:memory:", + "query": "SELECT id, name FROM table" + } + } + + Response:: + + [ + { + "id": 1, + "name": foo + }, + + { + "id": 2, + "name": bar + } + ] + """ engine = self._get_engine(engine, *args, **kwargs) @@ -59,7 +123,43 @@ class DbPlugin(Plugin): def insert(self, table, records, engine=None, *args, **kwargs): - """ Inserts records (as a list of dicts) into a table """ + """ + Inserts records (as a list of hashes) into a table. + + :param table: Table name + :type table: str + :param records: Records to be inserted (as a list of hashes) + :type records: list + :param engine: Engine to be used (default: default class engine) + :type engine: str + :param args: Extra arguments that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html) + :param kwargs: Extra kwargs that will be passed to ``sqlalchemy.create_engine`` (see http://docs.sqlalchemy.org/en/latest/core/engines.html) + + Example: + + Request:: + + { + "type": "request", + "target": "your_host", + "action": "db.insert", + "args": { + "table": "table", + "engine": "sqlite:///:memory:", + "records": [ + { + "id": 1, + "name": foo + }, + + { + "id": 2, + "name": bar + } + ] + } + } + """ engine = self._get_engine(engine, *args, **kwargs) diff --git a/platypush/plugins/google/__init__.py b/platypush/plugins/google/__init__.py index a2761bd802..95707b5549 100644 --- a/platypush/plugins/google/__init__.py +++ b/platypush/plugins/google/__init__.py @@ -1,3 +1,7 @@ +""" +.. moduleauthor:: Fabio Manganiello +""" + import os from platypush.plugins import Plugin @@ -7,6 +11,7 @@ from platypush.plugins.google.credentials import get_credentials class GooglePlugin(Plugin): """ Executes calls to the Google APIs using the google-api-python-client. + This class is extended by ``GoogleMailPlugin``, ``GoogleCalendarPlugin`` etc. In order to use Google services (like GMail, Maps, Calendar etc.) with your account you need to: @@ -19,12 +24,23 @@ class GooglePlugin(Plugin): 4. Click on the "Download JSON" icon next to your newly created client ID - 5. Generate a credentials file for the needed scope: + 5. Generate a credentials file for the needed scope:: - $ python -m platypush.plugins.google.credentials 'https://www.googleapis.com/auth/gmail.compose' ~/client_secret.json + python -m platypush.plugins.google.credentials 'https://www.googleapis.com/auth/gmail.compose' ~/client_secret.json + + Requires: + + * **google-api-python-client** (``pip install google-api-python-client``) """ def __init__(self, scopes, *args, **kwargs): + """ + Initialized the Google plugin with the required scopes. + + :param scopes: List of required scopes + :type scopes: list + """ + super().__init__(*args, **kwargs) self.credentials = {} diff --git a/platypush/plugins/google/calendar.py b/platypush/plugins/google/calendar.py index 4d6881b43e..d35c1e6001 100644 --- a/platypush/plugins/google/calendar.py +++ b/platypush/plugins/google/calendar.py @@ -1,3 +1,7 @@ +""" +.. moduleauthor:: Fabio Manganiello +""" + import base64 import datetime import httplib2 @@ -11,6 +15,10 @@ from platypush.plugins.calendar import CalendarInterface class GoogleCalendarPlugin(GooglePlugin, CalendarInterface): + """ + Google calendar plugin + """ + scopes = ['https://www.googleapis.com/auth/calendar.readonly'] def __init__(self, *args, **kwargs): @@ -18,6 +26,11 @@ class GoogleCalendarPlugin(GooglePlugin, CalendarInterface): def get_upcoming_events(self, max_results=10): + """ + Get the upcoming events. See + :func:`~platypush.plugins.calendar.CalendarPlugin.get_upcoming_events`. + """ + now = datetime.datetime.utcnow().isoformat() + 'Z' service = self._get_service() result = service.events().list(calendarId='primary', timeMin=now, diff --git a/platypush/plugins/google/mail.py b/platypush/plugins/google/mail.py index a2e6254ba7..8cb45ce2c1 100644 --- a/platypush/plugins/google/mail.py +++ b/platypush/plugins/google/mail.py @@ -1,3 +1,7 @@ +""" +.. moduleauthor:: Fabio Manganiello +""" + import base64 import httplib2 import mimetypes @@ -18,6 +22,10 @@ from platypush.plugins.google import GooglePlugin class GoogleMailPlugin(GooglePlugin): + """ + GMail plugin. It allows you to programmatically compose and (TODO) get emails + """ + scopes = ['https://www.googleapis.com/auth/gmail.modify'] def __init__(self, *args, **kwargs): @@ -25,6 +33,25 @@ class GoogleMailPlugin(GooglePlugin): def compose(self, sender, to, subject, body, files=None): + """ + Compose a message. + + :param sender: Sender email/name + :type sender: str + + :param to: Recipient email or comma-separated list of recipient emails + :type to: str + + :param subject: Email subject + :type subject: str + + :param body: Email body + :type body: str + + :param files: Optional list of files to attach + :type files: list + """ + message = MIMEMultipart() if files else MIMEText(body) message['to'] = to message['from'] = sender @@ -68,6 +95,9 @@ class GoogleMailPlugin(GooglePlugin): def get_labels(self): + """ + Returns the available labels on the GMail account + """ service = self._get_service() results = service.users().labels().list(userId='me').execute() labels = results.get('labels', []) diff --git a/platypush/plugins/google/maps.py b/platypush/plugins/google/maps.py index 4d08062194..6f38676fab 100644 --- a/platypush/plugins/google/maps.py +++ b/platypush/plugins/google/maps.py @@ -1,3 +1,7 @@ +""" +.. moduleauthor:: Fabio Manganiello +""" + import json import requests @@ -6,14 +10,33 @@ from platypush.plugins.google import GooglePlugin class GoogleMapsPlugin(GooglePlugin): + """ + Plugins that provides utilities to interact with Google Maps API services. + """ + scopes = [] def __init__(self, api_key, *args, **kwargs): + """ + :param api_key: Server-side API key to be used for the requests, get one at https://console.developers.google.com + :type api_key: str + """ + super().__init__(scopes=self.scopes, *args, **kwargs) self.api_key = api_key def get_address_from_latlng(self, latitude, longitude): + """ + Get an address information given lat/long + + :param latitude: Latitude + :type latitude: float + + :param longitude: Longitude + :type longitude: float + """ + response = requests.get('https://maps.googleapis.com/maps/api/geocode/json', params = { 'latlng': '{},{}'.format(latitude, longitude), diff --git a/platypush/plugins/gpio/__init__.py b/platypush/plugins/gpio/__init__.py index d7b1a18afa..99f331cbbb 100644 --- a/platypush/plugins/gpio/__init__.py +++ b/platypush/plugins/gpio/__init__.py @@ -1,14 +1,45 @@ +""" +.. moduleauthor:: Fabio Manganiello +""" + import threading import time -import RPi.GPIO as gpio - from platypush.message.response import Response from platypush.plugins import Plugin class GpioPlugin(Plugin): + """ + Plugin to handle raw read/write operation on the Raspberry Pi GPIO pins. + + Requires: + * **RPi.GPIO** (`pip install RPi.GPIO`) + """ + def write(self, pin, val): + """ + Write a byte value to a pin. + + :param pin: PIN number + :type pin: int + + :param val: Value to write + :type val: int + + :returns: dict + + Response:: + + output = { + "pin": , + "val": , + "method": "write" + } + """ + + import RPi.GPIO as gpio + gpio.setmode(gpio.BCM) gpio.setup(pin, gpio.OUT) gpio.output(pin, val) @@ -19,7 +50,26 @@ class GpioPlugin(Plugin): 'method': 'write', }) - def read(self, pin, val): + def read(self, pin): + """ + Reads a value from a PIN. + + :param pin: PIN number + :type pin: int + + :returns: dict + + Response:: + + output = { + "pin": , + "val": , + "method": "read" + } + """ + + import RPi.GPIO as gpio + gpio.setmode(gpio.BCM) gpio.setup(pin, gpio.IN) val = gpio.input(pin) diff --git a/platypush/plugins/weather/forecast.py b/platypush/plugins/weather/forecast.py index c4b078ad31..bacb9bdec0 100644 --- a/platypush/plugins/weather/forecast.py +++ b/platypush/plugins/weather/forecast.py @@ -15,6 +15,7 @@ class WeatherForecastPlugin(HttpRequestPlugin): def get_current_weather(self, **kwargs): response = self.get(self.url) + print(response) return Response(output=response.output['currently']) def get_hourly_forecast(self, **kwargs):