feat: Allow importing follows from Pixelfed

This commit is contained in:
ThatOneCalculator 2022-10-27 14:17:40 -07:00
parent b60e529d7d
commit 6ed18667b7
4 changed files with 71 additions and 34 deletions

View file

@ -29,7 +29,7 @@
- Improve accesibility score - Improve accesibility score
<details><summary>Current Misskey score is 57/100</summary> <details><summary>Current Misskey score is 57/100</summary>
![](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)
</details> </details>
@ -77,6 +77,7 @@
- Fix incoming chat scrolling globally - Fix incoming chat scrolling globally
- Update notifier - Update notifier
- Allow admins to set logo URL via admin settings - Allow admins to set logo URL via admin settings
- Allow importing follows from Pixelfed
- Obliteration of Ai-chan - Obliteration of Ai-chan
- [Make showing ads optional](https://github.com/misskey-dev/misskey/pull/8996) - [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) - [Tapping avatar in mobile opens account modal](https://github.com/misskey-dev/misskey/pull/9056)

View file

@ -1,6 +1,6 @@
{ {
"name": "calckey", "name": "calckey",
"version": "12.119.0-calc.4.7", "version": "12.119.0-calc.5.1",
"codename": "aqua", "codename": "aqua",
"repository": { "repository": {
"type": "git", "type": "git",

View file

@ -1,14 +1,14 @@
import Bull from 'bull'; import { IsNull } from 'typeorm';
import { queueLogger } from '../../logger.js';
import follow from '@/services/following/create.js'; import follow from '@/services/following/create.js';
import * as Acct from '@/misc/acct.js'; import * as Acct from '@/misc/acct.js';
import { resolveUser } from '@/remote/resolve-user.js'; import { resolveUser } from '@/remote/resolve-user.js';
import { downloadTextFile } from '@/misc/download-text-file.js'; import { downloadTextFile } from '@/misc/download-text-file.js';
import { isSelfHost, toPuny } from '@/misc/convert-host.js'; import { isSelfHost, toPuny } from '@/misc/convert-host.js';
import { Users, DriveFiles } from '@/models/index.js'; import { Users, DriveFiles } from '@/models/index.js';
import { DbUserImportJobData } from '@/queue/types.js'; import type { DbUserImportJobData } from '@/queue/types.js';
import { IsNull } from 'typeorm'; import { queueLogger } from '../../logger.js';
import type Bull from 'bull';
const logger = queueLogger.createSubLogger('import-following'); const logger = queueLogger.createSubLogger('import-following');
@ -33,39 +33,75 @@ export async function importFollowing(job: Bull.Job<DbUserImportJobData>, done:
let linenum = 0; let linenum = 0;
for (const line of csv.trim().split('\n')) { if (file.type.endsWith('json')) {
linenum++; for (const acct of JSON.parse(csv)) {
try {
const { username, host } = Acct.parse(acct);
try { let target = isSelfHost(host!) ? await Users.findOneBy({
const acct = line.split(',')[0].trim(); host: IsNull(),
const { username, host } = Acct.parse(acct); usernameLower: username.toLowerCase(),
}) : await Users.findOneBy({
host: toPuny(host!),
usernameLower: username.toLowerCase(),
});
let target = isSelfHost(host!) ? await Users.findOneBy({ if (host == null && target == null) continue;
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) { if (target == null) {
target = await resolveUser(username, host); 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) { try {
throw new Error(`cannot resolve user: @${username}@${host}`); 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}`);
} }
} }

View file

@ -20,7 +20,7 @@ export const meta = {
}, },
unexpectedFileType: { unexpectedFileType: {
message: 'We need csv file.', message: 'Must be a CSV or JSON file.',
code: 'UNEXPECTED_FILE_TYPE', code: 'UNEXPECTED_FILE_TYPE',
id: '660f3599-bce0-4f95-9dde-311fd841c183', id: '660f3599-bce0-4f95-9dde-311fd841c183',
}, },