Skip to content
This repository has been archived by the owner on Jul 7, 2022. It is now read-only.

Commit

Permalink
Merge pull request #29 from randomchars/dev
Browse files Browse the repository at this point in the history
Raise exceptions for errors
  • Loading branch information
Richard Borcsik committed Jan 31, 2015
2 parents 3adcdab + 8122c97 commit 5a99e43
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 65 deletions.
2 changes: 1 addition & 1 deletion pushbullet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
from .pushbullet import PushBullet
from .device import Device
from .listener import Listener
from .invalid_key_error import InvalidKeyError
from .errors import PushBulletError, InvalidKeyError, PushError
8 changes: 8 additions & 0 deletions pushbullet/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class PushBulletError(Exception):
pass

class InvalidKeyError(PushBulletError):
pass

class PushError(PushBulletError):
pass
6 changes: 0 additions & 6 deletions pushbullet/invalid_key_error.py

This file was deleted.

50 changes: 24 additions & 26 deletions pushbullet/pushbullet.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from .device import Device
from .channel import Channel
from .contact import Contact
from .invalid_key_error import InvalidKeyError
from .errors import PushBulletError, InvalidKeyError, PushError
from .filetype import get_file_type


Expand Down Expand Up @@ -92,19 +92,19 @@ def new_device(self, nickname):
if r.status_code == requests.codes.ok:
new_device = Device(self, r.json())
self.devices.append(new_device)
return True, new_device
return new_device
else:
return False, None
raise PushBulletError(r.text)

def new_contact(self, name, email):
data = {"name": name, "email": email}
r = self._session.post(self.CONTACTS_URL, data=json.dumps(data))
if r.status_code == requests.codes.ok:
new_contact = Contact(self, r.json())
self.contacts.append(new_contact)
return True, new_contact
return new_contact
else:
return False, None
raise PushBulletError(r.text)

def edit_device(self, device, nickname=None, model=None, manufacturer=None):
data = {"nickname": nickname}
Expand All @@ -113,9 +113,10 @@ def edit_device(self, device, nickname=None, model=None, manufacturer=None):
if r.status_code == requests.codes.ok:
new_device = Device(self, r.json())
self.devices[self.devices.index(device)] = new_device
return True, new_device
return new_device
else:
return False, device
raise PushBulletError(r.text)


def edit_contact(self, contact, name):
data = {"name": name}
Expand All @@ -124,27 +125,28 @@ def edit_contact(self, contact, name):
if r.status_code == requests.codes.ok:
new_contact = Contact(self, r.json())
self.contacts[self.contacts.index(contact)] = new_contact
return True, new_contact
return new_contact
else:
return False, contact
raise PushBulletError(r.text)


def remove_device(self, device):
iden = device.device_iden
r = self._session.delete("{}/{}".format(self.DEVICES_URL, iden))
if r.status_code == requests.codes.ok:
self.devices.remove(device)
return True, r.json()
else:
return False, r.json()
raise PushBulletError(r.text)


def remove_contact(self, contact):
iden = contact.iden
r = self._session.delete("{}/{}".format(self.CONTACTS_URL, iden))
if r.status_code == requests.codes.ok:
self.contacts.remove(contact)
return True, r.json()
return True
else:
return False, r.json()
raise PushBulletError(r.text)

def get_pushes(self, modified_after=None, limit=None):
data = {"modified_after": modified_after, "limit": limit}
Expand All @@ -154,7 +156,7 @@ def get_pushes(self, modified_after=None, limit=None):
while get_more_pushes:
r = self._session.get(self.PUSH_URL, params=data)
if r.status_code != requests.codes.ok:
return False, r.json()
raise PushBulletError(r.text)

pushes_list += r.json().get("pushes")
if 'cursor' in r.json() and (not limit or len(pushes_list) < limit):
Expand All @@ -168,18 +170,14 @@ def dismiss_push(self, iden):
data = {"dismissed": True}
r = self._session.post("{}/{}".format(self.PUSH_URL, iden), data=json.dumps(data))

if r.status_code == requests.codes.ok:
return True, r.json()
else:
return False, r.json()
if r.status_code != requests.codes.ok:
raise PushBulletError(r.text)

def delete_push(self, iden):
r = self._session.delete("{}/{}".format(self.PUSH_URL, iden))

if r.status_code == requests.codes.ok:
return True, r.json()
else:
return False, r.json()
if r.status_code != requests.codes.ok:
raise PushBulletError(r.text)

def upload_file(self, f, file_name, file_type=None):
if not file_type:
Expand All @@ -191,15 +189,15 @@ def upload_file(self, f, file_name, file_type=None):
r = self._session.post(self.UPLOAD_REQUEST_URL, data=json.dumps(data))

if r.status_code != requests.codes.ok:
return False, r.json()
raise PushBulletError(r.text)

upload_data = r.json().get("data")
file_url = r.json().get("file_url")
upload_url = r.json().get("upload_url")

upload = requests.post(upload_url, data=upload_data, files={"file": f})

return True, {"file_type": file_type, "file_url": file_url, "file_name": file_name}
return {"file_type": file_type, "file_url": file_url, "file_name": file_name}

def push_file(self, file_name, file_url, file_type, body=None, device=None, contact=None, email=None, channel=None):
data = {"type": "file", "file_type": file_type, "file_url": file_url, "file_name": file_name}
Expand Down Expand Up @@ -242,9 +240,9 @@ def _push(self, data):
r = self._session.post(self.PUSH_URL, data=json.dumps(data))

if r.status_code == requests.codes.ok:
return True, r.json()
return r.json()
else:
return False, r.json()
raise PushError(r.text)

def refresh(self):
self._load_devices()
Expand Down
68 changes: 36 additions & 32 deletions readme.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ Authentication
pb = PushBullet(api_key)
If your key is invalid (that is, the Pushbullet API returns a ``401``), an ``InvalidKeyError`` is raised.

Pushing things
~~~~~~~~~~~~~~

Expand All @@ -67,30 +69,32 @@ Pushing a text note

.. code:: python
success, push = pb.push_note("This is the title", "This is the body".)
push = pb.push_note("This is the title", "This is the body".)
``push`` is a dictionary containing the data returned by the Pushbullet API.

Pushing an address
^^^^^^^^^^^^^^^^^^

.. code:: python
address = " 25 E 85th St, 10028 New York, NY"
success, push = pb.push_address("home", address)
push = pb.push_address("home", address)
Pushing a list
^^^^^^^^^^^^^^

.. code:: python
to_buy = ["milk", "bread", "cider"]
success, push = phone.push_list("Shopping list", to_buy)
push = phone.push_list("Shopping list", to_buy)
Pushing a link
^^^^^^^^^^^^^^

.. code:: python
success, push = phone.push_link("Cool site", "https://github.com")
push = phone.push_link("Cool site", "https://github.com")
Pushing a file
^^^^^^^^^^^^^^
Expand All @@ -100,17 +104,19 @@ Pushing files is a two part process. First you need to upload the file, and afte
.. code:: python
with open("my_cool_picture.jpg", "rb") as pic:
success, file_data = pb.upload_file(pic, "picture.jpg")
file_data = pb.upload_file(pic, "picture.jpg")
push = pb.push_file(**file_data)
success, push = pb.push_file(**file_data)
``upload_file`` returns a dictionary containing ``file_type``, ``file_url`` and ``file_name`` keys. These are the same parameters that ``push_file`` take.


The advantage of this is that if you already have a file uploaded somewhere, you can use that instead of uploading again. For example:


.. code:: python
success, push = pb.push_file(file_url="https://i.imgur.com/IAYZ20i.jpg", file_name="cat.jpg", file_type="image/jpeg")
push = pb.push_file(file_url="https://i.imgur.com/IAYZ20i.jpg", file_name="cat.jpg", file_type="image/jpeg")
Working with pushes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -119,20 +125,21 @@ You can also view all previous pushes:

.. code:: python
success, pushes = pb.get_pushes()
pushes = pb.get_pushes()
Pushes is a list containg dictionaries that have push data. You can use this data to dismiss notifications or delete pushes.
Pushes is a list containig dictionaries that have push data. You can use this data to dismiss notifications or delete pushes.

.. code:: python
latest = pushes[0]
# We already read it, so let's dismiss it
success, error_message = pb.dismiss_push(lates.get("iden"))
pb.dismiss_push(latest.get("iden"))
# Now delete it
success, error_message = pb.delete_push(lates.get("iden"))
pb.delete_push(latest.get("iden"))
Both of these raise ``PushBulletError`` if there's an error.

Pushing to specific devices
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -153,13 +160,13 @@ Now we can use the device objects like we did with `pb`:

.. code:: python
success, push = motog.push_note("Hello world!", "We're using the api.")
push = motog.push_note("Hello world!", "We're using the api.")
Alternatively we can pass the device to push methods:

.. code:: python
success, push = pb.push_note("Hello world!", "We're using the api.", device=motog)
push = pb.push_note("Hello world!", "We're using the api.", device=motog)
Creating new devices
^^^^^^^^^^^^^^^^^^^^
Expand All @@ -168,7 +175,7 @@ Creating a new device is easy too, you only need to specify a name for it.

.. code:: python
success, listener = pb.new_device("Listener")
listener = pb.new_device("Listener")
Now you can use it like any other device.

Expand All @@ -179,8 +186,8 @@ You can change the nickname, the manufacturer and the model of the device:

.. code:: python
success, listener = pb.edit_device(listener, make="Python", model="3.4.1")
success, motog = pb.edit_device(motog, nickname="My MotoG")
listener = pb.edit_device(listener, make="Python", model="3.4.1")
motog = pb.edit_device(motog, nickname="My MotoG")
Deleting devices
Expand All @@ -190,8 +197,9 @@ Of course, you can also delete devices, even those not added by you.

.. code:: python
success, error_message = pb.remove_device(listener)
pb.remove_device(listener)
A ``PushBulletError`` is raised on error.

Channels
~~~~~~~~~~~~
Expand All @@ -212,7 +220,7 @@ Then you can send a push to all subscribers of this channel like so:

.. code:: python
success, push = my_channel.push_note("Hello Channel!", "Hello My Channel")
push = my_channel.push_note("Hello Channel!", "Hello My Channel")
Note that you can only push to channels which have been created by the current
user.
Expand All @@ -229,24 +237,24 @@ Contacts work just like devices:
print(pb.contacts)
# [Contact('Peter' <[email protected]>), Contact('Sophie' <[email protected]>]
sophie = pb.contacs[1]
sophie = pb.contacts[1]
Now we can use the contact objects like we did with `pb` or with the devices.:

.. code:: python
success, push = sophie.push_note("Hello world!", "We're using the api.")
push = sophie.push_note("Hello world!", "We're using the api.")
# Or:
success, push = pb.push_note("Hello world!", "We're using the api.", contact=sophie)
push = pb.push_note("Hello world!", "We're using the api.", contact=sophie)
Adding new contacts
^^^^^^^^^^^^^^^^^^^^

.. code:: python
success, bob = pb.new_contact("Bob", "[email protected]")
bob = pb.new_contact("Bob", "[email protected]")
Editing contacts
^^^^^^^^^^^^^^^^^
Expand All @@ -255,34 +263,30 @@ You can change the name of any contact:

.. code:: python
success, bob = pb.edit_contact(bob, "bobby")
bob = pb.edit_contact(bob, "bobby")
Deleting contacts
^^^^^^^^^^^^^^^^^^^

.. code:: python
success, error_message = pb.remove_contact(bob)
pb.remove_contact(bob)
Error checking
~~~~~~~~~~~~~~

Most methods return a tuple containing a bool value indicating success or failure, and the response from the server.

.. code:: Python
success, push = pb.push_note("Hello world!", "We're using the api.")
If the Pushbullet api returns an error code a ``PushError`` an __
``InvalidKeyError`` or a ``PushBulletError`` is raised. The first __
two are both subclasses of ``PushBulletError``

The `pushbullet api documetation <https://www.pushbullet.com/api>`__
contains a list of possible status codes.

TODO
----

- Websocket support
- Tests, tests, tests. Write them.
- More tests. Write them all.

License
-------
Expand Down

0 comments on commit 5a99e43

Please sign in to comment.