PeerTube/server/core/models/video/video-source.ts

149 lines
3.5 KiB
TypeScript
Raw Normal View History

import { type FileStorageType, type VideoSource } from '@peertube/peertube-models'
import { STATIC_DOWNLOAD_PATHS, WEBSERVER } from '@server/initializers/constants.js'
import { MVideoSource } from '@server/types/models/video/video-source.js'
import { join } from 'path'
2023-07-19 16:02:49 +02:00
import { Transaction } from 'sequelize'
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Table, UpdatedAt } from 'sequelize-typescript'
import { SequelizeModel, doesExist, getSort } from '../shared/index.js'
import { getResolutionLabel } from './formatter/video-api-format.js'
import { VideoModel } from './video.js'
@Table({
tableName: 'videoSource',
indexes: [
{
2023-07-19 16:02:49 +02:00
fields: [ 'videoId' ]
},
{
fields: [ { name: 'createdAt', order: 'DESC' } ]
},
{
fields: [ 'keptOriginalFilename' ],
unique: true
}
]
})
2024-02-22 10:12:04 +01:00
export class VideoSourceModel extends SequelizeModel<VideoSourceModel> {
@CreatedAt
createdAt: Date
@UpdatedAt
updatedAt: Date
@AllowNull(false)
@Column
inputFilename: string
@AllowNull(true)
@Column
keptOriginalFilename: string
@AllowNull(true)
@Column
resolution: number
@AllowNull(true)
@Column
width: number
@AllowNull(true)
@Column
height: number
@AllowNull(true)
@Column
fps: number
@AllowNull(true)
@Column(DataType.BIGINT)
size: number
@AllowNull(true)
@Column(DataType.JSONB)
metadata: any
@AllowNull(true)
@Column
storage: FileStorageType
@AllowNull(true)
@Column
fileUrl: string
@ForeignKey(() => VideoModel)
@Column
videoId: number
2023-07-19 16:02:49 +02:00
@BelongsTo(() => VideoModel, {
foreignKey: {
allowNull: false
},
onDelete: 'cascade'
})
Video: Awaited<VideoModel>
2023-07-19 16:02:49 +02:00
static loadLatest (videoId: number, transaction?: Transaction) {
return VideoSourceModel.findOne<MVideoSource>({
2023-07-19 16:02:49 +02:00
where: { videoId },
order: getSort('-createdAt'),
transaction
})
}
static loadByKeptOriginalFilename (keptOriginalFilename: string) {
return VideoSourceModel.findOne<MVideoSource>({
where: { keptOriginalFilename }
})
}
static listAll (videoId: number, transaction?: Transaction) {
return VideoSourceModel.findAll<MVideoSource>({
where: { videoId },
transaction
})
}
// ---------------------------------------------------------------------------
static async doesOwnedFileExist (filename: string, storage: FileStorageType) {
const query = 'SELECT 1 FROM "videoSource" ' +
'INNER JOIN "video" ON "video"."id" = "videoSource"."videoId" AND "video"."remote" IS FALSE ' +
`WHERE "keptOriginalFilename" = $filename AND "storage" = $storage LIMIT 1`
return doesExist({ sequelize: this.sequelize, query, bind: { filename, storage } })
}
// ---------------------------------------------------------------------------
getFileDownloadUrl () {
if (!this.keptOriginalFilename) return null
return WEBSERVER.URL + join(STATIC_DOWNLOAD_PATHS.ORIGINAL_VIDEO_FILE, this.keptOriginalFilename)
}
2023-07-19 16:02:49 +02:00
toFormattedJSON (): VideoSource {
return {
filename: this.inputFilename,
inputFilename: this.inputFilename,
fileDownloadUrl: this.getFileDownloadUrl(),
resolution: {
id: this.resolution,
label: this.resolution !== null
? getResolutionLabel(this.resolution)
: null
},
size: this.size,
width: this.width,
height: this.height,
fps: this.fps,
metadata: this.metadata,
2023-07-19 16:02:49 +02:00
createdAt: this.createdAt.toISOString()
}
}
}