]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/models/video/tag.ts
Fix ownership change
[github/Chocobozzz/PeerTube.git] / server / models / video / tag.ts
CommitLineData
3fd3ab2d 1import * as Bluebird from 'bluebird'
1735c825 2import { QueryTypes, Transaction } from 'sequelize'
3fd3ab2d
C
3import { AllowNull, BelongsToMany, Column, CreatedAt, Is, Model, Table, UpdatedAt } from 'sequelize-typescript'
4import { isVideoTagValid } from '../../helpers/custom-validators/videos'
5import { throwIfNotValid } from '../utils'
6import { VideoModel } from './video'
7import { VideoTagModel } from './video-tag'
2d3741d6 8import { VideoPrivacy, VideoState } from '../../../shared/models/videos'
96ca24f0 9import { MTag } from '@server/typings/models'
3fd3ab2d
C
10
11@Table({
12 tableName: 'tag',
13 timestamps: false,
14 indexes: [
7920c273 15 {
3fd3ab2d
C
16 fields: [ 'name' ],
17 unique: true
7920c273 18 }
e02643f3 19 ]
3fd3ab2d
C
20})
21export class TagModel extends Model<TagModel> {
e02643f3 22
3fd3ab2d
C
23 @AllowNull(false)
24 @Is('VideoTag', value => throwIfNotValid(value, isVideoTagValid, 'tag'))
25 @Column
26 name: string
7920c273 27
3fd3ab2d
C
28 @CreatedAt
29 createdAt: Date
7920c273 30
3fd3ab2d
C
31 @UpdatedAt
32 updatedAt: Date
33
34 @BelongsToMany(() => VideoModel, {
7920c273 35 foreignKey: 'tagId',
3fd3ab2d 36 through: () => VideoTagModel,
0a6658fd 37 onDelete: 'CASCADE'
7920c273 38 })
3fd3ab2d
C
39 Videos: VideoModel[]
40
96ca24f0
C
41 static findOrCreateTags (tags: string[], transaction: Transaction): Promise<MTag[]> {
42 if (tags === null) return Promise.resolve([])
2efd32f6 43
96ca24f0 44 const tasks: Bluebird<MTag>[] = []
3fd3ab2d
C
45 tags.forEach(tag => {
46 const query = {
47 where: {
48 name: tag
49 },
50 defaults: {
51 name: tag
d9bdd007
C
52 },
53 transaction
4ff0d862 54 }
4ff0d862 55
96ca24f0 56 const promise = TagModel.findOrCreate<MTag>(query)
3fd3ab2d
C
57 .then(([ tagInstance ]) => tagInstance)
58 tasks.push(promise)
59 })
6fcd19ba 60
3fd3ab2d
C
61 return Promise.all(tasks)
62 }
2d3741d6
C
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 },
1735c825 76 type: QueryTypes.SELECT as QueryTypes.SELECT
2d3741d6
C
77 }
78
3acc5084 79 return TagModel.sequelize.query<{ name: string }>(query, options)
2d3741d6
C
80 .then(data => data.map(d => d.name))
81 }
4ff0d862 82}