Verified Commit a0eeb45f authored by Chocobozzz's avatar Chocobozzz

Update data in DB when regenerate thumbnails

parent ca873292
......@@ -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) {
......
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 {
......
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)
}
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment