query_gallery.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. # ©️ Dan Gazizullin, 2021-2023
  2. # This file is a part of Hikka Userbot
  3. # 🌐 https://github.com/hikariatama/Hikka
  4. # You can redistribute it and/or modify it under the terms of the GNU AGPLv3
  5. # 🔑 https://www.gnu.org/licenses/agpl-3.0.html
  6. import asyncio
  7. import logging
  8. import time
  9. import typing
  10. from aiogram.types import InlineQuery, InlineQueryResultArticle, InputTextMessageContent
  11. from .. import utils
  12. from .types import InlineUnit
  13. logger = logging.getLogger(__name__)
  14. class QueryGallery(InlineUnit):
  15. async def query_gallery(
  16. self,
  17. query: InlineQuery,
  18. items: typing.List[typing.Dict[str, typing.Any]],
  19. *,
  20. force_me: bool = False,
  21. disable_security: bool = False,
  22. always_allow: typing.Optional[typing.List[int]] = None,
  23. ) -> bool:
  24. """
  25. Answer inline query with a bunch of inline galleries
  26. :param query: `InlineQuery` which should be answered with inline gallery
  27. :param items: Array of dicts with inline results.
  28. Each dict *must* has a:
  29. - `title` - The title of the result
  30. - `description` - Short description of the result
  31. - `next_handler` - Inline gallery handler. Callback or awaitable
  32. Each dict *can* has a:
  33. - `caption` - Caption of photo. Defaults to `""`
  34. - `force_me` - Whether the button must be accessed only by owner. Defaults to `False`
  35. - `disable_security` - Whether to disable the security checks at all. Defaults to `False`
  36. :param force_me: Either this gallery buttons must be pressed only by owner scope or no
  37. :param always_allow: Users, that are allowed to press buttons in addition to previous rules
  38. :param disable_security: By default, Hikka will try to check security of gallery
  39. If you want to disable all security checks on this gallery in particular, pass `disable_security=True`
  40. :return: Status of answer
  41. """
  42. if not isinstance(force_me, bool):
  43. logger.error(
  44. "Invalid type for `force_me`. Expected `bool`, got %s",
  45. type(force_me),
  46. )
  47. return False
  48. if not isinstance(disable_security, bool):
  49. logger.error(
  50. "Invalid type for `disable_security`. Expected `bool`, got %s",
  51. type(disable_security),
  52. )
  53. return False
  54. if always_allow and not isinstance(always_allow, list):
  55. logger.error(
  56. "Invalid type for `always_allow`. Expected `list`, got %s",
  57. type(always_allow),
  58. )
  59. return False
  60. if not always_allow:
  61. always_allow = []
  62. if (
  63. not isinstance(items, list)
  64. or not all(isinstance(i, dict) for i in items)
  65. or not all(
  66. "title" in i
  67. and "description" in i
  68. and "next_handler" in i
  69. and (
  70. callable(i["next_handler"])
  71. or asyncio.iscoroutinefunction(i)
  72. or isinstance(i, list)
  73. )
  74. and isinstance(i["title"], str)
  75. and isinstance(i["description"], str)
  76. for i in items
  77. )
  78. ):
  79. logger.error("Invalid `items` specified in query gallery")
  80. return False
  81. result = []
  82. for i in items:
  83. if "thumb_handler" not in i:
  84. photo_url = await self._call_photo(i["next_handler"])
  85. if not photo_url:
  86. return False
  87. if isinstance(photo_url, list):
  88. photo_url = photo_url[0]
  89. if not isinstance(photo_url, str):
  90. logger.error(
  91. "Invalid result from `next_handler`. Expected `str`, got %s",
  92. type(photo_url),
  93. )
  94. continue
  95. else:
  96. photo_url = await self._call_photo(i["thumb_handler"])
  97. if not photo_url:
  98. return False
  99. if isinstance(photo_url, list):
  100. photo_url = photo_url[0]
  101. if not isinstance(photo_url, str):
  102. logger.error(
  103. "Invalid result from `thumb_handler`. Expected `str`, got %s",
  104. type(photo_url),
  105. )
  106. continue
  107. id_ = utils.rand(16)
  108. self._custom_map[id_] = {
  109. "handler": i["next_handler"],
  110. "ttl": round(time.time()) + 120,
  111. **({"always_allow": always_allow} if always_allow else {}),
  112. **({"force_me": force_me} if force_me else {}),
  113. **({"disable_security": disable_security} if disable_security else {}),
  114. **({"caption": i["caption"]} if "caption" in i else {}),
  115. }
  116. result += [
  117. InlineQueryResultArticle(
  118. id=utils.rand(20),
  119. title=i["title"],
  120. description=i["description"],
  121. input_message_content=InputTextMessageContent(
  122. f"🌘 <b>Opening gallery...</b>\n<i>#id: {id_}</i>",
  123. "HTML",
  124. disable_web_page_preview=True,
  125. ),
  126. thumb_url=photo_url,
  127. thumb_width=128,
  128. thumb_height=128,
  129. )
  130. ]
  131. await query.answer(result, cache_time=0)
  132. return True