Skip to content

Commit

Permalink
Merge pull request #347 from dfpc-coe/video-api
Browse files Browse the repository at this point in the history
Video API & Skittle Course
  • Loading branch information
ingalls authored Sep 25, 2024
2 parents d470ea9 + 5fb74e7 commit 0b6a0ef
Show file tree
Hide file tree
Showing 15 changed files with 635 additions and 440 deletions.
Binary file added api/icons/custom/course.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion api/icons/generator.json

Large diffs are not rendered by default.

Binary file modified api/icons/generator.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion api/icons/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ for (const icon of xmljs.xml2js(String(await fs.readFile(new URL('../icons/icons
file: path.parse(icon.filePath._text).base,
parent: icon.parentID._text,
data: img.toString('base64'),
children: (icon.childrenIDs && Array.isArray(icon.childrenIDs.id)) ? icon.childrenIDs.id.map((id) => {
children: (icon.childrenIDs && Array.isArray(icon.childrenIDs.id)) ? icon.childrenIDs.id.map((id: { _text: string }) => {
return id._text;
}) : []
};
Expand Down
72 changes: 72 additions & 0 deletions api/lib/api/video.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { Static, Type } from '@sinclair/typebox';
import TAKAPI from '../tak-api.js';

export const Feed = Type.Object({
uuid: Type.String(),
active: Type.Boolean(),
alias: Type.String(),
url: Type.String(),

order: Type.Union([Type.Integer(), Type.Null()]),
macAddress: Type.String(),
roverPort: Type.String(),
ignoreEmbeddedKLV: Type.String(),
source: Type.Union([Type.String(), Type.Null()]),
networkTimeout: Type.String(),
bufferTime: Type.String(),
rtspReliable: Type.String(),
thumbnail: Type.Union([Type.String(), Type.Null()]),
classification: Type.Union([Type.String(), Type.Null()]),
latitude: Type.Union([Type.String(), Type.Null()]),
longitude: Type.Union([Type.String(), Type.Null()]),
fov: Type.Union([Type.String(), Type.Null()]),
heading: Type.Union([Type.String(), Type.Null()]),
range: Type.Union([Type.String(), Type.Null()]),
width: Type.Union([Type.Integer(), Type.Null()]),
height: Type.Union([Type.Integer(), Type.Null()]),
bitrate: Type.Union([Type.Integer(), Type.Null()]),
});

export const Video = Type.Object({
uuid: Type.String(),
active: Type.Boolean(),
alias: Type.String(),
thumbnail: Type.Union([Type.String(), Type.Null()]),
classification: Type.Union([Type.String(), Type.Null()]),
feeds: Type.Array(Feed)
})

export const VideoList = Type.Object({
videoConnections: Type.Array(Video)
});

export const VideoListInput = Type.Object({
protocol: Type.Optional(Type.String())
})

export default class {
api: TAKAPI;

constructor(api: TAKAPI) {
this.api = api;
}

async list(
query: Static<typeof VideoListInput> = {}
): Promise<Static<typeof VideoList>> {
const url = new URL(`/Marti/api/video`, this.api.url);

let q: keyof Static<typeof VideoListInput>;
for (q in query) {
if (query[q] !== undefined) {
url.searchParams.append(q, String(query[q]));
}
}

const res = await this.api.fetch(url, {
method: 'GET'
});

return await res.typed(VideoList);
}
}
1 change: 1 addition & 0 deletions api/lib/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Err from '@openaddresses/batch-error';
handlebars.registerHelper('fallback', (...params: Array<unknown>) => {
params.pop(); // Contains Config stuff from handlebars
const found = params.find(el => !!el)
return found;
})

interface ValidateStyle {
Expand Down
3 changes: 3 additions & 0 deletions api/lib/tak-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Credentials from './api/credentials.js';
import Contacts from './api/contacts.js';
import Files from './api/files.js';
import Group from './api/groups.js';
import Video from './api/video.js';
import Export from './api/export.js';
import Err from '@openaddresses/batch-error';
import * as auth from './tak-auth.js';
Expand All @@ -28,6 +29,7 @@ export default class TAKAPI {
Credentials: Credentials;
Contacts: Contacts;
Group: Group;
Video: Video;
Export: Export;
Files: Files;

Expand All @@ -44,6 +46,7 @@ export default class TAKAPI {
this.Credentials = new Credentials(this);
this.Contacts = new Contacts(this);
this.Group = new Group(this);
this.Video = new Video(this);
this.Files = new Files(this);
}

Expand Down
354 changes: 177 additions & 177 deletions api/package-lock.json

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions api/routes/marti-video.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Type } from '@sinclair/typebox'
import Schema from '@openaddresses/batch-schema';
import Err from '@openaddresses/batch-error';
import Auth from '../lib/auth.js';
import Config from '../lib/config.js';
import {
VideoList,
VideoListInput,
} from '../lib/api/video.js';
import TAKAPI, {
APIAuthCertificate,
} from '../lib/tak-api.js';

export default async function router(schema: Schema, config: Config) {
await schema.get('/marti/video', {
name: 'List Video',
group: 'MartiVideos',
params: Type.Object({
name: Type.String(),
}),
description: 'Helper API to get list video streams',
query: VideoListInput,
res: VideoList
}, async (req, res) => {
try {
const user = await Auth.as_user(config, req);
const auth = (await config.models.Profile.from(user.email)).auth;
const api = await TAKAPI.init(new URL(String(config.server.api)), new APIAuthCertificate(auth.cert, auth.key));

const list = await api.Video.list(req.query);

return res.json(list);
} catch (err) {
return Err.respond(err, res);
}
});
}
Loading

0 comments on commit 0b6a0ef

Please sign in to comment.