Repository: streamlink/streamlink
Pull request #1429 (2018-01-13 08:41:28)

[zengatv] New Plugin for zengatv.com
Fixed streamlink/streamlink#890



Patch:
diff --git a/docs/plugin_matrix.rst b/docs/plugin_matrix.rst
index 796c18e6..4d5da31c 100644
--- a/docs/plugin_matrix.rst
+++ b/docs/plugin_matrix.rst
@@ -267,6 +267,7 @@ zattoo              - zattoo.com         Yes   Yes
                     - nettv.net... [10]_
                     - tvonline.ewe.de
 zdf_mediathek       zdf.de               Yes   Yes   Streams may be geo-restricted to Germany.
+zengatv             zengatv.com          Yes   No
 zhanqitv            zhanqi.tv            Yes   No
 =================== ==================== ===== ===== ===========================
 
diff --git a/src/streamlink/plugins/zengatv.py b/src/streamlink/plugins/zengatv.py
new file mode 100644
index 00000000..24c79a36
--- /dev/null
+++ b/src/streamlink/plugins/zengatv.py
@@ -0,0 +1,48 @@
+import re
+
+from streamlink.plugin import Plugin
+from streamlink.plugin.api import http
+from streamlink.plugin.api import useragents
+from streamlink.stream import HLSStream
+
+
+class ZengaTV(Plugin):
+    """Streamlink Plugin for livestreams on zengatv.com"""
+
+    _url_re = re.compile(r"https?://(www\.)?zengatv\.com/\w+")
+    _id_re = re.compile(r"""id=(?P<q>["'])dvrid(?P=q)\svalue=(?P=q)(?P<id>[^"']+)(?P=q)""")
+    _id_2_re = re.compile(r"""LivePlayer\(.+["'](?P<id>D\d+)["']""")
+
+    api_url = "http://www.zengatv.com/changeResulation/"
+
+    @classmethod
+    def can_handle_url(cls, url):
+        return cls._url_re.match(url) is not None
+
+    def _get_streams(self):
+        headers = {
+            "User-Agent": useragents.FIREFOX,
+            "Referer": self.url,
+        }
+
+        res = http.get(self.url, headers=headers)
+        for id_re in (self._id_re, self._id_2_re):
+            m = id_re.search(res.text)
+            if not m:
+                continue
+            break
+
+        if not m:
+            self.logger.error("No video id found")
+            return
+
+        dvr_id = m.group("id")
+        self.logger.debug("Found video id: {0}".format(dvr_id))
+        data = {"feed": "hd", "dvrId": dvr_id}
+        res = http.post(self.api_url, headers=headers, data=data)
+        if res.status_code == 200:
+            for s in HLSStream.parse_variant_playlist(self.session, res.text, headers=headers).items():
+                yield s
+
+
+__plugin__ = ZengaTV


Test patch:
diff --git a/tests/test_plugin_zengatv.py b/tests/test_plugin_zengatv.py
new file mode 100644
index 00000000..5566b004
--- /dev/null
+++ b/tests/test_plugin_zengatv.py
@@ -0,0 +1,22 @@
+import unittest
+
+from streamlink.plugins.zengatv import ZengaTV
+
+
+class TestPluginZengaTV(unittest.TestCase):
+    def test_can_handle_url(self):
+        should_match = [
+            "http://www.zengatv.com/indiatoday.html",
+            "http://www.zengatv.com/live/87021a6d-411e-11e2-b4c6-7071bccc85ac.html",
+            "http://zengatv.com/indiatoday.html",
+            "http://zengatv.com/live/87021a6d-411e-11e2-b4c6-7071bccc85ac.html",
+        ]
+        for url in should_match:
+            self.assertTrue(ZengaTV.can_handle_url(url))
+
+        should_not_match = [
+            "http://www.zengatv.com",
+            "http://www.zengatv.com/"
+        ]
+        for url in should_not_match:
+            self.assertFalse(ZengaTV.can_handle_url(url))