]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/lib/activitypub/process/misc.ts
Move models to typescript-sequelize
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / process / misc.ts
CommitLineData
0d0e8dd0 1import * as magnetUtil from 'magnet-uri'
54141398 2import { VideoTorrentObject } from '../../../../shared'
3fd3ab2d
C
3import { VideoChannelObject } from '../../../../shared/models/activitypub/objects'
4import { VideoPrivacy } from '../../../../shared/models/videos'
5import { doRequest } from '../../../helpers'
54141398 6import { isVideoFileInfoHashValid } from '../../../helpers/custom-validators/videos'
3fd3ab2d
C
7import { ACTIVITY_PUB, VIDEO_MIMETYPE_EXT } from '../../../initializers'
8import { AccountModel } from '../../../models/account/account'
9import { VideoModel } from '../../../models/video/video'
10import { VideoChannelModel } from '../../../models/video/video-channel'
11import { VideoChannelShareModel } from '../../../models/video/video-channel-share'
12import { VideoShareModel } from '../../../models/video/video-share'
4e50b6a1 13import { getOrCreateAccountAndServer } from '../account'
20494f12 14
3fd3ab2d 15function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChannelObject, account: AccountModel) {
20494f12
C
16 return {
17 name: videoChannelObject.name,
18 description: videoChannelObject.content,
19 uuid: videoChannelObject.uuid,
20 url: videoChannelObject.id,
21 createdAt: new Date(videoChannelObject.published),
22 updatedAt: new Date(videoChannelObject.updated),
23 remote: true,
24 accountId: account.id
25 }
26}
0d0e8dd0 27
571389d4 28async function videoActivityObjectToDBAttributes (
3fd3ab2d 29 videoChannel: VideoChannelModel,
9a27cdc2
C
30 videoObject: VideoTorrentObject,
31 to: string[] = [],
32 cc: string[] = []
571389d4 33) {
9a27cdc2
C
34 let privacy = VideoPrivacy.PRIVATE
35 if (to.indexOf(ACTIVITY_PUB.PUBLIC) !== -1) privacy = VideoPrivacy.PUBLIC
36 else if (cc.indexOf(ACTIVITY_PUB.PUBLIC) !== -1) privacy = VideoPrivacy.UNLISTED
37
0d0e8dd0 38 const duration = videoObject.duration.replace(/[^\d]+/, '')
40ff5707
C
39 let language = null
40 if (videoObject.language) {
41 language = parseInt(videoObject.language.identifier, 10)
42 }
43
f595d394
C
44 let category = null
45 if (videoObject.category) {
46 category = parseInt(videoObject.category.identifier, 10)
47 }
48
49 let licence = null
50 if (videoObject.licence) {
51 licence = parseInt(videoObject.licence.identifier, 10)
52 }
53
54 let description = null
55 if (videoObject.content) {
56 description = videoObject.content
57 }
58
3fd3ab2d 59 return {
0d0e8dd0
C
60 name: videoObject.name,
61 uuid: videoObject.uuid,
62 url: videoObject.id,
f595d394
C
63 category,
64 licence,
40ff5707 65 language,
f595d394 66 description,
0d0e8dd0 67 nsfw: videoObject.nsfw,
0d0e8dd0
C
68 channelId: videoChannel.id,
69 duration: parseInt(duration, 10),
efc32059 70 createdAt: new Date(videoObject.published),
0d0e8dd0 71 // FIXME: updatedAt does not seems to be considered by Sequelize
efc32059 72 updatedAt: new Date(videoObject.updated),
0d0e8dd0
C
73 views: videoObject.views,
74 likes: 0,
75 dislikes: 0,
0d0e8dd0 76 remote: true,
9a27cdc2 77 privacy
0d0e8dd0 78 }
0d0e8dd0
C
79}
80
3fd3ab2d 81function videoFileActivityUrlToDBAttributes (videoCreated: VideoModel, videoObject: VideoTorrentObject) {
20494f12
C
82 const mimeTypes = Object.keys(VIDEO_MIMETYPE_EXT)
83 const fileUrls = videoObject.url.filter(u => {
84 return mimeTypes.indexOf(u.mimeType) !== -1 && u.mimeType.startsWith('video/')
85 })
86
87 if (fileUrls.length === 0) {
88 throw new Error('Cannot find video files for ' + videoCreated.url)
89 }
0d0e8dd0 90
3fd3ab2d 91 const attributes = []
20494f12 92 for (const fileUrl of fileUrls) {
0d0e8dd0 93 // Fetch associated magnet uri
20494f12
C
94 const magnet = videoObject.url.find(u => {
95 return u.mimeType === 'application/x-bittorrent;x-scheme-handler/magnet' && u.width === fileUrl.width
96 })
97
98 if (!magnet) throw new Error('Cannot find associated magnet uri for file ' + fileUrl.url)
0d0e8dd0
C
99
100 const parsed = magnetUtil.decode(magnet.url)
101 if (!parsed || isVideoFileInfoHashValid(parsed.infoHash) === false) throw new Error('Cannot parse magnet URI ' + magnet.url)
102
103 const attribute = {
20494f12 104 extname: VIDEO_MIMETYPE_EXT[fileUrl.mimeType],
0d0e8dd0 105 infoHash: parsed.infoHash,
20494f12
C
106 resolution: fileUrl.width,
107 size: fileUrl.size,
0d0e8dd0
C
108 videoId: videoCreated.id
109 }
110 attributes.push(attribute)
111 }
112
113 return attributes
114}
115
3fd3ab2d 116async function addVideoShares (instance: VideoModel, shares: string[]) {
4e50b6a1
C
117 for (const share of shares) {
118 // Fetch url
119 const json = await doRequest({
120 uri: share,
121 json: true
122 })
123 const actor = json['actor']
124 if (!actor) continue
125
126 const account = await getOrCreateAccountAndServer(actor)
127
128 const entry = {
129 accountId: account.id,
130 videoId: instance.id
131 }
132
3fd3ab2d 133 await VideoShareModel.findOrCreate({
4e50b6a1
C
134 where: entry,
135 defaults: entry
136 })
137 }
138}
139
3fd3ab2d 140async function addVideoChannelShares (instance: VideoChannelModel, shares: string[]) {
4e50b6a1
C
141 for (const share of shares) {
142 // Fetch url
143 const json = await doRequest({
144 uri: share,
145 json: true
146 })
147 const actor = json['actor']
148 if (!actor) continue
149
150 const account = await getOrCreateAccountAndServer(actor)
151
152 const entry = {
153 accountId: account.id,
154 videoChannelId: instance.id
155 }
156
3fd3ab2d 157 await VideoChannelShareModel.findOrCreate({
4e50b6a1
C
158 where: entry,
159 defaults: entry
160 })
161 }
162}
163
0d0e8dd0
C
164// ---------------------------------------------------------------------------
165
166export {
167 videoFileActivityUrlToDBAttributes,
20494f12 168 videoActivityObjectToDBAttributes,
4e50b6a1
C
169 videoChannelActivityObjectToDBAttributes,
170 addVideoChannelShares,
171 addVideoShares
0d0e8dd0 172}