Refractor activity pub lib/helpers
[oweals/peertube.git] / server / lib / activitypub / process / misc.ts
1 import * as magnetUtil from 'magnet-uri'
2 import { VideoTorrentObject } from '../../../../shared'
3 import { VideoChannelObject } from '../../../../shared/models/activitypub/objects/video-channel-object'
4 import { isVideoFileInfoHashValid } from '../../../helpers/custom-validators/videos'
5 import { ACTIVITY_PUB, VIDEO_MIMETYPE_EXT } from '../../../initializers/constants'
6 import { AccountInstance } from '../../../models/account/account-interface'
7 import { VideoChannelInstance } from '../../../models/video/video-channel-interface'
8 import { VideoFileAttributes } from '../../../models/video/video-file-interface'
9 import { VideoAttributes, VideoInstance } from '../../../models/video/video-interface'
10 import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum'
11
12 function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChannelObject, account: AccountInstance) {
13   return {
14     name: videoChannelObject.name,
15     description: videoChannelObject.content,
16     uuid: videoChannelObject.uuid,
17     url: videoChannelObject.id,
18     createdAt: new Date(videoChannelObject.published),
19     updatedAt: new Date(videoChannelObject.updated),
20     remote: true,
21     accountId: account.id
22   }
23 }
24
25 async function videoActivityObjectToDBAttributes (
26   videoChannel: VideoChannelInstance,
27   videoObject: VideoTorrentObject,
28   to: string[] = [],
29   cc: string[] = []
30 ) {
31   let privacy = VideoPrivacy.PRIVATE
32   if (to.indexOf(ACTIVITY_PUB.PUBLIC) !== -1) privacy = VideoPrivacy.PUBLIC
33   else if (cc.indexOf(ACTIVITY_PUB.PUBLIC) !== -1) privacy = VideoPrivacy.UNLISTED
34
35   const duration = videoObject.duration.replace(/[^\d]+/, '')
36   const videoData: VideoAttributes = {
37     name: videoObject.name,
38     uuid: videoObject.uuid,
39     url: videoObject.id,
40     category: parseInt(videoObject.category.identifier, 10),
41     licence: parseInt(videoObject.licence.identifier, 10),
42     language: parseInt(videoObject.language.identifier, 10),
43     nsfw: videoObject.nsfw,
44     description: videoObject.content,
45     channelId: videoChannel.id,
46     duration: parseInt(duration, 10),
47     createdAt: new Date(videoObject.published),
48     // FIXME: updatedAt does not seems to be considered by Sequelize
49     updatedAt: new Date(videoObject.updated),
50     views: videoObject.views,
51     likes: 0,
52     dislikes: 0,
53     remote: true,
54     privacy
55   }
56
57   return videoData
58 }
59
60 function videoFileActivityUrlToDBAttributes (videoCreated: VideoInstance, videoObject: VideoTorrentObject) {
61   const mimeTypes = Object.keys(VIDEO_MIMETYPE_EXT)
62   const fileUrls = videoObject.url.filter(u => {
63     return mimeTypes.indexOf(u.mimeType) !== -1 && u.mimeType.startsWith('video/')
64   })
65
66   if (fileUrls.length === 0) {
67     throw new Error('Cannot find video files for ' + videoCreated.url)
68   }
69
70   const attributes: VideoFileAttributes[] = []
71   for (const fileUrl of fileUrls) {
72     // Fetch associated magnet uri
73     const magnet = videoObject.url.find(u => {
74       return u.mimeType === 'application/x-bittorrent;x-scheme-handler/magnet' && u.width === fileUrl.width
75     })
76
77     if (!magnet) throw new Error('Cannot find associated magnet uri for file ' + fileUrl.url)
78
79     const parsed = magnetUtil.decode(magnet.url)
80     if (!parsed || isVideoFileInfoHashValid(parsed.infoHash) === false) throw new Error('Cannot parse magnet URI ' + magnet.url)
81
82     const attribute = {
83       extname: VIDEO_MIMETYPE_EXT[fileUrl.mimeType],
84       infoHash: parsed.infoHash,
85       resolution: fileUrl.width,
86       size: fileUrl.size,
87       videoId: videoCreated.id
88     }
89     attributes.push(attribute)
90   }
91
92   return attributes
93 }
94
95 // ---------------------------------------------------------------------------
96
97 export {
98   videoFileActivityUrlToDBAttributes,
99   videoActivityObjectToDBAttributes,
100   videoChannelActivityObjectToDBAttributes
101 }