jrnl/jrnl/editor.py
Micah Jerome Ellison 34c7903300
Replace flake8 and isort with ruff linter and add black --check to linting step (#1763)
* Add ruff

* Add ruff config

* Add ruff rules that look useful and are already passing

* Add more ruff rules after talking with Jonathan

* Add line length exception for acceptably long indented line

* Resolve ruff line length 88 rule in args. Changing small lines but adding a noqa ignore directive to longer lines that look best as they are. Their dedented length is still less than 88

* poe format

* Resolve all remaining ruff line length errors

* Replace flake* and isort with ruff calls

* Add black --check as final lint step. ruff catches most but not all black formatting issues

* Remove unneeded flakeheaven setting

* Remove flake* and isort now that ruff is handling all their business

* Update pyproject, lockfile with latest version of ruff

* Document each ruff rule with comment

* Add black --version call before black --check

* Remove extraneous period
2023-07-15 12:35:10 -07:00

121 lines
3.5 KiB
Python

# 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,
},
)
)