rewrite yesno function to use new centralized messages

This commit is contained in:
Jonathan Wren 2022-05-17 11:01:34 -07:00
parent 3381ca752c
commit 4e4125155c
6 changed files with 74 additions and 20 deletions

View file

@ -289,7 +289,10 @@ class Journal:
def ask_delete(entry): def ask_delete(entry):
return yesno( return yesno(
f"Delete entry '{entry.pprint(short=True)}'?", Message(
MsgText.DeleteEntryQuestion,
params={"entry_title": entry.pprint(short=True)},
),
default=False, default=False,
) )

View file

@ -124,10 +124,7 @@ def install():
pass pass
# Encrypt it? # Encrypt it?
encrypt = yesno( encrypt = yesno(Message(MsgText.EncryptJournalQuestion), default=False)
"Do you want to encrypt your journal? You can always change this later",
default=False,
)
if encrypt: if encrypt:
default_config["encrypt"] = True default_config["encrypt"] = True
print_msg(Message(MsgText.JournalEncrypted, MsgStyle.NORMAL)) print_msg(Message(MsgText.JournalEncrypted, MsgStyle.NORMAL))

View file

@ -53,6 +53,10 @@ class MsgStyle(Enum):
"decoration": MsgDecoration.BRACKET, "decoration": MsgDecoration.BRACKET,
"color": _MsgColor("white"), "color": _MsgColor("white"),
} }
PROMPT = {
"decoration": MsgDecoration.NONE,
"color": _MsgColor("white"),
}
TITLE = { TITLE = {
"decoration": MsgDecoration.BOX, "decoration": MsgDecoration.BOX,
"color": _MsgColor("cyan"), "color": _MsgColor("cyan"),
@ -103,6 +107,19 @@ class MsgText(Enum):
AllDoneUpgrade = "We're all done here and you can start enjoying jrnl 2" AllDoneUpgrade = "We're all done here and you can start enjoying jrnl 2"
# --- Prompts --- #
DeleteEntryQuestion = "Delete entry '{entry_title}'?"
EncryptJournalQuestion = """
Do you want to encrypt your journal? (You can always change this later)
"""
YesOrNoPromptDefaultYes = "[Y/n]"
YesOrNoPromptDefaultNo = "[y/N]"
# these should be lowercase, if possible in language
# "lowercase" means whatever `.lower()` returns
OneCharacterYes = "y"
OneCharacterNo = "n"
# --- Exceptions ---# # --- Exceptions ---#
UncaughtException = """ UncaughtException = """
{name} {name}

View file

@ -4,6 +4,7 @@
import logging import logging
import textwrap import textwrap
from typing import Union
from rich.text import Text from rich.text import Text
from rich.console import Console from rich.console import Console
@ -38,20 +39,22 @@ def list_journals(configuration):
return result return result
def print_msg(msg: Message) -> None: def print_msg(msg: Message, is_prompt: bool = False) -> Union[None, str]:
print_msgs([msg], style=msg.style) return print_msgs([msg], style=msg.style, is_prompt=is_prompt)
def print_msgs( def print_msgs(
msgs: list[Message], msgs: list[Message],
delimiter: str = "\n", delimiter: str = "\n",
style: MsgStyle = MsgStyle.NORMAL, style: MsgStyle = MsgStyle.NORMAL,
) -> None: is_prompt: bool = False,
) -> Union[None, str]:
# Same as print_msg, but for a list # Same as print_msg, but for a list
text = Text("") text = Text("")
decoration_callback = style.decoration.callback decoration_callback = style.decoration.callback
args = style.decoration.args args = style.decoration.args
prepend_newline = False prepend_newline = False
append_space = False
for msg in msgs: for msg in msgs:
args = _add_extra_style_args_if_needed(args, msg=msg) args = _add_extra_style_args_if_needed(args, msg=msg)
@ -59,20 +62,27 @@ def print_msgs(
if _needs_prepended_newline(msg): if _needs_prepended_newline(msg):
prepend_newline = True prepend_newline = True
m = format_msg(msg) if _needs_appended_space(msg):
append_space = True
m = format_msg_text(msg)
m.append(delimiter) m.append(delimiter)
text.append(m) text.append(m)
text.rstrip() text.rstrip()
if append_space:
text.append(" ")
# Always print messages to stderr # Always print messages to stderr
console = Console(stderr=True) console = Console(stderr=True)
decorated_text = decoration_callback(text, **args)
console.print( if is_prompt:
decoration_callback(text, **args), return str(console.input(prompt=decorated_text))
new_line_start=prepend_newline, else:
) console.print(decorated_text, new_line_start=prepend_newline)
def _add_extra_style_args_if_needed(args, msg): def _add_extra_style_args_if_needed(args, msg):
@ -85,10 +95,18 @@ def _needs_prepended_newline(msg: Message) -> bool:
return is_keyboard_int(msg) return is_keyboard_int(msg)
def _needs_appended_space(msg: Message) -> bool:
return is_prompt(msg)
def is_prompt(msg: Message) -> bool:
return msg.style == MsgStyle.PROMPT
def is_keyboard_int(msg: Message) -> bool: def is_keyboard_int(msg: Message) -> bool:
return msg.text == MsgText.KeyboardInterruptMsg return msg.text == MsgText.KeyboardInterruptMsg
def format_msg(msg: Message) -> Text: def format_msg_text(msg: Message) -> Text:
text = textwrap.dedent(msg.text.value.format(**msg.params)).strip() text = textwrap.dedent(msg.text.value.format(**msg.params)).strip()
return Text(text) return Text(text)

View file

@ -7,6 +7,7 @@ from jrnl.messages import Message
from jrnl.messages import MsgText from jrnl.messages import MsgText
from jrnl.messages import MsgStyle from jrnl.messages import MsgStyle
from jrnl.output import print_msg from jrnl.output import print_msg
from jrnl.output import print_msgs
def create_password(journal_name: str) -> str: def create_password(journal_name: str) -> str:
@ -20,14 +21,32 @@ def create_password(journal_name: str) -> str:
print_msg(Message(MsgText.PasswordDidNotMatch, MsgStyle.ERROR)) print_msg(Message(MsgText.PasswordDidNotMatch, MsgStyle.ERROR))
if yesno(str(MsgText.PasswordStoreInKeychain), default=True): if yesno(Message(MsgText.PasswordStoreInKeychain), default=True):
from .EncryptedJournal import set_keychain from .EncryptedJournal import set_keychain
set_keychain(journal_name, pw) set_keychain(journal_name, pw)
return pw return pw
def yesno(prompt: str, default: bool = True): def yesno(prompt: Message, default: bool = True) -> bool:
prompt = f"{prompt.strip()} {'[Y/n]' if default else '[y/N]'} " response = print_msgs(
response = input(prompt) [
return {"y": True, "n": False}.get(response.lower().strip(), default) prompt,
Message(
MsgText.YesOrNoPromptDefaultYes
if default
else MsgText.YesOrNoPromptDefaultNo
),
],
style=MsgStyle.PROMPT,
delimiter=" ",
is_prompt=True,
)
answers = {
str(MsgText.OneCharacterYes): True,
str(MsgText.OneCharacterNo): False,
}
# Does using `lower()` work in all languages?
return answers.get(str(response).lower().strip(), default)

View file

@ -115,7 +115,7 @@ def upgrade_jrnl(config_path):
**kwargs, **kwargs,
) )
cont = yesno("\nContinue upgrading jrnl?", default=False) cont = yesno(Message(MsgText.ContinueUpgrade), default=False)
if not cont: if not cont:
raise JrnlException(Message(MsgText.UpgradeAborted), MsgStyle.WARNING) raise JrnlException(Message(MsgText.UpgradeAborted), MsgStyle.WARNING)