はじまりの大地

このコミットが含まれているのは:
2024-07-15 09:14:04 +09:00
コミット 6632905f32
3501個のファイルの変更1439465行の追加0行の削除
+206
ファイルの表示
@@ -0,0 +1,206 @@
import { WatchedWordsList } from '@peertube/peertube-models'
import { logger } from '@server/helpers/logger.js'
import { wordsToRegExp } from '@server/helpers/regexp.js'
import { MAccountId, MWatchedWordsList } from '@server/types/models/index.js'
import { LRUCache } from 'lru-cache'
import { Transaction } from 'sequelize'
import {
AllowNull,
BelongsTo,
Column,
CreatedAt,
DataType, ForeignKey, Table,
UpdatedAt
} from 'sequelize-typescript'
import { LRU_CACHE, USER_EXPORT_MAX_ITEMS } from '../../initializers/constants.js'
import { AccountModel } from '../account/account.js'
import { SequelizeModel, getSort } from '../shared/index.js'
@Table({
tableName: 'watchedWordsList',
indexes: [
{
fields: [ 'listName', 'accountId' ],
unique: true
},
{
fields: [ 'accountId' ]
}
]
})
export class WatchedWordsListModel extends SequelizeModel<WatchedWordsListModel> {
@CreatedAt
createdAt: Date
@UpdatedAt
updatedAt: Date
@AllowNull(false)
@Column
listName: string
@AllowNull(false)
@Column(DataType.ARRAY(DataType.STRING))
words: string[]
@ForeignKey(() => AccountModel)
@Column
accountId: number
@BelongsTo(() => AccountModel, {
foreignKey: {
allowNull: false
},
onDelete: 'CASCADE'
})
Account: Awaited<AccountModel>
// accountId => reg expressions
private static readonly regexCache = new LRUCache<number, { listName: string, regex: RegExp }[]>({
max: LRU_CACHE.WATCHED_WORDS_REGEX.MAX_SIZE,
ttl: LRU_CACHE.WATCHED_WORDS_REGEX.TTL
})
static load (options: {
id: number
accountId: number
}) {
const { id, accountId } = options
const query = {
where: { id, accountId }
}
return this.findOne(query)
}
static loadByListName (options: {
listName: string
accountId: number
}) {
const { listName, accountId } = options
const query = {
where: { listName, accountId }
}
return this.findOne(query)
}
// ---------------------------------------------------------------------------
static listNamesOf (account: MAccountId) {
const query = {
raw: true,
attributes: [ 'listName' ],
where: { accountId: account.id }
}
return WatchedWordsListModel.findAll(query)
.then(rows => rows.map(r => r.listName))
}
static listForAPI (options: {
accountId: number
start: number
count: number
sort: string
}) {
const { accountId, start, count, sort } = options
const query = {
offset: start,
limit: count,
order: getSort(sort),
where: { accountId }
}
return Promise.all([
WatchedWordsListModel.count(query),
WatchedWordsListModel.findAll(query)
]).then(([ total, data ]) => ({ total, data }))
}
static listForExport (options: {
accountId: number
}) {
const { accountId } = options
return WatchedWordsListModel.findAll({
limit: USER_EXPORT_MAX_ITEMS,
order: getSort('createdAt'),
where: { accountId }
})
}
// ---------------------------------------------------------------------------
static async buildWatchedWordsRegexp (options: {
accountId: number
transaction: Transaction
}) {
const { accountId, transaction } = options
if (WatchedWordsListModel.regexCache.has(accountId)) {
return WatchedWordsListModel.regexCache.get(accountId)
}
const models = await WatchedWordsListModel.findAll<MWatchedWordsList>({
where: { accountId },
transaction
})
const result = models.map(m => ({ listName: m.listName, regex: wordsToRegExp(m.words) }))
this.regexCache.set(accountId, result)
logger.debug('Will cache watched words regex', { accountId, result, tags: [ 'watched-words' ] })
return result
}
static createList (options: {
accountId: number
listName: string
words: string[]
}) {
WatchedWordsListModel.regexCache.delete(options.accountId)
return super.create(options)
}
updateList (options: {
listName: string
words?: string[]
}) {
const { listName, words } = options
if (words && words.length === 0) {
throw new Error('Cannot update watched words with an empty list')
}
if (words) this.words = words
if (listName) this.listName = listName
WatchedWordsListModel.regexCache.delete(this.accountId)
return this.save()
}
destroy () {
WatchedWordsListModel.regexCache.delete(this.accountId)
return super.destroy()
}
toFormattedJSON (): WatchedWordsList {
return {
id: this.id,
listName: this.listName,
words: this.words,
updatedAt: this.updatedAt,
createdAt: this.createdAt
}
}
}