We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[8tracks] throws 403 error after first 4 songs. Nothing downloads.
8tracks recently updated their API to version 3. They probably updated their security on this (because, according to their license, you can only skip 3 songs within a certain time frame).


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `youtube_dl/extractor/eighttracks.py`
Content:
```
1 # coding: utf-8
2 from __future__ import unicode_literals
3 
4 import json
5 import random
6 import re
7 
8 from .common import InfoExtractor
9 from ..utils import (
10     compat_str,
11 )
12 
13 
14 class EightTracksIE(InfoExtractor):
15     IE_NAME = '8tracks'
16     _VALID_URL = r'https?://8tracks\.com/(?P<user>[^/]+)/(?P<id>[^/#]+)(?:#.*)?$'
17     _TEST = {
18         "name": "EightTracks",
19         "url": "http://8tracks.com/ytdl/youtube-dl-test-tracks-a",
20         "info_dict": {
21             'id': '1336550',
22             'display_id': 'youtube-dl-test-tracks-a',
23             "description": "test chars:  \"'/\\ä↭",
24             "title": "youtube-dl test tracks \"'/\\ä↭<>",
25         },
26         "playlist": [
27             {
28                 "md5": "96ce57f24389fc8734ce47f4c1abcc55",
29                 "info_dict": {
30                     "id": "11885610",
31                     "ext": "m4a",
32                     "title": "youtue-dl project<>\"' - youtube-dl test track 1 \"'/\\\u00e4\u21ad",
33                     "uploader_id": "ytdl"
34                 }
35             },
36             {
37                 "md5": "4ab26f05c1f7291ea460a3920be8021f",
38                 "info_dict": {
39                     "id": "11885608",
40                     "ext": "m4a",
41                     "title": "youtube-dl project - youtube-dl test track 2 \"'/\\\u00e4\u21ad",
42                     "uploader_id": "ytdl"
43                 }
44             },
45             {
46                 "md5": "d30b5b5f74217410f4689605c35d1fd7",
47                 "info_dict": {
48                     "id": "11885679",
49                     "ext": "m4a",
50                     "title": "youtube-dl project as well - youtube-dl test track 3 \"'/\\\u00e4\u21ad",
51                     "uploader_id": "ytdl"
52                 }
53             },
54             {
55                 "md5": "4eb0a669317cd725f6bbd336a29f923a",
56                 "info_dict": {
57                     "id": "11885680",
58                     "ext": "m4a",
59                     "title": "youtube-dl project as well - youtube-dl test track 4 \"'/\\\u00e4\u21ad",
60                     "uploader_id": "ytdl"
61                 }
62             },
63             {
64                 "md5": "1893e872e263a2705558d1d319ad19e8",
65                 "info_dict": {
66                     "id": "11885682",
67                     "ext": "m4a",
68                     "title": "PH - youtube-dl test track 5 \"'/\\\u00e4\u21ad",
69                     "uploader_id": "ytdl"
70                 }
71             },
72             {
73                 "md5": "b673c46f47a216ab1741ae8836af5899",
74                 "info_dict": {
75                     "id": "11885683",
76                     "ext": "m4a",
77                     "title": "PH - youtube-dl test track 6 \"'/\\\u00e4\u21ad",
78                     "uploader_id": "ytdl"
79                 }
80             },
81             {
82                 "md5": "1d74534e95df54986da7f5abf7d842b7",
83                 "info_dict": {
84                     "id": "11885684",
85                     "ext": "m4a",
86                     "title": "phihag - youtube-dl test track 7 \"'/\\\u00e4\u21ad",
87                     "uploader_id": "ytdl"
88                 }
89             },
90             {
91                 "md5": "f081f47af8f6ae782ed131d38b9cd1c0",
92                 "info_dict": {
93                     "id": "11885685",
94                     "ext": "m4a",
95                     "title": "phihag - youtube-dl test track 8 \"'/\\\u00e4\u21ad",
96                     "uploader_id": "ytdl"
97                 }
98             }
99         ]
100     }
101 
102     def _real_extract(self, url):
103         mobj = re.match(self._VALID_URL, url)
104         playlist_id = mobj.group('id')
105 
106         webpage = self._download_webpage(url, playlist_id)
107 
108         json_like = self._search_regex(
109             r"(?s)PAGE.mix = (.*?);\n", webpage, 'trax information')
110         data = json.loads(json_like)
111 
112         session = str(random.randint(0, 1000000000))
113         mix_id = data['id']
114         track_count = data['tracks_count']
115         first_url = 'http://8tracks.com/sets/%s/play?player=sm&mix_id=%s&format=jsonh' % (session, mix_id)
116         next_url = first_url
117         entries = []
118         for i in range(track_count):
119             api_json = self._download_webpage(
120                 next_url, playlist_id,
121                 note='Downloading song information %d/%d' % (i + 1, track_count),
122                 errnote='Failed to download song information')
123             api_data = json.loads(api_json)
124             track_data = api_data['set']['track']
125             info = {
126                 'id': compat_str(track_data['id']),
127                 'url': track_data['track_file_stream_url'],
128                 'title': track_data['performer'] + u' - ' + track_data['name'],
129                 'raw_title': track_data['name'],
130                 'uploader_id': data['user']['login'],
131                 'ext': 'm4a',
132             }
133             entries.append(info)
134             next_url = 'http://8tracks.com/sets/%s/next?player=sm&mix_id=%s&format=jsonh&track_id=%s' % (
135                 session, mix_id, track_data['id'])
136         return {
137             '_type': 'playlist',
138             'entries': entries,
139             'id': compat_str(mix_id),
140             'display_id': playlist_id,
141             'title': data.get('name'),
142             'description': data.get('description'),
143         }
144
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/youtube_dl/extractor/eighttracks.py b/youtube_dl/extractor/eighttracks.py
--- a/youtube_dl/extractor/eighttracks.py
+++ b/youtube_dl/extractor/eighttracks.py
@@ -4,10 +4,12 @@
 import json
 import random
 import re
+import time
 
 from .common import InfoExtractor
 from ..utils import (
     compat_str,
+    ExtractorError,
 )
 
 
@@ -112,14 +114,30 @@
         session = str(random.randint(0, 1000000000))
         mix_id = data['id']
         track_count = data['tracks_count']
+        duration = data['duration']
+        avg_song_duration = duration / track_count
         first_url = 'http://8tracks.com/sets/%s/play?player=sm&mix_id=%s&format=jsonh' % (session, mix_id)
         next_url = first_url
         entries = []
+
         for i in range(track_count):
-            api_json = self._download_webpage(
-                next_url, playlist_id,
-                note='Downloading song information %d/%d' % (i + 1, track_count),
-                errnote='Failed to download song information')
+            
+            api_json = None
+            download_tries = 0
+
+            while api_json is None:
+                try:
+                    api_json = self._download_webpage(
+                        next_url, playlist_id,
+                        note='Downloading song information %d/%d' % (i + 1, track_count),
+                        errnote='Failed to download song information')
+                except ExtractorError:
+                    if download_tries > 3:
+                        raise
+                    else:
+                        download_tries += 1
+                        time.sleep(avg_song_duration)
+
             api_data = json.loads(api_json)
             track_data = api_data['set']['track']
             info = {
@@ -131,6 +149,7 @@
                 'ext': 'm4a',
             }
             entries.append(info)
+
             next_url = 'http://8tracks.com/sets/%s/next?player=sm&mix_id=%s&format=jsonh&track_id=%s' % (
                 session, mix_id, track_data['id'])
         return {

{"golden_diff": "diff --git a/youtube_dl/extractor/eighttracks.py b/youtube_dl/extractor/eighttracks.py\n--- a/youtube_dl/extractor/eighttracks.py\n+++ b/youtube_dl/extractor/eighttracks.py\n@@ -4,10 +4,12 @@\n import json\n import random\n import re\n+import time\n \n from .common import InfoExtractor\n from ..utils import (\n     compat_str,\n+    ExtractorError,\n )\n \n \n@@ -112,14 +114,30 @@\n         session = str(random.randint(0, 1000000000))\n         mix_id = data['id']\n         track_count = data['tracks_count']\n+        duration = data['duration']\n+        avg_song_duration = duration / track_count\n         first_url = 'http://8tracks.com/sets/%s/play?player=sm&mix_id=%s&format=jsonh' % (session, mix_id)\n         next_url = first_url\n         entries = []\n+\n         for i in range(track_count):\n-            api_json = self._download_webpage(\n-                next_url, playlist_id,\n-                note='Downloading song information %d/%d' % (i + 1, track_count),\n-                errnote='Failed to download song information')\n+            \n+            api_json = None\n+            download_tries = 0\n+\n+            while api_json is None:\n+                try:\n+                    api_json = self._download_webpage(\n+                        next_url, playlist_id,\n+                        note='Downloading song information %d/%d' % (i + 1, track_count),\n+                        errnote='Failed to download song information')\n+                except ExtractorError:\n+                    if download_tries > 3:\n+                        raise\n+                    else:\n+                        download_tries += 1\n+                        time.sleep(avg_song_duration)\n+\n             api_data = json.loads(api_json)\n             track_data = api_data['set']['track']\n             info = {\n@@ -131,6 +149,7 @@\n                 'ext': 'm4a',\n             }\n             entries.append(info)\n+\n             next_url = 'http://8tracks.com/sets/%s/next?player=sm&mix_id=%s&format=jsonh&track_id=%s' % (\n                 session, mix_id, track_data['id'])\n         return {\n", "issue": "[8tracks] throws 403 error after first 4 songs. Nothing downloads.\n8tracks recently updated their API to version 3. They probably updated their security on this (because, according to their license, you can only skip 3 songs within a certain time frame).\n\n", "before_files": [{"content": "# coding: utf-8\nfrom __future__ import unicode_literals\n\nimport json\nimport random\nimport re\n\nfrom .common import InfoExtractor\nfrom ..utils import (\n    compat_str,\n)\n\n\nclass EightTracksIE(InfoExtractor):\n    IE_NAME = '8tracks'\n    _VALID_URL = r'https?://8tracks\\.com/(?P<user>[^/]+)/(?P<id>[^/#]+)(?:#.*)?$'\n    _TEST = {\n        \"name\": \"EightTracks\",\n        \"url\": \"http://8tracks.com/ytdl/youtube-dl-test-tracks-a\",\n        \"info_dict\": {\n            'id': '1336550',\n            'display_id': 'youtube-dl-test-tracks-a',\n            \"description\": \"test chars:  \\\"'/\\\\\u00e4\u21ad\",\n            \"title\": \"youtube-dl test tracks \\\"'/\\\\\u00e4\u21ad<>\",\n        },\n        \"playlist\": [\n            {\n                \"md5\": \"96ce57f24389fc8734ce47f4c1abcc55\",\n                \"info_dict\": {\n                    \"id\": \"11885610\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"youtue-dl project<>\\\"' - youtube-dl test track 1 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"4ab26f05c1f7291ea460a3920be8021f\",\n                \"info_dict\": {\n                    \"id\": \"11885608\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"youtube-dl project - youtube-dl test track 2 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"d30b5b5f74217410f4689605c35d1fd7\",\n                \"info_dict\": {\n                    \"id\": \"11885679\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"youtube-dl project as well - youtube-dl test track 3 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"4eb0a669317cd725f6bbd336a29f923a\",\n                \"info_dict\": {\n                    \"id\": \"11885680\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"youtube-dl project as well - youtube-dl test track 4 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"1893e872e263a2705558d1d319ad19e8\",\n                \"info_dict\": {\n                    \"id\": \"11885682\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"PH - youtube-dl test track 5 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"b673c46f47a216ab1741ae8836af5899\",\n                \"info_dict\": {\n                    \"id\": \"11885683\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"PH - youtube-dl test track 6 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"1d74534e95df54986da7f5abf7d842b7\",\n                \"info_dict\": {\n                    \"id\": \"11885684\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"phihag - youtube-dl test track 7 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"f081f47af8f6ae782ed131d38b9cd1c0\",\n                \"info_dict\": {\n                    \"id\": \"11885685\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"phihag - youtube-dl test track 8 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            }\n        ]\n    }\n\n    def _real_extract(self, url):\n        mobj = re.match(self._VALID_URL, url)\n        playlist_id = mobj.group('id')\n\n        webpage = self._download_webpage(url, playlist_id)\n\n        json_like = self._search_regex(\n            r\"(?s)PAGE.mix = (.*?);\\n\", webpage, 'trax information')\n        data = json.loads(json_like)\n\n        session = str(random.randint(0, 1000000000))\n        mix_id = data['id']\n        track_count = data['tracks_count']\n        first_url = 'http://8tracks.com/sets/%s/play?player=sm&mix_id=%s&format=jsonh' % (session, mix_id)\n        next_url = first_url\n        entries = []\n        for i in range(track_count):\n            api_json = self._download_webpage(\n                next_url, playlist_id,\n                note='Downloading song information %d/%d' % (i + 1, track_count),\n                errnote='Failed to download song information')\n            api_data = json.loads(api_json)\n            track_data = api_data['set']['track']\n            info = {\n                'id': compat_str(track_data['id']),\n                'url': track_data['track_file_stream_url'],\n                'title': track_data['performer'] + u' - ' + track_data['name'],\n                'raw_title': track_data['name'],\n                'uploader_id': data['user']['login'],\n                'ext': 'm4a',\n            }\n            entries.append(info)\n            next_url = 'http://8tracks.com/sets/%s/next?player=sm&mix_id=%s&format=jsonh&track_id=%s' % (\n                session, mix_id, track_data['id'])\n        return {\n            '_type': 'playlist',\n            'entries': entries,\n            'id': compat_str(mix_id),\n            'display_id': playlist_id,\n            'title': data.get('name'),\n            'description': data.get('description'),\n        }\n", "path": "youtube_dl/extractor/eighttracks.py"}], "after_files": [{"content": "# coding: utf-8\nfrom __future__ import unicode_literals\n\nimport json\nimport random\nimport re\nimport time\n\nfrom .common import InfoExtractor\nfrom ..utils import (\n    compat_str,\n    ExtractorError,\n)\n\n\nclass EightTracksIE(InfoExtractor):\n    IE_NAME = '8tracks'\n    _VALID_URL = r'https?://8tracks\\.com/(?P<user>[^/]+)/(?P<id>[^/#]+)(?:#.*)?$'\n    _TEST = {\n        \"name\": \"EightTracks\",\n        \"url\": \"http://8tracks.com/ytdl/youtube-dl-test-tracks-a\",\n        \"info_dict\": {\n            'id': '1336550',\n            'display_id': 'youtube-dl-test-tracks-a',\n            \"description\": \"test chars:  \\\"'/\\\\\u00e4\u21ad\",\n            \"title\": \"youtube-dl test tracks \\\"'/\\\\\u00e4\u21ad<>\",\n        },\n        \"playlist\": [\n            {\n                \"md5\": \"96ce57f24389fc8734ce47f4c1abcc55\",\n                \"info_dict\": {\n                    \"id\": \"11885610\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"youtue-dl project<>\\\"' - youtube-dl test track 1 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"4ab26f05c1f7291ea460a3920be8021f\",\n                \"info_dict\": {\n                    \"id\": \"11885608\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"youtube-dl project - youtube-dl test track 2 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"d30b5b5f74217410f4689605c35d1fd7\",\n                \"info_dict\": {\n                    \"id\": \"11885679\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"youtube-dl project as well - youtube-dl test track 3 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"4eb0a669317cd725f6bbd336a29f923a\",\n                \"info_dict\": {\n                    \"id\": \"11885680\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"youtube-dl project as well - youtube-dl test track 4 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"1893e872e263a2705558d1d319ad19e8\",\n                \"info_dict\": {\n                    \"id\": \"11885682\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"PH - youtube-dl test track 5 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"b673c46f47a216ab1741ae8836af5899\",\n                \"info_dict\": {\n                    \"id\": \"11885683\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"PH - youtube-dl test track 6 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"1d74534e95df54986da7f5abf7d842b7\",\n                \"info_dict\": {\n                    \"id\": \"11885684\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"phihag - youtube-dl test track 7 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            },\n            {\n                \"md5\": \"f081f47af8f6ae782ed131d38b9cd1c0\",\n                \"info_dict\": {\n                    \"id\": \"11885685\",\n                    \"ext\": \"m4a\",\n                    \"title\": \"phihag - youtube-dl test track 8 \\\"'/\\\\\\u00e4\\u21ad\",\n                    \"uploader_id\": \"ytdl\"\n                }\n            }\n        ]\n    }\n\n    def _real_extract(self, url):\n        mobj = re.match(self._VALID_URL, url)\n        playlist_id = mobj.group('id')\n\n        webpage = self._download_webpage(url, playlist_id)\n\n        json_like = self._search_regex(\n            r\"(?s)PAGE.mix = (.*?);\\n\", webpage, 'trax information')\n        data = json.loads(json_like)\n\n        session = str(random.randint(0, 1000000000))\n        mix_id = data['id']\n        track_count = data['tracks_count']\n        duration = data['duration']\n        avg_song_duration = duration / track_count\n        first_url = 'http://8tracks.com/sets/%s/play?player=sm&mix_id=%s&format=jsonh' % (session, mix_id)\n        next_url = first_url\n        entries = []\n\n        for i in range(track_count):\n            \n            api_json = None\n            download_tries = 0\n\n            while api_json is None:\n                try:\n                    api_json = self._download_webpage(\n                        next_url, playlist_id,\n                        note='Downloading song information %d/%d' % (i + 1, track_count),\n                        errnote='Failed to download song information')\n                except ExtractorError:\n                    if download_tries > 3:\n                        raise\n                    else:\n                        download_tries += 1\n                        time.sleep(avg_song_duration)\n\n            api_data = json.loads(api_json)\n            track_data = api_data['set']['track']\n            info = {\n                'id': compat_str(track_data['id']),\n                'url': track_data['track_file_stream_url'],\n                'title': track_data['performer'] + u' - ' + track_data['name'],\n                'raw_title': track_data['name'],\n                'uploader_id': data['user']['login'],\n                'ext': 'm4a',\n            }\n            entries.append(info)\n\n            next_url = 'http://8tracks.com/sets/%s/next?player=sm&mix_id=%s&format=jsonh&track_id=%s' % (\n                session, mix_id, track_data['id'])\n        return {\n            '_type': 'playlist',\n            'entries': entries,\n            'id': compat_str(mix_id),\n            'display_id': playlist_id,\n            'title': data.get('name'),\n            'description': data.get('description'),\n        }\n", "path": "youtube_dl/extractor/eighttracks.py"}]}