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:
parent
b6b67576c1
commit
6577e6b051
3
bbs.py
3
bbs.py
@ -42,8 +42,7 @@ class bbsServer():
|
|||||||
try:
|
try:
|
||||||
comms(conn, addr, node + 1)
|
comms(conn, addr, node + 1)
|
||||||
|
|
||||||
|
except (RuntimeError, OSError):
|
||||||
except RuntimeError:
|
|
||||||
print("Node %s hung up..." % (node + 1))
|
print("Node %s hung up..." % (node + 1))
|
||||||
|
|
||||||
print("Node %s offline." % (node + 1))
|
print("Node %s offline." % (node + 1))
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
[Main]
|
[Main]
|
||||||
Port = 2043
|
Port = 2062
|
||||||
DefaultSplash = "Welcome to the SB17 BBS on %node%!"
|
DefaultSplash = "Welcome to the SB17 BBS on %node%!"
|
||||||
MaxConnections = 5
|
MaxConnections = 5
|
||||||
Menus = 2
|
Menus = 2
|
||||||
|
msgDb = messages.json
|
||||||
|
|
||||||
[Auth]
|
[Auth]
|
||||||
userDb = users.json
|
userDb = users.json
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
# Configuration
|
# 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.
|
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
|
## String Replacements
|
||||||
|
@ -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 can show a menu to the user after logging in ✓
|
||||||
- BBS Server menu allows user to modify their own profile ✓
|
- BBS Server menu allows user to modify their own profile ✓
|
||||||
- BBS Server can display pre-coded messages in a messages space ✓
|
- 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
|
#### 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)
|
- 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.
|
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
31
docs/message.schema.json
Normal 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"
|
||||||
|
]
|
||||||
|
}
|
66
functions.py
66
functions.py
@ -4,11 +4,15 @@ import sys
|
|||||||
import comms
|
import comms
|
||||||
import menus
|
import menus
|
||||||
import auth
|
import auth
|
||||||
|
import datetime
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read(sys.argv[1])
|
config.read(sys.argv[1])
|
||||||
|
|
||||||
userDb = config.get("Auth","userDb")
|
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):
|
def printProfile(conn, userId, node, lastMenu):
|
||||||
comms.sendString(conn, "\u001B[2JProfile:\r\n")
|
comms.sendString(conn, "\u001B[2JProfile:\r\n")
|
||||||
@ -50,8 +54,66 @@ def editProfile(conn, userID, node, lastMenu):
|
|||||||
menus.printMenu(conn, lastMenu, node, userID)
|
menus.printMenu(conn, lastMenu, node, userID)
|
||||||
|
|
||||||
def pubMessages(conn, userID, node, lastMenu):
|
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)
|
comms.getChar(conn)
|
||||||
menus.printMenu(conn, lastMenu, node, userID)
|
|
||||||
|
|
||||||
|
|
||||||
|
1
menus.py
1
menus.py
@ -34,6 +34,7 @@ def parseResponse(conn, menu, node, user, response):
|
|||||||
comms.sendString(conn, "\u001B[2J\r")
|
comms.sendString(conn, "\u001B[2J\r")
|
||||||
if response.strip('\x00') == "X":
|
if response.strip('\x00') == "X":
|
||||||
comms.sendString(conn, "Goodbye!")
|
comms.sendString(conn, "Goodbye!")
|
||||||
|
conn.close()
|
||||||
|
|
||||||
if response.strip('\x00') == "P":
|
if response.strip('\x00') == "P":
|
||||||
functions.printProfile(conn, user, node, menu)
|
functions.printProfile(conn, user, node, menu)
|
||||||
|
18
messages.json
Normal file
18
messages.json
Normal 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!"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -12,7 +12,7 @@
|
|||||||
"name": "J4YC33",
|
"name": "J4YC33",
|
||||||
"password": "d32190c6322e27087c934b7bd9ff642bbe71d5782f2242028c3c15298c7aeac6",
|
"password": "d32190c6322e27087c934b7bd9ff642bbe71d5782f2242028c3c15298c7aeac6",
|
||||||
"salt": "SI13YMJl8kWLBhNN",
|
"salt": "SI13YMJl8kWLBhNN",
|
||||||
"description": "J4YC33 IS SPARTACUS!"
|
"description": "\u0000I *AM* Spartacus!"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user