From 343b572dc9b78f03b1de5c8313a280c6a8c42af2 Mon Sep 17 00:00:00 2001 From: Rikudou_Sage Date: Wed, 4 Oct 2023 20:13:43 +0200 Subject: [PATCH] Feat: Add synchronization from Mastodon to Fediseer (#146) --- .../synchronize-lemmy.component.html | 1 + .../synchronize-mastodon.component.html | 40 +++++++++++- .../synchronize-mastodon.component.ts | 64 ++++++++++++++++++- 3 files changed, 103 insertions(+), 2 deletions(-) diff --git a/src/app/synchronization/pages/synchronize-lemmy/synchronize-lemmy.component.html b/src/app/synchronization/pages/synchronize-lemmy/synchronize-lemmy.component.html index 90b5e76..2a7c7da 100644 --- a/src/app/synchronization/pages/synchronize-lemmy/synchronize-lemmy.component.html +++ b/src/app/synchronization/pages/synchronize-lemmy/synchronize-lemmy.component.html @@ -113,6 +113,7 @@

Preview

[newList]="sourceBlockedInstances" [newToStringCallback]="lemmyToFediseerSyncNewListCallback" [purgeMode]="false" + [highlightRemoved]="false" addedText="This domain is only on your instance blocklist and will be added to your Fediseer censures" /> diff --git a/src/app/synchronization/pages/synchronize-mastodon/synchronize-mastodon.component.html b/src/app/synchronization/pages/synchronize-mastodon/synchronize-mastodon.component.html index 2c42688..669504c 100644 --- a/src/app/synchronization/pages/synchronize-mastodon/synchronize-mastodon.component.html +++ b/src/app/synchronization/pages/synchronize-mastodon/synchronize-mastodon.component.html @@ -44,7 +44,7 @@

Setup OAuth

-

Synchronization

+

Synchronization from Fediseer to Mastodon

Preview
+ +
+
+

Synchronization from Mastodon to Fediseer

+
+
+

+ Note that no domains will be removed from Fediseer, only domains that are present on + {{currentInstance}} but not here on Fediseer + will be added to your Fediseer censure list. +

+
+ +
+ +
+
+

Preview

+ +
+ +
+ + + + +
+
+
+
+

Original blacklist

diff --git a/src/app/synchronization/pages/synchronize-mastodon/synchronize-mastodon.component.ts b/src/app/synchronization/pages/synchronize-mastodon/synchronize-mastodon.component.ts index ca15c55..3cb5c53 100644 --- a/src/app/synchronization/pages/synchronize-mastodon/synchronize-mastodon.component.ts +++ b/src/app/synchronization/pages/synchronize-mastodon/synchronize-mastodon.component.ts @@ -16,8 +16,12 @@ import { } from "../../components/filter-form/filter-form.component"; import {InstanceDetailResponse} from "../../../response/instance-detail.response"; import {SynchronizationMode} from "../../../types/synchronization-mode"; -import {OriginalToStringCallback} from "../../components/blacklist-diff/blacklist-diff.component"; +import {NewToStringCallback, OriginalToStringCallback} from "../../components/blacklist-diff/blacklist-diff.component"; import {NormalizedInstanceDetailResponse} from "../../../response/normalized-instance-detail.response"; +import {CachedFediseerApiService} from "../../../services/cached-fediseer-api.service"; +import {ApiResponseHelperService} from "../../../services/api-response-helper.service"; +import {ApiResponse, FediseerApiService} from "../../../services/fediseer-api.service"; +import {SuccessResponse} from "../../../response/success.response"; @Component({ selector: 'app-synchronize-mastodon', @@ -27,6 +31,7 @@ import {NormalizedInstanceDetailResponse} from "../../../response/normalized-ins export class SynchronizeMastodonComponent implements OnInit { protected readonly MastodonBlacklistSeverity = MastodonBlacklistSeverity; protected readonly currentInstance = this.authManager.currentInstanceSnapshot.name; + protected readonly mastodonToFediseerSyncNewListCallback: NewToStringCallback = instance => instance.domain; private syncSettings: MastodonSynchronizationSettings = this.database.mastodonSynchronizationSettings; @@ -51,6 +56,7 @@ export class SynchronizeMastodonComponent implements OnInit { public loadingPreview: boolean = true; public purgeMode: boolean | null = null; public instancesToBanPreview: InstanceDetailResponse[] | null = null; + public myCensuredInstances: string[] = []; public saveSettingsCallback: SaveSettingsCallback = (database, settings) => { database.mastodonSynchronizationSettings = settings; @@ -59,6 +65,7 @@ export class SynchronizeMastodonComponent implements OnInit { return database.mastodonSynchronizationSettings; } public instanceToStringCallback: OriginalToStringCallback = instance => instance.domain; + public loadingPreviewMastodonToFediseer: boolean = true; constructor( private readonly database: DatabaseService, @@ -66,6 +73,9 @@ export class SynchronizeMastodonComponent implements OnInit { private readonly authManager: AuthenticationManagerService, private readonly mastodonApi: MastodonApiService, private readonly messageService: MessageService, + private readonly cachedFediseerApi: CachedFediseerApiService, + private readonly fediseerApi: FediseerApiService, + private readonly apiResponseHelper: ApiResponseHelperService, ) { } @@ -123,6 +133,15 @@ export class SynchronizeMastodonComponent implements OnInit { } this.originallyBlockedInstances = instances; this.sourceBlockedInstances = instances; + + const myCensures = await toPromise(this.cachedFediseerApi.getCensuresByInstances([ + this.authManager.currentInstanceSnapshot.name, + ], {ttl: 10})); + if (this.apiResponseHelper.handleErrors([myCensures])) { + return; + } + this.myCensuredInstances = myCensures.successResponse!.instances.map(instance => instance.domain); + this.loadingPreviewMastodonToFediseer = false; } public async saveOauth(): Promise { @@ -263,4 +282,47 @@ export class SynchronizeMastodonComponent implements OnInit { this.instancesToBanPreview = [...instancesToBan.censured, ...instancesToBan.hesitated]; this.loadingPreview = false; } + + public async synchronizeFromMastodon() { + this.loading = true; + + const instances = this.sourceBlockedInstances.filter( + instance => !this.myCensuredInstances.includes(instance.domain), + ); + + const promises: Promise>[] = []; + for (const instance of instances) { + let reasons: string[] = []; + if (instance.private_comment) { + reasons.push(instance.private_comment); + } + if (instance.public_comment) { + reasons.push(instance.public_comment); + } + + reasons = reasons.join(',').split(',').map(reason => reason.trim().toLowerCase()); + promises.push(toPromise(this.fediseerApi.censureInstance(instance.domain, reasons.length ? reasons.join(',') : null))); + } + + const responses = await Promise.all(promises); + if (this.apiResponseHelper.handleErrors(responses)) { + this.loading = false; + return; + } + + this.cachedFediseerApi.getCensuresByInstances( + [this.authManager.currentInstanceSnapshot.name], + {clear: true, ttl: 10}, + ).subscribe(response => { + if (!response.success) { + this.messageService.createWarning(`Couldn't fetch new list of your censured instances, please reload the page to get fresh data.`); + return; + } + + this.myCensuredInstances = response.successResponse!.instances.map(instance => instance.domain); + }); + + this.messageService.createSuccess(`Your Mastodon blocklist was successfully synchronized to Fediseer. Please add reasons to the newly imported censures (if you haven't done so on Mastodon) to help your fellow admins.`); + this.loading = false; + } }