.oO SearXNG Developer Documentation Oo.
Loading...
Searching...
No Matches
tokyotoshokan.py
Go to the documentation of this file.
1# SPDX-License-Identifier: AGPL-3.0-or-later
2"""Tokyo Toshokan (A BitTorrent Library for Japanese Media)
3
4"""
5
6import re
7from datetime import datetime
8from urllib.parse import urlencode
9
10from lxml import html
11from searx.utils import extract_text, int_or_zero
12
13# about
14about = {
15 "website": 'https://www.tokyotosho.info/',
16 "wikidata_id": None,
17 "official_api_documentation": None,
18 "use_official_api": False,
19 "require_api_key": False,
20 "results": 'HTML',
21}
22
23# engine dependent config
24categories = ['files']
25paging = True
26
27# search-url
28base_url = 'https://www.tokyotosho.info/'
29search_url = base_url + 'search.php?{query}'
30
31
32# do search-request
33def request(query, params):
34 query = urlencode({'page': params['pageno'], 'terms': query})
35 params['url'] = search_url.format(query=query)
36 return params
37
38
39# get response from search-request
40def response(resp):
41 results = []
42
43 dom = html.fromstring(resp.text)
44 rows = dom.xpath('//table[@class="listing"]//tr[contains(@class, "category_0")]')
45
46 # check if there are no results or page layout was changed so we cannot parse it
47 # currently there are two rows for each result, so total count must be even
48 if len(rows) == 0 or len(rows) % 2 != 0:
49 return []
50
51 # regular expression for parsing torrent size strings
52 size_re = re.compile(r'[\d.]+(T|G|M)?B', re.IGNORECASE)
53
54 # processing the results, two rows at a time
55 for i in range(0, len(rows), 2):
56 # parse the first row
57 name_row = rows[i]
58
59 links = name_row.xpath('./td[@class="desc-top"]/a')
60 params = {'template': 'torrent.html', 'url': links[-1].attrib.get('href'), 'title': extract_text(links[-1])}
61 # I have not yet seen any torrents without magnet links, but
62 # it's better to be prepared to stumble upon one some day
63 if len(links) == 2:
64 magnet = links[0].attrib.get('href')
65 if magnet.startswith('magnet'):
66 # okay, we have a valid magnet link, let's add it to the result
67 params['magnetlink'] = magnet
68
69 # no more info in the first row, start parsing the second one
70 info_row = rows[i + 1]
71 desc = extract_text(info_row.xpath('./td[@class="desc-bot"]')[0])
72 for item in desc.split('|'):
73 item = item.strip()
74 if item.startswith('Size:'):
75 try:
76 params['filesize'] = size_re.search(item).group()
77 except: # pylint: disable=bare-except
78 pass
79 elif item.startswith('Date:'):
80 try:
81 # Date: 2016-02-21 21:44 UTC
82 date = datetime.strptime(item, 'Date: %Y-%m-%d %H:%M UTC')
83 params['publishedDate'] = date
84 except: # pylint: disable=bare-except
85 pass
86 elif item.startswith('Comment:'):
87 params['content'] = item
88 stats = info_row.xpath('./td[@class="stats"]/span')
89 # has the layout not changed yet?
90 if len(stats) == 3:
91 params['seed'] = int_or_zero(extract_text(stats[0]))
92 params['leech'] = int_or_zero(extract_text(stats[1]))
93
94 results.append(params)
95
96 return results