Send follow/accept
[oweals/peertube.git] / server / lib / activitypub / misc.ts
1 import * as magnetUtil from 'magnet-uri'
2 import * as Sequelize from 'sequelize'
3 import { VideoTorrentObject } from '../../../shared'
4 import { isVideoFileInfoHashValid } from '../../helpers/custom-validators/videos'
5 import { database as db } from '../../initializers'
6 import { VIDEO_MIMETYPE_EXT } from '../../initializers/constants'
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
11 async function videoActivityObjectToDBAttributes (
12   videoChannel: VideoChannelInstance,
13   videoObject: VideoTorrentObject,
14   t: Sequelize.Transaction
15 ) {
16   const videoFromDatabase = await db.Video.loadByUUIDOrURL(videoObject.uuid, videoObject.id, t)
17   if (videoFromDatabase) throw new Error('Video with this UUID/Url already exists.')
18
19   const duration = videoObject.duration.replace(/[^\d]+/, '')
20   const videoData: VideoAttributes = {
21     name: videoObject.name,
22     uuid: videoObject.uuid,
23     url: videoObject.id,
24     category: parseInt(videoObject.category.identifier, 10),
25     licence: parseInt(videoObject.licence.identifier, 10),
26     language: parseInt(videoObject.language.identifier, 10),
27     nsfw: videoObject.nsfw,
28     description: videoObject.content,
29     channelId: videoChannel.id,
30     duration: parseInt(duration, 10),
31     createdAt: videoObject.published,
32     // FIXME: updatedAt does not seems to be considered by Sequelize
33     updatedAt: videoObject.updated,
34     views: videoObject.views,
35     likes: 0,
36     dislikes: 0,
37     // likes: videoToCreateData.likes,
38     // dislikes: videoToCreateData.dislikes,
39     remote: true,
40     privacy: 1
41     // privacy: videoToCreateData.privacy
42   }
43
44   return videoData
45 }
46
47 function videoFileActivityUrlToDBAttributes (videoCreated: VideoInstance, videoObject: VideoTorrentObject) {
48   const fileUrls = videoObject.url
49     .filter(u => Object.keys(VIDEO_MIMETYPE_EXT).indexOf(u.mimeType) !== -1)
50
51   const attributes: VideoFileAttributes[] = []
52   for (const url of fileUrls) {
53     // Fetch associated magnet uri
54     const magnet = videoObject.url
55       .find(u => {
56         return u.mimeType === 'application/x-bittorrent;x-scheme-handler/magnet' && u.width === url.width
57       })
58     if (!magnet) throw new Error('Cannot find associated magnet uri for file ' + url.url)
59
60     const parsed = magnetUtil.decode(magnet.url)
61     if (!parsed || isVideoFileInfoHashValid(parsed.infoHash) === false) throw new Error('Cannot parse magnet URI ' + magnet.url)
62
63     const attribute = {
64       extname: VIDEO_MIMETYPE_EXT[url.mimeType],
65       infoHash: parsed.infoHash,
66       resolution: url.width,
67       size: url.size,
68       videoId: videoCreated.id
69     }
70     attributes.push(attribute)
71   }
72
73   return attributes
74 }
75
76 // ---------------------------------------------------------------------------
77
78 export {
79   videoFileActivityUrlToDBAttributes,
80   videoActivityObjectToDBAttributes
81 }