lemmy.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # SPDX-License-Identifier: AGPL-3.0-or-later
  2. # lint: pylint
  3. """This engine uses the Lemmy API (https://lemmy.ml/api/v3/search), which is
  4. documented at `lemmy-js-client`_ / `Interface Search`_. Since Lemmy is
  5. federated, results are from many different, independent lemmy instances, and not
  6. only the official one.
  7. .. _lemmy-js-client: https://join-lemmy.org/api/modules.html
  8. .. _Interface Search: https://join-lemmy.org/api/interfaces/Search.html
  9. Configuration
  10. =============
  11. The engine has the following additional settings:
  12. - :py:obj:`base_url`
  13. - :py:obj:`lemmy_type`
  14. This implementation is used by different lemmy engines in the :ref:`settings.yml
  15. <settings engine>`:
  16. .. code:: yaml
  17. - name: lemmy communities
  18. lemmy_type: Communities
  19. ...
  20. - name: lemmy users
  21. lemmy_type: Users
  22. ...
  23. - name: lemmy posts
  24. lemmy_type: Posts
  25. ...
  26. - name: lemmy comments
  27. lemmy_type: Comments
  28. ...
  29. Implementations
  30. ===============
  31. """
  32. from urllib.parse import urlencode
  33. from markdown_it import MarkdownIt
  34. from searx.utils import html_to_text
  35. about = {
  36. "website": 'https://lemmy.ml/',
  37. "wikidata_id": 'Q84777032',
  38. "official_api_documentation": "https://join-lemmy.org/api/",
  39. "use_official_api": True,
  40. "require_api_key": False,
  41. "results": 'JSON',
  42. }
  43. paging = True
  44. categories = ['general', 'social media']
  45. base_url = "https://lemmy.ml/"
  46. """By default, https://lemmy.ml is used for providing the results. If you want
  47. to use a different lemmy instance, you can specify ``base_url``.
  48. """
  49. lemmy_type = "Communities"
  50. """Any of ``Communities``, ``Users``, ``Posts``, ``Comments``"""
  51. def request(query, params):
  52. args = {
  53. 'q': query,
  54. 'page': params['pageno'],
  55. 'type_': lemmy_type,
  56. }
  57. params['url'] = f"{base_url}api/v3/search?{urlencode(args)}"
  58. return params
  59. def _format_content(content):
  60. html = MarkdownIt("commonmark", {"typographer": True}).enable(["replacements", "smartquotes"]).render(content)
  61. return html_to_text(html)
  62. def _get_communities(json):
  63. results = []
  64. for result in json["communities"]:
  65. results.append(
  66. {
  67. 'url': result['community']['actor_id'],
  68. 'title': result['community']['title'],
  69. 'content': _format_content(result['community'].get('description', '')),
  70. }
  71. )
  72. return results
  73. def _get_users(json):
  74. results = []
  75. for result in json["users"]:
  76. results.append(
  77. {
  78. 'url': result['person']['actor_id'],
  79. 'title': result['person']['name'],
  80. 'content': _format_content(result['person'].get('bio', '')),
  81. }
  82. )
  83. return results
  84. def _get_posts(json):
  85. results = []
  86. for result in json["posts"]:
  87. results.append(
  88. {
  89. 'url': result['post']['ap_id'],
  90. 'title': result['post']['name'],
  91. 'content': _format_content(result['post'].get('body', '')),
  92. }
  93. )
  94. return results
  95. def _get_comments(json):
  96. results = []
  97. for result in json["comments"]:
  98. results.append(
  99. {
  100. 'url': result['comment']['ap_id'],
  101. 'title': result['post']['name'],
  102. 'content': _format_content(result['comment']['content']),
  103. }
  104. )
  105. return results
  106. def response(resp):
  107. json = resp.json()
  108. if lemmy_type == "Communities":
  109. return _get_communities(json)
  110. if lemmy_type == "Users":
  111. return _get_users(json)
  112. if lemmy_type == "Posts":
  113. return _get_posts(json)
  114. if lemmy_type == "Comments":
  115. return _get_comments(json)
  116. raise ValueError(f"Unsupported lemmy type: {lemmy_type}")