Move models to typescript-sequelize

This commit is contained in:
Chocobozzz 2017-12-12 17:53:50 +01:00
parent c893d4514e
commit 3fd3ab2d34
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
150 changed files with 3676 additions and 5074 deletions

View File

@ -77,11 +77,13 @@
"pem": "^1.12.3", "pem": "^1.12.3",
"pg": "^6.4.2", "pg": "^6.4.2",
"pg-hstore": "^2.3.2", "pg-hstore": "^2.3.2",
"reflect-metadata": "^0.1.10",
"request": "^2.81.0", "request": "^2.81.0",
"rimraf": "^2.5.4", "rimraf": "^2.5.4",
"safe-buffer": "^5.0.1", "safe-buffer": "^5.0.1",
"scripty": "^1.5.0", "scripty": "^1.5.0",
"sequelize": "^4.7.5", "sequelize": "^4.7.5",
"sequelize-typescript": "^0.6.1",
"ts-node": "^3.3.0", "ts-node": "^3.3.0",
"typescript": "^2.5.2", "typescript": "^2.5.2",
"uuid": "^3.1.0", "uuid": "^3.1.0",

View File

@ -1,12 +1,10 @@
import * as rimraf from 'rimraf'
import * as Promise from 'bluebird' import * as Promise from 'bluebird'
import * as rimraf from 'rimraf'
import { CONFIG, initDatabase, sequelizeTypescript } from '../../../server/initializers'
import { CONFIG } from '../../../server/initializers/constants' initDatabase(true)
import { database as db } from '../../../server/initializers/database'
db.init(true)
.then(() => { .then(() => {
return db.sequelize.drop() return sequelizeTypescript.drop()
}) })
.then(() => { .then(() => {
console.info('Tables of %s deleted.', CONFIG.DATABASE.DBNAME) console.info('Tables of %s deleted.', CONFIG.DATABASE.DBNAME)

View File

@ -1,6 +1,6 @@
import * as program from 'commander' import * as program from 'commander'
import { initDatabase } from '../server/initializers'
import { database as db } from '../server/initializers/database' import { UserModel } from '../server/models/account/user'
program program
.option('-u, --user [user]', 'User') .option('-u, --user [user]', 'User')
@ -11,9 +11,9 @@ if (program['user'] === undefined) {
process.exit(-1) process.exit(-1)
} }
db.init(true) initDatabase(true)
.then(() => { .then(() => {
return db.User.loadByUsername(program['user']) return UserModel.loadByUsername(program['user'])
}) })
.then(user => { .then(user => {
if (!user) { if (!user) {

View File

@ -1,12 +1,14 @@
import { database as db } from '../server/initializers/database' import { getServerAccount } from '../server/helpers'
import { getServerAccount } from '../server/helpers/utils' import { initDatabase } from '../server/initializers'
import { AccountFollowModel } from '../server/models/account/account-follow'
import { VideoModel } from '../server/models/video/video'
db.init(true) initDatabase(true)
.then(() => { .then(() => {
return getServerAccount() return getServerAccount()
}) })
.then(serverAccount => { .then(serverAccount => {
return db.AccountFollow.listAcceptedFollowingUrlsForApi([ serverAccount.id ], undefined) return AccountFollowModel.listAcceptedFollowingUrlsForApi([ serverAccount.id ], undefined)
}) })
.then(res => { .then(res => {
return res.total > 0 return res.total > 0
@ -18,7 +20,7 @@ db.init(true)
} }
console.log('Updating torrent files.') console.log('Updating torrent files.')
return db.Video.list() return VideoModel.list()
}) })
.then(videos => { .then(videos => {
const tasks: Promise<any>[] = [] const tasks: Promise<any>[] = []

View File

@ -41,8 +41,8 @@ if (errorMessage !== null) {
// Do not use barrels because we don't want to load all modules here (we need to initialize database first) // Do not use barrels because we don't want to load all modules here (we need to initialize database first)
import { logger } from './server/helpers/logger' import { logger } from './server/helpers/logger'
// Initialize database and models // Initialize database and models
import { database as db } from './server/initializers/database' import { initDatabase } from './server/initializers/database'
db.init(false).then(() => onDatabaseInitDone()) initDatabase(false).then(() => onDatabaseInitDone())
// ----------- PeerTube modules ----------- // ----------- PeerTube modules -----------
import { migrate, installApplication } from './server/initializers' import { migrate, installApplication } from './server/initializers'

View File

@ -1,20 +1,22 @@
// Intercept ActivityPub client requests // Intercept ActivityPub client requests
import * as express from 'express' import * as express from 'express'
import { pageToStartAndCount } from '../../helpers' import { activityPubCollectionPagination, pageToStartAndCount } from '../../helpers'
import { activityPubCollectionPagination } from '../../helpers/activitypub' import { ACTIVITY_PUB, CONFIG } from '../../initializers'
import { buildVideoChannelAnnounceToFollowers } from '../../lib/activitypub/send'
import { database as db } from '../../initializers'
import { ACTIVITY_PUB, CONFIG } from '../../initializers/constants'
import { buildVideoChannelAnnounceToFollowers } from '../../lib/activitypub/send/send-announce'
import { buildVideoAnnounceToFollowers } from '../../lib/index' import { buildVideoAnnounceToFollowers } from '../../lib/index'
import { executeIfActivityPub, localAccountValidator } from '../../middlewares' import { asyncMiddleware, executeIfActivityPub, localAccountValidator } from '../../middlewares'
import { asyncMiddleware } from '../../middlewares/async' import {
import { videoChannelsGetValidator, videoChannelsShareValidator } from '../../middlewares/validators/video-channels' videoChannelsGetValidator,
import { videosGetValidator, videosShareValidator } from '../../middlewares/validators/videos' videoChannelsShareValidator,
import { AccountInstance, VideoChannelInstance } from '../../models' videosGetValidator,
import { VideoChannelShareInstance } from '../../models/video/video-channel-share-interface' videosShareValidator
import { VideoInstance } from '../../models/video/video-interface' } from '../../middlewares/validators'
import { VideoShareInstance } from '../../models/video/video-share-interface' import { AccountModel } from '../../models/account/account'
import { AccountFollowModel } from '../../models/account/account-follow'
import { VideoModel } from '../../models/video/video'
import { VideoChannelModel } from '../../models/video/video-channel'
import { VideoChannelShareModel } from '../../models/video/video-channel-share'
import { VideoShareModel } from '../../models/video/video-share'
const activityPubClientRouter = express.Router() const activityPubClientRouter = express.Router()
@ -62,57 +64,57 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function accountController (req: express.Request, res: express.Response, next: express.NextFunction) { function accountController (req: express.Request, res: express.Response, next: express.NextFunction) {
const account: AccountInstance = res.locals.account const account: AccountModel = res.locals.account
return res.json(account.toActivityPubObject()).end() return res.json(account.toActivityPubObject()).end()
} }
async function accountFollowersController (req: express.Request, res: express.Response, next: express.NextFunction) { async function accountFollowersController (req: express.Request, res: express.Response, next: express.NextFunction) {
const account: AccountInstance = res.locals.account const account: AccountModel = res.locals.account
const page = req.query.page || 1 const page = req.query.page || 1
const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE)
const result = await db.AccountFollow.listAcceptedFollowerUrlsForApi([ account.id ], undefined, start, count) const result = await AccountFollowModel.listAcceptedFollowerUrlsForApi([ account.id ], undefined, start, count)
const activityPubResult = activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result) const activityPubResult = activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result)
return res.json(activityPubResult) return res.json(activityPubResult)
} }
async function accountFollowingController (req: express.Request, res: express.Response, next: express.NextFunction) { async function accountFollowingController (req: express.Request, res: express.Response, next: express.NextFunction) {
const account: AccountInstance = res.locals.account const account: AccountModel = res.locals.account
const page = req.query.page || 1 const page = req.query.page || 1
const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE)
const result = await db.AccountFollow.listAcceptedFollowingUrlsForApi([ account.id ], undefined, start, count) const result = await AccountFollowModel.listAcceptedFollowingUrlsForApi([ account.id ], undefined, start, count)
const activityPubResult = activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result) const activityPubResult = activityPubCollectionPagination(CONFIG.WEBSERVER.URL + req.url, page, result)
return res.json(activityPubResult) return res.json(activityPubResult)
} }
function videoController (req: express.Request, res: express.Response, next: express.NextFunction) { function videoController (req: express.Request, res: express.Response, next: express.NextFunction) {
const video: VideoInstance = res.locals.video const video: VideoModel = res.locals.video
return res.json(video.toActivityPubObject()) return res.json(video.toActivityPubObject())
} }
async function videoAnnounceController (req: express.Request, res: express.Response, next: express.NextFunction) { async function videoAnnounceController (req: express.Request, res: express.Response, next: express.NextFunction) {
const share = res.locals.videoShare as VideoShareInstance const share = res.locals.videoShare as VideoShareModel
const object = await buildVideoAnnounceToFollowers(share.Account, res.locals.video, undefined) const object = await buildVideoAnnounceToFollowers(share.Account, res.locals.video, undefined)
return res.json(object) return res.json(object)
} }
async function videoChannelAnnounceController (req: express.Request, res: express.Response, next: express.NextFunction) { async function videoChannelAnnounceController (req: express.Request, res: express.Response, next: express.NextFunction) {
const share = res.locals.videoChannelShare as VideoChannelShareInstance const share = res.locals.videoChannelShare as VideoChannelShareModel
const object = await buildVideoChannelAnnounceToFollowers(share.Account, share.VideoChannel, undefined) const object = await buildVideoChannelAnnounceToFollowers(share.Account, share.VideoChannel, undefined)
return res.json(object) return res.json(object)
} }
async function videoChannelController (req: express.Request, res: express.Response, next: express.NextFunction) { async function videoChannelController (req: express.Request, res: express.Response, next: express.NextFunction) {
const videoChannel: VideoChannelInstance = res.locals.videoChannel const videoChannel: VideoChannelModel = res.locals.videoChannel
return res.json(videoChannel.toActivityPubObject()) return res.json(videoChannel.toActivityPubObject())
} }

View File

@ -2,13 +2,13 @@ import * as express from 'express'
import { Activity } from '../../../shared/models/activitypub/activity' import { Activity } from '../../../shared/models/activitypub/activity'
import { activityPubCollectionPagination } from '../../helpers/activitypub' import { activityPubCollectionPagination } from '../../helpers/activitypub'
import { pageToStartAndCount } from '../../helpers/core-utils' import { pageToStartAndCount } from '../../helpers/core-utils'
import { database as db } from '../../initializers'
import { ACTIVITY_PUB } from '../../initializers/constants' import { ACTIVITY_PUB } from '../../initializers/constants'
import { addActivityData } from '../../lib/activitypub/send/send-add' import { addActivityData } from '../../lib/activitypub/send/send-add'
import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url' import { getAnnounceActivityPubUrl } from '../../lib/activitypub/url'
import { announceActivityData } from '../../lib/index' import { announceActivityData } from '../../lib/index'
import { asyncMiddleware, localAccountValidator } from '../../middlewares' import { asyncMiddleware, localAccountValidator } from '../../middlewares'
import { AccountInstance } from '../../models/account/account-interface' import { AccountModel } from '../../models/account/account'
import { VideoModel } from '../../models/video/video'
const outboxRouter = express.Router() const outboxRouter = express.Router()
@ -26,12 +26,12 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function outboxController (req: express.Request, res: express.Response, next: express.NextFunction) { async function outboxController (req: express.Request, res: express.Response, next: express.NextFunction) {
const account: AccountInstance = res.locals.account const account: AccountModel = res.locals.account
const page = req.query.page || 1 const page = req.query.page || 1
const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE) const { start, count } = pageToStartAndCount(page, ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE)
const data = await db.Video.listAllAndSharedByAccountForOutbox(account.id, start, count) const data = await VideoModel.listAllAndSharedByAccountForOutbox(account.id, start, count)
const activities: Activity[] = [] const activities: Activity[] = []
for (const video of data.data) { for (const video of data.data) {

View File

@ -1,11 +1,9 @@
import * as express from 'express' import * as express from 'express'
import { asyncMiddleware, jobsSortValidator, setJobsSort, setPagination } from '../../middlewares' import { UserRight } from '../../../shared/models/users'
import { paginationValidator } from '../../middlewares/validators/pagination' import { getFormattedObjects } from '../../helpers'
import { database as db } from '../../initializers' import { asyncMiddleware, authenticate, ensureUserHasRight, jobsSortValidator, setJobsSort, setPagination } from '../../middlewares'
import { getFormattedObjects } from '../../helpers/utils' import { paginationValidator } from '../../middlewares/validators'
import { authenticate } from '../../middlewares/oauth' import { JobModel } from '../../models/job/job'
import { ensureUserHasRight } from '../../middlewares/user-right'
import { UserRight } from '../../../shared/models/users/user-right.enum'
const jobsRouter = express.Router() const jobsRouter = express.Router()
@ -28,7 +26,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function listJobs (req: express.Request, res: express.Response, next: express.NextFunction) { async function listJobs (req: express.Request, res: express.Response, next: express.NextFunction) {
const resultList = await db.Job.listForApi(req.query.start, req.query.count, req.query.sort) const resultList = await JobModel.listForApi(req.query.start, req.query.count, req.query.sort)
return res.json(getFormattedObjects(resultList.data, resultList.total)) return res.json(getFormattedObjects(resultList.data, resultList.total))
} }

View File

@ -3,8 +3,8 @@ import * as express from 'express'
import { CONFIG } from '../../initializers' import { CONFIG } from '../../initializers'
import { logger } from '../../helpers' import { logger } from '../../helpers'
import { asyncMiddleware } from '../../middlewares' import { asyncMiddleware } from '../../middlewares'
import { database as db } from '../../initializers/database'
import { OAuthClientLocal } from '../../../shared' import { OAuthClientLocal } from '../../../shared'
import { OAuthClientModel } from '../../models/oauth/oauth-client'
const oauthClientsRouter = express.Router() const oauthClientsRouter = express.Router()
@ -27,7 +27,7 @@ async function getLocalClient (req: express.Request, res: express.Response, next
return res.type('json').status(403).end() return res.type('json').status(403).end()
} }
const client = await db.OAuthClient.loadFirstClient() const client = await OAuthClientModel.loadFirstClient()
if (!client) throw new Error('No client available.') if (!client) throw new Error('No client available.')
const json: OAuthClientLocal = { const json: OAuthClientLocal = {

View File

@ -1,24 +1,24 @@
import * as express from 'express' import * as express from 'express'
import { UserRight } from '../../../../shared/models/users/user-right.enum' import { UserRight } from '../../../../shared/models/users'
import { getFormattedObjects } from '../../../helpers' import { getAccountFromWebfinger, getFormattedObjects, getServerAccount, logger, retryTransactionWrapper } from '../../../helpers'
import { retryTransactionWrapper } from '../../../helpers/database-utils' import { sequelizeTypescript, SERVER_ACCOUNT_NAME } from '../../../initializers'
import { logger } from '../../../helpers/logger' import { saveAccountAndServerIfNotExist } from '../../../lib/activitypub'
import { getServerAccount } from '../../../helpers/utils' import { sendUndoFollow } from '../../../lib/activitypub/send'
import { getAccountFromWebfinger } from '../../../helpers/webfinger'
import { SERVER_ACCOUNT_NAME } from '../../../initializers/constants'
import { database as db } from '../../../initializers/database'
import { saveAccountAndServerIfNotExist } from '../../../lib/activitypub/account'
import { sendUndoFollow } from '../../../lib/activitypub/send/send-undo'
import { sendFollow } from '../../../lib/index' import { sendFollow } from '../../../lib/index'
import { asyncMiddleware, paginationValidator, removeFollowingValidator, setFollowersSort, setPagination } from '../../../middlewares' import {
import { authenticate } from '../../../middlewares/oauth' asyncMiddleware,
import { setBodyHostsPort } from '../../../middlewares/servers' authenticate,
import { setFollowingSort } from '../../../middlewares/sort' ensureUserHasRight,
import { ensureUserHasRight } from '../../../middlewares/user-right' paginationValidator,
import { followValidator } from '../../../middlewares/validators/follows' removeFollowingValidator,
import { followersSortValidator, followingSortValidator } from '../../../middlewares/validators/sort' setBodyHostsPort,
import { AccountInstance } from '../../../models/account/account-interface' setFollowersSort,
import { AccountFollowInstance } from '../../../models/index' setFollowingSort,
setPagination
} from '../../../middlewares'
import { followersSortValidator, followingSortValidator, followValidator } from '../../../middlewares/validators'
import { AccountModel } from '../../../models/account/account'
import { AccountFollowModel } from '../../../models/account/account-follow'
const serverFollowsRouter = express.Router() const serverFollowsRouter = express.Router()
@ -63,14 +63,14 @@ export {
async function listFollowing (req: express.Request, res: express.Response, next: express.NextFunction) { async function listFollowing (req: express.Request, res: express.Response, next: express.NextFunction) {
const serverAccount = await getServerAccount() const serverAccount = await getServerAccount()
const resultList = await db.AccountFollow.listFollowingForApi(serverAccount.id, req.query.start, req.query.count, req.query.sort) const resultList = await AccountFollowModel.listFollowingForApi(serverAccount.id, req.query.start, req.query.count, req.query.sort)
return res.json(getFormattedObjects(resultList.data, resultList.total)) return res.json(getFormattedObjects(resultList.data, resultList.total))
} }
async function listFollowers (req: express.Request, res: express.Response, next: express.NextFunction) { async function listFollowers (req: express.Request, res: express.Response, next: express.NextFunction) {
const serverAccount = await getServerAccount() const serverAccount = await getServerAccount()
const resultList = await db.AccountFollow.listFollowersForApi(serverAccount.id, req.query.start, req.query.count, req.query.sort) const resultList = await AccountFollowModel.listFollowersForApi(serverAccount.id, req.query.start, req.query.count, req.query.sort)
return res.json(getFormattedObjects(resultList.data, resultList.total)) return res.json(getFormattedObjects(resultList.data, resultList.total))
} }
@ -110,14 +110,14 @@ async function followRetry (req: express.Request, res: express.Response, next: e
return res.status(204).end() return res.status(204).end()
} }
async function follow (fromAccount: AccountInstance, targetAccount: AccountInstance, targetAlreadyInDB: boolean) { async function follow (fromAccount: AccountModel, targetAccount: AccountModel, targetAlreadyInDB: boolean) {
try { try {
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
if (targetAlreadyInDB === false) { if (targetAlreadyInDB === false) {
await saveAccountAndServerIfNotExist(targetAccount, t) await saveAccountAndServerIfNotExist(targetAccount, t)
} }
const [ accountFollow ] = await db.AccountFollow.findOrCreate({ const [ accountFollow ] = await AccountFollowModel.findOrCreate({
where: { where: {
accountId: fromAccount.id, accountId: fromAccount.id,
targetAccountId: targetAccount.id targetAccountId: targetAccount.id
@ -145,9 +145,9 @@ async function follow (fromAccount: AccountInstance, targetAccount: AccountInsta
} }
async function removeFollow (req: express.Request, res: express.Response, next: express.NextFunction) { async function removeFollow (req: express.Request, res: express.Response, next: express.NextFunction) {
const follow: AccountFollowInstance = res.locals.follow const follow: AccountFollowModel = res.locals.follow
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
if (follow.state === 'accepted') await sendUndoFollow(follow, t) if (follow.state === 'accepted') await sendUndoFollow(follow, t)
await follow.destroy({ transaction: t }) await follow.destroy({ transaction: t })
@ -164,7 +164,7 @@ async function removeFollow (req: express.Request, res: express.Response, next:
async function loadLocalOrGetAccountFromWebfinger (name: string, host: string) { async function loadLocalOrGetAccountFromWebfinger (name: string, host: string) {
let loadedFromDB = true let loadedFromDB = true
let account = await db.Account.loadByNameAndHost(name, host) let account = await AccountModel.loadByNameAndHost(name, host)
if (!account) { if (!account) {
const nameWithDomain = name + '@' + host const nameWithDomain = name + '@' + host

View File

@ -1,7 +1,7 @@
import * as express from 'express' import * as express from 'express'
import { UserCreate, UserRight, UserRole, UserUpdate, UserUpdateMe, UserVideoRate as FormattedUserVideoRate } from '../../../shared' import { UserCreate, UserRight, UserRole, UserUpdate, UserUpdateMe, UserVideoRate as FormattedUserVideoRate } from '../../../shared'
import { getFormattedObjects, logger, retryTransactionWrapper } from '../../helpers' import { getFormattedObjects, logger, retryTransactionWrapper } from '../../helpers'
import { CONFIG, database as db } from '../../initializers' import { CONFIG } from '../../initializers'
import { createUserAccountAndChannel } from '../../lib' import { createUserAccountAndChannel } from '../../lib'
import { import {
asyncMiddleware, asyncMiddleware,
@ -11,6 +11,7 @@ import {
paginationValidator, paginationValidator,
setPagination, setPagination,
setUsersSort, setUsersSort,
setVideosSort,
token, token,
usersAddValidator, usersAddValidator,
usersGetValidator, usersGetValidator,
@ -21,9 +22,10 @@ import {
usersUpdateValidator, usersUpdateValidator,
usersVideoRatingValidator usersVideoRatingValidator
} from '../../middlewares' } from '../../middlewares'
import { setVideosSort } from '../../middlewares/sort' import { videosSortValidator } from '../../middlewares/validators'
import { videosSortValidator } from '../../middlewares/validators/sort' import { AccountVideoRateModel } from '../../models/account/account-video-rate'
import { UserInstance } from '../../models' import { UserModel } from '../../models/account/user'
import { VideoModel } from '../../models/video/video'
const usersRouter = express.Router() const usersRouter = express.Router()
@ -107,8 +109,8 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function getUserVideos (req: express.Request, res: express.Response, next: express.NextFunction) { async function getUserVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
const user = res.locals.oauth.token.User const user = res.locals.oauth.token.User as UserModel
const resultList = await db.Video.listUserVideosForApi(user.id ,req.query.start, req.query.count, req.query.sort) const resultList = await VideoModel.listUserVideosForApi(user.id ,req.query.start, req.query.count, req.query.sort)
return res.json(getFormattedObjects(resultList.data, resultList.total)) return res.json(getFormattedObjects(resultList.data, resultList.total))
} }
@ -127,7 +129,7 @@ async function createUserRetryWrapper (req: express.Request, res: express.Respon
async function createUser (req: express.Request) { async function createUser (req: express.Request) {
const body: UserCreate = req.body const body: UserCreate = req.body
const user = db.User.build({ const user = new UserModel({
username: body.username, username: body.username,
password: body.password, password: body.password,
email: body.email, email: body.email,
@ -155,7 +157,7 @@ async function registerUserRetryWrapper (req: express.Request, res: express.Resp
async function registerUser (req: express.Request) { async function registerUser (req: express.Request) {
const body: UserCreate = req.body const body: UserCreate = req.body
const user = db.User.build({ const user = new UserModel({
username: body.username, username: body.username,
password: body.password, password: body.password,
email: body.email, email: body.email,
@ -171,7 +173,7 @@ async function registerUser (req: express.Request) {
async function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) { async function getUserInformation (req: express.Request, res: express.Response, next: express.NextFunction) {
// We did not load channels in res.locals.user // We did not load channels in res.locals.user
const user = await db.User.loadByUsernameAndPopulateChannels(res.locals.oauth.token.user.username) const user = await UserModel.loadByUsernameAndPopulateChannels(res.locals.oauth.token.user.username)
return res.json(user.toFormattedJSON()) return res.json(user.toFormattedJSON())
} }
@ -184,7 +186,7 @@ async function getUserVideoRating (req: express.Request, res: express.Response,
const videoId = +req.params.videoId const videoId = +req.params.videoId
const accountId = +res.locals.oauth.token.User.Account.id const accountId = +res.locals.oauth.token.User.Account.id
const ratingObj = await db.AccountVideoRate.load(accountId, videoId, null) const ratingObj = await AccountVideoRateModel.load(accountId, videoId, null)
const rating = ratingObj ? ratingObj.type : 'none' const rating = ratingObj ? ratingObj.type : 'none'
const json: FormattedUserVideoRate = { const json: FormattedUserVideoRate = {
@ -195,13 +197,13 @@ async function getUserVideoRating (req: express.Request, res: express.Response,
} }
async function listUsers (req: express.Request, res: express.Response, next: express.NextFunction) { async function listUsers (req: express.Request, res: express.Response, next: express.NextFunction) {
const resultList = await db.User.listForApi(req.query.start, req.query.count, req.query.sort) const resultList = await UserModel.listForApi(req.query.start, req.query.count, req.query.sort)
return res.json(getFormattedObjects(resultList.data, resultList.total)) return res.json(getFormattedObjects(resultList.data, resultList.total))
} }
async function removeUser (req: express.Request, res: express.Response, next: express.NextFunction) { async function removeUser (req: express.Request, res: express.Response, next: express.NextFunction) {
const user = await db.User.loadById(req.params.id) const user = await UserModel.loadById(req.params.id)
await user.destroy() await user.destroy()
@ -225,7 +227,7 @@ async function updateMe (req: express.Request, res: express.Response, next: expr
async function updateUser (req: express.Request, res: express.Response, next: express.NextFunction) { async function updateUser (req: express.Request, res: express.Response, next: express.NextFunction) {
const body: UserUpdate = req.body const body: UserUpdate = req.body
const user: UserInstance = res.locals.user const user = res.locals.user as UserModel
if (body.email !== undefined) user.email = body.email if (body.email !== undefined) user.email = body.email
if (body.videoQuota !== undefined) user.videoQuota = body.videoQuota if (body.videoQuota !== undefined) user.videoQuota = body.videoQuota

View File

@ -1,11 +1,10 @@
import * as express from 'express' import * as express from 'express'
import { database as db } from '../../../initializers/database'
import { import {
logger, logger,
getFormattedObjects, getFormattedObjects,
retryTransactionWrapper retryTransactionWrapper
} from '../../../helpers' } from '../../../helpers'
import { sequelizeTypescript } from '../../../initializers'
import { import {
authenticate, authenticate,
ensureUserHasRight, ensureUserHasRight,
@ -16,9 +15,11 @@ import {
setPagination, setPagination,
asyncMiddleware asyncMiddleware
} from '../../../middlewares' } from '../../../middlewares'
import { VideoInstance } from '../../../models'
import { VideoAbuseCreate, UserRight } from '../../../../shared' import { VideoAbuseCreate, UserRight } from '../../../../shared'
import { sendVideoAbuse } from '../../../lib/index' import { sendVideoAbuse } from '../../../lib/index'
import { AccountModel } from '../../../models/account/account'
import { VideoModel } from '../../../models/video/video'
import { VideoAbuseModel } from '../../../models/video/video-abuse'
const abuseVideoRouter = express.Router() const abuseVideoRouter = express.Router()
@ -46,7 +47,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function listVideoAbuses (req: express.Request, res: express.Response, next: express.NextFunction) { async function listVideoAbuses (req: express.Request, res: express.Response, next: express.NextFunction) {
const resultList = await db.VideoAbuse.listForApi(req.query.start, req.query.count, req.query.sort) const resultList = await VideoAbuseModel.listForApi(req.query.start, req.query.count, req.query.sort)
return res.json(getFormattedObjects(resultList.data, resultList.total)) return res.json(getFormattedObjects(resultList.data, resultList.total))
} }
@ -63,8 +64,8 @@ async function reportVideoAbuseRetryWrapper (req: express.Request, res: express.
} }
async function reportVideoAbuse (req: express.Request, res: express.Response) { async function reportVideoAbuse (req: express.Request, res: express.Response) {
const videoInstance = res.locals.video as VideoInstance const videoInstance = res.locals.video as VideoModel
const reporterAccount = res.locals.oauth.token.User.Account const reporterAccount = res.locals.oauth.token.User.Account as AccountModel
const body: VideoAbuseCreate = req.body const body: VideoAbuseCreate = req.body
const abuseToCreate = { const abuseToCreate = {
@ -73,8 +74,8 @@ async function reportVideoAbuse (req: express.Request, res: express.Response) {
videoId: videoInstance.id videoId: videoInstance.id
} }
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
const videoAbuseInstance = await db.VideoAbuse.create(abuseToCreate, { transaction: t }) const videoAbuseInstance = await VideoAbuseModel.create(abuseToCreate, { transaction: t })
videoAbuseInstance.Video = videoInstance videoAbuseInstance.Video = videoInstance
// We send the video abuse to the origin server // We send the video abuse to the origin server

View File

@ -1,6 +1,4 @@
import * as express from 'express' import * as express from 'express'
import { database as db } from '../../../initializers'
import { logger, getFormattedObjects } from '../../../helpers' import { logger, getFormattedObjects } from '../../../helpers'
import { import {
authenticate, authenticate,
@ -13,8 +11,8 @@ import {
setPagination, setPagination,
asyncMiddleware asyncMiddleware
} from '../../../middlewares' } from '../../../middlewares'
import { BlacklistedVideoInstance } from '../../../models'
import { BlacklistedVideo, UserRight } from '../../../../shared' import { BlacklistedVideo, UserRight } from '../../../../shared'
import { VideoBlacklistModel } from '../../../models/video/video-blacklist'
const blacklistRouter = express.Router() const blacklistRouter = express.Router()
@ -57,18 +55,18 @@ async function addVideoToBlacklist (req: express.Request, res: express.Response,
videoId: videoInstance.id videoId: videoInstance.id
} }
await db.BlacklistedVideo.create(toCreate) await VideoBlacklistModel.create(toCreate)
return res.type('json').status(204).end() return res.type('json').status(204).end()
} }
async function listBlacklist (req: express.Request, res: express.Response, next: express.NextFunction) { async function listBlacklist (req: express.Request, res: express.Response, next: express.NextFunction) {
const resultList = await db.BlacklistedVideo.listForApi(req.query.start, req.query.count, req.query.sort) const resultList = await VideoBlacklistModel.listForApi(req.query.start, req.query.count, req.query.sort)
return res.json(getFormattedObjects<BlacklistedVideo, BlacklistedVideoInstance>(resultList.data, resultList.total)) return res.json(getFormattedObjects<BlacklistedVideo, VideoBlacklistModel>(resultList.data, resultList.total))
} }
async function removeVideoFromBlacklistController (req: express.Request, res: express.Response, next: express.NextFunction) { async function removeVideoFromBlacklistController (req: express.Request, res: express.Response, next: express.NextFunction) {
const blacklistedVideo = res.locals.blacklistedVideo as BlacklistedVideoInstance const blacklistedVideo = res.locals.blacklistedVideo as VideoBlacklistModel
try { try {
await blacklistedVideo.destroy() await blacklistedVideo.destroy()

View File

@ -1,7 +1,7 @@
import * as express from 'express' import * as express from 'express'
import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared' import { VideoChannelCreate, VideoChannelUpdate } from '../../../../shared'
import { getFormattedObjects, logger, resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers' import { getFormattedObjects, logger, resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers'
import { database as db } from '../../../initializers' import { sequelizeTypescript } from '../../../initializers'
import { createVideoChannel } from '../../../lib' import { createVideoChannel } from '../../../lib'
import { sendUpdateVideoChannel } from '../../../lib/activitypub/send/send-update' import { sendUpdateVideoChannel } from '../../../lib/activitypub/send/send-update'
import { import {
@ -17,7 +17,8 @@ import {
videoChannelsSortValidator, videoChannelsSortValidator,
videoChannelsUpdateValidator videoChannelsUpdateValidator
} from '../../../middlewares' } from '../../../middlewares'
import { AccountInstance, VideoChannelInstance } from '../../../models' import { AccountModel } from '../../../models/account/account'
import { VideoChannelModel } from '../../../models/video/video-channel'
const videoChannelRouter = express.Router() const videoChannelRouter = express.Router()
@ -66,13 +67,13 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function listVideoChannels (req: express.Request, res: express.Response, next: express.NextFunction) { async function listVideoChannels (req: express.Request, res: express.Response, next: express.NextFunction) {
const resultList = await db.VideoChannel.listForApi(req.query.start, req.query.count, req.query.sort) const resultList = await VideoChannelModel.listForApi(req.query.start, req.query.count, req.query.sort)
return res.json(getFormattedObjects(resultList.data, resultList.total)) return res.json(getFormattedObjects(resultList.data, resultList.total))
} }
async function listVideoAccountChannels (req: express.Request, res: express.Response, next: express.NextFunction) { async function listVideoAccountChannels (req: express.Request, res: express.Response, next: express.NextFunction) {
const resultList = await db.VideoChannel.listByAccount(res.locals.account.id) const resultList = await VideoChannelModel.listByAccount(res.locals.account.id)
return res.json(getFormattedObjects(resultList.data, resultList.total)) return res.json(getFormattedObjects(resultList.data, resultList.total))
} }
@ -93,10 +94,10 @@ async function addVideoChannelRetryWrapper (req: express.Request, res: express.R
async function addVideoChannel (req: express.Request, res: express.Response) { async function addVideoChannel (req: express.Request, res: express.Response) {
const videoChannelInfo: VideoChannelCreate = req.body const videoChannelInfo: VideoChannelCreate = req.body
const account: AccountInstance = res.locals.oauth.token.User.Account const account: AccountModel = res.locals.oauth.token.User.Account
let videoChannelCreated: VideoChannelInstance let videoChannelCreated: VideoChannelModel
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
videoChannelCreated = await createVideoChannel(videoChannelInfo, account, t) videoChannelCreated = await createVideoChannel(videoChannelInfo, account, t)
}) })
@ -115,12 +116,12 @@ async function updateVideoChannelRetryWrapper (req: express.Request, res: expres
} }
async function updateVideoChannel (req: express.Request, res: express.Response) { async function updateVideoChannel (req: express.Request, res: express.Response) {
const videoChannelInstance: VideoChannelInstance = res.locals.videoChannel const videoChannelInstance = res.locals.videoChannel as VideoChannelModel
const videoChannelFieldsSave = videoChannelInstance.toJSON() const videoChannelFieldsSave = videoChannelInstance.toJSON()
const videoChannelInfoToUpdate: VideoChannelUpdate = req.body const videoChannelInfoToUpdate = req.body as VideoChannelUpdate
try { try {
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
const sequelizeOptions = { const sequelizeOptions = {
transaction: t transaction: t
} }
@ -158,9 +159,9 @@ async function removeVideoChannelRetryWrapper (req: express.Request, res: expres
} }
async function removeVideoChannel (req: express.Request, res: express.Response) { async function removeVideoChannel (req: express.Request, res: express.Response) {
const videoChannelInstance: VideoChannelInstance = res.locals.videoChannel const videoChannelInstance: VideoChannelModel = res.locals.videoChannel
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
await videoChannelInstance.destroy({ transaction: t }) await videoChannelInstance.destroy({ transaction: t })
}) })
@ -168,7 +169,7 @@ async function removeVideoChannel (req: express.Request, res: express.Response)
} }
async function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) { async function getVideoChannel (req: express.Request, res: express.Response, next: express.NextFunction) {
const videoChannelWithVideos = await db.VideoChannel.loadAndPopulateAccountAndVideos(res.locals.videoChannel.id) const videoChannelWithVideos = await VideoChannelModel.loadAndPopulateAccountAndVideos(res.locals.videoChannel.id)
return res.json(videoChannelWithVideos.toFormattedJSON()) return res.json(videoChannelWithVideos.toFormattedJSON())
} }

View File

@ -12,16 +12,19 @@ import {
retryTransactionWrapper retryTransactionWrapper
} from '../../../helpers' } from '../../../helpers'
import { getServerAccount } from '../../../helpers/utils' import { getServerAccount } from '../../../helpers/utils'
import { CONFIG, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_MIMETYPE_EXT, VIDEO_PRIVACIES } from '../../../initializers' import {
import { database as db } from '../../../initializers/database' CONFIG,
import { sendAddVideo } from '../../../lib/activitypub/send/send-add' sequelizeTypescript,
import { sendCreateViewToOrigin } from '../../../lib/activitypub/send/send-create' VIDEO_CATEGORIES,
import { sendUpdateVideo } from '../../../lib/activitypub/send/send-update' VIDEO_LANGUAGES,
import { shareVideoByServer } from '../../../lib/activitypub/share' VIDEO_LICENCES,
import { getVideoActivityPubUrl } from '../../../lib/activitypub/url' VIDEO_MIMETYPE_EXT,
import { fetchRemoteVideoDescription } from '../../../lib/activitypub/videos' VIDEO_PRIVACIES
} from '../../../initializers'
import { fetchRemoteVideoDescription, getVideoActivityPubUrl, shareVideoByServer } from '../../../lib/activitypub'
import { sendAddVideo, sendCreateViewToOrigin, sendUpdateVideo } from '../../../lib/activitypub/send'
import { sendCreateViewToVideoFollowers } from '../../../lib/index' import { sendCreateViewToVideoFollowers } from '../../../lib/index'
import { transcodingJobScheduler } from '../../../lib/jobs/transcoding-job-scheduler/transcoding-job-scheduler' import { transcodingJobScheduler } from '../../../lib/jobs/transcoding-job-scheduler'
import { import {
asyncMiddleware, asyncMiddleware,
authenticate, authenticate,
@ -35,7 +38,9 @@ import {
videosSortValidator, videosSortValidator,
videosUpdateValidator videosUpdateValidator
} from '../../../middlewares' } from '../../../middlewares'
import { VideoInstance } from '../../../models' import { TagModel } from '../../../models/video/tag'
import { VideoModel } from '../../../models/video/video'
import { VideoFileModel } from '../../../models/video/video-file'
import { abuseVideoRouter } from './abuse' import { abuseVideoRouter } from './abuse'
import { blacklistRouter } from './blacklist' import { blacklistRouter } from './blacklist'
import { videoChannelRouter } from './channel' import { videoChannelRouter } from './channel'
@ -99,7 +104,7 @@ videosRouter.put('/:id',
videosRouter.post('/upload', videosRouter.post('/upload',
authenticate, authenticate,
reqFiles, reqFiles,
videosAddValidator, asyncMiddleware(videosAddValidator),
asyncMiddleware(addVideoRetryWrapper) asyncMiddleware(addVideoRetryWrapper)
) )
@ -181,7 +186,7 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
duration: videoPhysicalFile['duration'], // duration was added by a previous middleware duration: videoPhysicalFile['duration'], // duration was added by a previous middleware
channelId: res.locals.videoChannel.id channelId: res.locals.videoChannel.id
} }
const video = db.Video.build(videoData) const video = new VideoModel(videoData)
video.url = getVideoActivityPubUrl(video) video.url = getVideoActivityPubUrl(video)
const videoFilePath = join(CONFIG.STORAGE.VIDEOS_DIR, videoPhysicalFile.filename) const videoFilePath = join(CONFIG.STORAGE.VIDEOS_DIR, videoPhysicalFile.filename)
@ -192,7 +197,7 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
resolution: videoFileHeight, resolution: videoFileHeight,
size: videoPhysicalFile.size size: videoPhysicalFile.size
} }
const videoFile = db.VideoFile.build(videoFileData) const videoFile = new VideoFileModel(videoFileData)
const videoDir = CONFIG.STORAGE.VIDEOS_DIR const videoDir = CONFIG.STORAGE.VIDEOS_DIR
const source = join(videoDir, videoPhysicalFile.filename) const source = join(videoDir, videoPhysicalFile.filename)
const destination = join(videoDir, video.getVideoFilename(videoFile)) const destination = join(videoDir, video.getVideoFilename(videoFile))
@ -210,7 +215,7 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
) )
await Promise.all(tasks) await Promise.all(tasks)
return db.sequelize.transaction(async t => { return sequelizeTypescript.transaction(async t => {
const sequelizeOptions = { transaction: t } const sequelizeOptions = { transaction: t }
if (CONFIG.TRANSCODING.ENABLED === true) { if (CONFIG.TRANSCODING.ENABLED === true) {
@ -232,9 +237,9 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
video.VideoFiles = [ videoFile ] video.VideoFiles = [ videoFile ]
if (videoInfo.tags) { if (videoInfo.tags) {
const tagInstances = await db.Tag.findOrCreateTags(videoInfo.tags, t) const tagInstances = await TagModel.findOrCreateTags(videoInfo.tags, t)
await video.setTags(tagInstances, sequelizeOptions) await video.$set('Tags', tagInstances, sequelizeOptions)
video.Tags = tagInstances video.Tags = tagInstances
} }
@ -264,13 +269,13 @@ async function updateVideoRetryWrapper (req: express.Request, res: express.Respo
} }
async function updateVideo (req: express.Request, res: express.Response) { async function updateVideo (req: express.Request, res: express.Response) {
const videoInstance: VideoInstance = res.locals.video const videoInstance: VideoModel = res.locals.video
const videoFieldsSave = videoInstance.toJSON() const videoFieldsSave = videoInstance.toJSON()
const videoInfoToUpdate: VideoUpdate = req.body const videoInfoToUpdate: VideoUpdate = req.body
const wasPrivateVideo = videoInstance.privacy === VideoPrivacy.PRIVATE const wasPrivateVideo = videoInstance.privacy === VideoPrivacy.PRIVATE
try { try {
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
const sequelizeOptions = { const sequelizeOptions = {
transaction: t transaction: t
} }
@ -286,9 +291,9 @@ async function updateVideo (req: express.Request, res: express.Response) {
const videoInstanceUpdated = await videoInstance.save(sequelizeOptions) const videoInstanceUpdated = await videoInstance.save(sequelizeOptions)
if (videoInfoToUpdate.tags) { if (videoInfoToUpdate.tags) {
const tagInstances = await db.Tag.findOrCreateTags(videoInfoToUpdate.tags, t) const tagInstances = await TagModel.findOrCreateTags(videoInfoToUpdate.tags, t)
await videoInstance.setTags(tagInstances, sequelizeOptions) await videoInstance.$set('Tags', tagInstances, sequelizeOptions)
videoInstance.Tags = tagInstances videoInstance.Tags = tagInstances
} }
@ -350,7 +355,7 @@ async function getVideoDescription (req: express.Request, res: express.Response)
} }
async function listVideos (req: express.Request, res: express.Response, next: express.NextFunction) { async function listVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
const resultList = await db.Video.listForApi(req.query.start, req.query.count, req.query.sort) const resultList = await VideoModel.listForApi(req.query.start, req.query.count, req.query.sort)
return res.json(getFormattedObjects(resultList.data, resultList.total)) return res.json(getFormattedObjects(resultList.data, resultList.total))
} }
@ -367,9 +372,9 @@ async function removeVideoRetryWrapper (req: express.Request, res: express.Respo
} }
async function removeVideo (req: express.Request, res: express.Response) { async function removeVideo (req: express.Request, res: express.Response) {
const videoInstance: VideoInstance = res.locals.video const videoInstance: VideoModel = res.locals.video
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
await videoInstance.destroy({ transaction: t }) await videoInstance.destroy({ transaction: t })
}) })
@ -377,7 +382,7 @@ async function removeVideo (req: express.Request, res: express.Response) {
} }
async function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) { async function searchVideos (req: express.Request, res: express.Response, next: express.NextFunction) {
const resultList = await db.Video.searchAndPopulateAccountAndServerAndTags( const resultList = await VideoModel.searchAndPopulateAccountAndServerAndTags(
req.query.search, req.query.search,
req.query.start, req.query.start,
req.query.count, req.query.count,

View File

@ -1,12 +1,12 @@
import * as express from 'express' import * as express from 'express'
import { UserVideoRateUpdate } from '../../../../shared' import { UserVideoRateUpdate } from '../../../../shared'
import { logger, retryTransactionWrapper } from '../../../helpers' import { logger, retryTransactionWrapper } from '../../../helpers'
import { VIDEO_RATE_TYPES } from '../../../initializers' import { sequelizeTypescript, VIDEO_RATE_TYPES } from '../../../initializers'
import { database as db } from '../../../initializers/database' import { sendVideoRateChangeToFollowers, sendVideoRateChangeToOrigin } from '../../../lib/activitypub'
import { sendVideoRateChangeToFollowers, sendVideoRateChangeToOrigin } from '../../../lib/activitypub/videos'
import { asyncMiddleware, authenticate, videoRateValidator } from '../../../middlewares' import { asyncMiddleware, authenticate, videoRateValidator } from '../../../middlewares'
import { AccountInstance } from '../../../models/account/account-interface' import { AccountModel } from '../../../models/account/account'
import { VideoInstance } from '../../../models/video/video-interface' import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
import { VideoModel } from '../../../models/video/video'
const rateVideoRouter = express.Router() const rateVideoRouter = express.Router()
@ -38,12 +38,12 @@ async function rateVideoRetryWrapper (req: express.Request, res: express.Respons
async function rateVideo (req: express.Request, res: express.Response) { async function rateVideo (req: express.Request, res: express.Response) {
const body: UserVideoRateUpdate = req.body const body: UserVideoRateUpdate = req.body
const rateType = body.rating const rateType = body.rating
const videoInstance: VideoInstance = res.locals.video const videoInstance: VideoModel = res.locals.video
const accountInstance: AccountInstance = res.locals.oauth.token.User.Account const accountInstance: AccountModel = res.locals.oauth.token.User.Account
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
const sequelizeOptions = { transaction: t } const sequelizeOptions = { transaction: t }
const previousRate = await db.AccountVideoRate.load(accountInstance.id, videoInstance.id, t) const previousRate = await AccountVideoRateModel.load(accountInstance.id, videoInstance.id, t)
let likesToIncrement = 0 let likesToIncrement = 0
let dislikesToIncrement = 0 let dislikesToIncrement = 0
@ -71,7 +71,7 @@ async function rateVideo (req: express.Request, res: express.Response) {
type: rateType type: rateType
} }
await db.AccountVideoRate.create(query, sequelizeOptions) await AccountVideoRateModel.create(query, sequelizeOptions)
} }
const incrementQuery = { const incrementQuery = {

View File

@ -2,8 +2,6 @@ import * as express from 'express'
import { join } from 'path' import { join } from 'path'
import * as validator from 'validator' import * as validator from 'validator'
import * as Bluebird from 'bluebird' import * as Bluebird from 'bluebird'
import { database as db } from '../initializers/database'
import { import {
CONFIG, CONFIG,
STATIC_PATHS, STATIC_PATHS,
@ -13,7 +11,7 @@ import {
} from '../initializers' } from '../initializers'
import { root, readFileBufferPromise, escapeHTML } from '../helpers' import { root, readFileBufferPromise, escapeHTML } from '../helpers'
import { asyncMiddleware } from '../middlewares' import { asyncMiddleware } from '../middlewares'
import { VideoInstance } from '../models' import { VideoModel } from '../models/video/video'
const clientsRouter = express.Router() const clientsRouter = express.Router()
@ -49,7 +47,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function addOpenGraphAndOEmbedTags (htmlStringPage: string, video: VideoInstance) { function addOpenGraphAndOEmbedTags (htmlStringPage: string, video: VideoModel) {
const previewUrl = CONFIG.WEBSERVER.URL + STATIC_PATHS.PREVIEWS + video.getPreviewName() const previewUrl = CONFIG.WEBSERVER.URL + STATIC_PATHS.PREVIEWS + video.getPreviewName()
const videoUrl = CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid const videoUrl = CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid
@ -108,13 +106,13 @@ function addOpenGraphAndOEmbedTags (htmlStringPage: string, video: VideoInstance
async function generateWatchHtmlPage (req: express.Request, res: express.Response, next: express.NextFunction) { async function generateWatchHtmlPage (req: express.Request, res: express.Response, next: express.NextFunction) {
const videoId = '' + req.params.id const videoId = '' + req.params.id
let videoPromise: Bluebird<VideoInstance> let videoPromise: Bluebird<VideoModel>
// Let Angular application handle errors // Let Angular application handle errors
if (validator.isUUID(videoId, 4)) { if (validator.isUUID(videoId, 4)) {
videoPromise = db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(videoId) videoPromise = VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(videoId)
} else if (validator.isInt(videoId)) { } else if (validator.isInt(videoId)) {
videoPromise = db.Video.loadAndPopulateAccountAndServerAndTags(+videoId) videoPromise = VideoModel.loadAndPopulateAccountAndServerAndTags(+videoId)
} else { } else {
return res.sendFile(indexPath) return res.sendFile(indexPath)
} }

View File

@ -1,9 +1,7 @@
import * as express from 'express' import * as express from 'express'
import { CONFIG, EMBED_SIZE, PREVIEWS_SIZE } from '../initializers' import { CONFIG, EMBED_SIZE, PREVIEWS_SIZE } from '../initializers'
import { oembedValidator } from '../middlewares' import { asyncMiddleware, oembedValidator } from '../middlewares'
import { asyncMiddleware } from '../middlewares/async' import { VideoModel } from '../models/video/video'
import { VideoInstance } from '../models'
const servicesRouter = express.Router() const servicesRouter = express.Router()
@ -21,7 +19,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function generateOEmbed (req: express.Request, res: express.Response, next: express.NextFunction) { function generateOEmbed (req: express.Request, res: express.Response, next: express.NextFunction) {
const video = res.locals.video as VideoInstance const video = res.locals.video as VideoModel
const webserverUrl = CONFIG.WEBSERVER.URL const webserverUrl = CONFIG.WEBSERVER.URL
const maxHeight = parseInt(req.query.maxheight, 10) const maxHeight = parseInt(req.query.maxheight, 10)
const maxWidth = parseInt(req.query.maxwidth, 10) const maxWidth = parseInt(req.query.maxwidth, 10)

View File

@ -1,6 +1,5 @@
import * as express from 'express' import * as express from 'express'
import * as cors from 'cors' import * as cors from 'cors'
import { import {
CONFIG, CONFIG,
STATIC_MAX_AGE, STATIC_MAX_AGE,

View File

@ -1,7 +1,7 @@
import * as express from 'express' import * as express from 'express'
import { asyncMiddleware } from '../middlewares/async' import { asyncMiddleware } from '../middlewares'
import { webfingerValidator } from '../middlewares/validators/webfinger' import { webfingerValidator } from '../middlewares/validators'
import { AccountInstance } from '../models/account/account-interface' import { AccountModel } from '../models/account/account'
const webfingerRouter = express.Router() const webfingerRouter = express.Router()
@ -19,7 +19,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function webfingerController (req: express.Request, res: express.Response, next: express.NextFunction) { function webfingerController (req: express.Request, res: express.Response, next: express.NextFunction) {
const account: AccountInstance = res.locals.account const account = res.locals.account as AccountModel
const json = { const json = {
subject: req.query.resource, subject: req.query.resource,

View File

@ -1,8 +1,8 @@
import { Activity } from '../../shared/models/activitypub/activity' import { ResultList } from '../../shared/models'
import { ResultList } from '../../shared/models/result-list.model' import { Activity } from '../../shared/models/activitypub'
import { AccountInstance } from '../models/account/account-interface' import { ACTIVITY_PUB } from '../initializers'
import { AccountModel } from '../models/account/account'
import { signObject } from './peertube-crypto' import { signObject } from './peertube-crypto'
import { ACTIVITY_PUB } from '../initializers/constants'
function activityPubContextify <T> (data: T) { function activityPubContextify <T> (data: T) {
return Object.assign(data,{ return Object.assign(data,{
@ -71,7 +71,7 @@ function activityPubCollectionPagination (url: string, page: any, result: Result
return orderedCollectionPagination return orderedCollectionPagination
} }
function buildSignedActivity (byAccount: AccountInstance, data: Object) { function buildSignedActivity (byAccount: AccountModel, data: Object) {
const activity = activityPubContextify(data) const activity = activityPubContextify(data)
return signObject(byAccount, activity) as Promise<Activity> return signObject(byAccount, activity) as Promise<Activity>

View File

@ -2,8 +2,7 @@ import * as Bluebird from 'bluebird'
import { Response } from 'express' import { Response } from 'express'
import 'express-validator' import 'express-validator'
import * as validator from 'validator' import * as validator from 'validator'
import { database as db } from '../../initializers' import { AccountModel } from '../../models/account/account'
import { AccountInstance } from '../../models'
import { isUserUsernameValid } from './users' import { isUserUsernameValid } from './users'
function isAccountNameValid (value: string) { function isAccountNameValid (value: string) {
@ -11,24 +10,24 @@ function isAccountNameValid (value: string) {
} }
function isAccountIdExist (id: number | string, res: Response) { function isAccountIdExist (id: number | string, res: Response) {
let promise: Bluebird<AccountInstance> let promise: Bluebird<AccountModel>
if (validator.isInt('' + id)) { if (validator.isInt('' + id)) {
promise = db.Account.load(+id) promise = AccountModel.load(+id)
} else { // UUID } else { // UUID
promise = db.Account.loadByUUID('' + id) promise = AccountModel.loadByUUID('' + id)
} }
return isAccountExist(promise, res) return isAccountExist(promise, res)
} }
function isLocalAccountNameExist (name: string, res: Response) { function isLocalAccountNameExist (name: string, res: Response) {
const promise = db.Account.loadLocalByName(name) const promise = AccountModel.loadLocalByName(name)
return isAccountExist(promise, res) return isAccountExist(promise, res)
} }
async function isAccountExist (p: Bluebird<AccountInstance>, res: Response) { async function isAccountExist (p: Bluebird<AccountModel>, res: Response) {
const account = await p const account = await p
if (!account) { if (!account) {

View File

@ -1,5 +1,5 @@
import * as validator from 'validator' import * as validator from 'validator'
import { CONSTRAINTS_FIELDS } from '../../../initializers/constants' import { CONSTRAINTS_FIELDS } from '../../../initializers'
import { isAccountNameValid } from '../accounts' import { isAccountNameValid } from '../accounts'
import { exists, isUUIDValid } from '../misc' import { exists, isUUIDValid } from '../misc'
import { isActivityPubUrlValid, isBaseActivityValid } from './misc' import { isActivityPubUrlValid, isBaseActivityValid } from './misc'

View File

@ -1,8 +1,9 @@
import * as validator from 'validator' import * as validator from 'validator'
import { Activity, ActivityType } from '../../../../shared/models/activitypub/activity' import { Activity, ActivityType } from '../../../../shared/models/activitypub'
import { isAccountAcceptActivityValid, isAccountDeleteActivityValid, isAccountFollowActivityValid } from './account' import { isAccountAcceptActivityValid, isAccountDeleteActivityValid, isAccountFollowActivityValid } from './account'
import { isAnnounceActivityValid } from './announce' import { isAnnounceActivityValid } from './announce'
import { isActivityPubUrlValid } from './misc' import { isActivityPubUrlValid } from './misc'
import { isDislikeActivityValid, isLikeActivityValid } from './rate'
import { isUndoActivityValid } from './undo' import { isUndoActivityValid } from './undo'
import { isVideoChannelCreateActivityValid, isVideoChannelDeleteActivityValid, isVideoChannelUpdateActivityValid } from './video-channels' import { isVideoChannelCreateActivityValid, isVideoChannelDeleteActivityValid, isVideoChannelUpdateActivityValid } from './video-channels'
import { import {
@ -12,7 +13,6 @@ import {
isVideoTorrentUpdateActivityValid isVideoTorrentUpdateActivityValid
} from './videos' } from './videos'
import { isViewActivityValid } from './view' import { isViewActivityValid } from './view'
import { isDislikeActivityValid, isLikeActivityValid } from './rate'
function isRootActivityValid (activity: any) { function isRootActivityValid (activity: any) {
return Array.isArray(activity['@context']) && return Array.isArray(activity['@context']) &&

View File

@ -1,7 +1,7 @@
import * as validator from 'validator' import * as validator from 'validator'
import { exists } from '../misc' import { CONSTRAINTS_FIELDS } from '../../../initializers'
import { isTestInstance } from '../../core-utils' import { isTestInstance } from '../../core-utils'
import { CONSTRAINTS_FIELDS } from '../../../initializers/constants' import { exists } from '../misc'
function isActivityPubUrlValid (url: string) { function isActivityPubUrlValid (url: string) {
const isURLOptions = { const isURLOptions = {

View File

@ -1,9 +0,0 @@
export * from './activitypub'
export * from './misc'
export * from './servers'
export * from './servers'
export * from './users'
export * from './accounts'
export * from './video-channels'
export * from './videos'
export * from './webfinger'

View File

@ -2,8 +2,8 @@ import * as express from 'express'
import 'express-validator' import 'express-validator'
import 'multer' import 'multer'
import * as validator from 'validator' import * as validator from 'validator'
import { CONSTRAINTS_FIELDS, database as db } from '../../initializers' import { CONSTRAINTS_FIELDS } from '../../initializers'
import { VideoChannelInstance } from '../../models' import { VideoChannelModel } from '../../models/video/video-channel'
import { exists } from './misc' import { exists } from './misc'
const VIDEO_CHANNELS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_CHANNELS const VIDEO_CHANNELS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEO_CHANNELS
@ -17,11 +17,11 @@ function isVideoChannelNameValid (value: string) {
} }
async function isVideoChannelExist (id: string, res: express.Response) { async function isVideoChannelExist (id: string, res: express.Response) {
let videoChannel: VideoChannelInstance let videoChannel: VideoChannelModel
if (validator.isInt(id)) { if (validator.isInt(id)) {
videoChannel = await db.VideoChannel.loadAndPopulateAccount(+id) videoChannel = await VideoChannelModel.loadAndPopulateAccount(+id)
} else { // UUID } else { // UUID
videoChannel = await db.VideoChannel.loadByUUIDAndPopulateAccount(id) videoChannel = await VideoChannelModel.loadByUUIDAndPopulateAccount(id)
} }
if (!videoChannel) { if (!videoChannel) {

View File

@ -4,10 +4,15 @@ import { values } from 'lodash'
import 'multer' import 'multer'
import * as validator from 'validator' import * as validator from 'validator'
import { VideoRateType } from '../../../shared' import { VideoRateType } from '../../../shared'
import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES, VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_RATE_TYPES } from '../../initializers' import {
import { VIDEO_PRIVACIES } from '../../initializers/constants' CONSTRAINTS_FIELDS,
import { database as db } from '../../initializers/database' VIDEO_CATEGORIES,
import { VideoInstance } from '../../models/video/video-interface' VIDEO_LANGUAGES,
VIDEO_LICENCES,
VIDEO_PRIVACIES,
VIDEO_RATE_TYPES
} from '../../initializers'
import { VideoModel } from '../../models/video/video'
import { exists, isArray } from './misc' import { exists, isArray } from './misc'
const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
@ -100,12 +105,12 @@ function isVideoFileSizeValid (value: string) {
} }
async function isVideoExist (id: string, res: Response) { async function isVideoExist (id: string, res: Response) {
let video: VideoInstance let video: VideoModel
if (validator.isInt(id)) { if (validator.isInt(id)) {
video = await db.Video.loadAndPopulateAccountAndServerAndTags(+id) video = await VideoModel.loadAndPopulateAccountAndServerAndTags(+id)
} else { // UUID } else { // UUID
video = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(id) video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(id)
} }
if (!video) { if (!video) {

View File

@ -1,6 +1,4 @@
import 'express-validator' import { CONFIG } from '../../initializers'
import 'multer'
import { CONFIG } from '../../initializers/constants'
import { exists } from './misc' import { exists } from './misc'
function isWebfingerResourceValid (value: string) { function isWebfingerResourceValid (value: string) {
@ -13,9 +11,7 @@ function isWebfingerResourceValid (value: string) {
const host = accountParts[1] const host = accountParts[1]
if (host !== CONFIG.WEBSERVER.HOST) return false return host === CONFIG.WEBSERVER.HOST
return true
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -1,5 +1,5 @@
import * as ffmpeg from 'fluent-ffmpeg' import * as ffmpeg from 'fluent-ffmpeg'
import { VideoResolution } from '../../shared/models/videos/video-resolution.enum' import { VideoResolution } from '../../shared/models/videos'
import { CONFIG } from '../initializers' import { CONFIG } from '../initializers'
function getVideoFileHeight (path: string) { function getVideoFileHeight (path: string) {

View File

@ -1,7 +1,6 @@
export * from './activitypub' export * from './activitypub'
export * from './core-utils' export * from './core-utils'
export * from './logger' export * from './logger'
export * from './custom-validators'
export * from './ffmpeg-utils' export * from './ffmpeg-utils'
export * from './database-utils' export * from './database-utils'
export * from './peertube-crypto' export * from './peertube-crypto'

View File

@ -2,7 +2,7 @@
import * as mkdirp from 'mkdirp' import * as mkdirp from 'mkdirp'
import * as path from 'path' import * as path from 'path'
import * as winston from 'winston' import * as winston from 'winston'
import { CONFIG } from '../initializers/constants' import { CONFIG } from '../initializers'
const label = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT const label = CONFIG.WEBSERVER.HOSTNAME + ':' + CONFIG.WEBSERVER.PORT

View File

@ -1,5 +1,5 @@
import { BCRYPT_SALT_SIZE, PRIVATE_RSA_KEY_SIZE } from '../initializers' import { BCRYPT_SALT_SIZE, PRIVATE_RSA_KEY_SIZE } from '../initializers'
import { AccountInstance } from '../models/account/account-interface' import { AccountModel } from '../models/account/account'
import { bcryptComparePromise, bcryptGenSaltPromise, bcryptHashPromise, createPrivateKey, getPublicKey } from './core-utils' import { bcryptComparePromise, bcryptGenSaltPromise, bcryptHashPromise, createPrivateKey, getPublicKey } from './core-utils'
import { jsig } from './custom-jsonld-signature' import { jsig } from './custom-jsonld-signature'
import { logger } from './logger' import { logger } from './logger'
@ -13,7 +13,7 @@ async function createPrivateAndPublicKeys () {
return { privateKey: key, publicKey } return { privateKey: key, publicKey }
} }
function isSignatureVerified (fromAccount: AccountInstance, signedDocument: object) { function isSignatureVerified (fromAccount: AccountModel, signedDocument: object) {
const publicKeyObject = { const publicKeyObject = {
'@context': jsig.SECURITY_CONTEXT_URL, '@context': jsig.SECURITY_CONTEXT_URL,
'@id': fromAccount.url, '@id': fromAccount.url,
@ -40,7 +40,7 @@ function isSignatureVerified (fromAccount: AccountInstance, signedDocument: obje
}) })
} }
function signObject (byAccount: AccountInstance, data: any) { function signObject (byAccount: AccountModel, data: any) {
const options = { const options = {
privateKeyPem: byAccount.privateKey, privateKeyPem: byAccount.privateKey,
creator: byAccount.url creator: byAccount.url

View File

@ -1,9 +1,10 @@
import * as express from 'express' import * as express from 'express'
import * as Sequelize from 'sequelize' import { Model } from 'sequelize-typescript'
import { ResultList } from '../../shared' import { ResultList } from '../../shared'
import { VideoResolution } from '../../shared/models/videos/video-resolution.enum' import { VideoResolution } from '../../shared/models/videos'
import { CONFIG, database as db } from '../initializers' import { CONFIG } from '../initializers'
import { AccountInstance } from '../models/account/account-interface' import { AccountModel } from '../models/account/account'
import { UserModel } from '../models/account/user'
import { pseudoRandomBytesPromise } from './core-utils' import { pseudoRandomBytesPromise } from './core-utils'
import { logger } from './logger' import { logger } from './logger'
@ -46,7 +47,7 @@ async function isSignupAllowed () {
return true return true
} }
const totalUsers = await db.User.countTotal() const totalUsers = await UserModel.countTotal()
return totalUsers < CONFIG.SIGNUP.LIMIT return totalUsers < CONFIG.SIGNUP.LIMIT
} }
@ -72,17 +73,17 @@ function computeResolutionsToTranscode (videoFileHeight: number) {
return resolutionsEnabled return resolutionsEnabled
} }
function resetSequelizeInstance (instance: Sequelize.Instance<any>, savedFields: object) { function resetSequelizeInstance (instance: Model<any>, savedFields: object) {
Object.keys(savedFields).forEach(key => { Object.keys(savedFields).forEach(key => {
const value = savedFields[key] const value = savedFields[key]
instance.set(key, value) instance.set(key, value)
}) })
} }
let serverAccount: AccountInstance let serverAccount: AccountModel
async function getServerAccount () { async function getServerAccount () {
if (serverAccount === undefined) { if (serverAccount === undefined) {
serverAccount = await db.Account.loadApplication() serverAccount = await AccountModel.loadApplication()
} }
if (!serverAccount) { if (!serverAccount) {

View File

@ -1,8 +1,8 @@
import * as WebFinger from 'webfinger.js' import * as WebFinger from 'webfinger.js'
import { WebFingerData } from '../../shared' import { WebFingerData } from '../../shared'
import { fetchRemoteAccount } from '../lib/activitypub/account' import { fetchRemoteAccount } from '../lib/activitypub'
import { isTestInstance } from './core-utils' import { isTestInstance } from './core-utils'
import { isActivityPubUrlValid } from './custom-validators' import { isActivityPubUrlValid } from './custom-validators/activitypub'
const webfinger = new WebFinger({ const webfinger = new WebFinger({
webfist_fallback: false, webfist_fallback: false,

View File

@ -1,8 +1,8 @@
import * as config from 'config' import * as config from 'config'
import { promisify0 } from '../helpers/core-utils' import { promisify0 } from '../helpers'
import { UserModel } from '../models/account/user-interface' import { UserModel } from '../models/account/user'
import { ApplicationModel } from '../models/application/application-interface' import { ApplicationModel } from '../models/application/application'
import { OAuthClientModel } from '../models/oauth/oauth-client-interface' import { OAuthClientModel } from '../models/oauth/oauth-client'
// Some checks on configuration files // Some checks on configuration files
function checkConfig () { function checkConfig () {
@ -57,22 +57,22 @@ async function checkFFmpeg (CONFIG: { TRANSCODING: { ENABLED: boolean } }) {
} }
// We get db by param to not import it in this file (import orders) // We get db by param to not import it in this file (import orders)
async function clientsExist (OAuthClient: OAuthClientModel) { async function clientsExist () {
const totalClients = await OAuthClient.countTotal() const totalClients = await OAuthClientModel.countTotal()
return totalClients !== 0 return totalClients !== 0
} }
// We get db by param to not import it in this file (import orders) // We get db by param to not import it in this file (import orders)
async function usersExist (User: UserModel) { async function usersExist () {
const totalUsers = await User.countTotal() const totalUsers = await UserModel.countTotal()
return totalUsers !== 0 return totalUsers !== 0
} }
// We get db by param to not import it in this file (import orders) // We get db by param to not import it in this file (import orders)
async function applicationExist (Application: ApplicationModel) { async function applicationExist () {
const totalApplication = await Application.countTotal() const totalApplication = await ApplicationModel.countTotal()
return totalApplication !== 0 return totalApplication !== 0
} }

View File

@ -1,16 +1,10 @@
import * as config from 'config' import * as config from 'config'
import { join } from 'path' import { join } from 'path'
import { JobCategory, JobState, VideoRateType } from '../../shared/models'
import { FollowState } from '../../shared/models/accounts'
import { VideoPrivacy } from '../../shared/models/videos'
// Do not use barrels, remain constants as independent as possible // Do not use barrels, remain constants as independent as possible
import { root, isTestInstance } from '../helpers/core-utils' import { isTestInstance, root } from '../helpers/core-utils'
import {
VideoRateType,
JobState,
JobCategory
} from '../../shared/models'
import { VideoPrivacy } from '../../shared/models/videos/video-privacy.enum'
import { FollowState } from '../../shared/models/accounts/follow.model'
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -1,72 +1,43 @@
import { join } from 'path' import { Sequelize as SequelizeTypescript } from 'sequelize-typescript'
import { flattenDepth } from 'lodash' import { isTestInstance } from '../helpers/core-utils'
require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string
import * as Sequelize from 'sequelize'
import { AvatarModel } from '../models/avatar'
import { CONFIG } from './constants'
// Do not use barrel, we need to load database first
import { logger } from '../helpers/logger' import { logger } from '../helpers/logger'
import { isTestInstance, readdirPromise } from '../helpers/core-utils'
import { VideoModel } from './../models/video/video-interface' import { AccountModel } from '../models/account/account'
import { VideoTagModel } from './../models/video/video-tag-interface' import { AccountFollowModel } from '../models/account/account-follow'
import { BlacklistedVideoModel } from './../models/video/video-blacklist-interface' import { AccountVideoRateModel } from '../models/account/account-video-rate'
import { VideoFileModel } from './../models/video/video-file-interface' import { UserModel } from '../models/account/user'
import { VideoAbuseModel } from './../models/video/video-abuse-interface' import { ApplicationModel } from '../models/application/application'
import { VideoChannelModel } from './../models/video/video-channel-interface' import { AvatarModel } from '../models/avatar/avatar'
import { UserModel } from '../models/account/user-interface' import { JobModel } from '../models/job/job'
import { AccountVideoRateModel } from '../models/account/account-video-rate-interface' import { OAuthClientModel } from '../models/oauth/oauth-client'
import { AccountFollowModel } from '../models/account/account-follow-interface' import { OAuthTokenModel } from '../models/oauth/oauth-token'
import { TagModel } from './../models/video/tag-interface' import { ServerModel } from '../models/server/server'
import { ServerModel } from '../models/server/server-interface' import { TagModel } from '../models/video/tag'
import { OAuthTokenModel } from './../models/oauth/oauth-token-interface' import { VideoModel } from '../models/video/video'
import { OAuthClientModel } from './../models/oauth/oauth-client-interface' import { VideoAbuseModel } from '../models/video/video-abuse'
import { JobModel } from './../models/job/job-interface' import { VideoBlacklistModel } from '../models/video/video-blacklist'
import { AccountModel } from './../models/account/account-interface' import { VideoChannelModel } from '../models/video/video-channel'
import { ApplicationModel } from './../models/application/application-interface' import { VideoChannelShareModel } from '../models/video/video-channel-share'
import { VideoChannelShareModel } from '../models/video/video-channel-share-interface' import { VideoFileModel } from '../models/video/video-file'
import { VideoShareModel } from '../models/video/video-share-interface' import { VideoShareModel } from '../models/video/video-share'
import { VideoTagModel } from '../models/video/video-tag'
import { CONFIG } from './constants'
require('pg').defaults.parseInt8 = true // Avoid BIGINT to be converted to string
const dbname = CONFIG.DATABASE.DBNAME const dbname = CONFIG.DATABASE.DBNAME
const username = CONFIG.DATABASE.USERNAME const username = CONFIG.DATABASE.USERNAME
const password = CONFIG.DATABASE.PASSWORD const password = CONFIG.DATABASE.PASSWORD
export type PeerTubeDatabase = { const sequelizeTypescript = new SequelizeTypescript({
sequelize?: Sequelize.Sequelize, database: dbname,
init?: (silent: boolean) => Promise<void>,
Application?: ApplicationModel,
Avatar?: AvatarModel,
Account?: AccountModel,
Job?: JobModel,
OAuthClient?: OAuthClientModel,
OAuthToken?: OAuthTokenModel,
Server?: ServerModel,
Tag?: TagModel,
AccountVideoRate?: AccountVideoRateModel,
AccountFollow?: AccountFollowModel,
User?: UserModel,
VideoAbuse?: VideoAbuseModel,
VideoChannel?: VideoChannelModel,
VideoChannelShare?: VideoChannelShareModel,
VideoShare?: VideoShareModel,
VideoFile?: VideoFileModel,
BlacklistedVideo?: BlacklistedVideoModel,
VideoTag?: VideoTagModel,
Video?: VideoModel
}
const database: PeerTubeDatabase = {}
const sequelize = new Sequelize(dbname, username, password, {
dialect: 'postgres', dialect: 'postgres',
host: CONFIG.DATABASE.HOSTNAME, username,
port: CONFIG.DATABASE.PORT, password,
modelPaths: [__dirname + '/models'],
benchmark: isTestInstance(), benchmark: isTestInstance(),
isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.SERIALIZABLE, isolationLevel: SequelizeTypescript.Transaction.ISOLATION_LEVELS.SERIALIZABLE,
operatorsAliases: false, operatorsAliases: false,
logging: (message: string, benchmark: number) => { logging: (message: string, benchmark: number) => {
if (process.env.NODE_DB_LOG === 'false') return if (process.env.NODE_DB_LOG === 'false') return
@ -79,34 +50,28 @@ const sequelize = new Sequelize(dbname, username, password, {
} }
}) })
database.sequelize = sequelize async function initDatabase (silent: boolean) {
sequelizeTypescript.addModels([
database.init = async (silent: boolean) => { ApplicationModel,
const modelDirectory = join(__dirname, '..', 'models') AvatarModel,
AccountModel,
const filePaths = await getModelFiles(modelDirectory) JobModel,
OAuthClientModel,
for (const filePath of filePaths) { OAuthTokenModel,
try { ServerModel,
const model = sequelize.import(filePath) TagModel,
AccountVideoRateModel,
database[model['name']] = model AccountFollowModel,
} catch (err) { UserModel,
logger.error('Cannot import database model %s.', filePath, err) VideoAbuseModel,
process.exit(0) VideoChannelModel,
} VideoChannelShareModel,
} VideoShareModel,
VideoFileModel,
for (const modelName of Object.keys(database)) { VideoBlacklistModel,
if ('associate' in database[modelName]) { VideoTagModel,
try { VideoModel
database[modelName].associate(database) ])
} catch (err) {
logger.error('Cannot associate model %s.', modelName, err)
process.exit(0)
}
}
}
if (!silent) logger.info('Database %s is ready.', dbname) if (!silent) logger.info('Database %s is ready.', dbname)
@ -116,51 +81,6 @@ database.init = async (silent: boolean) => {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
export { export {
database initDatabase,
} sequelizeTypescript
// ---------------------------------------------------------------------------
async function getModelFiles (modelDirectory: string) {
const files = await readdirPromise(modelDirectory)
const directories = files.filter(directory => {
// Find directories
if (
directory.endsWith('.js.map') ||
directory === 'index.js' || directory === 'index.ts' ||
directory === 'utils.js' || directory === 'utils.ts'
) return false
return true
})
const tasks: Promise<any>[] = []
// For each directory we read it and append model in the modelFilePaths array
for (const directory of directories) {
const modelDirectoryPath = join(modelDirectory, directory)
const promise = readdirPromise(modelDirectoryPath)
.then(files => {
const filteredFiles = files
.filter(file => {
if (
file === 'index.js' || file === 'index.ts' ||
file === 'utils.js' || file === 'utils.ts' ||
file.endsWith('-interface.js') || file.endsWith('-interface.ts') ||
file.endsWith('.js.map')
) return false
return true
})
.map(file => join(modelDirectoryPath, file))
return filteredFiles
})
tasks.push(promise)
}
const filteredFilesArray: string[][] = await Promise.all(tasks)
return flattenDepth<string>(filteredFilesArray, 1)
} }

View File

@ -1,16 +1,17 @@
import * as passwordGenerator from 'password-generator' import * as passwordGenerator from 'password-generator'
import { UserRole } from '../../shared' import { UserRole } from '../../shared'
import { logger, mkdirpPromise, rimrafPromise } from '../helpers' import { createPrivateAndPublicKeys, logger, mkdirpPromise, rimrafPromise } from '../helpers'
import { createUserAccountAndChannel } from '../lib' import { createLocalAccountWithoutKeys, createUserAccountAndChannel } from '../lib'
import { createLocalAccountWithoutKeys } from '../lib/user' import { UserModel } from '../models/account/user'
import { ApplicationModel } from '../models/application/application'
import { OAuthClientModel } from '../models/oauth/oauth-client'
import { applicationExist, clientsExist, usersExist } from './checker' import { applicationExist, clientsExist, usersExist } from './checker'
import { CACHE, CONFIG, LAST_MIGRATION_VERSION, SERVER_ACCOUNT_NAME } from './constants' import { CACHE, CONFIG, LAST_MIGRATION_VERSION, SERVER_ACCOUNT_NAME } from './constants'
import { database as db } from './database' import { sequelizeTypescript } from './database'
import { createPrivateAndPublicKeys } from '../helpers/peertube-crypto'
async function installApplication () { async function installApplication () {
try { try {
await db.sequelize.sync() await sequelizeTypescript.sync()
await removeCacheDirectories() await removeCacheDirectories()
await createDirectoriesIfNotExist() await createDirectoriesIfNotExist()
await createApplicationIfNotExist() await createApplicationIfNotExist()
@ -64,7 +65,7 @@ function createDirectoriesIfNotExist () {
} }
async function createOAuthClientIfNotExist () { async function createOAuthClientIfNotExist () {
const exist = await clientsExist(db.OAuthClient) const exist = await clientsExist()
// Nothing to do, clients already exist // Nothing to do, clients already exist
if (exist === true) return undefined if (exist === true) return undefined
@ -72,7 +73,7 @@ async function createOAuthClientIfNotExist () {
const id = passwordGenerator(32, false, /[a-z0-9]/) const id = passwordGenerator(32, false, /[a-z0-9]/)
const secret = passwordGenerator(32, false, /[a-zA-Z0-9]/) const secret = passwordGenerator(32, false, /[a-zA-Z0-9]/)
const client = db.OAuthClient.build({ const client = new OAuthClientModel({
clientId: id, clientId: id,
clientSecret: secret, clientSecret: secret,
grants: [ 'password', 'refresh_token' ], grants: [ 'password', 'refresh_token' ],
@ -87,7 +88,7 @@ async function createOAuthClientIfNotExist () {
} }
async function createOAuthAdminIfNotExist () { async function createOAuthAdminIfNotExist () {
const exist = await usersExist(db.User) const exist = await usersExist()
// Nothing to do, users already exist // Nothing to do, users already exist
if (exist === true) return undefined if (exist === true) return undefined
@ -120,7 +121,7 @@ async function createOAuthAdminIfNotExist () {
role, role,
videoQuota: -1 videoQuota: -1
} }
const user = db.User.build(userData) const user = new UserModel(userData)
await createUserAccountAndChannel(user, validatePassword) await createUserAccountAndChannel(user, validatePassword)
logger.info('Username: ' + username) logger.info('Username: ' + username)
@ -128,12 +129,12 @@ async function createOAuthAdminIfNotExist () {
} }
async function createApplicationIfNotExist () { async function createApplicationIfNotExist () {
const exist = await applicationExist(db.Application) const exist = await applicationExist()
// Nothing to do, application already exist // Nothing to do, application already exist
if (exist === true) return undefined if (exist === true) return undefined
logger.info('Creating Application table.') logger.info('Creating Application table.')
const applicationInstance = await db.Application.create({ migrationVersion: LAST_MIGRATION_VERSION }) const applicationInstance = await ApplicationModel.create({ migrationVersion: LAST_MIGRATION_VERSION })
logger.info('Creating application account.') logger.info('Creating application account.')

View File

@ -1,8 +1,7 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import * as Promise from 'bluebird' import * as Promise from 'bluebird'
import { stat } from 'fs' import { stat } from 'fs'
import { VideoModel } from '../../models/video/video'
import { VideoInstance } from '../../models'
function up (utils: { function up (utils: {
transaction: Sequelize.Transaction, transaction: Sequelize.Transaction,
@ -11,7 +10,7 @@ function up (utils: {
db: any db: any
}): Promise<void> { }): Promise<void> {
return utils.db.Video.listOwnedAndPopulateAuthorAndTags() return utils.db.Video.listOwnedAndPopulateAuthorAndTags()
.then((videos: VideoInstance[]) => { .then((videos: VideoModel[]) => {
const tasks: Promise<any>[] = [] const tasks: Promise<any>[] = []
videos.forEach(video => { videos.forEach(video => {

View File

@ -4,14 +4,14 @@ import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto'
import { shareVideoByServer } from '../../lib/activitypub/share' import { shareVideoByServer } from '../../lib/activitypub/share'
import { getVideoActivityPubUrl, getVideoChannelActivityPubUrl } from '../../lib/activitypub/url' import { getVideoActivityPubUrl, getVideoChannelActivityPubUrl } from '../../lib/activitypub/url'
import { createLocalAccountWithoutKeys } from '../../lib/user' import { createLocalAccountWithoutKeys } from '../../lib/user'
import { ApplicationModel } from '../../models/application/application'
import { JOB_CATEGORIES, SERVER_ACCOUNT_NAME } from '../constants' import { JOB_CATEGORIES, SERVER_ACCOUNT_NAME } from '../constants'
import { PeerTubeDatabase } from '../database'
async function up (utils: { async function up (utils: {
transaction: Sequelize.Transaction, transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface, queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize, sequelize: Sequelize.Sequelize,
db: PeerTubeDatabase db: any
}): Promise<void> { }): Promise<void> {
const q = utils.queryInterface const q = utils.queryInterface
const db = utils.db const db = utils.db
@ -65,7 +65,7 @@ async function up (utils: {
// Create application account // Create application account
{ {
const applicationInstance = await db.Application.findOne() const applicationInstance = await ApplicationModel.findOne()
const accountCreated = await createLocalAccountWithoutKeys(SERVER_ACCOUNT_NAME, null, applicationInstance.id, undefined) const accountCreated = await createLocalAccountWithoutKeys(SERVER_ACCOUNT_NAME, null, applicationInstance.id, undefined)
const { publicKey, privateKey } = await createPrivateAndPublicKeys() const { publicKey, privateKey } = await createPrivateAndPublicKeys()

View File

@ -1,11 +1,10 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import { PeerTubeDatabase } from '../database'
async function up (utils: { async function up (utils: {
transaction: Sequelize.Transaction, transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface, queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize, sequelize: Sequelize.Sequelize,
db: PeerTubeDatabase db: any
}): Promise<void> { }): Promise<void> {
await utils.queryInterface.removeColumn('Servers', 'email') await utils.queryInterface.removeColumn('Servers', 'email')
} }

View File

@ -1,11 +1,10 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import { PeerTubeDatabase } from '../database'
async function up (utils: { async function up (utils: {
transaction: Sequelize.Transaction, transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface, queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize, sequelize: Sequelize.Sequelize,
db: PeerTubeDatabase db: any
}): Promise<void> { }): Promise<void> {
await utils.queryInterface.removeColumn('Servers', 'publicKey') await utils.queryInterface.removeColumn('Servers', 'publicKey')
} }

View File

@ -1,11 +1,10 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import { PeerTubeDatabase } from '../database'
async function up (utils: { async function up (utils: {
transaction: Sequelize.Transaction, transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface, queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize, sequelize: Sequelize.Sequelize,
db: PeerTubeDatabase db: any
}): Promise<void> { }): Promise<void> {
await utils.db.Avatar.sync() await utils.db.Avatar.sync()

View File

@ -1,12 +1,11 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import { CONSTRAINTS_FIELDS } from '../constants' import { CONSTRAINTS_FIELDS } from '../constants'
import { PeerTubeDatabase } from '../database'
async function up (utils: { async function up (utils: {
transaction: Sequelize.Transaction, transaction: Sequelize.Transaction,
queryInterface: Sequelize.QueryInterface, queryInterface: Sequelize.QueryInterface,
sequelize: Sequelize.Sequelize, sequelize: Sequelize.Sequelize,
db: PeerTubeDatabase db: any
}): Promise<void> { }): Promise<void> {
{ {

View File

@ -1,19 +1,19 @@
import * as path from 'path' import * as path from 'path'
import { database as db } from './database'
import { LAST_MIGRATION_VERSION } from './constants'
import { logger, readdirPromise } from '../helpers' import { logger, readdirPromise } from '../helpers'
import { ApplicationModel } from '../models/application/application'
import { LAST_MIGRATION_VERSION } from './constants'
import { sequelizeTypescript } from './database'
async function migrate () { async function migrate () {
const tables = await db.sequelize.getQueryInterface().showAllTables() const tables = await sequelizeTypescript.getQueryInterface().showAllTables()
// No tables, we don't need to migrate anything // No tables, we don't need to migrate anything
// The installer will do that // The installer will do that
if (tables.length === 0) return if (tables.length === 0) return
let actualVersion = await db.Application.loadMigrationVersion() let actualVersion = await ApplicationModel.loadMigrationVersion()
if (actualVersion === null) { if (actualVersion === null) {
await db.Application.create({ migrationVersion: 0 }) await ApplicationModel.create({ migrationVersion: 0 })
actualVersion = 0 actualVersion = 0
} }
@ -78,17 +78,16 @@ async function executeMigration (actualVersion: number, entity: { version: strin
const migrationScript = require(path.join(__dirname, 'migrations', migrationScriptName)) const migrationScript = require(path.join(__dirname, 'migrations', migrationScriptName))
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
const options = { const options = {
transaction: t, transaction: t,
queryInterface: db.sequelize.getQueryInterface(), queryInterface: sequelizeTypescript.getQueryInterface(),
sequelize: db.sequelize, sequelize: sequelizeTypescript
db
} }
await migrationScript.up(options) await migrationScript.up(options)
// Update the new migration version // Update the new migration version
await db.Application.updateMigrationVersion(versionScript, t) await ApplicationModel.updateMigrationVersion(versionScript, t)
}) })
} }

View File

@ -1,17 +1,15 @@
import * as Bluebird from 'bluebird' import * as Bluebird from 'bluebird'
import * as url from 'url'
import { ActivityPubActor } from '../../../shared/models/activitypub/activitypub-actor'
import { isRemoteAccountValid } from '../../helpers/custom-validators/activitypub/account'
import { retryTransactionWrapper } from '../../helpers/database-utils'
import { logger } from '../../helpers/logger'
import { doRequest } from '../../helpers/requests'
import { ACTIVITY_PUB } from '../../initializers/constants'
import { database as db } from '../../initializers/database'
import { AccountInstance } from '../../models/account/account-interface'
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import * as url from 'url'
import { ActivityPubActor } from '../../../shared/models/activitypub'
import { doRequest, logger, retryTransactionWrapper } from '../../helpers'
import { isRemoteAccountValid } from '../../helpers/custom-validators/activitypub'
import { ACTIVITY_PUB, sequelizeTypescript } from '../../initializers'
import { AccountModel } from '../../models/account/account'
import { ServerModel } from '../../models/server/server'
async function getOrCreateAccountAndServer (accountUrl: string) { async function getOrCreateAccountAndServer (accountUrl: string) {
let account = await db.Account.loadByUrl(accountUrl) let account = await AccountModel.loadByUrl(accountUrl)
// We don't have this account in our database, fetch it on remote // We don't have this account in our database, fetch it on remote
if (!account) { if (!account) {
@ -28,11 +26,11 @@ async function getOrCreateAccountAndServer (accountUrl: string) {
return account return account
} }
function saveAccountAndServerIfNotExist (account: AccountInstance, t?: Transaction): Bluebird<AccountInstance> | Promise<AccountInstance> { function saveAccountAndServerIfNotExist (account: AccountModel, t?: Transaction): Bluebird<AccountModel> | Promise<AccountModel> {
if (t !== undefined) { if (t !== undefined) {
return save(t) return save(t)
} else { } else {
return db.sequelize.transaction(t => { return sequelizeTypescript.transaction(t => {
return save(t) return save(t)
}) })
} }
@ -49,7 +47,7 @@ function saveAccountAndServerIfNotExist (account: AccountInstance, t?: Transacti
}, },
transaction: t transaction: t
} }
const [ server ] = await db.Server.findOrCreate(serverOptions) const [ server ] = await ServerModel.findOrCreate(serverOptions)
// Save our new account in database // Save our new account in database
account.set('serverId', server.id) account.set('serverId', server.id)
@ -87,7 +85,7 @@ async function fetchRemoteAccount (accountUrl: string) {
const followersCount = await fetchAccountCount(accountJSON.followers) const followersCount = await fetchAccountCount(accountJSON.followers)
const followingCount = await fetchAccountCount(accountJSON.following) const followingCount = await fetchAccountCount(accountJSON.following)
const account = db.Account.build({ return new AccountModel({
uuid: accountJSON.uuid, uuid: accountJSON.uuid,
name: accountJSON.preferredUsername, name: accountJSON.preferredUsername,
url: accountJSON.url, url: accountJSON.url,
@ -101,8 +99,6 @@ async function fetchRemoteAccount (accountUrl: string) {
followersUrl: accountJSON.followers, followersUrl: accountJSON.followers,
followingUrl: accountJSON.following followingUrl: accountJSON.following
}) })
return account
} }
export { export {

View File

@ -1,8 +1,8 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { AccountInstance } from '../../models/account/account-interface' import { AccountModel } from '../../models/account/account'
import { activitypubHttpJobScheduler, ActivityPubHttpPayload } from '../jobs/activitypub-http-job-scheduler/activitypub-http-job-scheduler' import { activitypubHttpJobScheduler, ActivityPubHttpPayload } from '../jobs/activitypub-http-job-scheduler'
async function addFetchOutboxJob (account: AccountInstance, t: Transaction) { async function addFetchOutboxJob (account: AccountModel, t: Transaction) {
const jobPayload: ActivityPubHttpPayload = { const jobPayload: ActivityPubHttpPayload = {
uris: [ account.outboxUrl ] uris: [ account.outboxUrl ]
} }

View File

@ -1,18 +1,18 @@
import * as magnetUtil from 'magnet-uri' import * as magnetUtil from 'magnet-uri'
import { VideoTorrentObject } from '../../../../shared' import { VideoTorrentObject } from '../../../../shared'
import { VideoChannelObject } from '../../../../shared/models/activitypub/objects/video-channel-object' import { VideoChannelObject } from '../../../../shared/models/activitypub/objects'
import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum' import { VideoPrivacy } from '../../../../shared/models/videos'
import { doRequest } from '../../../helpers'
import { isVideoFileInfoHashValid } from '../../../helpers/custom-validators/videos' import { isVideoFileInfoHashValid } from '../../../helpers/custom-validators/videos'
import { doRequest } from '../../../helpers/requests' import { ACTIVITY_PUB, VIDEO_MIMETYPE_EXT } from '../../../initializers'
import { database as db } from '../../../initializers' import { AccountModel } from '../../../models/account/account'
import { ACTIVITY_PUB, VIDEO_MIMETYPE_EXT } from '../../../initializers/constants' import { VideoModel } from '../../../models/video/video'
import { AccountInstance } from '../../../models/account/account-interface' import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoChannelInstance } from '../../../models/video/video-channel-interface' import { VideoChannelShareModel } from '../../../models/video/video-channel-share'
import { VideoFileAttributes } from '../../../models/video/video-file-interface' import { VideoShareModel } from '../../../models/video/video-share'
import { VideoAttributes, VideoInstance } from '../../../models/video/video-interface'
import { getOrCreateAccountAndServer } from '../account' import { getOrCreateAccountAndServer } from '../account'
function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChannelObject, account: AccountInstance) { function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChannelObject, account: AccountModel) {
return { return {
name: videoChannelObject.name, name: videoChannelObject.name,
description: videoChannelObject.content, description: videoChannelObject.content,
@ -26,7 +26,7 @@ function videoChannelActivityObjectToDBAttributes (videoChannelObject: VideoChan
} }
async function videoActivityObjectToDBAttributes ( async function videoActivityObjectToDBAttributes (
videoChannel: VideoChannelInstance, videoChannel: VideoChannelModel,
videoObject: VideoTorrentObject, videoObject: VideoTorrentObject,
to: string[] = [], to: string[] = [],
cc: string[] = [] cc: string[] = []
@ -56,7 +56,7 @@ async function videoActivityObjectToDBAttributes (
description = videoObject.content description = videoObject.content
} }
const videoData: VideoAttributes = { return {
name: videoObject.name, name: videoObject.name,
uuid: videoObject.uuid, uuid: videoObject.uuid,
url: videoObject.id, url: videoObject.id,
@ -76,11 +76,9 @@ async function videoActivityObjectToDBAttributes (
remote: true, remote: true,
privacy privacy
} }
return videoData
} }
function videoFileActivityUrlToDBAttributes (videoCreated: VideoInstance, videoObject: VideoTorrentObject) { function videoFileActivityUrlToDBAttributes (videoCreated: VideoModel, videoObject: VideoTorrentObject) {
const mimeTypes = Object.keys(VIDEO_MIMETYPE_EXT) const mimeTypes = Object.keys(VIDEO_MIMETYPE_EXT)
const fileUrls = videoObject.url.filter(u => { const fileUrls = videoObject.url.filter(u => {
return mimeTypes.indexOf(u.mimeType) !== -1 && u.mimeType.startsWith('video/') return mimeTypes.indexOf(u.mimeType) !== -1 && u.mimeType.startsWith('video/')
@ -90,7 +88,7 @@ function videoFileActivityUrlToDBAttributes (videoCreated: VideoInstance, videoO
throw new Error('Cannot find video files for ' + videoCreated.url) throw new Error('Cannot find video files for ' + videoCreated.url)
} }
const attributes: VideoFileAttributes[] = [] const attributes = []
for (const fileUrl of fileUrls) { for (const fileUrl of fileUrls) {
// Fetch associated magnet uri // Fetch associated magnet uri
const magnet = videoObject.url.find(u => { const magnet = videoObject.url.find(u => {
@ -115,7 +113,7 @@ function videoFileActivityUrlToDBAttributes (videoCreated: VideoInstance, videoO
return attributes return attributes
} }
async function addVideoShares (instance: VideoInstance, shares: string[]) { async function addVideoShares (instance: VideoModel, shares: string[]) {
for (const share of shares) { for (const share of shares) {
// Fetch url // Fetch url
const json = await doRequest({ const json = await doRequest({
@ -132,14 +130,14 @@ async function addVideoShares (instance: VideoInstance, shares: string[]) {
videoId: instance.id videoId: instance.id
} }
await db.VideoShare.findOrCreate({ await VideoShareModel.findOrCreate({
where: entry, where: entry,
defaults: entry defaults: entry
}) })
} }
} }
async function addVideoChannelShares (instance: VideoChannelInstance, shares: string[]) { async function addVideoChannelShares (instance: VideoChannelModel, shares: string[]) {
for (const share of shares) { for (const share of shares) {
// Fetch url // Fetch url
const json = await doRequest({ const json = await doRequest({
@ -156,7 +154,7 @@ async function addVideoChannelShares (instance: VideoChannelInstance, shares: st
videoChannelId: instance.id videoChannelId: instance.id
} }
await db.VideoChannelShare.findOrCreate({ await VideoChannelShareModel.findOrCreate({
where: entry, where: entry,
defaults: entry defaults: entry
}) })

View File

@ -1,12 +1,12 @@
import { ActivityAccept } from '../../../../shared/models/activitypub/activity' import { ActivityAccept } from '../../../../shared/models/activitypub'
import { database as db } from '../../../initializers' import { AccountModel } from '../../../models/account/account'
import { AccountInstance } from '../../../models/account/account-interface' import { AccountFollowModel } from '../../../models/account/account-follow'
import { addFetchOutboxJob } from '../fetch' import { addFetchOutboxJob } from '../fetch'
async function processAcceptActivity (activity: ActivityAccept, inboxAccount?: AccountInstance) { async function processAcceptActivity (activity: ActivityAccept, inboxAccount?: AccountModel) {
if (inboxAccount === undefined) throw new Error('Need to accept on explicit inbox.') if (inboxAccount === undefined) throw new Error('Need to accept on explicit inbox.')
const targetAccount = await db.Account.loadByUrl(activity.actor) const targetAccount = await AccountModel.loadByUrl(activity.actor)
return processAccept(inboxAccount, targetAccount) return processAccept(inboxAccount, targetAccount)
} }
@ -19,8 +19,8 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function processAccept (account: AccountInstance, targetAccount: AccountInstance) { async function processAccept (account: AccountModel, targetAccount: AccountModel) {
const follow = await db.AccountFollow.loadByAccountAndTarget(account.id, targetAccount.id) const follow = await AccountFollowModel.loadByAccountAndTarget(account.id, targetAccount.id)
if (!follow) throw new Error('Cannot find associated follow.') if (!follow) throw new Error('Cannot find associated follow.')
follow.set('state', 'accepted') follow.set('state', 'accepted')

View File

@ -1,13 +1,15 @@
import * as Bluebird from 'bluebird' import * as Bluebird from 'bluebird'
import { VideoTorrentObject } from '../../../../shared' import { VideoTorrentObject } from '../../../../shared'
import { ActivityAdd } from '../../../../shared/models/activitypub/activity' import { ActivityAdd } from '../../../../shared/models/activitypub'
import { VideoRateType } from '../../../../shared/models/videos/video-rate.type' import { VideoRateType } from '../../../../shared/models/videos'
import { retryTransactionWrapper } from '../../../helpers/database-utils' import { logger, retryTransactionWrapper } from '../../../helpers'
import { logger } from '../../../helpers/logger' import { sequelizeTypescript } from '../../../initializers'
import { database as db } from '../../../initializers' import { AccountModel } from '../../../models/account/account'
import { AccountInstance } from '../../../models/account/account-interface' import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
import { VideoChannelInstance } from '../../../models/video/video-channel-interface' import { TagModel } from '../../../models/video/tag'
import { VideoInstance } from '../../../models/video/video-interface' import { VideoModel } from '../../../models/video/video'
import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoFileModel } from '../../../models/video/video-file'
import { getOrCreateAccountAndServer } from '../account' import { getOrCreateAccountAndServer } from '../account'
import { getOrCreateVideoChannel } from '../video-channels' import { getOrCreateVideoChannel } from '../video-channels'
import { generateThumbnailFromUrl } from '../videos' import { generateThumbnailFromUrl } from '../videos'
@ -37,9 +39,9 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function processAddVideo (account: AccountInstance, async function processAddVideo (account: AccountModel,
activity: ActivityAdd, activity: ActivityAdd,
videoChannel: VideoChannelInstance, videoChannel: VideoChannelModel,
videoToCreateData: VideoTorrentObject) { videoToCreateData: VideoTorrentObject) {
const options = { const options = {
arguments: [ account, activity, videoChannel, videoToCreateData ], arguments: [ account, activity, videoChannel, videoToCreateData ],
@ -64,24 +66,24 @@ async function processAddVideo (account: AccountInstance,
return video return video
} }
function addRemoteVideo (account: AccountInstance, function addRemoteVideo (account: AccountModel,
activity: ActivityAdd, activity: ActivityAdd,
videoChannel: VideoChannelInstance, videoChannel: VideoChannelModel,
videoToCreateData: VideoTorrentObject) { videoToCreateData: VideoTorrentObject) {
logger.debug('Adding remote video %s.', videoToCreateData.id) logger.debug('Adding remote video %s.', videoToCreateData.id)
return db.sequelize.transaction(async t => { return sequelizeTypescript.transaction(async t => {
const sequelizeOptions = { const sequelizeOptions = {
transaction: t transaction: t
} }
if (videoChannel.Account.id !== account.id) throw new Error('Video channel is not owned by this account.') if (videoChannel.Account.id !== account.id) throw new Error('Video channel is not owned by this account.')
const videoFromDatabase = await db.Video.loadByUUIDOrURL(videoToCreateData.uuid, videoToCreateData.id, t) const videoFromDatabase = await VideoModel.loadByUUIDOrURL(videoToCreateData.uuid, videoToCreateData.id, t)
if (videoFromDatabase) return videoFromDatabase if (videoFromDatabase) return videoFromDatabase
const videoData = await videoActivityObjectToDBAttributes(videoChannel, videoToCreateData, activity.to, activity.cc) const videoData = await videoActivityObjectToDBAttributes(videoChannel, videoToCreateData, activity.to, activity.cc)
const video = db.Video.build(videoData) const video = VideoModel.build(videoData)
// Don't block on request // Don't block on request
generateThumbnailFromUrl(video, videoToCreateData.icon) generateThumbnailFromUrl(video, videoToCreateData.icon)
@ -94,12 +96,12 @@ function addRemoteVideo (account: AccountInstance,
throw new Error('Cannot find valid files for video %s ' + videoToCreateData.url) throw new Error('Cannot find valid files for video %s ' + videoToCreateData.url)
} }
const tasks: Bluebird<any>[] = videoFileAttributes.map(f => db.VideoFile.create(f, { transaction: t })) const tasks: Bluebird<any>[] = videoFileAttributes.map(f => VideoFileModel.create(f, { transaction: t }))
await Promise.all(tasks) await Promise.all(tasks)
const tags = videoToCreateData.tag.map(t => t.name) const tags = videoToCreateData.tag.map(t => t.name)
const tagInstances = await db.Tag.findOrCreateTags(tags, t) const tagInstances = await TagModel.findOrCreateTags(tags, t)
await videoCreated.setTags(tagInstances, sequelizeOptions) await videoCreated.$set('Tags', tagInstances, sequelizeOptions)
logger.info('Remote video with uuid %s inserted.', videoToCreateData.uuid) logger.info('Remote video with uuid %s inserted.', videoToCreateData.uuid)
@ -107,13 +109,13 @@ function addRemoteVideo (account: AccountInstance,
}) })
} }
async function createRates (accountUrls: string[], video: VideoInstance, rate: VideoRateType) { async function createRates (accountUrls: string[], video: VideoModel, rate: VideoRateType) {
let rateCounts = 0 let rateCounts = 0
const tasks: Bluebird<any>[] = [] const tasks: Bluebird<any>[] = []
for (const accountUrl of accountUrls) { for (const accountUrl of accountUrls) {
const account = await getOrCreateAccountAndServer(accountUrl) const account = await getOrCreateAccountAndServer(accountUrl)
const p = db.AccountVideoRate const p = AccountVideoRateModel
.create({ .create({
videoId: video.id, videoId: video.id,
accountId: account.id, accountId: account.id,

View File

@ -1,10 +1,11 @@
import { ActivityAdd, ActivityAnnounce, ActivityCreate } from '../../../../shared/models/activitypub/activity' import { ActivityAdd, ActivityAnnounce, ActivityCreate } from '../../../../shared/models/activitypub'
import { retryTransactionWrapper } from '../../../helpers/database-utils' import { logger, retryTransactionWrapper } from '../../../helpers'
import { logger } from '../../../helpers/logger' import { sequelizeTypescript } from '../../../initializers'
import { database as db } from '../../../initializers/index' import { AccountModel } from '../../../models/account/account'
import { AccountInstance } from '../../../models/account/account-interface' import { VideoModel } from '../../../models/video/video'
import { VideoInstance } from '../../../models/index' import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoChannelInstance } from '../../../models/video/video-channel-interface' import { VideoChannelShareModel } from '../../../models/video/video-channel-share'
import { VideoShareModel } from '../../../models/video/video-share'
import { getOrCreateAccountAndServer } from '../account' import { getOrCreateAccountAndServer } from '../account'
import { forwardActivity } from '../send/misc' import { forwardActivity } from '../send/misc'
import { processAddActivity } from './process-add' import { processAddActivity } from './process-add'
@ -36,7 +37,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function processVideoChannelShare (accountAnnouncer: AccountInstance, activity: ActivityAnnounce) { function processVideoChannelShare (accountAnnouncer: AccountModel, activity: ActivityAnnounce) {
const options = { const options = {
arguments: [ accountAnnouncer, activity ], arguments: [ accountAnnouncer, activity ],
errorMessage: 'Cannot share the video channel with many retries.' errorMessage: 'Cannot share the video channel with many retries.'
@ -45,18 +46,18 @@ function processVideoChannelShare (accountAnnouncer: AccountInstance, activity:
return retryTransactionWrapper(shareVideoChannel, options) return retryTransactionWrapper(shareVideoChannel, options)
} }
async function shareVideoChannel (accountAnnouncer: AccountInstance, activity: ActivityAnnounce) { async function shareVideoChannel (accountAnnouncer: AccountModel, activity: ActivityAnnounce) {
const announcedActivity = activity.object as ActivityCreate const announcedActivity = activity.object as ActivityCreate
return db.sequelize.transaction(async t => { return sequelizeTypescript.transaction(async t => {
// Add share entry // Add share entry
const videoChannel: VideoChannelInstance = await processCreateActivity(announcedActivity) const videoChannel: VideoChannelModel = await processCreateActivity(announcedActivity)
const share = { const share = {
accountId: accountAnnouncer.id, accountId: accountAnnouncer.id,
videoChannelId: videoChannel.id videoChannelId: videoChannel.id
} }
const [ , created ] = await db.VideoChannelShare.findOrCreate({ const [ , created ] = await VideoChannelShareModel.findOrCreate({
where: share, where: share,
defaults: share, defaults: share,
transaction: t transaction: t
@ -72,7 +73,7 @@ async function shareVideoChannel (accountAnnouncer: AccountInstance, activity: A
}) })
} }
function processVideoShare (accountAnnouncer: AccountInstance, activity: ActivityAnnounce) { function processVideoShare (accountAnnouncer: AccountModel, activity: ActivityAnnounce) {
const options = { const options = {
arguments: [ accountAnnouncer, activity ], arguments: [ accountAnnouncer, activity ],
errorMessage: 'Cannot share the video with many retries.' errorMessage: 'Cannot share the video with many retries.'
@ -81,19 +82,19 @@ function processVideoShare (accountAnnouncer: AccountInstance, activity: Activit
return retryTransactionWrapper(shareVideo, options) return retryTransactionWrapper(shareVideo, options)
} }
function shareVideo (accountAnnouncer: AccountInstance, activity: ActivityAnnounce) { function shareVideo (accountAnnouncer: AccountModel, activity: ActivityAnnounce) {
const announcedActivity = activity.object as ActivityAdd const announcedActivity = activity.object as ActivityAdd
return db.sequelize.transaction(async t => { return sequelizeTypescript.transaction(async t => {
// Add share entry // Add share entry
const video: VideoInstance = await processAddActivity(announcedActivity) const video: VideoModel = await processAddActivity(announcedActivity)
const share = { const share = {
accountId: accountAnnouncer.id, accountId: accountAnnouncer.id,
videoId: video.id videoId: video.id
} }
const [ , created ] = await db.VideoShare.findOrCreate({ const [ , created ] = await VideoShareModel.findOrCreate({
where: share, where: share,
defaults: share, defaults: share,
transaction: t transaction: t

View File

@ -1,10 +1,12 @@
import { ActivityCreate, VideoChannelObject } from '../../../../shared' import { ActivityCreate, VideoChannelObject } from '../../../../shared'
import { DislikeObject } from '../../../../shared/models/activitypub/objects/dislike-object' import { DislikeObject, VideoAbuseObject, ViewObject } from '../../../../shared/models/activitypub/objects'
import { VideoAbuseObject } from '../../../../shared/models/activitypub/objects/video-abuse-object'
import { ViewObject } from '../../../../shared/models/activitypub/objects/view-object'
import { logger, retryTransactionWrapper } from '../../../helpers' import { logger, retryTransactionWrapper } from '../../../helpers'
import { database as db } from '../../../initializers' import { sequelizeTypescript } from '../../../initializers'
import { AccountInstance } from '../../../models/account/account-interface' import { AccountModel } from '../../../models/account/account'
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
import { VideoModel } from '../../../models/video/video'
import { VideoAbuseModel } from '../../../models/video/video-abuse'
import { VideoChannelModel } from '../../../models/video/video-channel'
import { getOrCreateAccountAndServer } from '../account' import { getOrCreateAccountAndServer } from '../account'
import { forwardActivity } from '../send/misc' import { forwardActivity } from '../send/misc'
import { getVideoChannelActivityPubUrl } from '../url' import { getVideoChannelActivityPubUrl } from '../url'
@ -37,7 +39,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function processCreateDislike (byAccount: AccountInstance, activity: ActivityCreate) { async function processCreateDislike (byAccount: AccountModel, activity: ActivityCreate) {
const options = { const options = {
arguments: [ byAccount, activity ], arguments: [ byAccount, activity ],
errorMessage: 'Cannot dislike the video with many retries.' errorMessage: 'Cannot dislike the video with many retries.'
@ -46,11 +48,11 @@ async function processCreateDislike (byAccount: AccountInstance, activity: Activ
return retryTransactionWrapper(createVideoDislike, options) return retryTransactionWrapper(createVideoDislike, options)
} }
function createVideoDislike (byAccount: AccountInstance, activity: ActivityCreate) { function createVideoDislike (byAccount: AccountModel, activity: ActivityCreate) {
const dislike = activity.object as DislikeObject const dislike = activity.object as DislikeObject
return db.sequelize.transaction(async t => { return sequelizeTypescript.transaction(async t => {
const video = await db.Video.loadByUrlAndPopulateAccount(dislike.object, t) const video = await VideoModel.loadByUrlAndPopulateAccount(dislike.object, t)
if (!video) throw new Error('Unknown video ' + dislike.object) if (!video) throw new Error('Unknown video ' + dislike.object)
const rate = { const rate = {
@ -58,7 +60,7 @@ function createVideoDislike (byAccount: AccountInstance, activity: ActivityCreat
videoId: video.id, videoId: video.id,
accountId: byAccount.id accountId: byAccount.id
} }
const [ , created ] = await db.AccountVideoRate.findOrCreate({ const [ , created ] = await AccountVideoRateModel.findOrCreate({
where: rate, where: rate,
defaults: rate, defaults: rate,
transaction: t transaction: t
@ -73,14 +75,14 @@ function createVideoDislike (byAccount: AccountInstance, activity: ActivityCreat
}) })
} }
async function processCreateView (byAccount: AccountInstance, activity: ActivityCreate) { async function processCreateView (byAccount: AccountModel, activity: ActivityCreate) {
const view = activity.object as ViewObject const view = activity.object as ViewObject
const video = await db.Video.loadByUrlAndPopulateAccount(view.object) const video = await VideoModel.loadByUrlAndPopulateAccount(view.object)
if (!video) throw new Error('Unknown video ' + view.object) if (!video) throw new Error('Unknown video ' + view.object)
const account = await db.Account.loadByUrl(view.actor) const account = await AccountModel.loadByUrl(view.actor)
if (!account) throw new Error('Unknown account ' + view.actor) if (!account) throw new Error('Unknown account ' + view.actor)
await video.increment('views') await video.increment('views')
@ -92,7 +94,7 @@ async function processCreateView (byAccount: AccountInstance, activity: Activity
} }
} }
async function processCreateVideoChannel (account: AccountInstance, videoChannelToCreateData: VideoChannelObject) { async function processCreateVideoChannel (account: AccountModel, videoChannelToCreateData: VideoChannelObject) {
const options = { const options = {
arguments: [ account, videoChannelToCreateData ], arguments: [ account, videoChannelToCreateData ],
errorMessage: 'Cannot insert the remote video channel with many retries.' errorMessage: 'Cannot insert the remote video channel with many retries.'
@ -107,15 +109,15 @@ async function processCreateVideoChannel (account: AccountInstance, videoChannel
return videoChannel return videoChannel
} }
function addRemoteVideoChannel (account: AccountInstance, videoChannelToCreateData: VideoChannelObject) { function addRemoteVideoChannel (account: AccountModel, videoChannelToCreateData: VideoChannelObject) {
logger.debug('Adding remote video channel "%s".', videoChannelToCreateData.uuid) logger.debug('Adding remote video channel "%s".', videoChannelToCreateData.uuid)
return db.sequelize.transaction(async t => { return sequelizeTypescript.transaction(async t => {
let videoChannel = await db.VideoChannel.loadByUUIDOrUrl(videoChannelToCreateData.uuid, videoChannelToCreateData.id, t) let videoChannel = await VideoChannelModel.loadByUUIDOrUrl(videoChannelToCreateData.uuid, videoChannelToCreateData.id, t)
if (videoChannel) return videoChannel if (videoChannel) return videoChannel
const videoChannelData = videoChannelActivityObjectToDBAttributes(videoChannelToCreateData, account) const videoChannelData = videoChannelActivityObjectToDBAttributes(videoChannelToCreateData, account)
videoChannel = db.VideoChannel.build(videoChannelData) videoChannel = new VideoChannelModel(videoChannelData)
videoChannel.url = getVideoChannelActivityPubUrl(videoChannel) videoChannel.url = getVideoChannelActivityPubUrl(videoChannel)
videoChannel = await videoChannel.save({ transaction: t }) videoChannel = await videoChannel.save({ transaction: t })
@ -125,7 +127,7 @@ function addRemoteVideoChannel (account: AccountInstance, videoChannelToCreateDa
}) })
} }
function processCreateVideoAbuse (account: AccountInstance, videoAbuseToCreateData: VideoAbuseObject) { function processCreateVideoAbuse (account: AccountModel, videoAbuseToCreateData: VideoAbuseObject) {
const options = { const options = {
arguments: [ account, videoAbuseToCreateData ], arguments: [ account, videoAbuseToCreateData ],
errorMessage: 'Cannot insert the remote video abuse with many retries.' errorMessage: 'Cannot insert the remote video abuse with many retries.'
@ -134,11 +136,11 @@ function processCreateVideoAbuse (account: AccountInstance, videoAbuseToCreateDa
return retryTransactionWrapper(addRemoteVideoAbuse, options) return retryTransactionWrapper(addRemoteVideoAbuse, options)
} }
function addRemoteVideoAbuse (account: AccountInstance, videoAbuseToCreateData: VideoAbuseObject) { function addRemoteVideoAbuse (account: AccountModel, videoAbuseToCreateData: VideoAbuseObject) {
logger.debug('Reporting remote abuse for video %s.', videoAbuseToCreateData.object) logger.debug('Reporting remote abuse for video %s.', videoAbuseToCreateData.object)
return db.sequelize.transaction(async t => { return sequelizeTypescript.transaction(async t => {
const video = await db.Video.loadByUrlAndPopulateAccount(videoAbuseToCreateData.object, t) const video = await VideoModel.loadByUrlAndPopulateAccount(videoAbuseToCreateData.object, t)
if (!video) { if (!video) {
logger.warn('Unknown video %s for remote video abuse.', videoAbuseToCreateData.object) logger.warn('Unknown video %s for remote video abuse.', videoAbuseToCreateData.object)
return undefined return undefined
@ -150,7 +152,7 @@ function addRemoteVideoAbuse (account: AccountInstance, videoAbuseToCreateData:
videoId: video.id videoId: video.id
} }
await db.VideoAbuse.create(videoAbuseData) await VideoAbuseModel.create(videoAbuseData)
logger.info('Remote abuse for video uuid %s created', videoAbuseToCreateData.object) logger.info('Remote abuse for video uuid %s created', videoAbuseToCreateData.object)
}) })

View File

@ -1,10 +1,9 @@
import { ActivityDelete } from '../../../../shared/models/activitypub/activity' import { ActivityDelete } from '../../../../shared/models/activitypub'
import { retryTransactionWrapper } from '../../../helpers/database-utils' import { logger, retryTransactionWrapper } from '../../../helpers'
import { logger } from '../../../helpers/logger' import { sequelizeTypescript } from '../../../initializers'
import { database as db } from '../../../initializers' import { AccountModel } from '../../../models/account/account'
import { AccountInstance } from '../../../models/account/account-interface' import { VideoModel } from '../../../models/video/video'
import { VideoChannelInstance } from '../../../models/video/video-channel-interface' import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoInstance } from '../../../models/video/video-interface'
import { getOrCreateAccountAndServer } from '../account' import { getOrCreateAccountAndServer } from '../account'
async function processDeleteActivity (activity: ActivityDelete) { async function processDeleteActivity (activity: ActivityDelete) {
@ -15,14 +14,14 @@ async function processDeleteActivity (activity: ActivityDelete) {
} }
{ {
let videoObject = await db.Video.loadByUrlAndPopulateAccount(activity.id) let videoObject = await VideoModel.loadByUrlAndPopulateAccount(activity.id)
if (videoObject !== undefined) { if (videoObject !== undefined) {
return processDeleteVideo(account, videoObject) return processDeleteVideo(account, videoObject)
} }
} }
{ {
let videoChannelObject = await db.VideoChannel.loadByUrl(activity.id) let videoChannelObject = await VideoChannelModel.loadByUrl(activity.id)
if (videoChannelObject !== undefined) { if (videoChannelObject !== undefined) {
return processDeleteVideoChannel(account, videoChannelObject) return processDeleteVideoChannel(account, videoChannelObject)
} }
@ -39,7 +38,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function processDeleteVideo (account: AccountInstance, videoToDelete: VideoInstance) { async function processDeleteVideo (account: AccountModel, videoToDelete: VideoModel) {
const options = { const options = {
arguments: [ account, videoToDelete ], arguments: [ account, videoToDelete ],
errorMessage: 'Cannot remove the remote video with many retries.' errorMessage: 'Cannot remove the remote video with many retries.'
@ -48,10 +47,10 @@ async function processDeleteVideo (account: AccountInstance, videoToDelete: Vide
await retryTransactionWrapper(deleteRemoteVideo, options) await retryTransactionWrapper(deleteRemoteVideo, options)
} }
async function deleteRemoteVideo (account: AccountInstance, videoToDelete: VideoInstance) { async function deleteRemoteVideo (account: AccountModel, videoToDelete: VideoModel) {
logger.debug('Removing remote video "%s".', videoToDelete.uuid) logger.debug('Removing remote video "%s".', videoToDelete.uuid)
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
if (videoToDelete.VideoChannel.Account.id !== account.id) { if (videoToDelete.VideoChannel.Account.id !== account.id) {
throw new Error('Account ' + account.url + ' does not own video channel ' + videoToDelete.VideoChannel.url) throw new Error('Account ' + account.url + ' does not own video channel ' + videoToDelete.VideoChannel.url)
} }
@ -62,7 +61,7 @@ async function deleteRemoteVideo (account: AccountInstance, videoToDelete: Video
logger.info('Remote video with uuid %s removed.', videoToDelete.uuid) logger.info('Remote video with uuid %s removed.', videoToDelete.uuid)
} }
async function processDeleteVideoChannel (account: AccountInstance, videoChannelToRemove: VideoChannelInstance) { async function processDeleteVideoChannel (account: AccountModel, videoChannelToRemove: VideoChannelModel) {
const options = { const options = {
arguments: [ account, videoChannelToRemove ], arguments: [ account, videoChannelToRemove ],
errorMessage: 'Cannot remove the remote video channel with many retries.' errorMessage: 'Cannot remove the remote video channel with many retries.'
@ -71,10 +70,10 @@ async function processDeleteVideoChannel (account: AccountInstance, videoChannel
await retryTransactionWrapper(deleteRemoteVideoChannel, options) await retryTransactionWrapper(deleteRemoteVideoChannel, options)
} }
async function deleteRemoteVideoChannel (account: AccountInstance, videoChannelToRemove: VideoChannelInstance) { async function deleteRemoteVideoChannel (account: AccountModel, videoChannelToRemove: VideoChannelModel) {
logger.debug('Removing remote video channel "%s".', videoChannelToRemove.uuid) logger.debug('Removing remote video channel "%s".', videoChannelToRemove.uuid)
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
if (videoChannelToRemove.Account.id !== account.id) { if (videoChannelToRemove.Account.id !== account.id) {
throw new Error('Account ' + account.url + ' does not own video channel ' + videoChannelToRemove.url) throw new Error('Account ' + account.url + ' does not own video channel ' + videoChannelToRemove.url)
} }
@ -85,7 +84,7 @@ async function deleteRemoteVideoChannel (account: AccountInstance, videoChannelT
logger.info('Remote video channel with uuid %s removed.', videoChannelToRemove.uuid) logger.info('Remote video channel with uuid %s removed.', videoChannelToRemove.uuid)
} }
async function processDeleteAccount (accountToRemove: AccountInstance) { async function processDeleteAccount (accountToRemove: AccountModel) {
const options = { const options = {
arguments: [ accountToRemove ], arguments: [ accountToRemove ],
errorMessage: 'Cannot remove the remote account with many retries.' errorMessage: 'Cannot remove the remote account with many retries.'
@ -94,10 +93,10 @@ async function processDeleteAccount (accountToRemove: AccountInstance) {
await retryTransactionWrapper(deleteRemoteAccount, options) await retryTransactionWrapper(deleteRemoteAccount, options)
} }
async function deleteRemoteAccount (accountToRemove: AccountInstance) { async function deleteRemoteAccount (accountToRemove: AccountModel) {
logger.debug('Removing remote account "%s".', accountToRemove.uuid) logger.debug('Removing remote account "%s".', accountToRemove.uuid)
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
await accountToRemove.destroy({ transaction: t }) await accountToRemove.destroy({ transaction: t })
}) })

View File

@ -1,10 +1,10 @@
import { ActivityFollow } from '../../../../shared/models/activitypub/activity' import { ActivityFollow } from '../../../../shared/models/activitypub'
import { retryTransactionWrapper } from '../../../helpers' import { logger, retryTransactionWrapper } from '../../../helpers'
import { database as db } from '../../../initializers' import { sequelizeTypescript } from '../../../initializers'
import { AccountInstance } from '../../../models/account/account-interface' import { AccountModel } from '../../../models/account/account'
import { logger } from '../../../helpers/logger' import { AccountFollowModel } from '../../../models/account/account-follow'
import { sendAccept } from '../send/send-accept'
import { getOrCreateAccountAndServer } from '../account' import { getOrCreateAccountAndServer } from '../account'
import { sendAccept } from '../send'
async function processFollowActivity (activity: ActivityFollow) { async function processFollowActivity (activity: ActivityFollow) {
const activityObject = activity.object const activityObject = activity.object
@ -21,7 +21,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function processFollow (account: AccountInstance, targetAccountURL: string) { function processFollow (account: AccountModel, targetAccountURL: string) {
const options = { const options = {
arguments: [ account, targetAccountURL ], arguments: [ account, targetAccountURL ],
errorMessage: 'Cannot follow with many retries.' errorMessage: 'Cannot follow with many retries.'
@ -30,14 +30,14 @@ function processFollow (account: AccountInstance, targetAccountURL: string) {
return retryTransactionWrapper(follow, options) return retryTransactionWrapper(follow, options)
} }
async function follow (account: AccountInstance, targetAccountURL: string) { async function follow (account: AccountModel, targetAccountURL: string) {
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
const targetAccount = await db.Account.loadByUrl(targetAccountURL, t) const targetAccount = await AccountModel.loadByUrl(targetAccountURL, t)
if (!targetAccount) throw new Error('Unknown account') if (!targetAccount) throw new Error('Unknown account')
if (targetAccount.isOwned() === false) throw new Error('This is not a local account.') if (targetAccount.isOwned() === false) throw new Error('This is not a local account.')
const [ accountFollow ] = await db.AccountFollow.findOrCreate({ const [ accountFollow ] = await AccountFollowModel.findOrCreate({
where: { where: {
accountId: account.id, accountId: account.id,
targetAccountId: targetAccount.id targetAccountId: targetAccount.id

View File

@ -1,7 +1,9 @@
import { ActivityLike } from '../../../../shared/models/activitypub/activity' import { ActivityLike } from '../../../../shared/models/activitypub'
import { retryTransactionWrapper } from '../../../helpers/database-utils' import { retryTransactionWrapper } from '../../../helpers'
import { database as db } from '../../../initializers' import { sequelizeTypescript } from '../../../initializers'
import { AccountInstance } from '../../../models/account/account-interface' import { AccountModel } from '../../../models/account/account'
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
import { VideoModel } from '../../../models/video/video'
import { getOrCreateAccountAndServer } from '../account' import { getOrCreateAccountAndServer } from '../account'
import { forwardActivity } from '../send/misc' import { forwardActivity } from '../send/misc'
@ -19,7 +21,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function processLikeVideo (byAccount: AccountInstance, activity: ActivityLike) { async function processLikeVideo (byAccount: AccountModel, activity: ActivityLike) {
const options = { const options = {
arguments: [ byAccount, activity ], arguments: [ byAccount, activity ],
errorMessage: 'Cannot like the video with many retries.' errorMessage: 'Cannot like the video with many retries.'
@ -28,11 +30,11 @@ async function processLikeVideo (byAccount: AccountInstance, activity: ActivityL
return retryTransactionWrapper(createVideoLike, options) return retryTransactionWrapper(createVideoLike, options)
} }
function createVideoLike (byAccount: AccountInstance, activity: ActivityLike) { function createVideoLike (byAccount: AccountModel, activity: ActivityLike) {
const videoUrl = activity.object const videoUrl = activity.object
return db.sequelize.transaction(async t => { return sequelizeTypescript.transaction(async t => {
const video = await db.Video.loadByUrlAndPopulateAccount(videoUrl) const video = await VideoModel.loadByUrlAndPopulateAccount(videoUrl)
if (!video) throw new Error('Unknown video ' + videoUrl) if (!video) throw new Error('Unknown video ' + videoUrl)
@ -41,7 +43,7 @@ function createVideoLike (byAccount: AccountInstance, activity: ActivityLike) {
videoId: video.id, videoId: video.id,
accountId: byAccount.id accountId: byAccount.id
} }
const [ , created ] = await db.AccountVideoRate.findOrCreate({ const [ , created ] = await AccountVideoRateModel.findOrCreate({
where: rate, where: rate,
defaults: rate, defaults: rate,
transaction: t transaction: t

View File

@ -1,8 +1,11 @@
import { ActivityFollow, ActivityLike, ActivityUndo } from '../../../../shared/models/activitypub/activity' import { ActivityFollow, ActivityLike, ActivityUndo } from '../../../../shared/models/activitypub'
import { DislikeObject } from '../../../../shared/models/activitypub/objects/dislike-object' import { DislikeObject } from '../../../../shared/models/activitypub/objects'
import { retryTransactionWrapper } from '../../../helpers/database-utils' import { logger, retryTransactionWrapper } from '../../../helpers'
import { logger } from '../../../helpers/logger' import { sequelizeTypescript } from '../../../initializers'
import { database as db } from '../../../initializers' import { AccountModel } from '../../../models/account/account'
import { AccountFollowModel } from '../../../models/account/account-follow'
import { AccountVideoRateModel } from '../../../models/account/account-video-rate'
import { VideoModel } from '../../../models/video/video'
import { forwardActivity } from '../send/misc' import { forwardActivity } from '../send/misc'
async function processUndoActivity (activity: ActivityUndo) { async function processUndoActivity (activity: ActivityUndo) {
@ -41,14 +44,14 @@ function processUndoLike (actor: string, activity: ActivityUndo) {
function undoLike (actor: string, activity: ActivityUndo) { function undoLike (actor: string, activity: ActivityUndo) {
const likeActivity = activity.object as ActivityLike const likeActivity = activity.object as ActivityLike
return db.sequelize.transaction(async t => { return sequelizeTypescript.transaction(async t => {
const byAccount = await db.Account.loadByUrl(actor, t) const byAccount = await AccountModel.loadByUrl(actor, t)
if (!byAccount) throw new Error('Unknown account ' + actor) if (!byAccount) throw new Error('Unknown account ' + actor)
const video = await db.Video.loadByUrlAndPopulateAccount(likeActivity.object, t) const video = await VideoModel.loadByUrlAndPopulateAccount(likeActivity.object, t)
if (!video) throw new Error('Unknown video ' + likeActivity.actor) if (!video) throw new Error('Unknown video ' + likeActivity.actor)
const rate = await db.AccountVideoRate.load(byAccount.id, video.id, t) const rate = await AccountVideoRateModel.load(byAccount.id, video.id, t)
if (!rate) throw new Error(`Unknown rate by account ${byAccount.id} for video ${video.id}.`) if (!rate) throw new Error(`Unknown rate by account ${byAccount.id} for video ${video.id}.`)
await rate.destroy({ transaction: t }) await rate.destroy({ transaction: t })
@ -74,14 +77,14 @@ function processUndoDislike (actor: string, activity: ActivityUndo) {
function undoDislike (actor: string, activity: ActivityUndo) { function undoDislike (actor: string, activity: ActivityUndo) {
const dislike = activity.object.object as DislikeObject const dislike = activity.object.object as DislikeObject
return db.sequelize.transaction(async t => { return sequelizeTypescript.transaction(async t => {
const byAccount = await db.Account.loadByUrl(actor, t) const byAccount = await AccountModel.loadByUrl(actor, t)
if (!byAccount) throw new Error('Unknown account ' + actor) if (!byAccount) throw new Error('Unknown account ' + actor)
const video = await db.Video.loadByUrlAndPopulateAccount(dislike.object, t) const video = await VideoModel.loadByUrlAndPopulateAccount(dislike.object, t)
if (!video) throw new Error('Unknown video ' + dislike.actor) if (!video) throw new Error('Unknown video ' + dislike.actor)
const rate = await db.AccountVideoRate.load(byAccount.id, video.id, t) const rate = await AccountVideoRateModel.load(byAccount.id, video.id, t)
if (!rate) throw new Error(`Unknown rate by account ${byAccount.id} for video ${video.id}.`) if (!rate) throw new Error(`Unknown rate by account ${byAccount.id} for video ${video.id}.`)
await rate.destroy({ transaction: t }) await rate.destroy({ transaction: t })
@ -105,10 +108,10 @@ function processUndoFollow (actor: string, followActivity: ActivityFollow) {
} }
function undoFollow (actor: string, followActivity: ActivityFollow) { function undoFollow (actor: string, followActivity: ActivityFollow) {
return db.sequelize.transaction(async t => { return sequelizeTypescript.transaction(async t => {
const follower = await db.Account.loadByUrl(actor, t) const follower = await AccountModel.loadByUrl(actor, t)
const following = await db.Account.loadByUrl(followActivity.object, t) const following = await AccountModel.loadByUrl(followActivity.object, t)
const accountFollow = await db.AccountFollow.loadByAccountAndTarget(follower.id, following.id, t) const accountFollow = await AccountFollowModel.loadByAccountAndTarget(follower.id, following.id, t)
if (!accountFollow) throw new Error(`'Unknown account follow ${follower.id} -> ${following.id}.`) if (!accountFollow) throw new Error(`'Unknown account follow ${follower.id} -> ${following.id}.`)

View File

@ -1,12 +1,13 @@
import * as Bluebird from 'bluebird' import * as Bluebird from 'bluebird'
import { VideoChannelObject, VideoTorrentObject } from '../../../../shared' import { VideoChannelObject, VideoTorrentObject } from '../../../../shared'
import { ActivityUpdate } from '../../../../shared/models/activitypub/activity' import { ActivityUpdate } from '../../../../shared/models/activitypub'
import { retryTransactionWrapper } from '../../../helpers/database-utils' import { logger, resetSequelizeInstance, retryTransactionWrapper } from '../../../helpers'
import { logger } from '../../../helpers/logger' import { sequelizeTypescript } from '../../../initializers'
import { resetSequelizeInstance } from '../../../helpers/utils' import { AccountModel } from '../../../models/account/account'
import { database as db } from '../../../initializers' import { TagModel } from '../../../models/video/tag'
import { AccountInstance } from '../../../models/account/account-interface' import { VideoModel } from '../../../models/video/video'
import { VideoInstance } from '../../../models/video/video-interface' import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoFileModel } from '../../../models/video/video-file'
import { getOrCreateAccountAndServer } from '../account' import { getOrCreateAccountAndServer } from '../account'
import { videoActivityObjectToDBAttributes, videoFileActivityUrlToDBAttributes } from './misc' import { videoActivityObjectToDBAttributes, videoFileActivityUrlToDBAttributes } from './misc'
@ -30,7 +31,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function processUpdateVideo (account: AccountInstance, video: VideoTorrentObject) { function processUpdateVideo (account: AccountModel, video: VideoTorrentObject) {
const options = { const options = {
arguments: [ account, video ], arguments: [ account, video ],
errorMessage: 'Cannot update the remote video with many retries' errorMessage: 'Cannot update the remote video with many retries'
@ -39,18 +40,18 @@ function processUpdateVideo (account: AccountInstance, video: VideoTorrentObject
return retryTransactionWrapper(updateRemoteVideo, options) return retryTransactionWrapper(updateRemoteVideo, options)
} }
async function updateRemoteVideo (account: AccountInstance, videoAttributesToUpdate: VideoTorrentObject) { async function updateRemoteVideo (account: AccountModel, videoAttributesToUpdate: VideoTorrentObject) {
logger.debug('Updating remote video "%s".', videoAttributesToUpdate.uuid) logger.debug('Updating remote video "%s".', videoAttributesToUpdate.uuid)
let videoInstance: VideoInstance let videoInstance: VideoModel
let videoFieldsSave: object let videoFieldsSave: object
try { try {
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
const sequelizeOptions = { const sequelizeOptions = {
transaction: t transaction: t
} }
const videoInstance = await db.Video.loadByUrlAndPopulateAccount(videoAttributesToUpdate.id, t) const videoInstance = await VideoModel.loadByUrlAndPopulateAccount(videoAttributesToUpdate.id, t)
if (!videoInstance) throw new Error('Video ' + videoAttributesToUpdate.id + ' not found.') if (!videoInstance) throw new Error('Video ' + videoAttributesToUpdate.id + ' not found.')
if (videoInstance.VideoChannel.Account.id !== account.id) { if (videoInstance.VideoChannel.Account.id !== account.id) {
@ -81,12 +82,12 @@ async function updateRemoteVideo (account: AccountInstance, videoAttributesToUpd
await Promise.all(videoFileDestroyTasks) await Promise.all(videoFileDestroyTasks)
const videoFileAttributes = videoFileActivityUrlToDBAttributes(videoInstance, videoAttributesToUpdate) const videoFileAttributes = videoFileActivityUrlToDBAttributes(videoInstance, videoAttributesToUpdate)
const tasks: Bluebird<any>[] = videoFileAttributes.map(f => db.VideoFile.create(f)) const tasks: Bluebird<any>[] = videoFileAttributes.map(f => VideoFileModel.create(f))
await Promise.all(tasks) await Promise.all(tasks)
const tags = videoAttributesToUpdate.tag.map(t => t.name) const tags = videoAttributesToUpdate.tag.map(t => t.name)
const tagInstances = await db.Tag.findOrCreateTags(tags, t) const tagInstances = await TagModel.findOrCreateTags(tags, t)
await videoInstance.setTags(tagInstances, sequelizeOptions) await videoInstance.$set('Tags', tagInstances, sequelizeOptions)
}) })
logger.info('Remote video with uuid %s updated', videoAttributesToUpdate.uuid) logger.info('Remote video with uuid %s updated', videoAttributesToUpdate.uuid)
@ -101,7 +102,7 @@ async function updateRemoteVideo (account: AccountInstance, videoAttributesToUpd
} }
} }
async function processUpdateVideoChannel (account: AccountInstance, videoChannel: VideoChannelObject) { async function processUpdateVideoChannel (account: AccountModel, videoChannel: VideoChannelObject) {
const options = { const options = {
arguments: [ account, videoChannel ], arguments: [ account, videoChannel ],
errorMessage: 'Cannot update the remote video channel with many retries.' errorMessage: 'Cannot update the remote video channel with many retries.'
@ -110,13 +111,13 @@ async function processUpdateVideoChannel (account: AccountInstance, videoChannel
await retryTransactionWrapper(updateRemoteVideoChannel, options) await retryTransactionWrapper(updateRemoteVideoChannel, options)
} }
async function updateRemoteVideoChannel (account: AccountInstance, videoChannel: VideoChannelObject) { async function updateRemoteVideoChannel (account: AccountModel, videoChannel: VideoChannelObject) {
logger.debug('Updating remote video channel "%s".', videoChannel.uuid) logger.debug('Updating remote video channel "%s".', videoChannel.uuid)
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
const sequelizeOptions = { transaction: t } const sequelizeOptions = { transaction: t }
const videoChannelInstance = await db.VideoChannel.loadByUrl(videoChannel.id) const videoChannelInstance = await VideoChannelModel.loadByUrl(videoChannel.id)
if (!videoChannelInstance) throw new Error('Video ' + videoChannel.id + ' not found.') if (!videoChannelInstance) throw new Error('Video ' + videoChannel.id + ' not found.')
if (videoChannelInstance.Account.id !== account.id) { if (videoChannelInstance.Account.id !== account.id) {

View File

@ -1,6 +1,6 @@
import { Activity, ActivityType } from '../../../../shared/models/activitypub/activity' import { Activity, ActivityType } from '../../../../shared/models/activitypub'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers'
import { AccountInstance } from '../../../models/account/account-interface' import { AccountModel } from '../../../models/account/account'
import { processAcceptActivity } from './process-accept' import { processAcceptActivity } from './process-accept'
import { processAddActivity } from './process-add' import { processAddActivity } from './process-add'
import { processAnnounceActivity } from './process-announce' import { processAnnounceActivity } from './process-announce'
@ -11,7 +11,7 @@ import { processLikeActivity } from './process-like'
import { processUndoActivity } from './process-undo' import { processUndoActivity } from './process-undo'
import { processUpdateActivity } from './process-update' import { processUpdateActivity } from './process-update'
const processActivity: { [ P in ActivityType ]: (activity: Activity, inboxAccount?: AccountInstance) => Promise<any> } = { const processActivity: { [ P in ActivityType ]: (activity: Activity, inboxAccount?: AccountModel) => Promise<any> } = {
Create: processCreateActivity, Create: processCreateActivity,
Add: processAddActivity, Add: processAddActivity,
Update: processUpdateActivity, Update: processUpdateActivity,
@ -23,7 +23,7 @@ const processActivity: { [ P in ActivityType ]: (activity: Activity, inboxAccoun
Like: processLikeActivity Like: processLikeActivity
} }
async function processActivities (activities: Activity[], signatureAccount?: AccountInstance, inboxAccount?: AccountInstance) { async function processActivities (activities: Activity[], signatureAccount?: AccountModel, inboxAccount?: AccountModel) {
for (const activity of activities) { for (const activity of activities) {
// When we fetch remote data, we don't have signature // When we fetch remote data, we don't have signature
if (signatureAccount && activity.actor !== signatureAccount.url) { if (signatureAccount && activity.actor !== signatureAccount.url) {

View File

@ -1,19 +1,19 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { Activity } from '../../../../shared/models/activitypub/activity' import { Activity } from '../../../../shared/models/activitypub'
import { logger } from '../../../helpers/logger' import { logger } from '../../../helpers'
import { ACTIVITY_PUB, database as db } from '../../../initializers' import { ACTIVITY_PUB } from '../../../initializers'
import { AccountInstance } from '../../../models/account/account-interface' import { AccountModel } from '../../../models/account/account'
import { VideoChannelInstance } from '../../../models/index' import { AccountFollowModel } from '../../../models/account/account-follow'
import { VideoInstance } from '../../../models/video/video-interface' import { VideoModel } from '../../../models/video/video'
import { import { VideoChannelModel } from '../../../models/video/video-channel'
activitypubHttpJobScheduler, import { VideoChannelShareModel } from '../../../models/video/video-channel-share'
ActivityPubHttpPayload import { VideoShareModel } from '../../../models/video/video-share'
} from '../../jobs/activitypub-http-job-scheduler/activitypub-http-job-scheduler' import { activitypubHttpJobScheduler, ActivityPubHttpPayload } from '../../jobs/activitypub-http-job-scheduler'
async function forwardActivity ( async function forwardActivity (
activity: Activity, activity: Activity,
t: Transaction, t: Transaction,
followersException: AccountInstance[] = [] followersException: AccountModel[] = []
) { ) {
const to = activity.to || [] const to = activity.to || []
const cc = activity.cc || [] const cc = activity.cc || []
@ -25,7 +25,7 @@ async function forwardActivity (
} }
} }
const toAccountFollowers = await db.Account.listByFollowersUrls(followersUrls, t) const toAccountFollowers = await AccountModel.listByFollowersUrls(followersUrls, t)
const uris = await computeFollowerUris(toAccountFollowers, followersException, t) const uris = await computeFollowerUris(toAccountFollowers, followersException, t)
if (uris.length === 0) { if (uris.length === 0) {
@ -45,10 +45,10 @@ async function forwardActivity (
async function broadcastToFollowers ( async function broadcastToFollowers (
data: any, data: any,
byAccount: AccountInstance, byAccount: AccountModel,
toAccountFollowers: AccountInstance[], toAccountFollowers: AccountModel[],
t: Transaction, t: Transaction,
followersException: AccountInstance[] = [] followersException: AccountModel[] = []
) { ) {
const uris = await computeFollowerUris(toAccountFollowers, followersException, t) const uris = await computeFollowerUris(toAccountFollowers, followersException, t)
if (uris.length === 0) { if (uris.length === 0) {
@ -67,7 +67,7 @@ async function broadcastToFollowers (
return activitypubHttpJobScheduler.createJob(t, 'activitypubHttpBroadcastHandler', jobPayload) return activitypubHttpJobScheduler.createJob(t, 'activitypubHttpBroadcastHandler', jobPayload)
} }
async function unicastTo (data: any, byAccount: AccountInstance, toAccountUrl: string, t: Transaction) { async function unicastTo (data: any, byAccount: AccountModel, toAccountUrl: string, t: Transaction) {
logger.debug('Creating unicast job.', { uri: toAccountUrl }) logger.debug('Creating unicast job.', { uri: toAccountUrl })
const jobPayload: ActivityPubHttpPayload = { const jobPayload: ActivityPubHttpPayload = {
@ -79,42 +79,42 @@ async function unicastTo (data: any, byAccount: AccountInstance, toAccountUrl: s
return activitypubHttpJobScheduler.createJob(t, 'activitypubHttpUnicastHandler', jobPayload) return activitypubHttpJobScheduler.createJob(t, 'activitypubHttpUnicastHandler', jobPayload)
} }
function getOriginVideoAudience (video: VideoInstance, accountsInvolvedInVideo: AccountInstance[]) { function getOriginVideoAudience (video: VideoModel, accountsInvolvedInVideo: AccountModel[]) {
return { return {
to: [ video.VideoChannel.Account.url ], to: [ video.VideoChannel.Account.url ],
cc: accountsInvolvedInVideo.map(a => a.followersUrl) cc: accountsInvolvedInVideo.map(a => a.followersUrl)
} }
} }
function getOriginVideoChannelAudience (videoChannel: VideoChannelInstance, accountsInvolved: AccountInstance[]) { function getOriginVideoChannelAudience (videoChannel: VideoChannelModel, accountsInvolved: AccountModel[]) {
return { return {
to: [ videoChannel.Account.url ], to: [ videoChannel.Account.url ],
cc: accountsInvolved.map(a => a.followersUrl) cc: accountsInvolved.map(a => a.followersUrl)
} }
} }
function getObjectFollowersAudience (accountsInvolvedInObject: AccountInstance[]) { function getObjectFollowersAudience (accountsInvolvedInObject: AccountModel[]) {
return { return {
to: accountsInvolvedInObject.map(a => a.followersUrl), to: accountsInvolvedInObject.map(a => a.followersUrl),
cc: [] cc: []
} }
} }
async function getAccountsInvolvedInVideo (video: VideoInstance, t: Transaction) { async function getAccountsInvolvedInVideo (video: VideoModel, t: Transaction) {
const accountsToForwardView = await db.VideoShare.loadAccountsByShare(video.id, t) const accountsToForwardView = await VideoShareModel.loadAccountsByShare(video.id, t)
accountsToForwardView.push(video.VideoChannel.Account) accountsToForwardView.push(video.VideoChannel.Account)
return accountsToForwardView return accountsToForwardView
} }
async function getAccountsInvolvedInVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { async function getAccountsInvolvedInVideoChannel (videoChannel: VideoChannelModel, t: Transaction) {
const accountsToForwardView = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id, t) const accountsToForwardView = await VideoChannelShareModel.loadAccountsByShare(videoChannel.id, t)
accountsToForwardView.push(videoChannel.Account) accountsToForwardView.push(videoChannel.Account)
return accountsToForwardView return accountsToForwardView
} }
async function getAudience (accountSender: AccountInstance, t: Transaction, isPublic = true) { async function getAudience (accountSender: AccountModel, t: Transaction, isPublic = true) {
const followerInboxUrls = await accountSender.getFollowerSharedInboxUrls(t) const followerInboxUrls = await accountSender.getFollowerSharedInboxUrls(t)
// Thanks Mastodon: https://github.com/tootsuite/mastodon/blob/master/app/lib/activitypub/tag_manager.rb#L47 // Thanks Mastodon: https://github.com/tootsuite/mastodon/blob/master/app/lib/activitypub/tag_manager.rb#L47
@ -132,14 +132,12 @@ async function getAudience (accountSender: AccountInstance, t: Transaction, isPu
return { to, cc } return { to, cc }
} }
async function computeFollowerUris (toAccountFollower: AccountInstance[], followersException: AccountInstance[], t: Transaction) { async function computeFollowerUris (toAccountFollower: AccountModel[], followersException: AccountModel[], t: Transaction) {
const toAccountFollowerIds = toAccountFollower.map(a => a.id) const toAccountFollowerIds = toAccountFollower.map(a => a.id)
const result = await db.AccountFollow.listAcceptedFollowerSharedInboxUrls(toAccountFollowerIds, t) const result = await AccountFollowModel.listAcceptedFollowerSharedInboxUrls(toAccountFollowerIds, t)
const followersSharedInboxException = followersException.map(f => f.sharedInboxUrl) const followersSharedInboxException = followersException.map(f => f.sharedInboxUrl)
const uris = result.data.filter(sharedInbox => followersSharedInboxException.indexOf(sharedInbox) === -1) return result.data.filter(sharedInbox => followersSharedInboxException.indexOf(sharedInbox) === -1)
return uris
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -1,11 +1,11 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { ActivityAccept } from '../../../../shared/models/activitypub/activity' import { ActivityAccept } from '../../../../shared/models/activitypub'
import { AccountInstance } from '../../../models' import { AccountModel } from '../../../models/account/account'
import { AccountFollowInstance } from '../../../models/account/account-follow-interface' import { AccountFollowModel } from '../../../models/account/account-follow'
import { unicastTo } from './misc'
import { getAccountFollowAcceptActivityPubUrl } from '../url' import { getAccountFollowAcceptActivityPubUrl } from '../url'
import { unicastTo } from './misc'
async function sendAccept (accountFollow: AccountFollowInstance, t: Transaction) { async function sendAccept (accountFollow: AccountFollowModel, t: Transaction) {
const follower = accountFollow.AccountFollower const follower = accountFollow.AccountFollower
const me = accountFollow.AccountFollowing const me = accountFollow.AccountFollowing
@ -23,7 +23,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function acceptActivityData (url: string, byAccount: AccountInstance) { function acceptActivityData (url: string, byAccount: AccountModel) {
const activity: ActivityAccept = { const activity: ActivityAccept = {
type: 'Accept', type: 'Accept',
id: url, id: url,

View File

@ -1,10 +1,11 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { ActivityAdd } from '../../../../shared/models/activitypub/activity' import { ActivityAdd } from '../../../../shared/models/activitypub'
import { VideoPrivacy } from '../../../../shared/models/videos/video-privacy.enum' import { VideoPrivacy } from '../../../../shared/models/videos'
import { AccountInstance, VideoInstance } from '../../../models' import { AccountModel } from '../../../models/account/account'
import { VideoModel } from '../../../models/video/video'
import { broadcastToFollowers, getAudience } from './misc' import { broadcastToFollowers, getAudience } from './misc'
async function sendAddVideo (video: VideoInstance, t: Transaction) { async function sendAddVideo (video: VideoModel, t: Transaction) {
const byAccount = video.VideoChannel.Account const byAccount = video.VideoChannel.Account
const videoObject = video.toActivityPubObject() const videoObject = video.toActivityPubObject()
@ -15,16 +16,17 @@ async function sendAddVideo (video: VideoInstance, t: Transaction) {
async function addActivityData ( async function addActivityData (
url: string, url: string,
byAccount: AccountInstance, byAccount: AccountModel,
video: VideoInstance, video: VideoModel,
target: string, target: string,
object: any, object: any,
t: Transaction t: Transaction
) { ): Promise<ActivityAdd> {
const videoPublic = video.privacy === VideoPrivacy.PUBLIC const videoPublic = video.privacy === VideoPrivacy.PUBLIC
const { to, cc } = await getAudience(byAccount, t, videoPublic) const { to, cc } = await getAudience(byAccount, t, videoPublic)
const activity: ActivityAdd = {
return {
type: 'Add', type: 'Add',
id: url, id: url,
actor: byAccount.url, actor: byAccount.url,
@ -33,8 +35,6 @@ async function addActivityData (
object, object,
target target
} }
return activity
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -1,8 +1,9 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { ActivityAdd } from '../../../../shared/index' import { ActivityAdd } from '../../../../shared/index'
import { ActivityAnnounce, ActivityAudience, ActivityCreate } from '../../../../shared/models/activitypub/activity' import { ActivityAnnounce, ActivityAudience, ActivityCreate } from '../../../../shared/models/activitypub'
import { AccountInstance, VideoInstance } from '../../../models' import { AccountModel } from '../../../models/account/account'
import { VideoChannelInstance } from '../../../models/video/video-channel-interface' import { VideoModel } from '../../../models/video/video'
import { VideoChannelModel } from '../../../models/video/video-channel'
import { getAnnounceActivityPubUrl } from '../url' import { getAnnounceActivityPubUrl } from '../url'
import { import {
broadcastToFollowers, broadcastToFollowers,
@ -17,7 +18,7 @@ import {
import { addActivityData } from './send-add' import { addActivityData } from './send-add'
import { createActivityData } from './send-create' import { createActivityData } from './send-create'
async function buildVideoAnnounceToFollowers (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function buildVideoAnnounceToFollowers (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const url = getAnnounceActivityPubUrl(video.url, byAccount) const url = getAnnounceActivityPubUrl(video.url, byAccount)
const videoChannel = video.VideoChannel const videoChannel = video.VideoChannel
@ -25,18 +26,16 @@ async function buildVideoAnnounceToFollowers (byAccount: AccountInstance, video:
const accountsToForwardView = await getAccountsInvolvedInVideo(video, t) const accountsToForwardView = await getAccountsInvolvedInVideo(video, t)
const audience = getObjectFollowersAudience(accountsToForwardView) const audience = getObjectFollowersAudience(accountsToForwardView)
const data = await announceActivityData(url, byAccount, announcedActivity, t, audience) return announceActivityData(url, byAccount, announcedActivity, t, audience)
return data
} }
async function sendVideoAnnounceToFollowers (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendVideoAnnounceToFollowers (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const data = await buildVideoAnnounceToFollowers(byAccount, video, t) const data = await buildVideoAnnounceToFollowers(byAccount, video, t)
return broadcastToFollowers(data, byAccount, [ byAccount ], t) return broadcastToFollowers(data, byAccount, [ byAccount ], t)
} }
async function sendVideoAnnounceToOrigin (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendVideoAnnounceToOrigin (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const url = getAnnounceActivityPubUrl(video.url, byAccount) const url = getAnnounceActivityPubUrl(video.url, byAccount)
const videoChannel = video.VideoChannel const videoChannel = video.VideoChannel
@ -49,24 +48,22 @@ async function sendVideoAnnounceToOrigin (byAccount: AccountInstance, video: Vid
return unicastTo(data, byAccount, videoChannel.Account.sharedInboxUrl, t) return unicastTo(data, byAccount, videoChannel.Account.sharedInboxUrl, t)
} }
async function buildVideoChannelAnnounceToFollowers (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Transaction) { async function buildVideoChannelAnnounceToFollowers (byAccount: AccountModel, videoChannel: VideoChannelModel, t: Transaction) {
const url = getAnnounceActivityPubUrl(videoChannel.url, byAccount) const url = getAnnounceActivityPubUrl(videoChannel.url, byAccount)
const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject(), t) const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject(), t)
const accountsToForwardView = await getAccountsInvolvedInVideoChannel(videoChannel, t) const accountsToForwardView = await getAccountsInvolvedInVideoChannel(videoChannel, t)
const audience = getObjectFollowersAudience(accountsToForwardView) const audience = getObjectFollowersAudience(accountsToForwardView)
const data = await announceActivityData(url, byAccount, announcedActivity, t, audience) return announceActivityData(url, byAccount, announcedActivity, t, audience)
return data
} }
async function sendVideoChannelAnnounceToFollowers (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Transaction) { async function sendVideoChannelAnnounceToFollowers (byAccount: AccountModel, videoChannel: VideoChannelModel, t: Transaction) {
const data = await buildVideoChannelAnnounceToFollowers(byAccount, videoChannel, t) const data = await buildVideoChannelAnnounceToFollowers(byAccount, videoChannel, t)
return broadcastToFollowers(data, byAccount, [ byAccount ], t) return broadcastToFollowers(data, byAccount, [ byAccount ], t)
} }
async function sendVideoChannelAnnounceToOrigin (byAccount: AccountInstance, videoChannel: VideoChannelInstance, t: Transaction) { async function sendVideoChannelAnnounceToOrigin (byAccount: AccountModel, videoChannel: VideoChannelModel, t: Transaction) {
const url = getAnnounceActivityPubUrl(videoChannel.url, byAccount) const url = getAnnounceActivityPubUrl(videoChannel.url, byAccount)
const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject(), t) const announcedActivity = await createActivityData(url, videoChannel.Account, videoChannel.toActivityPubObject(), t)
@ -79,16 +76,16 @@ async function sendVideoChannelAnnounceToOrigin (byAccount: AccountInstance, vid
async function announceActivityData ( async function announceActivityData (
url: string, url: string,
byAccount: AccountInstance, byAccount: AccountModel,
object: ActivityCreate | ActivityAdd, object: ActivityCreate | ActivityAdd,
t: Transaction, t: Transaction,
audience?: ActivityAudience audience?: ActivityAudience
) { ): Promise<ActivityAnnounce> {
if (!audience) { if (!audience) {
audience = await getAudience(byAccount, t) audience = await getAudience(byAccount, t)
} }
const activity: ActivityAnnounce = { return {
type: 'Announce', type: 'Announce',
to: audience.to, to: audience.to,
cc: audience.cc, cc: audience.cc,
@ -96,8 +93,6 @@ async function announceActivityData (
actor: byAccount.url, actor: byAccount.url,
object object
} }
return activity
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -1,8 +1,10 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { ActivityAudience, ActivityCreate } from '../../../../shared/models/activitypub/activity' import { ActivityAudience, ActivityCreate } from '../../../../shared/models/activitypub'
import { getServerAccount } from '../../../helpers/utils' import { getServerAccount } from '../../../helpers'
import { AccountInstance, VideoChannelInstance, VideoInstance } from '../../../models' import { AccountModel } from '../../../models/account/account'
import { VideoAbuseInstance } from '../../../models/video/video-abuse-interface' import { VideoModel } from '../../../models/video/video'
import { VideoAbuseModel } from '../../../models/video/video-abuse'
import { VideoChannelModel } from '../../../models/video/video-channel'
import { getVideoAbuseActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoViewActivityPubUrl } from '../url' import { getVideoAbuseActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoViewActivityPubUrl } from '../url'
import { import {
broadcastToFollowers, broadcastToFollowers,
@ -13,7 +15,7 @@ import {
unicastTo unicastTo
} from './misc' } from './misc'
async function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { async function sendCreateVideoChannel (videoChannel: VideoChannelModel, t: Transaction) {
const byAccount = videoChannel.Account const byAccount = videoChannel.Account
const videoChannelObject = videoChannel.toActivityPubObject() const videoChannelObject = videoChannel.toActivityPubObject()
@ -22,7 +24,7 @@ async function sendCreateVideoChannel (videoChannel: VideoChannelInstance, t: Tr
return broadcastToFollowers(data, byAccount, [ byAccount ], t) return broadcastToFollowers(data, byAccount, [ byAccount ], t)
} }
async function sendVideoAbuse (byAccount: AccountInstance, videoAbuse: VideoAbuseInstance, video: VideoInstance, t: Transaction) { async function sendVideoAbuse (byAccount: AccountModel, videoAbuse: VideoAbuseModel, video: VideoModel, t: Transaction) {
const url = getVideoAbuseActivityPubUrl(videoAbuse) const url = getVideoAbuseActivityPubUrl(videoAbuse)
const audience = { to: [ video.VideoChannel.Account.url ], cc: [] } const audience = { to: [ video.VideoChannel.Account.url ], cc: [] }
@ -31,7 +33,7 @@ async function sendVideoAbuse (byAccount: AccountInstance, videoAbuse: VideoAbus
return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t) return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
} }
async function sendCreateViewToOrigin (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendCreateViewToOrigin (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const url = getVideoViewActivityPubUrl(byAccount, video) const url = getVideoViewActivityPubUrl(byAccount, video)
const viewActivity = createViewActivityData(byAccount, video) const viewActivity = createViewActivityData(byAccount, video)
@ -42,7 +44,7 @@ async function sendCreateViewToOrigin (byAccount: AccountInstance, video: VideoI
return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t) return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
} }
async function sendCreateViewToVideoFollowers (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendCreateViewToVideoFollowers (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const url = getVideoViewActivityPubUrl(byAccount, video) const url = getVideoViewActivityPubUrl(byAccount, video)
const viewActivity = createViewActivityData(byAccount, video) const viewActivity = createViewActivityData(byAccount, video)
@ -56,7 +58,7 @@ async function sendCreateViewToVideoFollowers (byAccount: AccountInstance, video
return broadcastToFollowers(data, serverAccount, accountsToForwardView, t, followersException) return broadcastToFollowers(data, serverAccount, accountsToForwardView, t, followersException)
} }
async function sendCreateDislikeToOrigin (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendCreateDislikeToOrigin (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const url = getVideoDislikeActivityPubUrl(byAccount, video) const url = getVideoDislikeActivityPubUrl(byAccount, video)
const dislikeActivity = createDislikeActivityData(byAccount, video) const dislikeActivity = createDislikeActivityData(byAccount, video)
@ -67,7 +69,7 @@ async function sendCreateDislikeToOrigin (byAccount: AccountInstance, video: Vid
return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t) return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
} }
async function sendCreateDislikeToVideoFollowers (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendCreateDislikeToVideoFollowers (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const url = getVideoDislikeActivityPubUrl(byAccount, video) const url = getVideoDislikeActivityPubUrl(byAccount, video)
const dislikeActivity = createDislikeActivityData(byAccount, video) const dislikeActivity = createDislikeActivityData(byAccount, video)
@ -79,12 +81,18 @@ async function sendCreateDislikeToVideoFollowers (byAccount: AccountInstance, vi
return broadcastToFollowers(data, byAccount, accountsToForwardView, t, followersException) return broadcastToFollowers(data, byAccount, accountsToForwardView, t, followersException)
} }
async function createActivityData (url: string, byAccount: AccountInstance, object: any, t: Transaction, audience?: ActivityAudience) { async function createActivityData (
url: string,
byAccount: AccountModel,
object: any,
t: Transaction,
audience?: ActivityAudience
): Promise<ActivityCreate> {
if (!audience) { if (!audience) {
audience = await getAudience(byAccount, t) audience = await getAudience(byAccount, t)
} }
const activity: ActivityCreate = { return {
type: 'Create', type: 'Create',
id: url, id: url,
actor: byAccount.url, actor: byAccount.url,
@ -92,18 +100,14 @@ async function createActivityData (url: string, byAccount: AccountInstance, obje
cc: audience.cc, cc: audience.cc,
object object
} }
return activity
} }
function createDislikeActivityData (byAccount: AccountInstance, video: VideoInstance) { function createDislikeActivityData (byAccount: AccountModel, video: VideoModel) {
const obj = { return {
type: 'Dislike', type: 'Dislike',
actor: byAccount.url, actor: byAccount.url,
object: video.url object: video.url
} }
return obj
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -121,12 +125,10 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function createViewActivityData (byAccount: AccountInstance, video: VideoInstance) { function createViewActivityData (byAccount: AccountModel, video: VideoModel) {
const obj = { return {
type: 'View', type: 'View',
actor: byAccount.url, actor: byAccount.url,
object: video.url object: video.url
} }
return obj
} }

View File

@ -1,32 +1,35 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { ActivityDelete } from '../../../../shared/models/activitypub/activity' import { ActivityDelete } from '../../../../shared/models/activitypub'
import { database as db } from '../../../initializers' import { AccountModel } from '../../../models/account/account'
import { AccountInstance, VideoChannelInstance, VideoInstance } from '../../../models' import { VideoModel } from '../../../models/video/video'
import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoChannelShareModel } from '../../../models/video/video-channel-share'
import { VideoShareModel } from '../../../models/video/video-share'
import { broadcastToFollowers } from './misc' import { broadcastToFollowers } from './misc'
async function sendDeleteVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { async function sendDeleteVideoChannel (videoChannel: VideoChannelModel, t: Transaction) {
const byAccount = videoChannel.Account const byAccount = videoChannel.Account
const data = deleteActivityData(videoChannel.url, byAccount) const data = deleteActivityData(videoChannel.url, byAccount)
const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id, t) const accountsInvolved = await VideoChannelShareModel.loadAccountsByShare(videoChannel.id, t)
accountsInvolved.push(byAccount) accountsInvolved.push(byAccount)
return broadcastToFollowers(data, byAccount, accountsInvolved, t) return broadcastToFollowers(data, byAccount, accountsInvolved, t)
} }
async function sendDeleteVideo (video: VideoInstance, t: Transaction) { async function sendDeleteVideo (video: VideoModel, t: Transaction) {
const byAccount = video.VideoChannel.Account const byAccount = video.VideoChannel.Account
const data = deleteActivityData(video.url, byAccount) const data = deleteActivityData(video.url, byAccount)
const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id, t) const accountsInvolved = await VideoShareModel.loadAccountsByShare(video.id, t)
accountsInvolved.push(byAccount) accountsInvolved.push(byAccount)
return broadcastToFollowers(data, byAccount, accountsInvolved, t) return broadcastToFollowers(data, byAccount, accountsInvolved, t)
} }
async function sendDeleteAccount (account: AccountInstance, t: Transaction) { async function sendDeleteAccount (account: AccountModel, t: Transaction) {
const data = deleteActivityData(account.url, account) const data = deleteActivityData(account.url, account)
return broadcastToFollowers(data, account, [ account ], t) return broadcastToFollowers(data, account, [ account ], t)
@ -42,12 +45,10 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function deleteActivityData (url: string, byAccount: AccountInstance) { function deleteActivityData (url: string, byAccount: AccountModel): ActivityDelete {
const activity: ActivityDelete = { return {
type: 'Delete', type: 'Delete',
id: url, id: url,
actor: byAccount.url actor: byAccount.url
} }
return activity
} }

View File

@ -1,11 +1,11 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { ActivityFollow } from '../../../../shared/models/activitypub/activity' import { ActivityFollow } from '../../../../shared/models/activitypub'
import { AccountInstance } from '../../../models' import { AccountModel } from '../../../models/account/account'
import { AccountFollowInstance } from '../../../models/account/account-follow-interface' import { AccountFollowModel } from '../../../models/account/account-follow'
import { getAccountFollowActivityPubUrl } from '../url' import { getAccountFollowActivityPubUrl } from '../url'
import { unicastTo } from './misc' import { unicastTo } from './misc'
function sendFollow (accountFollow: AccountFollowInstance, t: Transaction) { function sendFollow (accountFollow: AccountFollowModel, t: Transaction) {
const me = accountFollow.AccountFollower const me = accountFollow.AccountFollower
const following = accountFollow.AccountFollowing const following = accountFollow.AccountFollowing
@ -15,15 +15,13 @@ function sendFollow (accountFollow: AccountFollowInstance, t: Transaction) {
return unicastTo(data, me, following.inboxUrl, t) return unicastTo(data, me, following.inboxUrl, t)
} }
function followActivityData (url: string, byAccount: AccountInstance, targetAccount: AccountInstance) { function followActivityData (url: string, byAccount: AccountModel, targetAccount: AccountModel): ActivityFollow {
const activity: ActivityFollow = { return {
type: 'Follow', type: 'Follow',
id: url, id: url,
actor: byAccount.url, actor: byAccount.url,
object: targetAccount.url object: targetAccount.url
} }
return activity
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -1,6 +1,7 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { ActivityAudience, ActivityLike } from '../../../../shared/models/activitypub/activity' import { ActivityAudience, ActivityLike } from '../../../../shared/models/activitypub'
import { AccountInstance, VideoInstance } from '../../../models' import { AccountModel } from '../../../models/account/account'
import { VideoModel } from '../../../models/video/video'
import { getVideoLikeActivityPubUrl } from '../url' import { getVideoLikeActivityPubUrl } from '../url'
import { import {
broadcastToFollowers, broadcastToFollowers,
@ -11,7 +12,7 @@ import {
unicastTo unicastTo
} from './misc' } from './misc'
async function sendLikeToOrigin (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendLikeToOrigin (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const url = getVideoLikeActivityPubUrl(byAccount, video) const url = getVideoLikeActivityPubUrl(byAccount, video)
const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t) const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t)
@ -21,7 +22,7 @@ async function sendLikeToOrigin (byAccount: AccountInstance, video: VideoInstanc
return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t) return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
} }
async function sendLikeToVideoFollowers (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendLikeToVideoFollowers (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const url = getVideoLikeActivityPubUrl(byAccount, video) const url = getVideoLikeActivityPubUrl(byAccount, video)
const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t) const accountsInvolvedInVideo = await getAccountsInvolvedInVideo(video, t)
@ -34,16 +35,16 @@ async function sendLikeToVideoFollowers (byAccount: AccountInstance, video: Vide
async function likeActivityData ( async function likeActivityData (
url: string, url: string,
byAccount: AccountInstance, byAccount: AccountModel,
video: VideoInstance, video: VideoModel,
t: Transaction, t: Transaction,
audience?: ActivityAudience audience?: ActivityAudience
) { ): Promise<ActivityLike> {
if (!audience) { if (!audience) {
audience = await getAudience(byAccount, t) audience = await getAudience(byAccount, t)
} }
const activity: ActivityLike = { return {
type: 'Like', type: 'Like',
id: url, id: url,
actor: byAccount.url, actor: byAccount.url,
@ -51,8 +52,6 @@ async function likeActivityData (
cc: audience.cc, cc: audience.cc,
object: video.url object: video.url
} }
return activity
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

View File

@ -5,10 +5,10 @@ import {
ActivityFollow, ActivityFollow,
ActivityLike, ActivityLike,
ActivityUndo ActivityUndo
} from '../../../../shared/models/activitypub/activity' } from '../../../../shared/models/activitypub'
import { AccountInstance } from '../../../models' import { AccountModel } from '../../../models/account/account'
import { AccountFollowInstance } from '../../../models/account/account-follow-interface' import { AccountFollowModel } from '../../../models/account/account-follow'
import { VideoInstance } from '../../../models/video/video-interface' import { VideoModel } from '../../../models/video/video'
import { getAccountFollowActivityPubUrl, getUndoActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from '../url' import { getAccountFollowActivityPubUrl, getUndoActivityPubUrl, getVideoDislikeActivityPubUrl, getVideoLikeActivityPubUrl } from '../url'
import { import {
broadcastToFollowers, broadcastToFollowers,
@ -22,7 +22,7 @@ import { createActivityData, createDislikeActivityData } from './send-create'
import { followActivityData } from './send-follow' import { followActivityData } from './send-follow'
import { likeActivityData } from './send-like' import { likeActivityData } from './send-like'
async function sendUndoFollow (accountFollow: AccountFollowInstance, t: Transaction) { async function sendUndoFollow (accountFollow: AccountFollowModel, t: Transaction) {
const me = accountFollow.AccountFollower const me = accountFollow.AccountFollower
const following = accountFollow.AccountFollowing const following = accountFollow.AccountFollowing
@ -35,7 +35,7 @@ async function sendUndoFollow (accountFollow: AccountFollowInstance, t: Transact
return unicastTo(data, me, following.inboxUrl, t) return unicastTo(data, me, following.inboxUrl, t)
} }
async function sendUndoLikeToOrigin (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendUndoLikeToOrigin (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const likeUrl = getVideoLikeActivityPubUrl(byAccount, video) const likeUrl = getVideoLikeActivityPubUrl(byAccount, video)
const undoUrl = getUndoActivityPubUrl(likeUrl) const undoUrl = getUndoActivityPubUrl(likeUrl)
@ -47,7 +47,7 @@ async function sendUndoLikeToOrigin (byAccount: AccountInstance, video: VideoIns
return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t) return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
} }
async function sendUndoLikeToVideoFollowers (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendUndoLikeToVideoFollowers (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const likeUrl = getVideoLikeActivityPubUrl(byAccount, video) const likeUrl = getVideoLikeActivityPubUrl(byAccount, video)
const undoUrl = getUndoActivityPubUrl(likeUrl) const undoUrl = getUndoActivityPubUrl(likeUrl)
@ -60,7 +60,7 @@ async function sendUndoLikeToVideoFollowers (byAccount: AccountInstance, video:
return broadcastToFollowers(data, byAccount, toAccountsFollowers, t, followersException) return broadcastToFollowers(data, byAccount, toAccountsFollowers, t, followersException)
} }
async function sendUndoDislikeToOrigin (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendUndoDislikeToOrigin (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const dislikeUrl = getVideoDislikeActivityPubUrl(byAccount, video) const dislikeUrl = getVideoDislikeActivityPubUrl(byAccount, video)
const undoUrl = getUndoActivityPubUrl(dislikeUrl) const undoUrl = getUndoActivityPubUrl(dislikeUrl)
@ -74,7 +74,7 @@ async function sendUndoDislikeToOrigin (byAccount: AccountInstance, video: Video
return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t) return unicastTo(data, byAccount, video.VideoChannel.Account.sharedInboxUrl, t)
} }
async function sendUndoDislikeToVideoFollowers (byAccount: AccountInstance, video: VideoInstance, t: Transaction) { async function sendUndoDislikeToVideoFollowers (byAccount: AccountModel, video: VideoModel, t: Transaction) {
const dislikeUrl = getVideoDislikeActivityPubUrl(byAccount, video) const dislikeUrl = getVideoDislikeActivityPubUrl(byAccount, video)
const undoUrl = getUndoActivityPubUrl(dislikeUrl) const undoUrl = getUndoActivityPubUrl(dislikeUrl)
@ -103,16 +103,16 @@ export {
async function undoActivityData ( async function undoActivityData (
url: string, url: string,
byAccount: AccountInstance, byAccount: AccountModel,
object: ActivityFollow | ActivityLike | ActivityCreate, object: ActivityFollow | ActivityLike | ActivityCreate,
t: Transaction, t: Transaction,
audience?: ActivityAudience audience?: ActivityAudience
) { ): Promise<ActivityUndo> {
if (!audience) { if (!audience) {
audience = await getAudience(byAccount, t) audience = await getAudience(byAccount, t)
} }
const activity: ActivityUndo = { return {
type: 'Undo', type: 'Undo',
id: url, id: url,
actor: byAccount.url, actor: byAccount.url,
@ -120,6 +120,4 @@ async function undoActivityData (
cc: audience.cc, cc: audience.cc,
object object
} }
return activity
} }

View File

@ -1,31 +1,34 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { ActivityUpdate } from '../../../../shared/models/activitypub/activity' import { ActivityUpdate } from '../../../../shared/models/activitypub'
import { database as db } from '../../../initializers' import { AccountModel } from '../../../models/account/account'
import { AccountInstance, VideoChannelInstance, VideoInstance } from '../../../models' import { VideoModel } from '../../../models/video/video'
import { VideoChannelModel } from '../../../models/video/video-channel'
import { VideoChannelShareModel } from '../../../models/video/video-channel-share'
import { VideoShareModel } from '../../../models/video/video-share'
import { getUpdateActivityPubUrl } from '../url' import { getUpdateActivityPubUrl } from '../url'
import { broadcastToFollowers, getAudience } from './misc' import { broadcastToFollowers, getAudience } from './misc'
async function sendUpdateVideoChannel (videoChannel: VideoChannelInstance, t: Transaction) { async function sendUpdateVideoChannel (videoChannel: VideoChannelModel, t: Transaction) {
const byAccount = videoChannel.Account const byAccount = videoChannel.Account
const url = getUpdateActivityPubUrl(videoChannel.url, videoChannel.updatedAt.toISOString()) const url = getUpdateActivityPubUrl(videoChannel.url, videoChannel.updatedAt.toISOString())
const videoChannelObject = videoChannel.toActivityPubObject() const videoChannelObject = videoChannel.toActivityPubObject()
const data = await updateActivityData(url, byAccount, videoChannelObject, t) const data = await updateActivityData(url, byAccount, videoChannelObject, t)
const accountsInvolved = await db.VideoChannelShare.loadAccountsByShare(videoChannel.id, t) const accountsInvolved = await VideoChannelShareModel.loadAccountsByShare(videoChannel.id, t)
accountsInvolved.push(byAccount) accountsInvolved.push(byAccount)
return broadcastToFollowers(data, byAccount, accountsInvolved, t) return broadcastToFollowers(data, byAccount, accountsInvolved, t)
} }
async function sendUpdateVideo (video: VideoInstance, t: Transaction) { async function sendUpdateVideo (video: VideoModel, t: Transaction) {
const byAccount = video.VideoChannel.Account const byAccount = video.VideoChannel.Account
const url = getUpdateActivityPubUrl(video.url, video.updatedAt.toISOString()) const url = getUpdateActivityPubUrl(video.url, video.updatedAt.toISOString())
const videoObject = video.toActivityPubObject() const videoObject = video.toActivityPubObject()
const data = await updateActivityData(url, byAccount, videoObject, t) const data = await updateActivityData(url, byAccount, videoObject, t)
const accountsInvolved = await db.VideoShare.loadAccountsByShare(video.id, t) const accountsInvolved = await VideoShareModel.loadAccountsByShare(video.id, t)
accountsInvolved.push(byAccount) accountsInvolved.push(byAccount)
return broadcastToFollowers(data, byAccount, accountsInvolved, t) return broadcastToFollowers(data, byAccount, accountsInvolved, t)
@ -40,9 +43,9 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function updateActivityData (url: string, byAccount: AccountInstance, object: any, t: Transaction) { async function updateActivityData (url: string, byAccount: AccountModel, object: any, t: Transaction): Promise<ActivityUpdate> {
const { to, cc } = await getAudience(byAccount, t) const { to, cc } = await getAudience(byAccount, t)
const activity: ActivityUpdate = { return {
type: 'Update', type: 'Update',
id: url, id: url,
actor: byAccount.url, actor: byAccount.url,
@ -50,6 +53,4 @@ async function updateActivityData (url: string, byAccount: AccountInstance, obje
cc, cc,
object object
} }
return activity
} }

View File

@ -1,14 +1,15 @@
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { getServerAccount } from '../../helpers/utils' import { getServerAccount } from '../../helpers'
import { database as db } from '../../initializers' import { VideoModel } from '../../models/video/video'
import { VideoChannelInstance } from '../../models/index' import { VideoChannelModel } from '../../models/video/video-channel'
import { VideoInstance } from '../../models/video/video-interface' import { VideoChannelShareModel } from '../../models/video/video-channel-share'
import { sendVideoAnnounceToFollowers, sendVideoChannelAnnounceToFollowers } from './send/send-announce' import { VideoShareModel } from '../../models/video/video-share'
import { sendVideoAnnounceToFollowers, sendVideoChannelAnnounceToFollowers } from './send'
async function shareVideoChannelByServer (videoChannel: VideoChannelInstance, t: Transaction) { async function shareVideoChannelByServer (videoChannel: VideoChannelModel, t: Transaction) {
const serverAccount = await getServerAccount() const serverAccount = await getServerAccount()
await db.VideoChannelShare.create({ await VideoChannelShareModel.create({
accountId: serverAccount.id, accountId: serverAccount.id,
videoChannelId: videoChannel.id videoChannelId: videoChannel.id
}, { transaction: t }) }, { transaction: t })
@ -16,10 +17,10 @@ async function shareVideoChannelByServer (videoChannel: VideoChannelInstance, t:
return sendVideoChannelAnnounceToFollowers(serverAccount, videoChannel, t) return sendVideoChannelAnnounceToFollowers(serverAccount, videoChannel, t)
} }
async function shareVideoByServer (video: VideoInstance, t: Transaction) { async function shareVideoByServer (video: VideoModel, t: Transaction) {
const serverAccount = await getServerAccount() const serverAccount = await getServerAccount()
await db.VideoShare.create({ await VideoShareModel.create({
accountId: serverAccount.id, accountId: serverAccount.id,
videoId: video.id videoId: video.id
}, { transaction: t }) }, { transaction: t })

View File

@ -1,15 +1,15 @@
import { CONFIG } from '../../initializers/constants' import { CONFIG } from '../../initializers'
import { VideoInstance } from '../../models/video/video-interface' import { AccountModel } from '../../models/account/account'
import { VideoChannelInstance } from '../../models/video/video-channel-interface' import { AccountFollowModel } from '../../models/account/account-follow'
import { VideoAbuseInstance } from '../../models/video/video-abuse-interface' import { VideoModel } from '../../models/video/video'
import { AccountFollowInstance } from '../../models/account/account-follow-interface' import { VideoAbuseModel } from '../../models/video/video-abuse'
import { AccountInstance } from '../../models/account/account-interface' import { VideoChannelModel } from '../../models/video/video-channel'
function getVideoActivityPubUrl (video: VideoInstance) { function getVideoActivityPubUrl (video: VideoModel) {
return CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid return CONFIG.WEBSERVER.URL + '/videos/watch/' + video.uuid
} }
function getVideoChannelActivityPubUrl (videoChannel: VideoChannelInstance) { function getVideoChannelActivityPubUrl (videoChannel: VideoChannelModel) {
return CONFIG.WEBSERVER.URL + '/video-channels/' + videoChannel.uuid return CONFIG.WEBSERVER.URL + '/video-channels/' + videoChannel.uuid
} }
@ -17,37 +17,37 @@ function getAccountActivityPubUrl (accountName: string) {
return CONFIG.WEBSERVER.URL + '/account/' + accountName return CONFIG.WEBSERVER.URL + '/account/' + accountName
} }
function getVideoAbuseActivityPubUrl (videoAbuse: VideoAbuseInstance) { function getVideoAbuseActivityPubUrl (videoAbuse: VideoAbuseModel) {
return CONFIG.WEBSERVER.URL + '/admin/video-abuses/' + videoAbuse.id return CONFIG.WEBSERVER.URL + '/admin/video-abuses/' + videoAbuse.id
} }
function getVideoViewActivityPubUrl (byAccount: AccountInstance, video: VideoInstance) { function getVideoViewActivityPubUrl (byAccount: AccountModel, video: VideoModel) {
return video.url + '/views/' + byAccount.uuid + '/' + new Date().toISOString() return video.url + '/views/' + byAccount.uuid + '/' + new Date().toISOString()
} }
function getVideoLikeActivityPubUrl (byAccount: AccountInstance, video: VideoInstance) { function getVideoLikeActivityPubUrl (byAccount: AccountModel, video: VideoModel) {
return byAccount.url + '/likes/' + video.id return byAccount.url + '/likes/' + video.id
} }
function getVideoDislikeActivityPubUrl (byAccount: AccountInstance, video: VideoInstance) { function getVideoDislikeActivityPubUrl (byAccount: AccountModel, video: VideoModel) {
return byAccount.url + '/dislikes/' + video.id return byAccount.url + '/dislikes/' + video.id
} }
function getAccountFollowActivityPubUrl (accountFollow: AccountFollowInstance) { function getAccountFollowActivityPubUrl (accountFollow: AccountFollowModel) {
const me = accountFollow.AccountFollower const me = accountFollow.AccountFollower
const following = accountFollow.AccountFollowing const following = accountFollow.AccountFollowing
return me.url + '/follows/' + following.id return me.url + '/follows/' + following.id
} }
function getAccountFollowAcceptActivityPubUrl (accountFollow: AccountFollowInstance) { function getAccountFollowAcceptActivityPubUrl (accountFollow: AccountFollowModel) {
const follower = accountFollow.AccountFollower const follower = accountFollow.AccountFollower
const me = accountFollow.AccountFollowing const me = accountFollow.AccountFollowing
return follower.url + '/accepts/follows/' + me.id return follower.url + '/accepts/follows/' + me.id
} }
function getAnnounceActivityPubUrl (originalUrl: string, byAccount: AccountInstance) { function getAnnounceActivityPubUrl (originalUrl: string, byAccount: AccountModel) {
return originalUrl + '/announces/' + byAccount.id return originalUrl + '/announces/' + byAccount.id
} }

View File

@ -1,14 +1,13 @@
import { VideoChannelObject } from '../../../shared/models/activitypub/objects/video-channel-object' import { VideoChannelObject } from '../../../shared/models/activitypub/objects'
import { isVideoChannelObjectValid } from '../../helpers/custom-validators/activitypub/video-channels' import { doRequest, logger } from '../../helpers'
import { logger } from '../../helpers/logger' import { isVideoChannelObjectValid } from '../../helpers/custom-validators/activitypub'
import { doRequest } from '../../helpers/requests' import { ACTIVITY_PUB } from '../../initializers'
import { database as db } from '../../initializers' import { AccountModel } from '../../models/account/account'
import { ACTIVITY_PUB } from '../../initializers/constants' import { VideoChannelModel } from '../../models/video/video-channel'
import { AccountInstance } from '../../models/account/account-interface'
import { videoChannelActivityObjectToDBAttributes } from './process/misc' import { videoChannelActivityObjectToDBAttributes } from './process/misc'
async function getOrCreateVideoChannel (ownerAccount: AccountInstance, videoChannelUrl: string) { async function getOrCreateVideoChannel (ownerAccount: AccountModel, videoChannelUrl: string) {
let videoChannel = await db.VideoChannel.loadByUrl(videoChannelUrl) let videoChannel = await VideoChannelModel.loadByUrl(videoChannelUrl)
// We don't have this account in our database, fetch it on remote // We don't have this account in our database, fetch it on remote
if (!videoChannel) { if (!videoChannel) {
@ -22,7 +21,7 @@ async function getOrCreateVideoChannel (ownerAccount: AccountInstance, videoChan
return videoChannel return videoChannel
} }
async function fetchRemoteVideoChannel (ownerAccount: AccountInstance, videoChannelUrl: string) { async function fetchRemoteVideoChannel (ownerAccount: AccountModel, videoChannelUrl: string) {
const options = { const options = {
uri: videoChannelUrl, uri: videoChannelUrl,
method: 'GET', method: 'GET',
@ -48,7 +47,7 @@ async function fetchRemoteVideoChannel (ownerAccount: AccountInstance, videoChan
} }
const videoChannelAttributes = videoChannelActivityObjectToDBAttributes(videoChannelJSON, ownerAccount) const videoChannelAttributes = videoChannelActivityObjectToDBAttributes(videoChannelJSON, ownerAccount)
const videoChannel = db.VideoChannel.build(videoChannelAttributes) const videoChannel = new VideoChannelModel(videoChannelAttributes)
videoChannel.Account = ownerAccount videoChannel.Account = ownerAccount
return videoChannel return videoChannel

View File

@ -2,21 +2,22 @@ import { join } from 'path'
import * as request from 'request' import * as request from 'request'
import { Transaction } from 'sequelize' import { Transaction } from 'sequelize'
import { ActivityIconObject } from '../../../shared/index' import { ActivityIconObject } from '../../../shared/index'
import { doRequest, doRequestAndSaveToFile } from '../../helpers/requests' import { doRequest, doRequestAndSaveToFile } from '../../helpers'
import { CONFIG, REMOTE_SCHEME, STATIC_PATHS } from '../../initializers/constants' import { CONFIG, REMOTE_SCHEME, STATIC_PATHS } from '../../initializers'
import { AccountInstance } from '../../models/account/account-interface' import { AccountModel } from '../../models/account/account'
import { VideoInstance } from '../../models/video/video-interface' import { VideoModel } from '../../models/video/video'
import { sendLikeToOrigin } from './index'
import { sendCreateDislikeToOrigin, sendCreateDislikeToVideoFollowers } from './send/send-create'
import { sendLikeToVideoFollowers } from './send/send-like'
import { import {
sendCreateDislikeToOrigin,
sendCreateDislikeToVideoFollowers,
sendLikeToOrigin,
sendLikeToVideoFollowers,
sendUndoDislikeToOrigin, sendUndoDislikeToOrigin,
sendUndoDislikeToVideoFollowers, sendUndoDislikeToVideoFollowers,
sendUndoLikeToOrigin, sendUndoLikeToOrigin,
sendUndoLikeToVideoFollowers sendUndoLikeToVideoFollowers
} from './send/send-undo' } from './send'
function fetchRemoteVideoPreview (video: VideoInstance) { function fetchRemoteVideoPreview (video: VideoModel) {
// FIXME: use url // FIXME: use url
const host = video.VideoChannel.Account.Server.host const host = video.VideoChannel.Account.Server.host
const path = join(STATIC_PATHS.PREVIEWS, video.getPreviewName()) const path = join(STATIC_PATHS.PREVIEWS, video.getPreviewName())
@ -24,7 +25,7 @@ function fetchRemoteVideoPreview (video: VideoInstance) {
return request.get(REMOTE_SCHEME.HTTP + '://' + host + path) return request.get(REMOTE_SCHEME.HTTP + '://' + host + path)
} }
async function fetchRemoteVideoDescription (video: VideoInstance) { async function fetchRemoteVideoDescription (video: VideoModel) {
// FIXME: use url // FIXME: use url
const host = video.VideoChannel.Account.Server.host const host = video.VideoChannel.Account.Server.host
const path = video.getDescriptionPath() const path = video.getDescriptionPath()
@ -37,7 +38,7 @@ async function fetchRemoteVideoDescription (video: VideoInstance) {
return body.description ? body.description : '' return body.description ? body.description : ''
} }
function generateThumbnailFromUrl (video: VideoInstance, icon: ActivityIconObject) { function generateThumbnailFromUrl (video: VideoModel, icon: ActivityIconObject) {
const thumbnailName = video.getThumbnailName() const thumbnailName = video.getThumbnailName()
const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName) const thumbnailPath = join(CONFIG.STORAGE.THUMBNAILS_DIR, thumbnailName)
@ -49,8 +50,8 @@ function generateThumbnailFromUrl (video: VideoInstance, icon: ActivityIconObjec
} }
async function sendVideoRateChangeToFollowers ( async function sendVideoRateChangeToFollowers (
account: AccountInstance, account: AccountModel,
video: VideoInstance, video: VideoModel,
likes: number, likes: number,
dislikes: number, dislikes: number,
t: Transaction t: Transaction
@ -69,8 +70,8 @@ async function sendVideoRateChangeToFollowers (
} }
async function sendVideoRateChangeToOrigin ( async function sendVideoRateChangeToOrigin (
account: AccountInstance, account: AccountModel,
video: VideoInstance, video: VideoModel,
likes: number, likes: number,
dislikes: number, dislikes: number,
t: Transaction t: Transaction

View File

@ -1,11 +1,10 @@
import * as asyncLRU from 'async-lru' import * as asyncLRU from 'async-lru'
import { join } from 'path'
import { createWriteStream } from 'fs' import { createWriteStream } from 'fs'
import { join } from 'path'
import { database as db, CONFIG, CACHE } from '../../initializers'
import { logger, unlinkPromise } from '../../helpers' import { logger, unlinkPromise } from '../../helpers'
import { VideoInstance } from '../../models' import { CACHE, CONFIG } from '../../initializers'
import { fetchRemoteVideoPreview } from '../activitypub/videos' import { VideoModel } from '../../models/video/video'
import { fetchRemoteVideoPreview } from '../activitypub'
class VideosPreviewCache { class VideosPreviewCache {
@ -43,7 +42,7 @@ class VideosPreviewCache {
} }
private async loadPreviews (key: string) { private async loadPreviews (key: string) {
const video = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(key) const video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(key)
if (!video) return undefined if (!video) return undefined
if (video.isOwned()) return join(CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName()) if (video.isOwned()) return join(CONFIG.STORAGE.PREVIEWS_DIR, video.getPreviewName())
@ -53,7 +52,7 @@ class VideosPreviewCache {
return res return res
} }
private saveRemotePreviewAndReturnPath (video: VideoInstance) { private saveRemotePreviewAndReturnPath (video: VideoModel) {
const req = fetchRemoteVideoPreview(video) const req = fetchRemoteVideoPreview(video)
return new Promise<string>((res, rej) => { return new Promise<string>((res, rej) => {

View File

@ -1,5 +1,4 @@
import { logger } from '../../../helpers' import { doRequest, logger } from '../../../helpers'
import { doRequest } from '../../../helpers/requests'
import { ActivityPubHttpPayload, computeBody, maybeRetryRequestLater } from './activitypub-http-job-scheduler' import { ActivityPubHttpPayload, computeBody, maybeRetryRequestLater } from './activitypub-http-job-scheduler'
async function process (payload: ActivityPubHttpPayload, jobId: number) { async function process (payload: ActivityPubHttpPayload, jobId: number) {

View File

@ -1,7 +1,6 @@
import { logger } from '../../../helpers' import { doRequest, logger } from '../../../helpers'
import { doRequest } from '../../../helpers/requests' import { ACTIVITY_PUB } from '../../../initializers'
import { ACTIVITY_PUB } from '../../../initializers/constants' import { processActivities } from '../../activitypub/process'
import { processActivities } from '../../activitypub/process/process'
import { ActivityPubHttpPayload } from './activitypub-http-job-scheduler' import { ActivityPubHttpPayload } from './activitypub-http-job-scheduler'
async function process (payload: ActivityPubHttpPayload, jobId: number) { async function process (payload: ActivityPubHttpPayload, jobId: number) {

View File

@ -1,8 +1,7 @@
import { JobCategory } from '../../../../shared' import { JobCategory } from '../../../../shared'
import { buildSignedActivity } from '../../../helpers/activitypub' import { buildSignedActivity, logger } from '../../../helpers'
import { logger } from '../../../helpers/logger' import { ACTIVITY_PUB } from '../../../initializers'
import { ACTIVITY_PUB } from '../../../initializers/constants' import { AccountModel } from '../../../models/account/account'
import { database as db } from '../../../initializers/database'
import { JobHandler, JobScheduler } from '../job-scheduler' import { JobHandler, JobScheduler } from '../job-scheduler'
import * as activitypubHttpBroadcastHandler from './activitypub-http-broadcast-handler' import * as activitypubHttpBroadcastHandler from './activitypub-http-broadcast-handler'
@ -46,7 +45,7 @@ async function computeBody (payload: ActivityPubHttpPayload) {
let body = payload.body let body = payload.body
if (payload.signatureAccountId) { if (payload.signatureAccountId) {
const accountSignature = await db.Account.load(payload.signatureAccountId) const accountSignature = await AccountModel.load(payload.signatureAccountId)
if (!accountSignature) throw new Error('Unknown signature account id.') if (!accountSignature) throw new Error('Unknown signature account id.')
body = await buildSignedActivity(accountSignature, payload.body) body = await buildSignedActivity(accountSignature, payload.body)
} }

View File

@ -1,5 +1,4 @@
import { logger } from '../../../helpers' import { doRequest, logger } from '../../../helpers'
import { doRequest } from '../../../helpers/requests'
import { ActivityPubHttpPayload, computeBody, maybeRetryRequestLater } from './activitypub-http-job-scheduler' import { ActivityPubHttpPayload, computeBody, maybeRetryRequestLater } from './activitypub-http-job-scheduler'
async function process (payload: ActivityPubHttpPayload, jobId: number) { async function process (payload: ActivityPubHttpPayload, jobId: number) {

View File

@ -2,8 +2,8 @@ import { AsyncQueue, forever, queue } from 'async'
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import { JobCategory } from '../../../shared' import { JobCategory } from '../../../shared'
import { logger } from '../../helpers' import { logger } from '../../helpers'
import { database as db, JOB_STATES, JOBS_FETCH_LIMIT_PER_CYCLE, JOBS_FETCHING_INTERVAL } from '../../initializers' import { JOB_STATES, JOBS_FETCH_LIMIT_PER_CYCLE, JOBS_FETCHING_INTERVAL } from '../../initializers'
import { JobInstance } from '../../models' import { JobModel } from '../../models/job/job'
export interface JobHandler<P, T> { export interface JobHandler<P, T> {
process (data: object, jobId: number): Promise<T> process (data: object, jobId: number): Promise<T>
@ -24,12 +24,12 @@ class JobScheduler<P, T> {
logger.info('Jobs scheduler %s activated.', this.jobCategory) logger.info('Jobs scheduler %s activated.', this.jobCategory)
const jobsQueue = queue<JobInstance, JobQueueCallback>(this.processJob.bind(this)) const jobsQueue = queue<JobModel, JobQueueCallback>(this.processJob.bind(this))
// Finish processing jobs from a previous start // Finish processing jobs from a previous start
const state = JOB_STATES.PROCESSING const state = JOB_STATES.PROCESSING
try { try {
const jobs = await db.Job.listWithLimitByCategory(limit, state, this.jobCategory) const jobs = await JobModel.listWithLimitByCategory(limit, state, this.jobCategory)
this.enqueueJobs(jobsQueue, jobs) this.enqueueJobs(jobsQueue, jobs)
} catch (err) { } catch (err) {
@ -45,7 +45,7 @@ class JobScheduler<P, T> {
const state = JOB_STATES.PENDING const state = JOB_STATES.PENDING
try { try {
const jobs = await db.Job.listWithLimitByCategory(limit, state, this.jobCategory) const jobs = await JobModel.listWithLimitByCategory(limit, state, this.jobCategory)
this.enqueueJobs(jobsQueue, jobs) this.enqueueJobs(jobsQueue, jobs)
} catch (err) { } catch (err) {
@ -70,14 +70,14 @@ class JobScheduler<P, T> {
const options = { transaction } const options = { transaction }
return db.Job.create(createQuery, options) return JobModel.create(createQuery, options)
} }
private enqueueJobs (jobsQueue: AsyncQueue<JobInstance>, jobs: JobInstance[]) { private enqueueJobs (jobsQueue: AsyncQueue<JobModel>, jobs: JobModel[]) {
jobs.forEach(job => jobsQueue.push(job)) jobs.forEach(job => jobsQueue.push(job))
} }
private async processJob (job: JobInstance, callback: (err: Error) => void) { private async processJob (job: JobModel, callback: (err: Error) => void) {
const jobHandler = this.jobHandlers[job.handlerName] const jobHandler = this.jobHandlers[job.handlerName]
if (jobHandler === undefined) { if (jobHandler === undefined) {
const errorString = 'Unknown job handler ' + job.handlerName + ' for job ' + job.id const errorString = 'Unknown job handler ' + job.handlerName + ' for job ' + job.id
@ -110,7 +110,7 @@ class JobScheduler<P, T> {
return callback(null) return callback(null)
} }
private async onJobError (jobHandler: JobHandler<P, T>, job: JobInstance, err: Error) { private async onJobError (jobHandler: JobHandler<P, T>, job: JobModel, err: Error) {
job.state = JOB_STATES.ERROR job.state = JOB_STATES.ERROR
try { try {
@ -121,7 +121,7 @@ class JobScheduler<P, T> {
} }
} }
private async onJobSuccess (jobHandler: JobHandler<P, T>, job: JobInstance, jobResult: T) { private async onJobSuccess (jobHandler: JobHandler<P, T>, job: JobModel, jobResult: T) {
job.state = JOB_STATES.SUCCESS job.state = JOB_STATES.SUCCESS
try { try {

View File

@ -1,14 +1,15 @@
import { JobCategory } from '../../../../shared' import { JobCategory } from '../../../../shared'
import { VideoModel } from '../../../models/video/video'
import { JobHandler, JobScheduler } from '../job-scheduler' import { JobHandler, JobScheduler } from '../job-scheduler'
import * as videoFileOptimizer from './video-file-optimizer-handler' import * as videoFileOptimizer from './video-file-optimizer-handler'
import * as videoFileTranscoder from './video-file-transcoder-handler' import * as videoFileTranscoder from './video-file-transcoder-handler'
import { VideoInstance } from '../../../models/video/video-interface'
type TranscodingJobPayload = { type TranscodingJobPayload = {
videoUUID: string videoUUID: string
resolution?: number resolution?: number
} }
const jobHandlers: { [ handlerName: string ]: JobHandler<TranscodingJobPayload, VideoInstance> } = { const jobHandlers: { [ handlerName: string ]: JobHandler<TranscodingJobPayload, VideoModel> } = {
videoFileOptimizer, videoFileOptimizer,
videoFileTranscoder videoFileTranscoder
} }

View File

@ -1,14 +1,14 @@
import * as Bluebird from 'bluebird' import * as Bluebird from 'bluebird'
import { computeResolutionsToTranscode, logger } from '../../../helpers' import { computeResolutionsToTranscode, logger } from '../../../helpers'
import { database as db } from '../../../initializers/database' import { sequelizeTypescript } from '../../../initializers'
import { VideoInstance } from '../../../models' import { VideoModel } from '../../../models/video/video'
import { sendAddVideo } from '../../activitypub/send/send-add' import { shareVideoByServer } from '../../activitypub'
import { sendAddVideo } from '../../activitypub/send'
import { JobScheduler } from '../job-scheduler' import { JobScheduler } from '../job-scheduler'
import { TranscodingJobPayload } from './transcoding-job-scheduler' import { TranscodingJobPayload } from './transcoding-job-scheduler'
import { shareVideoByServer } from '../../activitypub/share'
async function process (data: TranscodingJobPayload, jobId: number) { async function process (data: TranscodingJobPayload, jobId: number) {
const video = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(data.videoUUID) const video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(data.videoUUID)
// No video, maybe deleted? // No video, maybe deleted?
if (!video) { if (!video) {
logger.info('Do not process job %d, video does not exist.', jobId, { videoUUID: video.uuid }) logger.info('Do not process job %d, video does not exist.', jobId, { videoUUID: video.uuid })
@ -25,13 +25,13 @@ function onError (err: Error, jobId: number) {
return Promise.resolve() return Promise.resolve()
} }
async function onSuccess (jobId: number, video: VideoInstance, jobScheduler: JobScheduler<TranscodingJobPayload, VideoInstance>) { async function onSuccess (jobId: number, video: VideoModel, jobScheduler: JobScheduler<TranscodingJobPayload, VideoModel>) {
if (video === undefined) return undefined if (video === undefined) return undefined
logger.info('Job %d is a success.', jobId) logger.info('Job %d is a success.', jobId)
// Maybe the video changed in database, refresh it // Maybe the video changed in database, refresh it
const videoDatabase = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(video.uuid) const videoDatabase = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(video.uuid)
// Video does not exist anymore // Video does not exist anymore
if (!videoDatabase) return undefined if (!videoDatabase) return undefined
@ -50,7 +50,7 @@ async function onSuccess (jobId: number, video: VideoInstance, jobScheduler: Job
if (resolutionsEnabled.length !== 0) { if (resolutionsEnabled.length !== 0) {
try { try {
await db.sequelize.transaction(async t => { await sequelizeTypescript.transaction(async t => {
const tasks: Bluebird<any>[] = [] const tasks: Bluebird<any>[] = []
for (const resolution of resolutionsEnabled) { for (const resolution of resolutionsEnabled) {

View File

@ -1,11 +1,10 @@
import { VideoResolution } from '../../../../shared' import { VideoResolution } from '../../../../shared'
import { logger } from '../../../helpers' import { logger } from '../../../helpers'
import { database as db } from '../../../initializers/database' import { VideoModel } from '../../../models/video/video'
import { VideoInstance } from '../../../models' import { sendUpdateVideo } from '../../activitypub/send'
import { sendUpdateVideo } from '../../activitypub/send/send-update'
async function process (data: { videoUUID: string, resolution: VideoResolution }, jobId: number) { async function process (data: { videoUUID: string, resolution: VideoResolution }, jobId: number) {
const video = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(data.videoUUID) const video = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(data.videoUUID)
// No video, maybe deleted? // No video, maybe deleted?
if (!video) { if (!video) {
logger.info('Do not process job %d, video does not exist.', jobId, { videoUUID: video.uuid }) logger.info('Do not process job %d, video does not exist.', jobId, { videoUUID: video.uuid })
@ -22,13 +21,13 @@ function onError (err: Error, jobId: number) {
return Promise.resolve() return Promise.resolve()
} }
async function onSuccess (jobId: number, video: VideoInstance) { async function onSuccess (jobId: number, video: VideoModel) {
if (video === undefined) return undefined if (video === undefined) return undefined
logger.info('Job %d is a success.', jobId) logger.info('Job %d is a success.', jobId)
// Maybe the video changed in database, refresh it // Maybe the video changed in database, refresh it
const videoDatabase = await db.Video.loadByUUIDAndPopulateAccountAndServerAndTags(video.uuid) const videoDatabase = await VideoModel.loadByUUIDAndPopulateAccountAndServerAndTags(video.uuid)
// Video does not exist anymore // Video does not exist anymore
if (!videoDatabase) return undefined if (!videoDatabase) return undefined

View File

@ -1,6 +1,7 @@
import { OAuthClientInstance, UserInstance } from '../models'
import { database as db } from '../initializers/database'
import { logger } from '../helpers' import { logger } from '../helpers'
import { UserModel } from '../models/account/user'
import { OAuthClientModel } from '../models/oauth/oauth-client'
import { OAuthTokenModel } from '../models/oauth/oauth-token'
type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date } type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpiresAt: Date, refreshTokenExpiresAt: Date }
@ -9,25 +10,25 @@ type TokenInfo = { accessToken: string, refreshToken: string, accessTokenExpires
function getAccessToken (bearerToken: string) { function getAccessToken (bearerToken: string) {
logger.debug('Getting access token (bearerToken: ' + bearerToken + ').') logger.debug('Getting access token (bearerToken: ' + bearerToken + ').')
return db.OAuthToken.getByTokenAndPopulateUser(bearerToken) return OAuthTokenModel.getByTokenAndPopulateUser(bearerToken)
} }
function getClient (clientId: string, clientSecret: string) { function getClient (clientId: string, clientSecret: string) {
logger.debug('Getting Client (clientId: ' + clientId + ', clientSecret: ' + clientSecret + ').') logger.debug('Getting Client (clientId: ' + clientId + ', clientSecret: ' + clientSecret + ').')
return db.OAuthClient.getByIdAndSecret(clientId, clientSecret) return OAuthClientModel.getByIdAndSecret(clientId, clientSecret)
} }
function getRefreshToken (refreshToken: string) { function getRefreshToken (refreshToken: string) {
logger.debug('Getting RefreshToken (refreshToken: ' + refreshToken + ').') logger.debug('Getting RefreshToken (refreshToken: ' + refreshToken + ').')
return db.OAuthToken.getByRefreshTokenAndPopulateClient(refreshToken) return OAuthTokenModel.getByRefreshTokenAndPopulateClient(refreshToken)
} }
async function getUser (username: string, password: string) { async function getUser (username: string, password: string) {
logger.debug('Getting User (username: ' + username + ', password: ******).') logger.debug('Getting User (username: ' + username + ', password: ******).')
const user = await db.User.getByUsername(username) const user = await UserModel.getByUsername(username)
if (!user) return null if (!user) return null
const passwordMatch = await user.isPasswordMatch(password) const passwordMatch = await user.isPasswordMatch(password)
@ -37,7 +38,7 @@ async function getUser (username: string, password: string) {
} }
async function revokeToken (tokenInfo: TokenInfo) { async function revokeToken (tokenInfo: TokenInfo) {
const token = await db.OAuthToken.getByRefreshTokenAndPopulateUser(tokenInfo.refreshToken) const token = await OAuthTokenModel.getByRefreshTokenAndPopulateUser(tokenInfo.refreshToken)
if (token) token.destroy() if (token) token.destroy()
/* /*
@ -53,7 +54,7 @@ async function revokeToken (tokenInfo: TokenInfo) {
return expiredToken return expiredToken
} }
async function saveToken (token: TokenInfo, client: OAuthClientInstance, user: UserInstance) { async function saveToken (token: TokenInfo, client: OAuthClientModel, user: UserModel) {
logger.debug('Saving token ' + token.accessToken + ' for client ' + client.id + ' and user ' + user.id + '.') logger.debug('Saving token ' + token.accessToken + ' for client ' + client.id + ' and user ' + user.id + '.')
const tokenToCreate = { const tokenToCreate = {
@ -65,7 +66,7 @@ async function saveToken (token: TokenInfo, client: OAuthClientInstance, user: U
userId: user.id userId: user.id
} }
const tokenCreated = await db.OAuthToken.create(tokenToCreate) const tokenCreated = await OAuthTokenModel.create(tokenToCreate)
const tokenToReturn = Object.assign(tokenCreated, { client, user }) const tokenToReturn = Object.assign(tokenCreated, { client, user })
return tokenToReturn return tokenToReturn

View File

@ -1,14 +1,13 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import { createPrivateAndPublicKeys } from '../helpers/peertube-crypto' import { createPrivateAndPublicKeys, logger } from '../helpers'
import { database as db } from '../initializers' import { CONFIG, sequelizeTypescript } from '../initializers'
import { CONFIG } from '../initializers/constants' import { AccountModel } from '../models/account/account'
import { UserInstance } from '../models' import { UserModel } from '../models/account/user'
import { getAccountActivityPubUrl } from './activitypub'
import { createVideoChannel } from './video-channel' import { createVideoChannel } from './video-channel'
import { logger } from '../helpers/logger'
import { getAccountActivityPubUrl } from './activitypub/url'
async function createUserAccountAndChannel (user: UserInstance, validateUser = true) { async function createUserAccountAndChannel (user: UserModel, validateUser = true) {
const { account, videoChannel } = await db.sequelize.transaction(async t => { const { account, videoChannel } = await sequelizeTypescript.transaction(async t => {
const userOptions = { const userOptions = {
transaction: t, transaction: t,
validate: validateUser validate: validateUser
@ -38,7 +37,7 @@ async function createUserAccountAndChannel (user: UserInstance, validateUser = t
async function createLocalAccountWithoutKeys (name: string, userId: number, applicationId: number, t: Sequelize.Transaction) { async function createLocalAccountWithoutKeys (name: string, userId: number, applicationId: number, t: Sequelize.Transaction) {
const url = getAccountActivityPubUrl(name) const url = getAccountActivityPubUrl(name)
const accountInstance = db.Account.build({ const accountInstance = new AccountModel({
name, name,
url, url,
publicKey: null, publicKey: null,

View File

@ -1,10 +1,10 @@
import * as Sequelize from 'sequelize' import * as Sequelize from 'sequelize'
import { VideoChannelCreate } from '../../shared/models' import { VideoChannelCreate } from '../../shared/models'
import { database as db } from '../initializers' import { AccountModel } from '../models/account/account'
import { AccountInstance } from '../models' import { VideoChannelModel } from '../models/video/video-channel'
import { getVideoChannelActivityPubUrl } from './activitypub/url' import { getVideoChannelActivityPubUrl } from './activitypub'
async function createVideoChannel (videoChannelInfo: VideoChannelCreate, account: AccountInstance, t: Sequelize.Transaction) { async function createVideoChannel (videoChannelInfo: VideoChannelCreate, account: AccountModel, t: Sequelize.Transaction) {
const videoChannelData = { const videoChannelData = {
name: videoChannelInfo.name, name: videoChannelInfo.name,
description: videoChannelInfo.description, description: videoChannelInfo.description,
@ -12,7 +12,7 @@ async function createVideoChannel (videoChannelInfo: VideoChannelCreate, account
accountId: account.id accountId: account.id
} }
const videoChannel = db.VideoChannel.build(videoChannelData) const videoChannel = VideoChannelModel.build(videoChannelData)
videoChannel.set('url', getVideoChannelActivityPubUrl(videoChannel)) videoChannel.set('url', getVideoChannelActivityPubUrl(videoChannel))
const options = { transaction: t } const options = { transaction: t }

View File

@ -2,16 +2,16 @@ import { eachSeries } from 'async'
import { NextFunction, Request, RequestHandler, Response } from 'express' import { NextFunction, Request, RequestHandler, Response } from 'express'
import { ActivityPubSignature } from '../../shared' import { ActivityPubSignature } from '../../shared'
import { isSignatureVerified, logger } from '../helpers' import { isSignatureVerified, logger } from '../helpers'
import { database as db } from '../initializers' import { ACCEPT_HEADERS, ACTIVITY_PUB } from '../initializers'
import { ACCEPT_HEADERS, ACTIVITY_PUB } from '../initializers/constants' import { fetchRemoteAccount, saveAccountAndServerIfNotExist } from '../lib/activitypub'
import { fetchRemoteAccount, saveAccountAndServerIfNotExist } from '../lib/activitypub/account' import { AccountModel } from '../models/account/account'
async function checkSignature (req: Request, res: Response, next: NextFunction) { async function checkSignature (req: Request, res: Response, next: NextFunction) {
const signatureObject: ActivityPubSignature = req.body.signature const signatureObject: ActivityPubSignature = req.body.signature
logger.debug('Checking signature of account %s...', signatureObject.creator) logger.debug('Checking signature of account %s...', signatureObject.creator)
let account = await db.Account.loadByUrl(signatureObject.creator) let account = await AccountModel.loadByUrl(signatureObject.creator)
// We don't have this account in our database, fetch it on remote // We don't have this account in our database, fetch it on remote
if (!account) { if (!account) {

View File

@ -1,8 +1,6 @@
import 'express-validator'
import * as express from 'express' import * as express from 'express'
import 'express-validator'
import { SortType } from '../helpers' import { SortType } from '../helpers'
import { database } from '../initializers'
function setUsersSort (req: express.Request, res: express.Response, next: express.NextFunction) { function setUsersSort (req: express.Request, res: express.Response, next: express.NextFunction) {
if (!req.query.sort) req.query.sort = '-createdAt' if (!req.query.sort) req.query.sort = '-createdAt'
@ -57,7 +55,7 @@ function setBlacklistSort (req: express.Request, res: express.Response, next: ex
// If we want to sort onto the BlacklistedVideos relation, we won't specify it in the query parameter ... // If we want to sort onto the BlacklistedVideos relation, we won't specify it in the query parameter ...
newSort.sortModel = undefined newSort.sortModel = undefined
} else { } else {
newSort.sortModel = database.Video newSort.sortModel = 'Video'
} }
newSort.sortValue = req.query.sort newSort.sortValue = req.query.sort

View File

@ -1,13 +1,12 @@
import 'express-validator'
import * as express from 'express' import * as express from 'express'
import 'express-validator'
import { UserInstance } from '../models'
import { UserRight } from '../../shared' import { UserRight } from '../../shared'
import { logger } from '../helpers' import { logger } from '../helpers'
import { UserModel } from '../models/account/user'
function ensureUserHasRight (userRight: UserRight) { function ensureUserHasRight (userRight: UserRight) {
return function (req: express.Request, res: express.Response, next: express.NextFunction) { return function (req: express.Request, res: express.Response, next: express.NextFunction) {
const user: UserInstance = res.locals.oauth.token.user const user = res.locals.oauth.token.user as UserModel
if (user.hasRight(userRight) === false) { if (user.hasRight(userRight) === false) {
logger.info('User %s does not have right %s to access to %s.', user.username, UserRight[userRight], req.path) logger.info('User %s does not have right %s to access to %s.', user.username, UserRight[userRight], req.path)
return res.sendStatus(403) return res.sendStatus(403)

View File

@ -1,7 +1,7 @@
import * as express from 'express' import * as express from 'express'
import { param } from 'express-validator/check' import { param } from 'express-validator/check'
import { logger, isLocalAccountNameExist } from '../../helpers' import { logger } from '../../helpers'
import { isAccountNameValid } from '../../helpers/custom-validators/accounts' import { isAccountNameValid, isLocalAccountNameExist } from '../../helpers/custom-validators/accounts'
import { areValidationErrors } from './utils' import { areValidationErrors } from './utils'
const localAccountValidator = [ const localAccountValidator = [

View File

@ -1,6 +1,7 @@
import * as express from 'express' import * as express from 'express'
import { body } from 'express-validator/check' import { body } from 'express-validator/check'
import { isRootActivityValid, logger } from '../../../helpers' import { logger } from '../../../helpers'
import { isRootActivityValid } from '../../../helpers/custom-validators/activitypub'
import { areValidationErrors } from '../utils' import { areValidationErrors } from '../utils'
const activityPubValidator = [ const activityPubValidator = [

View File

@ -1,6 +1,8 @@
import * as express from 'express' import * as express from 'express'
import { body } from 'express-validator/check' import { body } from 'express-validator/check'
import { isDateValid, isSignatureCreatorValid, isSignatureTypeValid, isSignatureValueValid, logger } from '../../../helpers' import { logger } from '../../../helpers'
import { isSignatureCreatorValid, isSignatureTypeValid, isSignatureValueValid } from '../../../helpers/custom-validators/activitypub'
import { isDateValid } from '../../../helpers/custom-validators/misc'
import { areValidationErrors } from '../utils' import { areValidationErrors } from '../utils'
const signatureValidator = [ const signatureValidator = [

View File

@ -1,12 +1,11 @@
import * as express from 'express' import * as express from 'express'
import { body, param } from 'express-validator/check' import { body, param } from 'express-validator/check'
import { isTestInstance } from '../../helpers/core-utils' import { getServerAccount, isTestInstance, logger } from '../../helpers'
import { isEachUniqueHostValid } from '../../helpers/custom-validators/servers'
import { logger } from '../../helpers/logger'
import { CONFIG, database as db } from '../../initializers'
import { areValidationErrors } from './utils'
import { getServerAccount } from '../../helpers/utils'
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc' import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
import { isEachUniqueHostValid } from '../../helpers/custom-validators/servers'
import { CONFIG } from '../../initializers'
import { AccountFollowModel } from '../../models/account/account-follow'
import { areValidationErrors } from './utils'
const followValidator = [ const followValidator = [
body('hosts').custom(isEachUniqueHostValid).withMessage('Should have an array of unique hosts'), body('hosts').custom(isEachUniqueHostValid).withMessage('Should have an array of unique hosts'),
@ -38,7 +37,7 @@ const removeFollowingValidator = [
if (areValidationErrors(req, res)) return if (areValidationErrors(req, res)) return
const serverAccount = await getServerAccount() const serverAccount = await getServerAccount()
const follow = await db.AccountFollow.loadByAccountAndTarget(serverAccount.id, req.params.accountId) const follow = await AccountFollowModel.loadByAccountAndTarget(serverAccount.id, req.params.accountId)
if (!follow) { if (!follow) {
return res.status(404) return res.status(404)

View File

@ -1,10 +1,11 @@
import * as express from 'express' import * as express from 'express'
import { query } from 'express-validator/check' import { query } from 'express-validator/check'
import { join } from 'path' import { join } from 'path'
import { isIdOrUUIDValid, isTestInstance, logger } from '../../helpers' import { isTestInstance, logger } from '../../helpers'
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
import { isVideoExist } from '../../helpers/custom-validators/videos'
import { CONFIG } from '../../initializers' import { CONFIG } from '../../initializers'
import { areValidationErrors } from './utils' import { areValidationErrors } from './utils'
import { isVideoExist } from '../../helpers/custom-validators/videos'
const urlShouldStartWith = CONFIG.WEBSERVER.SCHEME + '://' + join(CONFIG.WEBSERVER.HOST, 'videos', 'watch') + '/' const urlShouldStartWith = CONFIG.WEBSERVER.SCHEME + '://' + join(CONFIG.WEBSERVER.HOST, 'videos', 'watch') + '/'
const videoWatchRegex = new RegExp('([^/]+)$') const videoWatchRegex = new RegExp('([^/]+)$')

View File

@ -1,6 +1,5 @@
import { query } from 'express-validator/check' import { query } from 'express-validator/check'
import * as express from 'express' import * as express from 'express'
import { logger } from '../../helpers' import { logger } from '../../helpers'
import { SORTABLE_COLUMNS } from '../../initializers' import { SORTABLE_COLUMNS } from '../../initializers'
import { areValidationErrors } from './utils' import { areValidationErrors } from './utils'

View File

@ -1,18 +1,17 @@
import * as express from 'express' import * as express from 'express'
import 'express-validator' import 'express-validator'
import { body, param } from 'express-validator/check' import { body, param } from 'express-validator/check'
import { isSignupAllowed, logger } from '../../helpers'
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
import { import {
isIdOrUUIDValid,
isSignupAllowed,
isUserDisplayNSFWValid, isUserDisplayNSFWValid,
isUserPasswordValid, isUserPasswordValid,
isUserRoleValid, isUserRoleValid,
isUserUsernameValid, isUserUsernameValid,
isUserVideoQuotaValid, isUserVideoQuotaValid
logger } from '../../helpers/custom-validators/users'
} from '../../helpers'
import { isVideoExist } from '../../helpers/custom-validators/videos' import { isVideoExist } from '../../helpers/custom-validators/videos'
import { database as db } from '../../initializers/database' import { UserModel } from '../../models/account/user'
import { areValidationErrors } from './utils' import { areValidationErrors } from './utils'
const usersAddValidator = [ const usersAddValidator = [
@ -153,7 +152,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
async function checkUserIdExist (id: number, res: express.Response) { async function checkUserIdExist (id: number, res: express.Response) {
const user = await db.User.loadById(id) const user = await UserModel.loadById(id)
if (!user) { if (!user) {
res.status(404) res.status(404)
@ -168,7 +167,7 @@ async function checkUserIdExist (id: number, res: express.Response) {
} }
async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: string, res: express.Response) { async function checkUserNameOrEmailDoesNotAlreadyExist (username: string, email: string, res: express.Response) {
const user = await db.User.loadByUsernameOrEmail(username, email) const user = await UserModel.loadByUsernameOrEmail(username, email)
if (user) { if (user) {
res.status(409) res.status(409)

View File

@ -1,6 +1,5 @@
import * as express from 'express' import * as express from 'express'
import { validationResult } from 'express-validator/check' import { validationResult } from 'express-validator/check'
import { logger } from '../../helpers' import { logger } from '../../helpers'
function areValidationErrors (req: express.Request, res: express.Response) { function areValidationErrors (req: express.Request, res: express.Response) {

View File

@ -1,9 +1,10 @@
import * as express from 'express' import * as express from 'express'
import { param } from 'express-validator/check' import { param } from 'express-validator/check'
import { isIdOrUUIDValid, logger } from '../../helpers' import { logger } from '../../helpers'
import { isIdOrUUIDValid } from '../../helpers/custom-validators/misc'
import { isVideoExist } from '../../helpers/custom-validators/videos' import { isVideoExist } from '../../helpers/custom-validators/videos'
import { database as db } from '../../initializers/database' import { VideoModel } from '../../models/video/video'
import { VideoInstance } from '../../models/video/video-interface' import { VideoBlacklistModel } from '../../models/video/video-blacklist'
import { areValidationErrors } from './utils' import { areValidationErrors } from './utils'
const videosBlacklistRemoveValidator = [ const videosBlacklistRemoveValidator = [
@ -42,7 +43,7 @@ export {
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function checkVideoIsBlacklistable (video: VideoInstance, res: express.Response) { function checkVideoIsBlacklistable (video: VideoModel, res: express.Response) {
if (video.isOwned() === true) { if (video.isOwned() === true) {
res.status(403) res.status(403)
.json({ error: 'Cannot blacklist a local video' }) .json({ error: 'Cannot blacklist a local video' })
@ -54,8 +55,8 @@ function checkVideoIsBlacklistable (video: VideoInstance, res: express.Response)
return true return true
} }
async function checkVideoIsBlacklisted (video: VideoInstance, res: express.Response) { async function checkVideoIsBlacklisted (video: VideoModel, res: express.Response) {
const blacklistedVideo = await db.BlacklistedVideo.loadByVideoId(video.id) const blacklistedVideo = await VideoBlacklistModel.loadByVideoId(video.id)
if (!blacklistedVideo) { if (!blacklistedVideo) {
res.status(404) res.status(404)
.send('Blacklisted video not found') .send('Blacklisted video not found')

View File

@ -1,19 +1,18 @@
import * as express from 'express' import * as express from 'express'
import { body, param } from 'express-validator/check' import { body, param } from 'express-validator/check'
import { UserRight } from '../../../shared' import { UserRight } from '../../../shared'
import { isIdValid } from '../../helpers/custom-validators/misc' import { logger } from '../../helpers'
import { isAccountIdExist } from '../../helpers/custom-validators/accounts'
import { isIdOrUUIDValid, isIdValid } from '../../helpers/custom-validators/misc'
import { import {
isVideoChannelDescriptionValid, isVideoChannelDescriptionValid,
isVideoChannelExist, isVideoChannelExist,
isVideoChannelNameValid isVideoChannelNameValid
} from '../../helpers/custom-validators/video-channels' } from '../../helpers/custom-validators/video-channels'
import { isIdOrUUIDValid } from '../../helpers/index' import { UserModel } from '../../models/account/user'
import { logger } from '../../helpers/logger' import { VideoChannelModel } from '../../models/video/video-channel'
import { database as db } from '../../initializers' import { VideoChannelShareModel } from '../../models/video/video-channel-share'
import { UserInstance } from '../../models'
import { areValidationErrors } from './utils' import { areValidationErrors } from './utils'
import { isAccountIdExist } from '../../helpers/custom-validators/accounts'
import { VideoChannelInstance } from '../../models/video/video-channel-interface'
const listVideoAccountChannelsValidator = [ const listVideoAccountChannelsValidator = [
param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'), param('accountId').custom(isIdOrUUIDValid).withMessage('Should have a valid account id'),
@ -109,7 +108,7 @@ const videoChannelsShareValidator = [
if (areValidationErrors(req, res)) return if (areValidationErrors(req, res)) return
if (!await isVideoChannelExist(req.params.id, res)) return if (!await isVideoChannelExist(req.params.id, res)) return
const share = await db.VideoChannelShare.load(res.locals.video.id, req.params.accountId, undefined) const share = await VideoChannelShareModel.load(res.locals.video.id, req.params.accountId, undefined)
if (!share) { if (!share) {
return res.status(404) return res.status(404)
.end() .end()
@ -134,7 +133,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function checkUserCanDeleteVideoChannel (user: UserInstance, videoChannel: VideoChannelInstance, res: express.Response) { function checkUserCanDeleteVideoChannel (user: UserModel, videoChannel: VideoChannelModel, res: express.Response) {
// Retrieve the user who did the request // Retrieve the user who did the request
if (videoChannel.isOwned() === false) { if (videoChannel.isOwned() === false) {
res.status(403) res.status(403)
@ -159,7 +158,7 @@ function checkUserCanDeleteVideoChannel (user: UserInstance, videoChannel: Video
} }
async function checkVideoChannelIsNotTheLastOne (res: express.Response) { async function checkVideoChannelIsNotTheLastOne (res: express.Response) {
const count = await db.VideoChannel.countByAccount(res.locals.oauth.token.User.Account.id) const count = await VideoChannelModel.countByAccount(res.locals.oauth.token.User.Account.id)
if (count <= 1) { if (count <= 1) {
res.status(409) res.status(409)

View File

@ -1,6 +1,8 @@
import * as express from 'express' import * as express from 'express'
import 'express-validator'
import { body, param, query } from 'express-validator/check' import { body, param, query } from 'express-validator/check'
import { UserRight, VideoPrivacy } from '../../../shared' import { UserRight, VideoPrivacy } from '../../../shared'
import { getDurationFromVideoFile, logger } from '../../helpers'
import { isIdOrUUIDValid, isIdValid } from '../../helpers/custom-validators/misc' import { isIdOrUUIDValid, isIdValid } from '../../helpers/custom-validators/misc'
import { import {
isVideoAbuseReasonValid, isVideoAbuseReasonValid,
@ -16,12 +18,11 @@ import {
isVideoRatingTypeValid, isVideoRatingTypeValid,
isVideoTagsValid isVideoTagsValid
} from '../../helpers/custom-validators/videos' } from '../../helpers/custom-validators/videos'
import { getDurationFromVideoFile } from '../../helpers/ffmpeg-utils'
import { logger } from '../../helpers/logger'
import { CONSTRAINTS_FIELDS } from '../../initializers' import { CONSTRAINTS_FIELDS } from '../../initializers'
import { database as db } from '../../initializers/database' import { UserModel } from '../../models/account/user'
import { UserInstance } from '../../models/account/user-interface' import { VideoModel } from '../../models/video/video'
import { VideoInstance } from '../../models/video/video-interface' import { VideoChannelModel } from '../../models/video/video-channel'
import { VideoShareModel } from '../../models/video/video-share'
import { authenticate } from '../oauth' import { authenticate } from '../oauth'
import { areValidationErrors } from './utils' import { areValidationErrors } from './utils'
@ -48,7 +49,7 @@ const videosAddValidator = [
const videoFile: Express.Multer.File = req.files['videofile'][0] const videoFile: Express.Multer.File = req.files['videofile'][0]
const user = res.locals.oauth.token.User const user = res.locals.oauth.token.User
const videoChannel = await db.VideoChannel.loadByIdAndAccount(req.body.channelId, user.Account.id) const videoChannel = await VideoChannelModel.loadByIdAndAccount(req.body.channelId, user.Account.id)
if (!videoChannel) { if (!videoChannel) {
res.status(400) res.status(400)
.json({ error: 'Unknown video video channel for this account.' }) .json({ error: 'Unknown video video channel for this account.' })
@ -221,7 +222,7 @@ const videosShareValidator = [
if (areValidationErrors(req, res)) return if (areValidationErrors(req, res)) return
if (!await isVideoExist(req.params.id, res)) return if (!await isVideoExist(req.params.id, res)) return
const share = await db.VideoShare.load(req.params.accountId, res.locals.video.id, undefined) const share = await VideoShareModel.load(req.params.accountId, res.locals.video.id, undefined)
if (!share) { if (!share) {
return res.status(404) return res.status(404)
.end() .end()
@ -249,7 +250,7 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function checkUserCanDeleteVideo (user: UserInstance, video: VideoInstance, res: express.Response) { function checkUserCanDeleteVideo (user: UserModel, video: VideoModel, res: express.Response) {
// Retrieve the user who did the request // Retrieve the user who did the request
if (video.isOwned() === false) { if (video.isOwned() === false) {
res.status(403) res.status(403)

View File

@ -1,8 +1,8 @@
import * as express from 'express' import * as express from 'express'
import { query } from 'express-validator/check' import { query } from 'express-validator/check'
import { logger } from '../../helpers'
import { isWebfingerResourceValid } from '../../helpers/custom-validators/webfinger' import { isWebfingerResourceValid } from '../../helpers/custom-validators/webfinger'
import { logger } from '../../helpers/logger' import { AccountModel } from '../../models/account/account'
import { database as db } from '../../initializers'
import { areValidationErrors } from './utils' import { areValidationErrors } from './utils'
const webfingerValidator = [ const webfingerValidator = [
@ -17,7 +17,7 @@ const webfingerValidator = [
const nameWithHost = req.query.resource.substr(5) const nameWithHost = req.query.resource.substr(5)
const [ name ] = nameWithHost.split('@') const [ name ] = nameWithHost.split('@')
const account = await db.Account.loadLocalByName(name) const account = await AccountModel.loadLocalByName(name)
if (!account) { if (!account) {
return res.status(404) return res.status(404)
.send({ error: 'Account not found' }) .send({ error: 'Account not found' })

Some files were not shown because too many files have changed in this diff Show More