Repository: streamlink/streamlink
Pull request #2801 (2020-02-16 02:07:57)

Added support for ATV and ATVMas in albavision plugin
Replaces PR [https://github.com/streamlink/streamlink/pull/2791](https://github.com/streamlink/streamlink/pull/2791)

codecov[bot]: # [Codecov](https://codecov.io/gh/streamlink/streamlink/pull/2801?src=pr&el=h1) Report
> Merging [#2801](https://codecov.io/gh/streamlink/streamlink/pull/2801?src=pr&el=desc) into [master](https://codecov.io/gh/streamlink/streamlink/commit/045f2c6f3f4aefd2f9f75d79c44bce92d1dbec98?src=pr&el=desc) will **decrease** coverage by `1.14%`.
> The diff coverage is `13.88%`.


```diff
@@            Coverage Diff             @@
##           master    #2801      +/-   ##
==========================================
- Coverage   52.87%   51.72%   -1.15%     
==========================================
  Files         246      248       +2     
  Lines       15428    15153     -275     
==========================================
- Hits         8157     7838     -319     
- Misses       7271     7315      +44
```

malvinas2: Next attempt

Patch:
diff --git a/docs/plugin_matrix.rst b/docs/plugin_matrix.rst
index 362c8325..152d4889 100644
--- a/docs/plugin_matrix.rst
+++ b/docs/plugin_matrix.rst
@@ -19,6 +19,7 @@ afreeca                 play.afreecatv.com   Yes   No
 albavision              - tvc.com.ec         Yes   No    Some streams are geo-restricted.
                         - rts.com.ec
                         - elnueve.com.ar
+                        - atv.pe
 aljazeeraen             aljazeera.com        Yes   Yes   English version of the site.
 animelab                animelab.com         --    Yes   Requires a login. Streams may be geo-restricted to Australia and New Zealand.
 app17                   17app.co             Yes   --
diff --git a/src/streamlink/plugins/albavision.py b/src/streamlink/plugins/albavision.py
index 21e6dfe4..5dde7329 100644
--- a/src/streamlink/plugins/albavision.py
+++ b/src/streamlink/plugins/albavision.py
@@ -1,17 +1,18 @@
 """
 Support for the live streams on Albavision sites
-    - http://www.tvc.com.ec
-    - http://www.rts.com.ec
-    - https://www.elnueve.com.ar
+    - http://www.tvc.com.ec/envivo
+    - http://www.rts.com.ec/envivo
+    - http://www.elnueve.com.ar/en-vivo
+    - http://www.atv.pe/envivo/ATV
+    - http://www.atv.pe/envivo/ATVMas
 """
 import logging
 import re
 import time
 
 from streamlink import PluginError
-from streamlink.compat import quote, urlencode
+from streamlink.compat import quote, urlencode, urlparse
 from streamlink.plugin import Plugin
-from streamlink.plugin.api.utils import itertags
 from streamlink.stream import HLSStream
 from streamlink.utils import update_scheme
 
@@ -19,16 +20,18 @@ log = logging.getLogger(__name__)
 
 
 class Albavision(Plugin):
-    _url_re = re.compile(r"https?://(?:www\.)?(tvc.com.ec|rts.com.ec|elnueve.com.ar)/en-?vivo")
+    _url_re = re.compile(r"https?://(?:www\.)?(tvc.com.ec|rts.com.ec|elnueve.com.ar|atv.pe)/en-?vivo(?:/ATV(?:Mas)?)?")
     _token_input_re = re.compile(r"Math.floor\(Date.now\(\) / 3600000\),'([a-f0-9OK]+)'")
     _live_url_re = re.compile(r"LIVE_URL = '(.*?)';")
     _playlist_re = re.compile(r"file:\s*'(http.*m3u8)'")
     _token_url_re = re.compile(r"https://.*/token/.*?\?rsk=")
 
     _channel_urls = {
-        'Quito': 'http://d3aacg6baj4jn0.cloudfront.net/reproductor_rts_o_quito.html?iut=',
+        'ATV': 'http://dgrzfw9otv9ra.cloudfront.net/player_atv.html?iut=',
+        'ATVMas': 'http://dgrzfw9otv9ra.cloudfront.net/player_atv_mas.html?iut=',
+        'Canal5': 'http://dxejh4fchgs18.cloudfront.net/player_televicentro.html?iut=',
         'Guayaquil': 'http://d2a6tcnofawcbm.cloudfront.net/player_rts.html?iut=',
-        'Canal5': 'http://dxejh4fchgs18.cloudfront.net/player_televicentro.html?iut='
+        'Quito': 'http://d3aacg6baj4jn0.cloudfront.net/reproductor_rts_o_quito.html?iut=',
     }
 
     def __init__(self, url):
@@ -45,13 +48,12 @@ class Albavision(Plugin):
             self._page = self.session.http.get(self.url)
         return self._page
 
-    def _get_token_url(self):
-        token = self._get_live_url_token()
+    def _get_token_url(self, channelnumber):
+        token = self._get_live_url_token(channelnumber)
         if token:
-            m = self._token_url_re.search(self.page.text)
-            token_url = m and m.group(0)
+            m = self._token_url_re.findall(self.page.text)
+            token_url = m and m[channelnumber]
             if token_url:
-                log.debug("token_url={0}{1}".format(token_url, token))
                 return token_url + token
         else:
             log.error("Could not find site token")
@@ -66,18 +68,19 @@ class Albavision(Plugin):
             token_out[i], token_out[p] = token_out[p], token_out[i]
         token_out = ''.join(token_out)
         if token_out.endswith("OK"):
-            return token_out[:-2]  # return token without OK suffix
+            return token_out[:-2]
         else:
             log.error("Invalid site token: {0} => {1}".format(token_in, token_out))
 
-    def _get_live_url_token(self):
-        m = self._token_input_re.search(self.page.text)
+    def _get_live_url_token(self, channelnumber):
+        m = self._token_input_re.findall(self.page.text)
+        log.debug("Token input: {0}".format(m[channelnumber]))
         if m:
             date = int(time.time() // 3600)
-            return self.transform_token(m.group(1), date) or self.transform_token(m.group(1), date - 1)
+            return self.transform_token(m[channelnumber], date) or self.transform_token(m[channelnumber], date - 1)
 
-    def _get_token(self):
-        token_url = self._get_token_url()
+    def _get_token(self, channelnumber):
+        token_url = self._get_token_url(channelnumber)
         if token_url:
             res = self.session.http.get(token_url)
             data = self.session.http.json(res)
@@ -88,16 +91,24 @@ class Albavision(Plugin):
         m = self._live_url_re.search(self.page.text)
         playlist_url = m and update_scheme(self.url, m.group(1))
         player_url = self.url
-        token = self._get_token()
-
+        live_channel = None
+        p = urlparse(player_url)
+        channelnumber = 0
+        if p.netloc.endswith("tvc.com.ec"):
+            live_channel = "Canal5"
+        elif p.netloc.endswith("rts.com.ec"):
+            live_channel = "Guayaquil"
+        elif p.netloc.endswith("atv.pe"):
+            if p.path.endswith(("ATVMas", "ATVMas/")):
+                live_channel = "ATVMas"
+                channelnumber = 1
+            else:
+                live_channel = "ATV"
+        token = self._get_token(channelnumber)
+        log.debug("token {0}".format(token))
         if playlist_url:
             log.debug("Found playlist URL in the page")
         else:
-            live_channel = None
-            for div in itertags(self.page.text, "div"):
-                if div.attributes.get("id") == "botonLive":
-                    live_channel = div.attributes.get("data-canal")
-
             if live_channel:
                 log.debug("Live channel: {0}".format(live_channel))
                 player_url = self._channel_urls[live_channel] + quote(token)


Test patch:
diff --git a/tests/plugins/test_albavision.py b/tests/plugins/test_albavision.py
index d90cf864..e522d5bf 100644
--- a/tests/plugins/test_albavision.py
+++ b/tests/plugins/test_albavision.py
@@ -10,6 +10,8 @@ class TestPluginAlbavision:
         ("https://www.elnueve.com.ar/en-vivo",),
         ("http://www.rts.com.ec/envivo",),
         ("https://www.tvc.com.ec/envivo",),
+        ("http://www.atv.pe/envivo/ATV",),
+        ("http://www.atv.pe/envivo/ATVMas",),
     ]
     invalid_urls = [
         ("https://news.now.com/home/local",),