1 import * as magnetUtil from 'magnet-uri'
2 import { VideoTorrentObject } from '../../../../shared'
3 import { VideoPrivacy } from '../../../../shared/models/videos'
4 import { doRequest } from '../../../helpers'
5 import { isVideoFileInfoHashValid } from '../../../helpers/custom-validators/videos'
6 import { ACTIVITY_PUB, VIDEO_MIMETYPE_EXT } from '../../../initializers'
7 import { VideoModel } from '../../../models/video/video'
8 import { VideoChannelModel } from '../../../models/video/video-channel'
9 import { VideoShareModel } from '../../../models/video/video-share'
10 import { getOrCreateActorAndServerAndModel } from '../actor'
12 async function videoActivityObjectToDBAttributes (
13 videoChannel: VideoChannelModel,
14 videoObject: VideoTorrentObject,
18 let privacy = VideoPrivacy.PRIVATE
19 if (to.indexOf(ACTIVITY_PUB.PUBLIC) !== -1) privacy = VideoPrivacy.PUBLIC
20 else if (cc.indexOf(ACTIVITY_PUB.PUBLIC) !== -1) privacy = VideoPrivacy.UNLISTED
22 const duration = videoObject.duration.replace(/[^\d]+/, '')
24 if (videoObject.language) {
25 language = parseInt(videoObject.language.identifier, 10)
29 if (videoObject.category) {
30 category = parseInt(videoObject.category.identifier, 10)
34 if (videoObject.licence) {
35 licence = parseInt(videoObject.licence.identifier, 10)
38 let description = null
39 if (videoObject.content) {
40 description = videoObject.content
44 name: videoObject.name,
45 uuid: videoObject.uuid,
51 nsfw: videoObject.nsfw,
52 channelId: videoChannel.id,
53 duration: parseInt(duration, 10),
54 createdAt: new Date(videoObject.published),
55 // FIXME: updatedAt does not seems to be considered by Sequelize
56 updatedAt: new Date(videoObject.updated),
57 views: videoObject.views,
65 function videoFileActivityUrlToDBAttributes (videoCreated: VideoModel, videoObject: VideoTorrentObject) {
66 const mimeTypes = Object.keys(VIDEO_MIMETYPE_EXT)
67 const fileUrls = videoObject.url.filter(u => {
68 return mimeTypes.indexOf(u.mimeType) !== -1 && u.mimeType.startsWith('video/')
71 if (fileUrls.length === 0) {
72 throw new Error('Cannot find video files for ' + videoCreated.url)
76 for (const fileUrl of fileUrls) {
77 // Fetch associated magnet uri
78 const magnet = videoObject.url.find(u => {
79 return u.mimeType === 'application/x-bittorrent;x-scheme-handler/magnet' && u.width === fileUrl.width
82 if (!magnet) throw new Error('Cannot find associated magnet uri for file ' + fileUrl.url)
84 const parsed = magnetUtil.decode(magnet.url)
85 if (!parsed || isVideoFileInfoHashValid(parsed.infoHash) === false) throw new Error('Cannot parse magnet URI ' + magnet.url)
88 extname: VIDEO_MIMETYPE_EXT[fileUrl.mimeType],
89 infoHash: parsed.infoHash,
90 resolution: fileUrl.width,
92 videoId: videoCreated.id
94 attributes.push(attribute)
100 async function addVideoShares (instance: VideoModel, shares: string[]) {
101 for (const share of shares) {
103 const json = await doRequest({
107 const actorUrl = json['actor']
108 if (!actorUrl) continue
110 const actor = await getOrCreateActorAndServerAndModel(actorUrl)
117 await VideoShareModel.findOrCreate({
124 // ---------------------------------------------------------------------------
127 videoFileActivityUrlToDBAttributes,
128 videoActivityObjectToDBAttributes,