From da854ddd502cd70685ef779c673b9e63757b8aa0 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 28 Dec 2017 11:16:08 +0100 Subject: Propagate old comment on new follow --- server/models/account/user.ts | 2 +- server/models/activitypub/actor.ts | 9 +-- server/models/oauth/oauth-token.ts | 2 +- server/models/server/server.ts | 2 +- server/models/video/video-blacklist.ts | 2 +- server/models/video/video-comment.ts | 33 +++++++-- server/models/video/video.ts | 121 ++++++++++++++++++--------------- 7 files changed, 104 insertions(+), 67 deletions(-) (limited to 'server/models') diff --git a/server/models/account/user.ts b/server/models/account/user.ts index 1d5759ea3..d7e09e328 100644 --- a/server/models/account/user.ts +++ b/server/models/account/user.ts @@ -4,11 +4,11 @@ import { Scopes, Table, UpdatedAt } from 'sequelize-typescript' import { hasUserRight, USER_ROLE_LABELS, UserRight } from '../../../shared' -import { comparePassword, cryptPassword } from '../../helpers' import { isUserAutoPlayVideoValid, isUserDisplayNSFWValid, isUserPasswordValid, isUserRoleValid, isUserUsernameValid, isUserVideoQuotaValid } from '../../helpers/custom-validators/users' +import { comparePassword, cryptPassword } from '../../helpers/peertube-crypto' import { OAuthTokenModel } from '../oauth/oauth-token' import { getSort, throwIfNotValid } from '../utils' import { VideoChannelModel } from '../video/video-channel' diff --git a/server/models/activitypub/actor.ts b/server/models/activitypub/actor.ts index e7eb35e2c..3d96b3706 100644 --- a/server/models/activitypub/actor.ts +++ b/server/models/activitypub/actor.ts @@ -7,11 +7,12 @@ import { } from 'sequelize-typescript' import { ActivityPubActorType } from '../../../shared/models/activitypub' import { Avatar } from '../../../shared/models/avatars/avatar.model' -import { activityPubContextify } from '../../helpers' +import { activityPubContextify } from '../../helpers/activitypub' import { - isActivityPubUrlValid, isActorFollowersCountValid, isActorFollowingCountValid, isActorPreferredUsernameValid, - isActorPrivateKeyValid, isActorPublicKeyValid -} from '../../helpers/custom-validators/activitypub' + isActorFollowersCountValid, isActorFollowingCountValid, isActorPreferredUsernameValid, isActorPrivateKeyValid, + isActorPublicKeyValid +} from '../../helpers/custom-validators/activitypub/actor' +import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' import { ACTIVITY_PUB_ACTOR_TYPES, AVATARS_DIR, CONFIG, CONSTRAINTS_FIELDS } from '../../initializers' import { AccountModel } from '../account/account' import { AvatarModel } from '../avatar/avatar' diff --git a/server/models/oauth/oauth-token.ts b/server/models/oauth/oauth-token.ts index 995fa33d5..9d1b63813 100644 --- a/server/models/oauth/oauth-token.ts +++ b/server/models/oauth/oauth-token.ts @@ -1,5 +1,5 @@ import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' -import { logger } from '../../helpers' +import { logger } from '../../helpers/logger' import { AccountModel } from '../account/account' import { UserModel } from '../account/user' import { OAuthClientModel } from './oauth-client' diff --git a/server/models/server/server.ts b/server/models/server/server.ts index edfd8010b..d35aa0ca4 100644 --- a/server/models/server/server.ts +++ b/server/models/server/server.ts @@ -1,7 +1,7 @@ import * as Sequelize from 'sequelize' import { AllowNull, Column, CreatedAt, Default, Is, IsInt, Max, Model, Table, UpdatedAt } from 'sequelize-typescript' -import { logger } from '../../helpers' import { isHostValid } from '../../helpers/custom-validators/servers' +import { logger } from '../../helpers/logger' import { SERVERS_SCORE } from '../../initializers' import { throwIfNotValid } from '../utils' diff --git a/server/models/video/video-blacklist.ts b/server/models/video/video-blacklist.ts index 6db562719..3adcec149 100644 --- a/server/models/video/video-blacklist.ts +++ b/server/models/video/video-blacklist.ts @@ -1,5 +1,5 @@ import { BelongsTo, Column, CreatedAt, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript' -import { SortType } from '../../helpers' +import { SortType } from '../../helpers/utils' import { getSortOnModel } from '../utils' import { VideoModel } from './video' diff --git a/server/models/video/video-comment.ts b/server/models/video/video-comment.ts index 8ceeb563a..1992c2dd8 100644 --- a/server/models/video/video-comment.ts +++ b/server/models/video/video-comment.ts @@ -5,7 +5,7 @@ import { } from 'sequelize-typescript' import { VideoCommentObject } from '../../../shared/models/activitypub/objects/video-comment-object' import { VideoComment } from '../../../shared/models/videos/video-comment.model' -import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub' +import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' import { CONSTRAINTS_FIELDS } from '../../initializers' import { AccountModel } from '../account/account' import { ActorModel } from '../activitypub/actor' @@ -16,6 +16,7 @@ import { VideoModel } from './video' enum ScopeNames { WITH_ACCOUNT = 'WITH_ACCOUNT', WITH_IN_REPLY_TO = 'WITH_IN_REPLY_TO', + WITH_VIDEO = 'WITH_VIDEO', ATTRIBUTES_FOR_API = 'ATTRIBUTES_FOR_API' } @@ -56,7 +57,15 @@ enum ScopeNames { include: [ { model: () => VideoCommentModel, - as: 'InReplyTo' + as: 'InReplyToVideoComment' + } + ] + }, + [ScopeNames.WITH_VIDEO]: { + include: [ + { + model: () => VideoModel, + required: false } ] } @@ -108,7 +117,7 @@ export class VideoCommentModel extends Model { foreignKey: { allowNull: true }, - as: 'InReplyTo', + as: 'InReplyToVideoComment', onDelete: 'CASCADE' }) InReplyToVideoComment: VideoCommentModel @@ -155,6 +164,20 @@ export class VideoCommentModel extends Model { return VideoCommentModel.findOne(query) } + static loadByIdAndPopulateVideoAndAccountAndReply (id: number, t?: Sequelize.Transaction) { + const query: IFindOptions = { + where: { + id + } + } + + if (t !== undefined) query.transaction = t + + return VideoCommentModel + .scope([ ScopeNames.WITH_VIDEO, ScopeNames.WITH_ACCOUNT, ScopeNames.WITH_IN_REPLY_TO ]) + .findOne(query) + } + static loadByUrl (url: string, t?: Sequelize.Transaction) { const query: IFindOptions = { where: { @@ -238,8 +261,10 @@ export class VideoCommentModel extends Model { id: this.url, content: this.text, inReplyTo, + updated: this.updatedAt.toISOString(), published: this.createdAt.toISOString(), - url: this.url + url: this.url, + attributedTo: this.Account.Actor.url } } } diff --git a/server/models/video/video.ts b/server/models/video/video.ts index b6a2ce6b5..2504ae58a 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts @@ -5,65 +5,25 @@ import * as parseTorrent from 'parse-torrent' import { join } from 'path' import * as Sequelize from 'sequelize' import { - AfterDestroy, - AllowNull, - BelongsTo, - BelongsToMany, - Column, - CreatedAt, - DataType, - Default, - ForeignKey, - HasMany, - IFindOptions, - Is, - IsInt, - IsUUID, - Min, - Model, - Scopes, - Table, - UpdatedAt + AfterDestroy, AllowNull, BelongsTo, BelongsToMany, Column, CreatedAt, DataType, Default, ForeignKey, HasMany, IFindOptions, Is, + IsInt, IsUUID, Min, Model, Scopes, Table, UpdatedAt } from 'sequelize-typescript' import { IIncludeOptions } from 'sequelize-typescript/lib/interfaces/IIncludeOptions' import { VideoPrivacy, VideoResolution } from '../../../shared' import { VideoTorrentObject } from '../../../shared/models/activitypub/objects' import { Video, VideoDetails } from '../../../shared/models/videos' +import { activityPubCollection } from '../../helpers/activitypub' +import { createTorrentPromise, renamePromise, statPromise, unlinkPromise, writeFilePromise } from '../../helpers/core-utils' +import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub/misc' import { - activityPubCollection, - createTorrentPromise, - generateImageFromVideoFile, - getVideoFileHeight, - logger, - renamePromise, - statPromise, - transcode, - unlinkPromise, - writeFilePromise -} from '../../helpers' -import { isActivityPubUrlValid } from '../../helpers/custom-validators/activitypub' -import { - isVideoCategoryValid, - isVideoDescriptionValid, - isVideoDurationValid, - isVideoLanguageValid, - isVideoLicenceValid, - isVideoNameValid, - isVideoNSFWValid, - isVideoPrivacyValid + isVideoCategoryValid, isVideoDescriptionValid, isVideoDurationValid, isVideoLanguageValid, isVideoLicenceValid, isVideoNameValid, + isVideoNSFWValid, isVideoPrivacyValid } from '../../helpers/custom-validators/videos' +import { generateImageFromVideoFile, getVideoFileHeight, transcode } from '../../helpers/ffmpeg-utils' +import { logger } from '../../helpers/logger' import { - API_VERSION, - CONFIG, - CONSTRAINTS_FIELDS, - PREVIEWS_SIZE, - REMOTE_SCHEME, - STATIC_PATHS, - THUMBNAILS_SIZE, - VIDEO_CATEGORIES, - VIDEO_LANGUAGES, - VIDEO_LICENCES, - VIDEO_PRIVACIES + API_VERSION, CONFIG, CONSTRAINTS_FIELDS, PREVIEWS_SIZE, REMOTE_SCHEME, STATIC_PATHS, THUMBNAILS_SIZE, VIDEO_CATEGORIES, + VIDEO_LANGUAGES, VIDEO_LICENCES, VIDEO_PRIVACIES } from '../../initializers' import { getAnnounceActivityPubUrl } from '../../lib/activitypub' import { sendDeleteVideo } from '../../lib/activitypub/send' @@ -75,6 +35,7 @@ import { getSort, throwIfNotValid } from '../utils' import { TagModel } from './tag' import { VideoAbuseModel } from './video-abuse' import { VideoChannelModel } from './video-channel' +import { VideoCommentModel } from './video-comment' import { VideoFileModel } from './video-file' import { VideoShareModel } from './video-share' import { VideoTagModel } from './video-tag' @@ -85,7 +46,8 @@ enum ScopeNames { WITH_TAGS = 'WITH_TAGS', WITH_FILES = 'WITH_FILES', WITH_SHARES = 'WITH_SHARES', - WITH_RATES = 'WITH_RATES' + WITH_RATES = 'WITH_RATES', + WITH_COMMENTS = 'WITH_COMMENTS' } @Scopes({ @@ -151,6 +113,13 @@ enum ScopeNames { include: [ () => AccountModel ] } ] + }, + [ScopeNames.WITH_COMMENTS]: { + include: [ + { + model: () => VideoCommentModel + } + ] } }) @Table({ @@ -322,6 +291,15 @@ export class VideoModel extends Model { }) AccountVideoRates: AccountVideoRateModel[] + @HasMany(() => VideoCommentModel, { + foreignKey: { + name: 'videoId', + allowNull: false + }, + onDelete: 'cascade' + }) + VideoComments: VideoCommentModel[] + @AfterDestroy static removeFilesAndSendDelete (instance: VideoModel) { const tasks = [] @@ -417,7 +395,8 @@ export class VideoModel extends Model { include: [ AccountModel ] }, VideoFileModel, - TagModel + TagModel, + VideoCommentModel ] } @@ -536,7 +515,7 @@ export class VideoModel extends Model { } return VideoModel - .scope([ ScopeNames.WITH_RATES, ScopeNames.WITH_SHARES, ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ]) + .scope([ ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ]) .findById(id, options) } @@ -561,7 +540,27 @@ export class VideoModel extends Model { } return VideoModel - .scope([ ScopeNames.WITH_RATES, ScopeNames.WITH_SHARES, ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ]) + .scope([ ScopeNames.WITH_TAGS, ScopeNames.WITH_FILES, ScopeNames.WITH_ACCOUNT ]) + .findOne(options) + } + + static loadAndPopulateAll (id: number) { + const options = { + order: [ [ 'Tags', 'name', 'ASC' ] ], + where: { + id + } + } + + return VideoModel + .scope([ + ScopeNames.WITH_RATES, + ScopeNames.WITH_SHARES, + ScopeNames.WITH_TAGS, + ScopeNames.WITH_FILES, + ScopeNames.WITH_ACCOUNT, + ScopeNames.WITH_COMMENTS + ]) .findOne(options) } @@ -865,6 +864,17 @@ export class VideoModel extends Model { sharesObject = activityPubCollection(shares) } + let commentsObject + if (Array.isArray(this.VideoComments)) { + const comments: string[] = [] + + for (const videoComment of this.VideoComments) { + comments.push(videoComment.url) + } + + commentsObject = activityPubCollection(comments) + } + const url = [] for (const file of this.VideoFiles) { url.push({ @@ -925,6 +935,7 @@ export class VideoModel extends Model { likes: likesObject, dislikes: dislikesObject, shares: sharesObject, + comments: commentsObject, attributedTo: [ { type: 'Group', -- cgit v1.2.3