Repository: Flexget/Flexget

Issue:
Notify (Pushbullet) Plugin Error.
Hi, since last week i have this error in my log. Up to this point everything worked without problems.
```
2019-11-13 10:30 ERROR    notify_entry  NexBox    'x-ratelimit-reset'
Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notify.py", line 104, in send_notification
    send_notification(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notification_framework.py", line 124, in send_notification
    title, message, rendered_config
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notifiers/pushbullet.py", line 89, in notify
    self.send_push(key, title, message, config.get('url'), d, 'device_iden')
  File "/usr/local/lib/python3.5/dist-packages/flexget/components/notify/notifiers/pushbullet.py", line 130, in send_push
    int(response.headers['X-Ratelimit-Reset'])
  File "/usr/local/lib/python3.5/dist-packages/requests/structures.py", line 52, in __getitem__
    return self._store[key.lower()][1]
KeyError: 'x-ratelimit-reset'
```
Flexget: 2.21.32
API: 1.5.0

Same with Flexget 3.0.8 and Python 3.8


Discussion:
Having the same problem. The push message goes trough, but these errors show up in the log.
From a simple test manually sending the message, I did not get the `X-Ratelimit-` fields on the response header of a regular push. Could they be sending those only when reaching the rate limit?

If that's the case (can't test it while not rate limited) omitting the following debug message should be enough.
https://github.com/Flexget/Flexget/blob/00bba32cd38127f82e6ceb67ce73d147c1f37652/flexget/components/notify/notifiers/pushbullet.py#L128-L137
> 
> 
> Having the same problem. The push message goes trough, but these errors show up in the log.
> From a simple test manually sending the message, I did not get the `X-Ratelimit-` fields on the response header of a regular push. Could they be sending those only when reaching the rate limit?
> 
> If that's the case (can't test it while not rate limited) omitting the following debug message should be enough.
> 
> https://github.com/Flexget/Flexget/blob/00bba32cd38127f82e6ceb67ce73d147c1f37652/flexget/components/notify/notifiers/pushbullet.py#L128-L137

No, it does not help.
```
2019-11-27 01:12 ERROR    notify_entry  Rutor_BDRip _1080p 'x-ratelimit-reset'
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/flexget/components/notify/notify.py", line 101, in send_notification
    send_notification(*args, **kwargs)
  File "/usr/local/lib/python3.8/site-packages/flexget/components/notify/notification_framework.py", line 121, in send_notification
    notifier_plugin.notify(
  File "/usr/local/lib/python3.8/site-packages/flexget/components/notify/notifiers/pushbullet.py", line 88, in notify
    self.send_push(key, title, message, config.get('url'), d, 'device_iden')
  File "/usr/local/lib/python3.8/site-packages/flexget/components/notify/notifiers/pushbullet.py", line 129, in send_push
    #            int(response.headers['X-Ratelimit-Reset'])
  File "/usr/local/lib/python3.8/site-packages/requests/structures.py", line 52, in __getitem__
    return self._store[key.lower()][1]
KeyError: 'x-ratelimit-reset'
```
Accidentally "fixed" the wrong plugin 🤣 
Shouldn't we fix here too? https://github.com/Flexget/Flexget/blob/6d927bc779ec2c10f59bde6bb9d6b3a0ae2adda2/flexget/components/notify/notifiers/pushbullet.py#L128
I'd think so
```
2019-11-30 16:03 ERROR    notify_entry  download-movies-1080p-discover 'x-ratelimit-reset'
Traceback (most recent call last):
  File ".\flexget\flexget\components\notify\notify.py", line 101, in send_notification
    send_notification(*args, **kwargs)
  File ".\flexget\flexget\components\notify\notification_framework.py", line 122, in send_notification
    title, message, rendered_config
  File ".\flexget\flexget\components\notify\notifiers\pushbullet.py", line 93, in notify
    self.send_push(key, title, message, config.get('url'))
  File ".\flexget\flexget\components\notify\notifiers\pushbullet.py", line 128, in send_push
    int(response.headers['X-Ratelimit-Reset'])
  File ".\flexget\lib\site-packages\requests\structures.py", line 52, in __getitem__
    return self._store[key.lower()][1]
KeyError: 'x-ratelimit-reset'
```

Resolving patch:
diff --git a/flexget/components/notify/notifiers/pushbullet.py b/flexget/components/notify/notifiers/pushbullet.py
--- a/flexget/components/notify/notifiers/pushbullet.py
+++ b/flexget/components/notify/notifiers/pushbullet.py
@@ -92,7 +92,8 @@ def notify(self, title, message, config):
             else:
                 self.send_push(key, title, message, config.get('url'))
 
-    def send_push(self, api_key, title, body, url=None, destination=None, destination_type=None):
+    @staticmethod
+    def send_push(api_key, title, body, url=None, destination=None, destination_type=None):
         push_type = 'link' if url else 'note'
         notification = {'type': push_type, 'title': title, 'body': body}
         if url:
@@ -124,16 +125,16 @@ def send_push(self, api_key, title, body, url=None, destination=None, destinatio
                 message = str(e)
             raise PluginWarning(message)
 
-        reset_time = datetime.datetime.fromtimestamp(
-            int(response.headers['X-Ratelimit-Reset'])
-        ).strftime('%Y-%m-%d %H:%M:%S')
-        remaining = response.headers['X-Ratelimit-Remaining']
-        log.debug(
-            'Pushbullet notification sent. Database operations remaining until next reset: %s. '
-            'Next reset at: %s',
-            remaining,
-            reset_time,
-        )
+        reset_time = response.headers.get('X-Ratelimit-Reset')
+        remaining = response.headers.get('X-Ratelimit-Remaining')
+        if reset_time and remaining:
+            reset_time = datetime.datetime.fromtimestamp(int(reset_time))
+            log.debug(
+                'Pushbullet notification sent. Database operations remaining until next reset: %s. '
+                'Next reset at: %s',
+                remaining,
+                reset_time,
+            )
 
 
 @event('plugin.register')


Test patch: