diff options
Diffstat (limited to 'server/models')
-rw-r--r-- | server/models/account/account-video-rate.ts | 24 | ||||
-rw-r--r-- | server/models/activitypub/actor-follow.ts | 26 | ||||
-rw-r--r-- | server/models/utils.ts | 20 | ||||
-rw-r--r-- | server/models/video/video-comment.ts | 38 | ||||
-rw-r--r-- | server/models/video/video-share.ts | 18 |
5 files changed, 66 insertions, 60 deletions
diff --git a/server/models/account/account-video-rate.ts b/server/models/account/account-video-rate.ts index d5c214ecb..4bd8114cf 100644 --- a/server/models/account/account-video-rate.ts +++ b/server/models/account/account-video-rate.ts | |||
@@ -6,7 +6,7 @@ import { CONSTRAINTS_FIELDS, VIDEO_RATE_TYPES } from '../../initializers/constan | |||
6 | import { VideoModel } from '../video/video' | 6 | import { VideoModel } from '../video/video' |
7 | import { AccountModel } from './account' | 7 | import { AccountModel } from './account' |
8 | import { ActorModel } from '../activitypub/actor' | 8 | import { ActorModel } from '../activitypub/actor' |
9 | import { getSort, throwIfNotValid } from '../utils' | 9 | import { buildLocalAccountIdsIn, getSort, throwIfNotValid } from '../utils' |
10 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' | 10 | import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' |
11 | import { AccountVideoRate } from '../../../shared' | 11 | import { AccountVideoRate } from '../../../shared' |
12 | import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from '../video/video-channel' | 12 | import { ScopeNames as VideoChannelScopeNames, SummaryOptions, VideoChannelModel } from '../video/video-channel' |
@@ -219,25 +219,11 @@ export class AccountVideoRateModel extends Model<AccountVideoRateModel> { | |||
219 | [Op.lt]: beforeUpdatedAt | 219 | [Op.lt]: beforeUpdatedAt |
220 | }, | 220 | }, |
221 | videoId, | 221 | videoId, |
222 | type | 222 | type, |
223 | }, | 223 | accountId: { |
224 | include: [ | 224 | [Op.notIn]: buildLocalAccountIdsIn() |
225 | { | ||
226 | model: AccountModel.unscoped(), | ||
227 | required: true, | ||
228 | include: [ | ||
229 | { | ||
230 | model: ActorModel.unscoped(), | ||
231 | required: true, | ||
232 | where: { | ||
233 | serverId: { | ||
234 | [Op.ne]: null | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | ] | ||
239 | } | 225 | } |
240 | ], | 226 | }, |
241 | transaction: t | 227 | transaction: t |
242 | } | 228 | } |
243 | 229 | ||
diff --git a/server/models/activitypub/actor-follow.ts b/server/models/activitypub/actor-follow.ts index 3039b90c7..99a5fd117 100644 --- a/server/models/activitypub/actor-follow.ts +++ b/server/models/activitypub/actor-follow.ts | |||
@@ -23,7 +23,7 @@ import { logger } from '../../helpers/logger' | |||
23 | import { getServerActor } from '../../helpers/utils' | 23 | import { getServerActor } from '../../helpers/utils' |
24 | import { ACTOR_FOLLOW_SCORE, FOLLOW_STATES } from '../../initializers/constants' | 24 | import { ACTOR_FOLLOW_SCORE, FOLLOW_STATES } from '../../initializers/constants' |
25 | import { ServerModel } from '../server/server' | 25 | import { ServerModel } from '../server/server' |
26 | import { getSort } from '../utils' | 26 | import { createSafeIn, getSort } from '../utils' |
27 | import { ActorModel, unusedActorAttributesForAPI } from './actor' | 27 | import { ActorModel, unusedActorAttributesForAPI } from './actor' |
28 | import { VideoChannelModel } from '../video/video-channel' | 28 | import { VideoChannelModel } from '../video/video-channel' |
29 | import { AccountModel } from '../account/account' | 29 | import { AccountModel } from '../account/account' |
@@ -464,7 +464,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> { | |||
464 | } | 464 | } |
465 | } | 465 | } |
466 | 466 | ||
467 | static updateFollowScore (inboxUrl: string, value: number, t?: Transaction) { | 467 | static updateScore (inboxUrl: string, value: number, t?: Transaction) { |
468 | const query = `UPDATE "actorFollow" SET "score" = LEAST("score" + ${value}, ${ACTOR_FOLLOW_SCORE.MAX}) ` + | 468 | const query = `UPDATE "actorFollow" SET "score" = LEAST("score" + ${value}, ${ACTOR_FOLLOW_SCORE.MAX}) ` + |
469 | 'WHERE id IN (' + | 469 | 'WHERE id IN (' + |
470 | 'SELECT "actorFollow"."id" FROM "actorFollow" ' + | 470 | 'SELECT "actorFollow"."id" FROM "actorFollow" ' + |
@@ -480,6 +480,28 @@ export class ActorFollowModel extends Model<ActorFollowModel> { | |||
480 | return ActorFollowModel.sequelize.query(query, options) | 480 | return ActorFollowModel.sequelize.query(query, options) |
481 | } | 481 | } |
482 | 482 | ||
483 | static async updateScoreByFollowingServers (serverIds: number[], value: number, t?: Transaction) { | ||
484 | if (serverIds.length === 0) return | ||
485 | |||
486 | const me = await getServerActor() | ||
487 | const serverIdsString = createSafeIn(ActorFollowModel, serverIds) | ||
488 | |||
489 | const query = `UPDATE "actorFollow" SET "score" = "score" + ${value} ` + | ||
490 | 'WHERE id IN (' + | ||
491 | 'SELECT "actorFollow"."id" FROM "actorFollow" ' + | ||
492 | 'INNER JOIN "actor" ON "actor"."id" = "actorFollow"."targetActorId" ' + | ||
493 | `WHERE "actorFollow"."actorId" = ${me.Account.actorId} ` + // I'm the follower | ||
494 | `AND "actor"."serverId" IN (${serverIdsString})` + // Criteria on followings | ||
495 | ')' | ||
496 | |||
497 | const options = { | ||
498 | type: QueryTypes.BULKUPDATE, | ||
499 | transaction: t | ||
500 | } | ||
501 | |||
502 | return ActorFollowModel.sequelize.query(query, options) | ||
503 | } | ||
504 | |||
483 | private static async createListAcceptedFollowForApiQuery ( | 505 | private static async createListAcceptedFollowForApiQuery ( |
484 | type: 'followers' | 'following', | 506 | type: 'followers' | 'following', |
485 | actorIds: number[], | 507 | actorIds: number[], |
diff --git a/server/models/utils.ts b/server/models/utils.ts index 30de91e1d..24890f961 100644 --- a/server/models/utils.ts +++ b/server/models/utils.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import { Model, Sequelize } from 'sequelize-typescript' | 1 | import { Model, Sequelize } from 'sequelize-typescript' |
2 | import * as validator from 'validator' | 2 | import * as validator from 'validator' |
3 | import { Col } from 'sequelize/types/lib/utils' | 3 | import { Col } from 'sequelize/types/lib/utils' |
4 | import { OrderItem } from 'sequelize/types' | 4 | import { OrderItem, literal } from 'sequelize' |
5 | 5 | ||
6 | type SortType = { sortModel: any, sortValue: string } | 6 | type SortType = { sortModel: any, sortValue: string } |
7 | 7 | ||
@@ -129,16 +129,30 @@ function parseAggregateResult (result: any) { | |||
129 | return total | 129 | return total |
130 | } | 130 | } |
131 | 131 | ||
132 | const createSafeIn = (model: typeof Model, stringArr: string[]) => { | 132 | const createSafeIn = (model: typeof Model, stringArr: (string | number)[]) => { |
133 | return stringArr.map(t => model.sequelize.escape(t)) | 133 | return stringArr.map(t => model.sequelize.escape('' + t)) |
134 | .join(', ') | 134 | .join(', ') |
135 | } | 135 | } |
136 | 136 | ||
137 | function buildLocalAccountIdsIn () { | ||
138 | return literal( | ||
139 | '(SELECT "account"."id" FROM "account" INNER JOIN "actor" ON "actor"."id" = "account"."actorId" AND "actor"."serverId" IS NULL)' | ||
140 | ) | ||
141 | } | ||
142 | |||
143 | function buildLocalActorIdsIn () { | ||
144 | return literal( | ||
145 | '(SELECT "actor"."id" FROM "actor" WHERE "actor"."serverId" IS NULL)' | ||
146 | ) | ||
147 | } | ||
148 | |||
137 | // --------------------------------------------------------------------------- | 149 | // --------------------------------------------------------------------------- |
138 | 150 | ||
139 | export { | 151 | export { |
140 | buildBlockedAccountSQL, | 152 | buildBlockedAccountSQL, |
153 | buildLocalActorIdsIn, | ||
141 | SortType, | 154 | SortType, |
155 | buildLocalAccountIdsIn, | ||
142 | getSort, | 156 | getSort, |
143 | getVideoSort, | 157 | getVideoSort, |
144 | getSortOnModel, | 158 | getSortOnModel, |
diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts index 28e5818cd..6eda32f05 100644 --- a/server/models/video/video-comment.ts +++ b/server/models/video/video-comment.ts | |||
@@ -22,7 +22,7 @@ import { AccountModel } from '../account/account' | |||
22 | import { ActorModel } from '../activitypub/actor' | 22 | import { ActorModel } from '../activitypub/actor' |
23 | import { AvatarModel } from '../avatar/avatar' | 23 | import { AvatarModel } from '../avatar/avatar' |
24 | import { ServerModel } from '../server/server' | 24 | import { ServerModel } from '../server/server' |
25 | import { buildBlockedAccountSQL, getSort, throwIfNotValid } from '../utils' | 25 | import { buildBlockedAccountSQL, buildLocalAccountIdsIn, getSort, throwIfNotValid } from '../utils' |
26 | import { VideoModel } from './video' | 26 | import { VideoModel } from './video' |
27 | import { VideoChannelModel } from './video-channel' | 27 | import { VideoChannelModel } from './video-channel' |
28 | import { getServerActor } from '../../helpers/utils' | 28 | import { getServerActor } from '../../helpers/utils' |
@@ -30,7 +30,7 @@ import { UserModel } from '../account/user' | |||
30 | import { actorNameAlphabet } from '../../helpers/custom-validators/activitypub/actor' | 30 | import { actorNameAlphabet } from '../../helpers/custom-validators/activitypub/actor' |
31 | import { regexpCapture } from '../../helpers/regexp' | 31 | import { regexpCapture } from '../../helpers/regexp' |
32 | import { uniq } from 'lodash' | 32 | import { uniq } from 'lodash' |
33 | import { FindOptions, Op, Order, ScopeOptions, Sequelize, Transaction } from 'sequelize' | 33 | import { FindOptions, literal, Op, Order, ScopeOptions, Sequelize, Transaction } from 'sequelize' |
34 | 34 | ||
35 | enum ScopeNames { | 35 | enum ScopeNames { |
36 | WITH_ACCOUNT = 'WITH_ACCOUNT', | 36 | WITH_ACCOUNT = 'WITH_ACCOUNT', |
@@ -281,16 +281,22 @@ export class VideoCommentModel extends Model<VideoCommentModel> { | |||
281 | return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT ]).findOne(query) | 281 | return VideoCommentModel.scope([ ScopeNames.WITH_ACCOUNT ]).findOne(query) |
282 | } | 282 | } |
283 | 283 | ||
284 | static loadByUrlAndPopulateReplyAndVideo (url: string, t?: Transaction) { | 284 | static loadByUrlAndPopulateReplyAndVideoUrlAndAccount (url: string, t?: Transaction) { |
285 | const query: FindOptions = { | 285 | const query: FindOptions = { |
286 | where: { | 286 | where: { |
287 | url | 287 | url |
288 | } | 288 | }, |
289 | include: [ | ||
290 | { | ||
291 | attributes: [ 'id', 'url' ], | ||
292 | model: VideoModel.unscoped() | ||
293 | } | ||
294 | ] | ||
289 | } | 295 | } |
290 | 296 | ||
291 | if (t !== undefined) query.transaction = t | 297 | if (t !== undefined) query.transaction = t |
292 | 298 | ||
293 | return VideoCommentModel.scope([ ScopeNames.WITH_IN_REPLY_TO, ScopeNames.WITH_VIDEO ]).findOne(query) | 299 | return VideoCommentModel.scope([ ScopeNames.WITH_IN_REPLY_TO, ScopeNames.WITH_ACCOUNT ]).findOne(query) |
294 | } | 300 | } |
295 | 301 | ||
296 | static async listThreadsForApi (parameters: { | 302 | static async listThreadsForApi (parameters: { |
@@ -471,25 +477,11 @@ export class VideoCommentModel extends Model<VideoCommentModel> { | |||
471 | updatedAt: { | 477 | updatedAt: { |
472 | [Op.lt]: beforeUpdatedAt | 478 | [Op.lt]: beforeUpdatedAt |
473 | }, | 479 | }, |
474 | videoId | 480 | videoId, |
475 | }, | 481 | accountId: { |
476 | include: [ | 482 | [Op.notIn]: buildLocalAccountIdsIn() |
477 | { | ||
478 | required: true, | ||
479 | model: AccountModel.unscoped(), | ||
480 | include: [ | ||
481 | { | ||
482 | required: true, | ||
483 | model: ActorModel.unscoped(), | ||
484 | where: { | ||
485 | serverId: { | ||
486 | [Op.ne]: null | ||
487 | } | ||
488 | } | ||
489 | } | ||
490 | ] | ||
491 | } | 483 | } |
492 | ] | 484 | } |
493 | } | 485 | } |
494 | 486 | ||
495 | return VideoCommentModel.destroy(query) | 487 | return VideoCommentModel.destroy(query) |
diff --git a/server/models/video/video-share.ts b/server/models/video/video-share.ts index 3bab3c027..d8ed64557 100644 --- a/server/models/video/video-share.ts +++ b/server/models/video/video-share.ts | |||
@@ -4,7 +4,7 @@ import { isActivityPubUrlValid } from '../../helpers/custom-validators/activityp | |||
4 | import { CONSTRAINTS_FIELDS } from '../../initializers/constants' | 4 | import { CONSTRAINTS_FIELDS } from '../../initializers/constants' |
5 | import { AccountModel } from '../account/account' | 5 | import { AccountModel } from '../account/account' |
6 | import { ActorModel } from '../activitypub/actor' | 6 | import { ActorModel } from '../activitypub/actor' |
7 | import { throwIfNotValid } from '../utils' | 7 | import { buildLocalActorIdsIn, throwIfNotValid } from '../utils' |
8 | import { VideoModel } from './video' | 8 | import { VideoModel } from './video' |
9 | import { VideoChannelModel } from './video-channel' | 9 | import { VideoChannelModel } from './video-channel' |
10 | import { Op, Transaction } from 'sequelize' | 10 | import { Op, Transaction } from 'sequelize' |
@@ -207,19 +207,11 @@ export class VideoShareModel extends Model<VideoShareModel> { | |||
207 | updatedAt: { | 207 | updatedAt: { |
208 | [Op.lt]: beforeUpdatedAt | 208 | [Op.lt]: beforeUpdatedAt |
209 | }, | 209 | }, |
210 | videoId | 210 | videoId, |
211 | }, | 211 | actorId: { |
212 | include: [ | 212 | [Op.notIn]: buildLocalActorIdsIn() |
213 | { | ||
214 | model: ActorModel.unscoped(), | ||
215 | required: true, | ||
216 | where: { | ||
217 | serverId: { | ||
218 | [ Op.ne ]: null | ||
219 | } | ||
220 | } | ||
221 | } | 213 | } |
222 | ] | 214 | } |
223 | } | 215 | } |
224 | 216 | ||
225 | return VideoShareModel.destroy(query) | 217 | return VideoShareModel.destroy(query) |