From 37fc4bffa5c992bb09764540ee49142e67231a28 Mon Sep 17 00:00:00 2001 From: ingalls Date: Thu, 31 Oct 2024 15:13:12 -0600 Subject: [PATCH] PATCH update calls to Media Server --- api/lib/api/mission.ts | 2 +- api/lib/control/video-service.ts | 59 ++++++++++++++++++++++++++++++-- api/routes/video-lease.ts | 21 +++--------- 3 files changed, 62 insertions(+), 20 deletions(-) diff --git a/api/lib/api/mission.ts b/api/lib/api/mission.ts index 57c630038..4025c5ef9 100644 --- a/api/lib/api/mission.ts +++ b/api/lib/api/mission.ts @@ -384,7 +384,7 @@ export default class { async subscriptionRoles( name: string, opts?: Static - ): Promise>>> { + ): Promise>> { const url = this.#isGUID(name) ? new URL(`/Marti/api/missions/guid/${encodeURIComponent(name)}/subscriptions/roles`, this.api.url) : new URL(`/Marti/api/missions/${this.#encodeName(name)}/subscriptions/roles`, this.api.url); diff --git a/api/lib/control/video-service.ts b/api/lib/control/video-service.ts index 2b48c2c05..738a9cb8b 100644 --- a/api/lib/control/video-service.ts +++ b/api/lib/control/video-service.ts @@ -2,6 +2,7 @@ import Err from '@openaddresses/batch-error'; import Config from '../config.js'; import { Type, Static } from '@sinclair/typebox'; import { VideoLeaseResponse } from '../types.js'; +import moment from 'moment'; import fetch from '../fetch.js'; export const Protocols = Type.Object({ @@ -279,7 +280,6 @@ export default class VideoServiceControl { proxy?: string; }): Promise> { const video = await this.settings(); - if (!video.configured) throw new Err(400, null, 'Media Integration is not configured'); const headers = this.headers(video.username, video.password); @@ -349,6 +349,57 @@ export default class VideoServiceControl { return lease; } + async commit(leaseid: string, body: { name?: string, duration?: number }, opts: { + username: string; + admin: boolean; + }): Promise> { + const video = await this.settings(); + if (!video.configured) throw new Err(400, null, 'Media Integration is not configured'); + + let lease = await this.config.models.VideoLease.from(leaseid); + + if (opts.admin) { + lease = await this.config.models.VideoLease.commit(leaseid, { + ...body, + expiration: body.duration ? moment().add(body.duration, 'seconds').toISOString() : lease.expiration, + }); + } else if (lease.username === opts.username) { + lease = await this.config.models.VideoLease.commit(leaseid, { + ...body, + expiration: body.duration ? moment().add(body.duration, 'seconds').toISOString() : lease.expiration, + }); + } else { + throw new Err(400, null, 'You can only update a lease you created'); + } + + try { + await this.path(lease.path); + } catch (err) { + if (err instanceof Err && err.status === 404) { + const url = new URL(`/v3/config/paths/add/${lease.path}`, video.url); + url.port = '9997'; + + const headers = this.headers(video.username, video.password); + headers.append('Content-Type', 'application/json'); + + const res = await fetch(url, { + method: 'POST', + headers, + body: JSON.stringify({ + name: lease.path + }), + }) + + if (!res.ok) throw new Err(500, null, await res.text()) + } else { + throw err; + } + } + + + return lease; + } + async path(pathid: string): Promise> { const video = await this.settings(); if (!video.configured) throw new Err(400, null, 'Media Integration is not configured'); @@ -363,7 +414,11 @@ export default class VideoServiceControl { headers, }); - return await res.typed(PathConfig); + if (res.ok) { + return await res.typed(PathConfig); + } else { + throw new Err(res.status, new Error(await res.text()), 'Media Server Error'); + } } async delete(leaseid: string): Promise { diff --git a/api/routes/video-lease.ts b/api/routes/video-lease.ts index e5850c404..c4df4bdb1 100644 --- a/api/routes/video-lease.ts +++ b/api/routes/video-lease.ts @@ -165,23 +165,10 @@ export default async function router(schema: Schema, config: Config) { throw new Err(400, null, 'Only Administrators can request a lease > 16 hours') } - let lease = await config.models.VideoLease.from(req.params.lease); - - if (user.access === AuthUserAccess.ADMIN) { - lease = await config.models.VideoLease.commit(req.params.lease, { - ...req.body, - expiration: req.body.duration ? moment().add(req.body.duration, 'seconds').toISOString() : lease.expiration, - }); - } else { - if (lease.username === user.email) { - lease = await config.models.VideoLease.commit(req.params.lease, { - ...req.body, - expiration: req.body.duration ? moment().add(req.body.duration, 'seconds').toISOString() : lease.expiration, - }); - } else { - throw new Err(400, null, 'You can only update a lease you created'); - } - } + const lease = await videoControl.commit(req.params.lease, req.body, { + username: user.email, + admin: user.access === AuthUserAccess.ADMIN + }); res.json({ lease,