search.py 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. from typing import TYPE_CHECKING, Any, Optional
  2. from yandex_music import Album, Artist, JSONType, Playlist, Track, User, Video, YandexMusicModel
  3. from yandex_music.utils import model
  4. if TYPE_CHECKING:
  5. from yandex_music import Best, ClientType, SearchResult
  6. @model
  7. class Search(YandexMusicModel):
  8. """Класс, представляющий результаты поиска.
  9. Attributes:
  10. search_request_id (:obj:`str`): ID запроса.
  11. text (:obj:`str`): Текст запроса.
  12. best (:obj:`yandex_music.Best`, optional): Лучший результат.
  13. albums (:obj:`yandex_music.SearchResult`, optional): Найденные альбомы.
  14. artists (:obj:`yandex_music.SearchResult`, optional): Найденные исполнители.
  15. playlists (:obj:`yandex_music.SearchResult`, optional): Найденные плейлисты.
  16. tracks (:obj:`yandex_music.SearchResult`, optional): Найденные треки.
  17. videos (:obj:`yandex_music.SearchResult`, optional): Найденные видео.
  18. users (:obj:`yandex_music.SearchResult`, optional): Найденные пользователи.
  19. podcasts (:obj:`yandex_music.SearchResult`, optional): Найденные подкасты.
  20. podcast_episodes (:obj:`yandex_music.SearchResult`, optional): Найденные выпуски подкастов.
  21. type (:obj:`str`), optional: Тип результата по которому искали (аргумент в Client.search).
  22. page (:obj:`int`, optional): Текущая страница.
  23. per_page (:obj:`int`, optional): Результатов на странице.
  24. misspell_result (:obj:`str`, optional): Запрос с автоматическим исправлением.
  25. misspell_original (:obj:`str`, optional): Оригинальный запрос.
  26. misspell_corrected (:obj:`bool`, optional): Был ли исправлен запрос.
  27. nocorrect (:obj:`bool`, optional): Было ли отключено исправление результата.
  28. client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
  29. """
  30. search_request_id: str
  31. text: str
  32. best: Optional['Best']
  33. albums: Optional['SearchResult[Album]']
  34. artists: Optional['SearchResult[Artist]']
  35. playlists: Optional['SearchResult[Playlist]']
  36. tracks: Optional['SearchResult[Track]']
  37. videos: Optional['SearchResult[Video]']
  38. users: Optional['SearchResult[User]']
  39. podcasts: Optional['SearchResult[Album]']
  40. podcast_episodes: Optional['SearchResult[Track]']
  41. type: Optional[str] = None
  42. page: Optional[int] = None
  43. per_page: Optional[int] = None
  44. misspell_result: Optional[str] = None
  45. misspell_original: Optional[str] = None
  46. misspell_corrected: Optional[bool] = None
  47. nocorrect: Optional[bool] = None
  48. client: Optional['ClientType'] = None
  49. def __post_init__(self) -> None:
  50. self._id_attrs = (
  51. self.search_request_id,
  52. self.text,
  53. self.best,
  54. self.albums,
  55. self.artists,
  56. self.playlists,
  57. self.tracks,
  58. self.videos,
  59. self.users,
  60. self.podcasts,
  61. self.podcast_episodes,
  62. )
  63. def get_page(self, page: int, *args: Any, **kwargs: Any) -> Optional['Search']:
  64. """Получение определённой страницы поиска.
  65. Args:
  66. page (:obj:`int`): Номер страницы.
  67. *args: Произвольные аргументы (будут переданы в запрос).
  68. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  69. Returns:
  70. :obj:`yandex_music.Search` | :obj:`None`: Страница результата поиска или :obj:`None`.
  71. """
  72. assert isinstance(self.nocorrect, bool)
  73. assert isinstance(self.type, str)
  74. assert self.valid_client(self.client)
  75. return self.client.search(self.text, self.nocorrect, self.type, page, *args, **kwargs)
  76. async def get_page_async(self, page: int, *args: Any, **kwargs: Any) -> Optional['Search']:
  77. """Получение определённой страницы поиска.
  78. Args:
  79. page (:obj:`int`): Номер страницы.
  80. *args: Произвольные аргументы (будут переданы в запрос).
  81. **kwargs: Произвольные именованные аргументы (будут переданы в запрос).
  82. Returns:
  83. :obj:`yandex_music.Search` | :obj:`None`: Страница результата поиска или :obj:`None`.
  84. """
  85. assert isinstance(self.nocorrect, bool)
  86. assert isinstance(self.type, str)
  87. assert self.valid_async_client(self.client)
  88. return await self.client.search(self.text, self.nocorrect, self.type, page, *args, **kwargs)
  89. def next_page(self, *args: Any, **kwargs: Any) -> Optional['Search']:
  90. """Получение следующей страницы поиска.
  91. Returns:
  92. :obj:`yandex_music.Search` | :obj:`None`: Следующая страница результата поиска или :obj:`None`.
  93. """
  94. assert isinstance(self.page, int)
  95. return self.get_page(self.page + 1, *args, **kwargs)
  96. async def next_page_async(self, *args: Any, **kwargs: Any) -> Optional['Search']:
  97. """Получение следующей страницы поиска.
  98. Returns:
  99. :obj:`yandex_music.Search` | :obj:`None`: Следующая страница результата поиска или :obj:`None`.
  100. """
  101. assert isinstance(self.page, int)
  102. return await self.get_page_async(self.page + 1, *args, **kwargs)
  103. def prev_page(self, *args: Any, **kwargs: Any) -> Optional['Search']:
  104. """Получение предыдущей страницы поиска.
  105. Returns:
  106. :obj:`yandex_music.Search` | :obj:`None`: Предыдущая страница результата поиска или :obj:`None`.
  107. """
  108. assert isinstance(self.page, int)
  109. return self.get_page(self.page - 1, *args, **kwargs)
  110. async def prev_page_async(self, *args: Any, **kwargs: Any) -> Optional['Search']:
  111. """Получение предыдущей страницы поиска.
  112. Returns:
  113. :obj:`yandex_music.Search` | :obj:`None`: Предыдущая страница результата поиска или :obj:`None`.
  114. """
  115. assert isinstance(self.page, int)
  116. return await self.get_page_async(self.page - 1, *args, **kwargs)
  117. @classmethod
  118. def de_json(cls, data: 'JSONType', client: 'ClientType') -> Optional['Search']:
  119. """Десериализация объекта.
  120. Args:
  121. data (:obj:`dict`): Поля и значения десериализуемого объекта.
  122. client (:obj:`yandex_music.Client`, optional): Клиент Yandex Music.
  123. Returns:
  124. :obj:`yandex_music.Search`: Результаты поиска.
  125. """
  126. if not cls.is_dict_model_data(data):
  127. return None
  128. cls_data = cls.cleanup_data(data, client)
  129. from yandex_music import Best, SearchResult
  130. # в ОЧЕНЬ редких случаях сервер творит дичь и может вернуть результат плейлистов в поле artists
  131. # или вернуть в поле users результаты с плейлистами
  132. # очень редких это около 10 запросов за 3 месяца работы стороннего клиента
  133. cls_data['best'] = Best.de_json(data.get('best'), client)
  134. cls_data['albums'] = SearchResult.de_json(data.get('albums'), client, 'album')
  135. cls_data['artists'] = SearchResult.de_json(data.get('artists'), client, 'artist')
  136. cls_data['playlists'] = SearchResult.de_json(data.get('playlists'), client, 'playlist')
  137. cls_data['tracks'] = SearchResult.de_json(data.get('tracks'), client, 'track')
  138. cls_data['videos'] = SearchResult.de_json(data.get('videos'), client, 'video')
  139. cls_data['users'] = SearchResult.de_json(data.get('users'), client, 'user')
  140. cls_data['podcasts'] = SearchResult.de_json(data.get('podcasts'), client, 'podcast')
  141. cls_data['podcast_episodes'] = SearchResult.de_json(data.get('podcast_episodes'), client, 'podcast_episode')
  142. return cls(client=client, **cls_data) # type: ignore
  143. # camelCase псевдонимы
  144. #: Псевдоним для :attr:`get_page`
  145. getPage = get_page
  146. #: Псевдоним для :attr:`get_page_async`
  147. getPageAsync = get_page_async
  148. #: Псевдоним для :attr:`next_page`
  149. nextPage = next_page
  150. #: Псевдоним для :attr:`next_page_async`
  151. nextPageAsync = next_page_async
  152. #: Псевдоним для :attr:`prev_page`
  153. prevPage = prev_page
  154. #: Псевдоним для :attr:`prev_page_async`
  155. prevPageAsync = prev_page_async