From d76fa1f3d4f559e82a4c54e6f8feb0727ffc4b58 Mon Sep 17 00:00:00 2001 From: pukkandan Date: Tue, 10 May 2022 11:44:45 +0530 Subject: [PATCH] [cookies] Allow `cookiefile` to be a text stream Closes #3674 --- yt_dlp/YoutubeDL.py | 2 +- yt_dlp/cookies.py | 7 +++++-- yt_dlp/utils.py | 24 ++++++++++++++++++++++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index f9670429a..38ecd276f 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -312,7 +312,7 @@ class YoutubeDL: has been filtered out. break_per_url: Whether break_on_reject and break_on_existing should act on each input URL as opposed to for the entire queue - cookiefile: File name where cookies should be read from and dumped to + cookiefile: File name or text stream from where cookies should be read and dumped to cookiesfrombrowser: A tuple containing the name of the browser, the profile name/pathfrom where cookies are loaded, and the name of the keyring. Eg: ('chrome', ) or ('vivaldi', 'default', 'BASICTEXT') diff --git a/yt_dlp/cookies.py b/yt_dlp/cookies.py index b06edfc5d..c6edaebe4 100644 --- a/yt_dlp/cookies.py +++ b/yt_dlp/cookies.py @@ -83,9 +83,12 @@ def load_cookies(cookie_file, browser_specification, ydl): cookie_jars.append(extract_cookies_from_browser(browser_name, profile, YDLLogger(ydl), keyring=keyring)) if cookie_file is not None: - cookie_file = expand_path(cookie_file) + is_filename = YoutubeDLCookieJar.is_path(cookie_file) + if is_filename: + cookie_file = expand_path(cookie_file) + jar = YoutubeDLCookieJar(cookie_file) - if os.access(cookie_file, os.R_OK): + if not is_filename or os.access(cookie_file, os.R_OK): jar.load(ignore_discard=True, ignore_expires=True) cookie_jars.append(jar) diff --git a/yt_dlp/utils.py b/yt_dlp/utils.py index c9589537f..e683eaaf1 100644 --- a/yt_dlp/utils.py +++ b/yt_dlp/utils.py @@ -1439,6 +1439,26 @@ class YoutubeDLCookieJar(compat_cookiejar.MozillaCookieJar): 'CookieFileEntry', ('domain_name', 'include_subdomains', 'path', 'https_only', 'expires_at', 'name', 'value')) + def __init__(self, filename=None, *args, **kwargs): + super().__init__(None, *args, **kwargs) + if self.is_path(filename): + filename = os.fspath(filename) + self.filename = filename + + @staticmethod + def is_path(file): + return isinstance(file, (str, bytes, os.PathLike)) + + @contextlib.contextmanager + def open(self, file, *, write=False): + if self.is_path(file): + with open(file, 'w' if write else 'r', encoding='utf-8') as f: + yield f + else: + if write: + file.truncate(0) + yield file + def save(self, filename=None, ignore_discard=False, ignore_expires=False): """ Save cookies to a file. @@ -1458,7 +1478,7 @@ class YoutubeDLCookieJar(compat_cookiejar.MozillaCookieJar): if cookie.expires is None: cookie.expires = 0 - with open(filename, 'w', encoding='utf-8') as f: + with self.open(filename, write=True) as f: f.write(self._HEADER) now = time.time() for cookie in self: @@ -1514,7 +1534,7 @@ class YoutubeDLCookieJar(compat_cookiejar.MozillaCookieJar): return line cf = io.StringIO() - with open(filename, encoding='utf-8') as f: + with self.open(filename) as f: for line in f: try: cf.write(prepare_line(line))