prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  [bug] BTV plugin needs updating
  ## Bug Report
  - [x] This is a bug report and I have read the contribution guidelines.
  
  
  ### Description
  The location of the BTV livestream has moved to https://btvplus.bg/live/
  **Edit**: Livestreaming no longer requires a user to login, so that can be removed from the plugin info page.
  
  
  ### Expected / Actual behavior
  Streamlink should be able to handle the link.
  
  
  ### Reproduction steps / Explicit stream URLs to test
  1. streamlink https://btvplus.bg/live/ best 
  2. error: No plugin can handle URL: https://btvplus.bg/live/
  
  </issue>
  <code>
  [start of src/streamlink/plugins/btv.py]
  1 from __future__ import print_function
  2 import re
  3 
  4 from streamlink import PluginError
  5 from streamlink.plugin import Plugin
  6 from streamlink.plugin.api import validate
  7 from streamlink.stream import HLSStream
  8 from streamlink.utils import parse_json
  9 from streamlink.plugin import PluginArgument, PluginArguments
  10 
  11 
  12 class BTV(Plugin):
  13     arguments = PluginArguments(
  14         PluginArgument(
  15             "username",
  16             metavar="USERNAME",
  17             requires=["password"],
  18             help="""
  19         A BTV username required to access any stream.
  20         """
  21         ),
  22         PluginArgument(
  23             "password",
  24             sensitive=True,
  25             metavar="PASSWORD",
  26             help="""
  27         A BTV account password to use with --btv-username.
  28         """
  29         )
  30     )
  31     url_re = re.compile(r"https?://(?:www\.)?btv\.bg/live/?")
  32 
  33     api_url = "http://www.btv.bg/lbin/global/player_config.php"
  34     check_login_url = "http://www.btv.bg/lbin/userRegistration/check_user_login.php"
  35     login_url = "https://www.btv.bg/bin/registration2/login.php?action=login&settings=0"
  36 
  37     media_id_re = re.compile(r"media_id=(\d+)")
  38     src_re = re.compile(r"src: \"(http.*?)\"")
  39     api_schema = validate.Schema(
  40         validate.all(
  41             {"status": "ok", "config": validate.text},
  42             validate.get("config"),
  43             validate.all(
  44                 validate.transform(src_re.search),
  45                 validate.any(
  46                     None,
  47                     validate.get(1),
  48                     validate.url()
  49                 )
  50             )
  51         )
  52     )
  53 
  54     @classmethod
  55     def can_handle_url(cls, url):
  56         return cls.url_re.match(url) is not None
  57 
  58     def login(self, username, password):
  59         res = self.session.http.post(self.login_url, data={"username": username, "password": password})
  60         if "success_logged_in" in res.text:
  61             return True
  62         else:
  63             return False
  64 
  65     def get_hls_url(self, media_id):
  66         res = self.session.http.get(self.api_url, params=dict(media_id=media_id))
  67         try:
  68             return parse_json(res.text, schema=self.api_schema)
  69         except PluginError:
  70             return
  71 
  72     def _get_streams(self):
  73         if not self.options.get("username") or not self.options.get("password"):
  74             self.logger.error("BTV requires registration, set the username and password"
  75                               " with --btv-username and --btv-password")
  76         elif self.login(self.options.get("username"), self.options.get("password")):
  77             res = self.session.http.get(self.url)
  78             media_match = self.media_id_re.search(res.text)
  79             media_id = media_match and media_match.group(1)
  80             if media_id:
  81                 self.logger.debug("Found media id: {0}", media_id)
  82                 stream_url = self.get_hls_url(media_id)
  83                 if stream_url:
  84                     return HLSStream.parse_variant_playlist(self.session, stream_url)
  85         else:
  86             self.logger.error("Login failed, a valid username and password is required")
  87 
  88 
  89 __plugin__ = BTV
  90
  [end of src/streamlink/plugins/btv.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/btv.py b/src/streamlink/plugins/btv.py
  --- a/src/streamlink/plugins/btv.py
  +++ b/src/streamlink/plugins/btv.py
  @@ -1,38 +1,30 @@
  -from __future__ import print_function
  +import argparse
  +import logging
   import re
   
  -from streamlink import PluginError
  -from streamlink.plugin import Plugin
  +from streamlink.plugin import Plugin, PluginArguments, PluginArgument
   from streamlink.plugin.api import validate
   from streamlink.stream import HLSStream
   from streamlink.utils import parse_json
  -from streamlink.plugin import PluginArgument, PluginArguments
  +
  +log = logging.getLogger(__name__)
   
   
   class BTV(Plugin):
       arguments = PluginArguments(
           PluginArgument(
               "username",
  -            metavar="USERNAME",
  -            requires=["password"],
  -            help="""
  -        A BTV username required to access any stream.
  -        """
  +            help=argparse.SUPPRESS
           ),
           PluginArgument(
               "password",
               sensitive=True,
  -            metavar="PASSWORD",
  -            help="""
  -        A BTV account password to use with --btv-username.
  -        """
  +            help=argparse.SUPPRESS
           )
       )
  -    url_re = re.compile(r"https?://(?:www\.)?btv\.bg/live/?")
   
  -    api_url = "http://www.btv.bg/lbin/global/player_config.php"
  -    check_login_url = "http://www.btv.bg/lbin/userRegistration/check_user_login.php"
  -    login_url = "https://www.btv.bg/bin/registration2/login.php?action=login&settings=0"
  +    url_re = re.compile(r"https?://(?:www\.)?btvplus\.bg/live/?")
  +    api_url = "https://btvplus.bg/lbin/v3/btvplus/player_config.php"
   
       media_id_re = re.compile(r"media_id=(\d+)")
       src_re = re.compile(r"src: \"(http.*?)\"")
  @@ -55,35 +47,19 @@
       def can_handle_url(cls, url):
           return cls.url_re.match(url) is not None
   
  -    def login(self, username, password):
  -        res = self.session.http.post(self.login_url, data={"username": username, "password": password})
  -        if "success_logged_in" in res.text:
  -            return True
  -        else:
  -            return False
  -
       def get_hls_url(self, media_id):
           res = self.session.http.get(self.api_url, params=dict(media_id=media_id))
  -        try:
  -            return parse_json(res.text, schema=self.api_schema)
  -        except PluginError:
  -            return
  +        return parse_json(res.text, schema=self.api_schema)
   
       def _get_streams(self):
  -        if not self.options.get("username") or not self.options.get("password"):
  -            self.logger.error("BTV requires registration, set the username and password"
  -                              " with --btv-username and --btv-password")
  -        elif self.login(self.options.get("username"), self.options.get("password")):
  -            res = self.session.http.get(self.url)
  -            media_match = self.media_id_re.search(res.text)
  -            media_id = media_match and media_match.group(1)
  -            if media_id:
  -                self.logger.debug("Found media id: {0}", media_id)
  -                stream_url = self.get_hls_url(media_id)
  -                if stream_url:
  -                    return HLSStream.parse_variant_playlist(self.session, stream_url)
  -        else:
  -            self.logger.error("Login failed, a valid username and password is required")
  +        res = self.session.http.get(self.url)
  +        media_match = self.media_id_re.search(res.text)
  +        media_id = media_match and media_match.group(1)
  +        if media_id:
  +            log.debug("Found media id: {0}", media_id)
  +            stream_url = self.get_hls_url(media_id)
  +            if stream_url:
  +                return HLSStream.parse_variant_playlist(self.session, stream_url)
   
   
   __plugin__ = BTV
  
verification_info: {"golden_diff": "diff --git a/src/streamlink/plugins/btv.py b/src/streamlink/plugins/btv.py\n--- a/src/streamlink/plugins/btv.py\n+++ b/src/streamlink/plugins/btv.py\n@@ -1,38 +1,30 @@\n-from __future__ import print_function\n+import argparse\n+import logging\n import re\n \n-from streamlink import PluginError\n-from streamlink.plugin import Plugin\n+from streamlink.plugin import Plugin, PluginArguments, PluginArgument\n from streamlink.plugin.api import validate\n from streamlink.stream import HLSStream\n from streamlink.utils import parse_json\n-from streamlink.plugin import PluginArgument, PluginArguments\n+\n+log = logging.getLogger(__name__)\n \n \n class BTV(Plugin):\n     arguments = PluginArguments(\n         PluginArgument(\n             \"username\",\n-            metavar=\"USERNAME\",\n-            requires=[\"password\"],\n-            help=\"\"\"\n-        A BTV username required to access any stream.\n-        \"\"\"\n+            help=argparse.SUPPRESS\n         ),\n         PluginArgument(\n             \"password\",\n             sensitive=True,\n-            metavar=\"PASSWORD\",\n-            help=\"\"\"\n-        A BTV account password to use with --btv-username.\n-        \"\"\"\n+            help=argparse.SUPPRESS\n         )\n     )\n-    url_re = re.compile(r\"https?://(?:www\\.)?btv\\.bg/live/?\")\n \n-    api_url = \"http://www.btv.bg/lbin/global/player_config.php\"\n-    check_login_url = \"http://www.btv.bg/lbin/userRegistration/check_user_login.php\"\n-    login_url = \"https://www.btv.bg/bin/registration2/login.php?action=login&settings=0\"\n+    url_re = re.compile(r\"https?://(?:www\\.)?btvplus\\.bg/live/?\")\n+    api_url = \"https://btvplus.bg/lbin/v3/btvplus/player_config.php\"\n \n     media_id_re = re.compile(r\"media_id=(\\d+)\")\n     src_re = re.compile(r\"src: \\\"(http.*?)\\\"\")\n@@ -55,35 +47,19 @@\n     def can_handle_url(cls, url):\n         return cls.url_re.match(url) is not None\n \n-    def login(self, username, password):\n-        res = self.session.http.post(self.login_url, data={\"username\": username, \"password\": password})\n-        if \"success_logged_in\" in res.text:\n-            return True\n-        else:\n-            return False\n-\n     def get_hls_url(self, media_id):\n         res = self.session.http.get(self.api_url, params=dict(media_id=media_id))\n-        try:\n-            return parse_json(res.text, schema=self.api_schema)\n-        except PluginError:\n-            return\n+        return parse_json(res.text, schema=self.api_schema)\n \n     def _get_streams(self):\n-        if not self.options.get(\"username\") or not self.options.get(\"password\"):\n-            self.logger.error(\"BTV requires registration, set the username and password\"\n-                              \" with --btv-username and --btv-password\")\n-        elif self.login(self.options.get(\"username\"), self.options.get(\"password\")):\n-            res = self.session.http.get(self.url)\n-            media_match = self.media_id_re.search(res.text)\n-            media_id = media_match and media_match.group(1)\n-            if media_id:\n-                self.logger.debug(\"Found media id: {0}\", media_id)\n-                stream_url = self.get_hls_url(media_id)\n-                if stream_url:\n-                    return HLSStream.parse_variant_playlist(self.session, stream_url)\n-        else:\n-            self.logger.error(\"Login failed, a valid username and password is required\")\n+        res = self.session.http.get(self.url)\n+        media_match = self.media_id_re.search(res.text)\n+        media_id = media_match and media_match.group(1)\n+        if media_id:\n+            log.debug(\"Found media id: {0}\", media_id)\n+            stream_url = self.get_hls_url(media_id)\n+            if stream_url:\n+                return HLSStream.parse_variant_playlist(self.session, stream_url)\n \n \n __plugin__ = BTV\n", "issue": "[bug] BTV plugin needs updating\n## Bug Report\r\n- [x] This is a bug report and I have read the contribution guidelines.\r\n\r\n\r\n### Description\r\nThe location of the BTV livestream has moved to https://btvplus.bg/live/\r\n**Edit**: Livestreaming no longer requires a user to login, so that can be removed from the plugin info page.\r\n\r\n\r\n### Expected / Actual behavior\r\nStreamlink should be able to handle the link.\r\n\r\n\r\n### Reproduction steps / Explicit stream URLs to test\r\n1. streamlink https://btvplus.bg/live/ best \r\n2. error: No plugin can handle URL: https://btvplus.bg/live/\n", "before_files": [{"content": "from __future__ import print_function\nimport re\n\nfrom streamlink import PluginError\nfrom streamlink.plugin import Plugin\nfrom streamlink.plugin.api import validate\nfrom streamlink.stream import HLSStream\nfrom streamlink.utils import parse_json\nfrom streamlink.plugin import PluginArgument, PluginArguments\n\n\nclass BTV(Plugin):\n    arguments = PluginArguments(\n        PluginArgument(\n            \"username\",\n            metavar=\"USERNAME\",\n            requires=[\"password\"],\n            help=\"\"\"\n        A BTV username required to access any stream.\n        \"\"\"\n        ),\n        PluginArgument(\n            \"password\",\n            sensitive=True,\n            metavar=\"PASSWORD\",\n            help=\"\"\"\n        A BTV account password to use with --btv-username.\n        \"\"\"\n        )\n    )\n    url_re = re.compile(r\"https?://(?:www\\.)?btv\\.bg/live/?\")\n\n    api_url = \"http://www.btv.bg/lbin/global/player_config.php\"\n    check_login_url = \"http://www.btv.bg/lbin/userRegistration/check_user_login.php\"\n    login_url = \"https://www.btv.bg/bin/registration2/login.php?action=login&settings=0\"\n\n    media_id_re = re.compile(r\"media_id=(\\d+)\")\n    src_re = re.compile(r\"src: \\\"(http.*?)\\\"\")\n    api_schema = validate.Schema(\n        validate.all(\n            {\"status\": \"ok\", \"config\": validate.text},\n            validate.get(\"config\"),\n            validate.all(\n                validate.transform(src_re.search),\n                validate.any(\n                    None,\n                    validate.get(1),\n                    validate.url()\n                )\n            )\n        )\n    )\n\n    @classmethod\n    def can_handle_url(cls, url):\n        return cls.url_re.match(url) is not None\n\n    def login(self, username, password):\n        res = self.session.http.post(self.login_url, data={\"username\": username, \"password\": password})\n        if \"success_logged_in\" in res.text:\n            return True\n        else:\n            return False\n\n    def get_hls_url(self, media_id):\n        res = self.session.http.get(self.api_url, params=dict(media_id=media_id))\n        try:\n            return parse_json(res.text, schema=self.api_schema)\n        except PluginError:\n            return\n\n    def _get_streams(self):\n        if not self.options.get(\"username\") or not self.options.get(\"password\"):\n            self.logger.error(\"BTV requires registration, set the username and password\"\n                              \" with --btv-username and --btv-password\")\n        elif self.login(self.options.get(\"username\"), self.options.get(\"password\")):\n            res = self.session.http.get(self.url)\n            media_match = self.media_id_re.search(res.text)\n            media_id = media_match and media_match.group(1)\n            if media_id:\n                self.logger.debug(\"Found media id: {0}\", media_id)\n                stream_url = self.get_hls_url(media_id)\n                if stream_url:\n                    return HLSStream.parse_variant_playlist(self.session, stream_url)\n        else:\n            self.logger.error(\"Login failed, a valid username and password is required\")\n\n\n__plugin__ = BTV\n", "path": "src/streamlink/plugins/btv.py"}]}