Skip to content

Commit 65652a3

Browse files
committed
plugin.api: Add StreamMapper, a helper to map data to stream objects.
1 parent a008c3f commit 65652a3

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

src/livestreamer/plugin/api/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
from types import ModuleType as module
44

55
from .http_session import HTTPSession
6+
from .mapper import StreamMapper
67
from .support_plugin import load_support_plugin
78

8-
__all__ = ["HTTPSession", "load_support_plugin", "http"]
9+
__all__ = ["HTTPSession", "StreamMapper", "load_support_plugin", "http"]
910

1011

1112
class SupportPlugin(module):
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from functools import partial
2+
from itertools import product
3+
from operator import eq
4+
5+
6+
class StreamMapper(object):
7+
"""The stream mapper can be used to simplify the process of creating
8+
stream objects from data.
9+
10+
:param cmp: This callable is used to compare each mapping's key
11+
with a value.
12+
"""
13+
def __init__(self, cmp=eq):
14+
self._map = []
15+
self._cmp = cmp
16+
17+
def map(self, key, func, *args, **kwargs):
18+
"""Creates a key-function mapping.
19+
20+
The return value from the function should be either
21+
- A tuple containing a name and stream
22+
- A iterator of tuples containing a name and stream
23+
24+
Any extra arguments will be passed to the function.
25+
"""
26+
self._map.append((key, partial(func, *args, **kwargs)))
27+
28+
def _cmp_filter(self, args):
29+
value, (key, func) = args
30+
return self._cmp(key, value)
31+
32+
def _mapped_func(self, args):
33+
value, (key, func) = args
34+
return func(value)
35+
36+
def __call__(self, values):
37+
"""Runs through each value and transform it with a mapped function."""
38+
values = product(values, self._map)
39+
for value in map(self._mapped_func, filter(self._cmp_filter, values)):
40+
if isinstance(value, tuple) and len(value) == 2:
41+
yield value
42+
else:
43+
try:
44+
# TODO: Replace with "yield from" when dropping Python 2.
45+
for __ in value:
46+
yield __
47+
except TypeError:
48+
# Non-iterable returned
49+
continue

0 commit comments

Comments
 (0)