Updates to jobs and users client and server apis.

This commit is contained in:
Michael Woods
2025-02-17 17:42:33 -05:00
parent 7832792aa6
commit cff2a22078
5 changed files with 121 additions and 6 deletions

View File

@@ -125,6 +125,9 @@ def get_job_id(client: Client, bbs_callsign: str, job_id: int, get_data=True) ->
raise RuntimeError(f"Sending job failed: {response.status_code}: {response.payload}") raise RuntimeError(f"Sending job failed: {response.status_code}: {response.payload}")
return JobWrapper(response.payload) return JobWrapper(response.payload)
def get_user_jobs(): # TODO
pass
class JobSession: class JobSession:
def __init__(self, client: Client, bbs_callsign: str, default_timeout: int = 300, stutter: int = 2): def __init__(self, client: Client, bbs_callsign: str, default_timeout: int = 300, stutter: int = 2):
self.client = client self.client = client

View File

@@ -3,6 +3,7 @@ import datetime
from packetserver.client import Client from packetserver.client import Client
from packetserver.common import Request, Response, PacketServerConnection from packetserver.common import Request, Response, PacketServerConnection
from typing import Union, Optional from typing import Union, Optional
from packetserver.common.util import email_valid, random_string
from uuid import UUID, uuid4 from uuid import UUID, uuid4
import os.path import os.path
@@ -76,3 +77,34 @@ def get_users(client: Client, bbs_callsign: str, limit=None):
for u in response.payload: for u in response.payload:
user_list.append(UserWrapper(u)) user_list.append(UserWrapper(u))
return user_list return user_list
def update_self(client: Client, bbs_callsign: str, email: str = None, bio: str = None,
socials: Union[list[str],str] = None, location: str = None, status: str = None) -> bool:
payload = {}
if email is not None:
if not email_valid(email):
raise ValueError(f"{email} is not a valid e-mail address")
payload['email'] = email
if socials is not None:
payload['social'] = socials
if status is not None:
payload['status'] = str(status)
if location is not None:
payload['location'] = str(location)
if bio is not None:
payload['bio'] = str(bio)
req = Request.blank()
req.path = "user"
req.method = Request.Method.UPDATE
req.payload = payload
response = client.send_receive_callsign(req, bbs_callsign)
if response.status_code != 200:
raise RuntimeError(f"GET user {username} failed: {response.status_code}: {response.payload}")
return True

View File

@@ -336,7 +336,7 @@ def send_response(conn: PacketServerConnection, response: Response, original_req
logging.warning(f"Attempted to send data, but connection state is {conn.state.name}") logging.warning(f"Attempted to send data, but connection state is {conn.state.name}")
def send_blank_response(conn: PacketServerConnection, original_request: Request, status_code: int = 200, def send_blank_response(conn: PacketServerConnection, original_request: Request, status_code: int = 200,
payload: Union[bytes, bytearray, str, dict] = ""): payload: Union[bytes, bytearray, str, dict, list] = ""):
response = Response.blank() response = Response.blank()
response.status_code = status_code response.status_code = status_code
response.payload = payload response.payload = payload

View File

@@ -248,8 +248,26 @@ def handle_job_get_id(req: Request, conn: PacketServerConnection, db: ZODB.DB, j
def handle_job_get_user(req: Request, conn: PacketServerConnection, db: ZODB.DB): def handle_job_get_user(req: Request, conn: PacketServerConnection, db: ZODB.DB):
username = ax25.Address(conn.remote_callsign).call.upper().strip() username = ax25.Address(conn.remote_callsign).call.upper().strip()
# TODO finish user job lookup jobs = []
send_blank_response(conn, req, 404) value = "y"
include_data = True
for key in req.vars:
if key.lower().strip() == "data":
value = req.vars[key].lower().strip()
if value in no_values:
include_data = False
id_only = False
if 'id_only' in req.vars:
if req.vars['id_only'] in yes_values:
id_only = True
with db.transaction() as storage:
for jid in storage.root()['user_jobs'][username]:
jobs.append(Job.get_job_by_id(jid, storage.root()).to_dict(include_data=include_data))
if id_only:
send_blank_response(conn, req, status_code=200, payload=[x['id'] for x in jobs])
else:
send_blank_response(conn, req, status_code=200, payload=jobs)
def handle_job_get(req: Request, conn: PacketServerConnection, db: ZODB.DB): def handle_job_get(req: Request, conn: PacketServerConnection, db: ZODB.DB):
spl = [x for x in req.path.split("/") if x.strip() != ""] spl = [x for x in req.path.split("/") if x.strip() != ""]

View File

@@ -11,6 +11,7 @@ from packetserver.common import PacketServerConnection, Request, Response, Messa
import ZODB import ZODB
import logging import logging
import uuid import uuid
from traceback import format_exc
from uuid import UUID from uuid import UUID
from packetserver.common.util import email_valid from packetserver.common.util import email_valid
from BTrees.OOBTree import TreeSet from BTrees.OOBTree import TreeSet
@@ -243,8 +244,67 @@ def handle_user_get(req: Request, conn: PacketServerConnection, db: ZODB.DB):
response.payload = [x.to_safe_dict() for x in User.get_all_users(db.root(), limit=limit) if not x.hidden] response.payload = [x.to_safe_dict() for x in User.get_all_users(db.root(), limit=limit) if not x.hidden]
send_response(conn, response, req) send_response(conn, response, req)
def handle_user_update(req: Request, conn: PacketServerConnection, db: ZODB.DB): # TODO def handle_user_update(req: Request, conn: PacketServerConnection, db: ZODB.DB):
pass """
"status": str 300 cutoff
"bio": str 4k cutoff
"socials": list[str] each 300 cutoff
"email": str (must be an e-mail) validate with valid_email function from util
"location": str 1000 char cutoff
"""
username = ax25.Address(conn.remote_callsign).call.upper().strip()
logging.debug(f"Handling user update request for {username}: {req.payload}")
email = None
bio = None
socials = None
location = None
status = None
# set vars
if 'bio' in req.payload:
bio = str(req.payload['bio'])
if 'location' in req.payload:
location = str(req.payload['location'])
if 'status' in req.payload:
status = str(req.payload['stus'])
if 'email' in req.payload:
email = req.payload['email']
if not email_valid(email):
send_blank_response(conn, req, status_code=400, payload="email must be valid format")
return
if 'socials' in req.payload:
var_socials = req.payload['socials']
socials = []
if type(var_socials) is list:
for s in var_socials:
socials.append(str(s))
else:
socials.append(str(var_socials))
try:
with db.transaction() as db:
user = User.get_user_by_username(username, db.root())
if email is not None:
user.email = email
if bio is not None:
user.bio = bio
if socials is not None:
user.socials = socials
if location is not None:
user.location = location
if status is not None:
user.status = status
except:
logging.error(f"Error while updating user {username}:\n{format_exc()}")
send_blank_response(conn, req, status_code=500)
return
send_blank_response(conn, req, status_code=200)
def user_root_handler(req: Request, conn: PacketServerConnection, db: ZODB.DB): def user_root_handler(req: Request, conn: PacketServerConnection, db: ZODB.DB):
logging.debug(f"{req} being processed by user_root_handler") logging.debug(f"{req} being processed by user_root_handler")
@@ -255,5 +315,7 @@ def user_root_handler(req: Request, conn: PacketServerConnection, db: ZODB.DB):
logging.debug("user is authorized") logging.debug("user is authorized")
if req.method is Request.Method.GET: if req.method is Request.Method.GET:
handle_user_get(req, conn, db) handle_user_get(req, conn, db)
elif req.method is Request.Method.UPDATE:
handle_user_update(req, conn ,db)
else: else:
send_blank_response(conn, req, status_code=404) send_blank_response(conn, req, status_code=404)