# Copyright © 2012-2023 jrnl contributors # License: https://www.gnu.org/licenses/gpl-3.0.html import logging import os import subprocess import sys import tempfile from pathlib import Path from jrnl.exception import JrnlException from jrnl.messages import Message from jrnl.messages import MsgStyle from jrnl.messages import MsgText from jrnl.os_compat import on_windows from jrnl.os_compat import split_args from jrnl.output import print_msg from jrnl.path import absolute_path from jrnl.path import get_templates_path def get_text_from_editor(config: dict, template: str = "") -> str: suffix = ".jrnl" if config["template"]: template_filename = Path(config["template"]).name suffix = "-" + template_filename filehandle, tmpfile = tempfile.mkstemp(prefix="jrnl", text=True, suffix=suffix) os.close(filehandle) with open(tmpfile, "w", encoding="utf-8") as f: if template: f.write(template) try: subprocess.call(split_args(config["editor"]) + [tmpfile]) except FileNotFoundError: raise JrnlException( Message( MsgText.EditorMisconfigured, MsgStyle.ERROR, {"editor_key": config["editor"]}, ) ) with open(tmpfile, "r", encoding="utf-8") as f: raw = f.read() os.remove(tmpfile) if not raw: raise JrnlException(Message(MsgText.NoTextReceived, MsgStyle.NORMAL)) return raw def get_text_from_stdin() -> str: print_msg( Message( MsgText.WritingEntryStart, MsgStyle.TITLE, { "how_to_quit": MsgText.HowToQuitWindows if on_windows() else MsgText.HowToQuitLinux }, ) ) try: raw = sys.stdin.read() except KeyboardInterrupt: logging.error("Append mode: keyboard interrupt") raise JrnlException( Message(MsgText.KeyboardInterruptMsg, MsgStyle.ERROR_ON_NEW_LINE), Message(MsgText.JournalNotSaved, MsgStyle.WARNING), ) return raw def get_template_path(template_path: str, jrnl_template_dir: str) -> str: actual_template_path = os.path.join(jrnl_template_dir, template_path) if not os.path.exists(actual_template_path): logging.debug( f"Couldn't open {actual_template_path}. " "Treating template path like a local / abs path." ) actual_template_path = absolute_path(template_path) return actual_template_path def read_template_file(template_path: str) -> str: """ Reads the template file given a template path in this order: * Check $XDG_DATA_HOME/jrnl/templates/template_path. * Check template_arg as an absolute / relative path. If a file is found, its contents are returned as a string. If not, a JrnlException is raised. """ jrnl_template_dir = get_templates_path() actual_template_path = get_template_path(template_path, jrnl_template_dir) try: with open(actual_template_path, encoding="utf-8") as f: template_data = f.read() return template_data except FileNotFoundError: raise JrnlException( Message( MsgText.CantReadTemplate, MsgStyle.ERROR, { "template_path": template_path, "actual_template_path": actual_template_path, "jrnl_template_dir": str(jrnl_template_dir) + os.sep, }, ) )