Client OPDS per Calibre Web (Sailfish OS): core C++ testato, UI Silica, packaging RPM
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
#include "opdsparser.h"
|
||||
|
||||
#include <QStringList>
|
||||
#include <QVariantMap>
|
||||
#include <QXmlStreamReader>
|
||||
|
||||
static QString elementText(QXmlStreamReader &reader)
|
||||
{
|
||||
return reader.readElementText(QXmlStreamReader::IncludeChildElements).trimmed();
|
||||
}
|
||||
|
||||
static QVariantMap parseEntry(QXmlStreamReader &reader)
|
||||
{
|
||||
QVariantMap entry;
|
||||
QStringList authors;
|
||||
QVariantList formats;
|
||||
QString title;
|
||||
QString summary;
|
||||
QString id;
|
||||
QString coverHref;
|
||||
QString thumbHref;
|
||||
QString navHref;
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNext();
|
||||
if (reader.tokenType() == QXmlStreamReader::EndElement
|
||||
&& reader.name() == QLatin1String("entry"))
|
||||
break;
|
||||
if (reader.tokenType() != QXmlStreamReader::StartElement)
|
||||
continue;
|
||||
|
||||
const QStringRef name = reader.name();
|
||||
if (name == QLatin1String("title")) {
|
||||
title = elementText(reader);
|
||||
} else if (name == QLatin1String("id")) {
|
||||
id = elementText(reader);
|
||||
} else if (name == QLatin1String("name")) {
|
||||
const QString author = elementText(reader);
|
||||
if (!author.isEmpty())
|
||||
authors.append(author);
|
||||
} else if (name == QLatin1String("content") || name == QLatin1String("summary")) {
|
||||
if (summary.isEmpty())
|
||||
summary = elementText(reader);
|
||||
} else if (name == QLatin1String("link")) {
|
||||
const QXmlStreamAttributes attrs = reader.attributes();
|
||||
const QString rel = attrs.value(QLatin1String("rel")).toString();
|
||||
const QString href = attrs.value(QLatin1String("href")).toString();
|
||||
const QString type = attrs.value(QLatin1String("type")).toString();
|
||||
|
||||
if (rel == QLatin1String("http://opds-spec.org/image")) {
|
||||
coverHref = href;
|
||||
} else if (rel == QLatin1String("http://opds-spec.org/image/thumbnail")) {
|
||||
thumbHref = href;
|
||||
} else if (rel == QLatin1String("http://opds-spec.org/acquisition")) {
|
||||
QVariantMap format;
|
||||
format.insert(QStringLiteral("format"), attrs.value(QLatin1String("title")).toString());
|
||||
format.insert(QStringLiteral("mime"), type);
|
||||
format.insert(QStringLiteral("size"), attrs.value(QLatin1String("length")).toString().toLongLong());
|
||||
format.insert(QStringLiteral("url"), href);
|
||||
formats.append(format);
|
||||
} else if (rel == QLatin1String("subsection")) {
|
||||
if (navHref.isEmpty())
|
||||
navHref = href;
|
||||
} else if (navHref.isEmpty() && type.contains(QLatin1String("opds-catalog"))) {
|
||||
// calibre-web: i link di navigazione dell'indice non hanno rel="subsection"
|
||||
navHref = href;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entry.insert(QStringLiteral("title"), title);
|
||||
entry.insert(QStringLiteral("authors"), authors.join(QStringLiteral(", ")));
|
||||
entry.insert(QStringLiteral("summary"), summary);
|
||||
entry.insert(QStringLiteral("coverUrl"), !coverHref.isEmpty() ? coverHref : thumbHref);
|
||||
entry.insert(QStringLiteral("formats"), formats);
|
||||
entry.insert(QStringLiteral("id"), id);
|
||||
entry.insert(QStringLiteral("isNavigation"), !navHref.isEmpty());
|
||||
entry.insert(QStringLiteral("linkUrl"), navHref);
|
||||
return entry;
|
||||
}
|
||||
|
||||
bool OpdsParser::parse(const QByteArray &xml,
|
||||
QVariantList *entries,
|
||||
QString *nextUrl,
|
||||
QString *feedTitle,
|
||||
QString *errorMessage)
|
||||
{
|
||||
QXmlStreamReader reader(xml);
|
||||
QVariantList result;
|
||||
QString next;
|
||||
QString title;
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
reader.readNext();
|
||||
if (reader.tokenType() != QXmlStreamReader::StartElement)
|
||||
continue;
|
||||
|
||||
const QStringRef name = reader.name();
|
||||
if (name == QLatin1String("entry")) {
|
||||
result.append(parseEntry(reader));
|
||||
} else if (name == QLatin1String("link")) {
|
||||
const QXmlStreamAttributes attrs = reader.attributes();
|
||||
if (attrs.value(QLatin1String("rel")).toString() == QLatin1String("next"))
|
||||
next = attrs.value(QLatin1String("href")).toString();
|
||||
} else if (name == QLatin1String("title") && title.isEmpty()) {
|
||||
title = elementText(reader);
|
||||
}
|
||||
}
|
||||
|
||||
if (reader.hasError() && result.isEmpty()) {
|
||||
if (errorMessage)
|
||||
*errorMessage = reader.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (entries)
|
||||
*entries = result;
|
||||
if (nextUrl)
|
||||
*nextUrl = next;
|
||||
if (feedTitle)
|
||||
*feedTitle = title;
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user