Repository: Flexget/Flexget

Issue:
PyLoad plugin fails with Internal API Error
I'm using pyload as packaged by http://spk.unzureichende.info/ for Synology, using 0.4.9-4, and the latest flexget.

The problem seems to be the way urllib does the request:

```
>>> from urllib import urlencode; from urllib2 import urlopen; urlopen('http://localhost:8000/api/login', urlencode({'a': 1}))
urllib2.HTTPError: HTTP Error 500: Internal Server Error
```

Strangly, it works using requests:

```
>>> import requests; requests.post('http://dollhouse:8000/api/login')
<Response [200]>
```

It turns out that this is because urllib2 only sets this Accpet-Encoding header:

```
Accept-Encoding: identity
```

Things look better when I add gzip manually:

```
>>> import urllib2; headers = { 'Accept' : '*/*', 'Accept-Encoding': 'identity, gzip'}; re = urllib2.Request('http://localhost:8000/api/login', "", headers); urllib2.urlopen(re)
<addinfourl at 41238752 whose fp = <socket._fileobject object at 0x27466d0>>
```

I should say that I am using pyload as packaged by http://spk.unzureichende.info/ for Synology, using 0.4.9-4.

I've also described the issue here:

https://github.com/pyload/pyload/issues/297



Discussion:

Resolving patch:
diff --git a/flexget/plugins/output/pyload.py b/flexget/plugins/output/pyload.py
--- a/flexget/plugins/output/pyload.py
+++ b/flexget/plugins/output/pyload.py
@@ -1,10 +1,10 @@
 # -*- coding: utf-8 -*-
 
 from __future__ import unicode_literals, division, absolute_import
-from urllib import urlencode, quote
-from urllib2 import urlopen, URLError, HTTPError
+from urllib import quote
+from requests.exceptions import RequestException
 from logging import getLogger
-from flexget.utils import json
+from flexget.utils import json, requests
 from flexget.plugin import register_plugin, PluginError
 from flexget import validator
 
@@ -88,7 +88,7 @@ def add_entries(self, task, config):
 
         try:
             self.check_login(task, config)
-        except URLError:
+        except IOError:
             raise PluginError('pyLoad not reachable', log)
         except PluginError:
             raise
@@ -111,7 +111,7 @@ def add_entries(self, task, config):
             result = query_api(api, "parseURLs", {"html": content, "url": url, "session": self.session})
 
             # parsed { plugins: [urls] }
-            parsed = json.loads(result.read())
+            parsed = result.json()
 
             urls = []
 
@@ -149,7 +149,7 @@ def add_entries(self, task, config):
                         'dest': dest,
                         'session': self.session}
 
-                pid = query_api(api, "addPackage", post).read()
+                pid = query_api(api, "addPackage", post).text
                 log.debug('added package pid: %s' % pid)
 
                 if folder:
@@ -167,7 +167,7 @@ def check_login(self, task, config):
             # Login
             post = {'username': config['username'], 'password': config['password']}
             result = query_api(url, "login", post)
-            response = json.loads(result.read())
+            response = result.json()
             if not response:
                 raise PluginError('Login failed', log)
             self.session = response.replace('"', '')
@@ -175,7 +175,7 @@ def check_login(self, task, config):
             try:
                 query_api(url, 'getServerVersion', {'session': self.session})
             except HTTPError as e:
-                if e.code == 403:  # Forbidden
+                if e.response.status_code == 403:  # Forbidden
                     self.session = None
                     return self.check_login(task, config)
                 else:
@@ -184,10 +184,15 @@ def check_login(self, task, config):
 
 def query_api(url, method, post=None):
     try:
-        return urlopen(url.rstrip("/") + "/" + method.strip("/"), urlencode(post) if post else None)
-    except HTTPError as e:
-        if e.code == 500:
-            raise PluginError('Internal API Error', log)
+        response = requests.request(
+            'post' if post is not None else 'get',
+            url.rstrip("/") + "/" + method.strip("/"),
+            data=post)
+        response.raise_for_status()
+        return response
+    except RequestException as e:
+        if e.response.status_code == 500:
+            raise PluginError('Internal API Error: <%s> <%s> <%s>' % (method, url, post), log)
         raise
 
 register_plugin(PluginPyLoad, 'pyload', api_ver=2)


Test patch: