From ebaa847abd5e45e0c8f3bb54d1b30dfc17fab022 Mon Sep 17 00:00:00 2001 From: John Burwell Date: Tue, 25 Apr 2023 23:54:17 -0500 Subject: [PATCH] add --show-config option, update README --- README.md | 90 +++++++++++++++++++++++++++++++++++------------- rsbbs/config.py | 7 ++++ rsbbs/console.py | 8 +++++ rsbbs/rsbbs.py | 23 +++++++++++-- 4 files changed, 103 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index f2c30ff..9c72d0d 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ A message board for packet radio, suitable for use with ax25d. Really Simple BBS (`rsbbs`) implements a bulletin board system that enables -radio amateurs to read and store messages at your station. It is similar to the -PBBS function of popular Kantronics TNCs, and it uses similar commands (`B`, -`J`, `K`, `L`, `R`, `S`, `H`, etc.). +radio amateurs to read and store messages at your station. It generally adopts +conventions common to other popular BBS systems, (`B`, `J`, `K`, `L`, `R`, `S`, +`H`, etc.) It is designed to run on a linux system when called by `ax25d`. That is, when a user calls your station, `ax25d` answers the call and routes the connection to @@ -14,32 +14,55 @@ user calls your station, `ax25d` answers the call and routes the connection to ## Requirements -In general, you need a linux system with ax25d configured and working. This is -a python 3 application, so you will need python 3 also. +- **AX.25:** It is assumed that you have a radio connected to your host, that + you have configured your axports, and that ax25d can answer calls. +- **Python 3:** As this is a python 3 application, you will need python 3 and + pip. +- **Hardware:** A system capable of running Direwolf and ax25d should be more + than sufficient. ## Installation -Until I publish this thing to PyPI, you can clone it and build it yourself: +Clone this repository and install it with pip: -1. Clone the repo to a reasonable location. -2. `cd` to the repo directory -3. Run `python3 -m pip build .` -4. Run `python3 -m pip install .` -5. Run `rsbbs -h` to test installation and create config and data files. +``` +git clone https://git.b-wells.us/jmbwell/rsbbs.git +cd rsbbs +python3 -m virtualenv .venv +source .venv/bin/activate +pip install . +rsbbs -h +``` + +The config file will be created at first launch. ## Configuration By default, the `config.yaml` file lives in your system's user config -directory, such as `~/.config/rsbbs/config.yaml`. +directory, such as `~/.config/rsbbs/config.yaml`, as determined by the +`platformdirs` module. To use a `config.yaml` file from a different location, use the `-f` option: ``` -rsbbs -f ~/config.yaml -s KI5QKX +rsbbs -f ~/config.yaml -s ``` -If this file is missing, `rsbbs` will create it. +Either way, if the file is missing, `rsbbs` will create it. -The `config.yaml` file is pretty simple and self-explanatory for now. +The `config.yaml` file is pretty simple and self-explanatory for now: +``` +bbs_name: John's Really Simple BBS +callsign: HOSTCALL +banner_message: Leave a message! +command_prompt: ENTER COMMAND > +``` + +> Tip: +> To show the location of the current config file (among other configuration +> options), run: +> ``` +> rsbbs --show-config +> ``` ## Usage @@ -53,17 +76,25 @@ following to your `ax25d.conf` file: default * * * * * * * root /usr/local/bin/rsbbs rsbbs -s %U ``` -Notes: -- The installation path may vary on your system. -- Be sure to specify the `-s %U` parameters; this passes the ax.25 caller's - callsign to the `rsbbs` application. +> Notes: +> - Specify the full path to the `rsbbs` application. +> - The installation path may vary on your system. +> - If you install it in a virtualenv, specify the path to `rsbbs` in that +> virtualenv's `/bin` directory. +> - Be sure to specify the `-s %U` parameter; this passes the ax.25 caller's +> callsign to the `rsbbs` application. -See the ax25d man page for more details. + +See `man ax25d.conf` for more details. ### Directly -You can also run it directly, for administration purposes or just to talk to -yourself. It will not accept calls when run without ax25d. +You can launch it from the command line on your packet station's host, and you +can interact with it just as you would over the air. + +This might be useful for administration purposes or just to talk to yourself. +It does not have a standalone mode for taking calls, however -- that's what +ax25d is for. ``` rsbbs -s URCALL @@ -71,7 +102,7 @@ rsbbs -s URCALL ### Options -Run `sbbs -h` to see the following help: +Run `rsbbs -h` to see the following help: ``` usage: rsbbs [-h] [-d] -s CALLING_STATION [-f CONFIG_FILE] [-v] @@ -83,6 +114,7 @@ options: The callsign of the calling station -f CONFIG_FILE, --config-file CONFIG_FILE specify path to config.yaml file + --show-config show the current configuration and exit -v, --version show program's version number and exit ``` @@ -99,8 +131,20 @@ In general, on a macOS or linux system: 3. Create a venv 4. Install it in "editable" mode with `pip install -e .` +For example: +``` +git clone https://git.b-wells.us/jmbwell/rsbbs.git +cd rsbbs +python3 -m virtualenv .venv +source .venv/bin/activate +pip install -e . +rsbbs -h +``` + ## Contributing +Pull requests welcome. If you're not sure where to start: + 1. Fork it () 2. Create your feature branch (`git checkout -b feature/fooBar`) 3. Commit your changes (`git commit -am 'add some fooBar'`) diff --git a/rsbbs/config.py b/rsbbs/config.py index d5842a2..0d6a71d 100644 --- a/rsbbs/config.py +++ b/rsbbs/config.py @@ -48,6 +48,13 @@ class Config(): def __getattr__(self, __name: str): return self.config[__name] + def __repr__(self): + repr = [] + repr.append(f"app_name: {self.app_name}\r\n") + repr.append(f"config_file: {self.config_file}\r\n") + repr.append(yaml.dump(self.config)) + return ''.join(repr) + @property def config_file(self): # Use either the specified file or a file in a system config location diff --git a/rsbbs/console.py b/rsbbs/console.py index e1a77e6..f2dde08 100644 --- a/rsbbs/console.py +++ b/rsbbs/console.py @@ -74,6 +74,9 @@ class Console(): """Write something to stdout.""" sys.stdout.write(output + '\r\n') + def print_configuration(self): + self._write_output(repr(self.config)) + def print_greeting(self): # Show greeting greeting = [] @@ -258,6 +261,11 @@ class Console(): def run(self): + # If asked to show the config, show the config; + if self.config.args.show_config: + self.print_configuration() + exit(0) + # Show greeting self.print_greeting() diff --git a/rsbbs/rsbbs.py b/rsbbs/rsbbs.py index a77430f..17b388a 100755 --- a/rsbbs/rsbbs.py +++ b/rsbbs/rsbbs.py @@ -39,8 +39,8 @@ def main(): # [ short, long, action, default, dest, help, required ] ['-d', '--debug', 'store_true', None, 'debug', 'Enable debugging output to stdout', False], - ['-s', '--calling-station', 'store', 'N0CALL', 'calling_station', - 'Callsign of the calling station', True], + # ['-s', '--calling-station', 'store', 'N0CALL', 'calling_station', + # 'Callsign of the calling station', True], ['-f', '--config-file', 'store', None, 'config_file', 'Path to config.yaml file', False], ] @@ -48,6 +48,25 @@ def main(): argv_parser.add_argument( arg[0], arg[1], action=arg[2], default=arg[3], dest=arg[4], help=arg[5], required=arg[6]) + + group = argv_parser.add_mutually_exclusive_group(required=True) + + # Show config option: + group.add_argument( + '--show-config', + action='store_true', + default=None, + dest='show_config', + help="Show the configuration and exit") + + # Calling station: + group.add_argument( + '-s', + '--calling-station', + action='store', + default='N0CALL', + dest='calling_station', + help="Callsign of the calling station") # Version arg is special: argv_parser.add_argument(