summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoranatawa12 <anatawa12@icloud.com>2025-05-29 13:15:41 +0900
committerGitHub <noreply@github.com>2025-05-29 13:15:41 +0900
commit1214d1d8fc84bbd4b23937ed7dfa9c3392c0863d (patch)
tree91419ec77f2e99ba1e9abd31e113ec0546007227
parentFix: ミュート対象ユーザーが引用されているノートがRNさ... (diff)
downloadmisskey-1214d1d8fc84bbd4b23937ed7dfa9c3392c0863d.tar.gz
misskey-1214d1d8fc84bbd4b23937ed7dfa9c3392c0863d.tar.bz2
misskey-1214d1d8fc84bbd4b23937ed7dfa9c3392c0863d.zip
Export/Import withReplies (#15986)
* feat: export withReplies of UserList * feat: export withReplies of following * import following時のwithRepliesがデフォルト値であることを明示する * changelog * update index.d.ts --------- Co-authored-by: syuilo <4439005+syuilo@users.noreply.github.com>
-rw-r--r--CHANGELOG.md1
-rw-r--r--locales/index.d.ts2
-rw-r--r--locales/ja-JP.yml2
-rw-r--r--packages/backend/src/core/UserListService.ts3
-rw-r--r--packages/backend/src/queue/processors/ExportFollowingProcessorService.ts3
-rw-r--r--packages/backend/src/queue/processors/ExportUserListsProcessorService.ts4
-rw-r--r--packages/backend/src/queue/processors/ImportFollowingProcessorService.ts15
-rw-r--r--packages/backend/src/queue/processors/ImportUserListsProcessorService.ts19
8 files changed, 39 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee7a9d4841..10b19dacf8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -57,6 +57,7 @@
- Fix: Twitchのクリップがプレイヤーで再生できない問題を修正
### Server
+- Enhance: リストやフォローをエクスポートする際にリプライを含むかどうかの情報を含むように
- Enhance: チャットルームの最大メンバー数を30人から50人に調整
- Enhance: ノートのレスポンスにアンケートが添付されているかどうかを示すフラグ`hasPoll`を追加
- Enhance: チャットルームのレスポンスに招待されているかどうかを示すフラグ`invitationExists`を追加
diff --git a/locales/index.d.ts b/locales/index.d.ts
index c75c155d74..cecda4d44e 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -9707,7 +9707,7 @@ export interface Locale extends ILocale {
*/
"excludeInactiveUsers": string;
/**
- * インポートした人による返信をTLに含むようにする
+ * 返信をTLに含むかの情報がファイルにない場合に、インポートした人による返信をTLに含むようにする
*/
"withReplies": string;
};
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 865d5d4203..e059fc99ee 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -2556,7 +2556,7 @@ _exportOrImport:
userLists: "リスト"
excludeMutingUsers: "ミュートしているユーザーを除外"
excludeInactiveUsers: "使われていないアカウントを除外"
- withReplies: "インポートした人による返信をTLに含むようにする"
+ withReplies: "返信をTLに含むかの情報がファイルにない場合に、インポートした人による返信をTLに含むようにする"
_charts:
federation: "連合"
diff --git a/packages/backend/src/core/UserListService.ts b/packages/backend/src/core/UserListService.ts
index f0a8768c8f..61435500b7 100644
--- a/packages/backend/src/core/UserListService.ts
+++ b/packages/backend/src/core/UserListService.ts
@@ -91,7 +91,7 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit {
}
@bindThis
- public async addMember(target: MiUser, list: MiUserList, me: MiUser) {
+ public async addMember(target: MiUser, list: MiUserList, me: MiUser, options: { withReplies?: boolean } = {}) {
const currentCount = await this.userListMembershipsRepository.countBy({
userListId: list.id,
});
@@ -104,6 +104,7 @@ export class UserListService implements OnApplicationShutdown, OnModuleInit {
userId: target.id,
userListId: list.id,
userListUserId: list.userId,
+ withReplies: options.withReplies ?? false,
} as MiUserListMembership);
this.globalEventService.publishInternalEvent('userListMemberAdded', { userListId: list.id, memberId: target.id });
diff --git a/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts b/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts
index 903f962515..91c39cb758 100644
--- a/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts
+++ b/packages/backend/src/queue/processors/ExportFollowingProcessorService.ts
@@ -94,7 +94,8 @@ export class ExportFollowingProcessorService {
continue;
}
- const content = this.utilityService.getFullApAccount(u.username, u.host);
+ const userAcct = this.utilityService.getFullApAccount(u.username, u.host);
+ const content = `${userAcct},withReplies=${following.withReplies}`;
await new Promise<void>((res, rej) => {
stream.write(content + '\n', err => {
if (err) {
diff --git a/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts b/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts
index c483d79854..733e75f65f 100644
--- a/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts
+++ b/packages/backend/src/queue/processors/ExportUserListsProcessorService.ts
@@ -67,10 +67,12 @@ export class ExportUserListsProcessorService {
const users = await this.usersRepository.findBy({
id: In(memberships.map(j => j.userId)),
});
+ const usersWithReplies = new Set(memberships.filter(m => m.withReplies).map(m => m.userId));
for (const u of users) {
const acct = this.utilityService.getFullApAccount(u.username, u.host);
- const content = `${list.name},${acct}`;
+ // 3rd column and later will be key=value pairs
+ const content = `${list.name},${acct},withReplies=${usersWithReplies.has(u.id)}`;
await new Promise<void>((res, rej) => {
stream.write(content + '\n', err => {
if (err) {
diff --git a/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts b/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts
index 70c9f3a096..03663d3b06 100644
--- a/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts
+++ b/packages/backend/src/queue/processors/ImportFollowingProcessorService.ts
@@ -67,8 +67,19 @@ export class ImportFollowingProcessorService {
const user = job.data.user;
try {
- const acct = line.split(',')[0].trim();
+ const parts = line.split(',');
+ const acct = parts[0].trim();
const { username, host } = Acct.parse(acct);
+ let withReplies: boolean | null = null;
+
+ for (const keyValue of parts.slice(2)) {
+ const [key, value] = keyValue.split('=');
+ switch (key) {
+ case 'withReplies':
+ withReplies = value === 'true';
+ break;
+ }
+ }
if (!host) return;
@@ -95,7 +106,7 @@ export class ImportFollowingProcessorService {
this.logger.info(`Follow ${target.id} ${job.data.withReplies ? 'with replies' : 'without replies'} ...`);
- this.queueService.createFollowJob([{ from: user, to: { id: target.id }, silent: true, withReplies: job.data.withReplies }]);
+ await this.queueService.createFollowJob([{ from: user, to: { id: target.id }, silent: true, withReplies: withReplies ?? job.data.withReplies }]);
} catch (e) {
this.logger.warn(`Error: ${e}`);
}
diff --git a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts
index db9255b35d..bf061a1f78 100644
--- a/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts
+++ b/packages/backend/src/queue/processors/ImportUserListsProcessorService.ts
@@ -70,8 +70,19 @@ export class ImportUserListsProcessorService {
linenum++;
try {
- const listName = line.split(',')[0].trim();
- const { username, host } = Acct.parse(line.split(',')[1].trim());
+ const parts = line.split(',');
+ const listName = parts[0].trim();
+ const { username, host } = Acct.parse(parts[1].trim());
+ let withReplies = false;
+
+ for (const keyValue of parts.slice(2)) {
+ const [key, value] = keyValue.split('=');
+ switch (key) {
+ case 'withReplies':
+ withReplies = value === 'true';
+ break;
+ }
+ }
let list = await this.userListsRepository.findOneBy({
userId: user.id,
@@ -100,7 +111,9 @@ export class ImportUserListsProcessorService {
if (await this.userListMembershipsRepository.findOneBy({ userListId: list!.id, userId: target.id }) != null) continue;
- this.userListService.addMember(target, list!, user);
+ await this.userListService.addMember(target, list, user, {
+ withReplies: withReplies,
+ });
} catch (e) {
this.logger.warn(`Error in line:${linenum} ${e}`);
}