Add migrations
authorChocobozzz <me@florianbigard.com>
Wed, 24 Apr 2019 08:28:57 +0000 (10:28 +0200)
committerChocobozzz <me@florianbigard.com>
Wed, 24 Apr 2019 14:26:22 +0000 (16:26 +0200)
server/initializers/constants.ts
server/initializers/migrations/0370-thumbnail.ts [new file with mode: 0644]
server/lib/activitypub/process/process-undo.ts
server/lib/thumbnail.ts
server/models/video/thumbnail.ts
server/models/video/video-format-utils.ts

index 50a437b3d837da3378925333a75d98ac50e0470e..2be364cc8ec333e4e051fbbdb379f88fd58b33f9 100644 (file)
@@ -14,7 +14,7 @@ import { CONFIG, registerConfigChangedHandler } from './config'
 
 // ---------------------------------------------------------------------------
 
-const LAST_MIGRATION_VERSION = 365
+const LAST_MIGRATION_VERSION = 370
 
 // ---------------------------------------------------------------------------
 
diff --git a/server/initializers/migrations/0370-thumbnail.ts b/server/initializers/migrations/0370-thumbnail.ts
new file mode 100644 (file)
index 0000000..384ca1a
--- /dev/null
@@ -0,0 +1,50 @@
+import * as Sequelize from 'sequelize'
+
+async function up (utils: {
+  transaction: Sequelize.Transaction,
+  queryInterface: Sequelize.QueryInterface,
+  sequelize: Sequelize.Sequelize,
+  db: any
+}): Promise<void> {
+  {
+    const query = `
+CREATE TABLE IF NOT EXISTS "thumbnail"
+(
+  "id"              SERIAL,
+  "filename"        VARCHAR(255)             NOT NULL,
+  "height"          INTEGER DEFAULT NULL,
+  "width"           INTEGER DEFAULT NULL,
+  "type"            INTEGER                  NOT NULL,
+  "fileUrl"             VARCHAR(255),
+  "videoId"         INTEGER REFERENCES "video" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
+  "videoPlaylistId" INTEGER REFERENCES "videoPlaylist" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
+  "createdAt"       TIMESTAMP WITH TIME ZONE NOT NULL,
+  "updatedAt"       TIMESTAMP WITH TIME ZONE NOT NULL,
+  PRIMARY KEY ("id")
+);`
+    await utils.sequelize.query(query)
+  }
+
+  {
+    // All video thumbnails
+    const query = 'INSERT INTO "thumbnail" ("filename", "type", "videoId", "height", "width", "createdAt", "updatedAt")' +
+      'SELECT uuid || \'.jpg\', 1, id, 110, 200, NOW(), NOW() FROM "video"'
+    await utils.sequelize.query(query)
+  }
+
+  {
+    // All video previews
+    const query = 'INSERT INTO "thumbnail" ("filename", "type", "videoId", "height", "width", "createdAt", "updatedAt")' +
+      'SELECT uuid || \'.jpg\', 2, id, 315, 560, NOW(), NOW() FROM "video"'
+    await utils.sequelize.query(query)
+  }
+}
+
+function down (options) {
+  throw new Error('Not implemented.')
+}
+
+export {
+  up,
+  down
+}
index ed0177a67f785a0c5a3c260ac79cd1211b5d8764..2d48848fe7ec95daff18d787bb770dc8c0196012 100644 (file)
@@ -108,7 +108,10 @@ async function processUndoCacheFile (byActor: ActorModel, activity: ActivityUndo
 
   return sequelizeTypescript.transaction(async t => {
     const cacheFile = await VideoRedundancyModel.loadByUrl(cacheFileObject.id)
-    if (!cacheFile) throw new Error('Unknown video cache ' + cacheFileObject.id)
+    if (!cacheFile) {
+      logger.debug('Cannot undo unknown video cache %s.', cacheFileObject.id)
+      return
+    }
 
     if (cacheFile.actorId !== byActor.id) throw new Error('Cannot delete redundancy ' + cacheFile.url + ' of another actor.')
 
index 4ba521b973f5133c0a9d305838fc98d84ad29c5a..950b14c3bd18187a019f8213bcfbfff2f715c6f4 100644 (file)
@@ -20,19 +20,19 @@ function createPlaylistMiniatureFromExisting (inputPath: string, playlist: Video
   return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail })
 }
 
-function createPlaylistMiniatureFromUrl (url: string, playlist: VideoPlaylistModel, size?: ImageSize) {
+function createPlaylistMiniatureFromUrl (fileUrl: string, playlist: VideoPlaylistModel, size?: ImageSize) {
   const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromPlaylist(playlist, size)
   const type = ThumbnailType.MINIATURE
 
-  const thumbnailCreator = () => downloadImage(url, basePath, filename, { width, height })
-  return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, url })
+  const thumbnailCreator = () => downloadImage(fileUrl, basePath, filename, { width, height })
+  return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl })
 }
 
-function createVideoMiniatureFromUrl (url: string, video: VideoModel, type: ThumbnailType, size?: ImageSize) {
+function createVideoMiniatureFromUrl (fileUrl: string, video: VideoModel, type: ThumbnailType, size?: ImageSize) {
   const { filename, basePath, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
-  const thumbnailCreator = () => downloadImage(url, basePath, filename, { width, height })
+  const thumbnailCreator = () => downloadImage(fileUrl, basePath, filename, { width, height })
 
-  return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, url })
+  return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail, fileUrl })
 }
 
 function createVideoMiniatureFromExisting (inputPath: string, video: VideoModel, type: ThumbnailType, size?: ImageSize) {
@@ -51,7 +51,7 @@ function generateVideoMiniature (video: VideoModel, videoFile: VideoFileModel, t
   return createThumbnailFromFunction({ thumbnailCreator, filename, height, width, type, existingThumbnail })
 }
 
-function createPlaceholderThumbnail (url: string, video: VideoModel, type: ThumbnailType, size: ImageSize) {
+function createPlaceholderThumbnail (fileUrl: string, video: VideoModel, type: ThumbnailType, size: ImageSize) {
   const { filename, height, width, existingThumbnail } = buildMetadataFromVideo(video, type, size)
 
   const thumbnail = existingThumbnail ? existingThumbnail : new ThumbnailModel()
@@ -60,7 +60,7 @@ function createPlaceholderThumbnail (url: string, video: VideoModel, type: Thumb
   thumbnail.height = height
   thumbnail.width = width
   thumbnail.type = type
-  thumbnail.url = url
+  thumbnail.fileUrl = fileUrl
 
   return thumbnail
 }
@@ -132,10 +132,10 @@ async function createThumbnailFromFunction (parameters: {
   height: number,
   width: number,
   type: ThumbnailType,
-  url?: string,
+  fileUrl?: string,
   existingThumbnail?: ThumbnailModel
 }) {
-  const { thumbnailCreator, filename, width, height, type, existingThumbnail, url = null } = parameters
+  const { thumbnailCreator, filename, width, height, type, existingThumbnail, fileUrl = null } = parameters
 
   const thumbnail = existingThumbnail ? existingThumbnail : new ThumbnailModel()
 
@@ -143,7 +143,7 @@ async function createThumbnailFromFunction (parameters: {
   thumbnail.height = height
   thumbnail.width = width
   thumbnail.type = type
-  thumbnail.url = url
+  thumbnail.fileUrl = fileUrl
 
   await thumbnailCreator()
 
index ec945893f6a408e6637411f016152b3bf1f68d86..206e9a3d62b4021d946242b7db0989ac7ffe3b91 100644 (file)
@@ -42,7 +42,7 @@ export class ThumbnailModel extends Model<ThumbnailModel> {
 
   @AllowNull(true)
   @Column
-  url: string
+  fileUrl: string
 
   @ForeignKey(() => VideoModel)
   @Column
@@ -100,8 +100,8 @@ export class ThumbnailModel extends Model<ThumbnailModel> {
     return videoUUID + '.jpg'
   }
 
-  getUrl () {
-    if (this.url) return this.url
+  getFileUrl () {
+    if (this.fileUrl) return this.fileUrl
 
     const staticPath = ThumbnailModel.types[this.type].staticPath
     return WEBSERVER.URL + staticPath + this.filename
index 877fcbc57c7c938fee6d8c50ce9db6a31381d263..b947eb16f4b6608c16038ccf873227a403deabf0 100644 (file)
@@ -328,7 +328,7 @@ function videoModelToActivityPubObject (video: VideoModel): VideoTorrentObject {
     subtitleLanguage,
     icon: {
       type: 'Image',
-      url: miniature.getUrl(),
+      url: miniature.getFileUrl(),
       mediaType: 'image/jpeg',
       width: miniature.width,
       height: miniature.height