refactoring
This commit is contained in:
parent
cbba29012b
commit
44fc415100
|
@ -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"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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'])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user