cli client can now send messages.

This commit is contained in:
Michael Woods
2025-03-17 23:48:29 -04:00
parent 6d25551847
commit ec983c4613
6 changed files with 102 additions and 8 deletions

View File

@@ -14,7 +14,8 @@ def all_done():
storage.close() storage.close()
#port = int(sys.argv[1]) #port = int(sys.argv[1])
storage = ZODB.FileStorage.FileStorage('/home/alienhunter/.packetserver/data.zopedb') storage = ZODB.FileStorage.FileStorage('/tmp/tmp_ps_data/data.zopedb')
#storage = ZODB.FileStorage.FileStorage('/home/alienhunter/.packetserver/data.zopedb')
#db = ZEO.DB(('127.0.0.1',port)) #db = ZEO.DB(('127.0.0.1',port))
db = ZODB.DB(storage) db = ZODB.DB(storage)
c = db.open() c = db.open()

View File

@@ -7,6 +7,7 @@ from packetserver.common import Request, Response
from packetserver.client.cli.util import format_list_dicts, exit_client from packetserver.client.cli.util import format_list_dicts, exit_client
from packetserver.client.cli.job import job from packetserver.client.cli.job import job
from packetserver.client.cli.object import objects from packetserver.client.cli.object import objects
from packetserver.client.cli.message import message
import ZODB import ZODB
import ZODB.FileStorage import ZODB.FileStorage
import ax25 import ax25
@@ -184,6 +185,7 @@ cli.add_command(query_server)
cli.add_command(job, name='job') cli.add_command(job, name='job')
cli.add_command(objects, name='object') cli.add_command(objects, name='object')
cli.add_command(set_user, name='set') cli.add_command(set_user, name='set')
cli.add_command(message)
if __name__ == '__main__': if __name__ == '__main__':
cli() cli()

View File

@@ -0,0 +1,87 @@
import os
import sys
import os.path
from email.policy import default
import click
from packetserver.client.cli.util import exit_client, format_list_dicts
from copy import deepcopy
from uuid import UUID
from packetserver.client.messages import *
@click.group()
@click.pass_context
def message(ctx):
"""Send, search, and filter messages to and from other users on the BBS system."""
pass
@click.command()
@click.argument("recipients", type=str)
@click.argument("body", type=str)
@click.option("--body-filename", '-f', is_flag=True, default=False, help="Treat body argument as a filename to read body text from. '-' to read from stdin.")
@click.option("--attachment", "-A", multiple=True, default=[],
help="Files to attach to message in form '[<t|b>:]<filename>' use 't' for text (default), 'b' to interpret file as binary data.")
@click.pass_context
def send(ctx, recipients, body, body_filename, attachment):
"""Send a message to one or more recipients.
<recipients> should be a comma-separated list of recipients to send the message to
<body> should be either body text, or a filename (or '-' for stdin) to read body text from
"""
client = ctx.obj['client']
bbs = ctx.obj['bbs']
recips = [x.strip() for x in recipients.split(",") if x.strip() != ""]
if len(recips) == 0:
click.echo("You must specify at least one recipient.", err=True)
exit_client(ctx.obj, 89)
attachments = []
for a in attachment:
is_text = True
filename = a
if len(a) > 1:
if a[1] == ":":
filename = a[2:]
if a[0].lower() == "b":
is_text = False
try:
attachments.append(attachment_from_file(filename, binary=not is_text))
except Exception as e:
click.echo(str(e), err=True)
exit_client(ctx.obj, 89)
if len(attachments) == 0:
attachments = None
if body_filename:
if body == "-":
body_text = sys.stdin.read()
else:
if not os.path.isfile(body):
click.echo(f"{body} is not a file that can be read for body text.", err=True)
exit_client(ctx.obj, 92)
sys.exit(92)
try:
body_text = open(body, "r").read()
except:
click.echo(f"{body} is not a file that can be read for body text.", err=True)
exit_client(ctx.obj, 92)
sys.exit(92)
else:
body_text = body
try:
resp = send_message(client, bbs, body_text, recips, attachments=attachments)
click.echo(f"Message received by server: {resp}")
exit_client(ctx.obj, 0)
except Exception as e:
click.echo(f"Error sending message: {str(e)}", err=True)
exit_client(ctx.obj, 53)
message.add_command(send)

View File

@@ -100,6 +100,7 @@ def send_message(client: Client, bbs_callsign: str, text: str, to: list[str],
"to": to, "to": to,
"attachments": [] "attachments": []
} }
if attachments is not None:
for a in attachments: for a in attachments:
payload["attachments"].append(a.to_dict()) payload["attachments"].append(a.to_dict())

View File

@@ -118,5 +118,5 @@ def update_self(client: Client, bbs_callsign: str, email: str = None, bio: str =
req.payload = payload req.payload = payload
response = client.send_receive_callsign(req, bbs_callsign) response = client.send_receive_callsign(req, bbs_callsign)
if response.status_code != 200: if response.status_code != 200:
raise RuntimeError(f"GET user {username} failed: {response.status_code}: {response.payload}") raise RuntimeError(f"Updating profile failed: {response.status_code}: {response.payload}")
return True return True

View File

@@ -234,6 +234,7 @@ class Message(persistent.Persistent):
send_counter = send_counter + 1 send_counter = send_counter + 1
for recipient in recipients: for recipient in recipients:
msg = Message(self.text, recipient, self.msg_from, attachments=[x.copy() for x in new_attachments]) msg = Message(self.text, recipient, self.msg_from, attachments=[x.copy() for x in new_attachments])
msg.msg_id = self.msg_id
try: try:
mailbox_create(recipient, db.root()) mailbox_create(recipient, db.root())
msg.msg_delivered = True msg.msg_delivered = True
@@ -246,7 +247,9 @@ class Message(persistent.Persistent):
logging.error(f"Error sending message to {recipient}:\n{format_exc()}") logging.error(f"Error sending message to {recipient}:\n{format_exc()}")
failed.append(recipient) failed.append(recipient)
self.msg_delivered = True self.msg_delivered = True
self.attachments = [x.copy() for x in new_attachments] msg = Message(self.text, recipient, self.msg_from, attachments=[x.copy() for x in new_attachments])
msg.msg_id = self.msg_id
msg.msg_to = self.msg_to
db.root.messages[self.msg_from.upper().strip()].append(msg) db.root.messages[self.msg_from.upper().strip()].append(msg)
return send_counter, failed, self.msg_id return send_counter, failed, self.msg_id
@@ -451,7 +454,7 @@ def handle_message_post(req: Request, conn: PacketServerConnection, db: ZODB.DB)
send_blank_response(conn, req, status_code=201, payload={ send_blank_response(conn, req, status_code=201, payload={
"successes": send_counter, "successes": send_counter,
"failed": failed, "failed": failed,
'msg_id': msg_id}) 'msg_id': str(msg_id)})
def message_root_handler(req: Request, conn: PacketServerConnection, db: ZODB.DB): def message_root_handler(req: Request, conn: PacketServerConnection, db: ZODB.DB):
logging.debug(f"{req} being processed by message_root_handler") logging.debug(f"{req} being processed by message_root_handler")