From 5aac009e969cc3bd15c484ba3437348cb7a4d186 Mon Sep 17 00:00:00 2001 From: ConfuSomu Date: Sat, 20 Jan 2024 21:57:39 -0500 Subject: Implemement Actor information tab This class still has improvements to be made, but it works and I am satisfied with it! --- src/archive/base_archive.cpp | 4 ++ src/archive/base_archive.h | 9 +++-- src/archive/mastodon.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++++ src/archive/mastodon.h | 3 ++ 4 files changed, 103 insertions(+), 3 deletions(-) (limited to 'src/archive') diff --git a/src/archive/base_archive.cpp b/src/archive/base_archive.cpp index 47cadf2..472abb1 100644 --- a/src/archive/base_archive.cpp +++ b/src/archive/base_archive.cpp @@ -15,3 +15,7 @@ Archive::Archive(const QString& filename) : main_filename(filename) {} const QString Archive::get_instance_address() { return ""; } + +APActor* Archive::get_main_actor() { + return nullptr; +} diff --git a/src/archive/base_archive.h b/src/archive/base_archive.h index bf43306..27259b3 100644 --- a/src/archive/base_archive.h +++ b/src/archive/base_archive.h @@ -1,10 +1,10 @@ #pragma once - +#include "src/activitypub/apactivity.h" +#include "src/activitypub/apactor.h" +#include "src/types.h" #include #include #include -#include "src/activitypub/apactivity.h" -#include "src/types.h" enum ArchiveType { MASTODON @@ -35,6 +35,9 @@ public: virtual void update_status_list(ViewStatusTypes allowed_types, QListWidget *parent) = 0; virtual APActivity* get_activity(ArchiveItemRef index, Hinting_t hinting) = 0; + // Get the Actor that represents the data export, the user who's account data has been exported. + // Return nullptr if the Actor cannot be retrieved + virtual APActor* get_main_actor(); virtual const QString get_html_status_text(ArchiveItemRef status_index) = 0; virtual const QString get_instance_address(); diff --git a/src/archive/mastodon.cpp b/src/archive/mastodon.cpp index 781f928..121c366 100644 --- a/src/archive/mastodon.cpp +++ b/src/archive/mastodon.cpp @@ -355,6 +355,96 @@ const QString MastodonArchive::get_html_status_text(ArchiveItemRef index) { return text; } +APActor* MastodonArchive::get_main_actor() { + // Avoid recreating the Actor each time by caching it + if (actor) return actor; + + // First, get the file + QString actor_filepath = archive_root_dir.filePath("actor.json"); + if (not QFile::exists(actor_filepath)) return nullptr; + QFile actor_file(actor_filepath); + + if (!actor_file.open(QIODevice::ReadOnly | QIODevice::Text)) + return nullptr; + + QJsonParseError json_error; + QJsonDocument actor_json_document = QJsonDocument::fromJson(actor_file.readAll(), &json_error); + actor_file.close(); + + if (json_error.error != QJsonParseError::NoError or actor_json_document.isNull() or actor_json_document.isEmpty() or not actor_json_document.isObject()) + return nullptr; + + // Second, now check the JSON + QJsonObject actor_json(actor_json_document.object()); + + // Do some more throughful checks to make sure that the JSON is actually valid + // Please tell me if actor is not "actor.json" (also, i should instead first read actor.json to know the outbox file location, not the other way around as i've been doing since the beginning). Indeed, the checks are also quite random + if (not json_check_item(actor_json.value("@context"), "https://www.w3.org/ns/activitystreams") or actor_json.value("outbox").toString() != "outbox.json") + return nullptr; + + // Third, now parse the JSON :-D + { + APActorFields obj_fields; + // If the key doesn't exist then toString() will return a null QString + obj_fields.url = actor_json.value("id").toString(); + obj_fields.username = actor_json.value("preferredUsername").toString(); + obj_fields.display_name = actor_json.value("name").toString(); + obj_fields.summary = actor_json.value("summary").toString(); + obj_fields.manuallyApprovesFollowers = actor_json.value("manuallyApprovesFollowers").toBool(); + obj_fields.discoverable = actor_json.value("discoverable").toBool(); + obj_fields.joined_date = actor_json.value("published").toString(); + + if (actor_json.value("attachment").isArray()) { + QJsonArray table = actor_json.value("attachment").toArray(); + for (auto pair_obj : table) { + QJsonObject pair = pair_obj.toObject(); + + // Not a PropertyValue, so better not continue with this pair (just in case it represents something else) + if (pair.value("type").toString() != "PropertyValue") { + qDebug() << "not a PropertyValue!"; + continue; + } + + if (pair.contains("name") && pair.contains("value")) { + obj_fields.keys.append(pair.value("name").toString()); + obj_fields.values.append(pair.value("value").toString()); + } + } + } + + if (actor_json.value("alsoKnownAs").isArray()) { + QJsonArray list = actor_json.value("alsoKnownAs").toArray(); + for (auto id_obj : list) + obj_fields.also_known_as.append(id_obj.toString()); + } + + if (actor_json.value("icon").isObject()) { + APAttachmentFields att_fields; + QJsonObject attachment = actor_json.value("icon").toObject(); + + att_fields.media_type = attachment["mediaType"].toString(); + att_fields.path = archive_root_dir.absoluteFilePath(attachment["url"].toString()); + + obj_fields.avatar = new APAttachment(att_fields); + } + + if (actor_json.value("image").isObject()) { + APAttachmentFields att_fields; + QJsonObject attachment = actor_json.value("image").toObject(); + att_fields.media_type = attachment["mediaType"].toString(); + att_fields.path = archive_root_dir.absoluteFilePath(attachment["url"].toString()); + obj_fields.header = new APAttachment(att_fields); + } + + actor = new APActor(obj_fields); + + // TODO: query type. it seems to be always "Person", but maybe if the account is a bot, it changes? + // The code also currently ignores possible featured tags and users + } + + return actor; +} + void MastodonArchive::find_attachment_dir(QString example_attachment) { // Find the root directory name of the attachment QString root_name = example_attachment.split('/', Qt::SkipEmptyParts)[0]; diff --git a/src/archive/mastodon.h b/src/archive/mastodon.h index 75bc7ec..f148047 100644 --- a/src/archive/mastodon.h +++ b/src/archive/mastodon.h @@ -3,6 +3,7 @@ #include "src/archive/base_archive.h" #include "src/activitypub/fields.h" #include "src/activitypub/apactivity.h" +#include "src/activitypub/apactor.h" #include "src/types.h" #include @@ -19,6 +20,7 @@ public: void update_status_list(ViewStatusTypes allowed_types, QListWidget *parent); APActivity* get_activity(ArchiveItemRef index, Hinting_t hinting = {}); + APActor* get_main_actor(); const QString get_html_status_text(ArchiveItemRef status_index); const QString get_instance_address(); private: @@ -28,6 +30,7 @@ private: QJsonObject *outbox_json = nullptr; QJsonArray *outbox_items = nullptr; + APActor* actor = nullptr; bool is_status_type_allowed(StatusType status_type, ViewStatusTypes allowed_types); StatusType get_status_type(QJsonObject obj); -- cgit v1.2.3-54-g00ecf