Repository: pymedusa/Medusa

Issue:
[APP SUBMITTED]: IndexError: list index out of range
### INFO
**Python Version**: `2.7.6 (default, Oct 26 2016, 20:32:47) [GCC 4.8.4]`
**Operating System**: `Linux-4.2.0-42-generic-i686-with-Ubuntu-14.04-trusty`
**Locale**: `None`
**Branch**: [develop](../tree/develop)
**Database**: `44.2`
**Commit**: pymedusa/Medusa@617ad17ebd39c84054269f7a2a451cbc488f8fc5
**Link to Log**: https://gist.github.com/69fdacbf863b864733bcd1fa16b15429
### ERROR
<pre>
2016-11-26 00:57:09 ERROR    SEARCHQUEUE-BACKLOG-279271 :: [LimeTorrents] :: [617ad17] Unknown exception while searching LimeTorrents. Error: 'list index out of range'
Traceback (most recent call last):
  File "/home/home/SickRage/<a href="../blob/617ad17ebd39c84054269f7a2a451cbc488f8fc5/**********/search/core.py#L560">**********/search/core.py</a>", line 560, in searchProviders
    down_cur_quality, manual_search, manual_search_type)
  File "/home/home/SickRage/<a href="../blob/617ad17ebd39c84054269f7a2a451cbc488f8fc5/**********/providers/generic_provider.py#L193">**********/providers/generic_provider.py</a>", line 193, in find_search_results
    items_list += self.search(search_string, ep_obj=episode)
  File "/home/home/SickRage/<a href="../blob/617ad17ebd39c84054269f7a2a451cbc488f8fc5/**********/providers/torrent/html/limetorrents.py#L98">**********/providers/torrent/html/limetorrents.py</a>", line 98, in search
    results += self.parse(response.text, mode)
  File "/home/home/SickRage/<a href="../blob/617ad17ebd39c84054269f7a2a451cbc488f8fc5/**********/providers/torrent/html/limetorrents.py#L121">**********/providers/torrent/html/limetorrents.py</a>", line 121, in parse
    torrent_table = torrent_table[0 if mode == 'RSS' else 1]
IndexError: list index out of range
</pre>
---
_STAFF NOTIFIED_: @pymedusa/support @pymedusa/moderators


Discussion:

Resolving patch:
diff --git a/medusa/providers/torrent/html/limetorrents.py b/medusa/providers/torrent/html/limetorrents.py
--- a/medusa/providers/torrent/html/limetorrents.py
+++ b/medusa/providers/torrent/html/limetorrents.py
@@ -20,9 +20,12 @@
 
 import re
 import traceback
+
 from contextlib2 import suppress
-import requests
+
 from requests.compat import urljoin
+from requests.exceptions import ConnectionError as RequestsConnectionError, Timeout
+
 from ..torrent_provider import TorrentProvider
 from .... import logger, tv_cache
 from ....bs4_parser import BS4Parser
@@ -43,12 +46,11 @@ def __init__(self):
         self.public = True
 
         # URLs
-        self.url = 'https://www.limetorrents.cc/'
+        self.url = 'https://www.limetorrents.cc'
         self.urls = {
-            'index': self.url,
             'update': urljoin(self.url, '/post/updatestats.php'),
             'search': urljoin(self.url, '/search/tv/{query}/'),
-            'rss': urljoin(self.url, '/browse-torrents/TV-shows/date/{page}/')
+            'rss': urljoin(self.url, '/browse-torrents/TV-shows/date/{page}/'),
         }
 
         # Proper Strings
@@ -110,52 +112,56 @@ def parse(self, data, mode):
         """
         items = []
 
+        def process_column_header(th):
+            return th.span.get_text() if th.span else th.get_text()
+
         with BS4Parser(data, 'html5lib') as html:
-            torrent_table = html('table', class_='table2')
+            torrent_table = html.find('table', class_='table2')
 
-            if mode != 'RSS' and torrent_table and len(torrent_table) < 2:
+            if not torrent_table:
                 logger.log('Data returned from provider does not contain any {0}torrents'.format(
                            'confirmed ' if self.confirmed else ''), logger.DEBUG)
                 return items
 
-            torrent_table = torrent_table[0 if mode == 'RSS' else 1]
-            torrent_rows = torrent_table('tr')
+            torrent_rows = torrent_table.find_all('tr')
+            labels = [process_column_header(label) for label in torrent_rows[0]]
 
             # Skip the first row, since it isn't a valid result
             for row in torrent_rows[1:]:
-                cells = row('td')
+                cells = row.find_all('td')
+
                 try:
-                    verified = row('img', title='Verified torrent')
+                    title_cell = cells[labels.index('Torrent Name')]
+
+                    verified = title_cell.find('img', title='Verified torrent')
                     if self.confirmed and not verified:
                         continue
 
-                    url = row.find('a', rel='nofollow')
-                    title_info = row('a')
-                    info = title_info[1]['href']
-                    if not all([url, title_info, info]):
+                    title_anchors = title_cell.find_all('a')
+                    if not title_anchors or len(title_anchors) < 2:
                         continue
 
-                    title = title_info[1].get_text(strip=True)
-                    title2 = id_regex.search(info).group(1)
-                    if len(title) < len(title2):
-                        title = title2.replace('-', ' ')
-                    torrent_id = id_regex.search(info).group(2)
-                    torrent_hash = hash_regex.search(url['href']).group(2)
+                    title_url = title_anchors[0].get('href')
+                    title = title_anchors[1].get_text(strip=True)
+                    regex_result = id_regex.search(title_anchors[1].get('href'))
+
+                    alt_title = regex_result.group(1)
+                    if len(title) < len(alt_title):
+                        title = alt_title.replace('-', ' ')
+
+                    torrent_id = regex_result.group(2)
+                    torrent_hash = hash_regex.search(title_url).group(2)
                     if not all([title, torrent_id, torrent_hash]):
                         continue
 
-                    with suppress(requests.exceptions.Timeout):
+                    with suppress(RequestsConnectionError, Timeout):
                         # Suppress the timeout since we are not interested in actually getting the results
-                        self.session.get(self.urls['update'], timeout=0.1,
-                                         params={'torrent_id': torrent_id,
-                                                 'infohash': torrent_hash})
+                        self.session.get(self.urls['update'], timeout=0.1, params={'torrent_id': torrent_id,
+                                                                                   'infohash': torrent_hash})
 
                     # Remove comma as thousands separator from larger number like 2,000 seeders = 2000
-                    seeders = try_int(cells[3].get_text(strip=True).replace(',', ''))
-                    leechers = try_int(cells[4].get_text(strip=True).replace(',', ''))
-                    size = convert_size(cells[2].get_text(strip=True)) or -1
-                    download_url = 'magnet:?xt=urn:btih:{hash}&dn={title}{trackers}'.format(
-                        hash=torrent_hash, title=title, trackers=self._custom_trackers)
+                    seeders = try_int(cells[labels.index('Seed')].get_text(strip=True).replace(',', ''), 1)
+                    leechers = try_int(cells[labels.index('Leech')].get_text(strip=True).replace(',', ''))
 
                     if seeders < min(self.minseed, 1):
                         if mode != 'RSS':
@@ -164,6 +170,10 @@ def parse(self, data, mode):
                                        (title, seeders), logger.DEBUG)
                         continue
 
+                    size = convert_size(cells[labels.index('Size')].get_text(strip=True)) or -1
+                    download_url = 'magnet:?xt=urn:btih:{hash}&dn={title}{trackers}'.format(
+                        hash=torrent_hash, title=title, trackers=self._custom_trackers)
+
                     item = {
                         'title': title,
                         'link': download_url,


Test patch: