feat: experimental post import
This commit is contained in:
parent
74a9e374d6
commit
d5c80e74de
|
@ -0,0 +1,14 @@
|
|||
export type Post = {
|
||||
text: string | null;
|
||||
cw: string | null;
|
||||
localOnly: boolean;
|
||||
createdAt: Date;
|
||||
};
|
||||
|
||||
export function parse(acct: any): Post {
|
||||
return { text: acct.text, cw: acct.cw, localOnly: acct.localOnly, createdAt: new Date(acct.createdAt) };
|
||||
}
|
||||
|
||||
export function toJson(acct: Post): string {
|
||||
return { text: acct.text, cw: acct.cw, localOnly: acct.localOnly }.toString();
|
||||
}
|
|
@ -314,6 +314,23 @@ export function createImportFollowingJob(
|
|||
);
|
||||
}
|
||||
|
||||
export function createImportPostsJob(
|
||||
user: ThinUser,
|
||||
fileId: DriveFile["id"],
|
||||
) {
|
||||
return dbQueue.add(
|
||||
"importPosts",
|
||||
{
|
||||
user: user,
|
||||
fileId: fileId,
|
||||
},
|
||||
{
|
||||
removeOnComplete: true,
|
||||
removeOnFail: true,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function createImportMutingJob(user: ThinUser, fileId: DriveFile["id"]) {
|
||||
return dbQueue.add(
|
||||
"importMuting",
|
||||
|
|
|
@ -11,6 +11,7 @@ import { importFollowing } from "./import-following.js";
|
|||
import { importUserLists } from "./import-user-lists.js";
|
||||
import { deleteAccount } from "./delete-account.js";
|
||||
import { importMuting } from "./import-muting.js";
|
||||
import { importPosts } from "./import-posts.js";
|
||||
import { importBlocking } from "./import-blocking.js";
|
||||
import { importCustomEmojis } from "./import-custom-emojis.js";
|
||||
|
||||
|
@ -26,6 +27,7 @@ const jobs = {
|
|||
importMuting,
|
||||
importBlocking,
|
||||
importUserLists,
|
||||
importPosts,
|
||||
importCustomEmojis,
|
||||
deleteAccount,
|
||||
} as Record<
|
||||
|
|
|
@ -182,6 +182,7 @@ import * as ep___i_exportBlocking from "./endpoints/i/export-blocking.js";
|
|||
import * as ep___i_exportFollowing from "./endpoints/i/export-following.js";
|
||||
import * as ep___i_exportMute from "./endpoints/i/export-mute.js";
|
||||
import * as ep___i_exportNotes from "./endpoints/i/export-notes.js";
|
||||
import * as ep___i_importPosts from "./endpoints/i/import-posts.js";
|
||||
import * as ep___i_exportUserLists from "./endpoints/i/export-user-lists.js";
|
||||
import * as ep___i_favorites from "./endpoints/i/favorites.js";
|
||||
import * as ep___i_gallery_likes from "./endpoints/i/gallery/likes.js";
|
||||
|
@ -527,6 +528,7 @@ const eps = [
|
|||
["i/export-following", ep___i_exportFollowing],
|
||||
["i/export-mute", ep___i_exportMute],
|
||||
["i/export-notes", ep___i_exportNotes],
|
||||
["i/import-posts", ep___i_importPosts],
|
||||
["i/export-user-lists", ep___i_exportUserLists],
|
||||
["i/favorites", ep___i_favorites],
|
||||
["i/gallery/likes", ep___i_gallery_likes],
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
import define from "../../define.js";
|
||||
import { createImportPostsJob } from "@/queue/index.js";
|
||||
import { ApiError } from "../../error.js";
|
||||
import { DriveFiles } from "@/models/index.js";
|
||||
import { DAY } from "@/const.js";
|
||||
|
||||
export const meta = {
|
||||
secure: true,
|
||||
requireCredential: true,
|
||||
limit: {
|
||||
duration: DAY,
|
||||
max: 1,
|
||||
},
|
||||
errors: {
|
||||
noSuchFile: {
|
||||
message: "No such file.",
|
||||
code: "NO_SUCH_FILE",
|
||||
id: "e674141e-bd2a-ba85-e616-aefb187c9c2a",
|
||||
},
|
||||
|
||||
emptyFile: {
|
||||
message: "That file is empty.",
|
||||
code: "EMPTY_FILE",
|
||||
id: "d2f12af1-e7b4-feac-86a3-519548f2728e",
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const paramDef = {
|
||||
type: "object",
|
||||
properties: {
|
||||
fileId: { type: "string", format: "misskey:id" },
|
||||
},
|
||||
required: ["fileId"],
|
||||
} as const;
|
||||
|
||||
export default define(meta, paramDef, async (ps, user) => {
|
||||
const file = await DriveFiles.findOneBy({ id: ps.fileId });
|
||||
|
||||
if (file == null) throw new ApiError(meta.errors.noSuchFile);
|
||||
if (file.size === 0) throw new ApiError(meta.errors.emptyFile);
|
||||
createImportPostsJob(user, file.id);
|
||||
});
|
|
@ -7,6 +7,11 @@
|
|||
<template #icon><i class="ph-download-simple ph-bold ph-lg"></i></template>
|
||||
<MkButton primary :class="$style.button" inline @click="exportNotes()"><i class="ph-download-simple ph-bold ph-lg"></i> {{ i18n.ts.export }}</MkButton>
|
||||
</FormFolder>
|
||||
<FormFolder class="_formBlock">
|
||||
<template #label>{{ i18n.ts.import }}</template>
|
||||
<template #icon><i class="ph-upload-simple ph-bold ph-lg"></i></template>
|
||||
<MkButton primary :class="$style.button" inline @click="importPosts($event)"><i class="ph-upload-simple ph-bold ph-lg"></i> {{ i18n.ts.import }}</MkButton>
|
||||
</FormFolder>
|
||||
</FormSection>
|
||||
<FormSection>
|
||||
<template #label>{{ i18n.ts._exportOrImport.followingList }}</template>
|
||||
|
@ -108,6 +113,11 @@ const exportNotes = () => {
|
|||
os.api('i/export-notes', {}).then(onExportSuccess).catch(onError);
|
||||
};
|
||||
|
||||
const importPosts = async (ev) => {
|
||||
const file = await selectFile(ev.currentTarget ?? ev.target);
|
||||
os.api('i/import-posts', { fileId: file.id }).then(onImportSuccess).catch(onError);
|
||||
};
|
||||
|
||||
const exportFollowing = () => {
|
||||
os.api('i/export-following', {
|
||||
excludeMuting: excludeMutingUsers.value,
|
||||
|
|
Loading…
Reference in New Issue