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