Commit 86dd01e8 authored by Volker Krause's avatar Volker Krause
Browse files

Base extractor filters on MIME types rather than our own type enum

This is mostly migration scaffolding for now, as neither the consumer
nor the provider side has been adjusted to use MIME types yet, but we
can adapt both sides independently now.

This is part of a larger set of changes phasing out the use of
ExtractorInput altogether, as that ties us to a hardcoded set of
supported types.
parent a05b8bc4
Pipeline #54704 passed with stages
in 12 minutes and 4 seconds
......@@ -45,10 +45,10 @@ class ExtractorRepositoryPrivate;
* - \c ICal: iCalendar events, the argument to the script function is a KCalendarCore::Event instance.
*
* Filter definitions have the following field:
* - \c type: The type of data this filter applies to, one of: @c Mime, @c PkPass, @c JsonLd, @c Barcode, @c ICal, @c Text.
* - \c mimeType: The MIME type of the document part this filter can match against.
* - \c field: The name of the field to match against. This can be a field id in a Apple Wallet pass,
* A MIME message header name, a property on a Json-LD object or an iCal calendar or event.
* For @c Text or @c Barcode, this is ignored.
* For plain text or binary content, this is ignored.
* - \c match: A regular expression that is matched against the specified value (see QRegularExpression).
* - \c scope: Specifies how the filter should be applied relative to the document node that is being extracted.
* One of @c Current, @c Parent, @c Children, @c Ancestors, @c Descendants (@c Current is the default).
......@@ -58,13 +58,13 @@ class ExtractorRepositoryPrivate;
* [
* {
* "type": "Pdf",
* "filter": [ { "field": "From", "match": "@swiss.com", "type": "Email", "scope": "Ancestors" } ],
* "filter": [ { "field": "From", "match": "@swiss.com", "mimeType": "message/rfc822", "scope": "Ancestors" } ],
* "script": "swiss.js",
* "function": "parsePdf"
* },
* {
* "type": "PkPass",
* "filter": [ { "field": "passTypeIdentifier", "match": "pass.booking.swiss.com", "type": "PkPass", "scope": "Current" } ],
* "filter": [ { "field": "passTypeIdentifier", "match": "pass.booking.swiss.com", "mimeType": "application/vnd.apple.pkpass", "scope": "Current" } ],
* "script": "swiss.js",
* "function": "parsePkPass"
* }
......
......@@ -17,7 +17,7 @@ namespace KItinerary {
class ExtractorFilterPrivate : public QSharedData
{
public:
ExtractorInput::Type m_type = ExtractorInput::Unknown;
QString m_mimeType;
QString m_fieldName;
QRegularExpression m_exp;
ExtractorFilter::Scope m_scope = ExtractorFilter::Current;
......@@ -37,13 +37,23 @@ ExtractorFilter& ExtractorFilter::operator=(ExtractorFilter&&) = default;
ExtractorInput::Type ExtractorFilter::type() const
{
return d->m_type;
return ExtractorInput::typeFromMimeType(d->m_mimeType);
}
void ExtractorFilter::setType(ExtractorInput::Type type)
{
setMimeType(ExtractorInput::typeToMimeType(type));
}
QString ExtractorFilter::mimeType() const
{
return d->m_mimeType;
}
void ExtractorFilter::setMimeType(const QString &mimeType)
{
d.detach();
d->m_type = type;
d->m_mimeType = mimeType;
}
QString ExtractorFilter::fieldName() const
......@@ -65,15 +75,9 @@ bool ExtractorFilter::matches(const QString &data) const
return d->m_exp.match(data).hasMatch();
}
static bool needsFieldName(ExtractorInput::Type type)
static bool needsFieldName(const QString &mimeType)
{
switch (type) {
case ExtractorInput::Barcode:
case ExtractorInput::Text:
return false;
default:
return true;
}
return mimeType != QLatin1String("text/plain") && mimeType != QLatin1String("application/octet-stream");
}
template <typename T>
......@@ -91,21 +95,25 @@ static T readEnum(const QJsonValue &v, T defaultValue = {})
bool ExtractorFilter::load(const QJsonObject &obj)
{
d->m_type = ExtractorInput::typeFromName(obj.value(QLatin1String("type")).toString());
if (d->m_type == ExtractorInput::Unknown) {
d.detach();
d->m_mimeType = obj.value(QLatin1String("mimeType")).toString();
if (d->m_mimeType.isEmpty()) {
setType(ExtractorInput::typeFromName(obj.value(QLatin1String("type")).toString()));
}
if (d->m_mimeType.isEmpty()) {
qCDebug(Log) << "unspecified filter type";
}
d->m_fieldName = obj.value(QLatin1String("field")).toString();
d->m_exp.setPattern(obj.value(QLatin1String("match")).toString());
d->m_scope = readEnum<ExtractorFilter::Scope>(obj.value(QLatin1String("scope")), ExtractorFilter::Current);
return d->m_type != ExtractorInput::Unknown && (!d->m_fieldName.isEmpty() || !needsFieldName(d->m_type)) && d->m_exp.isValid();
return !d->m_mimeType.isEmpty() && (!d->m_fieldName.isEmpty() || !needsFieldName(d->m_mimeType)) && d->m_exp.isValid();
}
QJsonObject ExtractorFilter::toJson() const
{
QJsonObject obj;
obj.insert(QLatin1String("type"), ExtractorInput::typeToString(d->m_type));
if (needsFieldName(d->m_type)) {
obj.insert(QLatin1String("mimeType"), d->m_mimeType);
if (needsFieldName(d->m_mimeType)) {
obj.insert(QLatin1String("field"), d->m_fieldName);
}
obj.insert(QLatin1String("match"), pattern());
......
......@@ -33,7 +33,9 @@ public:
ExtractorFilter& operator=(ExtractorFilter&&);
/** The filter type. */
ExtractorInput::Type type() const;
[[deprecated("use mimeType()")]] ExtractorInput::Type type() const;
/** MIME type of the document part this filter can match. */
QString mimeType() const;
/** The field to filter on. */
QString fieldName() const;
/** Check if @p data matches this filter. */
......@@ -59,7 +61,8 @@ public:
/** Serialize filter to a JSON object. */
QJsonObject toJson() const;
void setType(ExtractorInput::Type type);
[[deprecated("use setMimeType()")]] void setType(ExtractorInput::Type type);
void setMimeType(const QString &mimeType);
void setFieldName(const QString &fieldName);
void setPattern(const QString &pattern);
void setScope(Scope scope);
......
......@@ -108,6 +108,9 @@ ExtractorInput::Type ExtractorInput::typeFromMimeType(const QString &mimeType)
if (mimeType == QLatin1String("text/plain")) {
return ExtractorInput::Text;
}
if (mimeType == QLatin1String("application/octet-stream")) {
return ExtractorInput::Barcode;
}
return {};
}
......@@ -168,4 +171,21 @@ ExtractorInput::Type ExtractorInput::typeFromName(const QString &name)
return {};
}
QString ExtractorInput::typeToMimeType(ExtractorInput::Type type)
{
switch (type) {
case Unknown: return {};
case Text: return QStringLiteral("text/plain");
case Barcode: return QStringLiteral("application/octet-stream");
case Email: return QStringLiteral("message/rfc822");
case Html: return QStringLiteral("text/html");
case JsonLd: return QStringLiteral("application/ld+json");
case ICal: return QStringLiteral("text/calendar");
case Pdf: return QStringLiteral("application/pdf");
case PkPass: return QStringLiteral("application/vnd.apple.pkpass");
}
return {};
}
#include "moc_extractorinput.cpp"
......@@ -44,6 +44,9 @@ namespace ExtractorInput
KITINERARY_EXPORT QString typeToString(Type type);
/** Convert string representation of the type to an enum. */
KITINERARY_EXPORT Type typeFromName(const QString &name);
/** Convert type to a MIME type. */
QString typeToMimeType(Type type);
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment