]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/lib/activitypub/process/misc.ts
Fix bad to/cc when undo dislike
[github/Chocobozzz/PeerTube.git] / server / lib / activitypub / process / misc.ts
CommitLineData
0d0e8dd0 1import * as magnetUtil from 'magnet-uri'
54141398
C
2import { VideoTorrentObject } from '../../../../shared'
3import { VideoChannelObject } from '../../../../shared/models/activitypub/objects/video-channel-object'
4e50b6a1 4import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum'
54141398 5import { isVideoFileInfoHashValid } from '../../../helpers/custom-validators/videos'
4e50b6a1
C
6import { doRequest } from '../../../helpers/requests'
7import { database as db } from '../../../initializers'
54141398
C
8import { ACTIVITY_PUB, VIDEO_MIMETYPE_EXT } from '../../../initializers/constants'
9import { AccountInstance } from '../../../models/account/account-interface'
10import { VideoChannelInstance } from '../../../models/video/video-channel-interface'
11import { VideoFileAttributes } from '../../../models/video/video-file-interface'
12import { VideoAttributes, VideoInstance } from '../../../models/video/video-interface'
4e50b6a1 13import { getOrCreateAccountAndServer } from '../account'
20494f12
C
14
15function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChannelObject, account: AccountInstance) {
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
C
28async function videoActivityObjectToDBAttributes (
29 videoChannel: VideoChannelInstance,
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
0d0e8dd0
C
44 const videoData: VideoAttributes = {
45 name: videoObject.name,
46 uuid: videoObject.uuid,
47 url: videoObject.id,
48 category: parseInt(videoObject.category.identifier, 10),
49 licence: parseInt(videoObject.licence.identifier, 10),
40ff5707 50 language,
0d0e8dd0
C
51 nsfw: videoObject.nsfw,
52 description: videoObject.content,
53 channelId: videoChannel.id,
54 duration: parseInt(duration, 10),
efc32059 55 createdAt: new Date(videoObject.published),
0d0e8dd0 56 // FIXME: updatedAt does not seems to be considered by Sequelize
efc32059 57 updatedAt: new Date(videoObject.updated),
0d0e8dd0
C
58 views: videoObject.views,
59 likes: 0,
60 dislikes: 0,
0d0e8dd0 61 remote: true,
9a27cdc2 62 privacy
0d0e8dd0
C
63 }
64
65 return videoData
66}
67
68function videoFileActivityUrlToDBAttributes (videoCreated: VideoInstance, videoObject: VideoTorrentObject) {
20494f12
C
69 const mimeTypes = Object.keys(VIDEO_MIMETYPE_EXT)
70 const fileUrls = videoObject.url.filter(u => {
71 return mimeTypes.indexOf(u.mimeType) !== -1 && u.mimeType.startsWith('video/')
72 })
73
74 if (fileUrls.length === 0) {
75 throw new Error('Cannot find video files for ' + videoCreated.url)
76 }
0d0e8dd0
C
77
78 const attributes: VideoFileAttributes[] = []
20494f12 79 for (const fileUrl of fileUrls) {
0d0e8dd0 80 // Fetch associated magnet uri
20494f12
C
81 const magnet = videoObject.url.find(u => {
82 return u.mimeType === 'application/x-bittorrent;x-scheme-handler/magnet' && u.width === fileUrl.width
83 })
84
85 if (!magnet) throw new Error('Cannot find associated magnet uri for file ' + fileUrl.url)
0d0e8dd0
C
86
87 const parsed = magnetUtil.decode(magnet.url)
88 if (!parsed || isVideoFileInfoHashValid(parsed.infoHash) === false) throw new Error('Cannot parse magnet URI ' + magnet.url)
89
90 const attribute = {
20494f12 91 extname: VIDEO_MIMETYPE_EXT[fileUrl.mimeType],
0d0e8dd0 92 infoHash: parsed.infoHash,
20494f12
C
93 resolution: fileUrl.width,
94 size: fileUrl.size,
0d0e8dd0
C
95 videoId: videoCreated.id
96 }
97 attributes.push(attribute)
98 }
99
100 return attributes
101}
102
4e50b6a1
C
103async function addVideoShares (instance: VideoInstance, shares: string[]) {
104 for (const share of shares) {
105 // Fetch url
106 const json = await doRequest({
107 uri: share,
108 json: true
109 })
110 const actor = json['actor']
111 if (!actor) continue
112
113 const account = await getOrCreateAccountAndServer(actor)
114
115 const entry = {
116 accountId: account.id,
117 videoId: instance.id
118 }
119
120 await db.VideoShare.findOrCreate({
121 where: entry,
122 defaults: entry
123 })
124 }
125}
126
127async function addVideoChannelShares (instance: VideoChannelInstance, shares: string[]) {
128 for (const share of shares) {
129 // Fetch url
130 const json = await doRequest({
131 uri: share,
132 json: true
133 })
134 const actor = json['actor']
135 if (!actor) continue
136
137 const account = await getOrCreateAccountAndServer(actor)
138
139 const entry = {
140 accountId: account.id,
141 videoChannelId: instance.id
142 }
143
144 await db.VideoChannelShare.findOrCreate({
145 where: entry,
146 defaults: entry
147 })
148 }
149}
150
0d0e8dd0
C
151// ---------------------------------------------------------------------------
152
153export {
154 videoFileActivityUrlToDBAttributes,
20494f12 155 videoActivityObjectToDBAttributes,
4e50b6a1
C
156 videoChannelActivityObjectToDBAttributes,
157 addVideoChannelShares,
158 addVideoShares
0d0e8dd0 159}