Add server migrations
authorChocobozzz <me@florianbigard.com>
Wed, 6 Mar 2019 10:32:53 +0000 (11:32 +0100)
committerChocobozzz <chocobozzz@cpy.re>
Mon, 18 Mar 2019 10:17:59 +0000 (11:17 +0100)
server/controllers/api/video-playlist.ts
server/initializers/constants.ts
server/initializers/migrations/0345-video-playlists.ts [new file with mode: 0644]
server/tests/api/videos/video-playlists.ts

index 2700e8dc7df441d23480416656f6ae309b0a9820..145764d3508570b99da579ec5bf6c4d61756364c 100644 (file)
@@ -13,7 +13,7 @@ import {
 import { VideoChannelModel } from '../../models/video/video-channel'
 import { videoPlaylistsSortValidator } from '../../middlewares/validators'
 import { buildNSFWFilter, createReqFiles, isUserAbleToSearchRemoteURI } from '../../helpers/express-utils'
-import { CONFIG, MIMETYPES, sequelizeTypescript, THUMBNAILS_SIZE } from '../../initializers'
+import { CONFIG, MIMETYPES, sequelizeTypescript, THUMBNAILS_SIZE, VIDEO_PLAYLIST_PRIVACIES } from '../../initializers'
 import { logger } from '../../helpers/logger'
 import { resetSequelizeInstance } from '../../helpers/database-utils'
 import { VideoPlaylistModel } from '../../models/video/video-playlist'
@@ -46,6 +46,8 @@ const reqThumbnailFile = createReqFiles([ 'thumbnailfile' ], MIMETYPES.IMAGE.MIM
 
 const videoPlaylistRouter = express.Router()
 
+videoPlaylistRouter.get('/privacies', listVideoPlaylistPrivacies)
+
 videoPlaylistRouter.get('/',
   paginationValidator,
   videoPlaylistsSortValidator,
@@ -121,6 +123,10 @@ export {
 
 // ---------------------------------------------------------------------------
 
+function listVideoPlaylistPrivacies (req: express.Request, res: express.Response) {
+  res.json(VIDEO_PLAYLIST_PRIVACIES)
+}
+
 async function listVideoPlaylists (req: express.Request, res: express.Response) {
   const serverActor = await getServerActor()
   const resultList = await VideoPlaylistModel.listForApi({
@@ -153,7 +159,7 @@ async function addVideoPlaylist (req: express.Request, res: express.Response) {
 
   videoPlaylist.url = getVideoPlaylistActivityPubUrl(videoPlaylist) // We use the UUID, so set the URL after building the object
 
-  if (videoPlaylistInfo.videoChannelId !== undefined) {
+  if (videoPlaylistInfo.videoChannelId) {
     const videoChannel = res.locals.videoChannel as VideoChannelModel
 
     videoPlaylist.videoChannelId = videoChannel.id
index cabb0681a62866d04ad58d45349731c724397c7e..4cbb87ab549c58f59b46898e11cb818ca5ed2788 100644 (file)
@@ -18,7 +18,7 @@ let config: IConfig = require('config')
 
 // ---------------------------------------------------------------------------
 
-const LAST_MIGRATION_VERSION = 340
+const LAST_MIGRATION_VERSION = 345
 
 // ---------------------------------------------------------------------------
 
diff --git a/server/initializers/migrations/0345-video-playlists.ts b/server/initializers/migrations/0345-video-playlists.ts
new file mode 100644 (file)
index 0000000..11670b1
--- /dev/null
@@ -0,0 +1,86 @@
+import * as Sequelize from 'sequelize'
+import { CONFIG } from '../constants'
+import { VideoPlaylistPrivacy, VideoPlaylistType } from '../../../shared/models/videos'
+import * as uuidv4 from 'uuid/v4'
+
+async function up (utils: {
+  transaction: Sequelize.Transaction,
+  queryInterface: Sequelize.QueryInterface,
+  sequelize: Sequelize.Sequelize
+}): Promise<void> {
+  const transaction = utils.transaction
+
+  {
+    const query = `
+CREATE TABLE IF NOT EXISTS "videoPlaylist"
+(
+  "id"             SERIAL,
+  "name"           VARCHAR(255)             NOT NULL,
+  "description"    VARCHAR(255),
+  "privacy"        INTEGER                  NOT NULL,
+  "url"            VARCHAR(2000)            NOT NULL,
+  "uuid"           UUID                     NOT NULL,
+  "type"           INTEGER                  NOT NULL DEFAULT 1,
+  "ownerAccountId" INTEGER                  NOT NULL REFERENCES "account" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
+  "videoChannelId" INTEGER REFERENCES "videoChannel" ("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, { transaction })
+  }
+
+  {
+    const query = `
+CREATE TABLE IF NOT EXISTS "videoPlaylistElement"
+(
+  "id"              SERIAL,
+  "url"             VARCHAR(2000)            NOT NULL,
+  "position"        INTEGER                  NOT NULL DEFAULT 1,
+  "startTimestamp"  INTEGER,
+  "stopTimestamp"   INTEGER,
+  "videoPlaylistId" INTEGER                  NOT NULL REFERENCES "videoPlaylist" ("id") ON DELETE CASCADE ON UPDATE CASCADE,
+  "videoId"         INTEGER                  NOT NULL REFERENCES "video" ("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, { transaction })
+  }
+
+  {
+    const userQuery = 'SELECT "username" FROM "user";'
+    const userResult = await utils.sequelize.query(userQuery, { transaction, type: Sequelize.QueryTypes.SELECT })
+    const usernames = userResult.map(r => r.username)
+
+    for (const username of usernames) {
+      const uuid = uuidv4()
+
+      const baseUrl = CONFIG.WEBSERVER.URL + '/video-playlists/' + uuid
+      const query = `
+ INSERT INTO "videoPlaylist" ("url", "uuid", "name", "privacy", "type", "ownerAccountId", "createdAt", "updatedAt")
+ SELECT '${baseUrl}' AS "url",
+         '${uuid}' AS "uuid",
+         'Watch later' AS "name",
+         ${VideoPlaylistPrivacy.PRIVATE} AS "privacy",
+         ${VideoPlaylistType.WATCH_LATER} AS "type",
+         "account"."id" AS "ownerAccountId",
+         NOW() as "createdAt",
+         NOW() as "updatedAt"
+ FROM "user" INNER JOIN "account" ON "user"."id" = "account"."userId"
+ WHERE "user"."username" = '${username}'`
+
+      await utils.sequelize.query(query, { transaction })
+    }
+  }
+}
+
+function down (options) {
+  throw new Error('Not implemented.')
+}
+
+export {
+  up,
+  down
+}
index 7dd1563fcc98394c45cea3c7997224acb799a469..baa2b3b8cefd9b92000a057910e569ec8bf19a90 100644 (file)
@@ -18,6 +18,7 @@ import {
   getPlaylistVideos,
   getVideoChannelPlaylistsList,
   getVideoPlaylist,
+  getVideoPlaylistPrivacies,
   getVideoPlaylistsList,
   getVideoPlaylistWithToken,
   killallServers,
@@ -95,6 +96,15 @@ describe('Test video playlists', function () {
     await waitJobs(servers)
   })
 
+  it('Should list video playlist privacies', async function () {
+    const res = await getVideoPlaylistPrivacies(servers[0].url)
+
+    const privacies = res.body
+    expect(Object.keys(privacies)).to.have.length.at.least(3)
+
+    expect(privacies[3]).to.equal('Private')
+  })
+
   it('Should list watch later playlist', async function () {
     const url = servers[ 0 ].url
     const accessToken = servers[ 0 ].accessToken