Compare commits

..

No commits in common. "main" and "workflow" have entirely different histories.

24 changed files with 50 additions and 98 deletions

View File

@ -29,8 +29,6 @@ user calls your station, `ax25d` answers the call and routes the connection to
you have configured your axports, and that ax25d can answer calls. 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 - **Python 3:** As this is a python 3 application, you will need python 3 and
pip. pip.
- Note on compiling Python3: If you build Python3 from source on
debian/raspbian, you will need libssl-dev, libffi-dev, and libsqlite3-dev
- **Hardware:** A system capable of running Direwolf and ax25d should be more - **Hardware:** A system capable of running Direwolf and ax25d should be more
than sufficient. than sufficient.

View File

@ -30,7 +30,7 @@ rsbbs = "rsbbs.rsbbs:main"
repository = "https://git.b-wells.us/jmbwell/rsbbs" repository = "https://git.b-wells.us/jmbwell/rsbbs"
[tool.setuptools.package-data] [tool.setuptools.package-data]
rsbbs = ["config_default.yaml","plugins/info/info_default.txt"] rsbbs = ["config_default.yaml"]
[tool.setuptools.dynamic] [tool.setuptools.dynamic]
version = {attr = "rsbbs.__version__"} version = {attr = "rsbbs.__version__"}

View File

@ -20,3 +20,11 @@ __all__ = ['config', 'console', 'controller',
'logger', 'models', 'parser', 'pluginloader'] 'logger', 'models', 'parser', 'pluginloader']
__version__ = "0.4.0" __version__ = "0.4.0"
from .config import Config
from .console import Console
from .controller import Controller
from .logger import Logger
from .parser import Parser
from .pluginloader import PluginLoader
from .user import User

View File

@ -28,15 +28,13 @@ class Config():
self.app_name = app_name self.app_name = app_name
self._argv_config_file = args.config_file self._argv_config_file = args.config_file
self._init_config_file()
self._load_config() self._load_config()
# Put the messages db file in the system's user data directory # Put the messages db file in the system's user data directory
db_dir = platformdirs.user_data_dir(appname=self.app_name)
if not os.path.exists(db_dir):
os.makedirs(db_dir)
self._config['db_path'] = os.path.join( self._config['db_path'] = os.path.join(
db_dir, platformdirs.user_data_dir(
appname=self.app_name,
ensure_exists=True),
'messages.db') 'messages.db')
# Grab some config from the command line for convenience # Grab some config from the command line for convenience
@ -65,11 +63,10 @@ class Config():
@property @property
def config_file(self): def config_file(self):
# Use either the specified file or a file in a system config location # Use either the specified file or a file in a system config location
config_dir = platformdirs.user_config_dir(appname=self.app_name)
if not os.path.exists(config_dir):
os.makedirs(config_dir)
config_file = self._argv_config_file or os.path.join( config_file = self._argv_config_file or os.path.join(
config_dir, platformdirs.user_config_dir(
appname=self.app_name,
ensure_exists=True),
'config.yaml' 'config.yaml'
) )
return config_file return config_file

View File

@ -16,15 +16,11 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import io
import logging import logging
import sys import sys
import rsbbs import rsbbs
from rsbbs.config import Config from rsbbs import Config, Controller
from rsbbs.controller import Controller
from rsbbs.parser import Parser
from rsbbs.pluginloader import PluginLoader
from rsbbs.models import User from rsbbs.models import User
@ -38,20 +34,11 @@ class Console():
self.controller = controller self.controller = controller
self.user = user self.user = user
self.parser = Parser() self.parser = rsbbs.Parser()
self.pluginloader = PluginLoader(self) self.pluginloader = rsbbs.PluginLoader(self)
self.pluginloader.load_plugins() self.pluginloader.load_plugins()
# Configure stdin and stdout newlines and encoding
# when invoked by ax25:
if not sys.stdin.isatty():
sys.stdout = io.TextIOWrapper(sys.stdout.detach(),
newline=None)
sys.stdin = io.TextIOWrapper(sys.stdin.detach(),
newline=None)
# #
# Input and output # Input and output
# #
@ -100,31 +87,18 @@ class Console():
self.write_output(prompt) self.write_output(prompt)
while True: while True:
input_line = sys.stdin.readline() input_line = sys.stdin.readline()
if input_line.lower().strip() == "/ex": if input_line.lower().strip() != "/ex":
break break
input_lines.append(input_line) input_lines.append(input_line)
return ''.join(input_lines) return ''.join(input_lines)
def write_chunk(self, chunk: str) -> None:
"""Write a chunk of data to stdout.
:param output: the chunk to write to stdout
"""
sys.stdout.write(chunk + '\r\n')
sys.stdout.flush()
def write_output(self, output: str) -> None: def write_output(self, output: str) -> None:
"""Write something to stdout. """Write something to stdout.
:param output: the string to write to stdout :param output: the string to write to stdout
""" """
chunk_size = 256 # Adjust the chunk size as needed sys.stdout.write(output + '\r\n')
for i in range(0, len(output), chunk_size):
chunk = output[i:i + chunk_size]
self.write_chunk(chunk)
def print_configuration(self) -> None: def print_configuration(self) -> None:
"""Print the current running configuration. """Print the current running configuration.

View File

@ -19,7 +19,7 @@
from sqlalchemy import create_engine from sqlalchemy import create_engine
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from rsbbs.config import Config from rsbbs import Config
from rsbbs.models import Base from rsbbs.models import Base

View File

@ -48,12 +48,10 @@ class Logger(logging.Logger):
logger.removeHandler(handler) logger.removeHandler(handler)
# Log to a file in the system user log directory # Log to a file in the system user log directory
log_dir = platformdirs.user_log_dir(appname=self.name) log_dir = platformdirs.user_log_dir(appname=self.name,
ensure_exists=True)
log_filepath = os.path.join(log_dir, 'activity.log') log_filepath = os.path.join(log_dir, 'activity.log')
if not os.path.exists(log_dir):
os.makedirs(log_dir)
handler = logging.FileHandler(filename=log_filepath) handler = logging.FileHandler(filename=log_filepath)
# Add the calling station to the log messages # Add the calling station to the log messages
@ -62,6 +60,7 @@ class Logger(logging.Logger):
# Add the handler! # Add the handler!
logger.addHandler(handler) logger.addHandler(handler)
class Formatter(logging.Formatter): class Formatter(logging.Formatter):
def __init__(self, var): def __init__(self, var):
super().__init__() super().__init__()

View File

@ -18,8 +18,7 @@
import logging import logging
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
class Plugin(): class Plugin():

View File

@ -21,8 +21,7 @@ import logging
import sqlalchemy import sqlalchemy
import sqlalchemy.exc import sqlalchemy.exc
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
from rsbbs.models import Message from rsbbs.models import Message
@ -49,12 +48,13 @@ class Plugin():
sqlalchemy.and_( sqlalchemy.and_(
Message.recipient == self.api.config.calling_station, Message.recipient == self.api.config.calling_station,
Message.id == number, Message.id == number,
)) )).returning(Message)
result = session.execute( result = session.execute(
statement, statement,
execution_options={"prebuffer_rows": True}) execution_options={"prebuffer_rows": True})
count = result.rowcount
session.commit() session.commit()
results = result.all()
count = len(results)
if count > 0: if count > 0:
self.api.write_output(f"Deleted message #{number}") self.api.write_output(f"Deleted message #{number}")
logging.info(f"deleted message {number}") logging.info(f"deleted message {number}")

View File

@ -19,8 +19,7 @@
import logging import logging
import sqlalchemy import sqlalchemy
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
from rsbbs.models import Message from rsbbs.models import Message
@ -43,12 +42,13 @@ class Plugin():
try: try:
statement = sqlalchemy.delete(Message).where( statement = sqlalchemy.delete(Message).where(
Message.recipient == self.api.config.calling_station Message.recipient == self.api.config.calling_station
) ).returning(Message)
result = session.execute( result = session.execute(
statement, statement,
execution_options={"prebuffer_rows": True}) execution_options={"prebuffer_rows": True})
count = result.rowcount
session.commit() session.commit()
messages = result.all()
count = len(messages)
if count > 0: if count > 0:
self.api.write_output(f"Deleted {count} messages") self.api.write_output(f"Deleted {count} messages")
logging.info(f"deleted {count} messages") logging.info(f"deleted {count} messages")

View File

@ -19,8 +19,7 @@
import logging import logging
import subprocess import subprocess
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
class Plugin(): class Plugin():

View File

@ -16,8 +16,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
class Plugin(): class Plugin():

View File

@ -17,14 +17,12 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
import logging import logging
import os
import pkg_resources import pkg_resources
import platformdirs import platformdirs
from pathlib import Path from pathlib import Path
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
class Plugin(): class Plugin():
@ -44,12 +42,10 @@ class Plugin():
@property @property
def file(self) -> Path: def file(self) -> Path:
file_dir = platformdirs.user_config_dir(
appname=self.api.config.app_name)
if not os.path.exists(file_dir):
os.makedirs(file_dir)
self._file = Path().joinpath( self._file = Path().joinpath(
file_dir, platformdirs.user_config_dir(
appname=self.api.config.app_name,
ensure_exists=True),
'info.txt' 'info.txt'
) )
return self._file return self._file

View File

@ -19,8 +19,7 @@
import logging import logging
import sqlalchemy import sqlalchemy
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
from rsbbs.models import Message from rsbbs.models import Message

View File

@ -19,8 +19,7 @@
import logging import logging
import sqlalchemy import sqlalchemy
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
from rsbbs.models import Message from rsbbs.models import Message

View File

@ -19,8 +19,7 @@
import logging import logging
import sqlalchemy import sqlalchemy
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
from rsbbs.models import Message, User from rsbbs.models import Message, User

View File

@ -20,8 +20,7 @@ import logging
import sqlalchemy import sqlalchemy
import sqlalchemy.exc import sqlalchemy.exc
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
from rsbbs.models import Message, User from rsbbs.models import Message, User

View File

@ -19,8 +19,7 @@
import logging import logging
import sqlalchemy import sqlalchemy
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
from rsbbs.models import Message, User from rsbbs.models import Message, User

View File

@ -19,8 +19,7 @@
import logging import logging
import sqlalchemy import sqlalchemy
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
from rsbbs.models import Message, User from rsbbs.models import Message, User

View File

@ -18,8 +18,7 @@
import logging import logging
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
from rsbbs.models import Message from rsbbs.models import Message

View File

@ -18,8 +18,7 @@
import logging import logging
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
from rsbbs.models import Message from rsbbs.models import Message

View File

@ -23,8 +23,7 @@ import sqlalchemy.orm
import subprocess import subprocess
from rsbbs import __version__ from rsbbs import __version__
from rsbbs.console import Console from rsbbs import Console, Parser
from rsbbs.parser import Parser
from rsbbs.models import Message, User from rsbbs.models import Message, User

View File

@ -18,10 +18,7 @@
import logging import logging
from rsbbs.config import Config from rsbbs import Config, Console, Controller, Logger
from rsbbs.console import Console
from rsbbs.controller import Controller
from rsbbs.logger import Logger
from rsbbs.args import parse_args from rsbbs.args import parse_args
@ -29,10 +26,6 @@ from rsbbs.user import User
def main(): def main():
"""RSBBS - The BBS for packet radio that is really simple.
main function.
"""
# Grab the invocation arguments # Grab the invocation arguments
args = parse_args() args = parse_args()

View File

@ -23,8 +23,7 @@ from typing import Any
from datetime import datetime, timezone from datetime import datetime, timezone
from rsbbs.config import Config from rsbbs import Config, Controller
from rsbbs.controller import Controller
from rsbbs.models import User as SAUser from rsbbs.models import User as SAUser