refactoring

This commit is contained in:
evilchili 2023-07-04 10:45:10 -07:00
parent cbba29012b
commit 44fc415100
5 changed files with 70 additions and 90 deletions

View File

@ -36,6 +36,7 @@ prompt-toolkit = "^3.0.38"
site = "site_tools.cli:app"
roll-table = "rolltable.cli:app"
pelican = "site_tools.tasks:pelican_main"
dmsh = "site_tools.cli:dmsh"

View File

@ -7,6 +7,7 @@ import shlex
import sys
import typer
import webbrowser
import termios
import site_tools as st
@ -20,11 +21,12 @@ from typing_extensions import Annotated
from collections import defaultdict
from site_tools.content_manager import create
from site_tools.shell.interactive_shell import InteractiveShell
from site_tools.shell.interactive_shell import DMShell
from rolltable.tables import RollTable
CONFIG = {
CONFIG = defaultdict(dict)
CONFIG.update({
'settings_base': st.DEV_SETTINGS_FILE_BASE,
'settings_publish': st.PUB_SETTINGS_FILE_BASE,
# Output path. Can be absolute or relative to tasks.py. Default: 'output'
@ -45,7 +47,7 @@ CONFIG = {
'production_host': 'deadsands.froghat.club',
# where to find roll table sources
'table_sources_path': 'sources',
}
})
app = typer.Typer()
@ -263,22 +265,10 @@ def new(
category, template or content_type.value))
@app.command()
def dmsh():
import termios, sys
session = defaultdict(dict)
prompt = InteractiveShell(
[
"[title]DM's Shell.[/title]",
'dmsh'
], config=CONFIG, session=session
)
# ensure the terminal is restored on exit.
old_attrs = termios.tcgetattr(sys.stdin)
try:
asyncio.run(prompt.start())
asyncio.run(DMShell(CONFIG).start())
finally:
termios.tcsetattr(sys.stdin, termios.TCSANOW, old_attrs)

View File

@ -29,6 +29,7 @@ BASE_STYLE = {
'toolbar.fg': '#888888',
'toolbar.bg': '#111111',
'toolbar.bold': '#FFFFFF',
'error': 'red',
}

View File

@ -3,7 +3,6 @@ from collections import namedtuple, defaultdict
from prompt_toolkit.completion import NestedCompleter
from site_tools.console import Console
from textwrap import dedent
@ -37,13 +36,22 @@ def command(usage, completer=None, binding=None):
class BasePrompt(NestedCompleter):
def __init__(self, console=None):
def __init__(self, cache={}):
super(BasePrompt, self).__init__(self._nested_completer_map())
self._prompt = ''
self._autocomplete_values = []
self._console = None
self._theme = None
self._toolbar = None
self._key_bindings = None
self._subshells = {}
self._cache = cache
self._name = 'Interactive Shell'
def _register_subshells(self):
for subclass in BasePrompt.__subclasses__():
if subclass.__name__ == self.__class__.__name__:
continue
self._subshells[subclass.__name__] = subclass(parent=self)
def _nested_completer_map(self):
return dict(
@ -56,13 +64,22 @@ class BasePrompt(NestedCompleter):
except KeyError:
return self.usage
def default_completer(self, document, complete_event):
raise NotImplementedError(f"Implement the 'default_completer' method of {self.__class__.__name__}")
@property
def name(self):
return self._name
@property
def cache(self):
return self._cache
@property
def key_bindings(self):
return self._key_bindings
@property
def usage(self):
text = dedent("""
[title]dmsh[/title]
text = dedent(f"""
[title]{self.name}[/title]
Available commands are listed below. Try 'help COMMAND' for detailed help.
@ -89,15 +106,15 @@ class BasePrompt(NestedCompleter):
@property
def autocomplete_values(self):
return self._autocomplete_values
return list(self.commands.keys())
@property
def toolbar(self):
return None
return self._toolbar
@property
def key_bindings(self):
return None
return self._key_bindings
def help(self, parts):
attr = None
@ -109,7 +126,7 @@ class BasePrompt(NestedCompleter):
def process(self, cmd, *parts):
if cmd in self.commands:
return self.commands[cmd].handler(self, parts)
self.console.error(f"Command {cmd} not understood.")
self.console.error(f"Command {cmd} not understood; try 'help' for help.")
def start(self, cmd=None):
while True:

View File

@ -7,72 +7,41 @@ from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.application import get_app
bindings = KeyBindings()
BINDINGS = KeyBindings()
class InteractiveShell(BasePrompt):
class DMShell(BasePrompt):
def __init__(self, prompt=[], config={}, session={}):
super().__init__()
self._prompt = prompt
self._config = config
self._wmt = ""
self._subshells = {}
def __init__(self, cache={}):
super().__init__(cache)
self._name = "DM Shell"
self._prompt = ['dm']
self._toolbar = [('class:bold', ' DMSH ')]
self._key_bindings = BINDINGS
self._register_subshells()
self._register_keybindings()
self._session = session
def _register_keybindings(self):
@bindings.add('c-q')
@bindings.add('c-d')
self._toolbar.extend([
('', " [H]elp "),
('', " [W]ild Magic Table "),
('', " [Q]uit "),
])
@self.key_bindings.add('c-q')
@self.key_bindings.add('c-d')
def quit(event):
self.quit()
@bindings.add('c-h')
@self.key_bindings.add('c-h')
def help(event):
self.help()
@bindings.add('c-w')
@self.key_bindings.add('c-w')
def wmt(event):
self.wmt()
def _register_subshells(self):
for subclass in BasePrompt.__subclasses__():
if subclass.__name__ == self.__class__.__name__:
continue
self._subshells[subclass.__name__] = subclass(parent=self)
@property
def key_bindings(self):
return bindings
@property
def toolbar(self):
return [
('class:bold', ' DMSH '),
('', " [H]elp "),
('', " [W]mt "),
('', " [Q]uit "),
]
@property
def session(self):
return self._session
@property
def autocomplete_values(self):
return list(self.commands.keys())
def default_completer(self, document, complete_event): # pragma: no cover
word = document.current_line_before_cursor
raise Exception(word)
def process(self, cmd, *parts):
if cmd in self.commands:
return self.commands[cmd].handler(self, parts)
return "Unknown Command; try help."
@command(usage="""
[title]QUIT[/title]
@ -86,8 +55,10 @@ class InteractiveShell(BasePrompt):
"""
Quit dmsh.
"""
get_app().exit()
raise SystemExit("Okay BYEEEE")
try:
get_app().exit()
finally:
raise SystemExit("")
@command(usage="""
[title]HELP FOR THE HELP LORD[/title]
@ -99,7 +70,7 @@ class InteractiveShell(BasePrompt):
[link]> help [COMMAND][/link]
""")
def help(self, *parts):
def help(self, parts=[]):
"""
Display the help message.
"""
@ -115,7 +86,7 @@ class InteractiveShell(BasePrompt):
[link]id[/link]
""")
def id(self, *parts):
def id(self, parts=[]):
"""
Increment the date by one day.
"""
@ -136,13 +107,13 @@ class InteractiveShell(BasePrompt):
"Gopher Gulch",
"Calamity Ridge"
]))
def loc(self, *parts):
def loc(self, parts=[]):
"""
Move the party to a new region of the Sahwat Desert.
"""
if parts:
self.session['location'] = (' '.join(parts))
self.console.print(f"The party is in {self.session['location']}.")
self.cache['location'] = (' '.join(parts))
self.console.print(f"The party is in {self.cache['location']}.")
@command(usage="""
[title]OVERLAND TRAVEL[/title]
@ -153,7 +124,7 @@ class InteractiveShell(BasePrompt):
[link]ot in[/link]
""")
def ot(self, *parts):
def ot(self, parts=[]):
"""
Increment the date by one day and record
"""
@ -162,7 +133,7 @@ class InteractiveShell(BasePrompt):
@command(usage="""
[title]WILD MAGIC TABLE[/title]
[b]wmt[/b] Generates a d20 wild magic surge roll table. The table will be cached for the session.
[b]wmt[/b] Generates a d20 wild magic surge roll table. The table will be cached for the cache.
[title]USAGE[/title]
@ -178,14 +149,14 @@ class InteractiveShell(BasePrompt):
"""
Generate a Wild Magic Table for resolving spell effects.
"""
if not self._wmt:
if 'wmt' not in self.cache:
rt = RollTable(
[Path(f"{self._config['table_sources_path']}/{source}").read_text()],
[Path(f"{self.cache['table_sources_path']}/{source}").read_text()],
frequency='default',
die=20,
)
table = Table(*rt.expanded_rows[0])
for row in rt.expanded_rows[1:]:
table.add_row(*row)
self._wmt = table
self.console.print(self._wmt)
self.cache['wmt'] = table
self.console.print(self.cache['wmt'])