]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/lib/activitypub/context.ts
Add ability for plugins to alter video jsonld
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / context.ts
1 import { ContextType } from '@shared/models'
2 import { Hooks } from '../plugins/hooks'
3
4 async function activityPubContextify <T> (data: T, type: ContextType) {
5 return { ...await getContextData(type), ...data }
6 }
7
8 // ---------------------------------------------------------------------------
9
10 export {
11 getContextData,
12 activityPubContextify
13 }
14
15 // ---------------------------------------------------------------------------
16
17 type ContextValue = { [ id: string ]: (string | { '@type': string, '@id': string }) }
18
19 const contextStore: { [ id in ContextType ]: (string | { [ id: string ]: string })[] } = {
20 Video: buildContext({
21 Hashtag: 'as:Hashtag',
22 uuid: 'sc:identifier',
23 category: 'sc:category',
24 licence: 'sc:license',
25 subtitleLanguage: 'sc:subtitleLanguage',
26 sensitive: 'as:sensitive',
27 language: 'sc:inLanguage',
28 identifier: 'sc:identifier',
29
30 // TODO: remove in a few versions, introduced in 4.2
31 icons: 'as:icon',
32
33 isLiveBroadcast: 'sc:isLiveBroadcast',
34 liveSaveReplay: {
35 '@type': 'sc:Boolean',
36 '@id': 'pt:liveSaveReplay'
37 },
38 permanentLive: {
39 '@type': 'sc:Boolean',
40 '@id': 'pt:permanentLive'
41 },
42 latencyMode: {
43 '@type': 'sc:Number',
44 '@id': 'pt:latencyMode'
45 },
46
47 Infohash: 'pt:Infohash',
48
49 originallyPublishedAt: 'sc:datePublished',
50 views: {
51 '@type': 'sc:Number',
52 '@id': 'pt:views'
53 },
54 state: {
55 '@type': 'sc:Number',
56 '@id': 'pt:state'
57 },
58 size: {
59 '@type': 'sc:Number',
60 '@id': 'pt:size'
61 },
62 fps: {
63 '@type': 'sc:Number',
64 '@id': 'pt:fps'
65 },
66 commentsEnabled: {
67 '@type': 'sc:Boolean',
68 '@id': 'pt:commentsEnabled'
69 },
70 downloadEnabled: {
71 '@type': 'sc:Boolean',
72 '@id': 'pt:downloadEnabled'
73 },
74 waitTranscoding: {
75 '@type': 'sc:Boolean',
76 '@id': 'pt:waitTranscoding'
77 },
78 support: {
79 '@type': 'sc:Text',
80 '@id': 'pt:support'
81 },
82 likes: {
83 '@id': 'as:likes',
84 '@type': '@id'
85 },
86 dislikes: {
87 '@id': 'as:dislikes',
88 '@type': '@id'
89 },
90 shares: {
91 '@id': 'as:shares',
92 '@type': '@id'
93 },
94 comments: {
95 '@id': 'as:comments',
96 '@type': '@id'
97 }
98 }),
99
100 Playlist: buildContext({
101 Playlist: 'pt:Playlist',
102 PlaylistElement: 'pt:PlaylistElement',
103 position: {
104 '@type': 'sc:Number',
105 '@id': 'pt:position'
106 },
107 startTimestamp: {
108 '@type': 'sc:Number',
109 '@id': 'pt:startTimestamp'
110 },
111 stopTimestamp: {
112 '@type': 'sc:Number',
113 '@id': 'pt:stopTimestamp'
114 },
115 uuid: 'sc:identifier'
116 }),
117
118 CacheFile: buildContext({
119 expires: 'sc:expires',
120 CacheFile: 'pt:CacheFile'
121 }),
122
123 Flag: buildContext({
124 Hashtag: 'as:Hashtag'
125 }),
126
127 Actor: buildContext({
128 playlists: {
129 '@id': 'pt:playlists',
130 '@type': '@id'
131 },
132 support: {
133 '@type': 'sc:Text',
134 '@id': 'pt:support'
135 },
136
137 // TODO: remove in a few versions, introduced in 4.2
138 icons: 'as:icon'
139 }),
140
141 WatchAction: buildContext({
142 WatchAction: 'sc:WatchAction',
143 startTimestamp: {
144 '@type': 'sc:Number',
145 '@id': 'pt:startTimestamp'
146 },
147 stopTimestamp: {
148 '@type': 'sc:Number',
149 '@id': 'pt:stopTimestamp'
150 },
151 watchSection: {
152 '@type': 'sc:Number',
153 '@id': 'pt:stopTimestamp'
154 },
155 uuid: 'sc:identifier'
156 }),
157
158 Collection: buildContext(),
159 Follow: buildContext(),
160 Reject: buildContext(),
161 Accept: buildContext(),
162 View: buildContext(),
163 Announce: buildContext(),
164 Comment: buildContext(),
165 Delete: buildContext(),
166 Rate: buildContext()
167 }
168
169 async function getContextData (type: ContextType) {
170 const contextData = await Hooks.wrapObject(
171 contextStore[type],
172 'filter:activity-pub.activity.context.build.result'
173 )
174
175 return { '@context': contextData }
176 }
177
178 function buildContext (contextValue?: ContextValue) {
179 const baseContext = [
180 'https://www.w3.org/ns/activitystreams',
181 'https://w3id.org/security/v1',
182 {
183 RsaSignature2017: 'https://w3id.org/security#RsaSignature2017'
184 }
185 ]
186
187 if (!contextValue) return baseContext
188
189 return [
190 ...baseContext,
191
192 {
193 pt: 'https://joinpeertube.org/ns#',
194 sc: 'http://schema.org/',
195
196 ...contextValue
197 }
198 ]
199 }