Browse Source

[fix] nyaa.si fixed

misnyo 7 years ago
parent
commit
01330f71cd
2 changed files with 139 additions and 86 deletions
  1. 48 53
      searx/engines/nyaa.py
  2. 91 33
      tests/unit/engines/test_nyaa.py

+ 48 - 53
searx/engines/nyaa.py

@@ -1,7 +1,7 @@
 """
 """
- Nyaa.se (Anime Bittorrent tracker)
+ Nyaa.si (Anime Bittorrent tracker)
 
 
- @website      http://www.nyaa.se/
+ @website      http://www.nyaa.si/
  @provide-api  no
  @provide-api  no
  @using-api    no
  @using-api    no
  @results      HTML
  @results      HTML
@@ -12,50 +12,25 @@
 from lxml import html
 from lxml import html
 from searx.engines.xpath import extract_text
 from searx.engines.xpath import extract_text
 from searx.url_utils import urlencode
 from searx.url_utils import urlencode
+from searx.utils import get_torrent_size
 
 
 # engine dependent config
 # engine dependent config
 categories = ['files', 'images', 'videos', 'music']
 categories = ['files', 'images', 'videos', 'music']
 paging = True
 paging = True
 
 
 # search-url
 # search-url
-base_url = 'http://www.nyaa.se/'
+base_url = 'http://www.nyaa.si/'
 search_url = base_url + '?page=search&{query}&offset={offset}'
 search_url = base_url + '?page=search&{query}&offset={offset}'
 
 
 # xpath queries
 # xpath queries
-xpath_results = '//table[@class="tlist"]//tr[contains(@class, "tlistrow")]'
-xpath_category = './/td[@class="tlisticon"]/a'
-xpath_title = './/td[@class="tlistname"]/a'
-xpath_torrent_file = './/td[@class="tlistdownload"]/a'
-xpath_filesize = './/td[@class="tlistsize"]/text()'
-xpath_seeds = './/td[@class="tlistsn"]/text()'
-xpath_leeches = './/td[@class="tlistln"]/text()'
-xpath_downloads = './/td[@class="tlistdn"]/text()'
-
-
-# convert a variable to integer or return 0 if it's not a number
-def int_or_zero(num):
-    if isinstance(num, list):
-        if len(num) < 1:
-            return 0
-        num = num[0]
-    if num.isdigit():
-        return int(num)
-    return 0
-
-
-# get multiplier to convert torrent size to bytes
-def get_filesize_mul(suffix):
-    return {
-        'KB': 1024,
-        'MB': 1024 ** 2,
-        'GB': 1024 ** 3,
-        'TB': 1024 ** 4,
-
-        'KIB': 1024,
-        'MIB': 1024 ** 2,
-        'GIB': 1024 ** 3,
-        'TIB': 1024 ** 4
-    }[str(suffix).upper()]
+xpath_results = '//table[contains(@class, "torrent-list")]//tr[not(th)]'
+xpath_category = './/td[1]/a[1]'
+xpath_title = './/td[2]/a[last()]'
+xpath_torrent_links = './/td[3]/a'
+xpath_filesize = './/td[4]/text()'
+xpath_seeds = './/td[6]/text()'
+xpath_leeches = './/td[7]/text()'
+xpath_downloads = './/td[8]/text()'
 
 
 
 
 # do search-request
 # do search-request
@@ -72,6 +47,14 @@ def response(resp):
     dom = html.fromstring(resp.text)
     dom = html.fromstring(resp.text)
 
 
     for result in dom.xpath(xpath_results):
     for result in dom.xpath(xpath_results):
+        # defaults
+        filesize = 0
+        seed = 0
+        leech = 0
+        downloads = 0
+        magnet_link = ""
+        torrent_link = ""
+
         # category in which our torrent belongs
         # category in which our torrent belongs
         category = result.xpath(xpath_category)[0].attrib.get('title')
         category = result.xpath(xpath_category)[0].attrib.get('title')
 
 
@@ -80,26 +63,37 @@ def response(resp):
         title = extract_text(page_a)
         title = extract_text(page_a)
 
 
         # link to the page
         # link to the page
-        href = page_a.attrib.get('href')
-
-        # link to the torrent file
-        torrent_link = result.xpath(xpath_torrent_file)[0].attrib.get('href')
-
-        # torrent size
+        href = base_url + page_a.attrib.get('href')
+
+        for link in result.xpath(xpath_torrent_links):
+            url = link.attrib.get('href')
+            if 'magnet' in url:
+                # link to the magnet
+                magnet_link = url
+            else:
+                # link to the torrent file
+                torrent_link = url
+
+        # get seeders and leechers
         try:
         try:
-            file_size, suffix = result.xpath(xpath_filesize)[0].split(' ')
-            file_size = int(float(file_size) * get_filesize_mul(suffix))
+            seed = int(result.xpath(xpath_seeds)[0])
+            leech = int(result.xpath(xpath_leeches)[0])
         except:
         except:
-            file_size = None
-
-        # seed count
-        seed = int_or_zero(result.xpath(xpath_seeds))
+            pass
 
 
-        # leech count
-        leech = int_or_zero(result.xpath(xpath_leeches))
+        # let's try to calculate the torrent size
+        try:
+            filesize_info = result.xpath(xpath_filesize)[0]
+            filesize, filesize_multiplier = filesize_info.split()
+            filesize = get_torrent_size(filesize, filesize_multiplier)
+        except:
+            pass
 
 
         # torrent downloads count
         # torrent downloads count
-        downloads = int_or_zero(result.xpath(xpath_downloads))
+        try:
+            downloads = result.xpath(xpath_downloads)[0]
+        except:
+            pass
 
 
         # content string contains all information not included into template
         # content string contains all information not included into template
         content = 'Category: "{category}". Downloaded {downloads} times.'
         content = 'Category: "{category}". Downloaded {downloads} times.'
@@ -110,8 +104,9 @@ def response(resp):
                         'content': content,
                         'content': content,
                         'seed': seed,
                         'seed': seed,
                         'leech': leech,
                         'leech': leech,
-                        'filesize': file_size,
+                        'filesize': filesize,
                         'torrentfile': torrent_link,
                         'torrentfile': torrent_link,
+                        'magnetlink': magnet_link,
                         'template': 'torrent.html'})
                         'template': 'torrent.html'})
 
 
     return results
     return results

+ 91 - 33
tests/unit/engines/test_nyaa.py

@@ -13,38 +13,92 @@ class TestNyaaEngine(SearxTestCase):
         params = nyaa.request(query, dic)
         params = nyaa.request(query, dic)
         self.assertTrue('url' in params)
         self.assertTrue('url' in params)
         self.assertTrue(query in params['url'])
         self.assertTrue(query in params['url'])
-        self.assertTrue('nyaa.se' in params['url'])
+        self.assertTrue('nyaa.si' in params['url'])
 
 
     def test_response(self):
     def test_response(self):
         resp = mock.Mock(text='<html></html>')
         resp = mock.Mock(text='<html></html>')
         self.assertEqual(nyaa.response(resp), [])
         self.assertEqual(nyaa.response(resp), [])
 
 
         html = """
         html = """
-        <table class="tlist">
-          <tbody>
-            <tr class="trusted tlistrow">
-              <td class="tlisticon">
-                <a href="//www.nyaa.se" title="English-translated Anime">
-                   <img src="//files.nyaa.se" alt="English-translated Anime">
-                </a>
-              </td>
-              <td class="tlistname">
-                <a href="//www.nyaa.se/?page3">
-                  Sample torrent title
-                </a>
-              </td>
-              <td class="tlistdownload">
-                <a href="//www.nyaa.se/?page_dl" title="Download">
-                  <img src="//files.nyaa.se/www-dl.png" alt="DL">
-                </a>
-              </td>
-              <td class="tlistsize">10 MiB</td>
-              <td class="tlistsn">1</td>
-              <td class="tlistln">3</td>
-              <td class="tlistdn">666</td>
-              <td class="tlistmn">0</td>
-            </tr>
-          </tbody>
+        <table class="table table-bordered table-hover table-striped torrent-list">
+        <thead>
+        <tr>
+        <th class="hdr-category text-center" style="width:80px;">
+        <div>Category</div>
+        </th>
+        <th class="hdr-name" style="width:auto;">
+        <div>Name</div>
+        </th>
+        <th class="hdr-comments sorting text-center" title="Comments" style="width:50px;">
+        <a href="/?f=0&amp;c=0_0&amp;q=Death+Parade&amp;s=comments&amp;o=desc"></a>
+        <i class="fa fa-comments-o"></i>
+        </th>
+        <th class="hdr-link text-center" style="width:70px;">
+        <div>Link</div>
+        </th>
+        <th class="hdr-size sorting text-center" style="width:100px;">
+        <a href="/?f=0&amp;c=0_0&amp;q=Death+Parade&amp;s=size&amp;o=desc"></a>
+        <div>Size</div>
+        </th>
+        <th class="hdr-date sorting_desc text-center" title="In local time" style="width:140px;">
+        <a href="/?f=0&amp;c=0_0&amp;q=Death+Parade&amp;s=id&amp;o=asc"></a>
+        <div>Date</div>
+        </th>
+        <th class="hdr-seeders sorting text-center" title="Seeders" style="width:50px;">
+        <a href="/?f=0&amp;c=0_0&amp;q=Death+Parade&amp;s=seeders&amp;o=desc"></a>
+        <i class="fa fa-arrow-up" aria-hidden="true"></i>
+        </th>
+        <th class="hdr-leechers sorting text-center" title="Leechers" style="width:50px;">
+        <a href="/?f=0&amp;c=0_0&amp;q=Death+Parade&amp;s=leechers&amp;o=desc"></a>
+        <i class="fa fa-arrow-down" aria-hidden="true"></i>
+        </th>
+        <th class="hdr-downloads sorting text-center" title="Completed downloads" style="width:50px;">
+        <a href="/?f=0&amp;c=0_0&amp;q=Death+Parade&amp;s=downloads&amp;o=desc"></a>
+        <i class="fa fa-check" aria-hidden="true"></i>
+        </th>
+        </tr>
+        </thead>
+        <tbody>
+        <tr class="default">
+        <td style="padding:0 4px;">
+        <a href="/?c=1_2" title="Anime - English-translated">
+        <img src="/static/img/icons/nyaa/1_2.png" alt="Anime - English-translated">
+        </a>
+        </td>
+        <td colspan="2">
+        <a href="/view/1" title="Sample title 1">Sample title 1</a>
+        </td>
+        <td class="text-center" style="white-space: nowrap;">
+        <a href="/download/1.torrent"><i class="fa fa-fw fa-download"></i></a>
+        <a href="magnet:?xt=urn:btih:2"><i class="fa fa-fw fa-magnet"></i></a>
+        </td>
+        <td class="text-center">723.7 MiB</td>
+        <td class="text-center" data-timestamp="1503307456" title="1 week 3
+        days 9 hours 44 minutes 39 seconds ago">2017-08-21 11:24</td>
+        <td class="text-center" style="color: green;">1</td>
+        <td class="text-center" style="color: red;">3</td>
+        <td class="text-center">12</td>
+        </tr>
+        <tr class="default">
+        <td style="padding:0 4px;">
+        <a href="/?c=1_2" title="Anime - English-translated">
+        <img src="/static/img/icons/nyaa/1_2.png" alt="Anime - English-translated">
+        </a>
+        </td>
+        <td colspan="2">
+        <a href="/view/2" title="Sample title 2">Sample title 2</a>
+        </td>
+        <td class="text-center" style="white-space: nowrap;">
+        <a href="magnet:?xt=urn:btih:2"><i class="fa fa-fw fa-magnet"></i></a>
+        </td>
+        <td class="text-center">8.2 GiB</td>
+        <td class="text-center" data-timestamp="1491608400" title="4 months 3
+        weeks 4 days 19 hours 28 minutes 55 seconds ago">2017-04-08 01:40</td>
+        <td class="text-center" style="color: green;">10</td>
+        <td class="text-center" style="color: red;">1</td>
+        <td class="text-center">206</td>
+        </tr>
+        </tbody>
         </table>
         </table>
         """
         """
 
 
@@ -52,15 +106,19 @@ class TestNyaaEngine(SearxTestCase):
         results = nyaa.response(resp)
         results = nyaa.response(resp)
 
 
         self.assertEqual(type(results), list)
         self.assertEqual(type(results), list)
-        self.assertEqual(len(results), 1)
+        self.assertEqual(len(results), 2)
 
 
         r = results[0]
         r = results[0]
-        self.assertTrue(r['url'].find('www.nyaa.se/?page3') >= 0)
-        self.assertTrue(r['torrentfile'].find('www.nyaa.se/?page_dl') >= 0)
-        self.assertTrue(r['content'].find('English-translated Anime') >= 0)
-        self.assertTrue(r['content'].find('Downloaded 666 times.') >= 0)
+        self.assertTrue(r['url'].find('1') >= 0)
+        self.assertTrue(r['torrentfile'].find('1.torrent') >= 0)
+        self.assertTrue(r['content'].find('Anime - English-translated') >= 0)
+        self.assertTrue(r['content'].find('Downloaded 12 times.') >= 0)
 
 
-        self.assertEqual(r['title'], 'Sample torrent title')
+        self.assertEqual(r['title'], 'Sample title 1')
         self.assertEqual(r['seed'], 1)
         self.assertEqual(r['seed'], 1)
         self.assertEqual(r['leech'], 3)
         self.assertEqual(r['leech'], 3)
-        self.assertEqual(r['filesize'], 10 * 1024 * 1024)
+        self.assertEqual(r['filesize'], 723700000)
+
+        r = results[1]
+        self.assertTrue(r['url'].find('2') >= 0)
+        self.assertTrue(r['magnetlink'].find('magnet:') >= 0)