Skip to content

Commit

Permalink
Updated the README.md a lot. People on reddit really suggested that
Browse files Browse the repository at this point in the history
I do such. thanks /u/msjgriffiths.

Also updated some of the examples for consistency and convenience.

Got part of the way through issue googleapis#14
  • Loading branch information
Toben Archer committed May 29, 2015
1 parent 4a606d6 commit 345c1e5
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 48 deletions.
15 changes: 11 additions & 4 deletions O365/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,24 +171,31 @@ def setRecipients(self,val):
{"EmailAddress":{"Address":"recipient@example.com"}}
with other options such ass "Name" with address. but at minimum it must have this.
a list: this must to be a list of libraries formatted the way specified above,
or it can be a list of libraries objects of type Contact. The method will sort
or it can be a list of dictionary objects of type Contact. The method will sort
out the libraries from the contacts.
a string: this is if you just want to throw an email address.
a contact: type Contact from this library.
a contact: type Contact from this dictionary.
a group: type Group, which is a list of contacts.
For each of these argument types the appropriate action will be taken to fit them to the
needs of the library.
'''
if isinstance(val,list):
self.json['ToRecipients'] = val
self.json['ToRecipients'] = []
if isinstance(val,Contact):
self.addRecipient(val)
else:
self.json['ToRecipients'].append(val)
elif isinstance(val,dict):
self.json['ToRecipients'] = [val]
elif isinstance(val,str):
if '@' in val:
self.json['ToRecipients'] = []
self.addRecipient(val)
elif isinstance(val,Contact):
self.json['ToRecipients'] = []
self.addRecipient(val)
elif isinstance(val,Group):
for person in val:
self.addRecipient(person)
else:
return False
return True
Expand Down
138 changes: 136 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# python-o365 - Office365 for you server
# Python-O365 - Office365 for you server

The objective O365 is to make it easy to make utilities that are to be run against an Office 365 account. If you wanted to script sending an email it could be as simple as:

Expand All @@ -12,5 +12,139 @@ m.setBody('Talk to the computer, cause the human does not want to hear it any mo
m.sendMessage()
```

To keep the library simple but powerful there are wrapper methods to access most of the attributes:
```python
m.setBody('a body!')
```

But all attributes listed on the documenation for the [Office365 API](https://msdn.microsoft.com/office/office365/APi/api-catalog) are available through the json representation stored in the instance of every O365 object:
```python
if m.json['IsReadReceiptRequested']:
m.reply('Got it.')
```

## Table of contents

- [Email](#email)
- [Calendar](#calendar)
- [Contacts](#contacts)
- [Files - One Drive](#files)

## Email
There are two classes for working with emails in O365.
#### Inbox
A collection of emails. This is used when ever you are requesting an email or emails. It can be set with filters so that you only download the emails which your script is interested in.
#### Message
An actual email with all it's associated data.

In the [Fetch File](https://github.com/Narcolapser/python-o365/blob/master/examples/fetchFile.py) example a filter is used to get only the unread messages with the subject line "Fetch File"
```python
i = Inbox(e,p,getNow=False) #Email, Password, Delay fetching so I can change the filters.

i.setFilter("IsRead eq false & Subject eq 'Fetch File'")

i.getMessages()
```

When the inbox has run it's getMessages method, whether when it is instanced or later, all the messages it retrieves will be stored in a list local to the instance of inbox. Inbox.messages

While the Inbox class is used exclusively for incoming mail, as the name might imply, the message class is incoming and out going. In the fetch file example in it's processMessage method it work with both an incoming message, "m", and prepares an out going message, "resp":
```python
def processMessage(m):
path = m.json['BodyPreview']

path = path[:path.index('\n')]
if path[-1] == '\r':
path = path[:-1]

att = Attachment(path=path)

resp = Message(auth=auth)
resp.setRecipients(m.getSender())

resp.setSubject('Your file sir!')
resp.setBody(path)
resp.attachments.append(att)
resp.sendMessage()

return True
```
In this method we pull the BodyPreview, less likely to have Markup, and pull out it's first line to get the path to a file. That path is then sent to the attachment class and a response message is created and sent. Simple and straight forward.

The attachment class is a relatively simple class for handling downloading and creating attachments. Attachments in Office365 are stored seperately from the email in most cases and as such will have to be downloaded and uploaded seperately as well. This however is also taken care of behind the scenes with O365. Simply call a message's getAttachments method to download the attachments locally to your process. This creates a list of attachments local to the instance of Message, as is seen in the [Email Printing example](https://github.com/Narcolapser/python-o365/blob/master/examples/EmailPrinting/emailprinting.py):
```python
m.fetchAttachments()
for att in m.attachments:
processAttachment(att,resp)
#various un-related bits left out for brevity.
```
The attachment class stores the files as base64 encoded files. But this doesn't matter to you! The attachment class can work with you if you want to just send/recieve raw binary or base64. You can also just give it a path to a file if you want to creat an attachment:
```python
att = Attachment(path=path)
```
or if you want to save the file
```
att.save(path)
```

## Calendar
Events are on a Calendar, Calendars are grouped into a Schedule. In the [Vehicle Booking](https://github.com/Narcolapser/python-o365/blob/master/examples/VehicleBookings/veh.py) example the purpose of the script is to create a json file with information to be imported into another program for presentation. We want to know all of the times the vehicles are booked out, for each vehicle, and by who, etc. This is done by simple getting the schedule and calendar for each vehicle and spitting out it's events:
```python
for veh in vj:
e = veh['email']
p = veh['password']

schedule = Schedule(e,p)
try:
result = schedule.getCalendars()
print 'Fetched calendars for',e,'was successful:',result
except:
print 'Login failed for',e

bookings = []

for cal in schedule.calendars:
print 'attempting to fetch events for',e
try:
result = cal.getEvents()
print 'Got events',result,'got',len(cal.events)
except:
print 'failed to fetch events'
print 'attempting for event information'
for event in cal.events:
print 'HERE!'
bookings.append(event.fullcalendarioJson())
json_outs[e] = bookings
```

Events can be made relatively easily too. You just have to create a event class:
```python
e = Event(authentication,parentCalendar)
```
and give it a few nesessary details:
```python
import time
e.setSubject('Coffee!')
e.setStart(time.gmtime(time.time()+3600)) #start an hour from now.
e.setEnd(time.gmtime(time.time()+7200)) #end two hours from now.
new_e = e.create()
```

## Contacts
Contacts are a small part of this library, but can have their use. You can store email addresses in your contacts list in folders and then use this as a form of mailing list:
```python
e = 'youremail@office365.com'
p = 'embarrassingly simple password.'
group = Group(e,p,'Contact folder name')
m = Message(auth=(e,p))
m.setSubject('News for today')
m.setBody(open('news.html','r').read())
m.setRecipients(group)
m.sendMessage()
```

## Files
This will be a new feature in 0.8. Coming soon.


#### To the King!
#### Soli Deo Gloria
32 changes: 0 additions & 32 deletions examples/VehicleBookings/veh.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,36 +40,4 @@
with open('bookings.json','w') as outs:
outs.write(json.dumps(json_outs,sort_keys=True,indent=4))


# with open('./ep.pw','r') as configFile:
# config = configFile.read()
# cjson = json.loads(config)
#
# e = cjson ['email']
# p = cjson ['password']
#
# i = Inbox(e,p)
# i.getMessages()
#
# printer = getRicoh()
# print "messages: ",len(i.messages)
# for m in i.messages:
# m.fetchAttachments()
# m.markAsRead()
# if not verifyUser(m.address):
# print "NOT OMER!"
# continue
# print "\t attachments: ",len(m.attachments),"from:",userFromEmail(m.address)
# for att in m.attachments:
# printer.setFlag('U',userFromEmail(m.address))
# p = att.byteString()
# if not p:
# continue
# print "length of byte string: ",len(p),"for attachment:",att.name
# if p:
# print "ready. set. PRINT!"
# printer.setFlag('t',att.name)
# ret = printer.sendPrint(p)
# print ret

#To the King!
16 changes: 7 additions & 9 deletions examples/fetchFile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@
log = logging.getLogger('ff')

def processMessage(m):
if m.json['Subject'] != 'Fetch File':
return False
m.markAsRead()

path = m.json['BodyPreview']

path = path[:path.index('\n')]
Expand All @@ -23,13 +19,11 @@ def processMessage(m):
att = Attachment(path=path)

resp = Message(auth=auth)
resp.setSubject('Your file sir!')
resp.setRecipients(m.getSender())
resp.setBody(path)


resp.setSubject('Your file sir!')
resp.setBody(path)
resp.attachments.append(att)

resp.sendMessage()

return True
Expand All @@ -45,7 +39,11 @@ def processMessage(m):

auth = (e,p)

i = Inbox(e,p)
i = Inbox(e,p,getNow=False) #Email, Password, Delay fetching so I can change the filters.

i.setFilter("IsRead eq false & Subject eq 'Fetch File'")

i.getMessages()

log.debug("messages: {0}".format(len(i.messages)))
for m in i.messages:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
https://github.com/Narcolapser/python-o365'''

setup(name='O365',
version='0.7',
version='0.7.1',
description='Python library for working with Microsoft Office 365',
long_description=long_desc,
author='Toben Archer',
Expand Down
2 changes: 2 additions & 0 deletions tests/run_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,7 @@ python test_event.py
python test_inbox.py
python test_message.py
python test_schedule.py
python test_group.py
python test_contact.py

echo "all tests done."

0 comments on commit 345c1e5

Please sign in to comment.