"request": "^2.81.0",
"sanitize-html": "2.x",
"scripty": "^2.0.0",
- "sequelize": "5.21.13",
- "sequelize-typescript": "^1.0.0-beta.4",
+ "sequelize": "6.3.5",
+ "sequelize-typescript": "^2.0.0-beta.1",
"sitemap": "^6.1.0",
"socket.io": "^3.0.2",
"srt-to-vtt": "^1.1.2",
-import * as Bluebird from 'bluebird'
import * as express from 'express'
import { move, readFile } from 'fs-extra'
import * as magnetUtil from 'magnet-uri'
} from '@server/types/models'
import { MVideoImport, MVideoImportFormattable } from '@server/types/models/video/video-import'
import { VideoImportCreate, VideoImportState, VideoPrivacy, VideoState } from '../../../../shared'
+import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type'
import { auditLoggerFactory, getAuditIdFromRes, VideoImportAuditView } from '../../../helpers/audit-logger'
import { moveAndProcessCaptionFile } from '../../../helpers/captions-utils'
import { VideoModel } from '../../../models/video/video'
import { VideoCaptionModel } from '../../../models/video/video-caption'
import { VideoImportModel } from '../../../models/video/video-import'
-import { HttpStatusCode } from '../../../../shared/core-utils/miscs/http-error-codes'
const auditLogger = auditLoggerFactory('video-imports')
const videoImportsRouter = express.Router()
tags: string[]
videoImportAttributes: Partial<MVideoImport>
user: MUser
-}): Bluebird<MVideoImportFormattable> {
+}): Promise<MVideoImportFormattable> {
const { video, thumbnailModel, previewModel, videoChannel, tags, videoImportAttributes, user } = parameters
return sequelizeTypescript.transaction(async t => {
+
import { ActorModel } from '../models/activitypub/actor'
-import * as Bluebird from 'bluebird'
-import { MActorFull, MActorAccountChannelId } from '../types/models'
+import { MActorAccountChannelId, MActorFull } from '../types/models'
type ActorFetchByUrlType = 'all' | 'association-ids'
-function fetchActorByUrl (url: string, fetchType: ActorFetchByUrlType): Bluebird<MActorFull | MActorAccountChannelId> {
+function fetchActorByUrl (url: string, fetchType: ActorFetchByUrlType): Promise<MActorFull | MActorAccountChannelId> {
if (fetchType === 'all') return ActorModel.loadByUrlAndPopulateAccountAndChannel(url)
if (fetchType === 'association-ids') return ActorModel.loadByUrl(url)
import { Response } from 'express'
-import { AccountModel } from '../../models/account/account'
-import * as Bluebird from 'bluebird'
-import { MAccountDefault } from '../../types/models'
import { UserModel } from '@server/models/account/user'
import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
+import { AccountModel } from '../../models/account/account'
+import { MAccountDefault } from '../../types/models'
function doesAccountIdExist (id: number | string, res: Response, sendNotFound = true) {
const promise = AccountModel.load(parseInt(id + '', 10))
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
if (!account) {
-import * as Bluebird from 'bluebird'
import { Response } from 'express'
import { CONFIG } from '@server/initializers/config'
import { DEFAULT_AUDIO_RESOLUTION } from '@server/initializers/constants'
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: 'only-immutable-attributes'): Bluebird<MVideoImmutable>
-function fetchVideo (id: number | string, fetchType: 'only-video', userId?: number): Bluebird<MVideoThumbnail>
-function fetchVideo (id: number | string, fetchType: 'only-video-with-rights', userId?: number): Bluebird<MVideoWithRights>
-function fetchVideo (id: number | string, fetchType: 'id' | 'none', userId?: number): Bluebird<MVideoIdThumbnail>
+function fetchVideo (id: number | string, fetchType: 'all', userId?: number): Promise<MVideoFullLight>
+function fetchVideo (id: number | string, fetchType: 'only-immutable-attributes'): Promise<MVideoImmutable>
+function fetchVideo (id: number | string, fetchType: 'only-video', userId?: number): Promise<MVideoThumbnail>
+function fetchVideo (id: number | string, fetchType: 'only-video-with-rights', userId?: number): Promise<MVideoWithRights>
+function fetchVideo (id: number | string, fetchType: 'id' | 'none', userId?: number): Promise<MVideoIdThumbnail>
function fetchVideo (
id: number | string,
fetchType: VideoFetchType,
userId?: number
-): Bluebird<MVideoFullLight | MVideoThumbnail | MVideoWithRights | MVideoIdThumbnail | MVideoImmutable>
+): Promise<MVideoFullLight | MVideoThumbnail | MVideoWithRights | MVideoIdThumbnail | MVideoImmutable>
function fetchVideo (
id: number | string,
fetchType: VideoFetchType,
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 === 'only-immutable-attributes') return VideoModel.loadImmutableAttributes(id)
type VideoFetchByUrlType = 'all' | 'only-video' | 'only-immutable-attributes'
-function fetchVideoByUrl (url: string, fetchType: 'all'): Bluebird<MVideoAccountLightBlacklistAllFiles>
-function fetchVideoByUrl (url: string, fetchType: 'only-immutable-attributes'): Bluebird<MVideoImmutable>
-function fetchVideoByUrl (url: string, fetchType: 'only-video'): Bluebird<MVideoThumbnail>
+function fetchVideoByUrl (url: string, fetchType: 'all'): Promise<MVideoAccountLightBlacklistAllFiles>
+function fetchVideoByUrl (url: string, fetchType: 'only-immutable-attributes'): Promise<MVideoImmutable>
+function fetchVideoByUrl (url: string, fetchType: 'only-video'): Promise<MVideoThumbnail>
function fetchVideoByUrl (
url: string,
fetchType: VideoFetchByUrlType
-): Bluebird<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable>
+): Promise<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable>
function fetchVideoByUrl (
url: string,
fetchType: VideoFetchByUrlType
-): Bluebird<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable> {
+): Promise<MVideoAccountLightBlacklistAllFiles | MVideoThumbnail | MVideoImmutable> {
if (fetchType === 'all') return VideoModel.loadByUrlAndPopulateAccount(url)
if (fetchType === 'only-immutable-attributes') return VideoModel.loadByUrlImmutableAttributes(url)
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
import { stat } from 'fs-extra'
import { VideoModel } from '../../models/video/video'
import { getVideoFilePath } from '@server/lib/video-paths'
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
import { Migration } from '../../models/migrations'
function up (utils: {
import * as Sequelize from 'sequelize'
-import * as Promise from 'bluebird'
function up (utils: {
transaction: Sequelize.Transaction
}): Promise<void> {
await utils.queryInterface.removeConstraint('actor', 'actor_avatarId_fkey')
- await utils.queryInterface.addConstraint('actor', [ 'avatarId' ], {
+ await utils.queryInterface.addConstraint('actor', {
+ fields: [ 'avatarId' ],
type: 'foreign key',
references: {
table: 'avatar',
await utils.queryInterface.removeConstraint('videoPlaylistElement', 'videoPlaylistElement_videoId_fkey')
- await utils.queryInterface.addConstraint('videoPlaylistElement', [ 'videoId' ], {
+ await utils.queryInterface.addConstraint('videoPlaylistElement', {
+ fields: [ 'videoId' ],
type: 'foreign key',
references: {
table: 'video',
return Promise.resolve()
})
+ logger.info('toto', { playlist, id: playlist.id })
+
const refreshedPlaylist = await VideoPlaylistModel.loadWithAccountAndChannel(playlist.id, null)
if (playlistObject.icon) {
const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: dislikeObject })
return sequelizeTypescript.transaction(async t => {
- const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, activity.id)
+ const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, activity.id, t)
if (existingRate && existingRate.type === 'dislike') return
await video.increment('dislikes', { transaction: t })
const { video } = await getOrCreateVideoAndAccountAndChannel({ videoObject: videoUrl })
return sequelizeTypescript.transaction(async t => {
- const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, activity.id)
+ const existingRate = await AccountVideoRateModel.loadByAccountAndVideoOrUrl(byAccount.id, video.id, activity.id, t)
if (existingRate && existingRate.type === 'like') return
if (existingRate && existingRate.type === 'dislike') {
import { MAccountActor, MActorUrl, MVideo, MVideoAccountLight, MVideoId } from '../../types/models'
async function createRates (ratesUrl: string[], video: MVideo, rate: VideoRateType) {
- let rateCounts = 0
-
await Bluebird.map(ratesUrl, async rateUrl => {
try {
// Fetch url
url: body.id
}
- const created = await AccountVideoRateModel.upsert(entry)
-
- if (created) rateCounts += 1
+ // Video "likes"/"dislikes" will be updated by the caller
+ await AccountVideoRateModel.upsert(entry)
} catch (err) {
logger.warn('Cannot add rate %s.', rateUrl, { err })
}
}, { concurrency: CRAWL_REQUEST_CONCURRENCY })
-
- logger.info('Adding %d %s to video %s.', rateCounts, rate, video.uuid)
-
- // This is "likes" and "dislikes"
- if (rateCounts !== 0) {
- const field = rate === 'like' ? 'likes' : 'dislikes'
- await video.increment(field, { by: rateCounts })
- }
}
async function sendVideoRateChange (
video.views = videoData.views
video.isLive = videoData.isLive
+ // Ensures we update the updated video attribute
+ video.changed('updatedAt', true)
+
const videoUpdated = await video.save(sequelizeOptions) as MVideoFullLight
if (thumbnailModel) await videoUpdated.addAndSaveThumbnail(thumbnailModel, t)
import * as express from 'express'
-import * as Bluebird from 'bluebird'
+import { readFile } from 'fs-extra'
+import { join } from 'path'
+import validator from 'validator'
import { buildFileLocale, getDefaultLocale, is18nLocale, POSSIBLE_LOCALES } from '../../shared/core-utils/i18n/i18n'
+import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes'
+import { VideoPlaylistPrivacy, VideoPrivacy } from '../../shared/models/videos'
+import { escapeHTML, isTestInstance, sha256 } from '../helpers/core-utils'
+import { logger } from '../helpers/logger'
+import { CONFIG } from '../initializers/config'
import {
+ ACCEPT_HEADERS,
AVATARS_SIZE,
CUSTOM_HTML_TAG_COMMENTS,
EMBED_SIZE,
- PLUGIN_GLOBAL_CSS_PATH,
- WEBSERVER,
FILES_CONTENT_HASH,
- ACCEPT_HEADERS
+ PLUGIN_GLOBAL_CSS_PATH,
+ WEBSERVER
} from '../initializers/constants'
-import { join } from 'path'
-import { escapeHTML, isTestInstance, sha256 } from '../helpers/core-utils'
-import { VideoModel } from '../models/video/video'
-import { VideoPlaylistModel } from '../models/video/video-playlist'
-import validator from 'validator'
-import { VideoPrivacy, VideoPlaylistPrivacy } from '../../shared/models/videos'
-import { readFile } from 'fs-extra'
-import { getActivityStreamDuration } from '../models/video/video-format-utils'
import { AccountModel } from '../models/account/account'
+import { VideoModel } from '../models/video/video'
import { VideoChannelModel } from '../models/video/video-channel'
-import { CONFIG } from '../initializers/config'
-import { logger } from '../helpers/logger'
+import { getActivityStreamDuration } from '../models/video/video-format-utils'
+import { VideoPlaylistModel } from '../models/video/video-playlist'
import { MAccountActor, MChannelActor } from '../types/models'
-import { HttpStatusCode } from '../../shared/core-utils/miscs/http-error-codes'
type Tags = {
ogType: string
}
private static async getAccountOrChannelHTMLPage (
- loader: () => Bluebird<MAccountActor | MChannelActor>,
+ loader: () => Promise<MAccountActor | MChannelActor>,
req: express.Request,
res: express.Response
) {
import * as Bull from 'bull'
-import * as Bluebird from 'bluebird'
+import { ActivitypubHttpFetcherPayload, FetchType } from '@shared/models'
import { logger } from '../../../helpers/logger'
-import { processActivities } from '../../activitypub/process'
-import { addVideoComments } from '../../activitypub/video-comments'
-import { crawlCollectionPage } from '../../activitypub/crawl'
-import { VideoModel } from '../../../models/video/video'
-import { addVideoShares } from '../../activitypub/share'
-import { createRates } from '../../activitypub/video-rates'
-import { createAccountPlaylists } from '../../activitypub/playlist'
import { AccountModel } from '../../../models/account/account'
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
-import { VideoShareModel } from '../../../models/video/video-share'
+import { VideoModel } from '../../../models/video/video'
import { VideoCommentModel } from '../../../models/video/video-comment'
+import { VideoShareModel } from '../../../models/video/video-share'
import { MAccountDefault, MVideoFullLight } from '../../../types/models'
-import { ActivitypubHttpFetcherPayload, FetchType } from '@shared/models'
+import { crawlCollectionPage } from '../../activitypub/crawl'
+import { createAccountPlaylists } from '../../activitypub/playlist'
+import { processActivities } from '../../activitypub/process'
+import { addVideoShares } from '../../activitypub/share'
+import { addVideoComments } from '../../activitypub/video-comments'
+import { createRates } from '../../activitypub/video-rates'
async function processActivityPubHttpFetcher (job: Bull.Job) {
logger.info('Processing ActivityPub fetcher in job %d.', job.id)
'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-dislikes': crawlStartDate => AccountVideoRateModel.cleanOldRatesOf(video.id, 'dislike' as 'dislike', crawlStartDate),
'video-shares': crawlStartDate => VideoShareModel.cleanOldSharesOf(video.id, crawlStartDate),
input: string
resolution: VideoResolution
fps: number
-
}) {
const { input, resolution, fps } = options
const probe = await ffprobePromise(input)
-import * as Bluebird from 'bluebird'
import * as express from 'express'
import { body, param, query } from 'express-validator'
import { omit } from 'lodash'
+import { Hooks } from '@server/lib/plugins/hooks'
+import { MUserDefault } from '@server/types/models'
+import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
+import { UserRole } from '../../../shared/models/users'
+import { UserRegister } from '../../../shared/models/users/user-register.model'
+import { isActorPreferredUsernameValid } from '../../helpers/custom-validators/activitypub/actor'
import { isIdOrUUIDValid, toBooleanOrNull, toIntOrNull } from '../../helpers/custom-validators/misc'
+import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
import {
isNoInstanceConfigWarningModal,
isNoWelcomeModal,
isUserVideoQuotaValid,
isUserVideosHistoryEnabledValid
} from '../../helpers/custom-validators/users'
+import { isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels'
import { logger } from '../../helpers/logger'
+import { doesVideoExist } from '../../helpers/middlewares'
import { isSignupAllowed, isSignupAllowedForCurrentIP } from '../../helpers/signup'
+import { isThemeRegistered } from '../../lib/plugins/theme-utils'
import { Redis } from '../../lib/redis'
import { UserModel } from '../../models/account/user'
-import { areValidationErrors } from './utils'
import { ActorModel } from '../../models/activitypub/actor'
-import { isActorPreferredUsernameValid } from '../../helpers/custom-validators/activitypub/actor'
-import { isVideoChannelNameValid } from '../../helpers/custom-validators/video-channels'
-import { UserRegister } from '../../../shared/models/users/user-register.model'
-import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
-import { isThemeRegistered } from '../../lib/plugins/theme-utils'
-import { doesVideoExist } from '../../helpers/middlewares'
-import { UserRole } from '../../../shared/models/users'
-import { MUserDefault } from '@server/types/models'
-import { Hooks } from '@server/lib/plugins/hooks'
-import { HttpStatusCode } from '../../../shared/core-utils/miscs/http-error-codes'
+import { areValidationErrors } from './utils'
const usersListValidator = [
query('blocked')
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()
if (!user) {
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
import { isAbuseMessageValid } from '@server/helpers/custom-validators/abuses'
+import { MAbuseMessage, MAbuseMessageFormattable } from '@server/types/models'
import { AbuseMessage } from '@shared/models'
import { AccountModel, ScopeNames as AccountScopeNames } from '../account/account'
-import { throwIfNotValid, getSort } from '../utils'
+import { getSort, throwIfNotValid } from '../utils'
import { AbuseModel } from './abuse'
-import { MAbuseMessageFormattable, MAbuseMessage } from '@server/types/models'
@Table({
tableName: 'abuseMessage',
}
]
})
-export class AbuseMessageModel extends Model<AbuseMessageModel> {
+export class AbuseMessageModel extends Model {
@AllowNull(false)
@Is('AbuseMessage', value => throwIfNotValid(value, isAbuseMessageValid, 'message'))
-import * as Bluebird from 'bluebird'
import { invert } from 'lodash'
import { literal, Op, QueryTypes } from 'sequelize'
import {
}
]
})
-export class AbuseModel extends Model<AbuseModel> {
+export class AbuseModel extends Model {
@AllowNull(false)
@Default(null)
})
VideoAbuse: VideoAbuseModel
- static loadByIdWithReporter (id: number): Bluebird<MAbuseReporter> {
+ static loadByIdWithReporter (id: number): Promise<MAbuseReporter> {
const query = {
where: {
id
return AbuseModel.findOne(query)
}
- static loadFull (id: number): Bluebird<MAbuseFull> {
+ static loadFull (id: number): Promise<MAbuseFull> {
const query = {
where: {
id
}
]
})
-export class VideoAbuseModel extends Model<VideoAbuseModel> {
+export class VideoAbuseModel extends Model {
@CreatedAt
createdAt: Date
}
]
})
-export class VideoCommentAbuseModel extends Model<VideoCommentAbuseModel> {
+export class VideoCommentAbuseModel extends Model {
@CreatedAt
createdAt: Date
-import * as Bluebird from 'bluebird'
import { Op } from 'sequelize'
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
import { MAccountBlocklist, MAccountBlocklistAccounts, MAccountBlocklistFormattable } from '@server/types/models'
}
]
})
-export class AccountBlocklistModel extends Model<AccountBlocklistModel> {
+export class AccountBlocklistModel extends Model {
@CreatedAt
createdAt: Date
})
}
- static loadByAccountAndTarget (accountId: number, targetAccountId: number): Bluebird<MAccountBlocklist> {
+ static loadByAccountAndTarget (accountId: number, targetAccountId: number): Promise<MAccountBlocklist> {
const query = {
where: {
accountId,
})
}
- static listHandlesBlockedBy (accountIds: number[]): Bluebird<string[]> {
+ static listHandlesBlockedBy (accountIds: number[]): Promise<string[]> {
const query = {
- attributes: [],
+ attributes: [ 'id' ],
where: {
accountId: {
[Op.in]: accountIds
import { values } from 'lodash'
-import { FindOptions, Op, Transaction } from 'sequelize'
+import { FindOptions, Op, QueryTypes, Transaction } from 'sequelize'
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
-import { VideoRateType } from '../../../shared/models/videos'
-import { CONSTRAINTS_FIELDS, VIDEO_RATE_TYPES } from '../../initializers/constants'
-import { VideoModel } from '../video/video'
-import { AccountModel } from './account'
-import { ActorModel } from '../activitypub/actor'
-import { buildLocalAccountIdsIn, getSort, throwIfNotValid } from '../utils'
-import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
-import { AccountVideoRate } from '../../../shared'
-import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from '../video/video-channel'
-import * as Bluebird from 'bluebird'
import {
MAccountVideoRate,
MAccountVideoRateAccountUrl,
MAccountVideoRateAccountVideo,
MAccountVideoRateFormattable
} from '@server/types/models/video/video-rate'
+import { AccountVideoRate } from '../../../shared'
+import { VideoRateType } from '../../../shared/models/videos'
+import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
+import { CONSTRAINTS_FIELDS, VIDEO_RATE_TYPES } from '../../initializers/constants'
+import { ActorModel } from '../activitypub/actor'
+import { buildLocalAccountIdsIn, getSort, throwIfNotValid } from '../utils'
+import { VideoModel } from '../video/video'
+import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from '../video/video-channel'
+import { AccountModel } from './account'
/*
Account rates per video.
}
]
})
-export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
+export class AccountVideoRateModel extends Model {
@AllowNull(false)
@Column(DataType.ENUM(...values(VIDEO_RATE_TYPES)))
})
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 = {
where: {
accountId,
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 = {
where: {
[Op.or]: [
accountName: string,
videoId: number | string,
t?: Transaction
- ): Bluebird<MAccountVideoRateAccountVideo> {
+ ): Promise<MAccountVideoRateAccountVideo> {
const options: FindOptions = {
where: {
videoId,
transaction: t
}
- const deleted = await AccountVideoRateModel.destroy(query)
+ await AccountVideoRateModel.destroy(query)
- const options = {
- transaction: t,
- where: {
- id: videoId
- }
- }
+ 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'
- if (type === 'like') await VideoModel.increment({ likes: -deleted }, options)
- else if (type === 'dislike') await VideoModel.increment({ dislikes: -deleted }, options)
+ return AccountVideoRateModel.sequelize.query(rawQuery, {
+ transaction: t,
+ replacements: { videoId, rateType: type },
+ type: QueryTypes.UPDATE
+ })
})
}
-import * as Bluebird from 'bluebird'
-import { FindOptions, IncludeOptions, Op, Transaction, WhereOptions } from 'sequelize'
+import { FindOptions, Includeable, IncludeOptions, Op, Transaction, WhereOptions } from 'sequelize'
import {
AllowNull,
BeforeDestroy,
required: false
}
- const query: FindOptions = {
- attributes: [ 'id', 'name', 'actorId' ],
- include: [
- {
- attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ],
- model: ActorModel.unscoped(),
- required: options.actorRequired ?? true,
- where: whereActor,
- include: [
- serverInclude,
+ const queryInclude: Includeable[] = [
+ {
+ attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ],
+ model: ActorModel.unscoped(),
+ required: options.actorRequired ?? true,
+ where: whereActor,
+ include: [
+ serverInclude,
- {
- model: AvatarModel.unscoped(),
- required: false
- }
- ]
- }
- ]
+ {
+ model: AvatarModel.unscoped(),
+ required: false
+ }
+ ]
+ }
+ ]
+
+ const query: FindOptions = {
+ attributes: [ 'id', 'name', 'actorId' ]
}
if (options.withAccountBlockerIds) {
- query.include.push({
+ queryInclude.push({
attributes: [ 'id' ],
model: AccountBlocklistModel.unscoped(),
as: 'BlockedAccounts',
]
}
+ query.include = queryInclude
+
return query
}
}))
}
]
})
-export class AccountModel extends Model<AccountModel> {
+export class AccountModel extends Model {
@AllowNull(false)
@Column
return undefined
}
- static load (id: number, transaction?: Transaction): Bluebird<MAccountDefault> {
+ static load (id: number, transaction?: Transaction): Promise<MAccountDefault> {
return AccountModel.findByPk(id, { transaction })
}
- static loadByNameWithHost (nameWithHost: string): Bluebird<MAccountDefault> {
+ static loadByNameWithHost (nameWithHost: string): Promise<MAccountDefault> {
const [ accountName, host ] = nameWithHost.split('@')
if (!host || host === WEBSERVER.HOST) return AccountModel.loadLocalByName(accountName)
return AccountModel.loadByNameAndHost(accountName, host)
}
- static loadLocalByName (name: string): Bluebird<MAccountDefault> {
+ static loadLocalByName (name: string): Promise<MAccountDefault> {
const fun = () => {
const query = {
where: {
})
}
- static loadByNameAndHost (name: string, host: string): Bluebird<MAccountDefault> {
+ static loadByNameAndHost (name: string, host: string): Promise<MAccountDefault> {
const query = {
include: [
{
return AccountModel.findOne(query)
}
- static loadByUrl (url: string, transaction?: Transaction): Bluebird<MAccountDefault> {
+ static loadByUrl (url: string, transaction?: Transaction): Promise<MAccountDefault> {
const query = {
include: [
{
})
}
- static loadAccountIdFromVideo (videoId: number): Bluebird<MAccount> {
+ static loadAccountIdFromVideo (videoId: number): Promise<MAccount> {
const query = {
include: [
{
return AccountModel.findOne(query)
}
- static listLocalsForSitemap (sort: string): Bluebird<MAccountActor[]> {
+ static listLocalsForSitemap (sort: string): Promise<MAccountActor[]> {
const query = {
attributes: [ ],
offset: 0,
}
]
})
-export class UserNotificationSettingModel extends Model<UserNotificationSettingModel> {
+export class UserNotificationSettingModel extends Model {
@AllowNull(false)
@Default(null)
}
] as (ModelIndexesOptions & { where?: WhereOptions })[]
})
-export class UserNotificationModel extends Model<UserNotificationModel> {
+export class UserNotificationModel extends Model {
@AllowNull(false)
@Default(null)
}
]
})
-export class UserVideoHistoryModel extends Model<UserVideoHistoryModel> {
+export class UserVideoHistoryModel extends Model {
@CreatedAt
createdAt: Date
-import * as Bluebird from 'bluebird'
import { values } from 'lodash'
import { col, FindOptions, fn, literal, Op, QueryTypes, where, WhereOptions } from 'sequelize'
import {
HasOne,
Is,
IsEmail,
+ IsUUID,
Model,
Scopes,
Table,
- UpdatedAt,
- IsUUID
+ UpdatedAt
} from 'sequelize-typescript'
import {
MMyUserFormattable,
}
]
})
-export class UserModel extends Model<UserModel> {
+export class UserModel extends Model {
@AllowNull(true)
@Is('UserPassword', value => throwIfNotValid(value, isUserPasswordValid, 'user password', true))
})
}
- static listWithRight (right: UserRight): Bluebird<MUserDefault[]> {
+ static listWithRight (right: UserRight): Promise<MUserDefault[]> {
const roles = Object.keys(USER_ROLE_LABELS)
.map(k => parseInt(k, 10) as UserRole)
.filter(role => hasUserRight(role, right))
return UserModel.findAll(query)
}
- static listUserSubscribersOf (actorId: number): Bluebird<MUserWithNotificationSetting[]> {
+ static listUserSubscribersOf (actorId: number): Promise<MUserWithNotificationSetting[]> {
const query = {
include: [
{
return UserModel.unscoped().findAll(query)
}
- static listByUsernames (usernames: string[]): Bluebird<MUserDefault[]> {
+ static listByUsernames (usernames: string[]): Promise<MUserDefault[]> {
const query = {
where: {
username: usernames
return UserModel.findAll(query)
}
- static loadById (id: number): Bluebird<MUser> {
+ static loadById (id: number): Promise<MUser> {
return UserModel.unscoped().findByPk(id)
}
- static loadByIdWithChannels (id: number, withStats = false): Bluebird<MUserDefault> {
+ static loadByIdWithChannels (id: number, withStats = false): Promise<MUserDefault> {
const scopes = [
ScopeNames.WITH_VIDEOCHANNELS
]
return UserModel.scope(scopes).findByPk(id)
}
- static loadByUsername (username: string): Bluebird<MUserDefault> {
+ static loadByUsername (username: string): Promise<MUserDefault> {
const query = {
where: {
username: { [Op.iLike]: username }
return UserModel.findOne(query)
}
- static loadForMeAPI (username: string): Bluebird<MUserNotifSettingChannelDefault> {
+ static loadForMeAPI (username: string): Promise<MUserNotifSettingChannelDefault> {
const query = {
where: {
username: { [Op.iLike]: username }
return UserModel.scope(ScopeNames.FOR_ME_API).findOne(query)
}
- static loadByEmail (email: string): Bluebird<MUserDefault> {
+ static loadByEmail (email: string): Promise<MUserDefault> {
const query = {
where: {
email
return UserModel.findOne(query)
}
- static loadByUsernameOrEmail (username: string, email?: string): Bluebird<MUserDefault> {
+ static loadByUsernameOrEmail (username: string, email?: string): Promise<MUserDefault> {
if (!email) email = username
const query = {
return UserModel.findOne(query)
}
- static loadByVideoId (videoId: number): Bluebird<MUserDefault> {
+ static loadByVideoId (videoId: number): Promise<MUserDefault> {
const query = {
include: [
{
return UserModel.findOne(query)
}
- static loadByVideoImportId (videoImportId: number): Bluebird<MUserDefault> {
+ static loadByVideoImportId (videoImportId: number): Promise<MUserDefault> {
const query = {
include: [
{
return UserModel.findOne(query)
}
- static loadByChannelActorId (videoChannelActorId: number): Bluebird<MUserDefault> {
+ static loadByChannelActorId (videoChannelActorId: number): Promise<MUserDefault> {
const query = {
include: [
{
return UserModel.findOne(query)
}
- static loadByAccountActorId (accountActorId: number): Bluebird<MUserDefault> {
+ static loadByAccountActorId (accountActorId: number): Promise<MUserDefault> {
const query = {
include: [
{
return UserModel.findOne(query)
}
- static loadByLiveId (liveId: number): Bluebird<MUser> {
+ static loadByLiveId (liveId: number): Promise<MUser> {
const query = {
include: [
{
-import * as Bluebird from 'bluebird'
import { difference, values } from 'lodash'
import { IncludeOptions, Op, QueryTypes, Transaction, WhereOptions } from 'sequelize'
import {
}
]
})
-export class ActorFollowModel extends Model<ActorFollowModel> {
+export class ActorFollowModel extends Model {
@AllowNull(false)
@Column(DataType.ENUM(...values(FOLLOW_STATES)))
.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 = {
where: {
actorId,
targetName: string,
targetHost: string,
t?: Transaction
- ): Bluebird<MActorFollowActorsDefaultSubscription> {
+ ): Promise<MActorFollowActorsDefaultSubscription> {
const actorFollowingPartInclude: IncludeOptions = {
model: ActorModel,
required: true,
})
}
- 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
.map(t => {
if (t.host) {
})
const query = {
- attributes: [],
+ attributes: [ 'id' ],
where: {
[Op.and]: [
{
selections.push('COUNT(*) AS "total"')
- const tasks: Bluebird<any>[] = []
+ const tasks: Promise<any>[] = []
for (const selection of selections) {
let query = 'SELECT ' + selection + ' FROM "actor" ' +
import { values } from 'lodash'
import { extname } from 'path'
+import { literal, Op, Transaction } from 'sequelize'
import {
AllowNull,
BelongsTo,
Table,
UpdatedAt
} from 'sequelize-typescript'
+import { ModelCache } from '@server/models/model-cache'
import { ActivityIconObject, ActivityPubActorType } from '../../../shared/models/activitypub'
import { Avatar } from '../../../shared/models/avatars/avatar.model'
import { activityPubContextify } from '../../helpers/activitypub'
} from '../../helpers/custom-validators/activitypub/actor'
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
import { ACTIVITY_PUB, ACTIVITY_PUB_ACTOR_TYPES, CONSTRAINTS_FIELDS, SERVER_ACTOR_NAME, WEBSERVER } from '../../initializers/constants'
-import { AccountModel } from '../account/account'
-import { AvatarModel } from '../avatar/avatar'
-import { ServerModel } from '../server/server'
-import { isOutdated, throwIfNotValid } from '../utils'
-import { VideoChannelModel } from '../video/video-channel'
-import { ActorFollowModel } from './actor-follow'
-import { VideoModel } from '../video/video'
import {
MActor,
MActorAccountChannelId,
MActorFull,
MActorHost,
MActorServer,
- MActorSummaryFormattable, MActorUrl,
+ MActorSummaryFormattable,
+ MActorUrl,
MActorWithInboxes
} from '../../types/models'
-import * as Bluebird from 'bluebird'
-import { Op, Transaction, literal } from 'sequelize'
-import { ModelCache } from '@server/models/model-cache'
+import { AccountModel } from '../account/account'
+import { AvatarModel } from '../avatar/avatar'
+import { ServerModel } from '../server/server'
+import { isOutdated, throwIfNotValid } from '../utils'
+import { VideoModel } from '../video/video'
+import { VideoChannelModel } from '../video/video-channel'
+import { ActorFollowModel } from './actor-follow'
enum ScopeNames {
FULL = 'FULL'
}
]
})
-export class ActorModel extends Model<ActorModel> {
+export class ActorModel extends Model {
@AllowNull(false)
@Column(DataType.ENUM(...values(ACTIVITY_PUB_ACTOR_TYPES)))
})
VideoChannel: VideoChannelModel
- static load (id: number): Bluebird<MActor> {
+ static load (id: number): Promise<MActor> {
return ActorModel.unscoped().findByPk(id)
}
- static loadFull (id: number): Bluebird<MActorFull> {
+ static loadFull (id: number): Promise<MActorFull> {
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 = {
include: [
{
.then(a => !!a)
}
- static listByFollowersUrls (followersUrls: string[], transaction?: Transaction): Bluebird<MActorFull[]> {
+ static listByFollowersUrls (followersUrls: string[], transaction?: Transaction): Promise<MActorFull[]> {
const query = {
where: {
followersUrl: {
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 query = {
where: {
})
}
- static loadLocalUrlByName (preferredUsername: string, transaction?: Transaction): Bluebird<MActorUrl> {
+ static loadLocalUrlByName (preferredUsername: string, transaction?: Transaction): Promise<MActorUrl> {
const fun = () => {
const query = {
attributes: [ 'url' ],
})
}
- static loadByNameAndHost (preferredUsername: string, host: string): Bluebird<MActorFull> {
+ static loadByNameAndHost (preferredUsername: string, host: string): Promise<MActorFull> {
const query = {
where: {
preferredUsername
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 = {
where: {
url
return ActorModel.unscoped().findOne(query)
}
- static loadByUrlAndPopulateAccountAndChannel (url: string, transaction?: Transaction): Bluebird<MActorFull> {
+ static loadByUrlAndPopulateAccountAndChannel (url: string, transaction?: Transaction): Promise<MActorFull> {
const query = {
where: {
url
}, { where, transaction })
}
- static loadAccountActorByVideoId (videoId: number): Bluebird<MActor> {
+ static loadAccountActorByVideoId (videoId: number): Promise<MActor> {
const query = {
include: [
{
tableName: 'application',
timestamps: false
})
-export class ApplicationModel extends Model<ApplicationModel> {
+export class ApplicationModel extends Model {
@AllowNull(false)
@Default(0)
}
]
})
-export class AvatarModel extends Model<AvatarModel> {
+export class AvatarModel extends Model {
@AllowNull(false)
@Column
doCache<T extends Model> (options: {
cacheType: ModelCacheType
key: string
- fun: () => Bluebird<T>
+ fun: () => Promise<T>
whitelist?: () => boolean
deleteKey?: DeleteKey
}) {
}
]
})
-export class OAuthClientModel extends Model<OAuthClientModel> {
+export class OAuthClientModel extends Model {
@AllowNull(false)
@Column
+import { Transaction } from 'sequelize'
import {
AfterDestroy,
AfterUpdate,
Table,
UpdatedAt
} from 'sequelize-typescript'
+import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token'
import { logger } from '../../helpers/logger'
-import { UserModel } from '../account/user'
-import { OAuthClientModel } from './oauth-client'
-import { Transaction } from 'sequelize'
+import { clearCacheByToken } from '../../lib/oauth-model'
import { AccountModel } from '../account/account'
+import { UserModel } from '../account/user'
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 { OAuthClientModel } from './oauth-client'
export type OAuthTokenInfo = {
refreshToken: string
}
]
})
-export class OAuthTokenModel extends Model<OAuthTokenModel> {
+export class OAuthTokenModel extends Model {
@AllowNull(false)
@Column
})
}
- static getByTokenAndPopulateUser (bearerToken: string): Bluebird<MOAuthTokenUser> {
+ static getByTokenAndPopulateUser (bearerToken: string): Promise<MOAuthTokenUser> {
const query = {
where: {
accessToken: bearerToken
})
}
- static getByRefreshTokenAndPopulateUser (refreshToken: string): Bluebird<MOAuthTokenUser> {
+ static getByRefreshTokenAndPopulateUser (refreshToken: string): Promise<MOAuthTokenUser> {
const query = {
where: {
refreshToken
+import { sample } from 'lodash'
+import { col, FindOptions, fn, literal, Op, Transaction, WhereOptions } from 'sequelize'
import {
AllowNull,
BeforeDestroy,
Table,
UpdatedAt
} from 'sequelize-typescript'
-import { ActorModel } from '../activitypub/actor'
-import { getSort, getVideoSort, parseAggregateResult, throwIfNotValid } from '../utils'
-import { isActivityPubUrlValid, isUrlValid } from '../../helpers/custom-validators/activitypub/misc'
-import { CONSTRAINTS_FIELDS, MIMETYPES } from '../../initializers/constants'
-import { VideoFileModel } from '../video/video-file'
-import { VideoModel } from '../video/video'
-import { VideoRedundancyStrategy, VideoRedundancyStrategyWithManual } from '../../../shared/models/redundancy'
-import { logger } from '../../helpers/logger'
-import { CacheFileObject, VideoPrivacy } from '../../../shared'
-import { VideoChannelModel } from '../video/video-channel'
-import { ServerModel } from '../server/server'
-import { sample } from 'lodash'
-import { isTestInstance } from '../../helpers/core-utils'
-import * as Bluebird from 'bluebird'
-import { col, FindOptions, fn, literal, Op, Transaction, WhereOptions } from 'sequelize'
-import { VideoStreamingPlaylistModel } from '../video/video-streaming-playlist'
-import { CONFIG } from '../../initializers/config'
+import { getServerActor } from '@server/models/application/application'
import { MVideoForRedundancyAPI, MVideoRedundancy, MVideoRedundancyAP, MVideoRedundancyVideo } from '@server/types/models'
import { VideoRedundanciesTarget } from '@shared/models/redundancy/video-redundancies-filters.model'
import {
StreamingPlaylistRedundancyInformation,
VideoRedundancy
} from '@shared/models/redundancy/video-redundancy.model'
-import { getServerActor } from '@server/models/application/application'
+import { CacheFileObject, VideoPrivacy } from '../../../shared'
+import { VideoRedundancyStrategy, VideoRedundancyStrategyWithManual } from '../../../shared/models/redundancy'
+import { isTestInstance } from '../../helpers/core-utils'
+import { isActivityPubUrlValid, isUrlValid } from '../../helpers/custom-validators/activitypub/misc'
+import { logger } from '../../helpers/logger'
+import { CONFIG } from '../../initializers/config'
+import { CONSTRAINTS_FIELDS, MIMETYPES } from '../../initializers/constants'
+import { ActorModel } from '../activitypub/actor'
+import { ServerModel } from '../server/server'
+import { getSort, getVideoSort, parseAggregateResult, throwIfNotValid } from '../utils'
+import { VideoModel } from '../video/video'
+import { VideoChannelModel } from '../video/video-channel'
+import { VideoFileModel } from '../video/video-file'
+import { VideoStreamingPlaylistModel } from '../video/video-streaming-playlist'
export enum ScopeNames {
WITH_VIDEO = 'WITH_VIDEO'
}
]
})
-export class VideoRedundancyModel extends Model<VideoRedundancyModel> {
+export class VideoRedundancyModel extends Model {
@CreatedAt
createdAt: Date
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 = {
where: { id },
transaction
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 = {
where: {
url
.then(r => !!r)
}
- static async getVideoSample (p: Bluebird<VideoModel[]>) {
+ static async getVideoSample (p: Promise<VideoModel[]>) {
const rows = await p
if (rows.length === 0) return undefined
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` +
')'
)
-import * as Bluebird from 'bluebird'
import { FindAndCountOptions, json, QueryTypes } from 'sequelize'
import { AllowNull, Column, CreatedAt, DataType, DefaultScope, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
import { MPlugin, MPluginFormattable } from '@server/types/models'
}
]
})
-export class PluginModel extends Model<PluginModel> {
+export class PluginModel extends Model {
@AllowNull(false)
@Is('PluginName', value => throwIfNotValid(value, isPluginNameValid, 'name'))
@UpdatedAt
updatedAt: Date
- static listEnabledPluginsAndThemes (): Bluebird<MPlugin[]> {
+ static listEnabledPluginsAndThemes (): Promise<MPlugin[]> {
const query = {
where: {
enabled: true,
return PluginModel.findAll(query)
}
- static loadByNpmName (npmName: string): Bluebird<MPlugin> {
+ static loadByNpmName (npmName: string): Promise<MPlugin> {
const name = this.normalizePluginName(npmName)
const type = this.getTypeFromNpmName(npmName)
})
}
- static listInstalled (): Bluebird<MPlugin[]> {
+ static listInstalled (): Promise<MPlugin[]> {
const query = {
where: {
uninstalled: false
-import * as Bluebird from 'bluebird'
import { Op } from 'sequelize'
import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
import { MServerBlocklist, MServerBlocklistAccountServer, MServerBlocklistFormattable } from '@server/types/models'
}
]
})
-export class ServerBlocklistModel extends Model<ServerBlocklistModel> {
+export class ServerBlocklistModel extends Model {
@CreatedAt
createdAt: Date
})
}
- static loadByAccountAndHost (accountId: number, host: string): Bluebird<MServerBlocklist> {
+ static loadByAccountAndHost (accountId: number, host: string): Promise<MServerBlocklist> {
const query = {
where: {
accountId
return ServerBlocklistModel.findOne(query)
}
- static listHostsBlockedBy (accountIds: number[]): Bluebird<string[]> {
+ static listHostsBlockedBy (accountIds: number[]): Promise<string[]> {
const query = {
attributes: [ ],
where: {
import { AllowNull, Column, CreatedAt, Default, HasMany, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
+import { MServer, MServerFormattable } from '@server/types/models/server'
import { isHostValid } from '../../helpers/custom-validators/servers'
import { ActorModel } from '../activitypub/actor'
import { throwIfNotValid } from '../utils'
import { ServerBlocklistModel } from './server-blocklist'
-import * as Bluebird from 'bluebird'
-import { MServer, MServerFormattable } from '@server/types/models/server'
@Table({
tableName: 'server',
}
]
})
-export class ServerModel extends Model<ServerModel> {
+export class ServerModel extends Model {
@AllowNull(false)
@Is('Host', value => throwIfNotValid(value, isHostValid, 'valid host'))
})
BlockedByAccounts: ServerBlocklistModel[]
- static load (id: number): Bluebird<MServer> {
+ static load (id: number): Promise<MServer> {
const query = {
where: {
id
return ServerModel.findOne(query)
}
- static loadByHost (host: string): Bluebird<MServer> {
+ static loadByHost (host: string): Promise<MServer> {
const query = {
where: {
host
function buildTrigramSearchIndex (indexName: string, attribute: string) {
return {
name: indexName,
- fields: [ Sequelize.literal('lower(immutable_unaccent(' + attribute + '))') as any ],
+ // FIXME: gin_trgm_ops is not taken into account in Sequelize 6, so adding it ourselves in the literal function
+ fields: [ Sequelize.literal('lower(immutable_unaccent(' + attribute + ')) gin_trgm_ops') as any ],
using: 'gin',
operator: 'gin_trgm_ops'
}
}
]
})
-export class ScheduleVideoUpdateModel extends Model<ScheduleVideoUpdateModel> {
+export class ScheduleVideoUpdateModel extends Model {
@AllowNull(false)
@Default(null)
-import * as Bluebird from 'bluebird'
-import { fn, QueryTypes, Transaction, col } from 'sequelize'
+import { col, fn, QueryTypes, Transaction } from 'sequelize'
import { AllowNull, BelongsToMany, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
+import { MTag } from '@server/types/models'
+import { VideoPrivacy, VideoState } from '../../../shared/models/videos'
import { isVideoTagValid } from '../../helpers/custom-validators/videos'
import { throwIfNotValid } from '../utils'
import { VideoModel } from './video'
import { VideoTagModel } from './video-tag'
-import { VideoPrivacy, VideoState } from '../../../shared/models/videos'
-import { MTag } from '@server/types/models'
@Table({
tableName: 'tag',
}
]
})
-export class TagModel extends Model<TagModel> {
+export class TagModel extends Model {
@AllowNull(false)
@Is('VideoTag', value => throwIfNotValid(value, isVideoTagValid, 'tag'))
static findOrCreateTags (tags: string[], transaction: Transaction): Promise<MTag[]> {
if (tags === null) return Promise.resolve([])
- const tasks: Bluebird<MTag>[] = []
+ const tasks: Promise<MTag>[] = []
tags.forEach(tag => {
const query = {
where: {
}
// 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 ' +
'INNER JOIN "videoTag" ON "videoTag"."tagId" = tag.id ' +
'INNER JOIN video ON video.id = "videoTag"."videoId" ' +
}
]
})
-export class ThumbnailModel extends Model<ThumbnailModel> {
+export class ThumbnailModel extends Model {
@AllowNull(false)
@Column
+import { FindOptions } from 'sequelize'
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
-import { getBlacklistSort, SortType, throwIfNotValid, searchAttribute } from '../utils'
-import { VideoModel } from './video'
-import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel'
-import { isVideoBlacklistReasonValid, isVideoBlacklistTypeValid } from '../../helpers/custom-validators/video-blacklist'
+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 { FindOptions } from 'sequelize'
+import { getBlacklistSort, searchAttribute, SortType, throwIfNotValid } from '../utils'
import { ThumbnailModel } from './thumbnail'
-import * as Bluebird from 'bluebird'
-import { MVideoBlacklist, MVideoBlacklistFormattable } from '@server/types/models'
+import { VideoModel } from './video'
+import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from './video-channel'
@Table({
tableName: 'videoBlacklist',
}
]
})
-export class VideoBlacklistModel extends Model<VideoBlacklistModel> {
+export class VideoBlacklistModel extends Model {
@AllowNull(true)
@Is('VideoBlacklistReason', value => throwIfNotValid(value, isVideoBlacklistReasonValid, 'reason', true))
})
}
- static loadByVideoId (id: number): Bluebird<MVideoBlacklist> {
+ static loadByVideoId (id: number): Promise<MVideoBlacklist> {
const query = {
where: {
videoId: id
+import { remove } from 'fs-extra'
+import { join } from 'path'
import { OrderItem, Transaction } from 'sequelize'
import {
AllowNull,
Table,
UpdatedAt
} from 'sequelize-typescript'
-import { buildWhereIdOrUUID, throwIfNotValid } from '../utils'
-import { VideoModel } from './video'
-import { isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions'
+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 { CONSTRAINTS_FIELDS, LAZY_STATIC_PATHS, VIDEO_LANGUAGES, WEBSERVER } from '../../initializers/constants'
-import { join } from 'path'
+import { isVideoCaptionLanguageValid } from '../../helpers/custom-validators/video-captions'
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'
+import { CONSTRAINTS_FIELDS, LAZY_STATIC_PATHS, VIDEO_LANGUAGES, WEBSERVER } from '../../initializers/constants'
+import { buildWhereIdOrUUID, throwIfNotValid } from '../utils'
+import { VideoModel } from './video'
export enum ScopeNames {
WITH_VIDEO_UUID_AND_REMOTE = 'WITH_VIDEO_UUID_AND_REMOTE'
}
]
})
-export class VideoCaptionModel extends Model<VideoCaptionModel> {
+export class VideoCaptionModel extends Model {
@CreatedAt
createdAt: Date
return undefined
}
- static loadByVideoIdAndLanguage (videoId: string | number, language: string): Bluebird<MVideoCaptionVideo> {
+ static loadByVideoIdAndLanguage (videoId: string | number, language: string): Promise<MVideoCaptionVideo> {
const videoInclude = {
model: VideoModel.unscoped(),
attributes: [ 'id', 'remote', 'uuid' ],
.then(([ caption ]) => caption)
}
- static listVideoCaptions (videoId: number): Bluebird<MVideoCaptionVideo[]> {
+ static listVideoCaptions (videoId: number): Promise<MVideoCaptionVideo[]> {
const query = {
order: [ [ 'language', 'ASC' ] ] as OrderItem[],
where: {
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 { MVideoChangeOwnershipFormattable, MVideoChangeOwnershipFull } from '@server/types/models/video/video-change-ownership'
import { VideoChangeOwnership, VideoChangeOwnershipStatus } from '../../../shared/models/videos'
+import { AccountModel } from '../account/account'
import { getSort } from '../utils'
-import { MVideoChangeOwnershipFormattable, MVideoChangeOwnershipFull } from '@server/types/models/video/video-change-ownership'
-import * as Bluebird from 'bluebird'
+import { ScopeNames as VideoScopeNames, VideoModel } from './video'
enum ScopeNames {
WITH_ACCOUNTS = 'WITH_ACCOUNTS',
]
}
}))
-export class VideoChangeOwnershipModel extends Model<VideoChangeOwnershipModel> {
+export class VideoChangeOwnershipModel extends Model {
@CreatedAt
createdAt: Date
]).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 ])
.findByPk(id)
}
-import * as Bluebird from 'bluebird'
-import { FindOptions, literal, Op, ScopeOptions } from 'sequelize'
+import { FindOptions, Includeable, literal, Op, ScopeOptions } from 'sequelize'
import {
AllowNull,
BeforeDestroy,
}
},
[ScopeNames.SUMMARY]: (options: SummaryOptions = {}) => {
+ const include: Includeable[] = [
+ {
+ attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ],
+ model: ActorModel.unscoped(),
+ required: options.actorRequired ?? true,
+ include: [
+ {
+ attributes: [ 'host' ],
+ model: ServerModel.unscoped(),
+ required: false
+ },
+ {
+ model: AvatarModel.unscoped(),
+ required: false
+ }
+ ]
+ }
+ ]
+
const base: FindOptions = {
- attributes: [ 'id', 'name', 'description', 'actorId' ],
- include: [
- {
- attributes: [ 'id', 'preferredUsername', 'url', 'serverId', 'avatarId' ],
- model: ActorModel.unscoped(),
- required: options.actorRequired ?? true,
- include: [
- {
- attributes: [ 'host' ],
- model: ServerModel.unscoped(),
- required: false
- },
- {
- model: AvatarModel.unscoped(),
- required: false
- }
- ]
- }
- ]
+ attributes: [ 'id', 'name', 'description', 'actorId' ]
}
if (options.withAccount === true) {
- base.include.push({
+ include.push({
model: AccountModel.scope({
method: [ AccountModelScopeNames.SUMMARY, { withAccountBlockerIds: options.withAccountBlockerIds } as AccountSummaryOptions ]
}),
})
}
+ base.include = include
+
return base
},
[ScopeNames.WITH_ACCOUNT]: {
}
]
})
-export class VideoChannelModel extends Model<VideoChannelModel> {
+export class VideoChannelModel extends Model {
@AllowNull(false)
@Is('VideoChannelName', value => throwIfNotValid(value, isVideoChannelNameValid, 'name'))
order: getSort(parameters.sort)
}
- const scopes = {
- method: [ ScopeNames.FOR_API, { actorId } as AvailableForListOptions ]
- }
return VideoChannelModel
- .scope(scopes)
+ .scope({
+ method: [ ScopeNames.FOR_API, { actorId } as AvailableForListOptions ]
+ })
.findAndCountAll(query)
.then(({ rows, count }) => {
return { total: count, data: rows }
})
}
- static listLocalsForSitemap (sort: string): Bluebird<MChannelActor[]> {
+ static listLocalsForSitemap (sort: string): Promise<MChannelActor[]> {
const query = {
attributes: [ ],
offset: 0,
}
}
- const scopes = {
- method: [ ScopeNames.FOR_API, { actorId: options.actorId } as AvailableForListOptions ]
- }
return VideoChannelModel
- .scope(scopes)
+ .scope({
+ method: [ ScopeNames.FOR_API, { actorId: options.actorId } as AvailableForListOptions ]
+ })
.findAndCountAll(query)
.then(({ rows, count }) => {
return { total: count, data: rows }
})
}
- static loadByIdAndPopulateAccount (id: number): Bluebird<MChannelAccountDefault> {
+ static loadByIdAndPopulateAccount (id: number): Promise<MChannelAccountDefault> {
return VideoChannelModel.unscoped()
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findByPk(id)
}
- static loadByIdAndAccount (id: number, accountId: number): Bluebird<MChannelAccountDefault> {
+ static loadByIdAndAccount (id: number, accountId: number): Promise<MChannelAccountDefault> {
const query = {
where: {
id,
.findOne(query)
}
- static loadAndPopulateAccount (id: number): Bluebird<MChannelAccountDefault> {
+ static loadAndPopulateAccount (id: number): Promise<MChannelAccountDefault> {
return VideoChannelModel.unscoped()
.scope([ ScopeNames.WITH_ACTOR, ScopeNames.WITH_ACCOUNT ])
.findByPk(id)
}
- static loadByUrlAndPopulateAccount (url: string): Bluebird<MChannelAccountDefault> {
+ static loadByUrlAndPopulateAccount (url: string): Promise<MChannelAccountDefault> {
const query = {
include: [
{
return VideoChannelModel.loadByNameAndHostAndPopulateAccount(name, host)
}
- static loadLocalByNameAndPopulateAccount (name: string): Bluebird<MChannelAccountDefault> {
+ static loadLocalByNameAndPopulateAccount (name: string): Promise<MChannelAccountDefault> {
const query = {
include: [
{
.findOne(query)
}
- static loadByNameAndHostAndPopulateAccount (name: string, host: string): Bluebird<MChannelAccountDefault> {
+ static loadByNameAndHostAndPopulateAccount (name: string, host: string): Promise<MChannelAccountDefault> {
const query = {
include: [
{
.findOne(query)
}
- static loadAndPopulateAccountAndVideos (id: number): Bluebird<MChannelActorAccountDefaultVideos> {
+ static loadAndPopulateAccountAndVideos (id: number): Promise<MChannelActorAccountDefaultVideos> {
const options = {
include: [
VideoModel
-import * as Bluebird from 'bluebird'
import { uniq } from 'lodash'
import { FindAndCountOptions, FindOptions, Op, Order, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize'
import {
}
]
})
-export class VideoCommentModel extends Model<VideoCommentModel> {
+export class VideoCommentModel extends Model {
@CreatedAt
createdAt: Date
})
CommentAbuses: VideoCommentAbuseModel[]
- static loadById (id: number, t?: Transaction): Bluebird<MComment> {
+ static loadById (id: number, t?: Transaction): Promise<MComment> {
const query: FindOptions = {
where: {
id
return VideoCommentModel.findOne(query)
}
- static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Transaction): Bluebird<MCommentOwnerVideoReply> {
+ static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Transaction): Promise<MCommentOwnerVideoReply> {
const query: FindOptions = {
where: {
id
.findOne(query)
}
- static loadByUrlAndPopulateAccountAndVideo (url: string, t?: Transaction): Bluebird<MCommentOwnerVideo> {
+ static loadByUrlAndPopulateAccountAndVideo (url: string, t?: Transaction): Promise<MCommentOwnerVideo> {
const query: FindOptions = {
where: {
url
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 = {
where: {
url
})
}
- 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 = {
order: [ [ 'createdAt', order ] ] as Order,
where: {
}
]
})
-export class VideoFileModel extends Model<VideoFileModel> {
+export class VideoFileModel extends Model {
@CreatedAt
createdAt: Date
Table,
UpdatedAt
} from 'sequelize-typescript'
-import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers/constants'
-import { getSort, throwIfNotValid } from '../utils'
-import { ScopeNames as VideoModelScopeNames, VideoModel } from './video'
-import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports'
+import { MVideoImportDefault, MVideoImportFormattable } from '@server/types/models/video/video-import'
import { VideoImport, VideoImportState } from '../../../shared'
+import { isVideoImportStateValid, isVideoImportTargetUrlValid } from '../../helpers/custom-validators/video-imports'
import { isVideoMagnetUriValid } from '../../helpers/custom-validators/videos'
+import { CONSTRAINTS_FIELDS, VIDEO_IMPORT_STATES } from '../../initializers/constants'
import { UserModel } from '../account/user'
-import * as Bluebird from 'bluebird'
-import { MVideoImportDefault, MVideoImportFormattable } from '@server/types/models/video/video-import'
+import { getSort, throwIfNotValid } from '../utils'
+import { ScopeNames as VideoModelScopeNames, VideoModel } from './video'
@DefaultScope(() => ({
include: [
}
]
})
-export class VideoImportModel extends Model<VideoImportModel> {
+export class VideoImportModel extends Model {
@CreatedAt
createdAt: Date
return undefined
}
- static loadAndPopulateVideo (id: number): Bluebird<MVideoImportDefault> {
+ static loadAndPopulateVideo (id: number): Promise<MVideoImportDefault> {
return VideoImportModel.findByPk(id)
}
}
]
})
-export class VideoLiveModel extends Model<VideoLiveModel> {
+export class VideoLiveModel extends Model {
@AllowNull(true)
@Column(DataType.STRING)
+import { AggregateOptions, Op, ScopeOptions, Sequelize, Transaction } from 'sequelize'
import {
AllowNull,
BelongsTo,
Table,
UpdatedAt
} from 'sequelize-typescript'
-import { ForAPIOptions, ScopeNames as VideoScopeNames, VideoModel } from './video'
-import { VideoPlaylistModel } from './video-playlist'
-import { getSort, throwIfNotValid } from '../utils'
-import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
-import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
-import { PlaylistElementObject } from '../../../shared/models/activitypub/objects/playlist-element-object'
import validator from 'validator'
-import { AggregateOptions, Op, ScopeOptions, Sequelize, Transaction } from 'sequelize'
-import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../shared/models/videos/playlist/video-playlist-element.model'
-import { AccountModel } from '../account/account'
-import { VideoPrivacy } from '../../../shared/models/videos'
-import * as Bluebird from 'bluebird'
+import { MUserAccountId } from '@server/types/models'
import {
MVideoPlaylistElement,
MVideoPlaylistElementAP,
MVideoPlaylistElementVideoUrlPlaylistPrivacy,
MVideoPlaylistVideoThumbnail
} from '@server/types/models/video/video-playlist-element'
-import { MUserAccountId } from '@server/types/models'
+import { PlaylistElementObject } from '../../../shared/models/activitypub/objects/playlist-element-object'
+import { VideoPrivacy } from '../../../shared/models/videos'
+import { VideoPlaylistElement, VideoPlaylistElementType } from '../../../shared/models/videos/playlist/video-playlist-element.model'
+import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
+import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
+import { AccountModel } from '../account/account'
+import { getSort, throwIfNotValid } from '../utils'
+import { ForAPIOptions, ScopeNames as VideoScopeNames, VideoModel } from './video'
+import { VideoPlaylistModel } from './video-playlist'
@Table({
tableName: 'videoPlaylistElement',
}
]
})
-export class VideoPlaylistElementModel extends Model<VideoPlaylistElementModel> {
+export class VideoPlaylistElementModel extends Model {
@CreatedAt
createdAt: Date
]).then(([ total, data ]) => ({ total, data }))
}
- static loadByPlaylistAndVideo (videoPlaylistId: number, videoId: number): Bluebird<MVideoPlaylistElement> {
+ static loadByPlaylistAndVideo (videoPlaylistId: number, videoId: number): Promise<MVideoPlaylistElement> {
const query = {
where: {
videoPlaylistId,
return VideoPlaylistElementModel.findOne(query)
}
- static loadById (playlistElementId: number | string): Bluebird<MVideoPlaylistElement> {
+ static loadById (playlistElementId: number | string): Promise<MVideoPlaylistElement> {
return VideoPlaylistElementModel.findByPk(playlistElementId)
}
static loadByPlaylistAndElementIdForAP (
playlistId: number | string,
playlistElementId: number
- ): Bluebird<MVideoPlaylistElementVideoUrlPlaylistPrivacy> {
+ ): Promise<MVideoPlaylistElementVideoUrlPlaylistPrivacy> {
const playlistWhere = validator.isUUID('' + playlistId) ? { uuid: playlistId } : { id: playlistId }
const query = {
})
}
- static loadFirstElementWithVideoThumbnail (videoPlaylistId: number): Bluebird<MVideoPlaylistVideoThumbnail> {
+ static loadFirstElementWithVideoThumbnail (videoPlaylistId: number): Promise<MVideoPlaylistVideoThumbnail> {
const query = {
order: getSort('position'),
where: {
-import * as Bluebird from 'bluebird'
import { join } from 'path'
import { FindOptions, literal, Op, ScopeOptions, Transaction, WhereOptions } from 'sequelize'
import {
]
},
[ScopeNames.AVAILABLE_FOR_LIST]: (options: AvailableForListOptions) => {
-
let whereActor: WhereOptions = {}
const whereAnd: WhereOptions[] = []
[Op.and]: whereAnd
}
- const accountScope = {
- method: [ AccountScopeNames.SUMMARY, { whereActor } as SummaryOptions ]
- }
-
return {
where,
include: [
{
- model: AccountModel.scope(accountScope),
+ model: AccountModel.scope({
+ method: [ AccountScopeNames.SUMMARY, { whereActor } as SummaryOptions ]
+ }),
required: true
},
{
}
]
})
-export class VideoPlaylistModel extends Model<VideoPlaylistModel> {
+export class VideoPlaylistModel extends Model {
@CreatedAt
createdAt: Date
})
}
- static listPlaylistIdsOf (accountId: number, videoIds: number[]): Bluebird<MVideoPlaylistIdWithElements[]> {
+ static listPlaylistIdsOf (accountId: number, videoIds: number[]): Promise<MVideoPlaylistIdWithElements[]> {
const query = {
attributes: [ 'id' ],
where: {
static doesPlaylistExist (url: string) {
const query = {
- attributes: [],
+ attributes: [ 'id' ],
where: {
url
}
.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 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 query = {
.findOne(query)
}
- static loadByUrlAndPopulateAccount (url: string): Bluebird<MVideoPlaylistAccountThumbnail> {
+ static loadByUrlAndPopulateAccount (url: string): Promise<MVideoPlaylistAccountThumbnail> {
const query = {
where: {
url
-import * as Bluebird from 'bluebird'
+import { literal, Op, Transaction } from 'sequelize'
import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Is, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript'
import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc'
import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
+import { MActorDefault } from '../../types/models'
+import { MVideoShareActor, MVideoShareFull } from '../../types/models/video'
import { ActorModel } from '../activitypub/actor'
import { buildLocalActorIdsIn, throwIfNotValid } from '../utils'
import { VideoModel } from './video'
-import { literal, Op, Transaction } from 'sequelize'
-import { MVideoShareActor, MVideoShareFull } from '../../types/models/video'
-import { MActorDefault } from '../../types/models'
enum ScopeNames {
FULL = 'FULL',
}
]
})
-export class VideoShareModel extends Model<VideoShareModel> {
+export class VideoShareModel extends Model {
@AllowNull(false)
@Is('VideoShareUrl', value => throwIfNotValid(value, isActivityPubUrlValid, 'url'))
})
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({
where: {
actorId,
})
}
- static loadByUrl (url: string, t: Transaction): Bluebird<MVideoShareFull> {
+ static loadByUrl (url: string, t: Transaction): Promise<MVideoShareFull> {
return VideoShareModel.scope(ScopeNames.FULL).findOne({
where: {
url
})
}
- static loadActorsByShare (videoId: number, t: Transaction): Bluebird<MActorDefault[]> {
+ static loadActorsByShare (videoId: number, t: Transaction): Promise<MActorDefault[]> {
const query = {
where: {
videoId
.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)
// /!\ On actor model
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)
// /!\ On actor model
}
]
})
-export class VideoStreamingPlaylistModel extends Model<VideoStreamingPlaylistModel> {
+export class VideoStreamingPlaylistModel extends Model {
@CreatedAt
createdAt: Date
}
]
})
-export class VideoTagModel extends Model<VideoTagModel> {
+export class VideoTagModel extends Model {
@CreatedAt
createdAt: Date
}
]
})
-export class VideoViewModel extends Model<VideoViewModel> {
+export class VideoViewModel extends Model {
@CreatedAt
createdAt: Date
import { remove } from 'fs-extra'
import { maxBy, minBy, pick } from 'lodash'
import { join } from 'path'
-import { FindOptions, IncludeOptions, Op, QueryTypes, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize'
+import { FindOptions, Includeable, IncludeOptions, Op, QueryTypes, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize'
import {
AllowNull,
BeforeDestroy,
attributes: [ 'id', 'url', 'uuid', 'remote' ]
},
[ScopeNames.FOR_API]: (options: ForAPIOptions) => {
- const query: FindOptions = {
- include: [
- {
- model: VideoChannelModel.scope({
- method: [
- VideoChannelScopeNames.SUMMARY, {
- withAccount: true,
- withAccountBlockerIds: options.withAccountBlockerIds
- } as SummaryOptions
- ]
- }),
- required: true
- },
- {
- attributes: [ 'type', 'filename' ],
- model: ThumbnailModel,
- required: false
- }
- ]
- }
+ const include: Includeable[] = [
+ {
+ model: VideoChannelModel.scope({
+ method: [
+ VideoChannelScopeNames.SUMMARY, {
+ withAccount: true,
+ withAccountBlockerIds: options.withAccountBlockerIds
+ } as SummaryOptions
+ ]
+ }),
+ required: true
+ },
+ {
+ attributes: [ 'type', 'filename' ],
+ model: ThumbnailModel,
+ required: false
+ }
+ ]
+
+ const query: FindOptions = {}
if (options.ids) {
query.where = {
}
if (options.withFiles === true) {
- query.include.push({
+ include.push({
model: VideoFileModel,
required: true
})
}
if (options.videoPlaylistId) {
- query.include.push({
+ include.push({
model: VideoPlaylistElementModel.unscoped(),
required: true,
where: {
})
}
+ query.include = include
+
return query
},
[ScopeNames.WITH_THUMBNAILS]: {
}
]
})
-export class VideoModel extends Model<VideoModel> {
+export class VideoModel extends Model {
@AllowNull(false)
@Default(DataType.UUIDV4)
return undefined
}
- static listLocal (): Bluebird<MVideoWithAllFiles[]> {
+ static listLocal (): Promise<MVideoWithAllFiles[]> {
const query = {
where: {
remote: false
})
}
- static listPublishedLiveIds () {
+ static async listPublishedLiveIds () {
const options = {
attributes: [ 'id' ],
where: {
}
}
- return VideoModel.findAll(options)
- .map(v => v.id)
+ const result = await VideoModel.findAll(options)
+
+ return result.map(v => v.id)
}
static listUserVideosForApi (
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 options = {
where,
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 options = {
where,
]).findOne(options)
}
- static loadImmutableAttributes (id: number | string, t?: Transaction): Bluebird<MVideoImmutable> {
+ static loadImmutableAttributes (id: number | string, t?: Transaction): Promise<MVideoImmutable> {
const fun = () => {
const query = {
where: buildWhereIdOrUUID(id),
})
}
- static loadWithRights (id: number | string, t?: Transaction): Bluebird<MVideoWithRights> {
+ static loadWithRights (id: number | string, t?: Transaction): Promise<MVideoWithRights> {
const where = buildWhereIdOrUUID(id)
const options = {
where,
]).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 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 query = {
]).findOne(query)
}
- static loadByUUID (uuid: string): Bluebird<MVideoThumbnail> {
+ static loadByUUID (uuid: string): Promise<MVideoThumbnail> {
const options = {
where: {
uuid
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 = {
where: {
url
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 query: FindOptions = {
where: {
})
}
- static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction): Bluebird<MVideoAccountLightBlacklistAllFiles> {
+ static loadByUrlAndPopulateAccount (url: string, transaction?: Transaction): Promise<MVideoAccountLightBlacklistAllFiles> {
const query: FindOptions = {
where: {
url
]).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 options = {
id: number | string
t?: Transaction
userId?: number
- }): Bluebird<MVideoDetails> {
+ }): Promise<MVideoDetails> {
const { id, t, userId } = parameters
const where = buildWhereIdOrUUID(id)
return VideoModel.update({ support: videoChannel.support }, options)
}
- static getAllIdsFromChannel (videoChannel: MChannelId): Bluebird<number[]> {
+ static getAllIdsFromChannel (videoChannel: MChannelId): Promise<number[]> {
const query = {
attributes: [ 'id' ],
where: {
it('Should save a live replay', async function () {
this.timeout(60000)
- await waitJobs(servers)
-
- const res = await getVideo(servers[0].url, liveVideoReplayId)
- const video: VideoDetails = res.body
-
- expect(video.state.id).to.equal(VideoState.PUBLISHED)
+ await waitUntilLivePublished(servers[0].url, servers[0].accessToken, liveVideoReplayId)
})
})
-import * as Bluebird from 'bluebird'
import { Router } from 'express'
import { Logger } from 'winston'
import { ActorModel } from '@server/models/activitypub/actor'
}
videos: {
- loadByUrl: (url: string) => Bluebird<MVideoThumbnail>
+ loadByUrl: (url: string) => Promise<MVideoThumbnail>
removeVideo: (videoId: number) => Promise<void>
}
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4=
-cls-bluebird@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/cls-bluebird/-/cls-bluebird-2.1.0.tgz#37ef1e080a8ffb55c2f4164f536f1919e7968aee"
- integrity sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4=
- dependencies:
- is-bluebird "^1.0.2"
- shimmer "^1.1.0"
-
cluster-key-slot@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz#30474b2a981fb12172695833052bc0d01336d10d"
dependencies:
binary-extensions "^2.0.0"
-is-bluebird@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/is-bluebird/-/is-bluebird-1.0.2.tgz#096439060f4aa411abee19143a84d6a55346d6e2"
- integrity sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=
-
is-buffer@^1.1.5, is-buffer@~1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
yargs-parser "13.1.2"
yargs-unparser "2.0.0"
-moment-timezone@^0.5.21, moment-timezone@^0.5.31:
+moment-timezone@^0.5.31:
version "0.5.32"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.32.tgz#db7677cc3cc680fd30303ebd90b0da1ca0dfecc2"
integrity sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA==
dependencies:
moment ">= 2.9.0"
-"moment@>= 2.9.0", moment@^2.24.0:
+"moment@>= 2.9.0", moment@^2.26.0:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
range-parser "~1.2.1"
statuses "~1.5.0"
-sequelize-pool@^2.3.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-2.3.0.tgz#64f1fe8744228172c474f530604b6133be64993d"
- integrity sha512-Ibz08vnXvkZ8LJTiUOxRcj1Ckdn7qafNZ2t59jYHMX1VIebTAOYefWdRYFt6z6+hy52WGthAHAoLc9hvk3onqA==
+sequelize-pool@^6.0.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-6.1.0.tgz#caaa0c1e324d3c2c3a399fed2c7998970925d668"
+ integrity sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg==
-sequelize-typescript@^1.0.0-beta.4:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/sequelize-typescript/-/sequelize-typescript-1.1.0.tgz#d5c2945e7fbfe55a934917b27d84589858d79123"
- integrity sha512-FAPEQPeAhIaFQNLAcf9Q2IWcqWhNcvn5OZZ7BzGB0CJMtImIsGg4E/EAb7huMmPaPwDArxJUWGqk1KurphTNRA==
+sequelize-typescript@^2.0.0-beta.1:
+ version "2.0.0-beta.1"
+ resolved "https://registry.yarnpkg.com/sequelize-typescript/-/sequelize-typescript-2.0.0-beta.1.tgz#08c52c35e7fb4f940b9919cbc77752776bcc800a"
+ integrity sha512-GHlNfh8vPIJKzXtk4A8MTndK3Uu87HO75fFFX4PM+35P/SW3fFCiw/KeHeQ6DjLz7zeI+fop2HFWVeuZarnJwQ==
dependencies:
glob "7.1.2"
-sequelize@5.21.13:
- version "5.21.13"
- resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-5.21.13.tgz#c8c2f6a2d44d0a234c101155447d494d8d216c7b"
- integrity sha512-wpwSpxzvADmgPkcOGeer5yFdAVsYeA7NLEw4evSXw03OlGL41J4S8hVz2/nilSWlJSwumlDGC9QbdwAmkWGqJg==
+sequelize@6.3.5:
+ version "6.3.5"
+ resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.3.5.tgz#80e3db7ac8b76d98c45ca93334197eb6e2335158"
+ integrity sha512-MiwiPkYSA8NWttRKAXdU9h0TxP6HAc1fl7qZmMO/VQqQOND83G4nZLXd0kWILtAoT9cxtZgFqeb/MPYgEeXwsw==
dependencies:
- bluebird "^3.5.0"
- cls-bluebird "^2.1.0"
debug "^4.1.1"
dottie "^2.0.0"
inflection "1.12.0"
lodash "^4.17.15"
- moment "^2.24.0"
- moment-timezone "^0.5.21"
+ moment "^2.26.0"
+ moment-timezone "^0.5.31"
retry-as-promised "^3.2.0"
- semver "^6.3.0"
- sequelize-pool "^2.3.0"
+ semver "^7.3.2"
+ sequelize-pool "^6.0.0"
toposort-class "^1.0.1"
- uuid "^3.3.3"
+ uuid "^8.1.0"
validator "^10.11.0"
- wkx "^0.4.8"
+ wkx "^0.5.0"
serialize-javascript@5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
-shimmer@^1.1.0:
- version "1.2.1"
- resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
- integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
-
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
assert-never "^1.2.1"
babel-walk "3.0.0-canary-5"
-wkx@^0.4.8:
- version "0.4.8"
- resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.4.8.tgz#a092cf088d112683fdc7182fd31493b2c5820003"
- integrity sha512-ikPXMM9IR/gy/LwiOSqWlSL3X/J5uk9EO2hHNRXS41eTLXaUFEVw9fn/593jW/tE5tedNg8YjT5HkCa4FqQZyQ==
+wkx@^0.5.0:
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c"
+ integrity sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==
dependencies:
"@types/node" "*"