mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2024-11-30 20:43:53 -06:00
Improve SQL query for my special playlists
This commit is contained in:
parent
35f28e94c7
commit
ac0868bcc0
@ -126,14 +126,13 @@ async function getUserVideoImports (req: express.Request, res: express.Response)
|
||||
|
||||
async function getUserInformation (req: express.Request, res: express.Response) {
|
||||
// We did not load channels in res.locals.user
|
||||
const user = await UserModel.loadByUsernameAndPopulateChannels(res.locals.oauth.token.user.username)
|
||||
const user = await UserModel.loadForMeAPI(res.locals.oauth.token.user.username)
|
||||
|
||||
return res.json(user.toFormattedJSON({ me: true }))
|
||||
return res.json(user.toMeFormattedJSON())
|
||||
}
|
||||
|
||||
async function getUserVideoQuotaUsed (req: express.Request, res: express.Response) {
|
||||
// We did not load channels in res.locals.user
|
||||
const user = await UserModel.loadByUsernameAndPopulateChannels(res.locals.oauth.token.user.username)
|
||||
const user = res.locals.oauth.token.user
|
||||
const videoQuotaUsed = await UserModel.getOriginalVideoFileTotalFromUser(user)
|
||||
const videoQuotaUsedDaily = await UserModel.getOriginalVideoFileTotalDailyFromUser(user)
|
||||
|
||||
|
@ -19,14 +19,15 @@ import {
|
||||
Table,
|
||||
UpdatedAt
|
||||
} from 'sequelize-typescript'
|
||||
import { hasUserRight, USER_ROLE_LABELS, UserRight, VideoPrivacy, MyUser } from '../../../shared'
|
||||
import { hasUserRight, MyUser, USER_ROLE_LABELS, UserRight, VideoPlaylistType, VideoPrivacy } from '../../../shared'
|
||||
import { User, UserRole } from '../../../shared/models/users'
|
||||
import {
|
||||
isNoInstanceConfigWarningModal,
|
||||
isNoWelcomeModal,
|
||||
isUserAdminFlagsValid,
|
||||
isUserAutoPlayVideoValid,
|
||||
isUserAutoPlayNextVideoValid,
|
||||
isUserAutoPlayNextVideoPlaylistValid,
|
||||
isUserAutoPlayNextVideoValid,
|
||||
isUserAutoPlayVideoValid,
|
||||
isUserBlockedReasonValid,
|
||||
isUserBlockedValid,
|
||||
isUserEmailVerifiedValid,
|
||||
@ -38,8 +39,7 @@ import {
|
||||
isUserVideoQuotaDailyValid,
|
||||
isUserVideoQuotaValid,
|
||||
isUserVideosHistoryEnabledValid,
|
||||
isUserWebTorrentEnabledValid,
|
||||
isNoWelcomeModal
|
||||
isUserWebTorrentEnabledValid
|
||||
} from '../../helpers/custom-validators/users'
|
||||
import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto'
|
||||
import { OAuthTokenModel } from '../oauth/oauth-token'
|
||||
@ -61,16 +61,17 @@ import { isThemeNameValid } from '../../helpers/custom-validators/plugins'
|
||||
import { getThemeOrDefault } from '../../lib/plugins/theme-utils'
|
||||
import * as Bluebird from 'bluebird'
|
||||
import {
|
||||
MMyUserFormattable,
|
||||
MUserDefault,
|
||||
MUserFormattable,
|
||||
MUserId,
|
||||
MUserNotifSettingChannelDefault,
|
||||
MUserWithNotificationSetting, MVideoFullLight
|
||||
MUserWithNotificationSetting,
|
||||
MVideoFullLight
|
||||
} from '@server/typings/models'
|
||||
|
||||
enum ScopeNames {
|
||||
WITH_VIDEO_CHANNEL = 'WITH_VIDEO_CHANNEL',
|
||||
WITH_SPECIAL_PLAYLISTS = 'WITH_SPECIAL_PLAYLISTS'
|
||||
FOR_ME_API = 'FOR_ME_API'
|
||||
}
|
||||
|
||||
@DefaultScope(() => ({
|
||||
@ -86,28 +87,31 @@ enum ScopeNames {
|
||||
]
|
||||
}))
|
||||
@Scopes(() => ({
|
||||
[ScopeNames.WITH_VIDEO_CHANNEL]: {
|
||||
[ScopeNames.FOR_ME_API]: {
|
||||
include: [
|
||||
{
|
||||
model: AccountModel,
|
||||
required: true,
|
||||
include: [ VideoChannelModel ]
|
||||
include: [
|
||||
{
|
||||
model: VideoChannelModel
|
||||
},
|
||||
{
|
||||
attributes: [ 'id', 'name', 'type' ],
|
||||
model: VideoPlaylistModel.unscoped(),
|
||||
required: true,
|
||||
where: {
|
||||
type: {
|
||||
[ Op.ne ]: VideoPlaylistType.REGULAR
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
model: UserNotificationSettingModel,
|
||||
required: true
|
||||
}
|
||||
]
|
||||
},
|
||||
[ScopeNames.WITH_SPECIAL_PLAYLISTS]: {
|
||||
attributes: {
|
||||
include: [
|
||||
[
|
||||
literal('(select array(select "id" from "videoPlaylist" where "ownerAccountId" in (select id from public.account where "userId" = "UserModel"."id") and name LIKE \'Watch later\'))'),
|
||||
'specialPlaylists'
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}))
|
||||
@Table({
|
||||
@ -436,17 +440,14 @@ export class UserModel extends Model<UserModel> {
|
||||
return UserModel.findOne(query)
|
||||
}
|
||||
|
||||
static loadByUsernameAndPopulateChannels (username: string): Bluebird<MUserNotifSettingChannelDefault> {
|
||||
static loadForMeAPI (username: string): Bluebird<MUserNotifSettingChannelDefault> {
|
||||
const query = {
|
||||
where: {
|
||||
username: { [ Op.iLike ]: username }
|
||||
}
|
||||
}
|
||||
|
||||
return UserModel.scope([
|
||||
ScopeNames.WITH_VIDEO_CHANNEL,
|
||||
ScopeNames.WITH_SPECIAL_PLAYLISTS
|
||||
]).findOne(query)
|
||||
return UserModel.scope(ScopeNames.FOR_ME_API).findOne(query)
|
||||
}
|
||||
|
||||
static loadByEmail (email: string): Bluebird<MUserDefault> {
|
||||
@ -625,11 +626,11 @@ export class UserModel extends Model<UserModel> {
|
||||
return comparePassword(password, this.password)
|
||||
}
|
||||
|
||||
toFormattedJSON (this: MUserFormattable, parameters: { withAdminFlags?: boolean, me?: boolean } = {}): User | MyUser {
|
||||
toFormattedJSON (this: MUserFormattable, parameters: { withAdminFlags?: boolean } = {}): User {
|
||||
const videoQuotaUsed = this.get('videoQuotaUsed')
|
||||
const videoQuotaUsedDaily = this.get('videoQuotaUsedDaily')
|
||||
|
||||
const json: User | MyUser = {
|
||||
const json: User = {
|
||||
id: this.id,
|
||||
username: this.username,
|
||||
email: this.email,
|
||||
@ -690,15 +691,18 @@ export class UserModel extends Model<UserModel> {
|
||||
})
|
||||
}
|
||||
|
||||
if (parameters.me) {
|
||||
Object.assign(json, {
|
||||
specialPlaylists: (this.get('specialPlaylists') as Array<number>).map(p => ({ id: p }))
|
||||
})
|
||||
}
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
toMeFormattedJSON (this: MMyUserFormattable): MyUser {
|
||||
const formatted = this.toFormattedJSON()
|
||||
|
||||
const specialPlaylists = this.Account.VideoPlaylists
|
||||
.map(p => ({ id: p.id, name: p.name, type: p.type }))
|
||||
|
||||
return Object.assign(formatted, { specialPlaylists })
|
||||
}
|
||||
|
||||
async isAbleToUploadVideo (videoFile: { size: number }) {
|
||||
if (this.videoQuota === -1 && this.videoQuotaDaily === -1) return Promise.resolve(true)
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
import * as chai from 'chai'
|
||||
import 'mocha'
|
||||
import { User, UserRole, Video, MyUser } from '../../../../shared/index'
|
||||
import { User, UserRole, Video, MyUser, VideoPlaylistType } from '../../../../shared/index'
|
||||
import {
|
||||
blockUser,
|
||||
cleanupTests,
|
||||
@ -251,7 +251,7 @@ describe('Test users', function () {
|
||||
|
||||
it('Should be able to get user information', async function () {
|
||||
const res1 = await getMyUserInformation(server.url, accessTokenUser)
|
||||
const userMe: User & MyUser = res1.body
|
||||
const userMe: MyUser = res1.body
|
||||
|
||||
const res2 = await getUserInformation(server.url, server.accessToken, userMe.id)
|
||||
const userGet: User = res2.body
|
||||
@ -271,6 +271,7 @@ describe('Test users', function () {
|
||||
expect(userGet.adminFlags).to.equal(UserAdminFlag.BY_PASS_VIDEO_AUTO_BLACKLIST)
|
||||
|
||||
expect(userMe.specialPlaylists).to.have.lengthOf(1)
|
||||
expect(userMe.specialPlaylists[0].type).to.equal(VideoPlaylistType.WATCH_LATER)
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
import { MNotificationSetting, MNotificationSettingFormattable } from './user-notification-setting'
|
||||
import { AccountModel } from '@server/models/account/account'
|
||||
import { MChannelFormattable } from '../video/video-channels'
|
||||
import { MVideoPlaylist } from '@server/typings/models'
|
||||
|
||||
type Use<K extends keyof UserModel, M> = PickWith<UserModel, K, M>
|
||||
|
||||
@ -65,6 +66,13 @@ export type MUserDefault = MUser &
|
||||
|
||||
// Format for API or AP object
|
||||
|
||||
type MAccountWithChannels = MAccountFormattable & PickWithOpt<AccountModel, 'VideoChannels', MChannelFormattable[]>
|
||||
type MAccountWithChannelsAndSpecialPlaylists = MAccountWithChannels &
|
||||
PickWithOpt<AccountModel, 'VideoPlaylists', MVideoPlaylist[]>
|
||||
|
||||
export type MUserFormattable = MUserQuotaUsed &
|
||||
Use<'Account', MAccountFormattable & PickWithOpt<AccountModel, 'VideoChannels', MChannelFormattable[]>> &
|
||||
Use<'Account', MAccountWithChannels> &
|
||||
PickWithOpt<UserModel, 'NotificationSetting', MNotificationSettingFormattable>
|
||||
|
||||
export type MMyUserFormattable = MUserFormattable &
|
||||
Use<'Account', MAccountWithChannelsAndSpecialPlaylists>
|
||||
|
@ -5,6 +5,7 @@ import { UserRole } from './user-role'
|
||||
import { NSFWPolicyType } from '../videos/nsfw-policy.type'
|
||||
import { UserNotificationSetting } from './user-notification-setting.model'
|
||||
import { UserAdminFlag } from './user-flag.model'
|
||||
import { VideoPlaylistType } from '@shared/models'
|
||||
|
||||
export interface User {
|
||||
id: number
|
||||
@ -47,6 +48,14 @@ export interface User {
|
||||
createdAt: Date
|
||||
}
|
||||
|
||||
export interface MyUser extends User {
|
||||
specialPlaylists: Partial<VideoPlaylist>[]
|
||||
export interface MyUserSpecialPlaylist {
|
||||
id: number
|
||||
name: string
|
||||
type: VideoPlaylistType
|
||||
}
|
||||
|
||||
export interface MyUser extends User {
|
||||
specialPlaylists: MyUserSpecialPlaylist[]
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user