// ---------------------------------------------------------------------------
function webfingerController (req: express.Request, res: express.Response) {
- const actor = res.locals.actorFull
+ const actor = res.locals.actorUrl
const json = {
subject: req.query.resource,
]
}
- return res.json(json).end()
+ return res.json(json)
}
createdAt: new Date(videoObject.published),
publishedAt: new Date(videoObject.published),
originallyPublishedAt: videoObject.originallyPublishedAt ? new Date(videoObject.originallyPublishedAt) : null,
- // FIXME: updatedAt does not seems to be considered by Sequelize
updatedAt: new Date(videoObject.updated),
views: videoObject.views,
likes: 0,
continue
}
- // FIXME: Bull queue typings does not have getJobs method
- const jobs = await (queue as any).getJobs(state, 0, start + count, asc)
+ const jobs = await queue.getJobs([ state ], 0, start + count, asc)
results = results.concat(jobs)
}
const nameWithHost = getHostWithPort(req.query.resource.substr(5))
const [ name ] = nameWithHost.split('@')
- // FIXME: we don't need the full actor
- const actor = await ActorModel.loadLocalByName(name)
+ const actor = await ActorModel.loadLocalUrlByName(name)
if (!actor) {
return res.status(404)
.send({ error: 'Actor not found' })
.end()
}
- res.locals.actorFull = actor
+ res.locals.actorUrl = actor
return next()
}
]
attributes: [ 'accountId', 'id' ],
where: {
accountId: {
- [Op.in]: accountIds // FIXME: sequelize ANY seems broken
+ [Op.in]: accountIds
},
targetAccountId
},
where: {
userId,
id: {
- [Op.in]: notificationIds // FIXME: sequelize ANY seems broken
+ [Op.in]: notificationIds
}
}
}
MActorFull,
MActorHost,
MActorServer,
- MActorSummaryFormattable,
+ MActorSummaryFormattable, MActorUrl,
MActorWithInboxes
} from '../../typings/models'
import * as Bluebird from 'bluebird'
})
VideoChannel: VideoChannelModel
- private static cache: { [ id: string ]: any } = {}
+ private static localNameCache: { [ id: string ]: any } = {}
+ private static localUrlCache: { [ id: string ]: any } = {}
static load (id: number): Bluebird<MActor> {
return ActorModel.unscoped().findByPk(id)
static loadLocalByName (preferredUsername: string, transaction?: Transaction): Bluebird<MActorFull> {
// The server actor never change, so we can easily cache it
- if (preferredUsername === SERVER_ACTOR_NAME && ActorModel.cache[preferredUsername]) {
- return Bluebird.resolve(ActorModel.cache[preferredUsername])
+ if (preferredUsername === SERVER_ACTOR_NAME && ActorModel.localNameCache[preferredUsername]) {
+ return Bluebird.resolve(ActorModel.localNameCache[preferredUsername])
}
const query = {
.findOne(query)
.then(actor => {
if (preferredUsername === SERVER_ACTOR_NAME) {
- ActorModel.cache[ preferredUsername ] = actor
+ ActorModel.localNameCache[ preferredUsername ] = actor
+ }
+
+ return actor
+ })
+ }
+
+ static loadLocalUrlByName (preferredUsername: string, transaction?: Transaction): Bluebird<MActorUrl> {
+ // The server actor never change, so we can easily cache it
+ if (preferredUsername === SERVER_ACTOR_NAME && ActorModel.localUrlCache[preferredUsername]) {
+ return Bluebird.resolve(ActorModel.localUrlCache[preferredUsername])
+ }
+
+ const query = {
+ attributes: [ 'url' ],
+ where: {
+ preferredUsername,
+ serverId: null
+ },
+ transaction
+ }
+
+ return ActorModel.unscoped()
+ .findOne(query)
+ .then(actor => {
+ if (preferredUsername === SERVER_ACTOR_NAME) {
+ ActorModel.localUrlCache[ preferredUsername ] = actor
}
return actor
attributes: [ 'accountId', 'id' ],
where: {
accountId: {
- [Op.in]: accountIds // FIXME: sequelize ANY seems broken
+ [Op.in]: accountIds
},
targetServerId
},
language
}
- return (VideoCaptionModel.upsert<VideoCaptionModel>(values, { transaction, returning: true }) as any) // FIXME: typings
+ return VideoCaptionModel.upsert(values, { transaction, returning: true })
.then(([ caption ]) => caption)
}
MChannelSummaryFormattable
} from '../../typings/models/video'
-// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
-const indexes: ModelIndexesOptions[] = [
- buildTrigramSearchIndex('video_channel_name_trigram', 'name'),
-
- {
- fields: [ 'accountId' ]
- },
- {
- fields: [ 'actorId' ]
- }
-]
-
export enum ScopeNames {
FOR_API = 'FOR_API',
WITH_ACCOUNT = 'WITH_ACCOUNT',
}))
@Table({
tableName: 'videoChannel',
- indexes
+ indexes: [
+ buildTrigramSearchIndex('video_channel_name_trigram', 'name'),
+
+ {
+ fields: [ 'accountId' ]
+ },
+ {
+ fields: [ 'actorId' ]
+ }
+ ]
})
export class VideoChannelModel extends Model<VideoChannelModel> {
model: VideoPlaylistElementModel.unscoped(),
where: {
videoId: {
- [Op.in]: videoIds // FIXME: sequelize ANY seems broken
+ [Op.in]: videoIds
}
},
required: true
import * as Bluebird from 'bluebird'
import { maxBy, minBy } from 'lodash'
import { join } from 'path'
-import {
- CountOptions,
- FindOptions,
- IncludeOptions,
- ModelIndexesOptions,
- Op,
- QueryTypes,
- ScopeOptions,
- Sequelize,
- Transaction,
- WhereOptions
-} from 'sequelize'
+import { CountOptions, FindOptions, IncludeOptions, Op, QueryTypes, ScopeOptions, Sequelize, Transaction, WhereOptions } from 'sequelize'
import {
AllowNull,
BeforeDestroy,
MVideoThumbnailBlacklist,
MVideoWithAllFiles,
MVideoWithFile,
- MVideoWithRights,
- MStreamingPlaylistFiles
+ MVideoWithRights
} from '../../typings/models'
import { MVideoFile, MVideoFileStreamingPlaylistVideo } from '../../typings/models/video/video-file'
import { MThumbnail } from '../../typings/models/video/thumbnail'
import { getHLSDirectory, getTorrentFileName, getTorrentFilePath, getVideoFilename, getVideoFilePath } from '@server/lib/video-paths'
import validator from 'validator'
-// FIXME: Define indexes here because there is an issue with TS and Sequelize.literal when called directly in the annotation
-const indexes: (ModelIndexesOptions & { where?: WhereOptions })[] = [
- buildTrigramSearchIndex('video_name_trigram', 'name'),
-
- { fields: [ 'createdAt' ] },
- {
- fields: [
- { name: 'publishedAt', order: 'DESC' },
- { name: 'id', order: 'ASC' }
- ]
- },
- { fields: [ 'duration' ] },
- { fields: [ 'views' ] },
- { fields: [ 'channelId' ] },
- {
- fields: [ 'originallyPublishedAt' ],
- where: {
- originallyPublishedAt: {
- [Op.ne]: null
- }
- }
- },
- {
- fields: [ 'category' ], // We don't care videos with an unknown category
- where: {
- category: {
- [Op.ne]: null
- }
- }
- },
- {
- fields: [ 'licence' ], // We don't care videos with an unknown licence
- where: {
- licence: {
- [Op.ne]: null
- }
- }
- },
- {
- fields: [ 'language' ], // We don't care videos with an unknown language
- where: {
- language: {
- [Op.ne]: null
- }
- }
- },
- {
- fields: [ 'nsfw' ], // Most of the videos are not NSFW
- where: {
- nsfw: true
- }
- },
- {
- fields: [ 'remote' ], // Only index local videos
- where: {
- remote: false
- }
- },
- {
- fields: [ 'uuid' ],
- unique: true
- },
- {
- fields: [ 'url' ],
- unique: true
- }
-]
-
export enum ScopeNames {
AVAILABLE_FOR_LIST_IDS = 'AVAILABLE_FOR_LIST_IDS',
FOR_API = 'FOR_API',
if (options.ids) {
query.where = {
id: {
- [ Op.in ]: options.ids // FIXME: sequelize ANY seems broken
+ [ Op.in ]: options.ids
}
}
}
}))
@Table({
tableName: 'video',
- indexes
+ indexes: [
+ buildTrigramSearchIndex('video_name_trigram', 'name'),
+
+ { fields: [ 'createdAt' ] },
+ {
+ fields: [
+ { name: 'publishedAt', order: 'DESC' },
+ { name: 'id', order: 'ASC' }
+ ]
+ },
+ { fields: [ 'duration' ] },
+ { fields: [ 'views' ] },
+ { fields: [ 'channelId' ] },
+ {
+ fields: [ 'originallyPublishedAt' ],
+ where: {
+ originallyPublishedAt: {
+ [Op.ne]: null
+ }
+ }
+ },
+ {
+ fields: [ 'category' ], // We don't care videos with an unknown category
+ where: {
+ category: {
+ [Op.ne]: null
+ }
+ }
+ },
+ {
+ fields: [ 'licence' ], // We don't care videos with an unknown licence
+ where: {
+ licence: {
+ [Op.ne]: null
+ }
+ }
+ },
+ {
+ fields: [ 'language' ], // We don't care videos with an unknown language
+ where: {
+ language: {
+ [Op.ne]: null
+ }
+ }
+ },
+ {
+ fields: [ 'nsfw' ], // Most of the videos are not NSFW
+ where: {
+ nsfw: true
+ }
+ },
+ {
+ fields: [ 'remote' ], // Only index local videos
+ where: {
+ remote: false
+ }
+ },
+ {
+ fields: [ 'uuid' ],
+ unique: true
+ },
+ {
+ fields: [ 'url' ],
+ unique: true
+ }
+ ]
})
export class VideoModel extends Model<VideoModel> {
} from './models'
import { MVideoPlaylistFull, MVideoPlaylistFullSummary } from './models/video/video-playlist'
import { MVideoImportDefault } from '@server/typings/models/video/video-import'
-import { MAccountBlocklist, MStreamingPlaylist, MVideoFile } from '@server/typings/models'
+import { MAccountBlocklist, MActorUrl, MStreamingPlaylist, MVideoFile } from '@server/typings/models'
import { MVideoPlaylistElement, MVideoPlaylistElementVideoUrlPlaylistPrivacy } from '@server/typings/models/video/video-playlist-element'
import { MAccountVideoRateAccountVideo } from '@server/typings/models/video/video-rate'
import { MVideoChangeOwnershipFull } from './models/video/video-change-ownership'
account?: MAccountDefault
+ actorUrl?: MActorUrl
actorFull?: MActorFull
user?: MUserDefault
if (!total) return 0
- // FIXME: check if we really need parseInt
return parseInt(total + '', 10)
}