Skip to content

Commit

Permalink
plugin.api: Add StreamMapper, a helper to map data to stream objects.
Browse files Browse the repository at this point in the history
  • Loading branch information
chrippa committed Nov 23, 2014
1 parent a008c3f commit 65652a3
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/livestreamer/plugin/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
from types import ModuleType as module

from .http_session import HTTPSession
from .mapper import StreamMapper
from .support_plugin import load_support_plugin

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


class SupportPlugin(module):
Expand Down
49 changes: 49 additions & 0 deletions src/livestreamer/plugin/api/mapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from functools import partial
from itertools import product
from operator import eq


class StreamMapper(object):
"""The stream mapper can be used to simplify the process of creating
stream objects from data.
:param cmp: This callable is used to compare each mapping's key
with a value.
"""
def __init__(self, cmp=eq):
self._map = []
self._cmp = cmp

def map(self, key, func, *args, **kwargs):
"""Creates a key-function mapping.
The return value from the function should be either
- A tuple containing a name and stream
- A iterator of tuples containing a name and stream
Any extra arguments will be passed to the function.
"""
self._map.append((key, partial(func, *args, **kwargs)))

def _cmp_filter(self, args):
value, (key, func) = args
return self._cmp(key, value)

def _mapped_func(self, args):
value, (key, func) = args
return func(value)

def __call__(self, values):
"""Runs through each value and transform it with a mapped function."""
values = product(values, self._map)
for value in map(self._mapped_func, filter(self._cmp_filter, values)):
if isinstance(value, tuple) and len(value) == 2:
yield value
else:
try:
# TODO: Replace with "yield from" when dropping Python 2.
for __ in value:
yield __
except TypeError:
# Non-iterable returned
continue

0 comments on commit 65652a3

Please sign in to comment.