save login
This commit is contained in:
parent
66e98dc98d
commit
b11ecfa61a
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
### Changes
|
### Changes
|
||||||
|
|
||||||
|
- Username and password login has been replaced with username and token
|
||||||
- Genre metadata available for all tracks
|
- Genre metadata available for all tracks
|
||||||
- Boolean command line options are now set like `--save-metadata` or `--no-save-metadata` for True or False
|
- Boolean command line options are now set like `--save-metadata` or `--no-save-metadata` for True or False
|
||||||
- Setting `--config` (formerly `--config-location`) can be set to "None" to not use any config file
|
- Setting `--config` (formerly `--config-location`) can be set to "None" to not use any config file
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[metadata]
|
[metadata]
|
||||||
name = zotify
|
name = zotify
|
||||||
version = 0.9.6
|
version = 0.9.7
|
||||||
author = Zotify Contributors
|
author = Zotify Contributors
|
||||||
description = A highly customizable music and podcast downloader
|
description = A highly customizable music and podcast downloader
|
||||||
long_description = file: README.md
|
long_description = file: README.md
|
||||||
|
|
|
@ -70,8 +70,8 @@ class Session(LibrespotSession):
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
session_builder: LibrespotSession.Builder,
|
session_builder: LibrespotSession.Builder,
|
||||||
oauth: OAuth,
|
|
||||||
language: str = "en",
|
language: str = "en",
|
||||||
|
oauth: OAuth | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""
|
"""
|
||||||
Authenticates user, saves credentials to a file and generates api token.
|
Authenticates user, saves credentials to a file and generates api token.
|
||||||
|
@ -96,7 +96,7 @@ class Session(LibrespotSession):
|
||||||
self.authenticate(session_builder.login_credentials)
|
self.authenticate(session_builder.login_credentials)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_file(auth: OAuth, cred_file: Path | str, language: str = "en") -> Session:
|
def from_file(cred_file: Path | str, language: str = "en") -> Session:
|
||||||
"""
|
"""
|
||||||
Creates session using saved credentials file
|
Creates session using saved credentials file
|
||||||
Args:
|
Args:
|
||||||
|
@ -107,17 +107,17 @@ class Session(LibrespotSession):
|
||||||
"""
|
"""
|
||||||
if not isinstance(cred_file, Path):
|
if not isinstance(cred_file, Path):
|
||||||
cred_file = Path(cred_file).expanduser()
|
cred_file = Path(cred_file).expanduser()
|
||||||
conf = (
|
config = (
|
||||||
LibrespotSession.Configuration.Builder()
|
LibrespotSession.Configuration.Builder()
|
||||||
.set_store_credentials(False)
|
.set_store_credentials(False)
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
session = LibrespotSession.Builder(conf).stored_file(str(cred_file))
|
session = LibrespotSession.Builder(config).stored_file(str(cred_file))
|
||||||
return Session(session, auth, language) # TODO
|
return Session(session, language)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_oauth(
|
def from_oauth(
|
||||||
auth: OAuth,
|
oauth: OAuth,
|
||||||
save_file: Path | str | None = None,
|
save_file: Path | str | None = None,
|
||||||
language: str = "en",
|
language: str = "en",
|
||||||
) -> Session:
|
) -> Session:
|
||||||
|
@ -129,24 +129,24 @@ class Session(LibrespotSession):
|
||||||
Returns:
|
Returns:
|
||||||
Zotify session
|
Zotify session
|
||||||
"""
|
"""
|
||||||
builder = LibrespotSession.Configuration.Builder()
|
config = LibrespotSession.Configuration.Builder()
|
||||||
if save_file:
|
if save_file:
|
||||||
if not isinstance(save_file, Path):
|
if not isinstance(save_file, Path):
|
||||||
save_file = Path(save_file).expanduser()
|
save_file = Path(save_file).expanduser()
|
||||||
save_file.parent.mkdir(parents=True, exist_ok=True)
|
save_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
builder.set_stored_credential_file(str(save_file))
|
config.set_stored_credential_file(str(save_file))
|
||||||
else:
|
else:
|
||||||
builder.set_store_credentials(False)
|
config.set_store_credentials(False)
|
||||||
|
|
||||||
token = auth.await_token()
|
token = oauth.await_token()
|
||||||
|
|
||||||
session = LibrespotSession.Builder(builder.build())
|
builder = LibrespotSession.Builder(config.build())
|
||||||
session.login_credentials = Authentication.LoginCredentials(
|
builder.login_credentials = Authentication.LoginCredentials(
|
||||||
username=auth.username,
|
username=oauth.username,
|
||||||
typ=Authentication.AuthenticationType.values()[3],
|
typ=Authentication.AuthenticationType.values()[3],
|
||||||
auth_data=token.access_token.encode(),
|
auth_data=token.access_token.encode(),
|
||||||
)
|
)
|
||||||
return Session(session, auth, language)
|
return Session(builder, language, oauth)
|
||||||
|
|
||||||
def __get_playable(
|
def __get_playable(
|
||||||
self, playable_id: PlayableId, quality: Quality
|
self, playable_id: PlayableId, quality: Quality
|
||||||
|
@ -186,7 +186,7 @@ class Session(LibrespotSession):
|
||||||
self.api(),
|
self.api(),
|
||||||
)
|
)
|
||||||
|
|
||||||
def oauth(self) -> OAuth:
|
def oauth(self) -> OAuth | None:
|
||||||
"""Returns OAuth service"""
|
"""Returns OAuth service"""
|
||||||
return self.__oauth
|
return self.__oauth
|
||||||
|
|
||||||
|
@ -282,7 +282,10 @@ class TokenProvider(LibrespotTokenProvider):
|
||||||
self._session = session
|
self._session = session
|
||||||
|
|
||||||
def get_token(self, *scopes) -> TokenProvider.StoredToken:
|
def get_token(self, *scopes) -> TokenProvider.StoredToken:
|
||||||
return self._session.oauth().get_token()
|
oauth = self._session.oauth()
|
||||||
|
if oauth is None:
|
||||||
|
return super().get_token(*scopes)
|
||||||
|
return oauth.get_token()
|
||||||
|
|
||||||
class StoredToken(LibrespotTokenProvider.StoredToken):
|
class StoredToken(LibrespotTokenProvider.StoredToken):
|
||||||
def __init__(self, obj):
|
def __init__(self, obj):
|
||||||
|
@ -301,15 +304,15 @@ class OAuth:
|
||||||
|
|
||||||
def __init__(self, username: str):
|
def __init__(self, username: str):
|
||||||
self.username = username
|
self.username = username
|
||||||
self.__server_thread = Thread(target=self.__run_server)
|
|
||||||
self.__server_thread.start()
|
|
||||||
|
|
||||||
def get_authorization_url(self) -> str:
|
def auth_interactive(self) -> str:
|
||||||
"""
|
"""
|
||||||
Generate OAuth URL
|
Starts local server for token callback
|
||||||
Returns:
|
Returns:
|
||||||
OAuth URL
|
OAuth URL
|
||||||
"""
|
"""
|
||||||
|
self.__server_thread = Thread(target=self.__run_server)
|
||||||
|
self.__server_thread.start()
|
||||||
self.__code_verifier = generate_code_verifier()
|
self.__code_verifier = generate_code_verifier()
|
||||||
code_challenge = get_code_challenge(self.__code_verifier)
|
code_challenge = get_code_challenge(self.__code_verifier)
|
||||||
params = {
|
params = {
|
||||||
|
|
|
@ -7,7 +7,7 @@ from zotify.app import App
|
||||||
from zotify.config import CONFIG_PATHS, CONFIG_VALUES
|
from zotify.config import CONFIG_PATHS, CONFIG_VALUES
|
||||||
from zotify.utils import OptionalOrFalse
|
from zotify.utils import OptionalOrFalse
|
||||||
|
|
||||||
VERSION = "0.9.6"
|
VERSION = "0.9.7"
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -51,7 +51,7 @@ def main():
|
||||||
help="Searches for only this type",
|
help="Searches for only this type",
|
||||||
)
|
)
|
||||||
parser.add_argument("--username", type=str, default="", help="Account username")
|
parser.add_argument("--username", type=str, default="", help="Account username")
|
||||||
parser.add_argument("--password", type=str, default="", help="Account password")
|
parser.add_argument("--token", type=str, default="", help="Account token")
|
||||||
group = parser.add_mutually_exclusive_group(required=True)
|
group = parser.add_mutually_exclusive_group(required=True)
|
||||||
group.add_argument(
|
group.add_argument(
|
||||||
"urls",
|
"urls",
|
||||||
|
@ -127,8 +127,7 @@ def main():
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
if args.version:
|
if args.version:
|
||||||
print(VERSION)
|
print(VERSION)
|
||||||
return
|
elif args.debug:
|
||||||
if args.debug:
|
|
||||||
args.func(args)
|
args.func(args)
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -149,28 +149,27 @@ class App:
|
||||||
Logger(self.__config)
|
Logger(self.__config)
|
||||||
|
|
||||||
# Create session
|
# Create session
|
||||||
# if args.username != "" and args.password != "":
|
if args.username != "" and args.token != "":
|
||||||
# self.__session = Session.from_userpass(
|
oauth = OAuth(args.username)
|
||||||
# args.username,
|
oauth.set_token(args.token, OAuth.RequestType.REFRESH)
|
||||||
# args.password,
|
self.__session = Session.from_oauth(
|
||||||
# self.__config.credentials_path,
|
oauth, self.__config.credentials_path, self.__config.language
|
||||||
# self.__config.language,
|
)
|
||||||
# )
|
elif self.__config.credentials_path.is_file():
|
||||||
# elif self.__config.credentials_path.is_file():
|
self.__session = Session.from_file(
|
||||||
# self.__session = Session.from_file(
|
self.__config.credentials_path,
|
||||||
# self.__config.credentials_path, self.__config.language
|
self.__config.language,
|
||||||
# )
|
)
|
||||||
# else:
|
else:
|
||||||
# self.__session = Session.from_prompt(
|
username = args.username
|
||||||
# self.__config.credentials_path, self.__config.language
|
while username == "":
|
||||||
# )
|
username = input("Username: ")
|
||||||
username = input("Username: ")
|
oauth = OAuth(username)
|
||||||
auth = OAuth(username)
|
auth_url = oauth.auth_interactive()
|
||||||
auth_url = auth.get_authorization_url()
|
print(f"\nClick on the following link to login:\n{auth_url}")
|
||||||
print(f"\nClick on the following link to login:\n{auth_url}")
|
self.__session = Session.from_oauth(
|
||||||
self.__session = Session.from_oauth(
|
oauth, self.__config.credentials_path, self.__config.language
|
||||||
auth, self.__config.credentials_path, self.__config.language
|
)
|
||||||
)
|
|
||||||
|
|
||||||
# Get items to download
|
# Get items to download
|
||||||
ids = self.get_selection(args)
|
ids = self.get_selection(args)
|
||||||
|
|
Loading…
Reference in New Issue