Skip to content

Commit

Permalink
Add a HTTP session to the plugin API.
Browse files Browse the repository at this point in the history
This HTTP session is shared between all
plugins loaded in the Livestreamer session.
  • Loading branch information
chrippa committed Mar 18, 2014
1 parent 9c36e32 commit 936e66d
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 3 deletions.
5 changes: 4 additions & 1 deletion src/livestreamer/plugin/api/__init__.py
Expand Up @@ -4,7 +4,9 @@

from types import ModuleType as module

__all__ = ["load_support_plugin"]
from .http_session import HTTPSession

__all__ = ["HTTPSession", "load_support_plugin", "http"]


def load_support_plugin(name):
Expand Down Expand Up @@ -72,3 +74,4 @@ def __getattr__(self, name):

support_plugin_path = "livestreamer.plugin.api.support_plugin"
sys.modules[support_plugin_path] = SupportPlugin("support_plugin")
http = None
78 changes: 78 additions & 0 deletions src/livestreamer/plugin/api/http_session.py
@@ -0,0 +1,78 @@
from requests import Session
from requests.exceptions import RequestException

from ...exceptions import PluginError
from ...utils import parse_json, parse_xml

__all__ = ["HTTPSession"]


def _parse_keyvalue_list(val):
for keyvalue in val.split(";"):
try:
key, value = keyvalue.split("=")
yield key.strip(), value.strip()
except ValueError:
continue


class HTTPSession(Session):
@classmethod
def json(cls, res, *args, **kwargs):
"""Parses JSON from a response."""
return parse_json(res.text, *args, **kwargs)

@classmethod
def xml(cls, res, *args, **kwargs):
"""Parses XML from a response."""
return parse_xml(res.text, *args, **kwargs)

def parse_cookies(self, cookies, **kwargs):
"""Parses a semi-colon delimited list of cookies.
Example: foo=bar;baz=qux
"""
for name, value in _parse_keyvalue_list(cookies):
self.cookies.set(name, value, **kwargs)

def parse_headers(self, headers):
"""Parses a semi-colon delimited list of headers.
Example: foo=bar;baz=qux
"""
for name, value in _parse_keyvalue_list(headers):
self.headers[name] = value

def parse_query_params(self, cookies, **kwargs):
"""Parses a semi-colon delimited list of query parameters.
Example: foo=bar;baz=qux
"""
for name, value in _parse_keyvalue_list(cookies):
self.params[name] = value

def request(self, method, url, *args, **kwargs):
exception = kwargs.pop("exception", PluginError)
headers = kwargs.pop("headers", {})
params = kwargs.pop("params", {})
session = kwargs.pop("session", None)
timeout = kwargs.pop("timeout", 20)

if session:
headers.update(session.headers)
params.update(session.params)

try:
res = Session.request(self, method, url,
headers=headers,
params=params,
timeout=timeout,
*args, **kwargs)
res.raise_for_status()
except (RequestException, IOError) as rerr:
err = exception("Unable to open URL: {url} ({err})".format(url=url,
err=rerr))
err.err = rerr
raise err

return res
7 changes: 5 additions & 2 deletions src/livestreamer/session.py
Expand Up @@ -8,6 +8,7 @@
from .exceptions import NoPluginError
from .logger import Logger
from .options import Options
from .plugin import api


def print_small_exception(start_after):
Expand Down Expand Up @@ -35,6 +36,7 @@ class Livestreamer(object):
options and log settings."""

def __init__(self):
self.http = api.HTTPSession()
self.options = Options({
"rtmpdump": is_win32 and "rtmpdump.exe" or "rtmpdump",
"rtmpdump-proxy": None,
Expand Down Expand Up @@ -157,13 +159,14 @@ def load_plugins(self, path):
try:
self.load_plugin(name, file, pathname, desc)
except Exception:
sys.stderr.write("Failed to load plugin "
"{0}:\n".format(name))
sys.stderr.write("Failed to load plugin {0}:\n".format(name))
print_small_exception("load_plugin")

continue

def load_plugin(self, name, file, pathname, desc):
# Set the global http session for this plugin
api.http = self.http
module = imp.load_module(name, file, pathname, desc)

if hasattr(module, "__plugin__"):
Expand Down

0 comments on commit 936e66d

Please sign in to comment.