prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Euronews plugin broken
  I dig up EuroNews plugin which is broken since December 2014.
  
  https://github.com/chrippa/livestreamer/issues/626
  
  </issue>
  <code>
  [start of src/streamlink/plugins/euronews.py]
  1 import re
  2 
  3 from itertools import chain
  4 
  5 from streamlink.compat import urlparse
  6 from streamlink.plugin import Plugin
  7 from streamlink.plugin.api import http
  8 from streamlink.stream import HLSStream, HTTPStream
  9 
  10 from streamlink.plugin.api.support_plugin import common_jwplayer as jwplayer
  11 
  12 _url_re = re.compile("http(s)?://(\w+\.)?euronews.com")
  13 
  14 
  15 class Euronews(Plugin):
  16     @classmethod
  17     def can_handle_url(self, url):
  18         return _url_re.match(url)
  19 
  20     def _create_stream(self, source):
  21         url = source["file"]
  22 
  23         if urlparse(url).path.endswith("m3u8"):
  24             streams = HLSStream.parse_variant_playlist(self.session, url)
  25 
  26             # TODO: Replace with "yield from" when dropping Python 2.
  27             for stream in streams.items():
  28                 yield stream
  29         else:
  30             name = source.get("label", "vod")
  31             yield name, HTTPStream(self.session, url)
  32 
  33     def _get_streams(self):
  34         res = http.get(self.url)
  35         playlist = jwplayer.parse_playlist(res)
  36         if not playlist:
  37             return
  38 
  39         for item in playlist:
  40             streams = map(self._create_stream, item["sources"])
  41 
  42             # TODO: Replace with "yield from" when dropping Python 2.
  43             for stream in chain.from_iterable(streams):
  44                 yield stream
  45 
  46 __plugin__ = Euronews
  47
  [end of src/streamlink/plugins/euronews.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/src/streamlink/plugins/euronews.py b/src/streamlink/plugins/euronews.py
  --- a/src/streamlink/plugins/euronews.py
  +++ b/src/streamlink/plugins/euronews.py
  @@ -1,46 +1,77 @@
   import re
   
  -from itertools import chain
  -
  -from streamlink.compat import urlparse
   from streamlink.plugin import Plugin
   from streamlink.plugin.api import http
  +from streamlink.plugin.api import validate
   from streamlink.stream import HLSStream, HTTPStream
   
  -from streamlink.plugin.api.support_plugin import common_jwplayer as jwplayer
  -
  -_url_re = re.compile("http(s)?://(\w+\.)?euronews.com")
  -
   
   class Euronews(Plugin):
  -    @classmethod
  -    def can_handle_url(self, url):
  -        return _url_re.match(url)
  +    _url_re = re.compile("http(?:s)?://(\w+)\.?euronews.com/(live|.*)")
  +    _re_vod = re.compile(r'<meta\s+property="og:video"\s+content="(http.*?)"\s*/>')
  +    _live_api_url = "http://fr.euronews.com/api/watchlive.json"
  +    _live_schema = validate.Schema({
  +        u"url": validate.url()
  +    })
  +    _stream_api_schema = validate.Schema({
  +        u'status': u'ok',
  +        u'primary': {
  +            validate.text: {
  +                validate.optional(u'hls'): validate.url(),
  +                validate.optional(u'rtsp'): validate.url(scheme="rtsp")
  +            }
  +        },
  +        validate.optional(u'backup'): {
  +            validate.text: {
  +                validate.optional(u'hls'): validate.url(),
  +                validate.optional(u'rtsp'): validate.url(scheme="rtsp")
  +            }
  +        }
  +    })
   
  -    def _create_stream(self, source):
  -        url = source["file"]
  +    @classmethod
  +    def can_handle_url(cls, url):
  +        return cls._url_re.match(url)
   
  -        if urlparse(url).path.endswith("m3u8"):
  -            streams = HLSStream.parse_variant_playlist(self.session, url)
  +    def _get_vod_stream(self):
  +        """
  +        Find the VOD video url
  +        :return: video url
  +        """
  +        res = http.get(self.url)
  +        video_urls = self._re_vod.findall(res.text)
  +        if len(video_urls):
  +            return dict(vod=HTTPStream(self.session, video_urls[0]))
   
  -            # TODO: Replace with "yield from" when dropping Python 2.
  -            for stream in streams.items():
  -                yield stream
  -        else:
  -            name = source.get("label", "vod")
  -            yield name, HTTPStream(self.session, url)
  +    def _get_live_streams(self, language):
  +        """
  +        Get the live stream in a particular language
  +        :param language:
  +        :return:
  +        """
  +        res = http.get(self._live_api_url)
  +        live_res = http.json(res, schema=self._live_schema)
  +        api_res = http.get(live_res[u"url"])
  +        stream_data = http.json(api_res, schema=self._stream_api_schema)
  +        # find the stream in the requested language
  +        if language in stream_data[u'primary']:
  +            playlist_url = stream_data[u'primary'][language][u"hls"]
  +            return HLSStream.parse_variant_playlist(self.session, playlist_url)
   
       def _get_streams(self):
  -        res = http.get(self.url)
  -        playlist = jwplayer.parse_playlist(res)
  -        if not playlist:
  -            return
  +        """
  +        Find the streams for euronews
  +        :return:
  +        """
  +        match = self._url_re.match(self.url)
  +        language, path = match.groups()
   
  -        for item in playlist:
  -            streams = map(self._create_stream, item["sources"])
  +        # remap domain to language (default to english)
  +        language = {"www": "en", "": "en", "arabic": "ar"}.get(language, language)
   
  -            # TODO: Replace with "yield from" when dropping Python 2.
  -            for stream in chain.from_iterable(streams):
  -                yield stream
  +        if path == "live":
  +            return self._get_live_streams(language)
  +        else:
  +            return self._get_vod_stream()
   
   __plugin__ = Euronews
  
verification_info: {"golden_diff": "diff --git a/src/streamlink/plugins/euronews.py b/src/streamlink/plugins/euronews.py\n--- a/src/streamlink/plugins/euronews.py\n+++ b/src/streamlink/plugins/euronews.py\n@@ -1,46 +1,77 @@\n import re\n \n-from itertools import chain\n-\n-from streamlink.compat import urlparse\n from streamlink.plugin import Plugin\n from streamlink.plugin.api import http\n+from streamlink.plugin.api import validate\n from streamlink.stream import HLSStream, HTTPStream\n \n-from streamlink.plugin.api.support_plugin import common_jwplayer as jwplayer\n-\n-_url_re = re.compile(\"http(s)?://(\\w+\\.)?euronews.com\")\n-\n \n class Euronews(Plugin):\n-    @classmethod\n-    def can_handle_url(self, url):\n-        return _url_re.match(url)\n+    _url_re = re.compile(\"http(?:s)?://(\\w+)\\.?euronews.com/(live|.*)\")\n+    _re_vod = re.compile(r'<meta\\s+property=\"og:video\"\\s+content=\"(http.*?)\"\\s*/>')\n+    _live_api_url = \"http://fr.euronews.com/api/watchlive.json\"\n+    _live_schema = validate.Schema({\n+        u\"url\": validate.url()\n+    })\n+    _stream_api_schema = validate.Schema({\n+        u'status': u'ok',\n+        u'primary': {\n+            validate.text: {\n+                validate.optional(u'hls'): validate.url(),\n+                validate.optional(u'rtsp'): validate.url(scheme=\"rtsp\")\n+            }\n+        },\n+        validate.optional(u'backup'): {\n+            validate.text: {\n+                validate.optional(u'hls'): validate.url(),\n+                validate.optional(u'rtsp'): validate.url(scheme=\"rtsp\")\n+            }\n+        }\n+    })\n \n-    def _create_stream(self, source):\n-        url = source[\"file\"]\n+    @classmethod\n+    def can_handle_url(cls, url):\n+        return cls._url_re.match(url)\n \n-        if urlparse(url).path.endswith(\"m3u8\"):\n-            streams = HLSStream.parse_variant_playlist(self.session, url)\n+    def _get_vod_stream(self):\n+        \"\"\"\n+        Find the VOD video url\n+        :return: video url\n+        \"\"\"\n+        res = http.get(self.url)\n+        video_urls = self._re_vod.findall(res.text)\n+        if len(video_urls):\n+            return dict(vod=HTTPStream(self.session, video_urls[0]))\n \n-            # TODO: Replace with \"yield from\" when dropping Python 2.\n-            for stream in streams.items():\n-                yield stream\n-        else:\n-            name = source.get(\"label\", \"vod\")\n-            yield name, HTTPStream(self.session, url)\n+    def _get_live_streams(self, language):\n+        \"\"\"\n+        Get the live stream in a particular language\n+        :param language:\n+        :return:\n+        \"\"\"\n+        res = http.get(self._live_api_url)\n+        live_res = http.json(res, schema=self._live_schema)\n+        api_res = http.get(live_res[u\"url\"])\n+        stream_data = http.json(api_res, schema=self._stream_api_schema)\n+        # find the stream in the requested language\n+        if language in stream_data[u'primary']:\n+            playlist_url = stream_data[u'primary'][language][u\"hls\"]\n+            return HLSStream.parse_variant_playlist(self.session, playlist_url)\n \n     def _get_streams(self):\n-        res = http.get(self.url)\n-        playlist = jwplayer.parse_playlist(res)\n-        if not playlist:\n-            return\n+        \"\"\"\n+        Find the streams for euronews\n+        :return:\n+        \"\"\"\n+        match = self._url_re.match(self.url)\n+        language, path = match.groups()\n \n-        for item in playlist:\n-            streams = map(self._create_stream, item[\"sources\"])\n+        # remap domain to language (default to english)\n+        language = {\"www\": \"en\", \"\": \"en\", \"arabic\": \"ar\"}.get(language, language)\n \n-            # TODO: Replace with \"yield from\" when dropping Python 2.\n-            for stream in chain.from_iterable(streams):\n-                yield stream\n+        if path == \"live\":\n+            return self._get_live_streams(language)\n+        else:\n+            return self._get_vod_stream()\n \n __plugin__ = Euronews\n", "issue": "Euronews plugin broken\nI dig up EuroNews plugin which is broken since December 2014.\r\n\r\nhttps://github.com/chrippa/livestreamer/issues/626\n", "before_files": [{"content": "import re\n\nfrom itertools import chain\n\nfrom streamlink.compat import urlparse\nfrom streamlink.plugin import Plugin\nfrom streamlink.plugin.api import http\nfrom streamlink.stream import HLSStream, HTTPStream\n\nfrom streamlink.plugin.api.support_plugin import common_jwplayer as jwplayer\n\n_url_re = re.compile(\"http(s)?://(\\w+\\.)?euronews.com\")\n\n\nclass Euronews(Plugin):\n    @classmethod\n    def can_handle_url(self, url):\n        return _url_re.match(url)\n\n    def _create_stream(self, source):\n        url = source[\"file\"]\n\n        if urlparse(url).path.endswith(\"m3u8\"):\n            streams = HLSStream.parse_variant_playlist(self.session, url)\n\n            # TODO: Replace with \"yield from\" when dropping Python 2.\n            for stream in streams.items():\n                yield stream\n        else:\n            name = source.get(\"label\", \"vod\")\n            yield name, HTTPStream(self.session, url)\n\n    def _get_streams(self):\n        res = http.get(self.url)\n        playlist = jwplayer.parse_playlist(res)\n        if not playlist:\n            return\n\n        for item in playlist:\n            streams = map(self._create_stream, item[\"sources\"])\n\n            # TODO: Replace with \"yield from\" when dropping Python 2.\n            for stream in chain.from_iterable(streams):\n                yield stream\n\n__plugin__ = Euronews\n", "path": "src/streamlink/plugins/euronews.py"}]}