1
0
Fork 0

Upgrade sequelize to v6

This commit is contained in:
Chocobozzz 2020-12-08 14:30:29 +01:00 committed by Chocobozzz
parent 6c8c15f914
commit b49f22d8f9
75 changed files with 436 additions and 498 deletions

View File

@ -142,8 +142,8 @@
"request": "^2.81.0", "request": "^2.81.0",
"sanitize-html": "2.x", "sanitize-html": "2.x",
"scripty": "^2.0.0", "scripty": "^2.0.0",
"sequelize": "5.21.13", "sequelize": "6.3.5",
"sequelize-typescript": "^1.0.0-beta.4", "sequelize-typescript": "^2.0.0-beta.1",
"sitemap": "^6.1.0", "sitemap": "^6.1.0",
"socket.io": "^3.0.2", "socket.io": "^3.0.2",
"srt-to-vtt": "^1.1.2", "srt-to-vtt": "^1.1.2",

View File

@ -1,4 +1,3 @@
import * as Bluebird from 'bluebird'
import * as express from 'express' import * as express from 'express'
import { move, readFile } from 'fs-extra' import { move, readFile } from 'fs-extra'
import * as magnetUtil from 'magnet-uri' import * as magnetUtil from 'magnet-uri'
@ -17,6 +16,7 @@ import {
} from '@server/types/models' } from '@server/types/models'
import { MVideoImport, MVideoImportFormattable } from '@server/types/models/video/video-import' import { MVideoImport, MVideoImportFormattable } from '@server/types/models/video/video-import'
import { VideoImportCreate, VideoImportState, VideoPrivacy, VideoState } from '../../../../shared' 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 { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type'
import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger' import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger'
import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils' import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils'
@ -36,7 +36,6 @@ import { asyncMiddleware, asyncRetryTransactionMiddleware, authenticate, videoIm
import { VideoModel } from '../../../models/video/video' import { VideoModel } from '../../../models/video/video'
import { VideoCaptionModel } from '../../../models/video/video-caption' import { VideoCaptionModel } from '../../../models/video/video-caption'
import { VideoImportModel } from '../../../models/video/video-import' import { VideoImportModel } from '../../../models/video/video-import'
import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const auditLogger = auditLoggerFactory('video-imports') const auditLogger = auditLoggerFactory('video-imports')
const videoImportsRouter = express.Router() const videoImportsRouter = express.Router()
@ -314,7 +313,7 @@ function insertIntoDB (parameters: {
tags: string[] tags: string[]
videoImportAttributes: Partial<MVideoImport> videoImportAttributes: Partial<MVideoImport>
user: MUser user: MUser
}): Bluebird<MVideoImportFormattable> { }): Promise<MVideoImportFormattable> {
const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters
return sequelizeTypescript.transaction(async t => { return sequelizeTypescript.transaction(async t => {

View File

@ -1,10 +1,10 @@
import { ActorModel } from '../models/activitypub/actor' import { ActorModel } from '../models/activitypub/actor'
import * as Bluebird from 'bluebird' import { MActorAccountChannelId, MActorFull } from '../types/models'
import { MActorFull, MActorAccountChannelId } from '../types/models'
type ActorFetchByUrlType = 'all' | 'association-ids' type ActorFetchByUrlType = 'all' | 'association-ids'
function fetchActorByUrl (url: string, fetchType: ActorFetchByUrlType): Bluebird<MActorFull | MActorAccountChannelId> { function fetchActorByUrl (url: string, fetchType: ActorFetchByUrlType): Promise<MActorFull | MActorAccountChannelId> {
if (fetchType === 'all') return ActorModel.loadByUrlAndPopulateAccountAndChannel(url) if (fetchType === 'all') return ActorModel.loadByUrlAndPopulateAccountAndChannel(url)
if (fetchType === 'association-ids') return ActorModel.loadByUrl(url) if (fetchType === 'association-ids') return ActorModel.loadByUrl(url)

View File

@ -1,9 +1,8 @@
import { Response } from 'express' 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 { UserModel } from '@server/models/account/user'
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes' 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) { function doesAccountIdExist (id: number | string, res: Response, sendNotFound = true) {
const promise = AccountModel.load(parseInt(id + '', 10)) const promise = AccountModel.load(parseInt(id + '', 10))
@ -23,7 +22,7 @@ function doesAccountNameWithHostExist (nameWithDomain: string, res: Response, se
return doesAccountExist(promise, res, sendNotFound) return doesAccountExist(promise, res, sendNotFound)
} }
async function doesAccountExist (p: Bluebird<MAccountDefault>, res: Response, sendNotFound: boolean) { async function doesAccountExist (p: Promise<MAccountDefault>, res: Response, sendNotFound: boolean) {
const account = await p const account = await p
if (!account) { if (!account) {

View File

@ -1,4 +1,3 @@
import * as Bluebird from 'bluebird'
import { Response } from 'express' import { Response } from 'express'
import { CONFIG } from '@server/initializers/config' import { CONFIG } from '@server/initializers/config'
import { DEFAULT_AUDIO_RESOLUTION } from '@server/initializers/constants' 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' type VideoFetchType = 'all' | 'only-video' | 'only-video-with-rights' | 'id' | 'none' | 'only-immutable-attributes'
function fetchVideo (id: number | string, fetchType: 'all', userId?: number): Bluebird<MVideoFullLight> function fetchVideo (id: number | string, fetchType: 'all', userId?: number): Promise<MVideoFullLight>
function fetchVideo (id: number | string, fetchType: 'only-immutable-attributes'): Bluebird<MVideoImmutable> function fetchVideo (id: number | string, fetchType: 'only-immutable-attributes'): Promise<MVideoImmutable>
function fetchVideo (id: number | string, fetchType: 'only-video', userId?: number): Bluebird<MVideoThumbnail> function fetchVideo (id: number | string, fetchType: 'only-video', userId?: number): Promise<MVideoThumbnail>
function fetchVideo (id: number | string, fetchType: 'only-video-with-rights', userId?: number): Bluebird<MVideoWithRights> function fetchVideo (id: number | string, fetchType: 'only-video-with-rights', userId?: number): Promise<MVideoWithRights>
function fetchVideo (id: number | string, fetchType: 'id' | 'none', userId?: number): Bluebird<MVideoIdThumbnail> function fetchVideo (id: number | string, fetchType: 'id' | 'none', userId?: number): Promise<MVideoIdThumbnail>
function fetchVideo ( function fetchVideo (
id: number | string, id: number | string,
fetchType: VideoFetchType, fetchType: VideoFetchType,
userId?: number userId?: number
): Bluebird<MVideoFullLight | MVideoThumbnail | MVideoWithRights | MVideoIdThumbnail | MVideoImmutable> ): Promise<MVideoFullLight | MVideoThumbnail | MVideoWithRights | MVideoIdThumbnail | MVideoImmutable>
function fetchVideo ( function fetchVideo (
id: number | string, id: number | string,
fetchType: VideoFetchType, fetchType: VideoFetchType,
userId?: number userId?: number
): Bluebird<MVideoFullLight | MVideoThumbnail | MVideoWithRights | MVideoIdThumbnail | MVideoImmutable> { ): Promise<MVideoFullLight | MVideoThumbnail | MVideoWithRights | MVideoIdThumbnail | MVideoImmutable> {
if (fetchType === 'all') return VideoModel.loadAndPopulateAccountAndServerAndTags(id, undefined, userId) if (fetchType === 'all') return VideoModel.loadAndPopulateAccountAndServerAndTags(id, undefined, userId)
if (fetchType === 'only-immutable-attributes') return VideoModel.loadImmutableAttributes(id) if (fetchType === 'only-immutable-attributes') return VideoModel.loadImmutableAttributes(id)
@ -48,17 +47,17 @@ function fetchVideo (
type VideoFetchByUrlType = 'all' | 'only-video' | 'only-immutable-attributes' type VideoFetchByUrlType = 'all' | 'only-video' | 'only-immutable-attributes'
function fetchVideoByUrl (url: string, fetchType: 'all'): Bluebird<MVideoAccountLightBlacklistAllFiles> function fetchVideoByUrl (url: string, fetchType: 'all'): Promise<MVideoAccountLightBlacklistAllFiles>
function fetchVideoByUrl (url: string, fetchType: 'only-immutable-attributes'): Bluebird<MVideoImmutable> function fetchVideoByUrl (url: string, fetchType: 'only-immutable-attributes'): Promise<MVideoImmutable>
function fetchVideoByUrl (url: string, fetchType: 'only-video'): Bluebird<MVideoThumbnail> function fetchVideoByUrl (url: string, fetchType: 'only-video'): Promise<MVideoThumbnail>
function fetchVideoByUrl ( function fetchVideoByUrl (
url: string, url: string,
fetchType: VideoFetchByUrlType fetchType: VideoFetchByUrlType
): Bluebird<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable> ): Promise<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable>
function fetchVideoByUrl ( function fetchVideoByUrl (
url: string, url: string,
fetchType: VideoFetchByUrlType fetchType: VideoFetchByUrlType
): Bluebird<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable> { ): Promise<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable> {
if (fetchType === 'all') return VideoModel.loadByUrlAndPopulateAccount(url) if (fetchType === 'all') return VideoModel.loadByUrlAndPopulateAccount(url)
if (fetchType === 'only-immutable-attributes') return VideoModel.loadByUrlImmutableAttributes(url) if (fetchType === 'only-immutable-attributes') return VideoModel.loadByUrlImmutableAttributes(url)

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations' import { Migration } from '../../models/migrations'
function up (utils: { function up (utils: {

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations' import { Migration } from '../../models/migrations'
function up (utils: { function up (utils: {

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: { function up (utils: {
transaction: Sequelize.Transaction transaction: Sequelize.Transaction

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: { function up (utils: {
transaction: Sequelize.Transaction transaction: Sequelize.Transaction

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: { function up (utils: {
transaction: Sequelize.Transaction transaction: Sequelize.Transaction

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations' import { Migration } from '../../models/migrations'
function up (utils: { function up (utils: {

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations' import { Migration } from '../../models/migrations'
function up (utils: { function up (utils: {

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations' import { Migration } from '../../models/migrations'
function up (utils: { function up (utils: {

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: { function up (utils: {
transaction: Sequelize.Transaction transaction: Sequelize.Transaction

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: { function up (utils: {
transaction: Sequelize.Transaction transaction: Sequelize.Transaction

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations' import { Migration } from '../../models/migrations'
function up (utils: { function up (utils: {

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: { function up (utils: {
transaction: Sequelize.Transaction transaction: Sequelize.Transaction

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
import { stat } from 'fs-extra' import { stat } from 'fs-extra'
import { VideoModel } from '../../models/video/video' import { VideoModel } from '../../models/video/video'
import { getVideoFilePath } from '@server/lib/video-paths' import { getVideoFilePath } from '@server/lib/video-paths'

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations' import { Migration } from '../../models/migrations'
function up (utils: { function up (utils: {

View File

@ -1,5 +1,4 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird'
function up (utils: { function up (utils: {
transaction: Sequelize.Transaction transaction: Sequelize.Transaction

View File

@ -7,7 +7,8 @@ async function up (utils: {
}): Promise<void> { }): Promise<void> {
await utils.queryInterface.removeConstraint('actor', 'actor_avatarId_fkey') await utils.queryInterface.removeConstraint('actor', 'actor_avatarId_fkey')
await utils.queryInterface.addConstraint('actor', [ 'avatarId' ], { await utils.queryInterface.addConstraint('actor', {
fields: [ 'avatarId' ],
type: 'foreign key', type: 'foreign key',
references: { references: {
table: 'avatar', table: 'avatar',

View File

@ -18,7 +18,8 @@ async function up (utils: {
await utils.queryInterface.removeConstraint('videoPlaylistElement', 'videoPlaylistElement_videoId_fkey') await utils.queryInterface.removeConstraint('videoPlaylistElement', 'videoPlaylistElement_videoId_fkey')
await utils.queryInterface.addConstraint('videoPlaylistElement', [ 'videoId' ], { await utils.queryInterface.addConstraint('videoPlaylistElement', {
fields: [ 'videoId' ],
type: 'foreign key', type: 'foreign key',
references: { references: {
table: 'video', table: 'video',

View File

@ -99,6 +99,8 @@ async function createOrUpdateVideoPlaylist (playlistObject: PlaylistObject, byAc
return Promise.resolve() return Promise.resolve()
}) })
logger.info('toto', { playlist, id: playlist.id })
const refreshedPlaylist = await VideoPlaylistModel.loadWithAccountAndChannel(playlist.id, null) const refreshedPlaylist = await VideoPlaylistModel.loadWithAccountAndChannel(playlist.id, null)
if (playlistObject.icon) { if (playlistObject.icon) {

View File

@ -33,7 +33,7 @@ async function processDislike (activity: ActivityCreate | ActivityDislike, byAct
const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: dislikeObject }) const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: dislikeObject })
return sequelizeTypescript.transaction(async t => { 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 if (existingRate && existingRate.type === 'dislike') return
await video.increment('dislikes', { transaction: t }) await video.increment('dislikes', { transaction: t })

View File

@ -30,7 +30,7 @@ async function processLikeVideo (byActor: MActorSignature, activity: ActivityLik
const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoUrl }) const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoUrl })
return sequelizeTypescript.transaction(async t => { 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 === 'like') return
if (existingRate && existingRate.type === 'dislike') { if (existingRate && existingRate.type === 'dislike') {

View File

@ -13,8 +13,6 @@ import { sendDislike } from './send/send-dislike'
import { MAccountActor, MActorUrl, MVideo, MVideoAccountLight, MVideoId } from '../../types/models' import { MAccountActor, MActorUrl, MVideo, MVideoAccountLight, MVideoId } from '../../types/models'
async function createRates (ratesUrl: string[], video: MVideo, rate: VideoRateType) { async function createRates (ratesUrl: string[], video: MVideo, rate: VideoRateType) {
let rateCounts = 0
await Bluebird.map(ratesUrl, async rateUrl => { await Bluebird.map(ratesUrl, async rateUrl => {
try { try {
// Fetch url // Fetch url
@ -43,21 +41,12 @@ async function createRates (ratesUrl: string[], video: MVideo, rate: VideoRateTy
url: body.id url: body.id
} }
const created = await AccountVideoRateModel.upsert(entry) // Video "likes"/"dislikes" will be updated by the caller
await AccountVideoRateModel.upsert(entry)
if (created) rateCounts += 1
} catch (err) { } catch (err) {
logger.warn('Cannot add rate %s.', rateUrl, { err }) logger.warn('Cannot add rate %s.', rateUrl, { err })
} }
}, { concurrency: CRAWL_REQUEST_CONCURRENCY }) }, { 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 ( async function sendVideoRateChange (

View File

@ -352,6 +352,9 @@ async function updateVideoFromAP (options: {
video.views = videoData.views video.views = videoData.views
video.isLive = videoData.isLive video.isLive = videoData.isLive
// Ensures we update the updated video attribute
video.changed('updatedAt', true)
const videoUpdated = await video.save(sequelizeOptions) as MVideoFullLight const videoUpdated = await video.save(sequelizeOptions) as MVideoFullLight
if (thumbnailModel) await videoUpdated.addAndSaveThumbnail(thumbnailModel, t) if (thumbnailModel) await videoUpdated.addAndSaveThumbnail(thumbnailModel, t)

View File

@ -1,29 +1,28 @@
import * as express from 'express' 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 { 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 { import {
ACCEPT_HEADERS,
AVATARS_SIZE, AVATARS_SIZE,
CUSTOM_HTML_TAG_COMMENTS, CUSTOM_HTML_TAG_COMMENTS,
EMBED_SIZE, EMBED_SIZE,
PLUGIN_GLOBAL_CSS_PATH,
WEBSERVER,
FILES_CONTENT_HASH, FILES_CONTENT_HASH,
ACCEPT_HEADERS PLUGIN_GLOBAL_CSS_PATH,
WEBSERVER
} from '../initializers/constants' } 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 { AccountModel } from '../models/account/account'
import { VideoModel } from '../models/video/video'
import { VideoChannelModel } from '../models/video/video-channel' import { VideoChannelModel } from '../models/video/video-channel'
import { CONFIG } from '../initializers/config' import { getActivityStreamDuration } from '../models/video/video-format-utils'
import { logger } from '../helpers/logger' import { VideoPlaylistModel } from '../models/video/video-playlist'
import { MAccountActor, MChannelActor } from '../types/models' import { MAccountActor, MChannelActor } from '../types/models'
import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes'
type Tags = { type Tags = {
ogType: string ogType: string
@ -218,7 +217,7 @@ class ClientHtml {
} }
private static async getAccountOrChannelHTMLPage ( private static async getAccountOrChannelHTMLPage (
loader: () => Bluebird<MAccountActor | MChannelActor>, loader: () => Promise<MAccountActor | MChannelActor>,
req: express.Request, req: express.Request,
res: express.Response res: express.Response
) { ) {

View File

@ -1,19 +1,18 @@
import * as Bull from 'bull' import * as Bull from 'bull'
import * as Bluebird from 'bluebird' import { ActivitypubHttpFetcherPayload, FetchType } from '@shared/models'
import { logger } from '../../../helpers/logger' 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 { AccountModel } from '../../../models/account/account'
import { AccountVideoRateModel } from '../../../models/account/account-video-rate' 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 { VideoCommentModel } from '../../../models/video/video-comment'
import { VideoShareModel } from '../../../models/video/video-share'
import { MAccountDefault, MVideoFullLight } from '../../../types/models' 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) { async function processActivityPubHttpFetcher (job: Bull.Job) {
logger.info('Processing ActivityPub fetcher in job %d.', job.id) 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) 'account-playlists': items => createAccountPlaylists(items, account)
} }
const cleanerType: { [ id in FetchType ]?: (crawlStartDate: Date) => Bluebird<any> } = { const cleanerType: { [ id in FetchType ]?: (crawlStartDate: Date) => Promise<any> } = {
'video-likes': crawlStartDate => AccountVideoRateModel.cleanOldRatesOf(video.id, 'like' as 'like', crawlStartDate), 'video-likes': crawlStartDate => AccountVideoRateModel.cleanOldRatesOf(video.id, 'like' as 'like', crawlStartDate),
'video-dislikes': crawlStartDate => AccountVideoRateModel.cleanOldRatesOf(video.id, 'dislike' as 'dislike', crawlStartDate), 'video-dislikes': crawlStartDate => AccountVideoRateModel.cleanOldRatesOf(video.id, 'dislike' as 'dislike', crawlStartDate),
'video-shares': crawlStartDate => VideoShareModel.cleanOldSharesOf(video.id, crawlStartDate), 'video-shares': crawlStartDate => VideoShareModel.cleanOldSharesOf(video.id, crawlStartDate),

View File

@ -111,7 +111,6 @@ async function buildTargetBitrate (options: {
input: string input: string
resolution: VideoResolution resolution: VideoResolution
fps: number fps: number
}) { }) {
const { input, resolution, fps } = options const { input, resolution, fps } = options
const probe = await ffprobePromise(input) const probe = await ffprobePromise(input)

View File

@ -1,8 +1,14 @@
import * as Bluebird from 'bluebird'
import * as express from 'express' import * as express from 'express'
import { body, param, query } from 'express-validator' import { body, param, query } from 'express-validator'
import { omit } from 'lodash' 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 { isIdOrUUIDValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
import { import {
isNoInstanceConfigWarningModal, isNoInstanceConfigWarningModal,
isNoWelcomeModal, isNoWelcomeModal,
@ -22,22 +28,15 @@ import {
isUserVideoQuotaValid, isUserVideoQuotaValid,
isUserVideosHistoryEnabledValid isUserVideosHistoryEnabledValid
} from '../../helpers/custom-validators/users' } from '../../helpers/custom-validators/users'
import { isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels'
import { logger } from '../../helpers/logger' import { logger } from '../../helpers/logger'
import { doesVideoExist } from '../../helpers/middlewares'
import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../helpers/signup' import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../helpers/signup'
import { isThemeRegistered } from '../../lib/plugins/theme-utils'
import { Redis } from '../../lib/redis' import { Redis } from '../../lib/redis'
import { UserModel } from '../../models/account/user' import { UserModel } from '../../models/account/user'
import { areValidationErrors } from './utils'
import { ActorModel } from '../../models/activitypub/actor' import { ActorModel } from '../../models/activitypub/actor'
import { isActorPreferredUsernameValid } from '../../helpers/custom-validators/activitypub/actor' import { areValidationErrors } from './utils'
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'
const usersListValidator = [ const usersListValidator = [
query('blocked') query('blocked')
@ -529,7 +528,7 @@ async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email:
return true return true
} }
async function checkUserExist (finder: () => Bluebird<MUserDefault>, res: express.Response, abortResponse = true) { async function checkUserExist (finder: () => Promise<MUserDefault>, res: express.Response, abortResponse = true) {
const user = await finder() const user = await finder()
if (!user) { if (!user) {

View File

@ -1,10 +1,10 @@
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
import { isAbuseMessageValid } from '@server/helpers/custom-validators/abuses' import { isAbuseMessageValid } from '@server/helpers/custom-validators/abuses'
import { MAbuseMessage, MAbuseMessageFormattable } from '@server/types/models'
import { AbuseMessage } from '@shared/models' import { AbuseMessage } from '@shared/models'
import { AccountModel, ScopeNames as AccountScopeNames } from '../account/account' import { AccountModel, ScopeNames as AccountScopeNames } from '../account/account'
import { throwIfNotValid, getSort } from '../utils' import { getSort, throwIfNotValid } from '../utils'
import { AbuseModel } from './abuse' import { AbuseModel } from './abuse'
import { MAbuseMessageFormattable, MAbuseMessage } from '@server/types/models'
@Table({ @Table({
tableName: 'abuseMessage', tableName: 'abuseMessage',
@ -17,7 +17,7 @@ import { MAbuseMessageFormattable, MAbuseMessage } from '@server/types/models'
} }
] ]
}) })
export class AbuseMessageModel extends Model<AbuseMessageModel> { export class AbuseMessageModel extends Model {
@AllowNull(false) @AllowNull(false)
@Is('AbuseMessage', value => throwIfNotValid(value, isAbuseMessageValid, 'message')) @Is('AbuseMessage', value => throwIfNotValid(value, isAbuseMessageValid, 'message'))

View File

@ -1,4 +1,3 @@
import * as Bluebird from 'bluebird'
import { invert } from 'lodash' import { invert } from 'lodash'
import { literal, Op, QueryTypes } from 'sequelize' import { literal, Op, QueryTypes } from 'sequelize'
import { import {
@ -188,7 +187,7 @@ export enum ScopeNames {
} }
] ]
}) })
export class AbuseModel extends Model<AbuseModel> { export class AbuseModel extends Model {
@AllowNull(false) @AllowNull(false)
@Default(null) @Default(null)
@ -265,7 +264,7 @@ export class AbuseModel extends Model<AbuseModel> {
}) })
VideoAbuse: VideoAbuseModel VideoAbuse: VideoAbuseModel
static loadByIdWithReporter (id: number): Bluebird<MAbuseReporter> { static loadByIdWithReporter (id: number): Promise<MAbuseReporter> {
const query = { const query = {
where: { where: {
id id
@ -281,7 +280,7 @@ export class AbuseModel extends Model<AbuseModel> {
return AbuseModel.findOne(query) return AbuseModel.findOne(query)
} }
static loadFull (id: number): Bluebird<MAbuseFull> { static loadFull (id: number): Promise<MAbuseFull> {
const query = { const query = {
where: { where: {
id id

View File

@ -14,7 +14,7 @@ import { AbuseModel } from './abuse'
} }
] ]
}) })
export class VideoAbuseModel extends Model<VideoAbuseModel> { export class VideoAbuseModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date

View File

@ -13,7 +13,7 @@ import { AbuseModel } from './abuse'
} }
] ]
}) })
export class VideoCommentAbuseModel extends Model<VideoCommentAbuseModel> { export class VideoCommentAbuseModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date

View File

@ -1,4 +1,3 @@
import * as Bluebird from 'bluebird'
import { Op } from 'sequelize' import { Op } from 'sequelize'
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/types/models' import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/types/models'
@ -41,7 +40,7 @@ enum ScopeNames {
} }
] ]
}) })
export class AccountBlocklistModel extends Model<AccountBlocklistModel> { export class AccountBlocklistModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date
@ -102,7 +101,7 @@ export class AccountBlocklistModel extends Model<AccountBlocklistModel> {
}) })
} }
static loadByAccountAndTarget (accountId: number, targetAccountId: number): Bluebird<MAccountBlocklist> { static loadByAccountAndTarget (accountId: number, targetAccountId: number): Promise<MAccountBlocklist> {
const query = { const query = {
where: { where: {
accountId, accountId,
@ -151,9 +150,9 @@ export class AccountBlocklistModel extends Model<AccountBlocklistModel> {
}) })
} }
static listHandlesBlockedBy (accountIds: number[]): Bluebird<string[]> { static listHandlesBlockedBy (accountIds: number[]): Promise<string[]> {
const query = { const query = {
attributes: [], attributes: [ 'id' ],
where: { where: {
accountId: { accountId: {
[Op.in]: accountIds [Op.in]: accountIds

View File

@ -1,22 +1,21 @@
import { values } from 'lodash' 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 { 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 { import {
MAccountVideoRate, MAccountVideoRate,
MAccountVideoRateAccountUrl, MAccountVideoRateAccountUrl,
MAccountVideoRateAccountVideo, MAccountVideoRateAccountVideo,
MAccountVideoRateFormattable MAccountVideoRateFormattable
} from '@server/types/models/video/video-rate' } 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. Account rates per video.
@ -43,7 +42,7 @@ import {
} }
] ]
}) })
export class AccountVideoRateModel extends Model<AccountVideoRateModel> { export class AccountVideoRateModel extends Model {
@AllowNull(false) @AllowNull(false)
@Column(DataType.ENUM(...values(VIDEO_RATE_TYPES))) @Column(DataType.ENUM(...values(VIDEO_RATE_TYPES)))
@ -84,7 +83,7 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
}) })
Account: AccountModel Account: AccountModel
static load (accountId: number, videoId: number, transaction?: Transaction): Bluebird<MAccountVideoRate> { static load (accountId: number, videoId: number, transaction?: Transaction): Promise<MAccountVideoRate> {
const options: FindOptions = { const options: FindOptions = {
where: { where: {
accountId, accountId,
@ -96,7 +95,7 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
return AccountVideoRateModel.findOne(options) return AccountVideoRateModel.findOne(options)
} }
static loadByAccountAndVideoOrUrl (accountId: number, videoId: number, url: string, t?: Transaction): Bluebird<MAccountVideoRate> { static loadByAccountAndVideoOrUrl (accountId: number, videoId: number, url: string, t?: Transaction): Promise<MAccountVideoRate> {
const options: FindOptions = { const options: FindOptions = {
where: { where: {
[Op.or]: [ [Op.or]: [
@ -152,7 +151,7 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
accountName: string, accountName: string,
videoId: number | string, videoId: number | string,
t?: Transaction t?: Transaction
): Bluebird<MAccountVideoRateAccountVideo> { ): Promise<MAccountVideoRateAccountVideo> {
const options: FindOptions = { const options: FindOptions = {
where: { where: {
videoId, videoId,
@ -240,17 +239,23 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
transaction: t 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, transaction: t,
where: { replacements: { videoId, rateType: type },
id: videoId type: QueryTypes.UPDATE
} })
}
if (type === 'like') await VideoModel.increment({ likes: -deleted }, options)
else if (type === 'dislike') await VideoModel.increment({ dislikes: -deleted }, options)
}) })
} }

View File

@ -1,5 +1,4 @@
import * as Bluebird from 'bluebird' import { FindOptions, Includeable, IncludeOptions, Op, Transaction, WhereOptions } from 'sequelize'
import { FindOptions, IncludeOptions, Op, Transaction, WhereOptions } from 'sequelize'
import { import {
AllowNull, AllowNull,
BeforeDestroy, BeforeDestroy,
@ -73,28 +72,29 @@ export type SummaryOptions = {
required: false required: false
} }
const query: FindOptions = { const queryInclude: Includeable[] = [
attributes: [ 'id', 'name', 'actorId' ], {
include: [ attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ],
{ model: ActorModel.unscoped(),
attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ], required: options.actorRequired ?? true,
model: ActorModel.unscoped(), where: whereActor,
required: options.actorRequired ?? true, include: [
where: whereActor, serverInclude,
include: [
serverInclude,
{ {
model: AvatarModel.unscoped(), model: AvatarModel.unscoped(),
required: false required: false
} }
] ]
} }
] ]
const query: FindOptions = {
attributes: [ 'id', 'name', 'actorId' ]
} }
if (options.withAccountBlockerIds) { if (options.withAccountBlockerIds) {
query.include.push({ queryInclude.push({
attributes: [ 'id' ], attributes: [ 'id' ],
model: AccountBlocklistModel.unscoped(), model: AccountBlocklistModel.unscoped(),
as: 'BlockedAccounts', as: 'BlockedAccounts',
@ -120,6 +120,8 @@ export type SummaryOptions = {
] ]
} }
query.include = queryInclude
return query return query
} }
})) }))
@ -138,7 +140,7 @@ export type SummaryOptions = {
} }
] ]
}) })
export class AccountModel extends Model<AccountModel> { export class AccountModel extends Model {
@AllowNull(false) @AllowNull(false)
@Column @Column
@ -244,11 +246,11 @@ export class AccountModel extends Model<AccountModel> {
return undefined return undefined
} }
static load (id: number, transaction?: Transaction): Bluebird<MAccountDefault> { static load (id: number, transaction?: Transaction): Promise<MAccountDefault> {
return AccountModel.findByPk(id, { transaction }) return AccountModel.findByPk(id, { transaction })
} }
static loadByNameWithHost (nameWithHost: string): Bluebird<MAccountDefault> { static loadByNameWithHost (nameWithHost: string): Promise<MAccountDefault> {
const [ accountName, host ] = nameWithHost.split('@') const [ accountName, host ] = nameWithHost.split('@')
if (!host || host === WEBSERVER.HOST) return AccountModel.loadLocalByName(accountName) if (!host || host === WEBSERVER.HOST) return AccountModel.loadLocalByName(accountName)
@ -256,7 +258,7 @@ export class AccountModel extends Model<AccountModel> {
return AccountModel.loadByNameAndHost(accountName, host) return AccountModel.loadByNameAndHost(accountName, host)
} }
static loadLocalByName (name: string): Bluebird<MAccountDefault> { static loadLocalByName (name: string): Promise<MAccountDefault> {
const fun = () => { const fun = () => {
const query = { const query = {
where: { where: {
@ -296,7 +298,7 @@ export class AccountModel extends Model<AccountModel> {
}) })
} }
static loadByNameAndHost (name: string, host: string): Bluebird<MAccountDefault> { static loadByNameAndHost (name: string, host: string): Promise<MAccountDefault> {
const query = { const query = {
include: [ include: [
{ {
@ -321,7 +323,7 @@ export class AccountModel extends Model<AccountModel> {
return AccountModel.findOne(query) return AccountModel.findOne(query)
} }
static loadByUrl (url: string, transaction?: Transaction): Bluebird<MAccountDefault> { static loadByUrl (url: string, transaction?: Transaction): Promise<MAccountDefault> {
const query = { const query = {
include: [ include: [
{ {
@ -354,7 +356,7 @@ export class AccountModel extends Model<AccountModel> {
}) })
} }
static loadAccountIdFromVideo (videoId: number): Bluebird<MAccount> { static loadAccountIdFromVideo (videoId: number): Promise<MAccount> {
const query = { const query = {
include: [ include: [
{ {
@ -377,7 +379,7 @@ export class AccountModel extends Model<AccountModel> {
return AccountModel.findOne(query) return AccountModel.findOne(query)
} }
static listLocalsForSitemap (sort: string): Bluebird<MAccountActor[]> { static listLocalsForSitemap (sort: string): Promise<MAccountActor[]> {
const query = { const query = {
attributes: [ ], attributes: [ ],
offset: 0, offset: 0,

View File

@ -28,7 +28,7 @@ import { UserModel } from './user'
} }
] ]
}) })
export class UserNotificationSettingModel extends Model<UserNotificationSettingModel> { export class UserNotificationSettingModel extends Model {
@AllowNull(false) @AllowNull(false)
@Default(null) @Default(null)

View File

@ -254,7 +254,7 @@ function buildAccountInclude (required: boolean, withActor = false) {
} }
] as (ModelIndexesOptions & { where?: WhereOptions })[] ] as (ModelIndexesOptions & { where?: WhereOptions })[]
}) })
export class UserNotificationModel extends Model<UserNotificationModel> { export class UserNotificationModel extends Model {
@AllowNull(false) @AllowNull(false)
@Default(null) @Default(null)

View File

@ -19,7 +19,7 @@ import { MUserAccountId, MUserId } from '@server/types/models'
} }
] ]
}) })
export class UserVideoHistoryModel extends Model<UserVideoHistoryModel> { export class UserVideoHistoryModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date

View File

@ -1,4 +1,3 @@
import * as Bluebird from 'bluebird'
import { values } from 'lodash' import { values } from 'lodash'
import { col, FindOptions, fn, literal, Op, QueryTypes, where, WhereOptions } from 'sequelize' import { col, FindOptions, fn, literal, Op, QueryTypes, where, WhereOptions } from 'sequelize'
import { import {
@ -16,11 +15,11 @@ import {
HasOne, HasOne,
Is, Is,
IsEmail, IsEmail,
IsUUID,
Model, Model,
Scopes, Scopes,
Table, Table,
UpdatedAt, UpdatedAt
IsUUID
} from 'sequelize-typescript' } from 'sequelize-typescript'
import { import {
MMyUserFormattable, MMyUserFormattable,
@ -220,7 +219,7 @@ enum ScopeNames {
} }
] ]
}) })
export class UserModel extends Model<UserModel> { export class UserModel extends Model {
@AllowNull(true) @AllowNull(true)
@Is('UserPassword', value => throwIfNotValid(value, isUserPasswordValid, 'user password', true)) @Is('UserPassword', value => throwIfNotValid(value, isUserPasswordValid, 'user password', true))
@ -483,7 +482,7 @@ export class UserModel extends Model<UserModel> {
}) })
} }
static listWithRight (right: UserRight): Bluebird<MUserDefault[]> { static listWithRight (right: UserRight): Promise<MUserDefault[]> {
const roles = Object.keys(USER_ROLE_LABELS) const roles = Object.keys(USER_ROLE_LABELS)
.map(k => parseInt(k, 10) as UserRole) .map(k => parseInt(k, 10) as UserRole)
.filter(role => hasUserRight(role, right)) .filter(role => hasUserRight(role, right))
@ -499,7 +498,7 @@ export class UserModel extends Model<UserModel> {
return UserModel.findAll(query) return UserModel.findAll(query)
} }
static listUserSubscribersOf (actorId: number): Bluebird<MUserWithNotificationSetting[]> { static listUserSubscribersOf (actorId: number): Promise<MUserWithNotificationSetting[]> {
const query = { const query = {
include: [ include: [
{ {
@ -538,7 +537,7 @@ export class UserModel extends Model<UserModel> {
return UserModel.unscoped().findAll(query) return UserModel.unscoped().findAll(query)
} }
static listByUsernames (usernames: string[]): Bluebird<MUserDefault[]> { static listByUsernames (usernames: string[]): Promise<MUserDefault[]> {
const query = { const query = {
where: { where: {
username: usernames username: usernames
@ -548,11 +547,11 @@ export class UserModel extends Model<UserModel> {
return UserModel.findAll(query) return UserModel.findAll(query)
} }
static loadById (id: number): Bluebird<MUser> { static loadById (id: number): Promise<MUser> {
return UserModel.unscoped().findByPk(id) return UserModel.unscoped().findByPk(id)
} }
static loadByIdWithChannels (id: number, withStats = false): Bluebird<MUserDefault> { static loadByIdWithChannels (id: number, withStats = false): Promise<MUserDefault> {
const scopes = [ const scopes = [
ScopeNames.WITH_VIDEOCHANNELS ScopeNames.WITH_VIDEOCHANNELS
] ]
@ -562,7 +561,7 @@ export class UserModel extends Model<UserModel> {
return UserModel.scope(scopes).findByPk(id) return UserModel.scope(scopes).findByPk(id)
} }
static loadByUsername (username: string): Bluebird<MUserDefault> { static loadByUsername (username: string): Promise<MUserDefault> {
const query = { const query = {
where: { where: {
username: { [Op.iLike]: username } username: { [Op.iLike]: username }
@ -572,7 +571,7 @@ export class UserModel extends Model<UserModel> {
return UserModel.findOne(query) return UserModel.findOne(query)
} }
static loadForMeAPI (username: string): Bluebird<MUserNotifSettingChannelDefault> { static loadForMeAPI (username: string): Promise<MUserNotifSettingChannelDefault> {
const query = { const query = {
where: { where: {
username: { [Op.iLike]: username } username: { [Op.iLike]: username }
@ -582,7 +581,7 @@ export class UserModel extends Model<UserModel> {
return UserModel.scope(ScopeNames.FOR_ME_API).findOne(query) return UserModel.scope(ScopeNames.FOR_ME_API).findOne(query)
} }
static loadByEmail (email: string): Bluebird<MUserDefault> { static loadByEmail (email: string): Promise<MUserDefault> {
const query = { const query = {
where: { where: {
email email
@ -592,7 +591,7 @@ export class UserModel extends Model<UserModel> {
return UserModel.findOne(query) return UserModel.findOne(query)
} }
static loadByUsernameOrEmail (username: string, email?: string): Bluebird<MUserDefault> { static loadByUsernameOrEmail (username: string, email?: string): Promise<MUserDefault> {
if (!email) email = username if (!email) email = username
const query = { const query = {
@ -608,7 +607,7 @@ export class UserModel extends Model<UserModel> {
return UserModel.findOne(query) return UserModel.findOne(query)
} }
static loadByVideoId (videoId: number): Bluebird<MUserDefault> { static loadByVideoId (videoId: number): Promise<MUserDefault> {
const query = { const query = {
include: [ include: [
{ {
@ -639,7 +638,7 @@ export class UserModel extends Model<UserModel> {
return UserModel.findOne(query) return UserModel.findOne(query)
} }
static loadByVideoImportId (videoImportId: number): Bluebird<MUserDefault> { static loadByVideoImportId (videoImportId: number): Promise<MUserDefault> {
const query = { const query = {
include: [ include: [
{ {
@ -656,7 +655,7 @@ export class UserModel extends Model<UserModel> {
return UserModel.findOne(query) return UserModel.findOne(query)
} }
static loadByChannelActorId (videoChannelActorId: number): Bluebird<MUserDefault> { static loadByChannelActorId (videoChannelActorId: number): Promise<MUserDefault> {
const query = { const query = {
include: [ include: [
{ {
@ -680,7 +679,7 @@ export class UserModel extends Model<UserModel> {
return UserModel.findOne(query) return UserModel.findOne(query)
} }
static loadByAccountActorId (accountActorId: number): Bluebird<MUserDefault> { static loadByAccountActorId (accountActorId: number): Promise<MUserDefault> {
const query = { const query = {
include: [ include: [
{ {
@ -697,7 +696,7 @@ export class UserModel extends Model<UserModel> {
return UserModel.findOne(query) return UserModel.findOne(query)
} }
static loadByLiveId (liveId: number): Bluebird<MUser> { static loadByLiveId (liveId: number): Promise<MUser> {
const query = { const query = {
include: [ include: [
{ {

View File

@ -1,4 +1,3 @@
import * as Bluebird from 'bluebird'
import { difference, values } from 'lodash' import { difference, values } from 'lodash'
import { IncludeOptions, Op, QueryTypes, Transaction, WhereOptions } from 'sequelize' import { IncludeOptions, Op, QueryTypes, Transaction, WhereOptions } from 'sequelize'
import { import {
@ -62,7 +61,7 @@ import { ActorModel, unusedActorAttributesForAPI } from './actor'
} }
] ]
}) })
export class ActorFollowModel extends Model<ActorFollowModel> { export class ActorFollowModel extends Model {
@AllowNull(false) @AllowNull(false)
@Column(DataType.ENUM(...values(FOLLOW_STATES))) @Column(DataType.ENUM(...values(FOLLOW_STATES)))
@ -176,7 +175,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
.then(results => results.length === 1) .then(results => results.length === 1)
} }
static loadByActorAndTarget (actorId: number, targetActorId: number, t?: Transaction): Bluebird<MActorFollowActorsDefault> { static loadByActorAndTarget (actorId: number, targetActorId: number, t?: Transaction): Promise<MActorFollowActorsDefault> {
const query = { const query = {
where: { where: {
actorId, actorId,
@ -205,7 +204,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
targetName: string, targetName: string,
targetHost: string, targetHost: string,
t?: Transaction t?: Transaction
): Bluebird<MActorFollowActorsDefaultSubscription> { ): Promise<MActorFollowActorsDefaultSubscription> {
const actorFollowingPartInclude: IncludeOptions = { const actorFollowingPartInclude: IncludeOptions = {
model: ActorModel, model: ActorModel,
required: true, required: true,
@ -258,7 +257,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
}) })
} }
static listSubscribedIn (actorId: number, targets: { name: string, host?: string }[]): Bluebird<MActorFollowFollowingHost[]> { static listSubscribedIn (actorId: number, targets: { name: string, host?: string }[]): Promise<MActorFollowFollowingHost[]> {
const whereTab = targets const whereTab = targets
.map(t => { .map(t => {
if (t.host) { if (t.host) {
@ -287,7 +286,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
}) })
const query = { const query = {
attributes: [], attributes: [ 'id' ],
where: { where: {
[Op.and]: [ [Op.and]: [
{ {
@ -671,7 +670,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> {
selections.push('COUNT(*) AS "total"') selections.push('COUNT(*) AS "total"')
const tasks: Bluebird<any>[] = [] const tasks: Promise<any>[] = []
for (const selection of selections) { for (const selection of selections) {
let query = 'SELECT ' + selection + ' FROM "actor" ' + let query = 'SELECT ' + selection + ' FROM "actor" ' +

View File

@ -1,5 +1,6 @@
import { values } from 'lodash' import { values } from 'lodash'
import { extname } from 'path' import { extname } from 'path'
import { literal, Op, Transaction } from 'sequelize'
import { import {
AllowNull, AllowNull,
BelongsTo, BelongsTo,
@ -16,6 +17,7 @@ import {
Table, Table,
UpdatedAt UpdatedAt
} from 'sequelize-typescript' } from 'sequelize-typescript'
import { ModelCache } from '@server/models/model-cache'
import { ActivityIconObject, ActivityPubActorType } from '../../../shared/models/activitypub' import { ActivityIconObject, ActivityPubActorType } from '../../../shared/models/activitypub'
import { Avatar } from '../../../shared/models/avatars/avatar.model' import { Avatar } from '../../../shared/models/avatars/avatar.model'
import { activityPubContextify } from '../../helpers/activitypub' import { activityPubContextify } from '../../helpers/activitypub'
@ -28,13 +30,6 @@ import {
} from '../../helpers/custom-validators/activitypub/actor' } from '../../helpers/custom-validators/activitypub/actor'
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' 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 { 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 { import {
MActor, MActor,
MActorAccountChannelId, MActorAccountChannelId,
@ -43,12 +38,17 @@ import {
MActorFull, MActorFull,
MActorHost, MActorHost,
MActorServer, MActorServer,
MActorSummaryFormattable, MActorUrl, MActorSummaryFormattable,
MActorUrl,
MActorWithInboxes MActorWithInboxes
} from '../../types/models' } from '../../types/models'
import * as Bluebird from 'bluebird' import { AccountModel } from '../account/account'
import { Op, Transaction, literal } from 'sequelize' import { AvatarModel } from '../avatar/avatar'
import { ModelCache } from '@server/models/model-cache' 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 { enum ScopeNames {
FULL = 'FULL' FULL = 'FULL'
@ -146,7 +146,7 @@ export const unusedActorAttributesForAPI = [
} }
] ]
}) })
export class ActorModel extends Model<ActorModel> { export class ActorModel extends Model {
@AllowNull(false) @AllowNull(false)
@Column(DataType.ENUM(...values(ACTIVITY_PUB_ACTOR_TYPES))) @Column(DataType.ENUM(...values(ACTIVITY_PUB_ACTOR_TYPES)))
@ -276,15 +276,15 @@ export class ActorModel extends Model<ActorModel> {
}) })
VideoChannel: VideoChannelModel VideoChannel: VideoChannelModel
static load (id: number): Bluebird<MActor> { static load (id: number): Promise<MActor> {
return ActorModel.unscoped().findByPk(id) return ActorModel.unscoped().findByPk(id)
} }
static loadFull (id: number): Bluebird<MActorFull> { static loadFull (id: number): Promise<MActorFull> {
return ActorModel.scope(ScopeNames.FULL).findByPk(id) return ActorModel.scope(ScopeNames.FULL).findByPk(id)
} }
static loadFromAccountByVideoId (videoId: number, transaction: Transaction): Bluebird<MActor> { static loadFromAccountByVideoId (videoId: number, transaction: Transaction): Promise<MActor> {
const query = { const query = {
include: [ include: [
{ {
@ -328,7 +328,7 @@ export class ActorModel extends Model<ActorModel> {
.then(a => !!a) .then(a => !!a)
} }
static listByFollowersUrls (followersUrls: string[], transaction?: Transaction): Bluebird<MActorFull[]> { static listByFollowersUrls (followersUrls: string[], transaction?: Transaction): Promise<MActorFull[]> {
const query = { const query = {
where: { where: {
followersUrl: { followersUrl: {
@ -341,7 +341,7 @@ export class ActorModel extends Model<ActorModel> {
return ActorModel.scope(ScopeNames.FULL).findAll(query) return ActorModel.scope(ScopeNames.FULL).findAll(query)
} }
static loadLocalByName (preferredUsername: string, transaction?: Transaction): Bluebird<MActorFull> { static loadLocalByName (preferredUsername: string, transaction?: Transaction): Promise<MActorFull> {
const fun = () => { const fun = () => {
const query = { const query = {
where: { where: {
@ -364,7 +364,7 @@ export class ActorModel extends Model<ActorModel> {
}) })
} }
static loadLocalUrlByName (preferredUsername: string, transaction?: Transaction): Bluebird<MActorUrl> { static loadLocalUrlByName (preferredUsername: string, transaction?: Transaction): Promise<MActorUrl> {
const fun = () => { const fun = () => {
const query = { const query = {
attributes: [ 'url' ], attributes: [ 'url' ],
@ -388,7 +388,7 @@ export class ActorModel extends Model<ActorModel> {
}) })
} }
static loadByNameAndHost (preferredUsername: string, host: string): Bluebird<MActorFull> { static loadByNameAndHost (preferredUsername: string, host: string): Promise<MActorFull> {
const query = { const query = {
where: { where: {
preferredUsername preferredUsername
@ -407,7 +407,7 @@ export class ActorModel extends Model<ActorModel> {
return ActorModel.scope(ScopeNames.FULL).findOne(query) return ActorModel.scope(ScopeNames.FULL).findOne(query)
} }
static loadByUrl (url: string, transaction?: Transaction): Bluebird<MActorAccountChannelId> { static loadByUrl (url: string, transaction?: Transaction): Promise<MActorAccountChannelId> {
const query = { const query = {
where: { where: {
url url
@ -430,7 +430,7 @@ export class ActorModel extends Model<ActorModel> {
return ActorModel.unscoped().findOne(query) return ActorModel.unscoped().findOne(query)
} }
static loadByUrlAndPopulateAccountAndChannel (url: string, transaction?: Transaction): Bluebird<MActorFull> { static loadByUrlAndPopulateAccountAndChannel (url: string, transaction?: Transaction): Promise<MActorFull> {
const query = { const query = {
where: { where: {
url url
@ -461,7 +461,7 @@ export class ActorModel extends Model<ActorModel> {
}, { where, transaction }) }, { where, transaction })
} }
static loadAccountActorByVideoId (videoId: number): Bluebird<MActor> { static loadAccountActorByVideoId (videoId: number): Promise<MActor> {
const query = { const query = {
include: [ include: [
{ {

View File

@ -24,7 +24,7 @@ export const getServerActor = memoizee(async function () {
tableName: 'application', tableName: 'application',
timestamps: false timestamps: false
}) })
export class ApplicationModel extends Model<ApplicationModel> { export class ApplicationModel extends Model {
@AllowNull(false) @AllowNull(false)
@Default(0) @Default(0)

View File

@ -18,7 +18,7 @@ import { MAvatarFormattable } from '@server/types/models'
} }
] ]
}) })
export class AvatarModel extends Model<AvatarModel> { export class AvatarModel extends Model {
@AllowNull(false) @AllowNull(false)
@Column @Column

View File

@ -40,7 +40,7 @@ class ModelCache {
doCache<T extends Model> (options: { doCache<T extends Model> (options: {
cacheType: ModelCacheType cacheType: ModelCacheType
key: string key: string
fun: () => Bluebird<T> fun: () => Promise<T>
whitelist?: () => boolean whitelist?: () => boolean
deleteKey?: DeleteKey deleteKey?: DeleteKey
}) { }) {

View File

@ -14,7 +14,7 @@ import { OAuthTokenModel } from './oauth-token'
} }
] ]
}) })
export class OAuthClientModel extends Model<OAuthClientModel> { export class OAuthClientModel extends Model {
@AllowNull(false) @AllowNull(false)
@Column @Column

View File

@ -1,3 +1,4 @@
import { Transaction } from 'sequelize'
import { import {
AfterDestroy, AfterDestroy,
AfterUpdate, AfterUpdate,
@ -11,15 +12,13 @@ import {
Table, Table,
UpdatedAt UpdatedAt
} from 'sequelize-typescript' } 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 { 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 = { export type OAuthTokenInfo = {
refreshToken: string refreshToken: string
@ -80,7 +79,7 @@ enum ScopeNames {
} }
] ]
}) })
export class OAuthTokenModel extends Model<OAuthTokenModel> { export class OAuthTokenModel extends Model {
@AllowNull(false) @AllowNull(false)
@Column @Column
@ -174,7 +173,7 @@ export class OAuthTokenModel extends Model<OAuthTokenModel> {
}) })
} }
static getByTokenAndPopulateUser (bearerToken: string): Bluebird<MOAuthTokenUser> { static getByTokenAndPopulateUser (bearerToken: string): Promise<MOAuthTokenUser> {
const query = { const query = {
where: { where: {
accessToken: bearerToken accessToken: bearerToken
@ -190,7 +189,7 @@ export class OAuthTokenModel extends Model<OAuthTokenModel> {
}) })
} }
static getByRefreshTokenAndPopulateUser (refreshToken: string): Bluebird<MOAuthTokenUser> { static getByRefreshTokenAndPopulateUser (refreshToken: string): Promise<MOAuthTokenUser> {
const query = { const query = {
where: { where: {
refreshToken refreshToken

View File

@ -1,3 +1,5 @@
import { sample } from 'lodash'
import { col, FindOptions, fn, literal, Op, Transaction, WhereOptions } from 'sequelize'
import { import {
AllowNull, AllowNull,
BeforeDestroy, BeforeDestroy,
@ -12,23 +14,7 @@ import {
Table, Table,
UpdatedAt UpdatedAt
} from 'sequelize-typescript' } from 'sequelize-typescript'
import { ActorModel } from '../activitypub/actor' import { getServerActor } from '@server/models/application/application'
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 { MVideoForRedundancyAPI, MVideoRedundancy, MVideoRedundancyAP, MVideoRedundancyVideo } from '@server/types/models' import { MVideoForRedundancyAPI, MVideoRedundancy, MVideoRedundancyAP, MVideoRedundancyVideo } from '@server/types/models'
import { VideoRedundanciesTarget } from '@shared/models/redundancy/video-redundancies-filters.model' import { VideoRedundanciesTarget } from '@shared/models/redundancy/video-redundancies-filters.model'
import { import {
@ -36,7 +22,20 @@ import {
StreamingPlaylistRedundancyInformation, StreamingPlaylistRedundancyInformation,
VideoRedundancy VideoRedundancy
} from '@shared/models/redundancy/video-redundancy.model' } 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 { export enum ScopeNames {
WITH_VIDEO = 'WITH_VIDEO' WITH_VIDEO = 'WITH_VIDEO'
@ -84,7 +83,7 @@ export enum ScopeNames {
} }
] ]
}) })
export class VideoRedundancyModel extends Model<VideoRedundancyModel> { export class VideoRedundancyModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date
@ -199,7 +198,7 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
return VideoRedundancyModel.scope(ScopeNames.WITH_VIDEO).findOne(query) return VideoRedundancyModel.scope(ScopeNames.WITH_VIDEO).findOne(query)
} }
static loadByIdWithVideo (id: number, transaction?: Transaction): Bluebird<MVideoRedundancyVideo> { static loadByIdWithVideo (id: number, transaction?: Transaction): Promise<MVideoRedundancyVideo> {
const query = { const query = {
where: { id }, where: { id },
transaction transaction
@ -208,7 +207,7 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
return VideoRedundancyModel.scope(ScopeNames.WITH_VIDEO).findOne(query) return VideoRedundancyModel.scope(ScopeNames.WITH_VIDEO).findOne(query)
} }
static loadByUrl (url: string, transaction?: Transaction): Bluebird<MVideoRedundancy> { static loadByUrl (url: string, transaction?: Transaction): Promise<MVideoRedundancy> {
const query = { const query = {
where: { where: {
url url
@ -251,7 +250,7 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
.then(r => !!r) .then(r => !!r)
} }
static async getVideoSample (p: Bluebird<VideoModel[]>) { static async getVideoSample (p: Promise<VideoModel[]>) {
const rows = await p const rows = await p
if (rows.length === 0) return undefined if (rows.length === 0) return undefined
@ -696,7 +695,7 @@ export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
const notIn = literal( 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` +
')' ')'
) )

View File

@ -1,4 +1,3 @@
import * as Bluebird from 'bluebird'
import { FindAndCountOptions, json, QueryTypes } from 'sequelize' import { FindAndCountOptions, json, QueryTypes } from 'sequelize'
import { AllowNull, Column, CreatedAt, DataType, DefaultScope, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' import { AllowNull, Column, CreatedAt, DataType, DefaultScope, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
import { MPlugin, MPluginFormattable } from '@server/types/models' import { MPlugin, MPluginFormattable } from '@server/types/models'
@ -29,7 +28,7 @@ import { getSort, throwIfNotValid } from '../utils'
} }
] ]
}) })
export class PluginModel extends Model<PluginModel> { export class PluginModel extends Model {
@AllowNull(false) @AllowNull(false)
@Is('PluginName', value => throwIfNotValid(value, isPluginNameValid, 'name')) @Is('PluginName', value => throwIfNotValid(value, isPluginNameValid, 'name'))
@ -87,7 +86,7 @@ export class PluginModel extends Model<PluginModel> {
@UpdatedAt @UpdatedAt
updatedAt: Date updatedAt: Date
static listEnabledPluginsAndThemes (): Bluebird<MPlugin[]> { static listEnabledPluginsAndThemes (): Promise<MPlugin[]> {
const query = { const query = {
where: { where: {
enabled: true, enabled: true,
@ -98,7 +97,7 @@ export class PluginModel extends Model<PluginModel> {
return PluginModel.findAll(query) return PluginModel.findAll(query)
} }
static loadByNpmName (npmName: string): Bluebird<MPlugin> { static loadByNpmName (npmName: string): Promise<MPlugin> {
const name = this.normalizePluginName(npmName) const name = this.normalizePluginName(npmName)
const type = this.getTypeFromNpmName(npmName) const type = this.getTypeFromNpmName(npmName)
@ -252,7 +251,7 @@ export class PluginModel extends Model<PluginModel> {
}) })
} }
static listInstalled (): Bluebird<MPlugin[]> { static listInstalled (): Promise<MPlugin[]> {
const query = { const query = {
where: { where: {
uninstalled: false uninstalled: false

View File

@ -1,4 +1,3 @@
import * as Bluebird from 'bluebird'
import { Op } from 'sequelize' import { Op } from 'sequelize'
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/types/models' import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/types/models'
@ -43,7 +42,7 @@ enum ScopeNames {
} }
] ]
}) })
export class ServerBlocklistModel extends Model<ServerBlocklistModel> { export class ServerBlocklistModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date
@ -101,7 +100,7 @@ export class ServerBlocklistModel extends Model<ServerBlocklistModel> {
}) })
} }
static loadByAccountAndHost (accountId: number, host: string): Bluebird<MServerBlocklist> { static loadByAccountAndHost (accountId: number, host: string): Promise<MServerBlocklist> {
const query = { const query = {
where: { where: {
accountId accountId
@ -120,7 +119,7 @@ export class ServerBlocklistModel extends Model<ServerBlocklistModel> {
return ServerBlocklistModel.findOne(query) return ServerBlocklistModel.findOne(query)
} }
static listHostsBlockedBy (accountIds: number[]): Bluebird<string[]> { static listHostsBlockedBy (accountIds: number[]): Promise<string[]> {
const query = { const query = {
attributes: [ ], attributes: [ ],
where: { where: {

View File

@ -1,10 +1,9 @@
import { AllowNull, Column, CreatedAt, Default, HasMany, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' 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 { isHostValid } from '../../helpers/custom-validators/servers'
import { ActorModel } from '../activitypub/actor' import { ActorModel } from '../activitypub/actor'
import { throwIfNotValid } from '../utils' import { throwIfNotValid } from '../utils'
import { ServerBlocklistModel } from './server-blocklist' import { ServerBlocklistModel } from './server-blocklist'
import * as Bluebird from 'bluebird'
import { MServer, MServerFormattable } from '@server/types/models/server'
@Table({ @Table({
tableName: 'server', tableName: 'server',
@ -15,7 +14,7 @@ import { MServer, MServerFormattable } from '@server/types/models/server'
} }
] ]
}) })
export class ServerModel extends Model<ServerModel> { export class ServerModel extends Model {
@AllowNull(false) @AllowNull(false)
@Is('Host', value => throwIfNotValid(value, isHostValid, 'valid host')) @Is('Host', value => throwIfNotValid(value, isHostValid, 'valid host'))
@ -51,7 +50,7 @@ export class ServerModel extends Model<ServerModel> {
}) })
BlockedByAccounts: ServerBlocklistModel[] BlockedByAccounts: ServerBlocklistModel[]
static load (id: number): Bluebird<MServer> { static load (id: number): Promise<MServer> {
const query = { const query = {
where: { where: {
id id
@ -61,7 +60,7 @@ export class ServerModel extends Model<ServerModel> {
return ServerModel.findOne(query) return ServerModel.findOne(query)
} }
static loadByHost (host: string): Bluebird<MServer> { static loadByHost (host: string): Promise<MServer> {
const query = { const query = {
where: { where: {
host host

View File

@ -113,7 +113,8 @@ function throwIfNotValid (value: any, validator: (value: any) => boolean, fieldN
function buildTrigramSearchIndex (indexName: string, attribute: string) { function buildTrigramSearchIndex (indexName: string, attribute: string) {
return { return {
name: indexName, 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', using: 'gin',
operator: 'gin_trgm_ops' operator: 'gin_trgm_ops'
} }

View File

@ -16,7 +16,7 @@ import { MScheduleVideoUpdateFormattable, MScheduleVideoUpdateVideoAll } from '@
} }
] ]
}) })
export class ScheduleVideoUpdateModel extends Model<ScheduleVideoUpdateModel> { export class ScheduleVideoUpdateModel extends Model {
@AllowNull(false) @AllowNull(false)
@Default(null) @Default(null)

View File

@ -1,12 +1,11 @@
import * as Bluebird from 'bluebird' import { col, fn, QueryTypes, Transaction } from 'sequelize'
import { fn, QueryTypes, Transaction, col } from 'sequelize'
import { AllowNull, BelongsToMany, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' 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 { isVideoTagValid } from '../../helpers/custom-validators/videos'
import { throwIfNotValid } from '../utils' import { throwIfNotValid } from '../utils'
import { VideoModel } from './video' import { VideoModel } from './video'
import { VideoTagModel } from './video-tag' import { VideoTagModel } from './video-tag'
import { VideoPrivacy, VideoState } from '../../../shared/models/videos'
import { MTag } from '@server/types/models'
@Table({ @Table({
tableName: 'tag', tableName: 'tag',
@ -22,7 +21,7 @@ import { MTag } from '@server/types/models'
} }
] ]
}) })
export class TagModel extends Model<TagModel> { export class TagModel extends Model {
@AllowNull(false) @AllowNull(false)
@Is('VideoTag', value => throwIfNotValid(value, isVideoTagValid, 'tag')) @Is('VideoTag', value => throwIfNotValid(value, isVideoTagValid, 'tag'))
@ -45,7 +44,7 @@ export class TagModel extends Model<TagModel> {
static findOrCreateTags (tags: string[], transaction: Transaction): Promise<MTag[]> { static findOrCreateTags (tags: string[], transaction: Transaction): Promise<MTag[]> {
if (tags === null) return Promise.resolve([]) if (tags === null) return Promise.resolve([])
const tasks: Bluebird<MTag>[] = [] const tasks: Promise<MTag>[] = []
tags.forEach(tag => { tags.forEach(tag => {
const query = { const query = {
where: { where: {
@ -66,7 +65,7 @@ export class TagModel extends Model<TagModel> {
} }
// threshold corresponds to how many video the field should have to be returned // threshold corresponds to how many video the field should have to be returned
static getRandomSamples (threshold: number, count: number): Bluebird<string[]> { static getRandomSamples (threshold: number, count: number): Promise<string[]> {
const query = 'SELECT tag.name FROM tag ' + const query = 'SELECT tag.name FROM tag ' +
'INNER JOIN "videoTag" ON "videoTag"."tagId" = tag.id ' + 'INNER JOIN "videoTag" ON "videoTag"."tagId" = tag.id ' +
'INNER JOIN video ON video.id = "videoTag"."videoId" ' + 'INNER JOIN video ON video.id = "videoTag"."videoId" ' +

View File

@ -34,7 +34,7 @@ import { buildRemoteVideoBaseUrl } from '@server/helpers/activitypub'
} }
] ]
}) })
export class ThumbnailModel extends Model<ThumbnailModel> { export class ThumbnailModel extends Model {
@AllowNull(false) @AllowNull(false)
@Column @Column

View File

@ -1,14 +1,13 @@
import { FindOptions } from 'sequelize'
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' 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 { VideoModel } from './video'
import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel' 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({ @Table({
tableName: 'videoBlacklist', tableName: 'videoBlacklist',
@ -19,7 +18,7 @@ import { MVideoBlacklist, MVideoBlacklistFormattable } from '@server/types/model
} }
] ]
}) })
export class VideoBlacklistModel extends Model<VideoBlacklistModel> { export class VideoBlacklistModel extends Model {
@AllowNull(true) @AllowNull(true)
@Is('VideoBlacklistReason', value => throwIfNotValid(value, isVideoBlacklistReasonValid, 'reason', true)) @Is('VideoBlacklistReason', value => throwIfNotValid(value, isVideoBlacklistReasonValid, 'reason', true))
@ -109,7 +108,7 @@ export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
}) })
} }
static loadByVideoId (id: number): Bluebird<MVideoBlacklist> { static loadByVideoId (id: number): Promise<MVideoBlacklist> {
const query = { const query = {
where: { where: {
videoId: id videoId: id

View File

@ -1,3 +1,5 @@
import { remove } from 'fs-extra'
import { join } from 'path'
import { OrderItem, Transaction } from 'sequelize' import { OrderItem, Transaction } from 'sequelize'
import { import {
AllowNull, AllowNull,
@ -13,18 +15,15 @@ import {
Table, Table,
UpdatedAt UpdatedAt
} from 'sequelize-typescript' } 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 { buildWhereIdOrUUID, throwIfNotValid } from '../utils'
import { VideoModel } from './video' 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 { export enum ScopeNames {
WITH_VIDEO_UUID_AND_REMOTE = 'WITH_VIDEO_UUID_AND_REMOTE' WITH_VIDEO_UUID_AND_REMOTE = 'WITH_VIDEO_UUID_AND_REMOTE'
@ -54,7 +53,7 @@ export enum ScopeNames {
} }
] ]
}) })
export class VideoCaptionModel extends Model<VideoCaptionModel> { export class VideoCaptionModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date
@ -101,7 +100,7 @@ export class VideoCaptionModel extends Model<VideoCaptionModel> {
return undefined return undefined
} }
static loadByVideoIdAndLanguage (videoId: string | number, language: string): Bluebird<MVideoCaptionVideo> { static loadByVideoIdAndLanguage (videoId: string | number, language: string): Promise<MVideoCaptionVideo> {
const videoInclude = { const videoInclude = {
model: VideoModel.unscoped(), model: VideoModel.unscoped(),
attributes: [ 'id', 'remote', 'uuid' ], attributes: [ 'id', 'remote', 'uuid' ],
@ -131,7 +130,7 @@ export class VideoCaptionModel extends Model<VideoCaptionModel> {
.then(([ caption ]) => caption) .then(([ caption ]) => caption)
} }
static listVideoCaptions (videoId: number): Bluebird<MVideoCaptionVideo[]> { static listVideoCaptions (videoId: number): Promise<MVideoCaptionVideo[]> {
const query = { const query = {
order: [ [ 'language', 'ASC' ] ] as OrderItem[], order: [ [ 'language', 'ASC' ] ] as OrderItem[],
where: { where: {

View File

@ -1,10 +1,9 @@
import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' 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 { 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 { enum ScopeNames {
WITH_ACCOUNTS = 'WITH_ACCOUNTS', WITH_ACCOUNTS = 'WITH_ACCOUNTS',
@ -54,7 +53,7 @@ enum ScopeNames {
] ]
} }
})) }))
export class VideoChangeOwnershipModel extends Model<VideoChangeOwnershipModel> { export class VideoChangeOwnershipModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date
@ -119,7 +118,7 @@ export class VideoChangeOwnershipModel extends Model<VideoChangeOwnershipModel>
]).then(([ count, rows ]) => ({ total: count, data: rows })) ]).then(([ count, rows ]) => ({ total: count, data: rows }))
} }
static load (id: number): Bluebird<MVideoChangeOwnershipFull> { static load (id: number): Promise<MVideoChangeOwnershipFull> {
return VideoChangeOwnershipModel.scope([ ScopeNames.WITH_ACCOUNTS, ScopeNames.WITH_VIDEO ]) return VideoChangeOwnershipModel.scope([ ScopeNames.WITH_ACCOUNTS, ScopeNames.WITH_VIDEO ])
.findByPk(id) .findByPk(id)
} }

View File

@ -1,5 +1,4 @@
import * as Bluebird from 'bluebird' import { FindOptions, Includeable, literal, Op, ScopeOptions } from 'sequelize'
import { FindOptions, literal, Op, ScopeOptions } from 'sequelize'
import { import {
AllowNull, AllowNull,
BeforeDestroy, BeforeDestroy,
@ -119,30 +118,31 @@ export type SummaryOptions = {
} }
}, },
[ScopeNames.SUMMARY]: (options: 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 = { const base: FindOptions = {
attributes: [ 'id', 'name', 'description', 'actorId' ], 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
}
]
}
]
} }
if (options.withAccount === true) { if (options.withAccount === true) {
base.include.push({ include.push({
model: AccountModel.scope({ model: AccountModel.scope({
method: [ AccountModelScopeNames.SUMMARY, { withAccountBlockerIds: options.withAccountBlockerIds } as AccountSummaryOptions ] method: [ AccountModelScopeNames.SUMMARY, { withAccountBlockerIds: options.withAccountBlockerIds } as AccountSummaryOptions ]
}), }),
@ -150,6 +150,8 @@ export type SummaryOptions = {
}) })
} }
base.include = include
return base return base
}, },
[ScopeNames.WITH_ACCOUNT]: { [ScopeNames.WITH_ACCOUNT]: {
@ -221,7 +223,7 @@ export type SummaryOptions = {
} }
] ]
}) })
export class VideoChannelModel extends Model<VideoChannelModel> { export class VideoChannelModel extends Model {
@AllowNull(false) @AllowNull(false)
@Is('VideoChannelName', value => throwIfNotValid(value, isVideoChannelNameValid, 'name')) @Is('VideoChannelName', value => throwIfNotValid(value, isVideoChannelNameValid, 'name'))
@ -328,18 +330,17 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
order: getSort(parameters.sort) order: getSort(parameters.sort)
} }
const scopes = {
method: [ ScopeNames.FOR_API, { actorId } as AvailableForListOptions ]
}
return VideoChannelModel return VideoChannelModel
.scope(scopes) .scope({
method: [ ScopeNames.FOR_API, { actorId } as AvailableForListOptions ]
})
.findAndCountAll(query) .findAndCountAll(query)
.then(({ rows, count }) => { .then(({ rows, count }) => {
return { total: count, data: rows } return { total: count, data: rows }
}) })
} }
static listLocalsForSitemap (sort: string): Bluebird<MChannelActor[]> { static listLocalsForSitemap (sort: string): Promise<MChannelActor[]> {
const query = { const query = {
attributes: [ ], attributes: [ ],
offset: 0, offset: 0,
@ -391,11 +392,10 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
} }
} }
const scopes = {
method: [ ScopeNames.FOR_API, { actorId: options.actorId } as AvailableForListOptions ]
}
return VideoChannelModel return VideoChannelModel
.scope(scopes) .scope({
method: [ ScopeNames.FOR_API, { actorId: options.actorId } as AvailableForListOptions ]
})
.findAndCountAll(query) .findAndCountAll(query)
.then(({ rows, count }) => { .then(({ rows, count }) => {
return { total: count, data: rows } return { total: count, data: rows }
@ -457,13 +457,13 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
}) })
} }
static loadByIdAndPopulateAccount (id: number): Bluebird<MChannelAccountDefault> { static loadByIdAndPopulateAccount (id: number): Promise<MChannelAccountDefault> {
return VideoChannelModel.unscoped() return VideoChannelModel.unscoped()
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findByPk(id) .findByPk(id)
} }
static loadByIdAndAccount (id: number, accountId: number): Bluebird<MChannelAccountDefault> { static loadByIdAndAccount (id: number, accountId: number): Promise<MChannelAccountDefault> {
const query = { const query = {
where: { where: {
id, id,
@ -476,13 +476,13 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
.findOne(query) .findOne(query)
} }
static loadAndPopulateAccount (id: number): Bluebird<MChannelAccountDefault> { static loadAndPopulateAccount (id: number): Promise<MChannelAccountDefault> {
return VideoChannelModel.unscoped() return VideoChannelModel.unscoped()
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ]) .scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findByPk(id) .findByPk(id)
} }
static loadByUrlAndPopulateAccount (url: string): Bluebird<MChannelAccountDefault> { static loadByUrlAndPopulateAccount (url: string): Promise<MChannelAccountDefault> {
const query = { const query = {
include: [ include: [
{ {
@ -508,7 +508,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
return VideoChannelModel.loadByNameAndHostAndPopulateAccount(name, host) return VideoChannelModel.loadByNameAndHostAndPopulateAccount(name, host)
} }
static loadLocalByNameAndPopulateAccount (name: string): Bluebird<MChannelAccountDefault> { static loadLocalByNameAndPopulateAccount (name: string): Promise<MChannelAccountDefault> {
const query = { const query = {
include: [ include: [
{ {
@ -527,7 +527,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
.findOne(query) .findOne(query)
} }
static loadByNameAndHostAndPopulateAccount (name: string, host: string): Bluebird<MChannelAccountDefault> { static loadByNameAndHostAndPopulateAccount (name: string, host: string): Promise<MChannelAccountDefault> {
const query = { const query = {
include: [ include: [
{ {
@ -552,7 +552,7 @@ export class VideoChannelModel extends Model<VideoChannelModel> {
.findOne(query) .findOne(query)
} }
static loadAndPopulateAccountAndVideos (id: number): Bluebird<MChannelActorAccountDefaultVideos> { static loadAndPopulateAccountAndVideos (id: number): Promise<MChannelActorAccountDefaultVideos> {
const options = { const options = {
include: [ include: [
VideoModel VideoModel

View File

@ -1,4 +1,3 @@
import * as Bluebird from 'bluebird'
import { uniq } from 'lodash' import { uniq } from 'lodash'
import { FindAndCountOptions, FindOptions, Op, Order, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize' import { FindAndCountOptions, FindOptions, Op, Order, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize'
import { import {
@ -174,7 +173,7 @@ export enum ScopeNames {
} }
] ]
}) })
export class VideoCommentModel extends Model<VideoCommentModel> { export class VideoCommentModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date
@ -255,7 +254,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
}) })
CommentAbuses: VideoCommentAbuseModel[] CommentAbuses: VideoCommentAbuseModel[]
static loadById (id: number, t?: Transaction): Bluebird<MComment> { static loadById (id: number, t?: Transaction): Promise<MComment> {
const query: FindOptions = { const query: FindOptions = {
where: { where: {
id id
@ -267,7 +266,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
return VideoCommentModel.findOne(query) return VideoCommentModel.findOne(query)
} }
static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Transaction): Bluebird<MCommentOwnerVideoReply> { static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Transaction): Promise<MCommentOwnerVideoReply> {
const query: FindOptions = { const query: FindOptions = {
where: { where: {
id id
@ -281,7 +280,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
.findOne(query) .findOne(query)
} }
static loadByUrlAndPopulateAccountAndVideo (url: string, t?: Transaction): Bluebird<MCommentOwnerVideo> { static loadByUrlAndPopulateAccountAndVideo (url: string, t?: Transaction): Promise<MCommentOwnerVideo> {
const query: FindOptions = { const query: FindOptions = {
where: { where: {
url url
@ -293,7 +292,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEO ]).findOne(query) return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_VIDEO ]).findOne(query)
} }
static loadByUrlAndPopulateReplyAndVideoUrlAndAccount (url: string, t?: Transaction): Bluebird<MCommentOwnerReplyVideoLight> { static loadByUrlAndPopulateReplyAndVideoUrlAndAccount (url: string, t?: Transaction): Promise<MCommentOwnerReplyVideoLight> {
const query: FindOptions = { const query: FindOptions = {
where: { where: {
url url
@ -501,7 +500,7 @@ export class VideoCommentModel extends Model<VideoCommentModel> {
}) })
} }
static listThreadParentComments (comment: MCommentId, t: Transaction, order: 'ASC' | 'DESC' = 'ASC'): Bluebird<MCommentOwner[]> { static listThreadParentComments (comment: MCommentId, t: Transaction, order: 'ASC' | 'DESC' = 'ASC'): Promise<MCommentOwner[]> {
const query = { const query = {
order: [ [ 'createdAt', order ] ] as Order, order: [ [ 'createdAt', order ] ] as Order,
where: { where: {

View File

@ -101,7 +101,7 @@ export enum ScopeNames {
} }
] ]
}) })
export class VideoFileModel extends Model<VideoFileModel> { export class VideoFileModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date

View File

@ -13,15 +13,14 @@ import {
Table, Table,
UpdatedAt UpdatedAt
} from 'sequelize-typescript' } 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 { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers/constants'
import { UserModel } from '../account/user'
import { getSort, throwIfNotValid } from '../utils' import { getSort, throwIfNotValid } from '../utils'
import { ScopeNames as VideoModelScopeNames, VideoModel } from './video' 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(() => ({ @DefaultScope(() => ({
include: [ include: [
@ -52,7 +51,7 @@ import { MVideoImportDefault, MVideoImportFormattable } from '@server/types/mode
} }
] ]
}) })
export class VideoImportModel extends Model<VideoImportModel> { export class VideoImportModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date
@ -120,7 +119,7 @@ export class VideoImportModel extends Model<VideoImportModel> {
return undefined return undefined
} }
static loadAndPopulateVideo (id: number): Bluebird<MVideoImportDefault> { static loadAndPopulateVideo (id: number): Promise<MVideoImportDefault> {
return VideoImportModel.findByPk(id) return VideoImportModel.findByPk(id)
} }

View File

@ -28,7 +28,7 @@ import { VideoBlacklistModel } from './video-blacklist'
} }
] ]
}) })
export class VideoLiveModel extends Model<VideoLiveModel> { export class VideoLiveModel extends Model {
@AllowNull(true) @AllowNull(true)
@Column(DataType.STRING) @Column(DataType.STRING)

View File

@ -1,3 +1,4 @@
import { AggregateOptions, Op, ScopeOptions, Sequelize, Transaction } from 'sequelize'
import { import {
AllowNull, AllowNull,
BelongsTo, BelongsTo,
@ -13,18 +14,8 @@ import {
Table, Table,
UpdatedAt UpdatedAt
} from 'sequelize-typescript' } 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 validator from 'validator'
import { AggregateOptions, Op, ScopeOptions, Sequelize, Transaction } from 'sequelize' import { MUserAccountId } from '@server/types/models'
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 { import {
MVideoPlaylistElement, MVideoPlaylistElement,
MVideoPlaylistElementAP, MVideoPlaylistElementAP,
@ -32,7 +23,15 @@ import {
MVideoPlaylistElementVideoUrlPlaylistPrivacy, MVideoPlaylistElementVideoUrlPlaylistPrivacy,
MVideoPlaylistVideoThumbnail MVideoPlaylistVideoThumbnail
} from '@server/types/models/video/video-playlist-element' } 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({ @Table({
tableName: 'videoPlaylistElement', tableName: 'videoPlaylistElement',
@ -49,7 +48,7 @@ import { MUserAccountId } from '@server/types/models'
} }
] ]
}) })
export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel> { export class VideoPlaylistElementModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date
@ -166,7 +165,7 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
]).then(([ total, data ]) => ({ total, data })) ]).then(([ total, data ]) => ({ total, data }))
} }
static loadByPlaylistAndVideo (videoPlaylistId: number, videoId: number): Bluebird<MVideoPlaylistElement> { static loadByPlaylistAndVideo (videoPlaylistId: number, videoId: number): Promise<MVideoPlaylistElement> {
const query = { const query = {
where: { where: {
videoPlaylistId, videoPlaylistId,
@ -177,14 +176,14 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
return VideoPlaylistElementModel.findOne(query) return VideoPlaylistElementModel.findOne(query)
} }
static loadById (playlistElementId: number | string): Bluebird<MVideoPlaylistElement> { static loadById (playlistElementId: number | string): Promise<MVideoPlaylistElement> {
return VideoPlaylistElementModel.findByPk(playlistElementId) return VideoPlaylistElementModel.findByPk(playlistElementId)
} }
static loadByPlaylistAndElementIdForAP ( static loadByPlaylistAndElementIdForAP (
playlistId: number | string, playlistId: number | string,
playlistElementId: number playlistElementId: number
): Bluebird<MVideoPlaylistElementVideoUrlPlaylistPrivacy> { ): Promise<MVideoPlaylistElementVideoUrlPlaylistPrivacy> {
const playlistWhere = validator.isUUID('' + playlistId) ? { uuid: playlistId } : { id: playlistId } const playlistWhere = validator.isUUID('' + playlistId) ? { uuid: playlistId } : { id: playlistId }
const query = { const query = {
@ -226,7 +225,7 @@ export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel>
}) })
} }
static loadFirstElementWithVideoThumbnail (videoPlaylistId: number): Bluebird<MVideoPlaylistVideoThumbnail> { static loadFirstElementWithVideoThumbnail (videoPlaylistId: number): Promise<MVideoPlaylistVideoThumbnail> {
const query = { const query = {
order: getSort('position'), order: getSort('position'),
where: { where: {

View File

@ -1,4 +1,3 @@
import * as Bluebird from 'bluebird'
import { join } from 'path' import { join } from 'path'
import { FindOptions, literal, Op, ScopeOptions, Transaction, WhereOptions } from 'sequelize' import { FindOptions, literal, Op, ScopeOptions, Transaction, WhereOptions } from 'sequelize'
import { import {
@ -125,7 +124,6 @@ type AvailableForListOptions = {
] ]
}, },
[ScopeNames.AVAILABLE_FOR_LIST]: (options: AvailableForListOptions) => { [ScopeNames.AVAILABLE_FOR_LIST]: (options: AvailableForListOptions) => {
let whereActor: WhereOptions = {} let whereActor: WhereOptions = {}
const whereAnd: WhereOptions[] = [] const whereAnd: WhereOptions[] = []
@ -182,15 +180,13 @@ type AvailableForListOptions = {
[Op.and]: whereAnd [Op.and]: whereAnd
} }
const accountScope = {
method: [ AccountScopeNames.SUMMARY, { whereActor } as SummaryOptions ]
}
return { return {
where, where,
include: [ include: [
{ {
model: AccountModel.scope(accountScope), model: AccountModel.scope({
method: [ AccountScopeNames.SUMMARY, { whereActor } as SummaryOptions ]
}),
required: true required: true
}, },
{ {
@ -217,7 +213,7 @@ type AvailableForListOptions = {
} }
] ]
}) })
export class VideoPlaylistModel extends Model<VideoPlaylistModel> { export class VideoPlaylistModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date
@ -367,7 +363,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
}) })
} }
static listPlaylistIdsOf (accountId: number, videoIds: number[]): Bluebird<MVideoPlaylistIdWithElements[]> { static listPlaylistIdsOf (accountId: number, videoIds: number[]): Promise<MVideoPlaylistIdWithElements[]> {
const query = { const query = {
attributes: [ 'id' ], attributes: [ 'id' ],
where: { where: {
@ -392,7 +388,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
static doesPlaylistExist (url: string) { static doesPlaylistExist (url: string) {
const query = { const query = {
attributes: [], attributes: [ 'id' ],
where: { where: {
url url
} }
@ -403,7 +399,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
.then(e => !!e) .then(e => !!e)
} }
static loadWithAccountAndChannelSummary (id: number | string, transaction: Transaction): Bluebird<MVideoPlaylistFullSummary> { static loadWithAccountAndChannelSummary (id: number | string, transaction: Transaction): Promise<MVideoPlaylistFullSummary> {
const where = buildWhereIdOrUUID(id) const where = buildWhereIdOrUUID(id)
const query = { const query = {
@ -416,7 +412,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
.findOne(query) .findOne(query)
} }
static loadWithAccountAndChannel (id: number | string, transaction: Transaction): Bluebird<MVideoPlaylistFull> { static loadWithAccountAndChannel (id: number | string, transaction: Transaction): Promise<MVideoPlaylistFull> {
const where = buildWhereIdOrUUID(id) const where = buildWhereIdOrUUID(id)
const query = { const query = {
@ -429,7 +425,7 @@ export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
.findOne(query) .findOne(query)
} }
static loadByUrlAndPopulateAccount (url: string): Bluebird<MVideoPlaylistAccountThumbnail> { static loadByUrlAndPopulateAccount (url: string): Promise<MVideoPlaylistAccountThumbnail> {
const query = { const query = {
where: { where: {
url url

View File

@ -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 { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
import { CONSTRAINTS_FIELDS } from '../../initializers/constants' import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
import { MActorDefault } from '../../types/models'
import { MVideoShareActor, MVideoShareFull } from '../../types/models/video'
import { ActorModel } from '../activitypub/actor' import { ActorModel } from '../activitypub/actor'
import { buildLocalActorIdsIn, throwIfNotValid } from '../utils' import { buildLocalActorIdsIn, throwIfNotValid } from '../utils'
import { VideoModel } from './video' import { VideoModel } from './video'
import { literal, Op, Transaction } from 'sequelize'
import { MVideoShareActor, MVideoShareFull } from '../../types/models/video'
import { MActorDefault } from '../../types/models'
enum ScopeNames { enum ScopeNames {
FULL = 'FULL', FULL = 'FULL',
@ -51,7 +50,7 @@ enum ScopeNames {
} }
] ]
}) })
export class VideoShareModel extends Model<VideoShareModel> { export class VideoShareModel extends Model {
@AllowNull(false) @AllowNull(false)
@Is('VideoShareUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url')) @Is('VideoShareUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url'))
@ -88,7 +87,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
}) })
Video: VideoModel Video: VideoModel
static load (actorId: number | string, videoId: number | string, t?: Transaction): Bluebird<MVideoShareActor> { static load (actorId: number | string, videoId: number | string, t?: Transaction): Promise<MVideoShareActor> {
return VideoShareModel.scope(ScopeNames.WITH_ACTOR).findOne({ return VideoShareModel.scope(ScopeNames.WITH_ACTOR).findOne({
where: { where: {
actorId, actorId,
@ -98,7 +97,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
}) })
} }
static loadByUrl (url: string, t: Transaction): Bluebird<MVideoShareFull> { static loadByUrl (url: string, t: Transaction): Promise<MVideoShareFull> {
return VideoShareModel.scope(ScopeNames.FULL).findOne({ return VideoShareModel.scope(ScopeNames.FULL).findOne({
where: { where: {
url url
@ -107,7 +106,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
}) })
} }
static loadActorsByShare (videoId: number, t: Transaction): Bluebird<MActorDefault[]> { static loadActorsByShare (videoId: number, t: Transaction): Promise<MActorDefault[]> {
const query = { const query = {
where: { where: {
videoId videoId
@ -125,7 +124,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
.then((res: MVideoShareFull[]) => res.map(r => r.Actor)) .then((res: MVideoShareFull[]) => res.map(r => r.Actor))
} }
static loadActorsWhoSharedVideosOf (actorOwnerId: number, t: Transaction): Bluebird<MActorDefault[]> { static loadActorsWhoSharedVideosOf (actorOwnerId: number, t: Transaction): Promise<MActorDefault[]> {
const safeOwnerId = parseInt(actorOwnerId + '', 10) const safeOwnerId = parseInt(actorOwnerId + '', 10)
// /!\ On actor model // /!\ On actor model
@ -150,7 +149,7 @@ export class VideoShareModel extends Model<VideoShareModel> {
return ActorModel.findAll(query) return ActorModel.findAll(query)
} }
static loadActorsByVideoChannel (videoChannelId: number, t: Transaction): Bluebird<MActorDefault[]> { static loadActorsByVideoChannel (videoChannelId: number, t: Transaction): Promise<MActorDefault[]> {
const safeChannelId = parseInt(videoChannelId + '', 10) const safeChannelId = parseInt(videoChannelId + '', 10)
// /!\ On actor model // /!\ On actor model

View File

@ -40,7 +40,7 @@ import { logger } from '@server/helpers/logger'
} }
] ]
}) })
export class VideoStreamingPlaylistModel extends Model<VideoStreamingPlaylistModel> { export class VideoStreamingPlaylistModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date

View File

@ -13,7 +13,7 @@ import { VideoModel } from './video'
} }
] ]
}) })
export class VideoTagModel extends Model<VideoTagModel> { export class VideoTagModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date

View File

@ -14,7 +14,7 @@ import * as Sequelize from 'sequelize'
} }
] ]
}) })
export class VideoViewModel extends Model<VideoViewModel> { export class VideoViewModel extends Model {
@CreatedAt @CreatedAt
createdAt: Date createdAt: Date

View File

@ -2,7 +2,7 @@ import * as Bluebird from 'bluebird'
import { remove } from 'fs-extra' import { remove } from 'fs-extra'
import { maxBy, minBy, pick } from 'lodash' import { maxBy, minBy, pick } from 'lodash'
import { join } from 'path' 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 { import {
AllowNull, AllowNull,
BeforeDestroy, BeforeDestroy,
@ -190,26 +190,26 @@ export type AvailableForListIDsOptions = {
attributes: [ 'id', 'url', 'uuid', 'remote' ] attributes: [ 'id', 'url', 'uuid', 'remote' ]
}, },
[ScopeNames.FOR_API]: (options: ForAPIOptions) => { [ScopeNames.FOR_API]: (options: ForAPIOptions) => {
const query: FindOptions = { const include: Includeable[] = [
include: [ {
{ model: VideoChannelModel.scope({
model: VideoChannelModel.scope({ method: [
method: [ VideoChannelScopeNames.SUMMARY, {
VideoChannelScopeNames.SUMMARY, { withAccount: true,
withAccount: true, withAccountBlockerIds: options.withAccountBlockerIds
withAccountBlockerIds: options.withAccountBlockerIds } as SummaryOptions
} as SummaryOptions ]
] }),
}), required: true
required: true },
}, {
{ attributes: [ 'type', 'filename' ],
attributes: [ 'type', 'filename' ], model: ThumbnailModel,
model: ThumbnailModel, required: false
required: false }
} ]
]
} const query: FindOptions = {}
if (options.ids) { if (options.ids) {
query.where = { query.where = {
@ -220,14 +220,14 @@ export type AvailableForListIDsOptions = {
} }
if (options.withFiles === true) { if (options.withFiles === true) {
query.include.push({ include.push({
model: VideoFileModel, model: VideoFileModel,
required: true required: true
}) })
} }
if (options.videoPlaylistId) { if (options.videoPlaylistId) {
query.include.push({ include.push({
model: VideoPlaylistElementModel.unscoped(), model: VideoPlaylistElementModel.unscoped(),
required: true, required: true,
where: { where: {
@ -236,6 +236,8 @@ export type AvailableForListIDsOptions = {
}) })
} }
query.include = include
return query return query
}, },
[ScopeNames.WITH_THUMBNAILS]: { [ScopeNames.WITH_THUMBNAILS]: {
@ -477,7 +479,7 @@ export type AvailableForListIDsOptions = {
} }
] ]
}) })
export class VideoModel extends Model<VideoModel> { export class VideoModel extends Model {
@AllowNull(false) @AllowNull(false)
@Default(DataType.UUIDV4) @Default(DataType.UUIDV4)
@ -860,7 +862,7 @@ export class VideoModel extends Model<VideoModel> {
return undefined return undefined
} }
static listLocal (): Bluebird<MVideoWithAllFiles[]> { static listLocal (): Promise<MVideoWithAllFiles[]> {
const query = { const query = {
where: { where: {
remote: false remote: false
@ -988,7 +990,7 @@ export class VideoModel extends Model<VideoModel> {
}) })
} }
static listPublishedLiveIds () { static async listPublishedLiveIds () {
const options = { const options = {
attributes: [ 'id' ], attributes: [ 'id' ],
where: { where: {
@ -997,8 +999,9 @@ export class VideoModel extends Model<VideoModel> {
} }
} }
return VideoModel.findAll(options) const result = await VideoModel.findAll(options)
.map(v => v.id)
return result.map(v => v.id)
} }
static listUserVideosForApi ( static listUserVideosForApi (
@ -1214,7 +1217,7 @@ export class VideoModel extends Model<VideoModel> {
return VideoModel.count(options) return VideoModel.count(options)
} }
static load (id: number | string, t?: Transaction): Bluebird<MVideoThumbnail> { static load (id: number | string, t?: Transaction): Promise<MVideoThumbnail> {
const where = buildWhereIdOrUUID(id) const where = buildWhereIdOrUUID(id)
const options = { const options = {
where, where,
@ -1224,7 +1227,7 @@ export class VideoModel extends Model<VideoModel> {
return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
} }
static loadWithBlacklist (id: number | string, t?: Transaction): Bluebird<MVideoThumbnailBlacklist> { static loadWithBlacklist (id: number | string, t?: Transaction): Promise<MVideoThumbnailBlacklist> {
const where = buildWhereIdOrUUID(id) const where = buildWhereIdOrUUID(id)
const options = { const options = {
where, where,
@ -1237,7 +1240,7 @@ export class VideoModel extends Model<VideoModel> {
]).findOne(options) ]).findOne(options)
} }
static loadImmutableAttributes (id: number | string, t?: Transaction): Bluebird<MVideoImmutable> { static loadImmutableAttributes (id: number | string, t?: Transaction): Promise<MVideoImmutable> {
const fun = () => { const fun = () => {
const query = { const query = {
where: buildWhereIdOrUUID(id), where: buildWhereIdOrUUID(id),
@ -1255,7 +1258,7 @@ export class VideoModel extends Model<VideoModel> {
}) })
} }
static loadWithRights (id: number | string, t?: Transaction): Bluebird<MVideoWithRights> { static loadWithRights (id: number | string, t?: Transaction): Promise<MVideoWithRights> {
const where = buildWhereIdOrUUID(id) const where = buildWhereIdOrUUID(id)
const options = { const options = {
where, where,
@ -1269,7 +1272,7 @@ export class VideoModel extends Model<VideoModel> {
]).findOne(options) ]).findOne(options)
} }
static loadOnlyId (id: number | string, t?: Transaction): Bluebird<MVideoIdThumbnail> { static loadOnlyId (id: number | string, t?: Transaction): Promise<MVideoIdThumbnail> {
const where = buildWhereIdOrUUID(id) const where = buildWhereIdOrUUID(id)
const options = { const options = {
@ -1281,7 +1284,7 @@ export class VideoModel extends Model<VideoModel> {
return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
} }
static loadWithFiles (id: number | string, t?: Transaction, logging?: boolean): Bluebird<MVideoWithAllFiles> { static loadWithFiles (id: number | string, t?: Transaction, logging?: boolean): Promise<MVideoWithAllFiles> {
const where = buildWhereIdOrUUID(id) const where = buildWhereIdOrUUID(id)
const query = { const query = {
@ -1297,7 +1300,7 @@ export class VideoModel extends Model<VideoModel> {
]).findOne(query) ]).findOne(query)
} }
static loadByUUID (uuid: string): Bluebird<MVideoThumbnail> { static loadByUUID (uuid: string): Promise<MVideoThumbnail> {
const options = { const options = {
where: { where: {
uuid uuid
@ -1307,7 +1310,7 @@ export class VideoModel extends Model<VideoModel> {
return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options) return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(options)
} }
static loadByUrl (url: string, transaction?: Transaction): Bluebird<MVideoThumbnail> { static loadByUrl (url: string, transaction?: Transaction): Promise<MVideoThumbnail> {
const query: FindOptions = { const query: FindOptions = {
where: { where: {
url url
@ -1318,7 +1321,7 @@ export class VideoModel extends Model<VideoModel> {
return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(query) return VideoModel.scope(ScopeNames.WITH_THUMBNAILS).findOne(query)
} }
static loadByUrlImmutableAttributes (url: string, transaction?: Transaction): Bluebird<MVideoImmutable> { static loadByUrlImmutableAttributes (url: string, transaction?: Transaction): Promise<MVideoImmutable> {
const fun = () => { const fun = () => {
const query: FindOptions = { const query: FindOptions = {
where: { where: {
@ -1338,7 +1341,7 @@ export class VideoModel extends Model<VideoModel> {
}) })
} }
static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction): Bluebird<MVideoAccountLightBlacklistAllFiles> { static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction): Promise<MVideoAccountLightBlacklistAllFiles> {
const query: FindOptions = { const query: FindOptions = {
where: { where: {
url url
@ -1355,7 +1358,7 @@ export class VideoModel extends Model<VideoModel> {
]).findOne(query) ]).findOne(query)
} }
static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Transaction, userId?: number): Bluebird<MVideoFullLight> { static loadAndPopulateAccountAndServerAndTags (id: number | string, t?: Transaction, userId?: number): Promise<MVideoFullLight> {
const where = buildWhereIdOrUUID(id) const where = buildWhereIdOrUUID(id)
const options = { const options = {
@ -1388,7 +1391,7 @@ export class VideoModel extends Model<VideoModel> {
id: number | string id: number | string
t?: Transaction t?: Transaction
userId?: number userId?: number
}): Bluebird<MVideoDetails> { }): Promise<MVideoDetails> {
const { id, t, userId } = parameters const { id, t, userId } = parameters
const where = buildWhereIdOrUUID(id) const where = buildWhereIdOrUUID(id)
@ -1487,7 +1490,7 @@ export class VideoModel extends Model<VideoModel> {
return VideoModel.update({ support: videoChannel.support }, options) return VideoModel.update({ support: videoChannel.support }, options)
} }
static getAllIdsFromChannel (videoChannel: MChannelId): Bluebird<number[]> { static getAllIdsFromChannel (videoChannel: MChannelId): Promise<number[]> {
const query = { const query = {
attributes: [ 'id' ], attributes: [ 'id' ],
where: { where: {

View File

@ -686,12 +686,7 @@ describe('Test live', function () {
it('Should save a live replay', async function () { it('Should save a live replay', async function () {
this.timeout(60000) this.timeout(60000)
await waitJobs(servers) await waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoReplayId)
const res = await getVideo(servers[0].url, liveVideoReplayId)
const video: VideoDetails = res.body
expect(video.state.id).to.equal(VideoState.PUBLISHED)
}) })
}) })

View File

@ -1,4 +1,3 @@
import * as Bluebird from 'bluebird'
import { Router } from 'express' import { Router } from 'express'
import { Logger } from 'winston' import { Logger } from 'winston'
import { ActorModel } from '@server/models/activitypub/actor' import { ActorModel } from '@server/models/activitypub/actor'
@ -29,7 +28,7 @@ export type PeerTubeHelpers = {
} }
videos: { videos: {
loadByUrl: (url: string) => Bluebird<MVideoThumbnail> loadByUrl: (url: string) => Promise<MVideoThumbnail>
removeVideo: (videoId: number) => Promise<void> removeVideo: (videoId: number) => Promise<void>
} }

View File

@ -1985,14 +1985,6 @@ clone@^1.0.2:
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= 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: cluster-key-slot@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d" 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: dependencies:
binary-extensions "^2.0.0" 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: is-buffer@^1.1.5, is-buffer@~1.1.6:
version "1.1.6" version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" 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-parser "13.1.2"
yargs-unparser "2.0.0" yargs-unparser "2.0.0"
moment-timezone@^0.5.21, moment-timezone@^0.5.31: moment-timezone@^0.5.31:
version "0.5.32" version "0.5.32"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.32.tgz#db7677cc3cc680fd30303ebd90b0da1ca0dfecc2" resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.32.tgz#db7677cc3cc680fd30303ebd90b0da1ca0dfecc2"
integrity sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA== integrity sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA==
dependencies: dependencies:
moment ">= 2.9.0" moment ">= 2.9.0"
"moment@>= 2.9.0", moment@^2.24.0: "moment@>= 2.9.0", moment@^2.26.0:
version "2.29.1" version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
@ -6926,38 +6913,36 @@ send@0.17.1:
range-parser "~1.2.1" range-parser "~1.2.1"
statuses "~1.5.0" statuses "~1.5.0"
sequelize-pool@^2.3.0: sequelize-pool@^6.0.0:
version "2.3.0" version "6.1.0"
resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-2.3.0.tgz#64f1fe8744228172c474f530604b6133be64993d" resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-6.1.0.tgz#caaa0c1e324d3c2c3a399fed2c7998970925d668"
integrity sha512-Ibz08vnXvkZ8LJTiUOxRcj1Ckdn7qafNZ2t59jYHMX1VIebTAOYefWdRYFt6z6+hy52WGthAHAoLc9hvk3onqA== integrity sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg==
sequelize-typescript@^1.0.0-beta.4: sequelize-typescript@^2.0.0-beta.1:
version "1.1.0" version "2.0.0-beta.1"
resolved "https://registry.yarnpkg.com/sequelize-typescript/-/sequelize-typescript-1.1.0.tgz#d5c2945e7fbfe55a934917b27d84589858d79123" resolved "https://registry.yarnpkg.com/sequelize-typescript/-/sequelize-typescript-2.0.0-beta.1.tgz#08c52c35e7fb4f940b9919cbc77752776bcc800a"
integrity sha512-FAPEQPeAhIaFQNLAcf9Q2IWcqWhNcvn5OZZ7BzGB0CJMtImIsGg4E/EAb7huMmPaPwDArxJUWGqk1KurphTNRA== integrity sha512-GHlNfh8vPIJKzXtk4A8MTndK3Uu87HO75fFFX4PM+35P/SW3fFCiw/KeHeQ6DjLz7zeI+fop2HFWVeuZarnJwQ==
dependencies: dependencies:
glob "7.1.2" glob "7.1.2"
sequelize@5.21.13: sequelize@6.3.5:
version "5.21.13" version "6.3.5"
resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-5.21.13.tgz#c8c2f6a2d44d0a234c101155447d494d8d216c7b" resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.3.5.tgz#80e3db7ac8b76d98c45ca93334197eb6e2335158"
integrity sha512-wpwSpxzvADmgPkcOGeer5yFdAVsYeA7NLEw4evSXw03OlGL41J4S8hVz2/nilSWlJSwumlDGC9QbdwAmkWGqJg== integrity sha512-MiwiPkYSA8NWttRKAXdU9h0TxP6HAc1fl7qZmMO/VQqQOND83G4nZLXd0kWILtAoT9cxtZgFqeb/MPYgEeXwsw==
dependencies: dependencies:
bluebird "^3.5.0"
cls-bluebird "^2.1.0"
debug "^4.1.1" debug "^4.1.1"
dottie "^2.0.0" dottie "^2.0.0"
inflection "1.12.0" inflection "1.12.0"
lodash "^4.17.15" lodash "^4.17.15"
moment "^2.24.0" moment "^2.26.0"
moment-timezone "^0.5.21" moment-timezone "^0.5.31"
retry-as-promised "^3.2.0" retry-as-promised "^3.2.0"
semver "^6.3.0" semver "^7.3.2"
sequelize-pool "^2.3.0" sequelize-pool "^6.0.0"
toposort-class "^1.0.1" toposort-class "^1.0.1"
uuid "^3.3.3" uuid "^8.1.0"
validator "^10.11.0" validator "^10.11.0"
wkx "^0.4.8" wkx "^0.5.0"
serialize-javascript@5.0.1: serialize-javascript@5.0.1:
version "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" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 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: signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" 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" assert-never "^1.2.1"
babel-walk "3.0.0-canary-5" babel-walk "3.0.0-canary-5"
wkx@^0.4.8: wkx@^0.5.0:
version "0.4.8" version "0.5.0"
resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.4.8.tgz#a092cf088d112683fdc7182fd31493b2c5820003" resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c"
integrity sha512-ikPXMM9IR/gy/LwiOSqWlSL3X/J5uk9EO2hHNRXS41eTLXaUFEVw9fn/593jW/tE5tedNg8YjT5HkCa4FqQZyQ== integrity sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"