Compare commits
No commits in common. "main" and "workflow" have entirely different histories.
@ -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.
|
||||||
|
|
||||||
|
|||||||
@ -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__"}
|
||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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__()
|
||||||
|
|||||||
@ -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():
|
||||||
|
|||||||
@ -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}")
|
||||||
|
|||||||
@ -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")
|
||||||
|
|||||||
@ -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():
|
||||||
|
|||||||
@ -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():
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user