From d55a9534623d8c2b132fb989db0cc030b0615d50 Mon Sep 17 00:00:00 2001 From: "Ilya (Marshal)" Date: Sun, 23 Apr 2023 01:34:02 +0200 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D1=80=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB=20"=D0=9F=D1=80?= =?UTF-8?q?=D0=B8=D0=BC=D0=B5=D1=80=D1=8B"=20=D0=B2=20=D0=B4=D0=BE=D0=BA?= =?UTF-8?q?=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D0=B0=D1=86=D0=B8=D1=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/source/examples.chart.md | 40 +++++++++++ .../source/examples.daily_playlist_updater.md | 43 ++++++++++++ docs/source/examples.get_album_with_tracks.md | 44 ++++++++++++ docs/source/examples.like_and_dislike.md | 32 +++++++++ docs/source/examples.lyrics_playing_track.md | 34 +++++++++ docs/source/examples.md | 25 +++++++ docs/source/examples.proxy.md | 32 +++++++++ docs/source/examples.search.md | 70 +++++++++++++++++++ docs/source/index.rst | 1 + 9 files changed, 321 insertions(+) create mode 100644 docs/source/examples.chart.md create mode 100644 docs/source/examples.daily_playlist_updater.md create mode 100644 docs/source/examples.get_album_with_tracks.md create mode 100644 docs/source/examples.like_and_dislike.md create mode 100644 docs/source/examples.lyrics_playing_track.md create mode 100644 docs/source/examples.md create mode 100644 docs/source/examples.proxy.md create mode 100644 docs/source/examples.search.md diff --git a/docs/source/examples.chart.md b/docs/source/examples.chart.md new file mode 100644 index 0000000..9509da1 --- /dev/null +++ b/docs/source/examples.chart.md @@ -0,0 +1,40 @@ +# Получение чарта + +Пример работы с чартом ЯМ. Получение треков, отображение позиций и их изменения с использованием эмодзи. + +```python +import os + +from yandex_music import Client + + +CHART_ID = 'world' +TOKEN = os.environ.get('TOKEN') + +client = Client(TOKEN).init() +chart = client.chart(CHART_ID).chart + +text = [f'🏆 {chart.title}', chart.description, '', 'Треки:'] + +for track_short in chart.tracks: + track, chart = track_short.track, track_short.chart + artists = '' + if track.artists: + artists = ' - ' + ', '.join(artist.name for artist in track.artists) + + track_text = f'{track.title}{artists}' + + if chart.progress == 'down': + track_text = '🔻 ' + track_text + elif chart.progress == 'up': + track_text = '🔺 ' + track_text + elif chart.progress == 'new': + track_text = '🆕 ' + track_text + elif chart.position == 1: + track_text = '👑 ' + track_text + + track_text = f'{chart.position} {track_text}' + text.append(track_text) + +print('\n'.join(text)) +``` diff --git a/docs/source/examples.daily_playlist_updater.md b/docs/source/examples.daily_playlist_updater.md new file mode 100644 index 0000000..9c38daa --- /dev/null +++ b/docs/source/examples.daily_playlist_updater.md @@ -0,0 +1,43 @@ +# Обновление стрика дейлика + +Отмечает "Плейлист дня" как прослушанный сегодня (добавляет +1 к счетчику). + +```python +import sys +import datetime +from yandex_music.client import Client + +# Help text +if len(sys.argv) == 1 or len(sys.argv) > 3: + print('Usage: DailyPlaylistUpdater.py token') + print('token - Authentication token') + quit() +# Authorization +elif len(sys.argv) == 2: + client = Client(sys.argv[1]).init() + +# Current daily playlist +PersonalPlaylistBlocks = client.landing(blocks=['personalplaylists']).blocks[0] +DailyPlaylist = next( + x.data.data for x in PersonalPlaylistBlocks.entities if x.data.data.generated_playlist_type == 'playlistOfTheDay' +) + +# Check if we don't need to update it +if DailyPlaylist.play_counter.updated: + modifiedDate = datetime.datetime.strptime(DailyPlaylist.modified, "%Y-%m-%dT%H:%M:%S%z").date() + if datetime.datetime.now().date() == modifiedDate: + print('\x1b[6;30;43m' + 'Looks like it has been already updated today' + '\x1b[0m') + quit() + +# Updated playlist +updatedPlaylist = client.users_playlists(user_id=DailyPlaylist.uid, kind=DailyPlaylist.kind)[0] + +if updatedPlaylist.play_counter.updated and not DailyPlaylist.play_counter.updated: + print('\x1b[6;30;42m' + 'Success!' + '\x1b[0m') +else: + print('\x1b[6;30;41m' + 'Something has gone wrong and nothing updated' + '\x1b[0m') + + # Debug information + print('Before:\n modified: %s\n PlayCounter: %s' % (DailyPlaylist.modified, DailyPlaylist.play_counter)) + print('After:\n modified: %s\n PlayCounter: %s' % (updatedPlaylist.modified, updatedPlaylist.play_counter)) +``` diff --git a/docs/source/examples.get_album_with_tracks.md b/docs/source/examples.get_album_with_tracks.md new file mode 100644 index 0000000..1aed554 --- /dev/null +++ b/docs/source/examples.get_album_with_tracks.md @@ -0,0 +1,44 @@ +# Получение альбома с треками + +Пример получения информации об альбоме. Пример отображения треков вместе с исполнителями и названием. + +```python +import os + +from yandex_music import Client + +# без авторизации недоступен список треков альбома +TOKEN = os.environ.get('TOKEN') +ALBUM_ID = 2832563 + +client = Client(TOKEN).init() + +album = client.albums_with_tracks(ALBUM_ID) +tracks = [] +for i, volume in enumerate(album.volumes): + if len(album.volumes) > 1: + tracks.append(f'💿 Диск {i + 1}') + tracks += volume + +text = 'АЛЬБОМ\n\n' +text += f'{album.title}\n' +text += f"Исполнитель: {', '.join([artist.name for artist in album.artists])}\n" +text += f'{album.year} · {album.genre}\n' + +cover = album.cover_uri +if cover: + text += f'Обложка: {cover.replace("%%", "400x400")}\n\n' + +text += 'Список треков:' + +print(text) + +for track in tracks: + if isinstance(track, str): + print(track) + else: + artists = '' + if track.artists: + artists = ' - ' + ', '.join(artist.name for artist in track.artists) + print(track.title + artists) +``` diff --git a/docs/source/examples.like_and_dislike.md b/docs/source/examples.like_and_dislike.md new file mode 100644 index 0000000..11d22e0 --- /dev/null +++ b/docs/source/examples.like_and_dislike.md @@ -0,0 +1,32 @@ +# Лайки и дизлайки сущностей + +Пример установки отметок "Мне нравится" и "Мне не нравится" на альбомы, треки, плейлисты и исполнителей. + +```python +import os + +from yandex_music import Client + + +TOKEN = os.environ.get('TOKEN') +ALBUM_ID = 2832563 + +client = Client(TOKEN).init() + +success = client.users_likes_albums_add(ALBUM_ID) +answer = 'Лайкнут' if success else 'Произошла ошибка' + +print(answer) + +success = client.users_likes_albums_remove(ALBUM_ID) +answer = 'Дизлайкнут' if success else 'Произошла ошибка' + +print(answer) + +# Тоже самое и в другими сущностями (плейлист, трек, исполнитель) +# client.users_likes_playlists_add(f'{user_id}:{playlist_id}') +# client.users_likes_playlists_remove(f'{user_id}:{playlist_id}') +# client.users_likes_tracks_add(track_id) +# client.users_likes_tracks_remove(track_id) +# и т.д. Читайте документацию. +``` diff --git a/docs/source/examples.lyrics_playing_track.md b/docs/source/examples.lyrics_playing_track.md new file mode 100644 index 0000000..1780151 --- /dev/null +++ b/docs/source/examples.lyrics_playing_track.md @@ -0,0 +1,34 @@ +# Текст текущего играющего трека + +Пример работы с очередями и получением текста. Выводит текущий проигрываемый трек и его текст. + +```python +import os + +from yandex_music import Client +from yandex_music.exceptions import NotFoundError + + +TOKEN = os.environ.get('TOKEN') + +client = Client(TOKEN).init() + +queues = client.queues_list() +# Последняя проигрываемая очередь всегда в начале списка +last_queue = client.queue(queues[0].id) + +last_track_id = last_queue.get_current_track() +last_track = last_track_id.fetch_track() + +artists = ', '.join(last_track.artists_name()) +title = last_track.title +print(f'Сейчас играет: {artists} - {title}') + +try: + lyrics = last_track.get_lyrics('LRC') + print(lyrics.fetch_lyrics()) + + print(f'\nИсточник: {lyrics.major.pretty_name}') +except NotFoundError: + print('Текст песни отсутствует') +``` diff --git a/docs/source/examples.md b/docs/source/examples.md new file mode 100644 index 0000000..bcf70c0 --- /dev/null +++ b/docs/source/examples.md @@ -0,0 +1,25 @@ +# Примеры + +В этом разделе есть небольшие примеры, чтобы показать, как выглядят скрипты, +написанные с помощью `yandex-music-api`. + +Перед просмотром примеров обязательно прочитайте секцию "[Начало работы](https://github.com/MarshalX/yandex-music-api#%D0%B8%D0%B7%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5-%D0%BF%D0%BE-%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D1%80%D0%B0%D0%BC)" +в основном README файле. Там есть сниппеты, которые помогут разобраться. + +Все примеры лицензированы в соответствии с +[Лицензией CC0](https://github.com/MarshalX/yandex-music-api/blob/master/examples/LICENSE.txt) +и поэтому полностью предназначены для общественного достояния. +Вы можете использовать их в качестве базы для своих собственных скриптов, +не беспокоясь об авторских правах. + +```{toctree} +examples.chart.md +examples.daily_playlist_updater.md +examples.get_album_with_tracks.md +examples.like_and_dislike.md +examples.lyrics_playing_track.md +examples.proxy.md +examples.search.md +``` + +Больше примеров доступно в папке [examples](https://github.com/MarshalX/yandex-music-api/tree/main/examples)! diff --git a/docs/source/examples.proxy.md b/docs/source/examples.proxy.md new file mode 100644 index 0000000..b6448b5 --- /dev/null +++ b/docs/source/examples.proxy.md @@ -0,0 +1,32 @@ +# Использование прокси + +Пример использования прокси, когда у пользователя нет подписки +(так как Яндекс.Музыка недоступна за пределами СНГ. Актуально для расположения +скрипта на зарубежном сервере). При проблемах с авторизацией или токеном +использование клиента без авторизации. + +```python +import os + +from yandex_music import Client +from yandex_music.exceptions import YandexMusicError +from yandex_music.utils.request import Request + +yandex_music_token = os.environ.get('YANDEX_MUSIC_TOKEN') +proxied_request = Request(proxy_url=os.environ.get('PROXY_URL')) + +try: + if not yandex_music_token: + raise YandexMusicError() + + # подключаемся без прокси для получения информации об аккаунте (доступно из других стран) + client = Client(yandex_music_token, request=Request()).init() + # проверяем отсутствие подписки у пользователя + if client.me and client.me.plus and not client.me.plus.has_plus: + # если подписки нет - пересоздаем клиент с использованием прокси + client = Client(yandex_music_token, request=proxied_request).init() +except YandexMusicError: + # если есть проблемы с авторизацией, токеном или чем-либо еще, то инициализируем клиент без авторизации + # так как сервисом можно пользоваться будучи гостем, но со своими ограничениями + client = Client(request=proxied_request) +``` diff --git a/docs/source/examples.search.md b/docs/source/examples.search.md new file mode 100644 index 0000000..825b632 --- /dev/null +++ b/docs/source/examples.search.md @@ -0,0 +1,70 @@ +# Работа с поиском + +Пример работы с поиском. Осуществление поисковых запросов, обработка лучшего результата и отображение статистики по найденным данным. + +```python +from yandex_music import Client + + +client = Client().init() + +type_to_name = { + 'track': 'трек', + 'artist': 'исполнитель', + 'album': 'альбом', + 'playlist': 'плейлист', + 'video': 'видео', + 'user': 'пользователь', + 'podcast': 'подкаст', + 'podcast_episode': 'эпизод подкаста', +} + + +def send_search_request_and_print_result(query): + search_result = client.search(query) + + text = [f'Результаты по запросу "{query}":', ''] + + best_result_text = '' + if search_result.best: + type_ = search_result.best.type + best = search_result.best.result + + text.append(f'❗️Лучший результат: {type_to_name.get(type_)}') + + if type_ in ['track', 'podcast_episode']: + artists = '' + if best.artists: + artists = ' - ' + ', '.join(artist.name for artist in best.artists) + best_result_text = best.title + artists + elif type_ == 'artist': + best_result_text = best.name + elif type_ in ['album', 'podcast']: + best_result_text = best.title + elif type_ == 'playlist': + best_result_text = best.title + elif type_ == 'video': + best_result_text = f'{best.title} {best.text}' + + text.append(f'Содержимое лучшего результата: {best_result_text}\n') + + if search_result.artists: + text.append(f'Исполнителей: {search_result.artists.total}') + if search_result.albums: + text.append(f'Альбомов: {search_result.albums.total}') + if search_result.tracks: + text.append(f'Треков: {search_result.tracks.total}') + if search_result.playlists: + text.append(f'Плейлистов: {search_result.playlists.total}') + if search_result.videos: + text.append(f'Видео: {search_result.videos.total}') + + text.append('') + print('\n'.join(text)) + + +if __name__ == '__main__': + while True: + input_query = input('Введите поисковой запрос: ') + send_search_request_and_print_result(input_query) +``` diff --git a/docs/source/index.rst b/docs/source/index.rst index 46e0201..e0e5118 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -16,6 +16,7 @@ token client client_async + examples module changes contributing