KItinerary

activitypubextractor.cpp
1/*
2 SPDX-FileCopyrightText: 2023 Volker Krause <vkrause@kde.org>
3 SPDX-License-Identifier: LGPL-2.0-or-later
4*/
5
6#include "activitypubextractor.h"
7
8#include "json/jsonldfilterengine.h"
9
10#include <KItinerary/ExtractorDocumentNode>
11#include <KItinerary/ExtractorResult>
12
13#include <QJsonArray>
14#include <QJsonObject>
15
16using namespace KItinerary;
17
18ActivityPubExtractor::ActivityPubExtractor() = default;
19ActivityPubExtractor::~ActivityPubExtractor() = default;
20
22{
23 return QStringLiteral("<ActivityPub>");
24}
25
26static bool isActivityStreamsContext(const QJsonValue &context)
27{
28 return context.isString() &&
29 context.toString() ==
30 QLatin1StringView("https://www.w3.org/ns/activitystreams");
31}
32
34{
35 const auto array = node.content<QJsonArray>();
36 for (const auto &v : array) {
37 if (!v.isObject()) {
38 continue;
39 }
40 const auto obj = v.toObject();
41 const auto context = obj.value(QLatin1StringView("@context"));
42 if (isActivityStreamsContext(context)) {
43 return true;
44 }
45 if (context.isArray()) {
46 const auto contexts = context.toArray();
47 if (std::any_of(contexts.begin(), contexts.end(), isActivityStreamsContext)) {
48 return true;
49 }
50 }
51 }
52 return false;
53}
54
55static void convertPlace(QJsonObject &obj)
56{
57 QJsonObject geo({
58 {QLatin1StringView("@type"), QLatin1String("GeoCoordinates")},
59 {QLatin1StringView("latitude"), obj.value(QLatin1String("latitude"))},
60 {QLatin1StringView("longitude"), obj.value(QLatin1String("longitude"))},
61 });
62 obj.insert(QLatin1StringView("geo"), geo);
63}
64
65// filter functions applied to objects of the corresponding (already normalized) type
66// IMPORTANT: keep alphabetically sorted by type!
67static constexpr const JsonLdFilterEngine::TypeFilter type_filters[] = {
68 { "Place", convertPlace },
69};
70
71// property mappings
72// IMPORTANT: keep alphabetically sorted by type!
73static constexpr const JsonLdFilterEngine::PropertyMapping property_mappings[] = {
74 { "Event", "endTime", "endDate" },
75 { "Event", "startTime", "startDate"},
76};
77
78// in theory we would need the whole JSON-LD schema-aware normalization here
79// in practice this is good enough and works
80// (should we ever need more, KHealthCertificate has some of that JSON-LD code)
81static QJsonValue convertActivityStreamObject(const QJsonValue &value)
82{
83 if (!value.isObject()) {
84 return value;
85 }
86
87 auto obj = value.toObject();
88 for (auto it = obj.begin(); it != obj.end(); ++it) {
89 if (it.value().isObject()) {
90 (*it) = convertActivityStreamObject(it.value());
91 }
92 }
93
94 if (const auto t = obj.value(QLatin1StringView("type")).toString();
95 !t.isEmpty()) {
96 obj.insert(QLatin1StringView("@type"), t);
97 }
98
99 JsonLdFilterEngine filterEngine;
100 filterEngine.setTypeFilters(type_filters);
101 filterEngine.setPropertyMappings(property_mappings);
102 filterEngine.filterRecursive(obj);
103
104 return obj;
105}
106
108{
109 const auto array = node.content<QJsonArray>();
110 QJsonArray result;
111 std::transform(array.begin(), array.end(), std::back_inserter(result), convertActivityStreamObject);
112 return result;
113}
ExtractorResult extract(const ExtractorDocumentNode &node, const ExtractorEngine *engine) const override
Extract data from node.
bool canHandle(const KItinerary::ExtractorDocumentNode &node) const override
Fast check whether this extractor is applicable for node.
QString name() const override
Identifier for this extractor.
A node in the extracted document object tree.
QJSValue content
The decoded content of this node.
Semantic data extraction engine.
Generic extraction result.
JSON-LD filtering for input normalization or type transforms.
void filterRecursive(QJsonObject &obj)
Recursively apply filtering rules to obj.
char * toString(const EngineQuery &query)
GeoCoordinates geo(const QVariant &location)
Returns the geo coordinates of a given location.
Classes for reservation/travel data models, data extraction and data augmentation.
Definition berelement.h:17
iterator begin()
iterator end()
iterator insert(QLatin1StringView key, const QJsonValue &value)
QJsonValue value(QLatin1StringView key) const const
bool isArray() const const
bool isObject() const const
bool isString() const const
QJsonArray toArray() const const
QJsonObject toObject() const const
QString toString() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 3 2024 11:45:33 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.