From 58ab35d1cbe1f8f5810a44c28c39a3b35262ba42 Mon Sep 17 00:00:00 2001 From: Aleksei Kovura <3616242+alex3kov@users.noreply.github.com> Date: Sun, 5 Nov 2017 17:59:23 +0300 Subject: [PATCH] First draft of libsecret support. --- youtube_dl/__init__.py | 29 ++++++++++++++++++++++++++++- youtube_dl/options.py | 4 ++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/youtube_dl/__init__.py b/youtube_dl/__init__.py index ba684a075..8f20a7ecc 100644 --- a/youtube_dl/__init__.py +++ b/youtube_dl/__init__.py @@ -11,6 +11,10 @@ import os import random import sys +import gi +gi.require_version('Secret', '1') +from gi.repository import Secret +from .compat import compat_urllib_parse from .options import ( parseOpts, @@ -46,6 +50,14 @@ from .YoutubeDL import YoutubeDL def _real_main(argv=None): + LIBSECRET_SCHEMA = Secret.Schema.new("io.github.rg3.youtube-dl.Store", + Secret.SchemaFlags.DONT_MATCH_NAME, + { + "user-name": Secret.SchemaAttributeType.STRING, + "domain-name": Secret.SchemaAttributeType.STRING + } + ) + # Compatibility fixes for Windows if sys.platform == 'win32': # https://github.com/rg3/youtube-dl/issues/820 @@ -141,7 +153,22 @@ def _real_main(argv=None): parser.error('auto number start must be positive or 0') if opts.usetitle and opts.useid: parser.error('using title conflicts with using video ID') - if opts.username is not None and opts.password is None: + if opts.username is not None and opts.password is None and opts.password_from_keyring is True: + # extract domain names, check if all videos are from the same domain. + all_domains = set(map(lambda url: compat_urllib_parse.urlparse(url).netloc, all_urls)) + if len(all_domains) > 1: + parser.error('You passed URLs from more than one domain - supplying credentials from command line is not supported in this case.') + domain_name = all_domains.pop() + password = Secret.password_lookup_sync(LIBSECRET_SCHEMA, { "user-name": opts.username, "domain-name": domain_name }, None) + if password is None: + print("Password for domain " + domain_name + " and user name " + opts.username + " not found in the keyring.") + supplied_password = compat_getpass('Type account password and press [Return]: ') + attributes = { "user-name": opts.username, "domain-name": domain_name } + label = "Youtube-dl: " + domain_name + " password" + Secret.password_store_sync(LIBSECRET_SCHEMA, attributes, Secret.COLLECTION_DEFAULT, label, supplied_password, None) + password = Secret.password_lookup_sync(LIBSECRET_SCHEMA, { "user-name": opts.username, "domain-name": domain_name }, None) + opts.password = password + if opts.username is not None and opts.password is None and opts.password_from_keyring is False: opts.password = compat_getpass('Type account password and press [Return]: ') if opts.ap_username is not None and opts.ap_password is None: opts.ap_password = compat_getpass('Type TV provider account password and press [Return]: ') diff --git a/youtube_dl/options.py b/youtube_dl/options.py index 4c0455044..eb15ae3bd 100644 --- a/youtube_dl/options.py +++ b/youtube_dl/options.py @@ -366,6 +366,10 @@ def parseOpts(overrideArguments=None): '--video-password', dest='videopassword', metavar='PASSWORD', help='Video password (vimeo, smotri, youku)') + authentication.add_option( + '--password-from-keyring', + action='store_true', dest='password_from_keyring', default=False, + help='Retrieve/store password from keyring. Experimental.') adobe_pass = optparse.OptionGroup(parser, 'Adobe Pass Options') adobe_pass.add_option(