diff options
author | Chocobozzz <me@florianbigard.com> | 2018-01-11 09:35:50 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2018-01-11 09:35:50 +0100 |
commit | 60650c77c8a2a98e92d869b237ae4900f369a8fc (patch) | |
tree | 7304a7591b5b23b99d219c4d06c6bd5c4c58c1c2 /server/models/activitypub | |
parent | 7ae71355c40e9065f83d3fc77b6750d1929ac201 (diff) | |
download | PeerTube-60650c77c8a2a98e92d869b237ae4900f369a8fc.tar.gz PeerTube-60650c77c8a2a98e92d869b237ae4900f369a8fc.tar.zst PeerTube-60650c77c8a2a98e92d869b237ae4900f369a8fc.zip |
Add scores to follows and remove bad ones
Diffstat (limited to 'server/models/activitypub')
-rw-r--r-- | server/models/activitypub/actor-follow.ts | 79 | ||||
-rw-r--r-- | server/models/activitypub/actor.ts | 13 |
2 files changed, 82 insertions, 10 deletions
diff --git a/server/models/activitypub/actor-follow.ts b/server/models/activitypub/actor-follow.ts index 5fcc3449d..78a65a0ff 100644 --- a/server/models/activitypub/actor-follow.ts +++ b/server/models/activitypub/actor-follow.ts | |||
@@ -1,8 +1,14 @@ | |||
1 | import * as Bluebird from 'bluebird' | 1 | import * as Bluebird from 'bluebird' |
2 | import { values } from 'lodash' | 2 | import { values } from 'lodash' |
3 | import * as Sequelize from 'sequelize' | 3 | import * as Sequelize from 'sequelize' |
4 | import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript' | 4 | import { |
5 | AllowNull, BelongsTo, Column, CreatedAt, DataType, Default, ForeignKey, IsInt, Max, Model, Table, | ||
6 | UpdatedAt | ||
7 | } from 'sequelize-typescript' | ||
5 | import { FollowState } from '../../../shared/models/actors' | 8 | import { FollowState } from '../../../shared/models/actors' |
9 | import { AccountFollow } from '../../../shared/models/actors/follow.model' | ||
10 | import { logger } from '../../helpers/logger' | ||
11 | import { ACTOR_FOLLOW_SCORE } from '../../initializers' | ||
6 | import { FOLLOW_STATES } from '../../initializers/constants' | 12 | import { FOLLOW_STATES } from '../../initializers/constants' |
7 | import { ServerModel } from '../server/server' | 13 | import { ServerModel } from '../server/server' |
8 | import { getSort } from '../utils' | 14 | import { getSort } from '../utils' |
@@ -20,6 +26,9 @@ import { ActorModel } from './actor' | |||
20 | { | 26 | { |
21 | fields: [ 'actorId', 'targetActorId' ], | 27 | fields: [ 'actorId', 'targetActorId' ], |
22 | unique: true | 28 | unique: true |
29 | }, | ||
30 | { | ||
31 | fields: [ 'score' ] | ||
23 | } | 32 | } |
24 | ] | 33 | ] |
25 | }) | 34 | }) |
@@ -29,6 +38,13 @@ export class ActorFollowModel extends Model<ActorFollowModel> { | |||
29 | @Column(DataType.ENUM(values(FOLLOW_STATES))) | 38 | @Column(DataType.ENUM(values(FOLLOW_STATES))) |
30 | state: FollowState | 39 | state: FollowState |
31 | 40 | ||
41 | @AllowNull(false) | ||
42 | @Default(ACTOR_FOLLOW_SCORE.BASE) | ||
43 | @IsInt | ||
44 | @Max(ACTOR_FOLLOW_SCORE.MAX) | ||
45 | @Column | ||
46 | score: number | ||
47 | |||
32 | @CreatedAt | 48 | @CreatedAt |
33 | createdAt: Date | 49 | createdAt: Date |
34 | 50 | ||
@@ -63,6 +79,34 @@ export class ActorFollowModel extends Model<ActorFollowModel> { | |||
63 | }) | 79 | }) |
64 | ActorFollowing: ActorModel | 80 | ActorFollowing: ActorModel |
65 | 81 | ||
82 | // Remove actor follows with a score of 0 (too many requests where they were unreachable) | ||
83 | static async removeBadActorFollows () { | ||
84 | const actorFollows = await ActorFollowModel.listBadActorFollows() | ||
85 | |||
86 | const actorFollowsRemovePromises = actorFollows.map(actorFollow => actorFollow.destroy()) | ||
87 | await Promise.all(actorFollowsRemovePromises) | ||
88 | |||
89 | const numberOfActorFollowsRemoved = actorFollows.length | ||
90 | |||
91 | if (numberOfActorFollowsRemoved) logger.info('Removed bad %d actor follows.', numberOfActorFollowsRemoved) | ||
92 | } | ||
93 | |||
94 | static updateActorFollowsScoreAndRemoveBadOnes (goodInboxes: string[], badInboxes: string[], t: Sequelize.Transaction) { | ||
95 | if (goodInboxes.length === 0 && badInboxes.length === 0) return | ||
96 | |||
97 | logger.info('Updating %d good actor follows and %d bad actor follows scores.', goodInboxes.length, badInboxes.length) | ||
98 | |||
99 | if (goodInboxes.length !== 0) { | ||
100 | ActorFollowModel.incrementScores(goodInboxes, ACTOR_FOLLOW_SCORE.BONUS, t) | ||
101 | .catch(err => logger.error('Cannot increment scores of good actor follows.', err)) | ||
102 | } | ||
103 | |||
104 | if (badInboxes.length !== 0) { | ||
105 | ActorFollowModel.incrementScores(badInboxes, ACTOR_FOLLOW_SCORE.PENALTY, t) | ||
106 | .catch(err => logger.error('Cannot decrement scores of bad actor follows.', err)) | ||
107 | } | ||
108 | } | ||
109 | |||
66 | static loadByActorAndTarget (actorId: number, targetActorId: number, t?: Sequelize.Transaction) { | 110 | static loadByActorAndTarget (actorId: number, targetActorId: number, t?: Sequelize.Transaction) { |
67 | const query = { | 111 | const query = { |
68 | where: { | 112 | where: { |
@@ -260,7 +304,37 @@ export class ActorFollowModel extends Model<ActorFollowModel> { | |||
260 | } | 304 | } |
261 | } | 305 | } |
262 | 306 | ||
263 | toFormattedJSON () { | 307 | private static incrementScores (inboxUrls: string[], value: number, t: Sequelize.Transaction) { |
308 | const inboxUrlsString = inboxUrls.map(url => `'${url}'`).join(',') | ||
309 | |||
310 | const query = 'UPDATE "actorFollow" SET "score" = "score" +' + value + ' ' + | ||
311 | 'WHERE id IN (' + | ||
312 | 'SELECT "actorFollow"."id" FROM "actorFollow" ' + | ||
313 | 'INNER JOIN "actor" ON "actor"."id" = "actorFollow"."actorId" ' + | ||
314 | 'WHERE "actor"."inboxUrl" IN (' + inboxUrlsString + ') OR "actor"."sharedInboxUrl" IN (' + inboxUrlsString + ')' + | ||
315 | ')' | ||
316 | |||
317 | const options = { | ||
318 | type: Sequelize.QueryTypes.BULKUPDATE, | ||
319 | transaction: t | ||
320 | } | ||
321 | |||
322 | return ActorFollowModel.sequelize.query(query, options) | ||
323 | } | ||
324 | |||
325 | private static listBadActorFollows () { | ||
326 | const query = { | ||
327 | where: { | ||
328 | score: { | ||
329 | [Sequelize.Op.lte]: 0 | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | |||
334 | return ActorFollowModel.findAll(query) | ||
335 | } | ||
336 | |||
337 | toFormattedJSON (): AccountFollow { | ||
264 | const follower = this.ActorFollower.toFormattedJSON() | 338 | const follower = this.ActorFollower.toFormattedJSON() |
265 | const following = this.ActorFollowing.toFormattedJSON() | 339 | const following = this.ActorFollowing.toFormattedJSON() |
266 | 340 | ||
@@ -268,6 +342,7 @@ export class ActorFollowModel extends Model<ActorFollowModel> { | |||
268 | id: this.id, | 342 | id: this.id, |
269 | follower, | 343 | follower, |
270 | following, | 344 | following, |
345 | score: this.score, | ||
271 | state: this.state, | 346 | state: this.state, |
272 | createdAt: this.createdAt, | 347 | createdAt: this.createdAt, |
273 | updatedAt: this.updatedAt | 348 | updatedAt: this.updatedAt |
diff --git a/server/models/activitypub/actor.ts b/server/models/activitypub/actor.ts index b88e06b41..912d8d748 100644 --- a/server/models/activitypub/actor.ts +++ b/server/models/activitypub/actor.ts | |||
@@ -204,7 +204,7 @@ export class ActorModel extends Model<ActorModel> { | |||
204 | VideoChannel: VideoChannelModel | 204 | VideoChannel: VideoChannelModel |
205 | 205 | ||
206 | static load (id: number) { | 206 | static load (id: number) { |
207 | return ActorModel.scope(ScopeNames.FULL).findById(id) | 207 | return ActorModel.unscoped().findById(id) |
208 | } | 208 | } |
209 | 209 | ||
210 | static listByFollowersUrls (followersUrls: string[], transaction?: Sequelize.Transaction) { | 210 | static listByFollowersUrls (followersUrls: string[], transaction?: Sequelize.Transaction) { |
@@ -267,20 +267,17 @@ export class ActorModel extends Model<ActorModel> { | |||
267 | avatar = this.Avatar.toFormattedJSON() | 267 | avatar = this.Avatar.toFormattedJSON() |
268 | } | 268 | } |
269 | 269 | ||
270 | let score: number | ||
271 | if (this.Server) { | ||
272 | score = this.Server.score | ||
273 | } | ||
274 | |||
275 | return { | 270 | return { |
276 | id: this.id, | 271 | id: this.id, |
277 | url: this.url, | 272 | url: this.url, |
278 | uuid: this.uuid, | 273 | uuid: this.uuid, |
274 | name: this.preferredUsername, | ||
279 | host: this.getHost(), | 275 | host: this.getHost(), |
280 | score, | ||
281 | followingCount: this.followingCount, | 276 | followingCount: this.followingCount, |
282 | followersCount: this.followersCount, | 277 | followersCount: this.followersCount, |
283 | avatar | 278 | avatar, |
279 | createdAt: this.createdAt, | ||
280 | updatedAt: this.updatedAt | ||
284 | } | 281 | } |
285 | } | 282 | } |
286 | 283 | ||