We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[APP SUBMITTED]: AttributeError: 'NoneType' object has no attribute 'find_all'

### INFO
**Python Version**: `3.7.3rc1 (default, Mar 13 2019, 11:01:15) [GCC 8.2.0]`
**Operating System**: `Linux-4.9.35-v7+-armv7l-with-debian-buster-sid`
**Locale**: `UTF-8`
**Branch**: [develop](../tree/develop)
**Database**: `44.14`
**Commit**: pymedusa/Medusa@429bbf9f1c90de20036a86e3512ed895a0fe5f2c
**Link to Log**: https://gist.github.com/63aae653b5bade13d837f97ec5089a0f
### ERROR
<pre>
2019-05-26 11:01:29 ERROR    SEARCHQUEUE-DAILY-SEARCH :: [BTDB] :: [429bbf9] DailySearchQueueItem Exception, error: 'NoneType' object has no attribute 'find_all'
Traceback (most recent call last):
  File "/home/pi/Medusa/<a href="../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/search/queue.py#L263">medusa/search/queue.py</a>", line 263, in run
    found_results = search_for_needed_episodes(self.scheduler_start_time, force=self.force)
  File "/home/pi/Medusa/<a href="../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/search/core.py#L524">medusa/search/core.py</a>", line 524, in search_for_needed_episodes
    cur_provider.cache.update_cache(scheduler_start_time)
  File "/home/pi/Medusa/<a href="../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/tv/cache.py#L207">medusa/tv/cache.py</a>", line 207, in update_cache
    data = self._get_rss_data()
  File "/home/pi/Medusa/<a href="../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/tv/cache.py#L190">medusa/tv/cache.py</a>", line 190, in _get_rss_data
    return {'entries': self.provider.search(self.search_params)}
  File "/home/pi/Medusa/<a href="../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/providers/torrent/html/btdb.py#L78">medusa/providers/torrent/html/btdb.py</a>", line 78, in search
    results += self.parse(response.text, mode)
  File "/home/pi/Medusa/<a href="../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/providers/torrent/html/btdb.py#L99">medusa/providers/torrent/html/btdb.py</a>", line 99, in parse
    torrent_rows = table_body.find_all('li', class_='recent-item')
AttributeError: 'NoneType' object has no attribute 'find_all'
</pre>
---
_STAFF NOTIFIED_: @pymedusa/support @pymedusa/moderators


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `medusa/providers/torrent/html/btdb.py`
Content:
```
1 # coding=utf-8
2 
3 """Provider code for BTDB."""
4 
5 from __future__ import unicode_literals
6 
7 import logging
8 
9 from medusa import tv
10 from medusa.bs4_parser import BS4Parser
11 from medusa.helper.common import convert_size
12 from medusa.logger.adapters.style import BraceAdapter
13 from medusa.providers.torrent.torrent_provider import TorrentProvider
14 
15 from requests.compat import urljoin
16 
17 log = BraceAdapter(logging.getLogger(__name__))
18 log.logger.addHandler(logging.NullHandler())
19 
20 
21 class BTDBProvider(TorrentProvider):
22     """BTDB Torrent provider."""
23 
24     def __init__(self):
25         """Initialize the class."""
26         super(BTDBProvider, self).__init__('BTDB')
27 
28         # Credentials
29         self.public = True
30 
31         # URLs
32         self.url = 'https://btdb.eu'
33         self.urls = {
34             'daily': urljoin(self.url, 'recent'),
35         }
36 
37         # Miscellaneous Options
38 
39         # Cache
40         self.cache = tv.Cache(self, min_time=20)
41 
42     def search(self, search_strings, age=0, ep_obj=None, **kwargs):
43         """
44         Search a provider and parse the results.
45 
46         :param search_strings: A dict with mode (key) and the search value (value)
47         :param age: Not used
48         :param ep_obj: Not used
49         :returns: A list of search results (structure)
50         """
51         results = []
52 
53         # Search Params
54         search_params = {
55             'category': 'show',
56         }
57 
58         for mode in search_strings:
59             log.debug('Search mode: {0}', mode)
60 
61             for search_string in search_strings[mode]:
62                 search_url = self.urls['daily']
63 
64                 if mode != 'RSS':
65                     search_url = self.url
66 
67                     search_params['search'] = search_string
68                     search_params['sort'] = 'popular'
69 
70                     log.debug('Search string: {search}',
71                               {'search': search_string})
72 
73                 response = self.session.get(search_url, params=search_params)
74                 if not response or not response.text:
75                     log.debug('No data returned from provider')
76                     continue
77 
78                 results += self.parse(response.text, mode)
79 
80         return results
81 
82     def parse(self, data, mode):
83         """
84         Parse search results for items.
85 
86         :param data: The raw response from a search
87         :param mode: The current mode used to search, e.g. RSS
88 
89         :return: A list of items found
90         """
91         items = []
92 
93         with BS4Parser(data, 'html5lib') as html:
94             if mode != 'RSS':
95                 table_body = html.find('div', class_='search-ret')
96                 torrent_rows = table_body.find_all('li', class_='search-ret-item')
97             else:
98                 table_body = html.find('div', class_='recent')
99                 torrent_rows = table_body.find_all('li', class_='recent-item')
100 
101             # Continue only if at least one release is found
102             if not table_body:
103                 log.debug('Data returned from provider does not contain any torrents')
104                 return items
105 
106             for row in torrent_rows:
107                 try:
108 
109                     title = row.h2.find('a').get('title')
110                     download_url = row.div.find('a').get('href')
111                     if not all([title, download_url]):
112                         continue
113 
114                     download_url += self._custom_trackers
115 
116                     spans = row.find('div').find_all('span')
117 
118                     seeders = int(spans[3].get_text().replace(',', ''))
119                     leechers = int(spans[4].get_text().replace(',', ''))
120 
121                     torrent_size = spans[0].get_text()
122                     size = convert_size(torrent_size, default=-1)
123 
124                     pubdate_raw = spans[2].get_text()
125                     pubdate = self.parse_pubdate(pubdate_raw)
126 
127                     item = {
128                         'title': title,
129                         'link': download_url,
130                         'size': size,
131                         'seeders': seeders,
132                         'leechers': leechers,
133                         'pubdate': pubdate,
134                     }
135 
136                     if mode != 'RSS':
137                         log.debug('Found result: {0} with {1} seeders and {2} leechers',
138                                   title, seeders, leechers)
139 
140                     items.append(item)
141                 except (AttributeError, TypeError, KeyError, ValueError, IndexError):
142                     log.exception('Failed parsing provider.')
143 
144         return items
145 
146 
147 provider = BTDBProvider()
148
```
--- 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/medusa/providers/torrent/html/btdb.py b/medusa/providers/torrent/html/btdb.py
--- a/medusa/providers/torrent/html/btdb.py
+++ b/medusa/providers/torrent/html/btdb.py
@@ -91,12 +91,11 @@
         items = []
 
         with BS4Parser(data, 'html5lib') as html:
-            if mode != 'RSS':
-                table_body = html.find('div', class_='search-ret')
-                torrent_rows = table_body.find_all('li', class_='search-ret-item')
-            else:
-                table_body = html.find('div', class_='recent')
-                torrent_rows = table_body.find_all('li', class_='recent-item')
+            cls_name = 'search-ret' if mode != 'RSS' else 'recent'
+            table_body = html.find('div', class_=cls_name)
+            torrent_rows = table_body.find_all(
+                'li', class_='{0}-item'.format(cls_name)
+            ) if table_body else []
 
             # Continue only if at least one release is found
             if not table_body:

{"golden_diff": "diff --git a/medusa/providers/torrent/html/btdb.py b/medusa/providers/torrent/html/btdb.py\n--- a/medusa/providers/torrent/html/btdb.py\n+++ b/medusa/providers/torrent/html/btdb.py\n@@ -91,12 +91,11 @@\n         items = []\n \n         with BS4Parser(data, 'html5lib') as html:\n-            if mode != 'RSS':\n-                table_body = html.find('div', class_='search-ret')\n-                torrent_rows = table_body.find_all('li', class_='search-ret-item')\n-            else:\n-                table_body = html.find('div', class_='recent')\n-                torrent_rows = table_body.find_all('li', class_='recent-item')\n+            cls_name = 'search-ret' if mode != 'RSS' else 'recent'\n+            table_body = html.find('div', class_=cls_name)\n+            torrent_rows = table_body.find_all(\n+                'li', class_='{0}-item'.format(cls_name)\n+            ) if table_body else []\n \n             # Continue only if at least one release is found\n             if not table_body:\n", "issue": "[APP SUBMITTED]: AttributeError: 'NoneType' object has no attribute 'find_all'\n\n### INFO\n**Python Version**: `3.7.3rc1 (default, Mar 13 2019, 11:01:15) [GCC 8.2.0]`\n**Operating System**: `Linux-4.9.35-v7+-armv7l-with-debian-buster-sid`\n**Locale**: `UTF-8`\n**Branch**: [develop](../tree/develop)\n**Database**: `44.14`\n**Commit**: pymedusa/Medusa@429bbf9f1c90de20036a86e3512ed895a0fe5f2c\n**Link to Log**: https://gist.github.com/63aae653b5bade13d837f97ec5089a0f\n### ERROR\n<pre>\n2019-05-26 11:01:29 ERROR    SEARCHQUEUE-DAILY-SEARCH :: [BTDB] :: [429bbf9] DailySearchQueueItem Exception, error: 'NoneType' object has no attribute 'find_all'\nTraceback (most recent call last):\n  File \"/home/pi/Medusa/<a href=\"../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/search/queue.py#L263\">medusa/search/queue.py</a>\", line 263, in run\n    found_results = search_for_needed_episodes(self.scheduler_start_time, force=self.force)\n  File \"/home/pi/Medusa/<a href=\"../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/search/core.py#L524\">medusa/search/core.py</a>\", line 524, in search_for_needed_episodes\n    cur_provider.cache.update_cache(scheduler_start_time)\n  File \"/home/pi/Medusa/<a href=\"../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/tv/cache.py#L207\">medusa/tv/cache.py</a>\", line 207, in update_cache\n    data = self._get_rss_data()\n  File \"/home/pi/Medusa/<a href=\"../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/tv/cache.py#L190\">medusa/tv/cache.py</a>\", line 190, in _get_rss_data\n    return {'entries': self.provider.search(self.search_params)}\n  File \"/home/pi/Medusa/<a href=\"../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/providers/torrent/html/btdb.py#L78\">medusa/providers/torrent/html/btdb.py</a>\", line 78, in search\n    results += self.parse(response.text, mode)\n  File \"/home/pi/Medusa/<a href=\"../blob/429bbf9f1c90de20036a86e3512ed895a0fe5f2c/medusa/providers/torrent/html/btdb.py#L99\">medusa/providers/torrent/html/btdb.py</a>\", line 99, in parse\n    torrent_rows = table_body.find_all('li', class_='recent-item')\nAttributeError: 'NoneType' object has no attribute 'find_all'\n</pre>\n---\n_STAFF NOTIFIED_: @pymedusa/support @pymedusa/moderators\n\n", "before_files": [{"content": "# coding=utf-8\n\n\"\"\"Provider code for BTDB.\"\"\"\n\nfrom __future__ import unicode_literals\n\nimport logging\n\nfrom medusa import tv\nfrom medusa.bs4_parser import BS4Parser\nfrom medusa.helper.common import convert_size\nfrom medusa.logger.adapters.style import BraceAdapter\nfrom medusa.providers.torrent.torrent_provider import TorrentProvider\n\nfrom requests.compat import urljoin\n\nlog = BraceAdapter(logging.getLogger(__name__))\nlog.logger.addHandler(logging.NullHandler())\n\n\nclass BTDBProvider(TorrentProvider):\n    \"\"\"BTDB Torrent provider.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize the class.\"\"\"\n        super(BTDBProvider, self).__init__('BTDB')\n\n        # Credentials\n        self.public = True\n\n        # URLs\n        self.url = 'https://btdb.eu'\n        self.urls = {\n            'daily': urljoin(self.url, 'recent'),\n        }\n\n        # Miscellaneous Options\n\n        # Cache\n        self.cache = tv.Cache(self, min_time=20)\n\n    def search(self, search_strings, age=0, ep_obj=None, **kwargs):\n        \"\"\"\n        Search a provider and parse the results.\n\n        :param search_strings: A dict with mode (key) and the search value (value)\n        :param age: Not used\n        :param ep_obj: Not used\n        :returns: A list of search results (structure)\n        \"\"\"\n        results = []\n\n        # Search Params\n        search_params = {\n            'category': 'show',\n        }\n\n        for mode in search_strings:\n            log.debug('Search mode: {0}', mode)\n\n            for search_string in search_strings[mode]:\n                search_url = self.urls['daily']\n\n                if mode != 'RSS':\n                    search_url = self.url\n\n                    search_params['search'] = search_string\n                    search_params['sort'] = 'popular'\n\n                    log.debug('Search string: {search}',\n                              {'search': search_string})\n\n                response = self.session.get(search_url, params=search_params)\n                if not response or not response.text:\n                    log.debug('No data returned from provider')\n                    continue\n\n                results += self.parse(response.text, mode)\n\n        return results\n\n    def parse(self, data, mode):\n        \"\"\"\n        Parse search results for items.\n\n        :param data: The raw response from a search\n        :param mode: The current mode used to search, e.g. RSS\n\n        :return: A list of items found\n        \"\"\"\n        items = []\n\n        with BS4Parser(data, 'html5lib') as html:\n            if mode != 'RSS':\n                table_body = html.find('div', class_='search-ret')\n                torrent_rows = table_body.find_all('li', class_='search-ret-item')\n            else:\n                table_body = html.find('div', class_='recent')\n                torrent_rows = table_body.find_all('li', class_='recent-item')\n\n            # Continue only if at least one release is found\n            if not table_body:\n                log.debug('Data returned from provider does not contain any torrents')\n                return items\n\n            for row in torrent_rows:\n                try:\n\n                    title = row.h2.find('a').get('title')\n                    download_url = row.div.find('a').get('href')\n                    if not all([title, download_url]):\n                        continue\n\n                    download_url += self._custom_trackers\n\n                    spans = row.find('div').find_all('span')\n\n                    seeders = int(spans[3].get_text().replace(',', ''))\n                    leechers = int(spans[4].get_text().replace(',', ''))\n\n                    torrent_size = spans[0].get_text()\n                    size = convert_size(torrent_size, default=-1)\n\n                    pubdate_raw = spans[2].get_text()\n                    pubdate = self.parse_pubdate(pubdate_raw)\n\n                    item = {\n                        'title': title,\n                        'link': download_url,\n                        'size': size,\n                        'seeders': seeders,\n                        'leechers': leechers,\n                        'pubdate': pubdate,\n                    }\n\n                    if mode != 'RSS':\n                        log.debug('Found result: {0} with {1} seeders and {2} leechers',\n                                  title, seeders, leechers)\n\n                    items.append(item)\n                except (AttributeError, TypeError, KeyError, ValueError, IndexError):\n                    log.exception('Failed parsing provider.')\n\n        return items\n\n\nprovider = BTDBProvider()\n", "path": "medusa/providers/torrent/html/btdb.py"}], "after_files": [{"content": "# coding=utf-8\n\n\"\"\"Provider code for BTDB.\"\"\"\n\nfrom __future__ import unicode_literals\n\nimport logging\n\nfrom medusa import tv\nfrom medusa.bs4_parser import BS4Parser\nfrom medusa.helper.common import convert_size\nfrom medusa.logger.adapters.style import BraceAdapter\nfrom medusa.providers.torrent.torrent_provider import TorrentProvider\n\nfrom requests.compat import urljoin\n\nlog = BraceAdapter(logging.getLogger(__name__))\nlog.logger.addHandler(logging.NullHandler())\n\n\nclass BTDBProvider(TorrentProvider):\n    \"\"\"BTDB Torrent provider.\"\"\"\n\n    def __init__(self):\n        \"\"\"Initialize the class.\"\"\"\n        super(BTDBProvider, self).__init__('BTDB')\n\n        # Credentials\n        self.public = True\n\n        # URLs\n        self.url = 'https://btdb.eu'\n        self.urls = {\n            'daily': urljoin(self.url, 'recent'),\n        }\n\n        # Miscellaneous Options\n\n        # Cache\n        self.cache = tv.Cache(self, min_time=20)\n\n    def search(self, search_strings, age=0, ep_obj=None, **kwargs):\n        \"\"\"\n        Search a provider and parse the results.\n\n        :param search_strings: A dict with mode (key) and the search value (value)\n        :param age: Not used\n        :param ep_obj: Not used\n        :returns: A list of search results (structure)\n        \"\"\"\n        results = []\n\n        # Search Params\n        search_params = {\n            'category': 'show',\n        }\n\n        for mode in search_strings:\n            log.debug('Search mode: {0}', mode)\n\n            for search_string in search_strings[mode]:\n                search_url = self.urls['daily']\n\n                if mode != 'RSS':\n                    search_url = self.url\n\n                    search_params['search'] = search_string\n                    search_params['sort'] = 'popular'\n\n                    log.debug('Search string: {search}',\n                              {'search': search_string})\n\n                response = self.session.get(search_url, params=search_params)\n                if not response or not response.text:\n                    log.debug('No data returned from provider')\n                    continue\n\n                results += self.parse(response.text, mode)\n\n        return results\n\n    def parse(self, data, mode):\n        \"\"\"\n        Parse search results for items.\n\n        :param data: The raw response from a search\n        :param mode: The current mode used to search, e.g. RSS\n\n        :return: A list of items found\n        \"\"\"\n        items = []\n\n        with BS4Parser(data, 'html5lib') as html:\n            cls_name = 'search-ret' if mode != 'RSS' else 'recent'\n            table_body = html.find('div', class_=cls_name)\n            torrent_rows = table_body.find_all(\n                'li', class_='{0}-item'.format(cls_name)\n            ) if table_body else []\n\n            # Continue only if at least one release is found\n            if not table_body:\n                log.debug('Data returned from provider does not contain any torrents')\n                return items\n\n            for row in torrent_rows:\n                try:\n\n                    title = row.h2.find('a').get('title')\n                    download_url = row.div.find('a').get('href')\n                    if not all([title, download_url]):\n                        continue\n\n                    download_url += self._custom_trackers\n\n                    spans = row.find('div').find_all('span')\n\n                    seeders = int(spans[3].get_text().replace(',', ''))\n                    leechers = int(spans[4].get_text().replace(',', ''))\n\n                    torrent_size = spans[0].get_text()\n                    size = convert_size(torrent_size, default=-1)\n\n                    pubdate_raw = spans[2].get_text()\n                    pubdate = self.parse_pubdate(pubdate_raw)\n\n                    item = {\n                        'title': title,\n                        'link': download_url,\n                        'size': size,\n                        'seeders': seeders,\n                        'leechers': leechers,\n                        'pubdate': pubdate,\n                    }\n\n                    if mode != 'RSS':\n                        log.debug('Found result: {0} with {1} seeders and {2} leechers',\n                                  title, seeders, leechers)\n\n                    items.append(item)\n                except (AttributeError, TypeError, KeyError, ValueError, IndexError):\n                    log.exception('Failed parsing provider.')\n\n        return items\n\n\nprovider = BTDBProvider()\n", "path": "medusa/providers/torrent/html/btdb.py"}]}