| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 | 
							- # SPDX-License-Identifier: AGPL-3.0-or-later
 
- # lint: pylint
 
- """Torznab WebAPI
 
- A engine that implements the `torznab WebAPI`_.
 
- .. _torznab WebAPI: https://torznab.github.io/spec-1.3-draft/torznab
 
- """
 
- from datetime import datetime
 
- from urllib.parse import quote
 
- from lxml import etree
 
- from searx.exceptions import SearxEngineAPIException
 
- # about
 
- about = {
 
-     "website": None,
 
-     "wikidata_id": None,
 
-     "official_api_documentation": "https://torznab.github.io/spec-1.3-draft",
 
-     "use_official_api": True,
 
-     "require_api_key": False,
 
-     "results": 'XML',
 
- }
 
- categories = ['files']
 
- paging = False
 
- time_range_support = False
 
- # defined in settings.yml
 
- # example (Jackett): "http://localhost:9117/api/v2.0/indexers/all/results/torznab"
 
- base_url = ''
 
- api_key = ''
 
- # https://newznab.readthedocs.io/en/latest/misc/api/#predefined-categories
 
- torznab_categories = []
 
- def init(engine_settings=None): # pylint: disable=unused-argument
 
-     if len(base_url) < 1:
 
-         raise ValueError('missing torznab base_url')
 
- def request(query, params):
 
-     search_url = base_url + '?t=search&q={search_query}'
 
-     if len(api_key) > 0:
 
-         search_url += '&apikey={api_key}'
 
-     if len(torznab_categories) > 0:
 
-         search_url += '&cat={torznab_categories}'
 
-     params['url'] = search_url.format(
 
-         search_query = quote(query),
 
-         api_key = api_key,
 
-         torznab_categories = ",".join([str(x) for x in torznab_categories])
 
-     )
 
-     return params
 
- def response(resp):
 
-     results = []
 
-     search_results = etree.XML(resp.content)
 
-     # handle errors
 
-     # https://newznab.readthedocs.io/en/latest/misc/api/#newznab-error-codes
 
-     if search_results.tag == "error":
 
-         raise SearxEngineAPIException(search_results.get("description"))
 
-     for item in search_results[0].iterfind('item'):
 
-         result = {'template': 'torrent.html'}
 
-         enclosure = item.find('enclosure')
 
-         result["filesize"] = int(enclosure.get('length'))
 
-         link = get_property(item, 'link')
 
-         guid = get_property(item, 'guid')
 
-         comments = get_property(item, 'comments')
 
-         # define url
 
-         result["url"] = enclosure.get('url')
 
-         if comments is not None and comments.startswith('http'):
 
-             result["url"] = comments
 
-         elif guid is not None and guid.startswith('http'):
 
-             result["url"] = guid
 
-         # define torrent file url
 
-         result["torrentfile"] = None
 
-         if enclosure.get('url').startswith("http"):
 
-             result["torrentfile"] = enclosure.get('url')
 
-         elif link is not None and link.startswith('http'):
 
-             result["torrentfile"] = link
 
-         # define magnet link
 
-         result["magnetlink"] = get_torznab_attr(item, 'magneturl')
 
-         if result["magnetlink"] is None:
 
-             if enclosure.get('url').startswith("magnet"):
 
-                 result["magnetlink"] = enclosure.get('url')
 
-             elif link is not None and link.startswith('magnet'):
 
-                 result["magnetlink"] = link
 
-         result["title"] = get_property(item, 'title')
 
-         result["files"] = get_property(item, 'files')
 
-         result["publishedDate"] = None
 
-         try:
 
-             result["publishedDate"] = datetime.strptime(
 
-                 get_property(item, 'pubDate'), '%a, %d %b %Y %H:%M:%S %z')
 
-         except (ValueError, TypeError) as e:
 
-             logger.debug("ignore exception (publishedDate): %s", e)
 
-         result["seed"] = get_torznab_attr(item, 'seeders')
 
-         # define leech
 
-         result["leech"] = get_torznab_attr(item, 'leechers')
 
-         if result["leech"] is None and result["seed"] is not None:
 
-             peers = get_torznab_attr(item, 'peers')
 
-             if peers is not None:
 
-                 result["leech"] = int(peers) - int(result["seed"])
 
-         results.append(result)
 
-     return results
 
- def get_property(item, property_name):
 
-     property_element = item.find(property_name)
 
-     if property_element is not None:
 
-         return property_element.text
 
-     return None
 
- def get_torznab_attr(item, attr_name):
 
-     element = item.find(
 
-         './/torznab:attr[@name="{attr_name}"]'.format(attr_name=attr_name),
 
-         {
 
-             'torznab': 'http://torznab.com/schemas/2015/feed'
 
-         }
 
-     )
 
-     if element is not None:
 
-         return element.get("value")
 
-     return None
 
 
  |