mirror of
https://github.com/kokonect-link/cherrypick
synced 2024-12-05 10:18:38 +09:00
Add Event schema to metadata
- add types from https://schema.org/Event - updated MkEvent to display new fields - minor refactoring
This commit is contained in:
parent
5abbcf6cd4
commit
b7c7e4d32d
@ -3,13 +3,13 @@ import { DI } from '@/di-symbols.js';
|
||||
import type { EventsRepository, NotesRepository } from '@/models/index.js';
|
||||
import type { Config } from '@/config.js';
|
||||
import type Logger from '@/logger.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IEvent } from '@/models/entities/Event.js';
|
||||
import { isEvent } from '../type.js';
|
||||
import { ApLoggerService } from '../ApLoggerService.js';
|
||||
import { ApResolverService } from '../ApResolverService.js';
|
||||
import type { Resolver } from '../ApResolverService.js';
|
||||
import type { IObject } from '../type.js';
|
||||
import { bindThis } from '@/decorators.js';
|
||||
import { IEvent } from '@/models/entities/Event.js';
|
||||
|
||||
@Injectable()
|
||||
export class ApEventService {
|
||||
@ -32,8 +32,8 @@ export class ApEventService {
|
||||
}
|
||||
|
||||
@bindThis
|
||||
public async extractEventFromNote(source: string | IObject, resolver?: Resolver): Promise<IEvent> {
|
||||
if (resolver == null) resolver = this.apResolverService.createResolver();
|
||||
public async extractEventFromNote(source: string | IObject, resolverParam?: Resolver): Promise<IEvent> {
|
||||
const resolver = resolverParam ?? this.apResolverService.createResolver();
|
||||
|
||||
const note = await resolver.resolve(source);
|
||||
|
||||
|
@ -35,13 +35,13 @@ export class Event {
|
||||
public title: string;
|
||||
|
||||
@Column('jsonb', {
|
||||
default: {
|
||||
default: {
|
||||
'@context': 'https://schema.org/',
|
||||
'@type': 'Event',
|
||||
},
|
||||
comment: 'metadata object describing the event. Follows https://schema.org/Event',
|
||||
})
|
||||
public metadata: unknown;
|
||||
public metadata: EventSchema;
|
||||
|
||||
//#region Denormalized fields
|
||||
@Column('enum', {
|
||||
@ -74,9 +74,46 @@ export class Event {
|
||||
}
|
||||
}
|
||||
|
||||
export type EventSchema = {
|
||||
'@context': 'https://schema.org';
|
||||
'@type': 'Event';
|
||||
name?: string;
|
||||
url?: string;
|
||||
description?: string;
|
||||
audience?: {
|
||||
'@type': 'Audience';
|
||||
name: string;
|
||||
};
|
||||
doorTime?: string;
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
eventStatus?: 'https://schema.org/EventCancelled' | 'https://schema.org/EventMovedOnline' | 'https://schema.org/EventPostponed' | 'https://schema.org/EventRescheduled' | 'https://schema.org/EventScheduled';
|
||||
inLanguage?: string;
|
||||
isAccessibleForFree?: boolean;
|
||||
keywords?: string;
|
||||
location?: string;
|
||||
offers?: {
|
||||
'@type': 'Offer';
|
||||
price?: string;
|
||||
priceCurrency?: string;
|
||||
availabilityStarts?: string;
|
||||
availabilityEnds?: string;
|
||||
url?: string;
|
||||
};
|
||||
organizer?: {
|
||||
name: string;
|
||||
sameAs?: string; // ie. URL to website/social
|
||||
};
|
||||
performer?: {
|
||||
name: string;
|
||||
sameAs?: string; // ie. URL to website/social
|
||||
}[];
|
||||
typicalAgeRange?: string;
|
||||
}
|
||||
|
||||
export type IEvent = {
|
||||
start: Date;
|
||||
end: Date | null
|
||||
title: string;
|
||||
metadata: Record<string, string>;
|
||||
metadata: EventSchema;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ export const paramDef = {
|
||||
},
|
||||
} as const;
|
||||
|
||||
function notAlphaNumeric(s: string) {
|
||||
function notAlphaNumeric(s: string): boolean {
|
||||
return null !== s.match(/[^\w]/);
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,66 @@
|
||||
<MkTime :time="note.event!.end" mode="detail"/>
|
||||
</dd>
|
||||
</template>
|
||||
<template v-for="[key, value] of Object.entries(note.event!.detail)" :key="key">
|
||||
<dt :class="$style.key">{{ key }}</dt>
|
||||
<dd :class="$style.value">{{ value }}</dd>
|
||||
<template v-if="note.event!.metadata.doorTime">
|
||||
<dt :class="$style.key">{{ "Door Time" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.doorTime }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.location">
|
||||
<dt :class="$style.key">{{ "Location" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.location }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.url">
|
||||
<dt :class="$style.key">{{ "URL" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.url }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.organizer">
|
||||
<dt :class="$style.key">{{ "Organizer" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.organizer.name }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.audience">
|
||||
<dt :class="$style.key">{{ "Audience" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.audience.name }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.inLanguage">
|
||||
<dt :class="$style.key">{{ "Language" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.inLanguage }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.typicalAgeRange">
|
||||
<dt :class="$style.key">{{ "Ages" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.typicalAgeRange }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.performer">
|
||||
<dt :class="$style.key">{{ "Performers" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.performer.join(', ') }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.offers?.url">
|
||||
<dt :class="$style.key">{{ "Tickets" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.url }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.isAccessibleForFree">
|
||||
<dt :class="$style.key">{{ "Free" }}</dt>
|
||||
<dd :class="$style.value">{{ "Yes" }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.offers?.price">
|
||||
<dt :class="$style.key">{{ "Price" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.offers.price }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.offers?.url">
|
||||
<dt :class="$style.key">{{ "Tickets Available" }}</dt>
|
||||
<dd :class="$style.value">
|
||||
{{ [
|
||||
(note.event!.metadata.offers.availabilityStarts ? 'From ' + note.event!.metadata.offers.availabilityStarts : ''),
|
||||
(note.event!.metadata.offers.availabilityEnds ? 'Until ' + note.event!.metadata.offers.availabilityEnds : '')]
|
||||
.join(' ') }}
|
||||
</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.offers?.url">
|
||||
<dt :class="$style.key">{{ "Tickets" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.url }}</dd>
|
||||
</template>
|
||||
<template v-if="note.event!.metadata.keywords">
|
||||
<dt :class="$style.key">{{ "Keywords" }}</dt>
|
||||
<dd :class="$style.value">{{ note.event!.metadata.keywords }}</dd>
|
||||
</template>
|
||||
</dl>
|
||||
</div>
|
||||
|
@ -515,7 +515,7 @@ export type Endpoints = {
|
||||
sinceDate?: number;
|
||||
untilDate?: number;
|
||||
sortBy?: 'startDate' | 'craetedAt';
|
||||
filters?: { key: string, values: (string | null)[] }[];
|
||||
filters?: { key: string[], values: (string | null)[] }[];
|
||||
}; res: Note[]; };
|
||||
'notes/reactions': { req: { noteId: Note['id']; type?: string | null; limit?: number; }; res: NoteReaction[]; };
|
||||
'notes/reactions/create': { req: { noteId: Note['id']; reaction: string; }; res: null; };
|
||||
|
Loading…
Reference in New Issue
Block a user