bt4g.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. # SPDX-License-Identifier: AGPL-3.0-or-later
  2. """BT4G_ (bt4g.com) is not a tracker and doesn't store any content and only
  3. collects torrent metadata (such as file names and file sizes) and a magnet link
  4. (torrent identifier).
  5. This engine does not parse the HTML page because there is an API in XML (RSS).
  6. The RSS feed provides fewer data like amount of seeders/leechers and the files
  7. in the torrent file. It's a tradeoff for a "stable" engine as the XML from RSS
  8. content will change way less than the HTML page.
  9. .. _BT4G: https://bt4g.com/
  10. Configuration
  11. =============
  12. The engine has the following additional settings:
  13. - :py:obj:`bt4g_order_by`
  14. - :py:obj:`bt4g_category`
  15. With this options a SearXNG maintainer is able to configure **additional**
  16. engines for specific torrent searches. For example a engine to search only for
  17. Movies and sort the result list by the count of seeders.
  18. .. code:: yaml
  19. - name: bt4g.movie
  20. engine: bt4g
  21. shortcut: bt4gv
  22. categories: video
  23. bt4g_order_by: seeders
  24. bt4g_category: 'movie'
  25. Implementations
  26. ===============
  27. """
  28. from datetime import datetime
  29. from urllib.parse import quote
  30. from lxml import etree
  31. # about
  32. about = {
  33. "website": 'https://bt4gprx.com',
  34. "use_official_api": False,
  35. "require_api_key": False,
  36. "results": 'XML',
  37. }
  38. # engine dependent config
  39. categories = ['files']
  40. paging = True
  41. time_range_support = True
  42. # search-url
  43. url = 'https://bt4gprx.com'
  44. search_url = url + '/search?q={search_term}&orderby={order_by}&category={category}&p={pageno}&page=rss'
  45. bt4g_order_by = 'relevance'
  46. """Result list can be ordered by ``relevance`` (default), ``size``, ``seeders``
  47. or ``time``.
  48. .. hint::
  49. When *time_range* is activate, the results always ordered by ``time``.
  50. """
  51. bt4g_category = 'all'
  52. """BT$G offers categories: ``all`` (default), ``audio``, ``movie``, ``doc``,
  53. ``app`` and `` other``.
  54. """
  55. def request(query, params):
  56. order_by = bt4g_order_by
  57. if params['time_range']:
  58. order_by = 'time'
  59. params['url'] = search_url.format(
  60. search_term=quote(query),
  61. order_by=order_by,
  62. category=bt4g_category,
  63. pageno=params['pageno'],
  64. )
  65. return params
  66. def response(resp):
  67. results = []
  68. search_results = etree.XML(resp.content)
  69. # return empty array if nothing is found
  70. if len(search_results) == 0:
  71. return []
  72. for entry in search_results.xpath('./channel/item'):
  73. title = entry.find("title").text
  74. link = entry.find("guid").text
  75. fullDescription = entry.find("description").text.split('<br>')
  76. magnetlink = entry.find("link").text
  77. pubDate = entry.find("pubDate").text
  78. results.append(
  79. {
  80. 'url': link,
  81. 'title': title,
  82. 'magnetlink': magnetlink,
  83. 'seed': 'N/A',
  84. 'leech': 'N/A',
  85. 'filesize': fullDescription[1],
  86. 'publishedDate': datetime.strptime(pubDate, '%a,%d %b %Y %H:%M:%S %z'),
  87. 'template': 'torrent.html',
  88. }
  89. )
  90. return results