import json
import mimetypes
import os
import requests


class _PushBullet(object):
    DEVICES_URL = 'https://api.pushbullet.com/v2/devices'
    PUSH_URL = 'https://api.pushbullet.com/v2/pushes'
    UPLOAD_URL = 'https://api.pushbullet.com/v2/upload-request'
    UPLOAD_LIMIT = 25000000

    def __init__(self, api_key=None):
        self.api_key = api_key
        if not api_key:
            try:
                os.getenv['PUSHBULLET_API_KEY']
            except KeyError:
                raise TypeError('Missing api_key')
        self._s = requests.session()
        self._s.auth = (self.api_key, '')
        self._s.headers = {'Content-Type': 'application/json'}

    def _push(self, data):
        if 'iden' in locals():
            data['device_iden'] = self.iden
        return self._s.post(self.PUSH_URL, data=json.dumps(data))

    def push_note(self, title, body):
        data = {'type': 'note',
                'title': title,
                'body': body}
        return self._push(data)

    def push_link(self, url, body=None, title=None):
        data = {'type': 'link',
                'title': title,
                'url': url,
                'body': body}
        return self._push(data)

    def push_address(self, address):
        data = {'type': 'address',
                'address': address}
        return self._push(data)

    def push_list(self, title, items):
        data = {'type': 'list',
                'title': title,
                'items': items}
        return self._push(data)

    def push_file(self, pfile, file_type=None, file_name=None):
        # FP
        if not isinstance(pfile, str):
            if os.fstat(pfile.fileno()).st_size > self.UPLOAD_LIMIT:
                return 'File too big'
            if not file_type:
                file_type = mimetypes.guess_type(pfile.name)
            if not file_name:
                file_name = pfile.name
            payload = {'file_type': file_type,
                       'file_name': file_name}
            r = self._s.get(self.UPLOAD_URL, params=payload)
            file_url = r.json()['file_url']
            upload_url = r.json()['upload_url']
            data = r.json()['data']
            files = {'file': pfile}
            requests.post(upload_url, files=files, data=data)
        # String/url
        else:
            if not file_type:
                file_type = mimetypes.guess_type(pfile)
            if not file_name:
                __, file_name = pfile.rsplit('/', 1)
            file_url = pfile
        data = {'type': 'file',
                'file_type': file_type,
                'file_name': file_name,
                'file_url': file_url}
        return self._push(data)


class PushBullet(_PushBullet):
    def __repr__(self):
        return '<PushBullet [{}]>'.format(self.api_key)

    def devices(self):
        r = self._s.get(self.DEVICES_URL)
        if r.status_code == 401:
            return 'Authentication error'
        return [Device(device, self.api_key) for device in r.json()['devices'] if device['active'] is not False]


class Device(_PushBullet):
    def __init__(self, device, api_key=None):
        self.iden = device['iden']
        self.type = device['type']
        self.active = device['active']
        self.model = device['model']
        self.pushable = device['pushable']
        super(Device, self).__init__(api_key)

    def __repr__(self):
        return '<Device [{} - {}]>'.format(self.model, self.iden)

    def delete(self):
        self._s.delete('{}/{}'.format(self.DEVICES_URL, self.iden))

@@ -280,16 +280,76 @@
 25000000
+%0A    CONTACTS_URL = 'https://api.pushbullet.com/v2/contacts'
 %0A%0A    de
@@ -467,16 +467,31 @@
         
+ self.api_key =
  os.gete
@@ -840,16 +840,87 @@
 lf.iden%0A
+        if 'email' in locals():%0A            data%5B'email'%5D = self.email%0A
         
@@ -3207,16 +3207,202 @@
 False%5D%0A%0A
+    def contacts(self):%0A        r = self._s.get(self.CONTACTS_URL)%0A        return %5BContact(contact, self.api_key) for contact in r.json()%5B'contacts'%5D if contact%5B'active'%5D is not False%5D%0A%0A
 %0Aclass D
@@ -3541,47 +3541,8 @@
 e'%5D%0A
-        self.active = device%5B'active'%5D%0A
     
@@ -3845,8 +3845,425 @@
 .iden))%0A
+%0A%0Aclass Contact(_PushBullet):%0A    def __init__(self, contact, api_key=None):%0A        self.iden = contact%5B'iden'%5D%0A        self.email = contact%5B'email'%5D%0A        self.name = contact%5B'name'%5D%0A        super(Contact, self).__init__(api_key)%0A%0A    def __repr__(self):%0A        return '%3CContact %5B%7B%7D - %7B%7D%5D%3E'.format(self.name, self.email)%0A%0A    def delete(self):%0A        self._s.delete('%7B%7D/%7B%7D'.format(self.CONTACTS_URL, self.iden))

Add Contacts support