Support additional video extensions
[oweals/peertube.git] / server / models / video / video-file.ts
1 import { values } from 'lodash'
2 import {
3   AllowNull,
4   BelongsTo,
5   Column,
6   CreatedAt,
7   DataType,
8   Default,
9   ForeignKey,
10   HasMany,
11   Is,
12   Model,
13   Table,
14   UpdatedAt
15 } from 'sequelize-typescript'
16 import {
17   isVideoFileExtnameValid,
18   isVideoFileInfoHashValid,
19   isVideoFileResolutionValid,
20   isVideoFileSizeValid,
21   isVideoFPSResolutionValid
22 } from '../../helpers/custom-validators/videos'
23 import { CONSTRAINTS_FIELDS } from '../../initializers'
24 import { throwIfNotValid } from '../utils'
25 import { VideoModel } from './video'
26 import * as Sequelize from 'sequelize'
27 import { VideoRedundancyModel } from '../redundancy/video-redundancy'
28
29 @Table({
30   tableName: 'videoFile',
31   indexes: [
32     {
33       fields: [ 'videoId' ]
34     },
35     {
36       fields: [ 'infoHash' ]
37     },
38     {
39       fields: [ 'videoId', 'resolution', 'fps' ],
40       unique: true
41     }
42   ]
43 })
44 export class VideoFileModel extends Model<VideoFileModel> {
45   @CreatedAt
46   createdAt: Date
47
48   @UpdatedAt
49   updatedAt: Date
50
51   @AllowNull(false)
52   @Is('VideoFileResolution', value => throwIfNotValid(value, isVideoFileResolutionValid, 'resolution'))
53   @Column
54   resolution: number
55
56   @AllowNull(false)
57   @Is('VideoFileSize', value => throwIfNotValid(value, isVideoFileSizeValid, 'size'))
58   @Column(DataType.BIGINT)
59   size: number
60
61   @AllowNull(false)
62   @Is('VideoFileExtname', value => throwIfNotValid(value, isVideoFileExtnameValid, 'extname'))
63   @Column
64   extname: string
65
66   @AllowNull(false)
67   @Is('VideoFileSize', value => throwIfNotValid(value, isVideoFileInfoHashValid, 'info hash'))
68   @Column
69   infoHash: string
70
71   @AllowNull(false)
72   @Default(-1)
73   @Is('VideoFileFPS', value => throwIfNotValid(value, isVideoFPSResolutionValid, 'fps'))
74   @Column
75   fps: number
76
77   @ForeignKey(() => VideoModel)
78   @Column
79   videoId: number
80
81   @BelongsTo(() => VideoModel, {
82     foreignKey: {
83       allowNull: false
84     },
85     onDelete: 'CASCADE'
86   })
87   Video: VideoModel
88
89   @HasMany(() => VideoRedundancyModel, {
90     foreignKey: {
91       allowNull: false
92     },
93     onDelete: 'CASCADE',
94     hooks: true
95   })
96   RedundancyVideos: VideoRedundancyModel[]
97
98   static isInfohashExists (infoHash: string) {
99     const query = 'SELECT 1 FROM "videoFile" WHERE "infoHash" = $infoHash LIMIT 1'
100     const options = {
101       type: Sequelize.QueryTypes.SELECT,
102       bind: { infoHash },
103       raw: true
104     }
105
106     return VideoModel.sequelize.query(query, options)
107               .then(results => {
108                 return results.length === 1
109               })
110   }
111
112   static loadWithVideo (id: number) {
113     const options = {
114       include: [
115         {
116           model: VideoModel.unscoped(),
117           required: true
118         }
119       ]
120     }
121
122     return VideoFileModel.findById(id, options)
123   }
124
125   hasSameUniqueKeysThan (other: VideoFileModel) {
126     return this.fps === other.fps &&
127       this.resolution === other.resolution &&
128       this.videoId === other.videoId
129   }
130 }