From 7737db1883c553e9491bebe8a79b9c06b2c74ff9 Mon Sep 17 00:00:00 2001 From: Tim Van Baak Date: Thu, 22 Jun 2023 20:43:03 -0700 Subject: [PATCH] Print logging to stderr --- intake/app.py | 8 ++++---- intake/cli.py | 29 +++++++++++++++-------------- intake/crontab.py | 25 ++++++++++++++++++------- intake/source.py | 9 +++++---- 4 files changed, 42 insertions(+), 29 deletions(-) diff --git a/intake/app.py b/intake/app.py index 6484659..eabed54 100644 --- a/intake/app.py +++ b/intake/app.py @@ -4,7 +4,7 @@ from pathlib import Path from random import getrandbits from typing import List import json -import os +import sys import time from flask import ( @@ -205,7 +205,7 @@ def deactivate(source_name, item_id): source = LocalSource(data_path, source_name) item = source.get_item(item_id) if item["active"]: - print(f"Deactivating {source_name}/{item_id}") + print(f"Deactivating {source_name}/{item_id}", file=sys.stderr) item["active"] = False source.save_item(item) return jsonify({"active": item["active"]}) @@ -233,14 +233,14 @@ def mass_deactivate(): data_path: Path = current_app.config["INTAKE_DATA"] params = request.get_json() if "items" not in params: - print(f"Bad request params: {params}") + print(f"Bad request params: {params}", file=sys.stderr) for info in params.get("items"): source = info["source"] itemid = info["itemid"] source = LocalSource(data_path, source) item = source.get_item(itemid) if item["active"]: - print(f"Deactivating {info['source']}/{info['itemid']}") + print(f"Deactivating {info['source']}/{info['itemid']}", file=sys.stderr) item["active"] = False source.save_item(item) return jsonify({}) diff --git a/intake/cli.py b/intake/cli.py index d537bbb..74f50bb 100644 --- a/intake/cli.py +++ b/intake/cli.py @@ -38,7 +38,7 @@ def cmd_edit(cmd_args): editor_cmd = os.environ.get("EDITOR") if not editor_cmd: - print("Cannot edit, no EDITOR set") + print("Cannot edit, no EDITOR set", file=sys.stderr) return 1 source_path: Path = data_path / args.source @@ -119,14 +119,14 @@ def cmd_update(cmd_args): update_items(source, items) else: for item in items: - print("Item:", item._item) + print("Item:", item._item, file=sys.stderr) except InvalidConfigException as ex: - print("Could not fetch", args.source) - print(ex) + print("Could not fetch", args.source, file=sys.stderr) + print(ex, file=sys.stderr) return 1 except SourceUpdateException as ex: - print("Error updating source", args.source) - print(ex) + print("Error updating source", args.source, file=sys.stderr) + print(ex, file=sys.stderr) return 1 return 0 @@ -167,10 +167,10 @@ def cmd_action(cmd_args): source = LocalSource(data_path, args.source) try: item = execute_action(source, args.item, args.action, 5) - print("Item:", item) + print("Item:", item, file=sys.stderr) except InvalidConfigException as ex: - print("Could not fetch", args.source) - print(ex) + print("Could not fetch", args.source, file=sys.stderr) + print(ex, file=sys.stderr) return 1 except SourceUpdateException as ex: print( @@ -180,8 +180,9 @@ def cmd_action(cmd_args): args.item, "action", args.action, + file=sys.stderr, ) - print(ex) + print(ex, file=sys.stderr) return 1 return 0 @@ -208,7 +209,7 @@ def cmd_feed(cmd_args): data_path: Path = Path(args.data) if args.data else intake_data_dir() if not data_path.exists() and data_path.is_dir(): - print("Not a directory:", data_path) + print("Not a directory:", data_path, file=sys.stderr) return 1 if not args.sources: @@ -273,7 +274,7 @@ def cmd_passwd(cmd_args): command_exists = subprocess.run(["command", "-v" "htpasswd"], shell=True) if command_exists.returncode: - print("Could not find htpasswd, cannot update password") + print("Could not find htpasswd, cannot update password", file=sys.stderr) return 1 data_path: Path = Path(args.data) if args.data else intake_data_dir() @@ -287,7 +288,7 @@ def cmd_passwd(cmd_args): ["htpasswd", "-b", "/etc/intake/htpasswd", user, password] ) if update_pwd.returncode: - print("Could not update password file") + print("Could not update password file", file=sys.stderr) return 1 new_creds = {"username": user, "secret": password} @@ -337,7 +338,7 @@ def cmd_run(cmd_args): app.run(port=args.port, debug=args.debug) return 0 except Exception as ex: - print(ex) + print(ex, file=sys.stderr) return 1 diff --git a/intake/crontab.py b/intake/crontab.py index e3d004f..934a5c0 100644 --- a/intake/crontab.py +++ b/intake/crontab.py @@ -1,6 +1,7 @@ from pathlib import Path import os import subprocess +import sys from intake.source import LocalSource @@ -27,18 +28,24 @@ def update_crontab_entries(data_path: Path): Update the intake-managed section of the user's crontab. """ # If there is no crontab command available, quit early. - crontab_exists = subprocess.run(["command", "-v" "crontab"], shell=True) + cmd = ("command", "-v", "crontab") + print("Executing", *cmd, file=sys.stderr) + crontab_exists = subprocess.run(cmd, shell=True) if crontab_exists.returncode: - print("Could not update crontab") + print("Could not update crontab", file=sys.stderr) return # Get the current crontab + cmd = ["crontab", "-e"] + print("Executing", *cmd, file=sys.stderr) get_crontab = subprocess.run( - ["crontab", "-e"], + cmd, env={**os.environ, "EDITOR": "cat"}, stdout=subprocess.PIPE, - stderr=subprocess.DEVNULL, + stderr=subprocess.PIPE, ) + for line in get_crontab.stderr.decode("utf8").splitlines(): + print("[stderr]", line, file=sys.stderr) crontab_lines = get_crontab.stdout.decode("utf-8").splitlines() # Splice the intake crons into the crontab @@ -67,16 +74,20 @@ def update_crontab_entries(data_path: Path): new_crontab_lines.extend(get_desired_crons(data_path)) new_crontab_lines.append(INTAKE_CRON_END) + print("Updating", len(new_crontab_lines) - 2, "crontab entries", file=sys.stderr) + # Save the updated crontab + cmd = ["crontab", "-"] + print("Executing", *cmd, file=sys.stderr) new_crontab: bytes = "\n".join(new_crontab_lines).encode("utf8") save_crontab = subprocess.Popen( - ["crontab", "-"], + cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) (stdout, stderr) = save_crontab.communicate(new_crontab) for line in stdout.decode("utf8").splitlines(): - print("[stdout]", line) + print("[stdout]", line, file=sys.stderr) for line in stderr.decode("utf8").splitlines(): - print("[stderr]", line) + print("[stderr]", line, file=sys.stderr) diff --git a/intake/source.py b/intake/source.py index a7bb549..99b2a1d 100755 --- a/intake/source.py +++ b/intake/source.py @@ -7,6 +7,7 @@ from typing import List import json import os import os.path +import sys from intake.types import InvalidConfigException, SourceUpdateException @@ -196,7 +197,7 @@ def _read_stdout(process: Popen, output: list) -> None: while True: data = process.stdout.readline() if data: - print(f"[stdout] <{repr(data)}>") + print(f"[stdout] <{repr(data)}>", file=sys.stderr) output.append(data) if process.poll() is not None: break @@ -210,7 +211,7 @@ def _read_stderr(process: Popen) -> None: while True: data = process.stderr.readline() if data: - print(f"[stderr] <{repr(data)}>") + print(f"[stderr] <{repr(data)}>", file=sys.stderr) if process.poll() is not None: break @@ -330,7 +331,7 @@ def update_items(source: LocalSource, fetched_items: List[Item]): """ # Get a list of item ids that already existed for this source. prior_ids = source.get_item_ids() - print(f"Found {len(prior_ids)} prior items") + print(f"Found {len(prior_ids)} prior items", file=sys.stderr) # Determine which items are new and which are updates. new_items: List[Item] = [] @@ -364,4 +365,4 @@ def update_items(source: LocalSource, fetched_items: List[Item]): source.delete_item(item_id) del_count += 1 - print(len(new_items), "new,", del_count, "deleted") + print(len(new_items), "new,", del_count, "deleted", file=sys.stderr)