mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2024-09-11 21:47:09 +03:00
Move models to typescript-sequelize
This commit is contained in:
parent
c893d4514e
commit
3fd3ab2d34
@ -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",
|
||||||
|
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
@ -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>[] = []
|
||||||
|
@ -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'
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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 = {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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 = {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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>
|
||||||
|
@ -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) {
|
||||||
|
@ -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'
|
||||||
|
@ -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']) &&
|
||||||
|
@ -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 = {
|
||||||
|
@ -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'
|
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -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) {
|
||||||
|
@ -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'
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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'
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -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)
|
|
||||||
}
|
}
|
||||||
|
@ -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.')
|
||||||
|
|
||||||
|
@ -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 => {
|
||||||
|
@ -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()
|
||||||
|
@ -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')
|
||||||
}
|
}
|
||||||
|
@ -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')
|
||||||
}
|
}
|
||||||
|
@ -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()
|
||||||
|
|
||||||
|
@ -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> {
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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 ]
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
})
|
})
|
||||||
|
@ -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')
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
})
|
})
|
||||||
|
@ -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 })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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}.`)
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -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,
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
}
|
||||||
|
@ -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 })
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
13
server/lib/cache/videos-preview-cache.ts
vendored
13
server/lib/cache/videos-preview-cache.ts
vendored
@ -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) => {
|
||||||
|
@ -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) {
|
||||||
|
@ -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) {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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 }
|
||||||
|
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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 = [
|
||||||
|
@ -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 = [
|
||||||
|
@ -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 = [
|
||||||
|
@ -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)
|
||||||
|
@ -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('([^/]+)$')
|
||||||
|
@ -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'
|
||||||
|
@ -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)
|
||||||
|
@ -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) {
|
||||||
|
@ -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')
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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
Loading…
Reference in New Issue
Block a user