From 641d1b993a6410576f079d3f4c0d2ef5627cc3e8 Mon Sep 17 00:00:00 2001 From: Gleb Liutsko Date: Sat, 23 Nov 2019 00:51:47 +0400 Subject: [PATCH 1/6] =?UTF-8?q?callback-=D1=84=D1=83=D0=BD=D0=BA=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20=D0=BA=D0=B0=D0=BF=D1=87=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yandex_music/client.py | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/yandex_music/client.py b/yandex_music/client.py index b5ec481..b5d5f20 100644 --- a/yandex_music/client.py +++ b/yandex_music/client.py @@ -8,7 +8,7 @@ from yandex_music import YandexMusicObject, Status, Settings, PermissionAlerts, ArtistAlbums from yandex_music.utils.request import Request from yandex_music.utils.difference import Difference -from yandex_music.exceptions import InvalidToken +from yandex_music.exceptions import InvalidToken, Captcha CLIENT_ID = '23cabbbdc6cd418abb4b39c32c41195d' CLIENT_SECRET = '53bc75238f0c4d08a118e51fe9203300' @@ -86,7 +86,8 @@ class Client(YandexMusicObject): self.account = self.account_status().account @classmethod - def from_credentials(cls, username, password, x_captcha_answer=None, x_captcha_key=None, *args, **kwargs): + def from_credentials(cls, username, password, x_captcha_answer=None, x_captcha_key=None, captch_callback=None, + *args, **kwargs): """Инициализция клиента по логину и паролю. Данный метод получает токен каждый раз при вызове. Рекомендуется сгенерировать его самостоятельно, сохранить и @@ -97,14 +98,28 @@ class Client(YandexMusicObject): password (:obj:`str`): Пароль клиента (аутентификатор). x_captcha_answer (:obj:`str`, optional): Ответ на капчу (цифры с картинки). x_captcha_key (:obj:`str`, optional): Уникальный ключ капчи. + captch_callback (:obj:`function`, optional): Функция обратного вызова для обработки капчи, должна + принимать объект класса :class:`yandex_music.exceptions.Captcha` и возвращать строку с кодом. **kwargs (:obj:`dict`, optional): Аргументы для конструктора клиента. Returns: :obj:`yandex_music.Client`. """ - return cls(cls().generate_token_by_username_and_password(username, password, x_captcha_answer=x_captcha_answer, - x_captcha_key=x_captcha_key), *args, **kwargs) + token = x_captcha_key = x_captcha_answer = None + if captch_callback: + while not token: + try: + token = cls().generate_token_by_username_and_password(username, password, x_captcha_answer=x_captcha_answer, + x_captcha_key=x_captcha_key, captch_callback=captch_callback) + except Captcha as e: + x_captcha_answer = captch_callback(e.captcha) + x_captcha_key = e.captcha.x_captcha_key + else: + token = cls().generate_token_by_username_and_password(username, password, x_captcha_answer=x_captcha_answer, + x_captcha_key=x_captcha_key, captch_callback=captch_callback) + + return cls(token, *args, **kwargs) @classmethod def from_token(cls, token, *args, **kwargs): From c19915ad8fa07e7b96391294bd4b58bab1d6928b Mon Sep 17 00:00:00 2001 From: Gleb Liutsko Date: Sat, 23 Nov 2019 01:03:00 +0400 Subject: [PATCH 2/6] =?UTF-8?q?=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B1=D0=B5=D0=BB=D0=B0=20=D0=B2=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=86=D0=B5=20=D1=81=D1=82=D1=80=D0=BE=D0=BA?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yandex_music/client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yandex_music/client.py b/yandex_music/client.py index b5d5f20..fa00c79 100644 --- a/yandex_music/client.py +++ b/yandex_music/client.py @@ -99,7 +99,7 @@ class Client(YandexMusicObject): x_captcha_answer (:obj:`str`, optional): Ответ на капчу (цифры с картинки). x_captcha_key (:obj:`str`, optional): Уникальный ключ капчи. captch_callback (:obj:`function`, optional): Функция обратного вызова для обработки капчи, должна - принимать объект класса :class:`yandex_music.exceptions.Captcha` и возвращать строку с кодом. + принимать объект класса :class:`yandex_music.exceptions.Captcha` и возвращать строку с кодом. **kwargs (:obj:`dict`, optional): Аргументы для конструктора клиента. Returns: From 0e5ac0a18181bc69c4e21e7af4c0783f331d0ecb Mon Sep 17 00:00:00 2001 From: Gleb Liutsko Date: Sat, 23 Nov 2019 14:56:48 +0400 Subject: [PATCH 3/6] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B2=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B5?= =?UTF-8?q?=20=D0=BA=D0=B0=D0=BF=D1=87=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yandex_music/client.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/yandex_music/client.py b/yandex_music/client.py index fa00c79..1397bab 100644 --- a/yandex_music/client.py +++ b/yandex_music/client.py @@ -86,7 +86,7 @@ class Client(YandexMusicObject): self.account = self.account_status().account @classmethod - def from_credentials(cls, username, password, x_captcha_answer=None, x_captcha_key=None, captch_callback=None, + def from_credentials(cls, username, password, x_captcha_answer=None, x_captcha_key=None, captcha_callback=None, *args, **kwargs): """Инициализция клиента по логину и паролю. @@ -98,7 +98,7 @@ class Client(YandexMusicObject): password (:obj:`str`): Пароль клиента (аутентификатор). x_captcha_answer (:obj:`str`, optional): Ответ на капчу (цифры с картинки). x_captcha_key (:obj:`str`, optional): Уникальный ключ капчи. - captch_callback (:obj:`function`, optional): Функция обратного вызова для обработки капчи, должна + captcha_callback (:obj:`function`, optional): Функция обратного вызова для обработки капчи, должна принимать объект класса :class:`yandex_music.exceptions.Captcha` и возвращать строку с кодом. **kwargs (:obj:`dict`, optional): Аргументы для конструктора клиента. @@ -106,18 +106,18 @@ class Client(YandexMusicObject): :obj:`yandex_music.Client`. """ - token = x_captcha_key = x_captcha_answer = None - if captch_callback: + token = None + if captcha_callback: while not token: try: token = cls().generate_token_by_username_and_password(username, password, x_captcha_answer=x_captcha_answer, - x_captcha_key=x_captcha_key, captch_callback=captch_callback) + x_captcha_key=x_captcha_key) except Captcha as e: - x_captcha_answer = captch_callback(e.captcha) + x_captcha_answer = captcha_callback(e.captcha) x_captcha_key = e.captcha.x_captcha_key else: token = cls().generate_token_by_username_and_password(username, password, x_captcha_answer=x_captcha_answer, - x_captcha_key=x_captcha_key, captch_callback=captch_callback) + x_captcha_key=x_captcha_key) return cls(token, *args, **kwargs) From a28fd555fceb08f86560bb2fe58cc1509ed952c4 Mon Sep 17 00:00:00 2001 From: Gleb Liutsko Date: Sat, 23 Nov 2019 15:22:38 +0400 Subject: [PATCH 4/6] =?UTF-8?q?=D0=A0=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D0=BD=D0=B3=20callback=20=D0=BE=D0=B1=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20=D0=BA=D0=B0=D0=BF=D1=87=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yandex_music/client.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/yandex_music/client.py b/yandex_music/client.py index 1397bab..0e67559 100644 --- a/yandex_music/client.py +++ b/yandex_music/client.py @@ -107,17 +107,16 @@ class Client(YandexMusicObject): """ token = None - if captcha_callback: - while not token: - try: - token = cls().generate_token_by_username_and_password(username, password, x_captcha_answer=x_captcha_answer, - x_captcha_key=x_captcha_key) - except Captcha as e: + while not token: + try: + token = cls().generate_token_by_username_and_password(username, password, x_captcha_answer=x_captcha_answer, + x_captcha_key=x_captcha_key) + except Captcha as e: + if captcha_callback: x_captcha_answer = captcha_callback(e.captcha) x_captcha_key = e.captcha.x_captcha_key - else: - token = cls().generate_token_by_username_and_password(username, password, x_captcha_answer=x_captcha_answer, - x_captcha_key=x_captcha_key) + else: + raise e return cls(token, *args, **kwargs) From 05cdb3f152e6c1b5ef852021f27a04a00d63f194 Mon Sep 17 00:00:00 2001 From: Gleb Liutsko Date: Sat, 23 Nov 2019 15:42:08 +0400 Subject: [PATCH 5/6] =?UTF-8?q?=D0=9F=D1=80=D0=B8=D0=BC=D0=B5=D1=80=20?= =?UTF-8?q?=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20=D0=BA?= =?UTF-8?q?=D0=B0=D0=BF=D1=87=D0=B8=20=D0=B2=20README?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/README.rst b/README.rst index 84a770c..adbf96d 100644 --- a/README.rst +++ b/README.rst @@ -212,6 +212,16 @@ music.yandex.ru/album/**1193829**/track/**10994777** return client +Пример инициализации клиента с обработкой капчи при помощи callback-функции: + +.. code:: python + + def proc_captcha(captcha): + captcha.download('captcha.png') + return input('Число с картинки: ') + + client = Client.from_credentials('login', 'pass', captcha_callback=proc_captcha) + -------------------- Изучение по примерам -------------------- From d0453446ca29b014cc0957554b050165eb5d30bc Mon Sep 17 00:00:00 2001 From: Il`ya Date: Sun, 24 Nov 2019 01:15:23 +0300 Subject: [PATCH 6/6] =?UTF-8?q?=D0=9C=D0=B5=D0=BB=D0=BA=D0=B8=D0=B9=20?= =?UTF-8?q?=D1=80=D0=B5=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=BD?= =?UTF-8?q?=D0=B3=20=D0=B8=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yandex_music/client.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/yandex_music/client.py b/yandex_music/client.py index 0e67559..82b0f51 100644 --- a/yandex_music/client.py +++ b/yandex_music/client.py @@ -90,8 +90,9 @@ class Client(YandexMusicObject): *args, **kwargs): """Инициализция клиента по логину и паролю. - Данный метод получает токен каждый раз при вызове. Рекомендуется сгенерировать его самостоятельно, сохранить и - использовать при следующих инициализациях клиента. Не храните логины и пароли! + Note: + Данный метод получает токен каждый раз при вызове. Рекомендуется сгенерировать его самостоятельно, сохранить + и использовать при следующих инициализациях клиента. Не храните логины и пароли! Args: username (:obj:`str`): Логин клиента (идентификатор). @@ -99,25 +100,29 @@ class Client(YandexMusicObject): x_captcha_answer (:obj:`str`, optional): Ответ на капчу (цифры с картинки). x_captcha_key (:obj:`str`, optional): Уникальный ключ капчи. captcha_callback (:obj:`function`, optional): Функция обратного вызова для обработки капчи, должна - принимать объект класса :class:`yandex_music.exceptions.Captcha` и возвращать строку с кодом. + принимать объект класса :class:`yandex_music.exceptions.Captcha` и возвращать проверочный код. **kwargs (:obj:`dict`, optional): Аргументы для конструктора клиента. Returns: :obj:`yandex_music.Client`. + + Raises: + :class:`yandex_music.YandexMusicError` """ token = None while not token: try: - token = cls().generate_token_by_username_and_password(username, password, x_captcha_answer=x_captcha_answer, + token = cls().generate_token_by_username_and_password(username, password, + x_captcha_answer=x_captcha_answer, x_captcha_key=x_captcha_key) except Captcha as e: - if captcha_callback: - x_captcha_answer = captcha_callback(e.captcha) - x_captcha_key = e.captcha.x_captcha_key - else: + if not captcha_callback: raise e + x_captcha_answer = captcha_callback(e.captcha) + x_captcha_key = e.captcha.x_captcha_key + return cls(token, *args, **kwargs) @classmethod