diff --git a/package.json b/package.json index 09493539b..38d01c77e 100644 --- a/package.json +++ b/package.json @@ -142,8 +142,8 @@ "request": "^2.81.0", "sanitize-html": "2.x", "scripty": "^2.0.0", - "sequelize": "5.21.13", - "sequelize-typescript": "^1.0.0-beta.4", + "sequelize": "6.3.5", + "sequelize-typescript": "^2.0.0-beta.1", "sitemap": "^6.1.0", "socket.io": "^3.0.2", "srt-to-vtt": "^1.1.2", diff --git a/server/controllers/api/videos/import.ts b/server/controllers/api/videos/import.ts index cd9ba046d..82e084c54 100644 --- a/server/controllers/api/videos/import.ts +++ b/server/controllers/api/videos/import.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird' import * as express from 'express' import { move, readFile } from 'fs-extra' import * as magnetUtil from 'magnet-uri' @@ -17,6 +16,7 @@ import { } from '@server/types/models' import { MVideoImport, MVideoImportFormattable } from '@server/types/models/video/video-import' import { VideoImportCreate, VideoImportState, VideoPrivacy, VideoState } from '../../../../shared' +import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger' import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils' @@ -36,7 +36,6 @@ import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoIm import { VideoModel } from '../../../models/video/video' import { VideoCaptionModel } from '../../../models/video/video-caption' import { VideoImportModel } from '../../../models/video/video-import' -import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes' const auditLogger = auditLoggerFactory('video-imports') const videoImportsRouter = express.Router() @@ -314,7 +313,7 @@ function insertIntoDB (parameters: { tags: string[] videoImportAttributes: Partial user: MUser -}): Bluebird { +}): Promise { const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters return sequelizeTypescript.transaction(async t => { diff --git a/server/helpers/actor.ts b/server/helpers/actor.ts index 015b4a39f..a60d3ed5d 100644 --- a/server/helpers/actor.ts +++ b/server/helpers/actor.ts @@ -1,10 +1,10 @@ + import { ActorModel } from '../models/activitypub/actor' -import * as Bluebird from 'bluebird' -import { MActorFull, MActorAccountChannelId } from '../types/models' +import { MActorAccountChannelId, MActorFull } from '../types/models' type ActorFetchByUrlType = 'all' | 'association-ids' -function fetchActorByUrl (url: string, fetchType: ActorFetchByUrlType): Bluebird { +function fetchActorByUrl (url: string, fetchType: ActorFetchByUrlType): Promise { if (fetchType === 'all') return ActorModel.loadByUrlAndPopulateAccountAndChannel(url) if (fetchType === 'association-ids') return ActorModel.loadByUrl(url) diff --git a/server/helpers/middlewares/accounts.ts b/server/helpers/middlewares/accounts.ts index 23470cac6..13ae6cdf4 100644 --- a/server/helpers/middlewares/accounts.ts +++ b/server/helpers/middlewares/accounts.ts @@ -1,9 +1,8 @@ import { Response } from 'express' -import { AccountModel } from '../../models/account/account' -import * as Bluebird from 'bluebird' -import { MAccountDefault } from '../../types/models' import { UserModel } from '@server/models/account/user' import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' +import { AccountModel } from '../../models/account/account' +import { MAccountDefault } from '../../types/models' function doesAccountIdExist (id: number | string, res: Response, sendNotFound = true) { const promise = AccountModel.load(parseInt(id + '', 10)) @@ -23,7 +22,7 @@ function doesAccountNameWithHostExist (nameWithDomain: string, res: Response, se return doesAccountExist(promise, res, sendNotFound) } -async function doesAccountExist (p: Bluebird, res: Response, sendNotFound: boolean) { +async function doesAccountExist (p: Promise, res: Response, sendNotFound: boolean) { const account = await p if (!account) { diff --git a/server/helpers/video.ts b/server/helpers/video.ts index 999137c6d..5d1cd7de1 100644 --- a/server/helpers/video.ts +++ b/server/helpers/video.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird' import { Response } from 'express' import { CONFIG } from '@server/initializers/config' import { DEFAULT_AUDIO_RESOLUTION } from '@server/initializers/constants' @@ -20,21 +19,21 @@ import { VideoModel } from '../models/video/video' type VideoFetchType = 'all' | 'only-video' | 'only-video-with-rights' | 'id' | 'none' | 'only-immutable-attributes' -function fetchVideo (id: number | string, fetchType: 'all', userId?: number): Bluebird -function fetchVideo (id: number | string, fetchType: 'only-immutable-attributes'): Bluebird -function fetchVideo (id: number | string, fetchType: 'only-video', userId?: number): Bluebird -function fetchVideo (id: number | string, fetchType: 'only-video-with-rights', userId?: number): Bluebird -function fetchVideo (id: number | string, fetchType: 'id' | 'none', userId?: number): Bluebird +function fetchVideo (id: number | string, fetchType: 'all', userId?: number): Promise +function fetchVideo (id: number | string, fetchType: 'only-immutable-attributes'): Promise +function fetchVideo (id: number | string, fetchType: 'only-video', userId?: number): Promise +function fetchVideo (id: number | string, fetchType: 'only-video-with-rights', userId?: number): Promise +function fetchVideo (id: number | string, fetchType: 'id' | 'none', userId?: number): Promise function fetchVideo ( id: number | string, fetchType: VideoFetchType, userId?: number -): Bluebird +): Promise function fetchVideo ( id: number | string, fetchType: VideoFetchType, userId?: number -): Bluebird { +): Promise { if (fetchType === 'all') return VideoModel.loadAndPopulateAccountAndServerAndTags(id, undefined, userId) if (fetchType === 'only-immutable-attributes') return VideoModel.loadImmutableAttributes(id) @@ -48,17 +47,17 @@ function fetchVideo ( type VideoFetchByUrlType = 'all' | 'only-video' | 'only-immutable-attributes' -function fetchVideoByUrl (url: string, fetchType: 'all'): Bluebird -function fetchVideoByUrl (url: string, fetchType: 'only-immutable-attributes'): Bluebird -function fetchVideoByUrl (url: string, fetchType: 'only-video'): Bluebird +function fetchVideoByUrl (url: string, fetchType: 'all'): Promise +function fetchVideoByUrl (url: string, fetchType: 'only-immutable-attributes'): Promise +function fetchVideoByUrl (url: string, fetchType: 'only-video'): Promise function fetchVideoByUrl ( url: string, fetchType: VideoFetchByUrlType -): Bluebird +): Promise function fetchVideoByUrl ( url: string, fetchType: VideoFetchByUrlType -): Bluebird { +): Promise { if (fetchType === 'all') return VideoModel.loadByUrlAndPopulateAccount(url) if (fetchType === 'only-immutable-attributes') return VideoModel.loadByUrlImmutableAttributes(url) diff --git a/server/initializers/migrations/0005-email-pod.ts b/server/initializers/migrations/0005-email-pod.ts index 417c33b1f..025bcdb59 100644 --- a/server/initializers/migrations/0005-email-pod.ts +++ b/server/initializers/migrations/0005-email-pod.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' import { Migration } from '../../models/migrations' function up (utils: { diff --git a/server/initializers/migrations/0010-email-user.ts b/server/initializers/migrations/0010-email-user.ts index f7d01f6d6..4193b7ff9 100644 --- a/server/initializers/migrations/0010-email-user.ts +++ b/server/initializers/migrations/0010-email-user.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' import { Migration } from '../../models/migrations' function up (utils: { diff --git a/server/initializers/migrations/0015-video-views.ts b/server/initializers/migrations/0015-video-views.ts index 47dd4069b..aa80ffbcc 100644 --- a/server/initializers/migrations/0015-video-views.ts +++ b/server/initializers/migrations/0015-video-views.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' function up (utils: { transaction: Sequelize.Transaction diff --git a/server/initializers/migrations/0020-video-likes.ts b/server/initializers/migrations/0020-video-likes.ts index 44333f3b0..aae815a8e 100644 --- a/server/initializers/migrations/0020-video-likes.ts +++ b/server/initializers/migrations/0020-video-likes.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' function up (utils: { transaction: Sequelize.Transaction diff --git a/server/initializers/migrations/0025-video-dislikes.ts b/server/initializers/migrations/0025-video-dislikes.ts index 2aa22e2d7..6eb6fb9dc 100644 --- a/server/initializers/migrations/0025-video-dislikes.ts +++ b/server/initializers/migrations/0025-video-dislikes.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' function up (utils: { transaction: Sequelize.Transaction diff --git a/server/initializers/migrations/0030-video-category.ts b/server/initializers/migrations/0030-video-category.ts index 00cd2d8cf..dd3922549 100644 --- a/server/initializers/migrations/0030-video-category.ts +++ b/server/initializers/migrations/0030-video-category.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' import { Migration } from '../../models/migrations' function up (utils: { diff --git a/server/initializers/migrations/0035-video-licence.ts b/server/initializers/migrations/0035-video-licence.ts index 61d666c5e..b4224d758 100644 --- a/server/initializers/migrations/0035-video-licence.ts +++ b/server/initializers/migrations/0035-video-licence.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' import { Migration } from '../../models/migrations' function up (utils: { diff --git a/server/initializers/migrations/0040-video-nsfw.ts b/server/initializers/migrations/0040-video-nsfw.ts index 44aec8a6c..d5aad3e53 100644 --- a/server/initializers/migrations/0040-video-nsfw.ts +++ b/server/initializers/migrations/0040-video-nsfw.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' import { Migration } from '../../models/migrations' function up (utils: { diff --git a/server/initializers/migrations/0045-user-display-nsfw.ts b/server/initializers/migrations/0045-user-display-nsfw.ts index 07795bd75..5226a25eb 100644 --- a/server/initializers/migrations/0045-user-display-nsfw.ts +++ b/server/initializers/migrations/0045-user-display-nsfw.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' function up (utils: { transaction: Sequelize.Transaction diff --git a/server/initializers/migrations/0050-video-language.ts b/server/initializers/migrations/0050-video-language.ts index 6f90abb44..0cd518272 100644 --- a/server/initializers/migrations/0050-video-language.ts +++ b/server/initializers/migrations/0050-video-language.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' function up (utils: { transaction: Sequelize.Transaction diff --git a/server/initializers/migrations/0055-video-uuid.ts b/server/initializers/migrations/0055-video-uuid.ts index 8a58aebb8..525a69ea5 100644 --- a/server/initializers/migrations/0055-video-uuid.ts +++ b/server/initializers/migrations/0055-video-uuid.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' import { Migration } from '../../models/migrations' function up (utils: { diff --git a/server/initializers/migrations/0060-video-file.ts b/server/initializers/migrations/0060-video-file.ts index 00647e60e..f07fa7780 100644 --- a/server/initializers/migrations/0060-video-file.ts +++ b/server/initializers/migrations/0060-video-file.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' function up (utils: { transaction: Sequelize.Transaction diff --git a/server/initializers/migrations/0065-video-file-size.ts b/server/initializers/migrations/0065-video-file-size.ts index 0bdc675c2..1aeb27f2d 100644 --- a/server/initializers/migrations/0065-video-file-size.ts +++ b/server/initializers/migrations/0065-video-file-size.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' import { stat } from 'fs-extra' import { VideoModel } from '../../models/video/video' import { getVideoFilePath } from '@server/lib/video-paths' diff --git a/server/initializers/migrations/0070-user-video-quota.ts b/server/initializers/migrations/0070-user-video-quota.ts index 1d073f244..3fc4d2970 100644 --- a/server/initializers/migrations/0070-user-video-quota.ts +++ b/server/initializers/migrations/0070-user-video-quota.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' import { Migration } from '../../models/migrations' function up (utils: { diff --git a/server/initializers/migrations/0130-user-autoplay-video.ts b/server/initializers/migrations/0130-user-autoplay-video.ts index d57934588..8f2767266 100644 --- a/server/initializers/migrations/0130-user-autoplay-video.ts +++ b/server/initializers/migrations/0130-user-autoplay-video.ts @@ -1,5 +1,4 @@ import * as Sequelize from 'sequelize' -import * as Promise from 'bluebird' function up (utils: { transaction: Sequelize.Transaction diff --git a/server/initializers/migrations/0150-avatar-cascade.ts b/server/initializers/migrations/0150-avatar-cascade.ts index fb3b25773..ecf3467a0 100644 --- a/server/initializers/migrations/0150-avatar-cascade.ts +++ b/server/initializers/migrations/0150-avatar-cascade.ts @@ -7,7 +7,8 @@ async function up (utils: { }): Promise { await utils.queryInterface.removeConstraint('actor', 'actor_avatarId_fkey') - await utils.queryInterface.addConstraint('actor', [ 'avatarId' ], { + await utils.queryInterface.addConstraint('actor', { + fields: [ 'avatarId' ], type: 'foreign key', references: { table: 'avatar', diff --git a/server/initializers/migrations/0410-video-playlist-element.ts b/server/initializers/migrations/0410-video-playlist-element.ts index 1b4692357..be61b932b 100644 --- a/server/initializers/migrations/0410-video-playlist-element.ts +++ b/server/initializers/migrations/0410-video-playlist-element.ts @@ -18,7 +18,8 @@ async function up (utils: { await utils.queryInterface.removeConstraint('videoPlaylistElement', 'videoPlaylistElement_videoId_fkey') - await utils.queryInterface.addConstraint('videoPlaylistElement', [ 'videoId' ], { + await utils.queryInterface.addConstraint('videoPlaylistElement', { + fields: [ 'videoId' ], type: 'foreign key', references: { table: 'video', diff --git a/server/lib/activitypub/playlist.ts b/server/lib/activitypub/playlist.ts index 53298e968..8b54a001a 100644 --- a/server/lib/activitypub/playlist.ts +++ b/server/lib/activitypub/playlist.ts @@ -99,6 +99,8 @@ async function createOrUpdateVideoPlaylist (playlistObject: PlaylistObject, byAc return Promise.resolve() }) + logger.info('toto', { playlist, id: playlist.id }) + const refreshedPlaylist = await VideoPlaylistModel.loadWithAccountAndChannel(playlist.id, null) if (playlistObject.icon) { diff --git a/server/lib/activitypub/process/process-dislike.ts b/server/lib/activitypub/process/process-dislike.ts index 635c8bfcc..089c7b881 100644 --- a/server/lib/activitypub/process/process-dislike.ts +++ b/server/lib/activitypub/process/process-dislike.ts @@ -33,7 +33,7 @@ async function processDislike (activity: ActivityCreate | ActivityDislike, byAct const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: dislikeObject }) return sequelizeTypescript.transaction(async t => { - const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, activity.id) + const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, activity.id, t) if (existingRate && existingRate.type === 'dislike') return await video.increment('dislikes', { transaction: t }) diff --git a/server/lib/activitypub/process/process-like.ts b/server/lib/activitypub/process/process-like.ts index 6acc097b1..8688b3b47 100644 --- a/server/lib/activitypub/process/process-like.ts +++ b/server/lib/activitypub/process/process-like.ts @@ -30,7 +30,7 @@ async function processLikeVideo (byActor: MActorSignature, activity: ActivityLik const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoUrl }) return sequelizeTypescript.transaction(async t => { - const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, activity.id) + const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, activity.id, t) if (existingRate && existingRate.type === 'like') return if (existingRate && existingRate.type === 'dislike') { diff --git a/server/lib/activitypub/video-rates.ts b/server/lib/activitypub/video-rates.ts index 581a2bca1..e246b1313 100644 --- a/server/lib/activitypub/video-rates.ts +++ b/server/lib/activitypub/video-rates.ts @@ -13,8 +13,6 @@ import { sendDislike } from './send/send-dislike' import { MAccountActor, MActorUrl, MVideo, MVideoAccountLight, MVideoId } from '../../types/models' async function createRates (ratesUrl: string[], video: MVideo, rate: VideoRateType) { - let rateCounts = 0 - await Bluebird.map(ratesUrl, async rateUrl => { try { // Fetch url @@ -43,21 +41,12 @@ async function createRates (ratesUrl: string[], video: MVideo, rate: VideoRateTy url: body.id } - const created = await AccountVideoRateModel.upsert(entry) - - if (created) rateCounts += 1 + // Video "likes"/"dislikes" will be updated by the caller + await AccountVideoRateModel.upsert(entry) } catch (err) { logger.warn('Cannot add rate %s.', rateUrl, { err }) } }, { concurrency: CRAWL_REQUEST_CONCURRENCY }) - - logger.info('Adding %d %s to video %s.', rateCounts, rate, video.uuid) - - // This is "likes" and "dislikes" - if (rateCounts !== 0) { - const field = rate === 'like' ? 'likes' : 'dislikes' - await video.increment(field, { by: rateCounts }) - } } async function sendVideoRateChange ( diff --git a/server/lib/activitypub/videos.ts b/server/lib/activitypub/videos.ts index b15d5da1c..cb462e258 100644 --- a/server/lib/activitypub/videos.ts +++ b/server/lib/activitypub/videos.ts @@ -352,6 +352,9 @@ async function updateVideoFromAP (options: { video.views = videoData.views video.isLive = videoData.isLive + // Ensures we update the updated video attribute + video.changed('updatedAt', true) + const videoUpdated = await video.save(sequelizeOptions) as MVideoFullLight if (thumbnailModel) await videoUpdated.addAndSaveThumbnail(thumbnailModel, t) diff --git a/server/lib/client-html.ts b/server/lib/client-html.ts index 32f5d29ab..43585c591 100644 --- a/server/lib/client-html.ts +++ b/server/lib/client-html.ts @@ -1,29 +1,28 @@ import * as express from 'express' -import * as Bluebird from 'bluebird' +import { readFile } from 'fs-extra' +import { join } from 'path' +import validator from 'validator' import { buildFileLocale, getDefaultLocale, is18nLocale, POSSIBLE_LOCALES } from '../../shared/core-utils/i18n/i18n' +import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' +import { VideoPlaylistPrivacy, VideoPrivacy } from '../../shared/models/videos' +import { escapeHTML, isTestInstance, sha256 } from '../helpers/core-utils' +import { logger } from '../helpers/logger' +import { CONFIG } from '../initializers/config' import { + ACCEPT_HEADERS, AVATARS_SIZE, CUSTOM_HTML_TAG_COMMENTS, EMBED_SIZE, - PLUGIN_GLOBAL_CSS_PATH, - WEBSERVER, FILES_CONTENT_HASH, - ACCEPT_HEADERS + PLUGIN_GLOBAL_CSS_PATH, + WEBSERVER } from '../initializers/constants' -import { join } from 'path' -import { escapeHTML, isTestInstance, sha256 } from '../helpers/core-utils' -import { VideoModel } from '../models/video/video' -import { VideoPlaylistModel } from '../models/video/video-playlist' -import validator from 'validator' -import { VideoPrivacy, VideoPlaylistPrivacy } from '../../shared/models/videos' -import { readFile } from 'fs-extra' -import { getActivityStreamDuration } from '../models/video/video-format-utils' import { AccountModel } from '../models/account/account' +import { VideoModel } from '../models/video/video' import { VideoChannelModel } from '../models/video/video-channel' -import { CONFIG } from '../initializers/config' -import { logger } from '../helpers/logger' +import { getActivityStreamDuration } from '../models/video/video-format-utils' +import { VideoPlaylistModel } from '../models/video/video-playlist' import { MAccountActor, MChannelActor } from '../types/models' -import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes' type Tags = { ogType: string @@ -218,7 +217,7 @@ class ClientHtml { } private static async getAccountOrChannelHTMLPage ( - loader: () => Bluebird, + loader: () => Promise, req: express.Request, res: express.Response ) { diff --git a/server/lib/job-queue/handlers/activitypub-http-fetcher.ts b/server/lib/job-queue/handlers/activitypub-http-fetcher.ts index a7c1a556c..e210ac3ef 100644 --- a/server/lib/job-queue/handlers/activitypub-http-fetcher.ts +++ b/server/lib/job-queue/handlers/activitypub-http-fetcher.ts @@ -1,19 +1,18 @@ import * as Bull from 'bull' -import * as Bluebird from 'bluebird' +import { ActivitypubHttpFetcherPayload, FetchType } from '@shared/models' import { logger } from '../../../helpers/logger' -import { processActivities } from '../../activitypub/process' -import { addVideoComments } from '../../activitypub/video-comments' -import { crawlCollectionPage } from '../../activitypub/crawl' -import { VideoModel } from '../../../models/video/video' -import { addVideoShares } from '../../activitypub/share' -import { createRates } from '../../activitypub/video-rates' -import { createAccountPlaylists } from '../../activitypub/playlist' import { AccountModel } from '../../../models/account/account' import { AccountVideoRateModel } from '../../../models/account/account-video-rate' -import { VideoShareModel } from '../../../models/video/video-share' +import { VideoModel } from '../../../models/video/video' import { VideoCommentModel } from '../../../models/video/video-comment' +import { VideoShareModel } from '../../../models/video/video-share' import { MAccountDefault, MVideoFullLight } from '../../../types/models' -import { ActivitypubHttpFetcherPayload, FetchType } from '@shared/models' +import { crawlCollectionPage } from '../../activitypub/crawl' +import { createAccountPlaylists } from '../../activitypub/playlist' +import { processActivities } from '../../activitypub/process' +import { addVideoShares } from '../../activitypub/share' +import { addVideoComments } from '../../activitypub/video-comments' +import { createRates } from '../../activitypub/video-rates' async function processActivityPubHttpFetcher (job: Bull.Job) { logger.info('Processing ActivityPub fetcher in job %d.', job.id) @@ -35,7 +34,7 @@ async function processActivityPubHttpFetcher (job: Bull.Job) { 'account-playlists': items => createAccountPlaylists(items, account) } - const cleanerType: { [ id in FetchType ]?: (crawlStartDate: Date) => Bluebird } = { + const cleanerType: { [ id in FetchType ]?: (crawlStartDate: Date) => Promise } = { 'video-likes': crawlStartDate => AccountVideoRateModel.cleanOldRatesOf(video.id, 'like' as 'like', crawlStartDate), 'video-dislikes': crawlStartDate => AccountVideoRateModel.cleanOldRatesOf(video.id, 'dislike' as 'dislike', crawlStartDate), 'video-shares': crawlStartDate => VideoShareModel.cleanOldSharesOf(video.id, crawlStartDate), diff --git a/server/lib/video-transcoding-profiles.ts b/server/lib/video-transcoding-profiles.ts index 3bf83d6a8..338f4de4a 100644 --- a/server/lib/video-transcoding-profiles.ts +++ b/server/lib/video-transcoding-profiles.ts @@ -111,7 +111,6 @@ async function buildTargetBitrate (options: { input: string resolution: VideoResolution fps: number - }) { const { input, resolution, fps } = options const probe = await ffprobePromise(input) diff --git a/server/middlewares/validators/users.ts b/server/middlewares/validators/users.ts index c93895f2f..6b6e6c2df 100644 --- a/server/middlewares/validators/users.ts +++ b/server/middlewares/validators/users.ts @@ -1,8 +1,14 @@ -import * as Bluebird from 'bluebird' import * as express from 'express' import { body, param, query } from 'express-validator' import { omit } from 'lodash' +import { Hooks } from '@server/lib/plugins/hooks' +import { MUserDefault } from '@server/types/models' +import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' +import { UserRole } from '../../../shared/models/users' +import { UserRegister } from '../../../shared/models/users/user-register.model' +import { isActorPreferredUsernameValid } from '../../helpers/custom-validators/activitypub/actor' import { isIdOrUUIDValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc' +import { isThemeNameValid } from '../../helpers/custom-validators/plugins' import { isNoInstanceConfigWarningModal, isNoWelcomeModal, @@ -22,22 +28,15 @@ import { isUserVideoQuotaValid, isUserVideosHistoryEnabledValid } from '../../helpers/custom-validators/users' +import { isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels' import { logger } from '../../helpers/logger' +import { doesVideoExist } from '../../helpers/middlewares' import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../helpers/signup' +import { isThemeRegistered } from '../../lib/plugins/theme-utils' import { Redis } from '../../lib/redis' import { UserModel } from '../../models/account/user' -import { areValidationErrors } from './utils' import { ActorModel } from '../../models/activitypub/actor' -import { isActorPreferredUsernameValid } from '../../helpers/custom-validators/activitypub/actor' -import { isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels' -import { UserRegister } from '../../../shared/models/users/user-register.model' -import { isThemeNameValid } from '../../helpers/custom-validators/plugins' -import { isThemeRegistered } from '../../lib/plugins/theme-utils' -import { doesVideoExist } from '../../helpers/middlewares' -import { UserRole } from '../../../shared/models/users' -import { MUserDefault } from '@server/types/models' -import { Hooks } from '@server/lib/plugins/hooks' -import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' +import { areValidationErrors } from './utils' const usersListValidator = [ query('blocked') @@ -529,7 +528,7 @@ async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: return true } -async function checkUserExist (finder: () => Bluebird, res: express.Response, abortResponse = true) { +async function checkUserExist (finder: () => Promise, res: express.Response, abortResponse = true) { const user = await finder() if (!user) { diff --git a/server/models/abuse/abuse-message.ts b/server/models/abuse/abuse-message.ts index fce20f7a7..7e51b3e07 100644 --- a/server/models/abuse/abuse-message.ts +++ b/server/models/abuse/abuse-message.ts @@ -1,10 +1,10 @@ import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' import { isAbuseMessageValid } from '@server/helpers/custom-validators/abuses' +import { MAbuseMessage, MAbuseMessageFormattable } from '@server/types/models' import { AbuseMessage } from '@shared/models' import { AccountModel, ScopeNames as AccountScopeNames } from '../account/account' -import { throwIfNotValid, getSort } from '../utils' +import { getSort, throwIfNotValid } from '../utils' import { AbuseModel } from './abuse' -import { MAbuseMessageFormattable, MAbuseMessage } from '@server/types/models' @Table({ tableName: 'abuseMessage', @@ -17,7 +17,7 @@ import { MAbuseMessageFormattable, MAbuseMessage } from '@server/types/models' } ] }) -export class AbuseMessageModel extends Model { +export class AbuseMessageModel extends Model { @AllowNull(false) @Is('AbuseMessage', value => throwIfNotValid(value, isAbuseMessageValid, 'message')) diff --git a/server/models/abuse/abuse.ts b/server/models/abuse/abuse.ts index 290270fe2..de249d211 100644 --- a/server/models/abuse/abuse.ts +++ b/server/models/abuse/abuse.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird' import { invert } from 'lodash' import { literal, Op, QueryTypes } from 'sequelize' import { @@ -188,7 +187,7 @@ export enum ScopeNames { } ] }) -export class AbuseModel extends Model { +export class AbuseModel extends Model { @AllowNull(false) @Default(null) @@ -265,7 +264,7 @@ export class AbuseModel extends Model { }) VideoAbuse: VideoAbuseModel - static loadByIdWithReporter (id: number): Bluebird { + static loadByIdWithReporter (id: number): Promise { const query = { where: { id @@ -281,7 +280,7 @@ export class AbuseModel extends Model { return AbuseModel.findOne(query) } - static loadFull (id: number): Bluebird { + static loadFull (id: number): Promise { const query = { where: { id diff --git a/server/models/abuse/video-abuse.ts b/server/models/abuse/video-abuse.ts index d92bcf19f..90aa0695e 100644 --- a/server/models/abuse/video-abuse.ts +++ b/server/models/abuse/video-abuse.ts @@ -14,7 +14,7 @@ import { AbuseModel } from './abuse' } ] }) -export class VideoAbuseModel extends Model { +export class VideoAbuseModel extends Model { @CreatedAt createdAt: Date diff --git a/server/models/abuse/video-comment-abuse.ts b/server/models/abuse/video-comment-abuse.ts index 8b34009b4..d3fce76a5 100644 --- a/server/models/abuse/video-comment-abuse.ts +++ b/server/models/abuse/video-comment-abuse.ts @@ -13,7 +13,7 @@ import { AbuseModel } from './abuse' } ] }) -export class VideoCommentAbuseModel extends Model { +export class VideoCommentAbuseModel extends Model { @CreatedAt createdAt: Date diff --git a/server/models/account/account-blocklist.ts b/server/models/account/account-blocklist.ts index 577b7dc19..fe9168ab8 100644 --- a/server/models/account/account-blocklist.ts +++ b/server/models/account/account-blocklist.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird' import { Op } from 'sequelize' import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/types/models' @@ -41,7 +40,7 @@ enum ScopeNames { } ] }) -export class AccountBlocklistModel extends Model { +export class AccountBlocklistModel extends Model { @CreatedAt createdAt: Date @@ -102,7 +101,7 @@ export class AccountBlocklistModel extends Model { }) } - static loadByAccountAndTarget (accountId: number, targetAccountId: number): Bluebird { + static loadByAccountAndTarget (accountId: number, targetAccountId: number): Promise { const query = { where: { accountId, @@ -151,9 +150,9 @@ export class AccountBlocklistModel extends Model { }) } - static listHandlesBlockedBy (accountIds: number[]): Bluebird { + static listHandlesBlockedBy (accountIds: number[]): Promise { const query = { - attributes: [], + attributes: [ 'id' ], where: { accountId: { [Op.in]: accountIds diff --git a/server/models/account/account-video-rate.ts b/server/models/account/account-video-rate.ts index 6955f45ee..d9c529491 100644 --- a/server/models/account/account-video-rate.ts +++ b/server/models/account/account-video-rate.ts @@ -1,22 +1,21 @@ import { values } from 'lodash' -import { FindOptions, Op, Transaction } from 'sequelize' +import { FindOptions, Op, QueryTypes, Transaction } from 'sequelize' import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' -import { VideoRateType } from '../../../shared/models/videos' -import { CONSTRAINTS_FIELDS, VIDEO_RATE_TYPES } from '../../initializers/constants' -import { VideoModel } from '../video/video' -import { AccountModel } from './account' -import { ActorModel } from '../activitypub/actor' -import { buildLocalAccountIdsIn, getSort, throwIfNotValid } from '../utils' -import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' -import { AccountVideoRate } from '../../../shared' -import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from '../video/video-channel' -import * as Bluebird from 'bluebird' import { MAccountVideoRate, MAccountVideoRateAccountUrl, MAccountVideoRateAccountVideo, MAccountVideoRateFormattable } from '@server/types/models/video/video-rate' +import { AccountVideoRate } from '../../../shared' +import { VideoRateType } from '../../../shared/models/videos' +import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' +import { CONSTRAINTS_FIELDS, VIDEO_RATE_TYPES } from '../../initializers/constants' +import { ActorModel } from '../activitypub/actor' +import { buildLocalAccountIdsIn, getSort, throwIfNotValid } from '../utils' +import { VideoModel } from '../video/video' +import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from '../video/video-channel' +import { AccountModel } from './account' /* Account rates per video. @@ -43,7 +42,7 @@ import { } ] }) -export class AccountVideoRateModel extends Model { +export class AccountVideoRateModel extends Model { @AllowNull(false) @Column(DataType.ENUM(...values(VIDEO_RATE_TYPES))) @@ -84,7 +83,7 @@ export class AccountVideoRateModel extends Model { }) Account: AccountModel - static load (accountId: number, videoId: number, transaction?: Transaction): Bluebird { + static load (accountId: number, videoId: number, transaction?: Transaction): Promise { const options: FindOptions = { where: { accountId, @@ -96,7 +95,7 @@ export class AccountVideoRateModel extends Model { return AccountVideoRateModel.findOne(options) } - static loadByAccountAndVideoOrUrl (accountId: number, videoId: number, url: string, t?: Transaction): Bluebird { + static loadByAccountAndVideoOrUrl (accountId: number, videoId: number, url: string, t?: Transaction): Promise { const options: FindOptions = { where: { [Op.or]: [ @@ -152,7 +151,7 @@ export class AccountVideoRateModel extends Model { accountName: string, videoId: number | string, t?: Transaction - ): Bluebird { + ): Promise { const options: FindOptions = { where: { videoId, @@ -240,17 +239,23 @@ export class AccountVideoRateModel extends Model { transaction: t } - const deleted = await AccountVideoRateModel.destroy(query) + await AccountVideoRateModel.destroy(query) - const options = { + const field = type === 'like' + ? 'likes' + : 'dislikes' + + const rawQuery = `UPDATE "video" SET "${field}" = ` + + '(' + + 'SELECT COUNT(id) FROM "accountVideoRate" WHERE "accountVideoRate"."videoId" = "video"."id" AND type = :rateType' + + ') ' + + 'WHERE "video"."id" = :videoId' + + return AccountVideoRateModel.sequelize.query(rawQuery, { transaction: t, - where: { - id: videoId - } - } - - if (type === 'like') await VideoModel.increment({ likes: -deleted }, options) - else if (type === 'dislike') await VideoModel.increment({ dislikes: -deleted }, options) + replacements: { videoId, rateType: type }, + type: QueryTypes.UPDATE + }) }) } diff --git a/server/models/account/account.ts b/server/models/account/account.ts index 8c244d432..c72f9c63d 100644 --- a/server/models/account/account.ts +++ b/server/models/account/account.ts @@ -1,5 +1,4 @@ -import * as Bluebird from 'bluebird' -import { FindOptions, IncludeOptions, Op, Transaction, WhereOptions } from 'sequelize' +import { FindOptions, Includeable, IncludeOptions, Op, Transaction, WhereOptions } from 'sequelize' import { AllowNull, BeforeDestroy, @@ -73,28 +72,29 @@ export type SummaryOptions = { required: false } - const query: FindOptions = { - attributes: [ 'id', 'name', 'actorId' ], - include: [ - { - attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ], - model: ActorModel.unscoped(), - required: options.actorRequired ?? true, - where: whereActor, - include: [ - serverInclude, + const queryInclude: Includeable[] = [ + { + attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ], + model: ActorModel.unscoped(), + required: options.actorRequired ?? true, + where: whereActor, + include: [ + serverInclude, - { - model: AvatarModel.unscoped(), - required: false - } - ] - } - ] + { + model: AvatarModel.unscoped(), + required: false + } + ] + } + ] + + const query: FindOptions = { + attributes: [ 'id', 'name', 'actorId' ] } if (options.withAccountBlockerIds) { - query.include.push({ + queryInclude.push({ attributes: [ 'id' ], model: AccountBlocklistModel.unscoped(), as: 'BlockedAccounts', @@ -120,6 +120,8 @@ export type SummaryOptions = { ] } + query.include = queryInclude + return query } })) @@ -138,7 +140,7 @@ export type SummaryOptions = { } ] }) -export class AccountModel extends Model { +export class AccountModel extends Model { @AllowNull(false) @Column @@ -244,11 +246,11 @@ export class AccountModel extends Model { return undefined } - static load (id: number, transaction?: Transaction): Bluebird { + static load (id: number, transaction?: Transaction): Promise { return AccountModel.findByPk(id, { transaction }) } - static loadByNameWithHost (nameWithHost: string): Bluebird { + static loadByNameWithHost (nameWithHost: string): Promise { const [ accountName, host ] = nameWithHost.split('@') if (!host || host === WEBSERVER.HOST) return AccountModel.loadLocalByName(accountName) @@ -256,7 +258,7 @@ export class AccountModel extends Model { return AccountModel.loadByNameAndHost(accountName, host) } - static loadLocalByName (name: string): Bluebird { + static loadLocalByName (name: string): Promise { const fun = () => { const query = { where: { @@ -296,7 +298,7 @@ export class AccountModel extends Model { }) } - static loadByNameAndHost (name: string, host: string): Bluebird { + static loadByNameAndHost (name: string, host: string): Promise { const query = { include: [ { @@ -321,7 +323,7 @@ export class AccountModel extends Model { return AccountModel.findOne(query) } - static loadByUrl (url: string, transaction?: Transaction): Bluebird { + static loadByUrl (url: string, transaction?: Transaction): Promise { const query = { include: [ { @@ -354,7 +356,7 @@ export class AccountModel extends Model { }) } - static loadAccountIdFromVideo (videoId: number): Bluebird { + static loadAccountIdFromVideo (videoId: number): Promise { const query = { include: [ { @@ -377,7 +379,7 @@ export class AccountModel extends Model { return AccountModel.findOne(query) } - static listLocalsForSitemap (sort: string): Bluebird { + static listLocalsForSitemap (sort: string): Promise { const query = { attributes: [ ], offset: 0, diff --git a/server/models/account/user-notification-setting.ts b/server/models/account/user-notification-setting.ts index acc192d53..ebab8b6d2 100644 --- a/server/models/account/user-notification-setting.ts +++ b/server/models/account/user-notification-setting.ts @@ -28,7 +28,7 @@ import { UserModel } from './user' } ] }) -export class UserNotificationSettingModel extends Model { +export class UserNotificationSettingModel extends Model { @AllowNull(false) @Default(null) diff --git a/server/models/account/user-notification.ts b/server/models/account/user-notification.ts index 452574dc8..52b792a5b 100644 --- a/server/models/account/user-notification.ts +++ b/server/models/account/user-notification.ts @@ -254,7 +254,7 @@ function buildAccountInclude (required: boolean, withActor = false) { } ] as (ModelIndexesOptions & { where?: WhereOptions })[] }) -export class UserNotificationModel extends Model { +export class UserNotificationModel extends Model { @AllowNull(false) @Default(null) diff --git a/server/models/account/user-video-history.ts b/server/models/account/user-video-history.ts index 76b469fbf..45171fc60 100644 --- a/server/models/account/user-video-history.ts +++ b/server/models/account/user-video-history.ts @@ -19,7 +19,7 @@ import { MUserAccountId, MUserId } from '@server/types/models' } ] }) -export class UserVideoHistoryModel extends Model { +export class UserVideoHistoryModel extends Model { @CreatedAt createdAt: Date diff --git a/server/models/account/user.ts b/server/models/account/user.ts index 10117099b..8e437c3be 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird' import { values } from 'lodash' import { col, FindOptions, fn, literal, Op, QueryTypes, where, WhereOptions } from 'sequelize' import { @@ -16,11 +15,11 @@ import { HasOne, Is, IsEmail, + IsUUID, Model, Scopes, Table, - UpdatedAt, - IsUUID + UpdatedAt } from 'sequelize-typescript' import { MMyUserFormattable, @@ -220,7 +219,7 @@ enum ScopeNames { } ] }) -export class UserModel extends Model { +export class UserModel extends Model { @AllowNull(true) @Is('UserPassword', value => throwIfNotValid(value, isUserPasswordValid, 'user password', true)) @@ -483,7 +482,7 @@ export class UserModel extends Model { }) } - static listWithRight (right: UserRight): Bluebird { + static listWithRight (right: UserRight): Promise { const roles = Object.keys(USER_ROLE_LABELS) .map(k => parseInt(k, 10) as UserRole) .filter(role => hasUserRight(role, right)) @@ -499,7 +498,7 @@ export class UserModel extends Model { return UserModel.findAll(query) } - static listUserSubscribersOf (actorId: number): Bluebird { + static listUserSubscribersOf (actorId: number): Promise { const query = { include: [ { @@ -538,7 +537,7 @@ export class UserModel extends Model { return UserModel.unscoped().findAll(query) } - static listByUsernames (usernames: string[]): Bluebird { + static listByUsernames (usernames: string[]): Promise { const query = { where: { username: usernames @@ -548,11 +547,11 @@ export class UserModel extends Model { return UserModel.findAll(query) } - static loadById (id: number): Bluebird { + static loadById (id: number): Promise { return UserModel.unscoped().findByPk(id) } - static loadByIdWithChannels (id: number, withStats = false): Bluebird { + static loadByIdWithChannels (id: number, withStats = false): Promise { const scopes = [ ScopeNames.WITH_VIDEOCHANNELS ] @@ -562,7 +561,7 @@ export class UserModel extends Model { return UserModel.scope(scopes).findByPk(id) } - static loadByUsername (username: string): Bluebird { + static loadByUsername (username: string): Promise { const query = { where: { username: { [Op.iLike]: username } @@ -572,7 +571,7 @@ export class UserModel extends Model { return UserModel.findOne(query) } - static loadForMeAPI (username: string): Bluebird { + static loadForMeAPI (username: string): Promise { const query = { where: { username: { [Op.iLike]: username } @@ -582,7 +581,7 @@ export class UserModel extends Model { return UserModel.scope(ScopeNames.FOR_ME_API).findOne(query) } - static loadByEmail (email: string): Bluebird { + static loadByEmail (email: string): Promise { const query = { where: { email @@ -592,7 +591,7 @@ export class UserModel extends Model { return UserModel.findOne(query) } - static loadByUsernameOrEmail (username: string, email?: string): Bluebird { + static loadByUsernameOrEmail (username: string, email?: string): Promise { if (!email) email = username const query = { @@ -608,7 +607,7 @@ export class UserModel extends Model { return UserModel.findOne(query) } - static loadByVideoId (videoId: number): Bluebird { + static loadByVideoId (videoId: number): Promise { const query = { include: [ { @@ -639,7 +638,7 @@ export class UserModel extends Model { return UserModel.findOne(query) } - static loadByVideoImportId (videoImportId: number): Bluebird { + static loadByVideoImportId (videoImportId: number): Promise { const query = { include: [ { @@ -656,7 +655,7 @@ export class UserModel extends Model { return UserModel.findOne(query) } - static loadByChannelActorId (videoChannelActorId: number): Bluebird { + static loadByChannelActorId (videoChannelActorId: number): Promise { const query = { include: [ { @@ -680,7 +679,7 @@ export class UserModel extends Model { return UserModel.findOne(query) } - static loadByAccountActorId (accountActorId: number): Bluebird { + static loadByAccountActorId (accountActorId: number): Promise { const query = { include: [ { @@ -697,7 +696,7 @@ export class UserModel extends Model { return UserModel.findOne(query) } - static loadByLiveId (liveId: number): Bluebird { + static loadByLiveId (liveId: number): Promise { const query = { include: [ { diff --git a/server/models/activitypub/actor-follow.ts b/server/models/activitypub/actor-follow.ts index 58bc63d34..ce6a4e267 100644 --- a/server/models/activitypub/actor-follow.ts +++ b/server/models/activitypub/actor-follow.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird' import { difference, values } from 'lodash' import { IncludeOptions, Op, QueryTypes, Transaction, WhereOptions } from 'sequelize' import { @@ -62,7 +61,7 @@ import { ActorModel, unusedActorAttributesForAPI } from './actor' } ] }) -export class ActorFollowModel extends Model { +export class ActorFollowModel extends Model { @AllowNull(false) @Column(DataType.ENUM(...values(FOLLOW_STATES))) @@ -176,7 +175,7 @@ export class ActorFollowModel extends Model { .then(results => results.length === 1) } - static loadByActorAndTarget (actorId: number, targetActorId: number, t?: Transaction): Bluebird { + static loadByActorAndTarget (actorId: number, targetActorId: number, t?: Transaction): Promise { const query = { where: { actorId, @@ -205,7 +204,7 @@ export class ActorFollowModel extends Model { targetName: string, targetHost: string, t?: Transaction - ): Bluebird { + ): Promise { const actorFollowingPartInclude: IncludeOptions = { model: ActorModel, required: true, @@ -258,7 +257,7 @@ export class ActorFollowModel extends Model { }) } - static listSubscribedIn (actorId: number, targets: { name: string, host?: string }[]): Bluebird { + static listSubscribedIn (actorId: number, targets: { name: string, host?: string }[]): Promise { const whereTab = targets .map(t => { if (t.host) { @@ -287,7 +286,7 @@ export class ActorFollowModel extends Model { }) const query = { - attributes: [], + attributes: [ 'id' ], where: { [Op.and]: [ { @@ -671,7 +670,7 @@ export class ActorFollowModel extends Model { selections.push('COUNT(*) AS "total"') - const tasks: Bluebird[] = [] + const tasks: Promise[] = [] for (const selection of selections) { let query = 'SELECT ' + selection + ' FROM "actor" ' + diff --git a/server/models/activitypub/actor.ts b/server/models/activitypub/actor.ts index a2fee0012..3b98e8841 100644 --- a/server/models/activitypub/actor.ts +++ b/server/models/activitypub/actor.ts @@ -1,5 +1,6 @@ import { values } from 'lodash' import { extname } from 'path' +import { literal, Op, Transaction } from 'sequelize' import { AllowNull, BelongsTo, @@ -16,6 +17,7 @@ import { Table, UpdatedAt } from 'sequelize-typescript' +import { ModelCache } from '@server/models/model-cache' import { ActivityIconObject, ActivityPubActorType } from '../../../shared/models/activitypub' import { Avatar } from '../../../shared/models/avatars/avatar.model' import { activityPubContextify } from '../../helpers/activitypub' @@ -28,13 +30,6 @@ import { } from '../../helpers/custom-validators/activitypub/actor' import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' import { ACTIVITY_PUB, ACTIVITY_PUB_ACTOR_TYPES, CONSTRAINTS_FIELDS, SERVER_ACTOR_NAME, WEBSERVER } from '../../initializers/constants' -import { AccountModel } from '../account/account' -import { AvatarModel } from '../avatar/avatar' -import { ServerModel } from '../server/server' -import { isOutdated, throwIfNotValid } from '../utils' -import { VideoChannelModel } from '../video/video-channel' -import { ActorFollowModel } from './actor-follow' -import { VideoModel } from '../video/video' import { MActor, MActorAccountChannelId, @@ -43,12 +38,17 @@ import { MActorFull, MActorHost, MActorServer, - MActorSummaryFormattable, MActorUrl, + MActorSummaryFormattable, + MActorUrl, MActorWithInboxes } from '../../types/models' -import * as Bluebird from 'bluebird' -import { Op, Transaction, literal } from 'sequelize' -import { ModelCache } from '@server/models/model-cache' +import { AccountModel } from '../account/account' +import { AvatarModel } from '../avatar/avatar' +import { ServerModel } from '../server/server' +import { isOutdated, throwIfNotValid } from '../utils' +import { VideoModel } from '../video/video' +import { VideoChannelModel } from '../video/video-channel' +import { ActorFollowModel } from './actor-follow' enum ScopeNames { FULL = 'FULL' @@ -146,7 +146,7 @@ export const unusedActorAttributesForAPI = [ } ] }) -export class ActorModel extends Model { +export class ActorModel extends Model { @AllowNull(false) @Column(DataType.ENUM(...values(ACTIVITY_PUB_ACTOR_TYPES))) @@ -276,15 +276,15 @@ export class ActorModel extends Model { }) VideoChannel: VideoChannelModel - static load (id: number): Bluebird { + static load (id: number): Promise { return ActorModel.unscoped().findByPk(id) } - static loadFull (id: number): Bluebird { + static loadFull (id: number): Promise { return ActorModel.scope(ScopeNames.FULL).findByPk(id) } - static loadFromAccountByVideoId (videoId: number, transaction: Transaction): Bluebird { + static loadFromAccountByVideoId (videoId: number, transaction: Transaction): Promise { const query = { include: [ { @@ -328,7 +328,7 @@ export class ActorModel extends Model { .then(a => !!a) } - static listByFollowersUrls (followersUrls: string[], transaction?: Transaction): Bluebird { + static listByFollowersUrls (followersUrls: string[], transaction?: Transaction): Promise { const query = { where: { followersUrl: { @@ -341,7 +341,7 @@ export class ActorModel extends Model { return ActorModel.scope(ScopeNames.FULL).findAll(query) } - static loadLocalByName (preferredUsername: string, transaction?: Transaction): Bluebird { + static loadLocalByName (preferredUsername: string, transaction?: Transaction): Promise { const fun = () => { const query = { where: { @@ -364,7 +364,7 @@ export class ActorModel extends Model { }) } - static loadLocalUrlByName (preferredUsername: string, transaction?: Transaction): Bluebird { + static loadLocalUrlByName (preferredUsername: string, transaction?: Transaction): Promise { const fun = () => { const query = { attributes: [ 'url' ], @@ -388,7 +388,7 @@ export class ActorModel extends Model { }) } - static loadByNameAndHost (preferredUsername: string, host: string): Bluebird { + static loadByNameAndHost (preferredUsername: string, host: string): Promise { const query = { where: { preferredUsername @@ -407,7 +407,7 @@ export class ActorModel extends Model { return ActorModel.scope(ScopeNames.FULL).findOne(query) } - static loadByUrl (url: string, transaction?: Transaction): Bluebird { + static loadByUrl (url: string, transaction?: Transaction): Promise { const query = { where: { url @@ -430,7 +430,7 @@ export class ActorModel extends Model { return ActorModel.unscoped().findOne(query) } - static loadByUrlAndPopulateAccountAndChannel (url: string, transaction?: Transaction): Bluebird { + static loadByUrlAndPopulateAccountAndChannel (url: string, transaction?: Transaction): Promise { const query = { where: { url @@ -461,7 +461,7 @@ export class ActorModel extends Model { }, { where, transaction }) } - static loadAccountActorByVideoId (videoId: number): Bluebird { + static loadAccountActorByVideoId (videoId: number): Promise { const query = { include: [ { diff --git a/server/models/application/application.ts b/server/models/application/application.ts index 3bba2c70e..909569de1 100644 --- a/server/models/application/application.ts +++ b/server/models/application/application.ts @@ -24,7 +24,7 @@ export const getServerActor = memoizee(async function () { tableName: 'application', timestamps: false }) -export class ApplicationModel extends Model { +export class ApplicationModel extends Model { @AllowNull(false) @Default(0) diff --git a/server/models/avatar/avatar.ts b/server/models/avatar/avatar.ts index d874dec99..0d246a144 100644 --- a/server/models/avatar/avatar.ts +++ b/server/models/avatar/avatar.ts @@ -18,7 +18,7 @@ import { MAvatarFormattable } from '@server/types/models' } ] }) -export class AvatarModel extends Model { +export class AvatarModel extends Model { @AllowNull(false) @Column diff --git a/server/models/model-cache.ts b/server/models/model-cache.ts index a87f99aa2..eafb5c13c 100644 --- a/server/models/model-cache.ts +++ b/server/models/model-cache.ts @@ -40,7 +40,7 @@ class ModelCache { doCache (options: { cacheType: ModelCacheType key: string - fun: () => Bluebird + fun: () => Promise whitelist?: () => boolean deleteKey?: DeleteKey }) { diff --git a/server/models/oauth/oauth-client.ts b/server/models/oauth/oauth-client.ts index 42c59bb79..8dbc1c2f5 100644 --- a/server/models/oauth/oauth-client.ts +++ b/server/models/oauth/oauth-client.ts @@ -14,7 +14,7 @@ import { OAuthTokenModel } from './oauth-token' } ] }) -export class OAuthClientModel extends Model { +export class OAuthClientModel extends Model { @AllowNull(false) @Column diff --git a/server/models/oauth/oauth-token.ts b/server/models/oauth/oauth-token.ts index 7f2313dad..6bc6cf27c 100644 --- a/server/models/oauth/oauth-token.ts +++ b/server/models/oauth/oauth-token.ts @@ -1,3 +1,4 @@ +import { Transaction } from 'sequelize' import { AfterDestroy, AfterUpdate, @@ -11,15 +12,13 @@ import { Table, UpdatedAt } from 'sequelize-typescript' -import { logger } from '../../helpers/logger' -import { UserModel } from '../account/user' -import { OAuthClientModel } from './oauth-client' -import { Transaction } from 'sequelize' -import { AccountModel } from '../account/account' -import { ActorModel } from '../activitypub/actor' -import { clearCacheByToken } from '../../lib/oauth-model' -import * as Bluebird from 'bluebird' import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token' +import { logger } from '../../helpers/logger' +import { clearCacheByToken } from '../../lib/oauth-model' +import { AccountModel } from '../account/account' +import { UserModel } from '../account/user' +import { ActorModel } from '../activitypub/actor' +import { OAuthClientModel } from './oauth-client' export type OAuthTokenInfo = { refreshToken: string @@ -80,7 +79,7 @@ enum ScopeNames { } ] }) -export class OAuthTokenModel extends Model { +export class OAuthTokenModel extends Model { @AllowNull(false) @Column @@ -174,7 +173,7 @@ export class OAuthTokenModel extends Model { }) } - static getByTokenAndPopulateUser (bearerToken: string): Bluebird { + static getByTokenAndPopulateUser (bearerToken: string): Promise { const query = { where: { accessToken: bearerToken @@ -190,7 +189,7 @@ export class OAuthTokenModel extends Model { }) } - static getByRefreshTokenAndPopulateUser (refreshToken: string): Bluebird { + static getByRefreshTokenAndPopulateUser (refreshToken: string): Promise { const query = { where: { refreshToken diff --git a/server/models/redundancy/video-redundancy.ts b/server/models/redundancy/video-redundancy.ts index 1b967996c..fa96a1e39 100644 --- a/server/models/redundancy/video-redundancy.ts +++ b/server/models/redundancy/video-redundancy.ts @@ -1,3 +1,5 @@ +import { sample } from 'lodash' +import { col, FindOptions, fn, literal, Op, Transaction, WhereOptions } from 'sequelize' import { AllowNull, BeforeDestroy, @@ -12,23 +14,7 @@ import { Table, UpdatedAt } from 'sequelize-typescript' -import { ActorModel } from '../activitypub/actor' -import { getSort, getVideoSort, parseAggregateResult, throwIfNotValid } from '../utils' -import { isActivityPubUrlValid, isUrlValid } from '../../helpers/custom-validators/activitypub/misc' -import { CONSTRAINTS_FIELDS, MIMETYPES } from '../../initializers/constants' -import { VideoFileModel } from '../video/video-file' -import { VideoModel } from '../video/video' -import { VideoRedundancyStrategy, VideoRedundancyStrategyWithManual } from '../../../shared/models/redundancy' -import { logger } from '../../helpers/logger' -import { CacheFileObject, VideoPrivacy } from '../../../shared' -import { VideoChannelModel } from '../video/video-channel' -import { ServerModel } from '../server/server' -import { sample } from 'lodash' -import { isTestInstance } from '../../helpers/core-utils' -import * as Bluebird from 'bluebird' -import { col, FindOptions, fn, literal, Op, Transaction, WhereOptions } from 'sequelize' -import { VideoStreamingPlaylistModel } from '../video/video-streaming-playlist' -import { CONFIG } from '../../initializers/config' +import { getServerActor } from '@server/models/application/application' import { MVideoForRedundancyAPI, MVideoRedundancy, MVideoRedundancyAP, MVideoRedundancyVideo } from '@server/types/models' import { VideoRedundanciesTarget } from '@shared/models/redundancy/video-redundancies-filters.model' import { @@ -36,7 +22,20 @@ import { StreamingPlaylistRedundancyInformation, VideoRedundancy } from '@shared/models/redundancy/video-redundancy.model' -import { getServerActor } from '@server/models/application/application' +import { CacheFileObject, VideoPrivacy } from '../../../shared' +import { VideoRedundancyStrategy, VideoRedundancyStrategyWithManual } from '../../../shared/models/redundancy' +import { isTestInstance } from '../../helpers/core-utils' +import { isActivityPubUrlValid, isUrlValid } from '../../helpers/custom-validators/activitypub/misc' +import { logger } from '../../helpers/logger' +import { CONFIG } from '../../initializers/config' +import { CONSTRAINTS_FIELDS, MIMETYPES } from '../../initializers/constants' +import { ActorModel } from '../activitypub/actor' +import { ServerModel } from '../server/server' +import { getSort, getVideoSort, parseAggregateResult, throwIfNotValid } from '../utils' +import { VideoModel } from '../video/video' +import { VideoChannelModel } from '../video/video-channel' +import { VideoFileModel } from '../video/video-file' +import { VideoStreamingPlaylistModel } from '../video/video-streaming-playlist' export enum ScopeNames { WITH_VIDEO = 'WITH_VIDEO' @@ -84,7 +83,7 @@ export enum ScopeNames { } ] }) -export class VideoRedundancyModel extends Model { +export class VideoRedundancyModel extends Model { @CreatedAt createdAt: Date @@ -199,7 +198,7 @@ export class VideoRedundancyModel extends Model { return VideoRedundancyModel.scope(ScopeNames.WITH_VIDEO).findOne(query) } - static loadByIdWithVideo (id: number, transaction?: Transaction): Bluebird { + static loadByIdWithVideo (id: number, transaction?: Transaction): Promise { const query = { where: { id }, transaction @@ -208,7 +207,7 @@ export class VideoRedundancyModel extends Model { return VideoRedundancyModel.scope(ScopeNames.WITH_VIDEO).findOne(query) } - static loadByUrl (url: string, transaction?: Transaction): Bluebird { + static loadByUrl (url: string, transaction?: Transaction): Promise { const query = { where: { url @@ -251,7 +250,7 @@ export class VideoRedundancyModel extends Model { .then(r => !!r) } - static async getVideoSample (p: Bluebird) { + static async getVideoSample (p: Promise) { const rows = await p if (rows.length === 0) return undefined @@ -696,7 +695,7 @@ export class VideoRedundancyModel extends Model { const notIn = literal( '(' + - `SELECT "videoFileId" FROM "videoRedundancy" WHERE "actorId" = ${actor.id} AND "videoFileId" IS NOT NULL` + + `SELECT "videoFileId" FROM "videoRedundancy" WHERE "actorId" = ${actor.id} AND "videoFileId" IS NOT NULL` + ')' ) diff --git a/server/models/server/plugin.ts b/server/models/server/plugin.ts index 95fb386b5..82387af6a 100644 --- a/server/models/server/plugin.ts +++ b/server/models/server/plugin.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird' import { FindAndCountOptions, json, QueryTypes } from 'sequelize' import { AllowNull, Column, CreatedAt, DataType, DefaultScope, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' import { MPlugin, MPluginFormattable } from '@server/types/models' @@ -29,7 +28,7 @@ import { getSort, throwIfNotValid } from '../utils' } ] }) -export class PluginModel extends Model { +export class PluginModel extends Model { @AllowNull(false) @Is('PluginName', value => throwIfNotValid(value, isPluginNameValid, 'name')) @@ -87,7 +86,7 @@ export class PluginModel extends Model { @UpdatedAt updatedAt: Date - static listEnabledPluginsAndThemes (): Bluebird { + static listEnabledPluginsAndThemes (): Promise { const query = { where: { enabled: true, @@ -98,7 +97,7 @@ export class PluginModel extends Model { return PluginModel.findAll(query) } - static loadByNpmName (npmName: string): Bluebird { + static loadByNpmName (npmName: string): Promise { const name = this.normalizePluginName(npmName) const type = this.getTypeFromNpmName(npmName) @@ -252,7 +251,7 @@ export class PluginModel extends Model { }) } - static listInstalled (): Bluebird { + static listInstalled (): Promise { const query = { where: { uninstalled: false diff --git a/server/models/server/server-blocklist.ts b/server/models/server/server-blocklist.ts index 68cd72ee7..4dc236537 100644 --- a/server/models/server/server-blocklist.ts +++ b/server/models/server/server-blocklist.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird' import { Op } from 'sequelize' import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/types/models' @@ -43,7 +42,7 @@ enum ScopeNames { } ] }) -export class ServerBlocklistModel extends Model { +export class ServerBlocklistModel extends Model { @CreatedAt createdAt: Date @@ -101,7 +100,7 @@ export class ServerBlocklistModel extends Model { }) } - static loadByAccountAndHost (accountId: number, host: string): Bluebird { + static loadByAccountAndHost (accountId: number, host: string): Promise { const query = { where: { accountId @@ -120,7 +119,7 @@ export class ServerBlocklistModel extends Model { return ServerBlocklistModel.findOne(query) } - static listHostsBlockedBy (accountIds: number[]): Bluebird { + static listHostsBlockedBy (accountIds: number[]): Promise { const query = { attributes: [ ], where: { diff --git a/server/models/server/server.ts b/server/models/server/server.ts index 771200797..0e58beeaf 100644 --- a/server/models/server/server.ts +++ b/server/models/server/server.ts @@ -1,10 +1,9 @@ import { AllowNull, Column, CreatedAt, Default, HasMany, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' +import { MServer, MServerFormattable } from '@server/types/models/server' import { isHostValid } from '../../helpers/custom-validators/servers' import { ActorModel } from '../activitypub/actor' import { throwIfNotValid } from '../utils' import { ServerBlocklistModel } from './server-blocklist' -import * as Bluebird from 'bluebird' -import { MServer, MServerFormattable } from '@server/types/models/server' @Table({ tableName: 'server', @@ -15,7 +14,7 @@ import { MServer, MServerFormattable } from '@server/types/models/server' } ] }) -export class ServerModel extends Model { +export class ServerModel extends Model { @AllowNull(false) @Is('Host', value => throwIfNotValid(value, isHostValid, 'valid host')) @@ -51,7 +50,7 @@ export class ServerModel extends Model { }) BlockedByAccounts: ServerBlocklistModel[] - static load (id: number): Bluebird { + static load (id: number): Promise { const query = { where: { id @@ -61,7 +60,7 @@ export class ServerModel extends Model { return ServerModel.findOne(query) } - static loadByHost (host: string): Bluebird { + static loadByHost (host: string): Promise { const query = { where: { host diff --git a/server/models/utils.ts b/server/models/utils.ts index a06d57831..143c1a23c 100644 --- a/server/models/utils.ts +++ b/server/models/utils.ts @@ -113,7 +113,8 @@ function throwIfNotValid (value: any, validator: (value: any) => boolean, fieldN function buildTrigramSearchIndex (indexName: string, attribute: string) { return { name: indexName, - fields: [ Sequelize.literal('lower(immutable_unaccent(' + attribute + '))') as any ], + // FIXME: gin_trgm_ops is not taken into account in Sequelize 6, so adding it ourselves in the literal function + fields: [ Sequelize.literal('lower(immutable_unaccent(' + attribute + ')) gin_trgm_ops') as any ], using: 'gin', operator: 'gin_trgm_ops' } diff --git a/server/models/video/schedule-video-update.ts b/server/models/video/schedule-video-update.ts index 1ce6bbfe5..22b08e91a 100644 --- a/server/models/video/schedule-video-update.ts +++ b/server/models/video/schedule-video-update.ts @@ -16,7 +16,7 @@ import { MScheduleVideoUpdateFormattable, MScheduleVideoUpdateVideoAll } from '@ } ] }) -export class ScheduleVideoUpdateModel extends Model { +export class ScheduleVideoUpdateModel extends Model { @AllowNull(false) @Default(null) diff --git a/server/models/video/tag.ts b/server/models/video/tag.ts index adbc4fb7d..d04205703 100644 --- a/server/models/video/tag.ts +++ b/server/models/video/tag.ts @@ -1,12 +1,11 @@ -import * as Bluebird from 'bluebird' -import { fn, QueryTypes, Transaction, col } from 'sequelize' +import { col, fn, QueryTypes, Transaction } from 'sequelize' import { AllowNull, BelongsToMany, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' +import { MTag } from '@server/types/models' +import { VideoPrivacy, VideoState } from '../../../shared/models/videos' import { isVideoTagValid } from '../../helpers/custom-validators/videos' import { throwIfNotValid } from '../utils' import { VideoModel } from './video' import { VideoTagModel } from './video-tag' -import { VideoPrivacy, VideoState } from '../../../shared/models/videos' -import { MTag } from '@server/types/models' @Table({ tableName: 'tag', @@ -22,7 +21,7 @@ import { MTag } from '@server/types/models' } ] }) -export class TagModel extends Model { +export class TagModel extends Model { @AllowNull(false) @Is('VideoTag', value => throwIfNotValid(value, isVideoTagValid, 'tag')) @@ -45,7 +44,7 @@ export class TagModel extends Model { static findOrCreateTags (tags: string[], transaction: Transaction): Promise { if (tags === null) return Promise.resolve([]) - const tasks: Bluebird[] = [] + const tasks: Promise[] = [] tags.forEach(tag => { const query = { where: { @@ -66,7 +65,7 @@ export class TagModel extends Model { } // threshold corresponds to how many video the field should have to be returned - static getRandomSamples (threshold: number, count: number): Bluebird { + static getRandomSamples (threshold: number, count: number): Promise { const query = 'SELECT tag.name FROM tag ' + 'INNER JOIN "videoTag" ON "videoTag"."tagId" = tag.id ' + 'INNER JOIN video ON video.id = "videoTag"."videoId" ' + diff --git a/server/models/video/thumbnail.ts b/server/models/video/thumbnail.ts index 20c1e5858..6878a3155 100644 --- a/server/models/video/thumbnail.ts +++ b/server/models/video/thumbnail.ts @@ -34,7 +34,7 @@ import { buildRemoteVideoBaseUrl } from '@server/helpers/activitypub' } ] }) -export class ThumbnailModel extends Model { +export class ThumbnailModel extends Model { @AllowNull(false) @Column diff --git a/server/models/video/video-blacklist.ts b/server/models/video/video-blacklist.ts index 36d2a30fa..aa18896da 100644 --- a/server/models/video/video-blacklist.ts +++ b/server/models/video/video-blacklist.ts @@ -1,14 +1,13 @@ +import { FindOptions } from 'sequelize' import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' -import { getBlacklistSort, SortType, throwIfNotValid, searchAttribute } from '../utils' +import { MVideoBlacklist, MVideoBlacklistFormattable } from '@server/types/models' +import { VideoBlacklist, VideoBlacklistType } from '../../../shared/models/videos' +import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist' +import { CONSTRAINTS_FIELDS } from '../../initializers/constants' +import { getBlacklistSort, searchAttribute, SortType, throwIfNotValid } from '../utils' +import { ThumbnailModel } from './thumbnail' import { VideoModel } from './video' import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel' -import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist' -import { VideoBlacklist, VideoBlacklistType } from '../../../shared/models/videos' -import { CONSTRAINTS_FIELDS } from '../../initializers/constants' -import { FindOptions } from 'sequelize' -import { ThumbnailModel } from './thumbnail' -import * as Bluebird from 'bluebird' -import { MVideoBlacklist, MVideoBlacklistFormattable } from '@server/types/models' @Table({ tableName: 'videoBlacklist', @@ -19,7 +18,7 @@ import { MVideoBlacklist, MVideoBlacklistFormattable } from '@server/types/model } ] }) -export class VideoBlacklistModel extends Model { +export class VideoBlacklistModel extends Model { @AllowNull(true) @Is('VideoBlacklistReason', value => throwIfNotValid(value, isVideoBlacklistReasonValid, 'reason', true)) @@ -109,7 +108,7 @@ export class VideoBlacklistModel extends Model { }) } - static loadByVideoId (id: number): Bluebird { + static loadByVideoId (id: number): Promise { const query = { where: { videoId: id diff --git a/server/models/video/video-caption.ts b/server/models/video/video-caption.ts index b68a6e99f..e8e883dd0 100644 --- a/server/models/video/video-caption.ts +++ b/server/models/video/video-caption.ts @@ -1,3 +1,5 @@ +import { remove } from 'fs-extra' +import { join } from 'path' import { OrderItem, Transaction } from 'sequelize' import { AllowNull, @@ -13,18 +15,15 @@ import { Table, UpdatedAt } from 'sequelize-typescript' +import { buildRemoteVideoBaseUrl } from '@server/helpers/activitypub' +import { MVideoAccountLight, MVideoCaptionFormattable, MVideoCaptionVideo } from '@server/types/models' +import { VideoCaption } from '../../../shared/models/videos/caption/video-caption.model' +import { isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions' +import { logger } from '../../helpers/logger' +import { CONFIG } from '../../initializers/config' +import { CONSTRAINTS_FIELDS, LAZY_STATIC_PATHS, VIDEO_LANGUAGES, WEBSERVER } from '../../initializers/constants' import { buildWhereIdOrUUID, throwIfNotValid } from '../utils' import { VideoModel } from './video' -import { isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions' -import { VideoCaption } from '../../../shared/models/videos/caption/video-caption.model' -import { CONSTRAINTS_FIELDS, LAZY_STATIC_PATHS, VIDEO_LANGUAGES, WEBSERVER } from '../../initializers/constants' -import { join } from 'path' -import { logger } from '../../helpers/logger' -import { remove } from 'fs-extra' -import { CONFIG } from '../../initializers/config' -import * as Bluebird from 'bluebird' -import { MVideoAccountLight, MVideoCaptionFormattable, MVideoCaptionVideo } from '@server/types/models' -import { buildRemoteVideoBaseUrl } from '@server/helpers/activitypub' export enum ScopeNames { WITH_VIDEO_UUID_AND_REMOTE = 'WITH_VIDEO_UUID_AND_REMOTE' @@ -54,7 +53,7 @@ export enum ScopeNames { } ] }) -export class VideoCaptionModel extends Model { +export class VideoCaptionModel extends Model { @CreatedAt createdAt: Date @@ -101,7 +100,7 @@ export class VideoCaptionModel extends Model { return undefined } - static loadByVideoIdAndLanguage (videoId: string | number, language: string): Bluebird { + static loadByVideoIdAndLanguage (videoId: string | number, language: string): Promise { const videoInclude = { model: VideoModel.unscoped(), attributes: [ 'id', 'remote', 'uuid' ], @@ -131,7 +130,7 @@ export class VideoCaptionModel extends Model { .then(([ caption ]) => caption) } - static listVideoCaptions (videoId: number): Bluebird { + static listVideoCaptions (videoId: number): Promise { const query = { order: [ [ 'language', 'ASC' ] ] as OrderItem[], where: { diff --git a/server/models/video/video-change-ownership.ts b/server/models/video/video-change-ownership.ts index ac0ab7e8b..298e8bfe2 100644 --- a/server/models/video/video-change-ownership.ts +++ b/server/models/video/video-change-ownership.ts @@ -1,10 +1,9 @@ import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' -import { AccountModel } from '../account/account' -import { ScopeNames as VideoScopeNames, VideoModel } from './video' -import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '../../../shared/models/videos' -import { getSort } from '../utils' import { MVideoChangeOwnershipFormattable, MVideoChangeOwnershipFull } from '@server/types/models/video/video-change-ownership' -import * as Bluebird from 'bluebird' +import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '../../../shared/models/videos' +import { AccountModel } from '../account/account' +import { getSort } from '../utils' +import { ScopeNames as VideoScopeNames, VideoModel } from './video' enum ScopeNames { WITH_ACCOUNTS = 'WITH_ACCOUNTS', @@ -54,7 +53,7 @@ enum ScopeNames { ] } })) -export class VideoChangeOwnershipModel extends Model { +export class VideoChangeOwnershipModel extends Model { @CreatedAt createdAt: Date @@ -119,7 +118,7 @@ export class VideoChangeOwnershipModel extends Model ]).then(([ count, rows ]) => ({ total: count, data: rows })) } - static load (id: number): Bluebird { + static load (id: number): Promise { return VideoChangeOwnershipModel.scope([ ScopeNames.WITH_ACCOUNTS, ScopeNames.WITH_VIDEO ]) .findByPk(id) } diff --git a/server/models/video/video-channel.ts b/server/models/video/video-channel.ts index 0c8aef18f..178878c55 100644 --- a/server/models/video/video-channel.ts +++ b/server/models/video/video-channel.ts @@ -1,5 +1,4 @@ -import * as Bluebird from 'bluebird' -import { FindOptions, literal, Op, ScopeOptions } from 'sequelize' +import { FindOptions, Includeable, literal, Op, ScopeOptions } from 'sequelize' import { AllowNull, BeforeDestroy, @@ -119,30 +118,31 @@ export type SummaryOptions = { } }, [ScopeNames.SUMMARY]: (options: SummaryOptions = {}) => { + const include: Includeable[] = [ + { + attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ], + model: ActorModel.unscoped(), + required: options.actorRequired ?? true, + include: [ + { + attributes: [ 'host' ], + model: ServerModel.unscoped(), + required: false + }, + { + model: AvatarModel.unscoped(), + required: false + } + ] + } + ] + const base: FindOptions = { - attributes: [ 'id', 'name', 'description', 'actorId' ], - include: [ - { - attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ], - model: ActorModel.unscoped(), - required: options.actorRequired ?? true, - include: [ - { - attributes: [ 'host' ], - model: ServerModel.unscoped(), - required: false - }, - { - model: AvatarModel.unscoped(), - required: false - } - ] - } - ] + attributes: [ 'id', 'name', 'description', 'actorId' ] } if (options.withAccount === true) { - base.include.push({ + include.push({ model: AccountModel.scope({ method: [ AccountModelScopeNames.SUMMARY, { withAccountBlockerIds: options.withAccountBlockerIds } as AccountSummaryOptions ] }), @@ -150,6 +150,8 @@ export type SummaryOptions = { }) } + base.include = include + return base }, [ScopeNames.WITH_ACCOUNT]: { @@ -221,7 +223,7 @@ export type SummaryOptions = { } ] }) -export class VideoChannelModel extends Model { +export class VideoChannelModel extends Model { @AllowNull(false) @Is('VideoChannelName', value => throwIfNotValid(value, isVideoChannelNameValid, 'name')) @@ -328,18 +330,17 @@ export class VideoChannelModel extends Model { order: getSort(parameters.sort) } - const scopes = { - method: [ ScopeNames.FOR_API, { actorId } as AvailableForListOptions ] - } return VideoChannelModel - .scope(scopes) + .scope({ + method: [ ScopeNames.FOR_API, { actorId } as AvailableForListOptions ] + }) .findAndCountAll(query) .then(({ rows, count }) => { return { total: count, data: rows } }) } - static listLocalsForSitemap (sort: string): Bluebird { + static listLocalsForSitemap (sort: string): Promise { const query = { attributes: [ ], offset: 0, @@ -391,11 +392,10 @@ export class VideoChannelModel extends Model { } } - const scopes = { - method: [ ScopeNames.FOR_API, { actorId: options.actorId } as AvailableForListOptions ] - } return VideoChannelModel - .scope(scopes) + .scope({ + method: [ ScopeNames.FOR_API, { actorId: options.actorId } as AvailableForListOptions ] + }) .findAndCountAll(query) .then(({ rows, count }) => { return { total: count, data: rows } @@ -457,13 +457,13 @@ export class VideoChannelModel extends Model { }) } - static loadByIdAndPopulateAccount (id: number): Bluebird { + static loadByIdAndPopulateAccount (id: number): Promise { return VideoChannelModel.unscoped() .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) .findByPk(id) } - static loadByIdAndAccount (id: number, accountId: number): Bluebird { + static loadByIdAndAccount (id: number, accountId: number): Promise { const query = { where: { id, @@ -476,13 +476,13 @@ export class VideoChannelModel extends Model { .findOne(query) } - static loadAndPopulateAccount (id: number): Bluebird { + static loadAndPopulateAccount (id: number): Promise { return VideoChannelModel.unscoped() .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) .findByPk(id) } - static loadByUrlAndPopulateAccount (url: string): Bluebird { + static loadByUrlAndPopulateAccount (url: string): Promise { const query = { include: [ { @@ -508,7 +508,7 @@ export class VideoChannelModel extends Model { return VideoChannelModel.loadByNameAndHostAndPopulateAccount(name, host) } - static loadLocalByNameAndPopulateAccount (name: string): Bluebird { + static loadLocalByNameAndPopulateAccount (name: string): Promise { const query = { include: [ { @@ -527,7 +527,7 @@ export class VideoChannelModel extends Model { .findOne(query) } - static loadByNameAndHostAndPopulateAccount (name: string, host: string): Bluebird { + static loadByNameAndHostAndPopulateAccount (name: string, host: string): Promise { const query = { include: [ { @@ -552,7 +552,7 @@ export class VideoChannelModel extends Model { .findOne(query) } - static loadAndPopulateAccountAndVideos (id: number): Bluebird { + static loadAndPopulateAccountAndVideos (id: number): Promise { const options = { include: [ VideoModel diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts index ed4a345eb..8d1c38826 100644 --- a/server/models/video/video-comment.ts +++ b/server/models/video/video-comment.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird' import { uniq } from 'lodash' import { FindAndCountOptions, FindOptions, Op, Order, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize' import { @@ -174,7 +173,7 @@ export enum ScopeNames { } ] }) -export class VideoCommentModel extends Model { +export class VideoCommentModel extends Model { @CreatedAt createdAt: Date @@ -255,7 +254,7 @@ export class VideoCommentModel extends Model { }) CommentAbuses: VideoCommentAbuseModel[] - static loadById (id: number, t?: Transaction): Bluebird { + static loadById (id: number, t?: Transaction): Promise { const query: FindOptions = { where: { id @@ -267,7 +266,7 @@ export class VideoCommentModel extends Model { return VideoCommentModel.findOne(query) } - static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Transaction): Bluebird { + static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Transaction): Promise { const query: FindOptions = { where: { id @@ -281,7 +280,7 @@ export class VideoCommentModel extends Model { .findOne(query) } - static loadByUrlAndPopulateAccountAndVideo (url: string, t?: Transaction): Bluebird { + static loadByUrlAndPopulateAccountAndVideo (url: string, t?: Transaction): Promise { const query: FindOptions = { where: { url @@ -293,7 +292,7 @@ export class VideoCommentModel extends Model { return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEO ]).findOne(query) } - static loadByUrlAndPopulateReplyAndVideoUrlAndAccount (url: string, t?: Transaction): Bluebird { + static loadByUrlAndPopulateReplyAndVideoUrlAndAccount (url: string, t?: Transaction): Promise { const query: FindOptions = { where: { url @@ -501,7 +500,7 @@ export class VideoCommentModel extends Model { }) } - static listThreadParentComments (comment: MCommentId, t: Transaction, order: 'ASC' | 'DESC' = 'ASC'): Bluebird { + static listThreadParentComments (comment: MCommentId, t: Transaction, order: 'ASC' | 'DESC' = 'ASC'): Promise { const query = { order: [ [ 'createdAt', order ] ] as Order, where: { diff --git a/server/models/video/video-file.ts b/server/models/video/video-file.ts index d48c9f5d4..48b337c68 100644 --- a/server/models/video/video-file.ts +++ b/server/models/video/video-file.ts @@ -101,7 +101,7 @@ export enum ScopeNames { } ] }) -export class VideoFileModel extends Model { +export class VideoFileModel extends Model { @CreatedAt createdAt: Date diff --git a/server/models/video/video-import.ts b/server/models/video/video-import.ts index ea1e085af..f3ed651b2 100644 --- a/server/models/video/video-import.ts +++ b/server/models/video/video-import.ts @@ -13,15 +13,14 @@ import { Table, UpdatedAt } from 'sequelize-typescript' +import { MVideoImportDefault, MVideoImportFormattable } from '@server/types/models/video/video-import' +import { VideoImport, VideoImportState } from '../../../shared' +import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports' +import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos' import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers/constants' +import { UserModel } from '../account/user' import { getSort, throwIfNotValid } from '../utils' import { ScopeNames as VideoModelScopeNames, VideoModel } from './video' -import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports' -import { VideoImport, VideoImportState } from '../../../shared' -import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos' -import { UserModel } from '../account/user' -import * as Bluebird from 'bluebird' -import { MVideoImportDefault, MVideoImportFormattable } from '@server/types/models/video/video-import' @DefaultScope(() => ({ include: [ @@ -52,7 +51,7 @@ import { MVideoImportDefault, MVideoImportFormattable } from '@server/types/mode } ] }) -export class VideoImportModel extends Model { +export class VideoImportModel extends Model { @CreatedAt createdAt: Date @@ -120,7 +119,7 @@ export class VideoImportModel extends Model { return undefined } - static loadAndPopulateVideo (id: number): Bluebird { + static loadAndPopulateVideo (id: number): Promise { return VideoImportModel.findByPk(id) } diff --git a/server/models/video/video-live.ts b/server/models/video/video-live.ts index 875ba9b31..cb4a9b896 100644 --- a/server/models/video/video-live.ts +++ b/server/models/video/video-live.ts @@ -28,7 +28,7 @@ import { VideoBlacklistModel } from './video-blacklist' } ] }) -export class VideoLiveModel extends Model { +export class VideoLiveModel extends Model { @AllowNull(true) @Column(DataType.STRING) diff --git a/server/models/video/video-playlist-element.ts b/server/models/video/video-playlist-element.ts index d357766e9..d2d7e2740 100644 --- a/server/models/video/video-playlist-element.ts +++ b/server/models/video/video-playlist-element.ts @@ -1,3 +1,4 @@ +import { AggregateOptions, Op, ScopeOptions, Sequelize, Transaction } from 'sequelize' import { AllowNull, BelongsTo, @@ -13,18 +14,8 @@ import { Table, UpdatedAt } from 'sequelize-typescript' -import { ForAPIOptions, ScopeNames as VideoScopeNames, VideoModel } from './video' -import { VideoPlaylistModel } from './video-playlist' -import { getSort, throwIfNotValid } from '../utils' -import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' -import { CONSTRAINTS_FIELDS } from '../../initializers/constants' -import { PlaylistElementObject } from '../../../shared/models/activitypub/objects/playlist-element-object' import validator from 'validator' -import { AggregateOptions, Op, ScopeOptions, Sequelize, Transaction } from 'sequelize' -import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../shared/models/videos/playlist/video-playlist-element.model' -import { AccountModel } from '../account/account' -import { VideoPrivacy } from '../../../shared/models/videos' -import * as Bluebird from 'bluebird' +import { MUserAccountId } from '@server/types/models' import { MVideoPlaylistElement, MVideoPlaylistElementAP, @@ -32,7 +23,15 @@ import { MVideoPlaylistElementVideoUrlPlaylistPrivacy, MVideoPlaylistVideoThumbnail } from '@server/types/models/video/video-playlist-element' -import { MUserAccountId } from '@server/types/models' +import { PlaylistElementObject } from '../../../shared/models/activitypub/objects/playlist-element-object' +import { VideoPrivacy } from '../../../shared/models/videos' +import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../shared/models/videos/playlist/video-playlist-element.model' +import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' +import { CONSTRAINTS_FIELDS } from '../../initializers/constants' +import { AccountModel } from '../account/account' +import { getSort, throwIfNotValid } from '../utils' +import { ForAPIOptions, ScopeNames as VideoScopeNames, VideoModel } from './video' +import { VideoPlaylistModel } from './video-playlist' @Table({ tableName: 'videoPlaylistElement', @@ -49,7 +48,7 @@ import { MUserAccountId } from '@server/types/models' } ] }) -export class VideoPlaylistElementModel extends Model { +export class VideoPlaylistElementModel extends Model { @CreatedAt createdAt: Date @@ -166,7 +165,7 @@ export class VideoPlaylistElementModel extends Model ]).then(([ total, data ]) => ({ total, data })) } - static loadByPlaylistAndVideo (videoPlaylistId: number, videoId: number): Bluebird { + static loadByPlaylistAndVideo (videoPlaylistId: number, videoId: number): Promise { const query = { where: { videoPlaylistId, @@ -177,14 +176,14 @@ export class VideoPlaylistElementModel extends Model return VideoPlaylistElementModel.findOne(query) } - static loadById (playlistElementId: number | string): Bluebird { + static loadById (playlistElementId: number | string): Promise { return VideoPlaylistElementModel.findByPk(playlistElementId) } static loadByPlaylistAndElementIdForAP ( playlistId: number | string, playlistElementId: number - ): Bluebird { + ): Promise { const playlistWhere = validator.isUUID('' + playlistId) ? { uuid: playlistId } : { id: playlistId } const query = { @@ -226,7 +225,7 @@ export class VideoPlaylistElementModel extends Model }) } - static loadFirstElementWithVideoThumbnail (videoPlaylistId: number): Bluebird { + static loadFirstElementWithVideoThumbnail (videoPlaylistId: number): Promise { const query = { order: getSort('position'), where: { diff --git a/server/models/video/video-playlist.ts b/server/models/video/video-playlist.ts index 9f9e0b069..93ecf8cea 100644 --- a/server/models/video/video-playlist.ts +++ b/server/models/video/video-playlist.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird' import { join } from 'path' import { FindOptions, literal, Op, ScopeOptions, Transaction, WhereOptions } from 'sequelize' import { @@ -125,7 +124,6 @@ type AvailableForListOptions = { ] }, [ScopeNames.AVAILABLE_FOR_LIST]: (options: AvailableForListOptions) => { - let whereActor: WhereOptions = {} const whereAnd: WhereOptions[] = [] @@ -182,15 +180,13 @@ type AvailableForListOptions = { [Op.and]: whereAnd } - const accountScope = { - method: [ AccountScopeNames.SUMMARY, { whereActor } as SummaryOptions ] - } - return { where, include: [ { - model: AccountModel.scope(accountScope), + model: AccountModel.scope({ + method: [ AccountScopeNames.SUMMARY, { whereActor } as SummaryOptions ] + }), required: true }, { @@ -217,7 +213,7 @@ type AvailableForListOptions = { } ] }) -export class VideoPlaylistModel extends Model { +export class VideoPlaylistModel extends Model { @CreatedAt createdAt: Date @@ -367,7 +363,7 @@ export class VideoPlaylistModel extends Model { }) } - static listPlaylistIdsOf (accountId: number, videoIds: number[]): Bluebird { + static listPlaylistIdsOf (accountId: number, videoIds: number[]): Promise { const query = { attributes: [ 'id' ], where: { @@ -392,7 +388,7 @@ export class VideoPlaylistModel extends Model { static doesPlaylistExist (url: string) { const query = { - attributes: [], + attributes: [ 'id' ], where: { url } @@ -403,7 +399,7 @@ export class VideoPlaylistModel extends Model { .then(e => !!e) } - static loadWithAccountAndChannelSummary (id: number | string, transaction: Transaction): Bluebird { + static loadWithAccountAndChannelSummary (id: number | string, transaction: Transaction): Promise { const where = buildWhereIdOrUUID(id) const query = { @@ -416,7 +412,7 @@ export class VideoPlaylistModel extends Model { .findOne(query) } - static loadWithAccountAndChannel (id: number | string, transaction: Transaction): Bluebird { + static loadWithAccountAndChannel (id: number | string, transaction: Transaction): Promise { const where = buildWhereIdOrUUID(id) const query = { @@ -429,7 +425,7 @@ export class VideoPlaylistModel extends Model { .findOne(query) } - static loadByUrlAndPopulateAccount (url: string): Bluebird { + static loadByUrlAndPopulateAccount (url: string): Promise { const query = { where: { url diff --git a/server/models/video/video-share.ts b/server/models/video/video-share.ts index f9ee94589..b7f5f3fa3 100644 --- a/server/models/video/video-share.ts +++ b/server/models/video/video-share.ts @@ -1,13 +1,12 @@ -import * as Bluebird from 'bluebird' +import { literal, Op, Transaction } from 'sequelize' import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' import { CONSTRAINTS_FIELDS } from '../../initializers/constants' +import { MActorDefault } from '../../types/models' +import { MVideoShareActor, MVideoShareFull } from '../../types/models/video' import { ActorModel } from '../activitypub/actor' import { buildLocalActorIdsIn, throwIfNotValid } from '../utils' import { VideoModel } from './video' -import { literal, Op, Transaction } from 'sequelize' -import { MVideoShareActor, MVideoShareFull } from '../../types/models/video' -import { MActorDefault } from '../../types/models' enum ScopeNames { FULL = 'FULL', @@ -51,7 +50,7 @@ enum ScopeNames { } ] }) -export class VideoShareModel extends Model { +export class VideoShareModel extends Model { @AllowNull(false) @Is('VideoShareUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url')) @@ -88,7 +87,7 @@ export class VideoShareModel extends Model { }) Video: VideoModel - static load (actorId: number | string, videoId: number | string, t?: Transaction): Bluebird { + static load (actorId: number | string, videoId: number | string, t?: Transaction): Promise { return VideoShareModel.scope(ScopeNames.WITH_ACTOR).findOne({ where: { actorId, @@ -98,7 +97,7 @@ export class VideoShareModel extends Model { }) } - static loadByUrl (url: string, t: Transaction): Bluebird { + static loadByUrl (url: string, t: Transaction): Promise { return VideoShareModel.scope(ScopeNames.FULL).findOne({ where: { url @@ -107,7 +106,7 @@ export class VideoShareModel extends Model { }) } - static loadActorsByShare (videoId: number, t: Transaction): Bluebird { + static loadActorsByShare (videoId: number, t: Transaction): Promise { const query = { where: { videoId @@ -125,7 +124,7 @@ export class VideoShareModel extends Model { .then((res: MVideoShareFull[]) => res.map(r => r.Actor)) } - static loadActorsWhoSharedVideosOf (actorOwnerId: number, t: Transaction): Bluebird { + static loadActorsWhoSharedVideosOf (actorOwnerId: number, t: Transaction): Promise { const safeOwnerId = parseInt(actorOwnerId + '', 10) // /!\ On actor model @@ -150,7 +149,7 @@ export class VideoShareModel extends Model { return ActorModel.findAll(query) } - static loadActorsByVideoChannel (videoChannelId: number, t: Transaction): Bluebird { + static loadActorsByVideoChannel (videoChannelId: number, t: Transaction): Promise { const safeChannelId = parseInt(videoChannelId + '', 10) // /!\ On actor model diff --git a/server/models/video/video-streaming-playlist.ts b/server/models/video/video-streaming-playlist.ts index 73bd89844..148768c21 100644 --- a/server/models/video/video-streaming-playlist.ts +++ b/server/models/video/video-streaming-playlist.ts @@ -40,7 +40,7 @@ import { logger } from '@server/helpers/logger' } ] }) -export class VideoStreamingPlaylistModel extends Model { +export class VideoStreamingPlaylistModel extends Model { @CreatedAt createdAt: Date diff --git a/server/models/video/video-tag.ts b/server/models/video/video-tag.ts index ca15e3426..5052b8c4d 100644 --- a/server/models/video/video-tag.ts +++ b/server/models/video/video-tag.ts @@ -13,7 +13,7 @@ import { VideoModel } from './video' } ] }) -export class VideoTagModel extends Model { +export class VideoTagModel extends Model { @CreatedAt createdAt: Date diff --git a/server/models/video/video-view.ts b/server/models/video/video-view.ts index 40db5effd..992cf258a 100644 --- a/server/models/video/video-view.ts +++ b/server/models/video/video-view.ts @@ -14,7 +14,7 @@ import * as Sequelize from 'sequelize' } ] }) -export class VideoViewModel extends Model { +export class VideoViewModel extends Model { @CreatedAt createdAt: Date diff --git a/server/models/video/video.ts b/server/models/video/video.ts index a43abbc09..d3fed338a 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts @@ -2,7 +2,7 @@ import * as Bluebird from 'bluebird' import { remove } from 'fs-extra' import { maxBy, minBy, pick } from 'lodash' import { join } from 'path' -import { FindOptions, IncludeOptions, Op, QueryTypes, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize' +import { FindOptions, Includeable, IncludeOptions, Op, QueryTypes, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize' import { AllowNull, BeforeDestroy, @@ -190,26 +190,26 @@ export type AvailableForListIDsOptions = { attributes: [ 'id', 'url', 'uuid', 'remote' ] }, [ScopeNames.FOR_API]: (options: ForAPIOptions) => { - const query: FindOptions = { - include: [ - { - model: VideoChannelModel.scope({ - method: [ - VideoChannelScopeNames.SUMMARY, { - withAccount: true, - withAccountBlockerIds: options.withAccountBlockerIds - } as SummaryOptions - ] - }), - required: true - }, - { - attributes: [ 'type', 'filename' ], - model: ThumbnailModel, - required: false - } - ] - } + const include: Includeable[] = [ + { + model: VideoChannelModel.scope({ + method: [ + VideoChannelScopeNames.SUMMARY, { + withAccount: true, + withAccountBlockerIds: options.withAccountBlockerIds + } as SummaryOptions + ] + }), + required: true + }, + { + attributes: [ 'type', 'filename' ], + model: ThumbnailModel, + required: false + } + ] + + const query: FindOptions = {} if (options.ids) { query.where = { @@ -220,14 +220,14 @@ export type AvailableForListIDsOptions = { } if (options.withFiles === true) { - query.include.push({ + include.push({ model: VideoFileModel, required: true }) } if (options.videoPlaylistId) { - query.include.push({ + include.push({ model: VideoPlaylistElementModel.unscoped(), required: true, where: { @@ -236,6 +236,8 @@ export type AvailableForListIDsOptions = { }) } + query.include = include + return query }, [ScopeNames.WITH_THUMBNAILS]: { @@ -477,7 +479,7 @@ export type AvailableForListIDsOptions = { } ] }) -export class VideoModel extends Model { +export class VideoModel extends Model { @AllowNull(false) @Default(DataType.UUIDV4) @@ -860,7 +862,7 @@ export class VideoModel extends Model { return undefined } - static listLocal (): Bluebird { + static listLocal (): Promise { const query = { where: { remote: false @@ -988,7 +990,7 @@ export class VideoModel extends Model { }) } - static listPublishedLiveIds () { + static async listPublishedLiveIds () { const options = { attributes: [ 'id' ], where: { @@ -997,8 +999,9 @@ export class VideoModel extends Model { } } - return VideoModel.findAll(options) - .map(v => v.id) + const result = await VideoModel.findAll(options) + + return result.map(v => v.id) } static listUserVideosForApi ( @@ -1214,7 +1217,7 @@ export class VideoModel extends Model { return VideoModel.count(options) } - static load (id: number | string, t?: Transaction): Bluebird { + static load (id: number | string, t?: Transaction): Promise { const where = buildWhereIdOrUUID(id) const options = { where, @@ -1224,7 +1227,7 @@ export class VideoModel extends Model { return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) } - static loadWithBlacklist (id: number | string, t?: Transaction): Bluebird { + static loadWithBlacklist (id: number | string, t?: Transaction): Promise { const where = buildWhereIdOrUUID(id) const options = { where, @@ -1237,7 +1240,7 @@ export class VideoModel extends Model { ]).findOne(options) } - static loadImmutableAttributes (id: number | string, t?: Transaction): Bluebird { + static loadImmutableAttributes (id: number | string, t?: Transaction): Promise { const fun = () => { const query = { where: buildWhereIdOrUUID(id), @@ -1255,7 +1258,7 @@ export class VideoModel extends Model { }) } - static loadWithRights (id: number | string, t?: Transaction): Bluebird { + static loadWithRights (id: number | string, t?: Transaction): Promise { const where = buildWhereIdOrUUID(id) const options = { where, @@ -1269,7 +1272,7 @@ export class VideoModel extends Model { ]).findOne(options) } - static loadOnlyId (id: number | string, t?: Transaction): Bluebird { + static loadOnlyId (id: number | string, t?: Transaction): Promise { const where = buildWhereIdOrUUID(id) const options = { @@ -1281,7 +1284,7 @@ export class VideoModel extends Model { return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) } - static loadWithFiles (id: number | string, t?: Transaction, logging?: boolean): Bluebird { + static loadWithFiles (id: number | string, t?: Transaction, logging?: boolean): Promise { const where = buildWhereIdOrUUID(id) const query = { @@ -1297,7 +1300,7 @@ export class VideoModel extends Model { ]).findOne(query) } - static loadByUUID (uuid: string): Bluebird { + static loadByUUID (uuid: string): Promise { const options = { where: { uuid @@ -1307,7 +1310,7 @@ export class VideoModel extends Model { return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) } - static loadByUrl (url: string, transaction?: Transaction): Bluebird { + static loadByUrl (url: string, transaction?: Transaction): Promise { const query: FindOptions = { where: { url @@ -1318,7 +1321,7 @@ export class VideoModel extends Model { return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(query) } - static loadByUrlImmutableAttributes (url: string, transaction?: Transaction): Bluebird { + static loadByUrlImmutableAttributes (url: string, transaction?: Transaction): Promise { const fun = () => { const query: FindOptions = { where: { @@ -1338,7 +1341,7 @@ export class VideoModel extends Model { }) } - static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction): Bluebird { + static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction): Promise { const query: FindOptions = { where: { url @@ -1355,7 +1358,7 @@ export class VideoModel extends Model { ]).findOne(query) } - static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Transaction, userId?: number): Bluebird { + static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Transaction, userId?: number): Promise { const where = buildWhereIdOrUUID(id) const options = { @@ -1388,7 +1391,7 @@ export class VideoModel extends Model { id: number | string t?: Transaction userId?: number - }): Bluebird { + }): Promise { const { id, t, userId } = parameters const where = buildWhereIdOrUUID(id) @@ -1487,7 +1490,7 @@ export class VideoModel extends Model { return VideoModel.update({ support: videoChannel.support }, options) } - static getAllIdsFromChannel (videoChannel: MChannelId): Bluebird { + static getAllIdsFromChannel (videoChannel: MChannelId): Promise { const query = { attributes: [ 'id' ], where: { diff --git a/server/tests/api/live/live.ts b/server/tests/api/live/live.ts index fdfc6105f..a74988aba 100644 --- a/server/tests/api/live/live.ts +++ b/server/tests/api/live/live.ts @@ -686,12 +686,7 @@ describe('Test live', function () { it('Should save a live replay', async function () { this.timeout(60000) - await waitJobs(servers) - - const res = await getVideo(servers[0].url, liveVideoReplayId) - const video: VideoDetails = res.body - - expect(video.state.id).to.equal(VideoState.PUBLISHED) + await waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoReplayId) }) }) diff --git a/server/types/plugins/register-server-option.model.ts b/server/types/plugins/register-server-option.model.ts index 74303d383..2e52d1efd 100644 --- a/server/types/plugins/register-server-option.model.ts +++ b/server/types/plugins/register-server-option.model.ts @@ -1,4 +1,3 @@ -import * as Bluebird from 'bluebird' import { Router } from 'express' import { Logger } from 'winston' import { ActorModel } from '@server/models/activitypub/actor' @@ -29,7 +28,7 @@ export type PeerTubeHelpers = { } videos: { - loadByUrl: (url: string) => Bluebird + loadByUrl: (url: string) => Promise removeVideo: (videoId: number) => Promise } diff --git a/yarn.lock b/yarn.lock index 5dd5fbd64..61a2ea05e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1985,14 +1985,6 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= -cls-bluebird@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cls-bluebird/-/cls-bluebird-2.1.0.tgz#37ef1e080a8ffb55c2f4164f536f1919e7968aee" - integrity sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4= - dependencies: - is-bluebird "^1.0.2" - shimmer "^1.1.0" - cluster-key-slot@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" @@ -4135,11 +4127,6 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-bluebird@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-bluebird/-/is-bluebird-1.0.2.tgz#096439060f4aa411abee19143a84d6a55346d6e2" - integrity sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI= - is-buffer@^1.1.5, is-buffer@~1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -5136,14 +5123,14 @@ mocha@^8.0.1: yargs-parser "13.1.2" yargs-unparser "2.0.0" -moment-timezone@^0.5.21, moment-timezone@^0.5.31: +moment-timezone@^0.5.31: version "0.5.32" resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.32.tgz#db7677cc3cc680fd30303ebd90b0da1ca0dfecc2" integrity sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA== dependencies: moment ">= 2.9.0" -"moment@>= 2.9.0", moment@^2.24.0: +"moment@>= 2.9.0", moment@^2.26.0: version "2.29.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== @@ -6926,38 +6913,36 @@ send@0.17.1: range-parser "~1.2.1" statuses "~1.5.0" -sequelize-pool@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-2.3.0.tgz#64f1fe8744228172c474f530604b6133be64993d" - integrity sha512-Ibz08vnXvkZ8LJTiUOxRcj1Ckdn7qafNZ2t59jYHMX1VIebTAOYefWdRYFt6z6+hy52WGthAHAoLc9hvk3onqA== +sequelize-pool@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-6.1.0.tgz#caaa0c1e324d3c2c3a399fed2c7998970925d668" + integrity sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg== -sequelize-typescript@^1.0.0-beta.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/sequelize-typescript/-/sequelize-typescript-1.1.0.tgz#d5c2945e7fbfe55a934917b27d84589858d79123" - integrity sha512-FAPEQPeAhIaFQNLAcf9Q2IWcqWhNcvn5OZZ7BzGB0CJMtImIsGg4E/EAb7huMmPaPwDArxJUWGqk1KurphTNRA== +sequelize-typescript@^2.0.0-beta.1: + version "2.0.0-beta.1" + resolved "https://registry.yarnpkg.com/sequelize-typescript/-/sequelize-typescript-2.0.0-beta.1.tgz#08c52c35e7fb4f940b9919cbc77752776bcc800a" + integrity sha512-GHlNfh8vPIJKzXtk4A8MTndK3Uu87HO75fFFX4PM+35P/SW3fFCiw/KeHeQ6DjLz7zeI+fop2HFWVeuZarnJwQ== dependencies: glob "7.1.2" -sequelize@5.21.13: - version "5.21.13" - resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-5.21.13.tgz#c8c2f6a2d44d0a234c101155447d494d8d216c7b" - integrity sha512-wpwSpxzvADmgPkcOGeer5yFdAVsYeA7NLEw4evSXw03OlGL41J4S8hVz2/nilSWlJSwumlDGC9QbdwAmkWGqJg== +sequelize@6.3.5: + version "6.3.5" + resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.3.5.tgz#80e3db7ac8b76d98c45ca93334197eb6e2335158" + integrity sha512-MiwiPkYSA8NWttRKAXdU9h0TxP6HAc1fl7qZmMO/VQqQOND83G4nZLXd0kWILtAoT9cxtZgFqeb/MPYgEeXwsw== dependencies: - bluebird "^3.5.0" - cls-bluebird "^2.1.0" debug "^4.1.1" dottie "^2.0.0" inflection "1.12.0" lodash "^4.17.15" - moment "^2.24.0" - moment-timezone "^0.5.21" + moment "^2.26.0" + moment-timezone "^0.5.31" retry-as-promised "^3.2.0" - semver "^6.3.0" - sequelize-pool "^2.3.0" + semver "^7.3.2" + sequelize-pool "^6.0.0" toposort-class "^1.0.1" - uuid "^3.3.3" + uuid "^8.1.0" validator "^10.11.0" - wkx "^0.4.8" + wkx "^0.5.0" serialize-javascript@5.0.1: version "5.0.1" @@ -6998,11 +6983,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shimmer@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337" - integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw== - signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" @@ -8351,10 +8331,10 @@ with@^7.0.0: assert-never "^1.2.1" babel-walk "3.0.0-canary-5" -wkx@^0.4.8: - version "0.4.8" - resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.4.8.tgz#a092cf088d112683fdc7182fd31493b2c5820003" - integrity sha512-ikPXMM9IR/gy/LwiOSqWlSL3X/J5uk9EO2hHNRXS41eTLXaUFEVw9fn/593jW/tE5tedNg8YjT5HkCa4FqQZyQ== +wkx@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c" + integrity sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg== dependencies: "@types/node" "*"