2 More Milestones

I have added the feature for the BBS to be able to accept user messages and display all messages.

Still to be done: asc pages for messages and implementation of that.

Yes, I do know that I'm still including my test data in the json files. I do not care.
This commit is contained in:
jaycee 2025-07-19 21:02:32 -06:00
parent b6b67576c1
commit 6577e6b051
9 changed files with 121 additions and 10 deletions

3
bbs.py
View File

@ -42,8 +42,7 @@ class bbsServer():
try:
comms(conn, addr, node + 1)
except RuntimeError:
except (RuntimeError, OSError):
print("Node %s hung up..." % (node + 1))
print("Node %s offline." % (node + 1))

View File

@ -1,8 +1,9 @@
[Main]
Port = 2043
Port = 2062
DefaultSplash = "Welcome to the SB17 BBS on %node%!"
MaxConnections = 5
Menus = 2
msgDb = messages.json
[Auth]
userDb = users.json

View File

@ -1,5 +1,4 @@
# Configuration
This file contains the information necessary to configure Pyscii-BBS. The default configuration provided will run, but you will likely want to change many of these values.
## String Replacements

View File

@ -26,10 +26,10 @@ Remember these rules for working on the following features:
- BBS Server can show a menu to the user after logging in ✓
- BBS Server menu allows user to modify their own profile ✓
- BBS Server can display pre-coded messages in a messages space ✓
- BBS Server can accept messages from users ✓
- BBS Server can display user submitted messages to message boards ✓
#### ToDo
- BBS Server can accept messages from users
- BBS Server can display user submitted messages to message boards
- BBS Server can show only certain users a different menu option (RBAC implementation)
At this point we have the bare minimum of a functioning BBS. The user flow at this stage is they connect, log in, and are presented with a menu that will let them edit their profile or visit a message board. The message board will be a single flow of messages and the user will have to select what messages to read. No unread/read list exists. It is a simple text-based telnet message board with an auth system.

31
docs/message.schema.json Normal file
View File

@ -0,0 +1,31 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://bbs.sb17.space/message.schema.json",
"title": "Message",
"description": "A Pyscii-BBS message object",
"type": "object",
"properties": {
"id" : {
"description": "The unique ID of the message entity",
"type": "integer"
},
"subject": {
"description": "The subject of the message entity",
"type": "string"
},
"body": {
"description": "The message body.",
"type": "string"
},
"date": {
"description": "The date the message is posted",
"type": "datetime",
},
},
"required": [
"id",
"subject",
"body",
"date"
]
}

View File

@ -4,11 +4,15 @@ import sys
import comms
import menus
import auth
import datetime
config = configparser.ConfigParser()
config.read(sys.argv[1])
userDb = config.get("Auth","userDb")
msgDB = config.get("Main","msgDb")
date_format_string = "%Y-%m-%d HH:MM:SS"
def printProfile(conn, userId, node, lastMenu):
comms.sendString(conn, "\u001B[2JProfile:\r\n")
@ -50,8 +54,66 @@ def editProfile(conn, userID, node, lastMenu):
menus.printMenu(conn, lastMenu, node, userID)
def pubMessages(conn, userID, node, lastMenu):
comms.sendString(conn, "There are no messages!\r\nPress any key to go back... ")
comms.sendString(conn, "\u001B[2JMessages:\r\n")
with open(msgDB) as msgdb:
messages = json.loads(msgdb.read())
for message in messages['messages']:
msgListElement = str(message['id']) + "\t|\t" + message['date'] + "\t|\t" + message['author'] + "\t|\t" + message['subject'] + "\t\t\t"
comms.sendString(conn,msgListElement+"\r\n")
comms.sendString(conn, "\r\nSend the M and the message number (eg. M0) number to read a message.\r\nPress C to Write a Message \r\nSend B to go back to the Menu: ")
response = comms.getString(conn,3)
if response.strip('\x00') == "B":
menus.printMenu(conn, lastMenu, node, userID)
elif response.strip('\x00')[0] == "M":
printMessage(conn, int(response.strip('\x00').replace('M','')))
elif response.strip('\x00') == "C":
writeMessage(conn, userID)
pubMessages(conn, userID, node, lastMenu)
def printMessage(conn, messageNum):
comms.sendString(conn, "\u001B[2JMessage:\r\n")
with open(msgDB) as msgdb:
messages = json.loads(msgdb.read())
for message in messages['messages']:
if message['id'] == int(messageNum):
comms.sendString(conn, "\r\nDate Published: " + message['date'])
comms.sendString(conn, "\r\nSubject: " + message['subject'])
comms.sendString(conn, "\r\nAuthor: " + message['author'])
comms.sendString(conn, "\r\nMessage: " + message['body'])
comms.sendString(conn, "\r\nPress any key to go back... ")
comms.getString(conn,2)
return
def writeMessage(conn, userid):
comms.sendString(conn, "\u001B[2JCompose Message:\r\n")
with open(userDb) as userdb:
users = json.load(userdb)
for user in users['users']:
if user['id'] == userid:
username = user['name']
with open(msgDB) as msgdb:
messages = json.load(msgdb)
message = {}
message["id"] = messages['messages'][-1]["id"] + 1
message['date'] = datetime.datetime.now().strftime(date_format_string)
comms.sendString(conn,"Subject: ")
message['subject'] = comms.getString(conn, 150)
message['author'] = username
comms.sendString(conn,"Message Body: ")
message['body'] = comms.getString(conn, 1500)
messages['messages'].append(message)
with open(msgDB,'w') as output:
json.dump(messages, output, indent=4)
comms.sendString(conn, "Message Published!\r\nPress any key to go back... ")
comms.getChar(conn)
menus.printMenu(conn, lastMenu, node, userID)

View File

@ -34,6 +34,7 @@ def parseResponse(conn, menu, node, user, response):
comms.sendString(conn, "\u001B[2J\r")
if response.strip('\x00') == "X":
comms.sendString(conn, "Goodbye!")
conn.close()
if response.strip('\x00') == "P":
functions.printProfile(conn, user, node, menu)

18
messages.json Normal file
View File

@ -0,0 +1,18 @@
{
"messages": [
{
"id": 0,
"author": "Default",
"subject": "Welcome!",
"body": "This is the first message in every PyScii BBS. It sets up the messages json.",
"date": "1970-01-01 00:00:00"
},
{
"id": 1,
"date": "2025-07-19 HH:MM:SS",
"subject": "\u0000First User Message",
"author": "J4YC33",
"body": "\u0000This is the first messsage on the Pyscii BBS!\\nIt's a fun thing!"
}
]
}

View File

@ -12,7 +12,7 @@
"name": "J4YC33",
"password": "d32190c6322e27087c934b7bd9ff642bbe71d5782f2242028c3c15298c7aeac6",
"salt": "SI13YMJl8kWLBhNN",
"description": "J4YC33 IS SPARTACUS!"
"description": "\u0000I *AM* Spartacus!"
}
]
}
}