From 3be4a1db6b6e144390cb337888daba6c4b52c852 Mon Sep 17 00:00:00 2001 From: Aleksei Kovura <3616242+alex3kov@users.noreply.github.com> Date: Fri, 10 Nov 2017 20:54:59 +0300 Subject: [PATCH] Handling additional exceptions, fixed formatting, minor edits. --- README.md | 24 ++++++++++++++++++++++++ youtube_dl/YoutubeDL.py | 1 + youtube_dl/extractor/common.py | 26 +++++++++++++++++--------- youtube_dl/options.py | 2 +- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index ea321d536..4a476adfa 100644 --- a/README.md +++ b/README.md @@ -362,6 +362,7 @@ Alternatively, refer to the [developer instructions](#developer-instructions) fo out, youtube-dl will ask interactively. -2, --twofactor TWOFACTOR Two-factor authentication code -n, --netrc Use .netrc authentication data + --keyring Retrieve authentication data from keyring. Experimental. --video-password PASSWORD Video password (vimeo, smotri, youku) ## Adobe Pass Options: @@ -481,6 +482,29 @@ On Windows you may also need to setup the `%HOME%` environment variable manually set HOME=%USERPROFILE% ``` +### Authentication with keyring + +This option retrieves credentials for an extractor from keyring (typically gnome-keyring or kwallet) using libsecret. +Check that you have python-gobject and libsecret installed. +After that you can add credentials for an extractor to the keyring like this, where *extractor* is the name of the extractor in lowercase: +``` +secret-tool store --label="Youtube-dl: password" extractor "" app "youtube-dl" +``` +For example: +``` +secret-tool store --label="Youtube-dl: youtube password" extractor "youtube" app "youtube-dl" +``` +Both username and password need to be put into password prompt of the above command in JSON format as follows. There are 2 characters that need to be escaped with a backslash: " (double quote" and \ (backslash). +``` +{"user":"","pass":""} +``` +For example, given that login is john.doe@gmail.com and password is Pass"wor\d : +``` +{"user":"john.doe@gmail.com","pass":"Pass\"wor\\d"} +``` +To activate authentication with keyring you should pass `--keyring` to youtube-dl or place it in the [configuration file](#configuration). + + # OUTPUT TEMPLATE The `-o` option allows users to indicate a template for the output file names. diff --git a/youtube_dl/YoutubeDL.py b/youtube_dl/YoutubeDL.py index 342d6b47c..8a80e9ecb 100755 --- a/youtube_dl/YoutubeDL.py +++ b/youtube_dl/YoutubeDL.py @@ -144,6 +144,7 @@ class YoutubeDL(object): ap_username: Multiple-system operator account username. ap_password: Multiple-system operator account password. usenetrc: Use netrc for authentication instead. + usekeyring: Use keyring for authentication instead. verbose: Print additional info to stdout. quiet: Do not print messages to stdout. no_warnings: Do not print out anything for warnings. diff --git a/youtube_dl/extractor/common.py b/youtube_dl/extractor/common.py index dde09939c..f1a075d6d 100644 --- a/youtube_dl/extractor/common.py +++ b/youtube_dl/extractor/common.py @@ -826,24 +826,32 @@ class InfoExtractor(object): except (IOError, netrc.NetrcParseError) as err: self._downloader.report_warning( 'parsing .netrc: %s' % error_to_compat_str(err)) - + if self._downloader.params.get('usekeyring', False): try: import gi gi.require_version('Secret', '1') from gi.repository import Secret - LIBSECRET_SCHEMA = Secret.Schema.new("io.github.rg3.youtube-dl.Store",Secret.SchemaFlags.DONT_MATCH_NAME,{"extractor": Secret.SchemaAttributeType.STRING,"app": Secret.SchemaAttributeType.STRING}) - secret = Secret.password_lookup_sync(LIBSECRET_SCHEMA, {"extractor": "json", "app": "youtube-dl"}, None) + LIBSECRET_SCHEMA = Secret.Schema.new("io.github.rg3.youtube-dl.Store", + Secret.SchemaFlags.DONT_MATCH_NAME, + { + "extractor": Secret.SchemaAttributeType.STRING, + "app": Secret.SchemaAttributeType.STRING + }) + secret = Secret.password_lookup_sync(LIBSECRET_SCHEMA, {"extractor": netrc_machine, "app": "youtube-dl"}, None) if secret is None: - raise netrc.NetrcParseError('Can\'t find credentials in keyring for "' + netrc_machine + '"') - print(str(secret)) + raise KeyError('Cannot find credentials in keyring for "' + netrc_machine + '"') secret_dict = json.loads(secret) - print('JSON Parsed: ' + str(secret_json)) - print('JSON User: ' + secret_json['u']) - print('JSON Password: ' + secret_json['p']) - except (IOError, netrc.NetrcParseError) as err: + username = secret_dict['user'] + password = secret_dict['pass'] + except KeyError as err: self._downloader.report_warning( 'Libsecret: %s' % error_to_compat_str(err)) + except json.decoder.JSONDecodeError: + self._downloader.report_warning( + 'JSON error, your JSON string in keyring is likely malformed') + except ImportError: + raise ImportError('Cannot import gi module. Check that you have python-gobject installed.') return username, password diff --git a/youtube_dl/options.py b/youtube_dl/options.py index 901687e38..10978d8a5 100644 --- a/youtube_dl/options.py +++ b/youtube_dl/options.py @@ -369,7 +369,7 @@ def parseOpts(overrideArguments=None): authentication.add_option( '--keyring', action='store_true', dest='usekeyring', default=False, - help='Retrieve password from keyring. Experimental.') + help='Retrieve authentication data from keyring. Experimental.') adobe_pass = optparse.OptionGroup(parser, 'Adobe Pass Options') adobe_pass.add_option(