1
0
mirror of https://github.com/mikf/gallery-dl.git synced 2024-11-25 04:02:32 +01:00

replace calls to print() with stdout_write() (#2529)

This commit is contained in:
Mike Fährmann 2022-05-19 13:24:37 +02:00
parent cf16f9a407
commit 688d6553b4
No known key found for this signature in database
GPG Key ID: 5680CA389D365A88
5 changed files with 68 additions and 43 deletions

View File

@ -12,7 +12,7 @@ import logging
from . import version, config, option, output, extractor, job, util, exception
__author__ = "Mike Fährmann"
__copyright__ = "Copyright 2014-2021 Mike Fährmann"
__copyright__ = "Copyright 2014-2022 Mike Fährmann"
__license__ = "GPLv2"
__maintainer__ = "Mike Fährmann"
__email__ = "mike_faehrmann@web.de"
@ -22,10 +22,13 @@ __version__ = version.__version__
def progress(urls, pformat):
"""Wrapper around urls to output a simple progress indicator"""
if pformat is True:
pformat = "[{current}/{total}] {url}"
pformat = "[{current}/{total}] {url}\n"
else:
pformat += "\n"
pinfo = {"total": len(urls)}
for pinfo["current"], pinfo["url"] in enumerate(urls, 1):
print(pformat.format_map(pinfo), file=sys.stderr)
output.stderr_write(pformat.format_map(pinfo))
yield pinfo["url"]
@ -196,20 +199,23 @@ def main():
pass
if args.list_modules:
for module_name in extractor.modules:
print(module_name)
extractor.modules.append("")
sys.stdout.write("\n".join(extractor.modules))
elif args.list_extractors:
write = sys.stdout.write
fmt = "{}\n{}\nCategory: {} - Subcategory: {}{}\n\n".format
for extr in extractor.extractors():
if not extr.__doc__:
continue
print(extr.__name__)
print(extr.__doc__)
print("Category:", extr.category,
"- Subcategory:", extr.subcategory)
test = next(extr._get_tests(), None)
if test:
print("Example :", test[0])
print()
write(fmt(
extr.__name__, extr.__doc__,
extr.category, extr.subcategory,
"\nExample : " + test[0] if test else "",
))
elif args.clear_cache:
from . import cache
log = logging.getLogger("cache")

View File

@ -11,6 +11,7 @@
from .common import Extractor, Message
from . import deviantart, flickr, mastodon, pixiv, reddit, smugmug, tumblr
from .. import text, oauth, util, config, exception
from ..output import stdout_write
from ..cache import cache
import urllib.parse
import hashlib
@ -37,7 +38,7 @@ class OAuthBase(Extractor):
def recv(self):
"""Open local HTTP server and recv callback parameters"""
import socket
print("Waiting for response. (Cancel with Ctrl+c)")
stdout_write("Waiting for response. (Cancel with Ctrl+c)\n")
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(("localhost", self.config("port", 6414)))
@ -60,7 +61,7 @@ class OAuthBase(Extractor):
def send(self, msg):
"""Send 'msg' to the socket opened in 'recv()'"""
print(msg)
stdout_write(msg)
self.client.send(b"HTTP/1.1 200 OK\r\n\r\n" + msg.encode())
self.client.close()
@ -69,12 +70,13 @@ class OAuthBase(Extractor):
import webbrowser
url += "?" + urllib.parse.urlencode(params)
if not self.config("browser", True) or not webbrowser.open(url):
print("Please open this URL in your browser:")
print(url, end="\n\n", flush=True)
stdout_write(
"Please open this URL in your browser:\n\n" + url + "\n\n")
return (recv or self.recv)()
def error(self, msg):
return self.send("Remote server reported an error:\n\n" + str(msg))
return self.send(
"Remote server reported an error:\n\n{}\n".format(msg))
def _oauth1_authorization_flow(
self, request_token_url, authorize_url, access_token_url):
@ -133,7 +135,7 @@ class OAuthBase(Extractor):
# check authorization response
if state != params.get("state"):
self.send("'state' mismatch: expected {}, got {}.".format(
self.send("'state' mismatch: expected {}, got {}.\n".format(
state, params.get("state")
))
return
@ -188,7 +190,7 @@ class OAuthBase(Extractor):
opt = self.oauth_config(names[0])
if self.cache and (opt is None or opt == "cache"):
msg += _vh + " been cached and will automatically be used."
msg += _vh + " been cached and will automatically be used.\n"
else:
msg += "Put " + _va + " into your configuration file as \n"
msg += " and\n".join(
@ -200,7 +202,7 @@ class OAuthBase(Extractor):
"\nor set\n'extractor.{}.{}' to \"cache\""
.format(self.subcategory, names[0])
)
msg += "\nto use {}.".format(_it)
msg += "\nto use {}.\n".format(_it)
return msg
@ -398,9 +400,9 @@ class OAuthPixiv(OAuthBase):
data = self.session.post(url, headers=headers, data=data).json()
if "error" in data:
print(data)
stdout_write("\n{}\n".format(data))
if data["error"] in ("invalid_request", "invalid_grant"):
print("'code' expired, try again")
stdout_write("'code' expired, try again\n\n")
return
token = data["refresh_token"]
@ -409,10 +411,10 @@ class OAuthPixiv(OAuthBase):
pixiv._refresh_token_cache.update(username, token)
self.log.info("Writing 'refresh-token' to cache")
print(self._generate_message(("refresh-token",), (token,)))
stdout_write(self._generate_message(("refresh-token",), (token,)))
def _input(self):
print("""
stdout_write("""\
1) Open your browser's Developer Tools (F12) and switch to the Network tab
2) Login
3) Select the last network monitor entry ('callback?state=...')
@ -421,6 +423,7 @@ class OAuthPixiv(OAuthBase):
- This 'code' will expire 30 seconds after logging in.
- Copy-pasting more than just the 'code' value will work as well,
like the entire URL or several query parameters.
""")
code = input("code: ")
return code.rpartition("=")[2].strip()

View File

@ -16,6 +16,7 @@ import collections
from . import extractor, downloader, postprocessor
from . import config, text, util, path, formatter, output, exception
from .extractor.message import Message
from .output import stdout_write
class Job():
@ -537,14 +538,14 @@ class KeywordJob(Job):
self.private = config.get(("output",), "private")
def handle_url(self, url, kwdict):
print("\nKeywords for filenames and --filter:")
print("------------------------------------")
stdout_write("\nKeywords for filenames and --filter:\n"
"------------------------------------\n")
self.print_kwdict(kwdict)
raise exception.StopExtraction()
def handle_directory(self, kwdict):
print("Keywords for directory names:")
print("-----------------------------")
stdout_write("Keywords for directory names:\n"
"-----------------------------\n")
self.print_kwdict(kwdict)
def handle_queue(self, url, kwdict):
@ -565,16 +566,17 @@ class KeywordJob(Job):
self.extractor.log.info(
"Try 'gallery-dl -K \"%s\"' instead.", url)
else:
print("Keywords for --chapter-filter:")
print("------------------------------")
stdout_write("Keywords for --chapter-filter:\n"
"------------------------------\n")
self.print_kwdict(kwdict)
if extr or self.extractor.categorytransfer:
print()
stdout_write("\n")
KeywordJob(extr or url, self).run()
raise exception.StopExtraction()
def print_kwdict(self, kwdict, prefix=""):
"""Print key-value pairs in 'kwdict' with formatting"""
write = sys.stdout.write
suffix = "]" if prefix else ""
for key, value in sorted(kwdict.items()):
if key[0] == "_" and not self.private:
@ -588,13 +590,13 @@ class KeywordJob(Job):
if value and isinstance(value[0], dict):
self.print_kwdict(value[0], key + "[][")
else:
print(key, "[]", sep="")
write(key + "[]\n")
for val in value:
print(" -", val)
write(" - " + str(val) + "\n")
else:
# string or number
print(key, "\n ", value, sep="")
write("{}\n {}\n".format(key, value))
class UrlJob(Job):
@ -609,14 +611,14 @@ class UrlJob(Job):
@staticmethod
def handle_url(url, _):
print(url)
stdout_write(url + "\n")
@staticmethod
def handle_url_fallback(url, kwdict):
print(url)
stdout_write(url + "\n")
if "_fallback" in kwdict:
for url in kwdict["_fallback"]:
print("|", url)
stdout_write("| " + url + "\n")
def handle_queue(self, url, kwdict):
cls = kwdict.get("_extractor")
@ -653,15 +655,18 @@ class InfoJob(Job):
return 0
def _print_multi(self, title, *values):
print(title, "\n ", " / ".join(json.dumps(v) for v in values), sep="")
stdout_write("{}\n {}\n\n".format(
title, " / ".join(json.dumps(v) for v in values)))
def _print_config(self, title, optname, value):
optval = self.extractor.config(optname, util.SENTINEL)
if optval is not util.SENTINEL:
print(title, "(custom):\n ", json.dumps(optval))
print(title, "(default):\n ", json.dumps(value))
stdout_write(
"{} (custom):\n {}\n{} (default):\n {}\n\n".format(
title, json.dumps(optval), title, json.dumps(value)))
elif value:
print(title, "(default):\n ", json.dumps(value))
stdout_write(
"{} (default):\n {}\n\n".format(title, json.dumps(value)))
class DataJob(Job):

View File

@ -39,8 +39,9 @@ class AppendCommandAction(argparse.Action):
class DeprecatedConfigConstAction(argparse.Action):
"""Set argparse const values as config values + deprecation warning"""
def __call__(self, parser, namespace, values, option_string=None):
print("warning: {} is deprecated. Use {} instead.".format(
"/".join(self.option_strings), self.choices), file=sys.stderr)
sys.stderr.write(
"warning: {} is deprecated. Use {} instead.\n".format(
"/".join(self.option_strings), self.choices))
namespace.options.append(((), self.dest, self.const))

View File

@ -149,10 +149,13 @@ class TestInfoJob(TestJob):
self.assertEqual(self._capture_stdout(extr), """\
Category / Subcategory
"test_category" / "test_subcategory"
Filename format (default):
"test_{filename}.{extension}"
Directory format (default):
["{category}"]
""")
def test_custom(self):
@ -165,18 +168,22 @@ Directory format (default):
self.assertEqual(self._capture_stdout(extr), """\
Category / Subcategory
"test_category" / "test_subcategory"
Filename format (custom):
"custom"
Filename format (default):
"test_{filename}.{extension}"
Directory format (custom):
["custom"]
Directory format (default):
["{category}"]
Request interval (custom):
321
Request interval (default):
123.456
""")
def test_base_category(self):
@ -186,10 +193,13 @@ Request interval (default):
self.assertEqual(self._capture_stdout(extr), """\
Category / Subcategory / Basecategory
"test_category" / "test_subcategory" / "test_basecategory"
Filename format (default):
"test_{filename}.{extension}"
Directory format (default):
["{category}"]
""")