Skip to content

Commit

Permalink
Merge pull request googleapis#159 from AnoojNair/master
Browse files Browse the repository at this point in the history
Planner and tasks
  • Loading branch information
Geethanadh Padavala authored Jan 7, 2019
2 parents 44ce040 + 7a25fb5 commit cbe44fc
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 0 deletions.
1 change: 1 addition & 0 deletions O365/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
from .mailbox import MailBox
from .message import Message, MessageAttachment, Recipient
from .sharepoint import Sharepoint, Site
from .planner import Planner,Task
from .utils import ImportanceLevel, Query
from .utils import OneDriveWellKnowFolderNames, OutlookWellKnowFolderNames
11 changes: 11 additions & 0 deletions O365/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from O365.mailbox import MailBox
from O365.message import Message
from O365.sharepoint import Sharepoint
from O365.planner import Planner
from O365.utils import ME_RESOURCE


Expand Down Expand Up @@ -153,3 +154,13 @@ def sharepoint(self, *, resource=''):
'Sharepoint api only works on Microsoft Graph API')

return Sharepoint(parent=self, main_resource=resource)

def planner(self, *, resource=''):
""" Get an instance to read information from Microsoft planner """

if not isinstance(self.protocol , MSGraphProtocol):
# TODO: Custom protocol accessing OneDrive/Sharepoint Api fails here
raise RuntimeError(
'planner api only works on Microsoft Graph API')

return Planner(parent=self, main_resource=resource)
135 changes: 135 additions & 0 deletions O365/planner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import logging

from dateutil.parser import parse

from O365.address_book import Contact
from O365.drive import Storage
from O365.utils import ApiComponent

log = logging.getLogger(__name__)

class Task(ApiComponent):
""" A Microsoft Planner task """

_endpoints = {
}

def __init__(self, *, parent=None, con=None, **kwargs):
""" A Microsoft planner task
:param parent: parent object
:type parent: Planner
:param Connection con: connection to use if no parent specified
:param Protocol protocol: protocol to use if no parent specified
(kwargs)
:param str main_resource: use this resource instead of parent resource
(kwargs)
"""
assert parent or con, 'Need a parent or a connection'
self.con = parent.con if parent else con

cloud_data = kwargs.get(self._cloud_data_key, {})

self.object_id = cloud_data.get('id')

# Choose the main_resource passed in kwargs over parent main_resource
main_resource = (kwargs.pop('main_resource', None) or
getattr(parent,
'main_resource',
None) if parent else None)

main_resource = '{}{}'.format(main_resource, '')

super().__init__(
protocol=parent.protocol if parent else kwargs.get('protocol'),
main_resource=main_resource)

self.plan_id = cloud_data.get('plan_id')
self.bucket_id = cloud_data.get('bucketId')
self.title = cloud_data.get(self._cc('title'), '')
self.order_hint = cloud_data.get(self._cc('orderHint'), '')
self.assignee_priority = cloud_data.get(self._cc('assigneePriority'), '')
self.percent_complete = cloud_data.get(self._cc('percentComplete'), '')
self.title = cloud_data.get(self._cc('title'), '')
self.has_description = cloud_data.get(self._cc('hasDescription'), '')
created = cloud_data.get(self._cc('createdDateTime'), None)
due_date = cloud_data.get(self._cc('dueDateTime'), None)
start_date = cloud_data.get(self._cc('startDateTime'), None)
completed_date = cloud_data.get(self._cc('completedDateTime'), None)
local_tz = self.protocol.timezone
self.start_date = parse(start_date).astimezone(local_tz) if start_date else None
self.created_date = parse(created).astimezone(local_tz) if created else None
self.due_date = parse(due_date).astimezone(local_tz) if due_date else None
self.completed_date = parse(completed_date).astimezone(local_tz) if completed_date else None
self.preview_type = cloud_data.get(self._cc('previewType'), None)
self.reference_count = cloud_data.get(self._cc('referenceCount'), None)
self.checklist_item_count = cloud_data.get(self._cc('checklistItemCount'), None)
self.active_checklist_item_count = cloud_data.get(self._cc('activeChecklistItemCount'), None)
self.conversation_thread_id = cloud_data.get(self._cc('conversationThreadId'), None)


def __str__(self):
return self.__repr__()

def __repr__(self):
return 'Task: {}'.format(self.title)



class Planner(ApiComponent):
""" A microsoft planner class
In order to use the API following permissions are required.
Delegated (work or school account) - Group.Read.All, Group.ReadWrite.All
"""

_endpoints = {
'get_my_tasks': '/me/planner/tasks',
}
task_constructor = Task

def __init__(self, *, parent=None, con=None, **kwargs):
""" A Planner object
:param parent: parent object
:type parent: Account
:param Connection con: connection to use if no parent specified
:param Protocol protocol: protocol to use if no parent specified
(kwargs)
:param str main_resource: use this resource instead of parent resource
(kwargs)
"""
assert parent or con, 'Need a parent or a connection'
self.con = parent.con if parent else con

# Choose the main_resource passed in kwargs over the host_name
main_resource = kwargs.pop('main_resource',
'') # defaults to blank resource
super().__init__(
protocol=parent.protocol if parent else kwargs.get('protocol'),
main_resource=main_resource)

def __str__(self):
return self.__repr__()

def __repr__(self):
return 'Microsoft Planner'

def get_my_tasks(self, *args):
""" Returns a list of open planner tasks assigned to me
:rtype: tasks
"""

url = self.build_url(self._endpoints.get('get_my_tasks'))

response = self.con.get(url)

if not response:
return None

data = response.json()

return [
self.task_constructor(parent=self, **{self._cloud_data_key: site})
for site in data.get('value', [])]

28 changes: 28 additions & 0 deletions tests/test_planner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#from O365 import Account
#from O365 import Planner

#class MockConnection:

# ret_value = None

# def get(self, url, params=None, **kwargs):
# self.url = url
# self.kwargs = kwargs

#class TestPlanner:

# def setup_class(self):
# credentials = ("client id","client secret")
# self.account = Account(credentials)
# self.planner = self.account.planner()
# self.planner.con = MockConnection()

# def teardown_class(self):
# pass

# def test_planner(self):
# assert self.planner

# def test_get_my_tasks(self):
# tasks = self.planner.get_my_tasks()
# assert len(tasks) > 0

0 comments on commit cbe44fc

Please sign in to comment.