From 0172d3afb09c557af6288d9fc640cf1af9013a8c Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Thu, 27 Oct 2022 14:17:40 -0700 Subject: [PATCH] feat: :sparkles: Allow importing follows from Pixelfed --- CALCKEY.md | 3 +- package.json | 2 +- .../queue/processors/db/import-following.ts | 98 +++++++++++++------ .../api/endpoints/i/import-following.ts | 2 +- 4 files changed, 71 insertions(+), 34 deletions(-) diff --git a/CALCKEY.md b/CALCKEY.md index a2250116b..f14956307 100644 --- a/CALCKEY.md +++ b/CALCKEY.md @@ -29,7 +29,7 @@ - Improve accesibility score
Current Misskey score is 57/100 -![](https://pool.jortage.com/voringme/misskey/8ff18aae-4dc6-4b08-9e05-a4c9d051a9e3.png) +![accesibility score](https://pool.jortage.com/voringme/misskey/8ff18aae-4dc6-4b08-9e05-a4c9d051a9e3.png)
@@ -77,6 +77,7 @@ - Fix incoming chat scrolling globally - Update notifier - Allow admins to set logo URL via admin settings +- Allow importing follows from Pixelfed - Obliteration of Ai-chan - [Make showing ads optional](https://github.com/misskey-dev/misskey/pull/8996) - [Tapping avatar in mobile opens account modal](https://github.com/misskey-dev/misskey/pull/9056) diff --git a/package.json b/package.json index 43498cc7c..1faba872a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "calckey", - "version": "12.119.0-calc.4.7", + "version": "12.119.0-calc.5.1", "codename": "aqua", "repository": { "type": "git", diff --git a/packages/backend/src/queue/processors/db/import-following.ts b/packages/backend/src/queue/processors/db/import-following.ts index 1824c3669..6c40ebc1c 100644 --- a/packages/backend/src/queue/processors/db/import-following.ts +++ b/packages/backend/src/queue/processors/db/import-following.ts @@ -1,14 +1,14 @@ -import Bull from 'bull'; - -import { queueLogger } from '../../logger.js'; +import { IsNull } from 'typeorm'; import follow from '@/services/following/create.js'; + import * as Acct from '@/misc/acct.js'; import { resolveUser } from '@/remote/resolve-user.js'; import { downloadTextFile } from '@/misc/download-text-file.js'; import { isSelfHost, toPuny } from '@/misc/convert-host.js'; import { Users, DriveFiles } from '@/models/index.js'; -import { DbUserImportJobData } from '@/queue/types.js'; -import { IsNull } from 'typeorm'; +import type { DbUserImportJobData } from '@/queue/types.js'; +import { queueLogger } from '../../logger.js'; +import type Bull from 'bull'; const logger = queueLogger.createSubLogger('import-following'); @@ -33,39 +33,75 @@ export async function importFollowing(job: Bull.Job, done: let linenum = 0; - for (const line of csv.trim().split('\n')) { - linenum++; + if (file.type.endsWith('json')) { + for (const acct of JSON.parse(csv)) { + try { + const { username, host } = Acct.parse(acct); - try { - const acct = line.split(',')[0].trim(); - const { username, host } = Acct.parse(acct); + let target = isSelfHost(host!) ? await Users.findOneBy({ + host: IsNull(), + usernameLower: username.toLowerCase(), + }) : await Users.findOneBy({ + host: toPuny(host!), + usernameLower: username.toLowerCase(), + }); - let target = isSelfHost(host!) ? await Users.findOneBy({ - host: IsNull(), - usernameLower: username.toLowerCase(), - }) : await Users.findOneBy({ - host: toPuny(host!), - usernameLower: username.toLowerCase(), - }); + if (host == null && target == null) continue; - if (host == null && target == null) continue; + if (target == null) { + target = await resolveUser(username, host); + } - if (target == null) { - target = await resolveUser(username, host); + if (target == null) { + throw new Error(`cannot resolve user: @${username}@${host}`); + } + + // skip myself + if (target.id === job.data.user.id) continue; + + logger.info(`Follow[${linenum}] ${target.id} ...`); + + follow(user, target); + } catch (e) { + logger.warn(`Error in line:${linenum} ${e}`); } + } + } + else { + for (const line of csv.trim().split('\n')) { + linenum++; - if (target == null) { - throw new Error(`cannot resolve user: @${username}@${host}`); + try { + const acct = line.split(',')[0].trim(); + const { username, host } = Acct.parse(acct); + + let target = isSelfHost(host!) ? await Users.findOneBy({ + host: IsNull(), + usernameLower: username.toLowerCase(), + }) : await Users.findOneBy({ + host: toPuny(host!), + usernameLower: username.toLowerCase(), + }); + + if (host == null && target == null) continue; + + if (target == null) { + target = await resolveUser(username, host); + } + + if (target == null) { + throw new Error(`cannot resolve user: @${username}@${host}`); + } + + // skip myself + if (target.id === job.data.user.id) continue; + + logger.info(`Follow[${linenum}] ${target.id} ...`); + + follow(user, target); + } catch (e) { + logger.warn(`Error in line:${linenum} ${e}`); } - - // skip myself - if (target.id === job.data.user.id) continue; - - logger.info(`Follow[${linenum}] ${target.id} ...`); - - follow(user, target); - } catch (e) { - logger.warn(`Error in line:${linenum} ${e}`); } } diff --git a/packages/backend/src/server/api/endpoints/i/import-following.ts b/packages/backend/src/server/api/endpoints/i/import-following.ts index 28d9d38fa..23414547f 100644 --- a/packages/backend/src/server/api/endpoints/i/import-following.ts +++ b/packages/backend/src/server/api/endpoints/i/import-following.ts @@ -20,7 +20,7 @@ export const meta = { }, unexpectedFileType: { - message: 'We need csv file.', + message: 'Must be a CSV or JSON file.', code: 'UNEXPECTED_FILE_TYPE', id: '660f3599-bce0-4f95-9dde-311fd841c183', },