diff options
Diffstat (limited to 'server/models')
-rw-r--r-- | server/models/video/tag.ts | 24 | ||||
-rw-r--r-- | server/models/video/video.ts | 23 |
2 files changed, 45 insertions, 2 deletions
diff --git a/server/models/video/tag.ts b/server/models/video/tag.ts index 6d79a5575..e39a418cd 100644 --- a/server/models/video/tag.ts +++ b/server/models/video/tag.ts | |||
@@ -1,10 +1,11 @@ | |||
1 | import * as Bluebird from 'bluebird' | 1 | import * as Bluebird from 'bluebird' |
2 | import { Transaction } from 'sequelize' | 2 | import * as Sequelize from 'sequelize' |
3 | import { AllowNull, BelongsToMany, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' | 3 | import { AllowNull, BelongsToMany, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript' |
4 | import { isVideoTagValid } from '../../helpers/custom-validators/videos' | 4 | import { isVideoTagValid } from '../../helpers/custom-validators/videos' |
5 | import { throwIfNotValid } from '../utils' | 5 | import { throwIfNotValid } from '../utils' |
6 | import { VideoModel } from './video' | 6 | import { VideoModel } from './video' |
7 | import { VideoTagModel } from './video-tag' | 7 | import { VideoTagModel } from './video-tag' |
8 | import { VideoPrivacy, VideoState } from '../../../shared/models/videos' | ||
8 | 9 | ||
9 | @Table({ | 10 | @Table({ |
10 | tableName: 'tag', | 11 | tableName: 'tag', |
@@ -36,7 +37,7 @@ export class TagModel extends Model<TagModel> { | |||
36 | }) | 37 | }) |
37 | Videos: VideoModel[] | 38 | Videos: VideoModel[] |
38 | 39 | ||
39 | static findOrCreateTags (tags: string[], transaction: Transaction) { | 40 | static findOrCreateTags (tags: string[], transaction: Sequelize.Transaction) { |
40 | if (tags === null) return [] | 41 | if (tags === null) return [] |
41 | 42 | ||
42 | const tasks: Bluebird<TagModel>[] = [] | 43 | const tasks: Bluebird<TagModel>[] = [] |
@@ -59,4 +60,23 @@ export class TagModel extends Model<TagModel> { | |||
59 | 60 | ||
60 | return Promise.all(tasks) | 61 | return Promise.all(tasks) |
61 | } | 62 | } |
63 | |||
64 | // threshold corresponds to how many video the field should have to be returned | ||
65 | static getRandomSamples (threshold: number, count: number): Bluebird<string[]> { | ||
66 | const query = 'SELECT tag.name FROM tag ' + | ||
67 | 'INNER JOIN "videoTag" ON "videoTag"."tagId" = tag.id ' + | ||
68 | 'INNER JOIN video ON video.id = "videoTag"."videoId" ' + | ||
69 | 'WHERE video.privacy = $videoPrivacy AND video.state = $videoState ' + | ||
70 | 'GROUP BY tag.name HAVING COUNT(tag.name) >= $threshold ' + | ||
71 | 'ORDER BY random() ' + | ||
72 | 'LIMIT $count' | ||
73 | |||
74 | const options = { | ||
75 | bind: { threshold, count, videoPrivacy: VideoPrivacy.PUBLIC, videoState: VideoState.PUBLISHED }, | ||
76 | type: Sequelize.QueryTypes.SELECT | ||
77 | } | ||
78 | |||
79 | return TagModel.sequelize.query(query, options) | ||
80 | .then(data => data.map(d => d.name)) | ||
81 | } | ||
62 | } | 82 | } |
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 3410833c8..695990b17 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -1083,6 +1083,29 @@ export class VideoModel extends Model<VideoModel> { | |||
1083 | }) | 1083 | }) |
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | // threshold corresponds to how many video the field should have to be returned | ||
1087 | static getRandomFieldSamples (field: 'category' | 'channelId', threshold: number, count: number) { | ||
1088 | const query: IFindOptions<VideoModel> = { | ||
1089 | attributes: [ field ], | ||
1090 | limit: count, | ||
1091 | group: field, | ||
1092 | having: Sequelize.where(Sequelize.fn('COUNT', Sequelize.col(field)), { | ||
1093 | [Sequelize.Op.gte]: threshold | ||
1094 | }) as any, // FIXME: typings | ||
1095 | where: { | ||
1096 | [field]: { | ||
1097 | [Sequelize.Op.not]: null, | ||
1098 | }, | ||
1099 | privacy: VideoPrivacy.PUBLIC, | ||
1100 | state: VideoState.PUBLISHED | ||
1101 | }, | ||
1102 | order: [ this.sequelize.random() ] | ||
1103 | } | ||
1104 | |||
1105 | return VideoModel.findAll(query) | ||
1106 | .then(rows => rows.map(r => r[field])) | ||
1107 | } | ||
1108 | |||
1086 | private static buildActorWhereWithFilter (filter?: VideoFilter) { | 1109 | private static buildActorWhereWithFilter (filter?: VideoFilter) { |
1087 | if (filter && filter === 'local') { | 1110 | if (filter && filter === 'local') { |
1088 | return { | 1111 | return { |