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" site = "site_tools.cli:app"
roll-table = "rolltable.cli:app" roll-table = "rolltable.cli:app"
pelican = "site_tools.tasks:pelican_main" pelican = "site_tools.tasks:pelican_main"
dmsh = "site_tools.cli:dmsh"

View File

@ -7,6 +7,7 @@ import shlex
import sys import sys
import typer import typer
import webbrowser import webbrowser
import termios
import site_tools as st import site_tools as st
@ -20,11 +21,12 @@ from typing_extensions import Annotated
from collections import defaultdict from collections import defaultdict
from site_tools.content_manager import create 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 from rolltable.tables import RollTable
CONFIG = { CONFIG = defaultdict(dict)
CONFIG.update({
'settings_base': st.DEV_SETTINGS_FILE_BASE, 'settings_base': st.DEV_SETTINGS_FILE_BASE,
'settings_publish': st.PUB_SETTINGS_FILE_BASE, 'settings_publish': st.PUB_SETTINGS_FILE_BASE,
# Output path. Can be absolute or relative to tasks.py. Default: 'output' # Output path. Can be absolute or relative to tasks.py. Default: 'output'
@ -45,7 +47,7 @@ CONFIG = {
'production_host': 'deadsands.froghat.club', 'production_host': 'deadsands.froghat.club',
# where to find roll table sources # where to find roll table sources
'table_sources_path': 'sources', 'table_sources_path': 'sources',
} })
app = typer.Typer() app = typer.Typer()
@ -263,22 +265,10 @@ def new(
category, template or content_type.value)) category, template or content_type.value))
@app.command()
def dmsh(): 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) old_attrs = termios.tcgetattr(sys.stdin)
try: try:
asyncio.run(prompt.start()) asyncio.run(DMShell(CONFIG).start())
finally: finally:
termios.tcsetattr(sys.stdin, termios.TCSANOW, old_attrs) termios.tcsetattr(sys.stdin, termios.TCSANOW, old_attrs)

View File

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

View File

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

View File

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