Add dirty migration :/
This commit is contained in:
parent
50d6de9c28
commit
a7d647c440
|
@ -21,7 +21,11 @@ import {
|
||||||
VIDEO_MIMETYPE_EXT,
|
VIDEO_MIMETYPE_EXT,
|
||||||
VIDEO_PRIVACIES
|
VIDEO_PRIVACIES
|
||||||
} from '../../../initializers'
|
} from '../../../initializers'
|
||||||
import { fetchRemoteVideoDescription, getVideoActivityPubUrl, shareVideoByServer } from '../../../lib/activitypub'
|
import {
|
||||||
|
fetchRemoteVideoDescription,
|
||||||
|
getVideoActivityPubUrl,
|
||||||
|
shareVideoByServerAndChannel
|
||||||
|
} from '../../../lib/activitypub'
|
||||||
import { sendCreateVideo, sendCreateViewToOrigin, sendCreateViewToVideoFollowers, sendUpdateVideo } from '../../../lib/activitypub/send'
|
import { sendCreateVideo, sendCreateViewToOrigin, sendCreateViewToVideoFollowers, sendUpdateVideo } from '../../../lib/activitypub/send'
|
||||||
import { transcodingJobScheduler } from '../../../lib/jobs/transcoding-job-scheduler'
|
import { transcodingJobScheduler } from '../../../lib/jobs/transcoding-job-scheduler'
|
||||||
import {
|
import {
|
||||||
|
@ -249,7 +253,7 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi
|
||||||
|
|
||||||
await sendCreateVideo(video, t)
|
await sendCreateVideo(video, t)
|
||||||
// TODO: share by video channel
|
// TODO: share by video channel
|
||||||
await shareVideoByServer(video, t)
|
await shareVideoByServerAndChannel(video, t)
|
||||||
|
|
||||||
logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid)
|
logger.info('Video with name %s and uuid %s created.', videoInfo.name, videoCreated.uuid)
|
||||||
|
|
||||||
|
@ -306,7 +310,7 @@ async function updateVideo (req: express.Request, res: express.Response) {
|
||||||
if (wasPrivateVideo === true && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE) {
|
if (wasPrivateVideo === true && videoInstanceUpdated.privacy !== VideoPrivacy.PRIVATE) {
|
||||||
await sendCreateVideo(videoInstanceUpdated, t)
|
await sendCreateVideo(videoInstanceUpdated, t)
|
||||||
// TODO: Send by video channel
|
// TODO: Send by video channel
|
||||||
await shareVideoByServer(videoInstanceUpdated, t)
|
await shareVideoByServerAndChannel(videoInstanceUpdated, t)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { values } from 'lodash'
|
import { values } from 'lodash'
|
||||||
import * as Sequelize from 'sequelize'
|
import * as Sequelize from 'sequelize'
|
||||||
import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto'
|
import { createPrivateAndPublicKeys } from '../../helpers/peertube-crypto'
|
||||||
import { shareVideoByServer } from '../../lib/activitypub/share'
|
import { shareVideoByServerAndChannel } from '../../lib/activitypub/share'
|
||||||
import { getVideoActivityPubUrl, getVideoChannelActivityPubUrl } from '../../lib/activitypub/url'
|
import { getVideoActivityPubUrl, getVideoChannelActivityPubUrl } from '../../lib/activitypub/url'
|
||||||
import { createLocalAccountWithoutKeys } from '../../lib/user'
|
import { createLocalAccountWithoutKeys } from '../../lib/user'
|
||||||
import { ApplicationModel } from '../../models/application/application'
|
import { ApplicationModel } from '../../models/application/application'
|
||||||
|
@ -197,7 +197,7 @@ async function up (utils: {
|
||||||
})
|
})
|
||||||
|
|
||||||
for (const video of videos) {
|
for (const video of videos) {
|
||||||
await shareVideoByServer(video, undefined)
|
await shareVideoByServerAndChannel(video, undefined)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,235 @@
|
||||||
|
import * as Sequelize from 'sequelize'
|
||||||
|
import { DataType } from 'sequelize-typescript'
|
||||||
|
|
||||||
|
async function up (utils: {
|
||||||
|
transaction: Sequelize.Transaction,
|
||||||
|
queryInterface: Sequelize.QueryInterface,
|
||||||
|
sequelize: Sequelize.Sequelize
|
||||||
|
}): Promise<void> {
|
||||||
|
// Create actor table
|
||||||
|
{
|
||||||
|
const queries = [
|
||||||
|
`
|
||||||
|
CREATE TYPE enum_actor_type AS ENUM (
|
||||||
|
'Group',
|
||||||
|
'Person',
|
||||||
|
'Application'
|
||||||
|
)
|
||||||
|
`,
|
||||||
|
`
|
||||||
|
CREATE TABLE actor (
|
||||||
|
id integer NOT NULL,
|
||||||
|
type enum_actor_type NOT NULL,
|
||||||
|
uuid uuid NOT NULL,
|
||||||
|
name character varying(255) NOT NULL,
|
||||||
|
url character varying(2000) NOT NULL,
|
||||||
|
"publicKey" character varying(5000),
|
||||||
|
"privateKey" character varying(5000),
|
||||||
|
"followersCount" integer NOT NULL,
|
||||||
|
"followingCount" integer NOT NULL,
|
||||||
|
"inboxUrl" character varying(2000) NOT NULL,
|
||||||
|
"outboxUrl" character varying(2000) NOT NULL,
|
||||||
|
"sharedInboxUrl" character varying(2000) NOT NULL,
|
||||||
|
"followersUrl" character varying(2000) NOT NULL,
|
||||||
|
"followingUrl" character varying(2000) NOT NULL,
|
||||||
|
"avatarId" integer,
|
||||||
|
"serverId" integer,
|
||||||
|
"createdAt" timestamp with time zone NOT NULL,
|
||||||
|
"updatedAt" timestamp with time zone NOT NULL
|
||||||
|
);`,
|
||||||
|
`
|
||||||
|
CREATE SEQUENCE actor_id_seq
|
||||||
|
AS integer
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1
|
||||||
|
`,
|
||||||
|
`ALTER SEQUENCE actor_id_seq OWNED BY actor.id`,
|
||||||
|
`ALTER TABLE ONLY actor ALTER COLUMN id SET DEFAULT nextval('actor_id_seq'::regclass)`,
|
||||||
|
`ALTER TABLE ONLY actor ADD CONSTRAINT actor_pkey PRIMARY KEY (id);`,
|
||||||
|
`CREATE UNIQUE INDEX actor_name_server_id ON actor USING btree (name, "serverId")`,
|
||||||
|
`ALTER TABLE ONLY actor
|
||||||
|
ADD CONSTRAINT "actor_avatarId_fkey" FOREIGN KEY ("avatarId") REFERENCES avatar(id) ON UPDATE CASCADE ON DELETE CASCADE`,
|
||||||
|
`ALTER TABLE ONLY actor
|
||||||
|
ADD CONSTRAINT "actor_serverId_fkey" FOREIGN KEY ("serverId") REFERENCES server(id) ON UPDATE CASCADE ON DELETE CASCADE;`
|
||||||
|
]
|
||||||
|
|
||||||
|
for (const query of queries) {
|
||||||
|
await utils.sequelize.query(query)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// tslint:disable:no-trailing-whitespace
|
||||||
|
const query1 =
|
||||||
|
`
|
||||||
|
INSERT INTO "actor"
|
||||||
|
(
|
||||||
|
type, uuid, name, url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
|
||||||
|
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'Application', uuid, name, url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
|
||||||
|
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
|
||||||
|
FROM account
|
||||||
|
WHERE "applicationId" IS NOT NULL
|
||||||
|
`
|
||||||
|
await utils.sequelize.query(query1)
|
||||||
|
|
||||||
|
const query2 =
|
||||||
|
`
|
||||||
|
INSERT INTO "actor"
|
||||||
|
(
|
||||||
|
type, uuid, name, url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
|
||||||
|
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'Person', uuid, name, url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
|
||||||
|
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
|
||||||
|
FROM account
|
||||||
|
WHERE "applicationId" IS NULL
|
||||||
|
`
|
||||||
|
await utils.sequelize.query(query2)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const data = {
|
||||||
|
type: DataType.INTEGER,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: null
|
||||||
|
}
|
||||||
|
await utils.queryInterface.addColumn('account', 'actorId', data)
|
||||||
|
|
||||||
|
const query1 = `UPDATE account SET "actorId" = (SELECT id FROM actor WHERE actor.url = account.url)`
|
||||||
|
await utils.sequelize.query(query1)
|
||||||
|
|
||||||
|
data.allowNull = false
|
||||||
|
await utils.queryInterface.changeColumn('account', 'actorId', data)
|
||||||
|
|
||||||
|
const query2 = `ALTER TABLE ONLY account
|
||||||
|
ADD CONSTRAINT "account_actorId_fkey" FOREIGN KEY ("actorId") REFERENCES actor(id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||||
|
`
|
||||||
|
await utils.sequelize.query(query2)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const query = `
|
||||||
|
INSERT INTO actor
|
||||||
|
(
|
||||||
|
type, uuid, name, url, "publicKey", "privateKey", "followersCount", "followingCount", "inboxUrl", "outboxUrl",
|
||||||
|
"sharedInboxUrl", "followersUrl", "followingUrl", "avatarId", "serverId", "createdAt", "updatedAt"
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
'Group', "videoChannel".uuid, "videoChannel".uuid, "videoChannel".url, null, null, 0, 0, "videoChannel".url || '/inbox',
|
||||||
|
"videoChannel".url || '/outbox', "videoChannel".url || '/inbox', "videoChannel".url || '/followers', "videoChannel".url || '/following',
|
||||||
|
null, account."serverId", "videoChannel"."createdAt", "videoChannel"."updatedAt"
|
||||||
|
FROM "videoChannel"
|
||||||
|
INNER JOIN "account" on "videoChannel"."accountId" = "account".id
|
||||||
|
`
|
||||||
|
await utils.sequelize.query(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const data = {
|
||||||
|
type: DataType.INTEGER,
|
||||||
|
allowNull: true,
|
||||||
|
defaultValue: null
|
||||||
|
}
|
||||||
|
await utils.queryInterface.addColumn('videoChannel', 'actorId', data)
|
||||||
|
|
||||||
|
const query1 = `UPDATE "videoChannel" SET "actorId" = (SELECT id FROM actor WHERE actor.url = "videoChannel".url)`
|
||||||
|
await utils.sequelize.query(query1)
|
||||||
|
|
||||||
|
data.allowNull = false
|
||||||
|
await utils.queryInterface.changeColumn('videoChannel', 'actorId', data)
|
||||||
|
|
||||||
|
const query2 = `
|
||||||
|
ALTER TABLE ONLY "videoChannel"
|
||||||
|
ADD CONSTRAINT "videoChannel_actorId_fkey" FOREIGN KEY ("actorId") REFERENCES actor(id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||||
|
`
|
||||||
|
await utils.sequelize.query(query2)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
await utils.queryInterface.renameTable('accountFollow', 'actorFollow')
|
||||||
|
await utils.queryInterface.renameColumn('actorFollow', 'accountId', 'actorId')
|
||||||
|
await utils.queryInterface.renameColumn('actorFollow', 'targetAccountId', 'targetActorId')
|
||||||
|
|
||||||
|
try {
|
||||||
|
await utils.queryInterface.removeConstraint('actorFollow', 'AccountFollows_accountId_fkey')
|
||||||
|
await utils.queryInterface.removeConstraint('actorFollow', 'AccountFollows_targetAccountId_fkey')
|
||||||
|
} catch {
|
||||||
|
await utils.queryInterface.removeConstraint('actorFollow', 'accountFollow_accountId_fkey')
|
||||||
|
await utils.queryInterface.removeConstraint('actorFollow', 'accountFollow_targetAccountId_fkey')
|
||||||
|
}
|
||||||
|
|
||||||
|
const query1 = `UPDATE "actorFollow"
|
||||||
|
SET "actorId" =
|
||||||
|
(SELECT "actorId" FROM account WHERE id = "actorFollow"."actorId")`
|
||||||
|
await utils.sequelize.query(query1)
|
||||||
|
|
||||||
|
const query2 = `UPDATE "actorFollow"
|
||||||
|
SET "targetActorId" =
|
||||||
|
(SELECT "actorId" FROM account WHERE id = "actorFollow"."actorId")`
|
||||||
|
|
||||||
|
await utils.sequelize.query(query2)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
await utils.queryInterface.renameColumn('videoShare', 'accountId', 'actorId')
|
||||||
|
|
||||||
|
try {
|
||||||
|
await utils.queryInterface.removeConstraint('videoShare', 'VideoShares_accountId_fkey')
|
||||||
|
} catch {
|
||||||
|
await utils.queryInterface.removeConstraint('videoShare', 'videoShare_accountId_fkey')
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = `UPDATE "videoShare"
|
||||||
|
SET "actorId" =
|
||||||
|
(SELECT "actorId" FROM account WHERE id = "videoShare"."actorId")`
|
||||||
|
await utils.sequelize.query(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const columnsToDelete = [
|
||||||
|
'uuid',
|
||||||
|
'url',
|
||||||
|
'publicKey',
|
||||||
|
'privateKey',
|
||||||
|
'followersCount',
|
||||||
|
'followingCount',
|
||||||
|
'inboxUrl',
|
||||||
|
'outboxUrl',
|
||||||
|
'sharedInboxUrl',
|
||||||
|
'followersUrl',
|
||||||
|
'followingUrl',
|
||||||
|
'serverId',
|
||||||
|
'avatarId'
|
||||||
|
]
|
||||||
|
for (const columnToDelete of columnsToDelete) {
|
||||||
|
await utils.queryInterface.removeColumn('account', columnToDelete)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const columnsToDelete = [
|
||||||
|
'uuid',
|
||||||
|
'remote',
|
||||||
|
'url'
|
||||||
|
]
|
||||||
|
for (const columnToDelete of columnsToDelete) {
|
||||||
|
await utils.queryInterface.removeColumn('videoChannel', columnToDelete)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function down (options) {
|
||||||
|
throw new Error('Not implemented.')
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
up,
|
||||||
|
down
|
||||||
|
}
|
|
@ -4,17 +4,27 @@ import { VideoModel } from '../../models/video/video'
|
||||||
import { VideoShareModel } from '../../models/video/video-share'
|
import { VideoShareModel } from '../../models/video/video-share'
|
||||||
import { sendVideoAnnounceToFollowers } from './send'
|
import { sendVideoAnnounceToFollowers } from './send'
|
||||||
|
|
||||||
async function shareVideoByServer (video: VideoModel, t: Transaction) {
|
async function shareVideoByServerAndChannel (video: VideoModel, t: Transaction) {
|
||||||
const serverActor = await getServerActor()
|
const serverActor = await getServerActor()
|
||||||
|
|
||||||
await VideoShareModel.create({
|
const serverShare = VideoShareModel.create({
|
||||||
actorId: serverActor.id,
|
actorId: serverActor.id,
|
||||||
videoId: video.id
|
videoId: video.id
|
||||||
}, { transaction: t })
|
}, { transaction: t })
|
||||||
|
|
||||||
|
const videoChannelShare = VideoShareModel.create({
|
||||||
|
actorId: video.VideoChannel.actorId,
|
||||||
|
videoId: video.id
|
||||||
|
}, { transaction: t })
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
serverShare,
|
||||||
|
videoChannelShare
|
||||||
|
])
|
||||||
|
|
||||||
return sendVideoAnnounceToFollowers(serverActor, video, t)
|
return sendVideoAnnounceToFollowers(serverActor, video, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
shareVideoByServer
|
shareVideoByServerAndChannel
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import * as Bluebird from 'bluebird'
|
||||||
import { computeResolutionsToTranscode, logger } from '../../../helpers'
|
import { computeResolutionsToTranscode, logger } from '../../../helpers'
|
||||||
import { sequelizeTypescript } from '../../../initializers'
|
import { sequelizeTypescript } from '../../../initializers'
|
||||||
import { VideoModel } from '../../../models/video/video'
|
import { VideoModel } from '../../../models/video/video'
|
||||||
import { shareVideoByServer } from '../../activitypub'
|
import { shareVideoByServerAndChannel } from '../../activitypub'
|
||||||
import { sendCreateVideo } from '../../activitypub/send'
|
import { sendCreateVideo } from '../../activitypub/send'
|
||||||
import { JobScheduler } from '../job-scheduler'
|
import { JobScheduler } from '../job-scheduler'
|
||||||
import { TranscodingJobPayload } from './transcoding-job-scheduler'
|
import { TranscodingJobPayload } from './transcoding-job-scheduler'
|
||||||
|
@ -38,7 +38,7 @@ async function onSuccess (jobId: number, video: VideoModel, jobScheduler: JobSch
|
||||||
// Now we'll add the video's meta data to our followers
|
// Now we'll add the video's meta data to our followers
|
||||||
await sendCreateVideo(video, undefined)
|
await sendCreateVideo(video, undefined)
|
||||||
// TODO: share by channel
|
// TODO: share by channel
|
||||||
await shareVideoByServer(video, undefined)
|
await shareVideoByServerAndChannel(video, undefined)
|
||||||
|
|
||||||
const originalFileHeight = await videoDatabase.getOriginalFileHeight()
|
const originalFileHeight = await videoDatabase.getOriginalFileHeight()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue