From 4e75ea61b50db788978e29a292a55ef739f01580 Mon Sep 17 00:00:00 2001 From: John Burwell Date: Sun, 30 Apr 2023 14:44:35 -0500 Subject: [PATCH] add basic user support --- rsbbs/__init__.py | 1 + rsbbs/console.py | 10 ++++--- rsbbs/models.py | 13 ++++++++- rsbbs/rsbbs.py | 7 ++++- rsbbs/user.py | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 rsbbs/user.py diff --git a/rsbbs/__init__.py b/rsbbs/__init__.py index e375bc2..142082b 100644 --- a/rsbbs/__init__.py +++ b/rsbbs/__init__.py @@ -27,3 +27,4 @@ from .controller import Controller from .logger import Logger from .parser import Parser from .pluginloader import PluginLoader +from .user import User diff --git a/rsbbs/console.py b/rsbbs/console.py index 473f917..039a718 100644 --- a/rsbbs/console.py +++ b/rsbbs/console.py @@ -20,16 +20,18 @@ import logging import sys import rsbbs -from rsbbs import Config, Controller, Parser, PluginLoader +from rsbbs import Config, Controller +from rsbbs.models import User # Main UI console class class Console(): - def __init__(self, config: Config, controller: Controller): + def __init__(self, config: Config, controller: Controller, user: User): self.config = config self.controller = controller + self.user = user self.parser = rsbbs.Parser() @@ -93,7 +95,9 @@ class Console(): f"{self.config.callsign} ") greeting.append(f"Welcome to {self.config.bbs_name}, " - f"{self.config.calling_station}") + f"{self.user.callsign}") + + greeting.append(f"Last login: {self.user.login_last}") greeting.append(self.config.banner_message) diff --git a/rsbbs/models.py b/rsbbs/models.py index 941c68b..68716a5 100644 --- a/rsbbs/models.py +++ b/rsbbs/models.py @@ -18,7 +18,7 @@ from datetime import datetime, timezone -from sqlalchemy import Boolean, DateTime, String +from sqlalchemy import Boolean, DateTime, String, Integer from sqlalchemy.orm import DeclarativeBase, Mapped from sqlalchemy.orm import mapped_column @@ -38,3 +38,14 @@ class Message(Base): datetime: Mapped[DateTime] = mapped_column( DateTime, default=datetime.now(timezone.utc)) is_private: Mapped[bool] = mapped_column(Boolean) + + +class User(Base): + __tablename__ = 'user' + id: Mapped[int] = mapped_column(primary_key=True) + callsign: Mapped[str] = mapped_column(String) + given_name: Mapped[str] = mapped_column(String, nullable=True) + family_name: Mapped[str] = mapped_column(String, nullable=True) + login_count: Mapped[int] = mapped_column(Integer) + login_last: Mapped[DateTime] = mapped_column( + DateTime, default=datetime.now(timezone.utc)) diff --git a/rsbbs/rsbbs.py b/rsbbs/rsbbs.py index 41141e8..9d32be3 100755 --- a/rsbbs/rsbbs.py +++ b/rsbbs/rsbbs.py @@ -23,6 +23,8 @@ from rsbbs import Config, Console, Controller, Logger from rsbbs.args import parse_args +from rsbbs.user import User + def main(): @@ -41,8 +43,11 @@ def main(): # Init the controller controller = Controller(config) + # Init the user: + user = User(controller, args.calling_station.upper()) + # Init the UI console - console = Console(config, controller) + console = Console(config, controller, user) # Start the app console.run() diff --git a/rsbbs/user.py b/rsbbs/user.py new file mode 100644 index 0000000..4329b07 --- /dev/null +++ b/rsbbs/user.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python +# +# Really Simple BBS - a really simple BBS for ax.25 packet radio. +# Copyright (C) 2023 John Burwell +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import logging +from typing import Any +import sqlalchemy + +from datetime import datetime, timezone + +from rsbbs import __version__ +from rsbbs import Controller + +from rsbbs.models import User as SAUser + + +class User(): + def __init__(self, controller: Controller, callsign: str): + self.controller = controller + self.callsign = callsign + self.user = self.get_or_create_user() + + def __getattr__(self, __name: str) -> Any: + return getattr(self.user, __name) + + def get_or_create_user(self): + with self.controller.session() as session: + session.expire_on_commit = False + try: + statement = sqlalchemy.select(SAUser).where( + SAUser.callsign == self.callsign.upper()) + exopts = {"prebuffer_rows": True} + result = session.execute(statement, + execution_options=exopts) + result = result.one_or_none() + if result: + user = result[0] + logging.info(f"User {result[0].callsign} found.") + self.login_last = user.login_last + user.login_count = user.login_count + 1 + user.login_last = datetime.now(timezone.utc) + session.commit() + else: + logging.info(f"User not found.") + user = SAUser( + callsign=self.callsign.upper(), + login_count=1, + ) + session.add(user) + session.commit() + logging.info(f"User added.") + return user + except Exception as e: + logging.error(e) + raise