feat: ✨ Allow importing follows from Pixelfed
This commit is contained in:
parent
b60e529d7d
commit
6ed18667b7
4 changed files with 71 additions and 34 deletions
|
@ -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)
|
||||||
|
|
|
@ -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",
|
||||||
|
|
|
@ -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}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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',
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue