Compare commits
3 Commits
main
...
feature/ed
Author | SHA1 | Date |
---|---|---|
Kainoa Kanter | 361109e601 | |
Cleo John | b5ca170e79 | |
Cleo John | 08e2e473c5 |
|
@ -0,0 +1,31 @@
|
||||||
|
export class PollChoiceLength1674000000000 {
|
||||||
|
name = 'PollChoiceLength1674000000000'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`CREATE TABLE "post_edits" (
|
||||||
|
"id" VARCHAR(32) NOT NULL,
|
||||||
|
"post_id" VARCHAR(32) REFERENCES "note" (id) ON DELETE CASCADE,
|
||||||
|
"user_id" VARCHAR(32) REFERENCES "user" (id) ON DELETE CASCADE,
|
||||||
|
"text" TEXT,
|
||||||
|
"cw" TEXT,
|
||||||
|
"media_attachments_changed" BOOLEAN,
|
||||||
|
"modified_at" DATE,
|
||||||
|
PRIMARY KEY ("id")
|
||||||
|
)`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "note" ADD "modified_at" DATE DEFAULT NULL`);
|
||||||
|
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "post_edits"."id" IS 'Unique Identified for this Edit.'`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "note"."modified_at" IS 'Null if not modified, else the time it was last modified'`)
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "post_edits"."post_id" IS 'The Post the Edit belongs to.'`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "post_edits"."user_id" IS 'The User that made the edit.'`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "post_edits"."text" IS 'The modified Text.'`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "post_edits"."cw" IS 'The modified CW.'`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "post_edits"."media_attachments_changed" IS 'Did media attachments got changed?'`);
|
||||||
|
await queryRunner.query(`COMMENT ON COLUMN "post_edits"."modified_at" IS 'When was the post modified?'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "modified_at"`);
|
||||||
|
await queryRunner.query(`DROP TABLE "post_edits"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
import type { CacheableRemoteUser } from "@/models/entities/user.js";
|
import type { CacheableRemoteUser } from "@/models/entities/user.js";
|
||||||
import type { IUpdate } from "../../type.js";
|
import type { IPost, IUpdate } from "../../type.js";
|
||||||
import { getApType, isActor } from "../../type.js";
|
import { getApType, isActor } from "../../type.js";
|
||||||
import { apLogger } from "../../logger.js";
|
import { apLogger } from "../../logger.js";
|
||||||
import { updateQuestion } from "../../models/question.js";
|
|
||||||
import Resolver from "../../resolver.js";
|
import Resolver from "../../resolver.js";
|
||||||
import { updatePerson } from "../../models/person.js";
|
import { updatePerson } from "../../models/person.js";
|
||||||
|
import { updatePost } from "../../models/note.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for the Update activity
|
* Handler for the Update activity
|
||||||
|
@ -29,10 +29,17 @@ export default async (
|
||||||
if (isActor(object)) {
|
if (isActor(object)) {
|
||||||
await updatePerson(actor.uri!, resolver, object);
|
await updatePerson(actor.uri!, resolver, object);
|
||||||
return "ok: Person updated";
|
return "ok: Person updated";
|
||||||
} else if (getApType(object) === "Question") {
|
}
|
||||||
await updateQuestion(object, resolver).catch((e) => console.log(e));
|
|
||||||
return "ok: Question updated";
|
switch (getApType(object)) {
|
||||||
} else {
|
case 'Question':
|
||||||
|
case 'Note':
|
||||||
|
case 'Article':
|
||||||
|
case 'Document':
|
||||||
|
case 'Page':
|
||||||
|
await updatePost(activity, object as IPost, resolver);
|
||||||
|
return `ok: Post updated`;
|
||||||
|
default:
|
||||||
return `skip: Unknown type: ${getApType(object)}`;
|
return `skip: Unknown type: ${getApType(object)}`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,15 +9,15 @@ import type { CacheableRemoteUser } from "@/models/entities/user.js";
|
||||||
import { htmlToMfm } from "../misc/html-to-mfm.js";
|
import { htmlToMfm } from "../misc/html-to-mfm.js";
|
||||||
import { extractApHashtags } from "./tag.js";
|
import { extractApHashtags } from "./tag.js";
|
||||||
import { unique, toArray, toSingle } from "@/prelude/array.js";
|
import { unique, toArray, toSingle } from "@/prelude/array.js";
|
||||||
import { extractPollFromQuestion } from "./question.js";
|
import { extractPollFromQuestion, updateQuestion } from "./question.js";
|
||||||
import vote from "@/services/note/polls/vote.js";
|
import vote from "@/services/note/polls/vote.js";
|
||||||
import { apLogger } from "../logger.js";
|
import { apLogger } from "../logger.js";
|
||||||
import type { DriveFile } from "@/models/entities/drive-file.js";
|
import type { DriveFile } from "@/models/entities/drive-file.js";
|
||||||
import { deliverQuestionUpdate } from "@/services/note/polls/update.js";
|
import { deliverQuestionUpdate } from "@/services/note/polls/update.js";
|
||||||
import { extractDbHost, toPuny } from "@/misc/convert-host.js";
|
import { extractDbHost, toPuny } from "@/misc/convert-host.js";
|
||||||
import { Emojis, Polls, MessagingMessages } from "@/models/index.js";
|
import { Emojis, Polls, MessagingMessages, Notes } from "@/models/index.js";
|
||||||
import type { Note } from "@/models/entities/note.js";
|
import type { Note } from "@/models/entities/note.js";
|
||||||
import type { IObject, IPost } from "../type.js";
|
import type { IObject, IPost, IUpdate } from "../type.js";
|
||||||
import {
|
import {
|
||||||
getOneApId,
|
getOneApId,
|
||||||
getApId,
|
getApId,
|
||||||
|
@ -380,6 +380,33 @@ export async function createNote(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update info of Post
|
||||||
|
* @param uri URI of AP post object
|
||||||
|
* @returns true if updated
|
||||||
|
*/
|
||||||
|
export async function updatePost(activity: IUpdate, value: any, resolver?: Resolver) {
|
||||||
|
|
||||||
|
const uri = typeof value === "string" ? value : value.id;
|
||||||
|
|
||||||
|
// Skip if URI points to this server
|
||||||
|
if (uri.startsWith(`${config.url}/`)) throw new Error("uri points local");
|
||||||
|
|
||||||
|
//#region Already registered with this server?
|
||||||
|
const note = await Notes.findOneBy({ uri });
|
||||||
|
if (note == null) throw new Error("Post is not registed");
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
// resolve new Post object
|
||||||
|
if (resolver == null) resolver = new Resolver();
|
||||||
|
const post = (await resolver.resolve(value)) as IPost;
|
||||||
|
|
||||||
|
if (post.type == "Question") {
|
||||||
|
updateQuestion(value, resolver, note);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve Note.
|
* Resolve Note.
|
||||||
*
|
*
|
||||||
|
|
|
@ -50,27 +50,18 @@ export async function extractPollFromQuestion(
|
||||||
* @param uri URI of AP Question object
|
* @param uri URI of AP Question object
|
||||||
* @returns true if updated
|
* @returns true if updated
|
||||||
*/
|
*/
|
||||||
export async function updateQuestion(value: any, resolver?: Resolver) {
|
export async function updateQuestion(value: any, resolver: Resolver, note: any) {
|
||||||
const uri = typeof value === "string" ? value : value.id;
|
const uri = typeof value === "string" ? value : value.id;
|
||||||
|
|
||||||
// Skip if URI points to this server
|
|
||||||
if (uri.startsWith(`${config.url}/`)) throw new Error("uri points local");
|
|
||||||
|
|
||||||
//#region Already registered with this server?
|
//#region Already registered with this server?
|
||||||
const note = await Notes.findOneBy({ uri });
|
|
||||||
if (note == null) throw new Error("Question is not registed");
|
|
||||||
|
|
||||||
const poll = await Polls.findOneBy({ noteId: note.id });
|
const poll = await Polls.findOneBy({ noteId: note.id });
|
||||||
if (poll == null) throw new Error("Question is not registed");
|
if (poll == null) throw new Error("Question is not registed");
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
// resolve new Question object
|
// resolve new Question object
|
||||||
if (resolver == null) resolver = new Resolver();
|
|
||||||
const question = (await resolver.resolve(value)) as IQuestion;
|
const question = (await resolver.resolve(value)) as IQuestion;
|
||||||
apLogger.debug(`fetched question: ${JSON.stringify(question, null, 2)}`);
|
apLogger.debug(`fetched question: ${JSON.stringify(question, null, 2)}`);
|
||||||
|
|
||||||
if (question.type !== "Question") throw new Error("object is not a Question");
|
|
||||||
|
|
||||||
const apChoices = question.oneOf || question.anyOf;
|
const apChoices = question.oneOf || question.anyOf;
|
||||||
|
|
||||||
let changed = false;
|
let changed = false;
|
||||||
|
|
|
@ -148,6 +148,7 @@ export interface IQuestion extends IObject {
|
||||||
};
|
};
|
||||||
_misskey_quote?: string;
|
_misskey_quote?: string;
|
||||||
quoteUrl?: string;
|
quoteUrl?: string;
|
||||||
|
quoteUri?: string;
|
||||||
oneOf?: IQuestionChoice[];
|
oneOf?: IQuestionChoice[];
|
||||||
anyOf?: IQuestionChoice[];
|
anyOf?: IQuestionChoice[];
|
||||||
endTime?: Date;
|
endTime?: Date;
|
||||||
|
|
Loading…
Reference in New Issue