mirror of https://github.com/Chocobozzz/PeerTube
Update data in DB when regenerate thumbnails
parent
ca87329289
commit
a0eeb45f14
|
@ -3,12 +3,13 @@ registerTSPaths()
|
|||
|
||||
import * as Bluebird from 'bluebird'
|
||||
import * as program from 'commander'
|
||||
import { pathExists } from 'fs-extra'
|
||||
import { pathExists, remove } from 'fs-extra'
|
||||
import { processImage } from '@server/helpers/image-utils'
|
||||
import { THUMBNAILS_SIZE } from '@server/initializers/constants'
|
||||
import { VideoModel } from '@server/models/video/video'
|
||||
import { MVideo } from '@server/types/models'
|
||||
import { initDatabaseModels } from '@server/initializers/database'
|
||||
import { ActorImageModel } from '@server/models/account/actor-image'
|
||||
|
||||
program
|
||||
.description('Regenerate local thumbnails using preview files')
|
||||
|
@ -37,13 +38,8 @@ async function processVideo (videoArg: MVideo) {
|
|||
const thumbnail = video.getMiniature()
|
||||
const preview = video.getPreview()
|
||||
|
||||
const thumbnailPath = thumbnail.getPath()
|
||||
const previewPath = preview.getPath()
|
||||
|
||||
if (!await pathExists(thumbnailPath)) {
|
||||
throw new Error(`Thumbnail ${thumbnailPath} does not exist on disk`)
|
||||
}
|
||||
|
||||
if (!await pathExists(previewPath)) {
|
||||
throw new Error(`Preview ${previewPath} does not exist on disk`)
|
||||
}
|
||||
|
@ -52,5 +48,22 @@ async function processVideo (videoArg: MVideo) {
|
|||
width: THUMBNAILS_SIZE.width,
|
||||
height: THUMBNAILS_SIZE.height
|
||||
}
|
||||
|
||||
const oldPath = thumbnail.getPath()
|
||||
|
||||
// Update thumbnail
|
||||
thumbnail.filename = ActorImageModel.generateFilename()
|
||||
thumbnail.width = size.width
|
||||
thumbnail.height = size.height
|
||||
|
||||
const thumbnailPath = thumbnail.getPath()
|
||||
await processImage(previewPath, thumbnailPath, size, true)
|
||||
|
||||
// Save new attributes
|
||||
await thumbnail.save()
|
||||
|
||||
// Remove old thumbnail
|
||||
await remove(oldPath)
|
||||
|
||||
// Don't federate, remote instances will refresh the thumbnails after a while
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import { maxBy, minBy } from 'lodash'
|
|||
import * as magnetUtil from 'magnet-uri'
|
||||
import { basename, join } from 'path'
|
||||
import { Transaction } from 'sequelize/types'
|
||||
import { ActorImageModel } from '@server/models/account/actor-image'
|
||||
import { TrackerModel } from '@server/models/server/tracker'
|
||||
import { VideoLiveModel } from '@server/models/video/video-live'
|
||||
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
|
||||
|
@ -899,7 +900,7 @@ function getPreviewFromIcons (videoObject: VideoObject) {
|
|||
function getPreviewUrl (previewIcon: ActivityIconObject, video: MVideoWithHost) {
|
||||
return previewIcon
|
||||
? previewIcon.url
|
||||
: buildRemoteVideoBaseUrl(video, join(LAZY_STATIC_PATHS.PREVIEWS, video.generatePreviewName()))
|
||||
: buildRemoteVideoBaseUrl(video, join(LAZY_STATIC_PATHS.PREVIEWS, ActorImageModel.generateFilename()))
|
||||
}
|
||||
|
||||
function getTrackerUrls (object: VideoObject, video: MVideoWithHost) {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { join } from 'path'
|
||||
import { ActorImageModel } from '@server/models/account/actor-image'
|
||||
import { ThumbnailType } from '../../shared/models/videos/thumbnail.type'
|
||||
import { generateImageFromVideoFile } from '../helpers/ffmpeg-utils'
|
||||
import { processImage } from '../helpers/image-utils'
|
||||
|
@ -200,7 +201,7 @@ function buildMetadataFromVideo (video: MVideoThumbnail, type: ThumbnailType, si
|
|||
: undefined
|
||||
|
||||
if (type === ThumbnailType.MINIATURE) {
|
||||
const filename = video.generateThumbnailName()
|
||||
const filename = ActorImageModel.generateFilename()
|
||||
const basePath = CONFIG.STORAGE.THUMBNAILS_DIR
|
||||
|
||||
return {
|
||||
|
@ -214,7 +215,7 @@ function buildMetadataFromVideo (video: MVideoThumbnail, type: ThumbnailType, si
|
|||
}
|
||||
|
||||
if (type === ThumbnailType.PREVIEW) {
|
||||
const filename = video.generatePreviewName()
|
||||
const filename = ActorImageModel.generateFilename()
|
||||
const basePath = CONFIG.STORAGE.PREVIEWS_DIR
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { remove } from 'fs-extra'
|
||||
import { join } from 'path'
|
||||
import { AfterDestroy, AllowNull, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { MActorImageFormattable } from '@server/types/models'
|
||||
import { ActorImageType } from '@shared/models'
|
||||
import { ActorImage } from '../../../shared/models/actors/actor-image.model'
|
||||
|
@ -53,6 +54,10 @@ export class ActorImageModel extends Model {
|
|||
.catch(err => logger.error('Cannot remove actor image file %s.', instance.filename, err))
|
||||
}
|
||||
|
||||
static generateFilename () {
|
||||
return uuidv4() + '.jpg'
|
||||
}
|
||||
|
||||
static loadByName (filename: string) {
|
||||
const query = {
|
||||
where: {
|
||||
|
|
|
@ -24,7 +24,6 @@ import {
|
|||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { buildNSFWFilter } from '@server/helpers/express-utils'
|
||||
import { getPrivaciesForFederation, isPrivacyForFederation, isStateForFederation } from '@server/helpers/video'
|
||||
import { LiveManager } from '@server/lib/live-manager'
|
||||
|
@ -1871,20 +1870,12 @@ export class VideoModel extends Model {
|
|||
this.Thumbnails.push(savedThumbnail)
|
||||
}
|
||||
|
||||
generateThumbnailName () {
|
||||
return uuidv4() + '.jpg'
|
||||
}
|
||||
|
||||
getMiniature () {
|
||||
if (Array.isArray(this.Thumbnails) === false) return undefined
|
||||
|
||||
return this.Thumbnails.find(t => t.type === ThumbnailType.MINIATURE)
|
||||
}
|
||||
|
||||
generatePreviewName () {
|
||||
return uuidv4() + '.jpg'
|
||||
}
|
||||
|
||||
hasPreview () {
|
||||
return !!this.getPreview()
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'mocha'
|
|||
import { expect } from 'chai'
|
||||
import { writeFile } from 'fs-extra'
|
||||
import { basename, join } from 'path'
|
||||
import { Video } from '@shared/models'
|
||||
import { Video, VideoDetails } from '@shared/models'
|
||||
import {
|
||||
buildServerDirectory,
|
||||
cleanupTests,
|
||||
|
@ -19,6 +19,17 @@ import {
|
|||
} from '../../../shared/extra-utils'
|
||||
import { HttpStatusCode } from '@shared/core-utils'
|
||||
|
||||
async function testThumbnail (server: ServerInfo, videoId: number | string) {
|
||||
const res = await getVideo(server.url, videoId)
|
||||
const video: VideoDetails = res.body
|
||||
|
||||
const res1 = await makeRawRequest(join(server.url, video.thumbnailPath), HttpStatusCode.OK_200)
|
||||
expect(res1.body).to.not.have.lengthOf(0)
|
||||
|
||||
const res2 = await makeRawRequest(join(server.url, video.thumbnailPath), HttpStatusCode.OK_200)
|
||||
expect(res2.body).to.not.have.lengthOf(0)
|
||||
}
|
||||
|
||||
describe('Test regenerate thumbnails script', function () {
|
||||
let servers: ServerInfo[]
|
||||
|
||||
|
@ -84,18 +95,21 @@ describe('Test regenerate thumbnails script', function () {
|
|||
await execCLI(`${env} npm run regenerate-thumbnails`)
|
||||
})
|
||||
|
||||
it('Should have regenerated local thumbnails', async function () {
|
||||
{
|
||||
const res1 = await makeRawRequest(join(servers[0].url, video1.thumbnailPath), HttpStatusCode.OK_200)
|
||||
expect(res1.body).to.not.have.lengthOf(0)
|
||||
it('Should have generated new thumbnail files', async function () {
|
||||
await testThumbnail(servers[0], video1.uuid)
|
||||
await testThumbnail(servers[0], video2.uuid)
|
||||
|
||||
const res2 = await makeRawRequest(join(servers[0].url, video1.previewPath), HttpStatusCode.OK_200)
|
||||
expect(res2.body).to.not.have.lengthOf(0)
|
||||
const res = await makeRawRequest(join(servers[0].url, remoteVideo.thumbnailPath), HttpStatusCode.OK_200)
|
||||
expect(res.body).to.have.lengthOf(0)
|
||||
})
|
||||
|
||||
it('Should have deleted old thumbnail files', async function () {
|
||||
{
|
||||
await makeRawRequest(join(servers[0].url, video1.thumbnailPath), HttpStatusCode.NOT_FOUND_404)
|
||||
}
|
||||
|
||||
{
|
||||
const res = await makeRawRequest(join(servers[0].url, video2.thumbnailPath), HttpStatusCode.OK_200)
|
||||
expect(res.body).to.not.have.lengthOf(0)
|
||||
await makeRawRequest(join(servers[0].url, video2.thumbnailPath), HttpStatusCode.NOT_FOUND_404)
|
||||
}
|
||||
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue