Skip to content

Commit

Permalink
Merge pull request elan-ev#1077 from LukasKalbertodt/include-recordin…
Browse files Browse the repository at this point in the history
…g-period

Include recording start & end time in `dcterms:Period` metadata
  • Loading branch information
LukasKalbertodt authored Sep 11, 2023
2 parents 4755f50 + 3985a17 commit 3621089
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 11 deletions.
25 changes: 20 additions & 5 deletions src/opencast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -347,12 +347,16 @@ export class Opencast {
* At the start of this method, `refreshConnection` is called. That
* potentially changed the `state`.
*/
async upload({ recordings, title, presenter, start, end, uploadSettings, onProgress }: {
async upload({
recordings, title, presenter, start, end, uploadSettings, startTime, endTime, onProgress,
}: {
recordings: Recording[];
title: string;
presenter: string;
start: number | null;
end: number | null;
startTime: Date;
endTime: Date;
uploadSettings: Settings["upload"];
onProgress: (p: number) => void;
}): Promise<UploadState> {
Expand All @@ -379,7 +383,9 @@ export class Opencast {
.then(response => response.text());

// Add metadata to media package
mediaPackage = await this.addDcCatalog({ mediaPackage, uploadSettings, title, presenter });
mediaPackage = await this.addDcCatalog(
{ mediaPackage, uploadSettings, title, presenter, startTime, endTime }
);

// Set appropriate ACL unless the configuration says no.
if (uploadSettings?.acl !== false) {
Expand Down Expand Up @@ -434,15 +440,17 @@ export class Opencast {
* Adds the DC Catalog with the given metadata to the current ingest process
* via `ingest/addDCCatalog`. Do not call this method outside of `upload`!
*/
async addDcCatalog({ mediaPackage, title, presenter, uploadSettings }: {
async addDcCatalog({ mediaPackage, uploadSettings, ...rest }: {
mediaPackage: string;
title: string;
presenter: string;
uploadSettings: Settings["upload"];
startTime: Date;
endTime: Date;
}) {
const seriesId = uploadSettings?.seriesId;
const template = uploadSettings?.dcc || DEFAULT_DCC_TEMPLATE;
const dcc = this.constructDcc(template, { presenter, title, seriesId });
const dcc = this.constructDcc(template, { ...rest, seriesId });

const body = new FormData();
body.append("mediaPackage", mediaPackage);
Expand Down Expand Up @@ -634,9 +642,11 @@ export class Opencast {
return renderTemplate(template, view);
}

constructDcc(template: string, { title, presenter, seriesId }: {
constructDcc(template: string, { title, presenter, startTime, endTime, seriesId }: {
title: string;
presenter: string;
startTime: Date;
endTime: Date;
seriesId?: string;
}) {
// Prepare template "view": the values that can be used within the template.
Expand All @@ -647,6 +657,8 @@ export class Opencast {
presenter,
seriesId,
now: new Date().toISOString(),
startTime: startTime.toISOString(),
endTime: endTime.toISOString(),
};

return renderTemplate(template, view);
Expand Down Expand Up @@ -762,6 +774,9 @@ const DEFAULT_DCC_TEMPLATE = `<?xml version="1.0" encoding="UTF-8"?>
<dcterms:title>{{ title }}</dcterms:title>
{{ #presenter }}<dcterms:creator>{{ presenter }}</dcterms:creator>{{ /presenter }}
{{ #seriesId }}<dcterms:isPartOf>{{ seriesId }}</dcterms:isPartOf>{{ /seriesId }}
<dcterms:temporal xsi:type="dcterms:Period">
start={{ startTime }}; end={{ endTime }}; scheme=W3CDTF;
</dcterms:temporal>
<dcterms:spatial>Opencast Studio</dcterms:spatial>
</dublincore>
`;
Expand Down
8 changes: 5 additions & 3 deletions src/steps/finish/upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const UploadBox: React.FC = () => {
const settings = useSettings();
const { t } = useTranslation();
const opencast = useOpencast();
const { recordings, upload: uploadState, title, presenter, start, end } = useStudioState();
const { recordings, upload: uploadState, title, presenter, ...state } = useStudioState();
const dispatch = useDispatch();

function onProgress(progress: number) {
Expand Down Expand Up @@ -108,10 +108,12 @@ export const UploadBox: React.FC = () => {
recordings: recordings.filter(Boolean),
title,
presenter,
start,
end,
uploadSettings: settings.upload,
onProgress,
start: state.start,
end: state.end,
startTime: state.recordingStartTime ?? unreachable("no start time set"),
endTime: state.recordingEndTime ?? unreachable("no end time set"),
});
progressHistory = [];

Expand Down
17 changes: 14 additions & 3 deletions src/studio-state.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export type StudioState = {
start: null | number;
end: null | number;

recordingStartTime: null | Date;
recordingEndTime: null | Date;

upload: {
error: null | string;
state: UploadState;
Expand Down Expand Up @@ -90,6 +93,9 @@ const initialState = (hasWebcam: boolean): StudioState => ({
start: null,
end: null,

recordingStartTime: null,
recordingEndTime: null,

upload: {
error: null,
state: "not_uploaded",
Expand Down Expand Up @@ -171,10 +177,15 @@ const reducer = (state: StudioState, action: ReducerAction): StudioState => {
case "USER_UNEXPETED_END":
return { ...state, userStream: null, userUnexpectedEnd: true };

case "START_RECORDING": return { ...state, isRecording: true };
case "STOP_RECORDING": return { ...state, isRecording: false };
case "START_RECORDING": return { ...state, isRecording: true, recordingStartTime: new Date() };
case "STOP_RECORDING": return { ...state, isRecording: false, recordingEndTime: new Date() };
case "STOP_RECORDING_PREMATURELY":
return { ...state, isRecording: false, prematureRecordingEnd: true };
return {
...state,
isRecording: false,
prematureRecordingEnd: true,
recordingEndTime: new Date(),
};
case "CLEAR_RECORDINGS":
return { ...state, recordings: [], prematureRecordingEnd: false };
case "ADD_RECORDING":
Expand Down

0 comments on commit 3621089

Please sign in to comment.