mirror of https://github.com/KDE/kasts.git
Add support for additional itunes tags
Most of the itunes fields are used as backup for non-existent regular fields. One exception is the entry image, which only exists in itunes tags.
This commit is contained in:
parent
030bc07bb5
commit
0aa9e91f19
|
@ -47,7 +47,7 @@ bool Database::migrateTo1()
|
||||||
{
|
{
|
||||||
qDebug() << "Migrating database to version 1";
|
qDebug() << "Migrating database to version 1";
|
||||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Feeds (name TEXT, url TEXT, image TEXT, link TEXT, description TEXT, deleteAfterCount INTEGER, deleteAfterType INTEGER, subscribed INTEGER, lastUpdated INTEGER, notify BOOL);")));
|
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Feeds (name TEXT, url TEXT, image TEXT, link TEXT, description TEXT, deleteAfterCount INTEGER, deleteAfterType INTEGER, subscribed INTEGER, lastUpdated INTEGER, notify BOOL);")));
|
||||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Entries (feed TEXT, id TEXT UNIQUE, title TEXT, content TEXT, created INTEGER, updated INTEGER, link TEXT, read bool, hasEnclosure BOOL);")));
|
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Entries (feed TEXT, id TEXT UNIQUE, title TEXT, content TEXT, created INTEGER, updated INTEGER, link TEXT, read bool, hasEnclosure BOOL, image TEXT);")));
|
||||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Authors (feed TEXT, id TEXT, name TEXT, uri TEXT, email TEXT);")));
|
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Authors (feed TEXT, id TEXT, name TEXT, uri TEXT, email TEXT);")));
|
||||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Enclosures (feed TEXT, id TEXT, duration INTEGER, size INTEGER, title TEXT, type TEXT, url TEXT);"))); //, playposition INTEGER, filename TEXT);")));
|
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Enclosures (feed TEXT, id TEXT, duration INTEGER, size INTEGER, title TEXT, type TEXT, url TEXT);"))); //, playposition INTEGER, filename TEXT);")));
|
||||||
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Queue (listnr INTEGER, feed TEXT, id TEXT);")));
|
TRUE_OR_RETURN(execute(QStringLiteral("CREATE TABLE IF NOT EXISTS Queue (listnr INTEGER, feed TEXT, id TEXT);")));
|
||||||
|
|
|
@ -45,7 +45,7 @@ DataManager::DataManager()
|
||||||
Database::instance().execute(query);
|
Database::instance().execute(query);
|
||||||
while (query.next()) {
|
while (query.next()) {
|
||||||
m_entrymap[feedurl] += query.value(QStringLiteral("id")).toString();
|
m_entrymap[feedurl] += query.value(QStringLiteral("id")).toString();
|
||||||
qDebug() << m_entrymap[feedurl];
|
//qDebug() << m_entrymap[feedurl];
|
||||||
}
|
}
|
||||||
Q_EMIT feedEntriesUpdated(feedurl);
|
Q_EMIT feedEntriesUpdated(feedurl);
|
||||||
});
|
});
|
||||||
|
@ -58,7 +58,7 @@ DataManager::DataManager()
|
||||||
while (query.next()) {
|
while (query.next()) {
|
||||||
m_feedmap += query.value(QStringLiteral("url")).toString();
|
m_feedmap += query.value(QStringLiteral("url")).toString();
|
||||||
}
|
}
|
||||||
qDebug() << m_feedmap;
|
//qDebug() << m_feedmap;
|
||||||
|
|
||||||
for (auto &feedurl : m_feedmap) {
|
for (auto &feedurl : m_feedmap) {
|
||||||
query.prepare(QStringLiteral("SELECT id FROM Entries WHERE feed=:feed ORDER BY updated DESC;"));
|
query.prepare(QStringLiteral("SELECT id FROM Entries WHERE feed=:feed ORDER BY updated DESC;"));
|
||||||
|
@ -67,17 +67,17 @@ DataManager::DataManager()
|
||||||
while (query.next()) {
|
while (query.next()) {
|
||||||
m_entrymap[feedurl] += query.value(QStringLiteral("id")).toString();
|
m_entrymap[feedurl] += query.value(QStringLiteral("id")).toString();
|
||||||
m_entries[query.value(QStringLiteral("id")).toString()] = nullptr;
|
m_entries[query.value(QStringLiteral("id")).toString()] = nullptr;
|
||||||
qDebug() << m_entrymap[feedurl];
|
//qDebug() << m_entrymap[feedurl];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qDebug() << m_entrymap;
|
//qDebug() << m_entrymap;
|
||||||
|
|
||||||
query.prepare(QStringLiteral("SELECT id FROM Queue ORDER BY listnr;"));
|
query.prepare(QStringLiteral("SELECT id FROM Queue ORDER BY listnr;"));
|
||||||
Database::instance().execute(query);
|
Database::instance().execute(query);
|
||||||
while (query.next()) {
|
while (query.next()) {
|
||||||
m_queuemap += query.value(QStringLiteral("id")).toString();
|
m_queuemap += query.value(QStringLiteral("id")).toString();
|
||||||
}
|
}
|
||||||
qDebug() << m_queuemap;
|
//qDebug() << m_queuemap;
|
||||||
}
|
}
|
||||||
|
|
||||||
Feed* DataManager::getFeed(int const index) const
|
Feed* DataManager::getFeed(int const index) const
|
||||||
|
@ -247,7 +247,7 @@ void DataManager::addtoQueue(const QString &feedurl, const QString &id)
|
||||||
|
|
||||||
// Add to internal queuemap data structure
|
// Add to internal queuemap data structure
|
||||||
m_queuemap += id;
|
m_queuemap += id;
|
||||||
qDebug() << m_queuemap;
|
//qDebug() << m_queuemap;
|
||||||
|
|
||||||
// Get index of this entry
|
// Get index of this entry
|
||||||
const int index = m_queuemap.indexOf(id); // add new entry to end of queue
|
const int index = m_queuemap.indexOf(id); // add new entry to end of queue
|
||||||
|
@ -281,7 +281,7 @@ void DataManager::removeQueueItem(const int &index)
|
||||||
// First remove the item from the internal data structure
|
// First remove the item from the internal data structure
|
||||||
const QString id = m_queuemap[index];
|
const QString id = m_queuemap[index];
|
||||||
m_queuemap.removeAt(index);
|
m_queuemap.removeAt(index);
|
||||||
qDebug() << m_queuemap;
|
//qDebug() << m_queuemap;
|
||||||
|
|
||||||
// Then make sure that the database Queue table reflects these changes
|
// Then make sure that the database Queue table reflects these changes
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
|
|
|
@ -67,6 +67,9 @@ void Fetcher::processFeed(Syndication::FeedPtr feed, const QString &url)
|
||||||
if (feed.isNull())
|
if (feed.isNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Retrieve "other" fields; this will include the "itunes" tags
|
||||||
|
QMultiMap<QString, QDomElement> otherItems = feed->additionalProperties();
|
||||||
|
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare(QStringLiteral("UPDATE Feeds SET name=:name, image=:image, link=:link, description=:description, lastUpdated=:lastUpdated WHERE url=:url;"));
|
query.prepare(QStringLiteral("UPDATE Feeds SET name=:name, image=:image, link=:link, description=:description, lastUpdated=:lastUpdated WHERE url=:url;"));
|
||||||
query.bindValue(QStringLiteral(":name"), feed->title());
|
query.bindValue(QStringLiteral(":name"), feed->title());
|
||||||
|
@ -77,15 +80,40 @@ void Fetcher::processFeed(Syndication::FeedPtr feed, const QString &url)
|
||||||
QDateTime current = QDateTime::currentDateTime();
|
QDateTime current = QDateTime::currentDateTime();
|
||||||
query.bindValue(QStringLiteral(":lastUpdated"), current.toSecsSinceEpoch());
|
query.bindValue(QStringLiteral(":lastUpdated"), current.toSecsSinceEpoch());
|
||||||
|
|
||||||
for (auto &author : feed->authors()) {
|
// Process authors
|
||||||
processAuthor(author, QLatin1String(""), url);
|
QString authorname, authoremail;
|
||||||
|
if (feed->authors().count() > 0) {
|
||||||
|
for (auto &author : feed->authors()) {
|
||||||
|
processAuthor(url, QLatin1String(""), author->name(), QLatin1String(""), QLatin1String(""));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Try to find itunes fields if plain author doesn't exist
|
||||||
|
QString authorname, authoremail;
|
||||||
|
// First try the "itunes:owner" tag, if that doesn't succeed, then try the "itunes:author" tag
|
||||||
|
if (otherItems.value(QStringLiteral("http://www.itunes.com/dtds/podcast-1.0.dtdowner")).hasChildNodes()) {
|
||||||
|
QDomNodeList nodelist = otherItems.value(QStringLiteral("http://www.itunes.com/dtds/podcast-1.0.dtdowner")).childNodes();
|
||||||
|
for (int i=0; i < nodelist.length(); i++) {
|
||||||
|
if (nodelist.item(i).nodeName() == QStringLiteral("itunes:name")) {
|
||||||
|
authorname = nodelist.item(i).toElement().text();
|
||||||
|
} else if (nodelist.item(i).nodeName() == QStringLiteral("itunes:email")) {
|
||||||
|
authoremail = nodelist.item(i).toElement().text();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
authorname = otherItems.value(QStringLiteral("http://www.itunes.com/dtds/podcast-1.0.dtdauthor")).text();
|
||||||
|
qDebug() << "authorname" << authorname;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString image;
|
QString image = feed->image()->url();
|
||||||
if (feed->image()->url().startsWith(QStringLiteral("/")))
|
// If there is no regular image tag, then try the itunes tags
|
||||||
image = QUrl(url).adjusted(QUrl::RemovePath).toString() + feed->image()->url();
|
if (image.isEmpty()) {
|
||||||
else
|
if (otherItems.value(QStringLiteral("http://www.itunes.com/dtds/podcast-1.0.dtdimage")).hasAttribute(QStringLiteral("href"))) {
|
||||||
image = feed->image()->url();
|
image = otherItems.value(QStringLiteral("http://www.itunes.com/dtds/podcast-1.0.dtdimage")).attribute(QStringLiteral("href"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (image.startsWith(QStringLiteral("/")))
|
||||||
|
image = QUrl(url).adjusted(QUrl::RemovePath).toString() + image;
|
||||||
query.bindValue(QStringLiteral(":image"), image);
|
query.bindValue(QStringLiteral(":image"), image);
|
||||||
Database::instance().execute(query);
|
Database::instance().execute(query);
|
||||||
|
|
||||||
|
@ -103,6 +131,10 @@ void Fetcher::processFeed(Syndication::FeedPtr feed, const QString &url)
|
||||||
void Fetcher::processEntry(Syndication::ItemPtr entry, const QString &url)
|
void Fetcher::processEntry(Syndication::ItemPtr entry, const QString &url)
|
||||||
{
|
{
|
||||||
qDebug() << "Processing" << entry->title();
|
qDebug() << "Processing" << entry->title();
|
||||||
|
|
||||||
|
// Retrieve "other" fields; this will include the "itunes" tags
|
||||||
|
QMultiMap<QString, QDomElement> otherItems = entry->additionalProperties();
|
||||||
|
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare(QStringLiteral("SELECT COUNT (id) FROM Entries WHERE id=:id;"));
|
query.prepare(QStringLiteral("SELECT COUNT (id) FROM Entries WHERE id=:id;"));
|
||||||
query.bindValue(QStringLiteral(":id"), entry->id());
|
query.bindValue(QStringLiteral(":id"), entry->id());
|
||||||
|
@ -112,7 +144,7 @@ void Fetcher::processEntry(Syndication::ItemPtr entry, const QString &url)
|
||||||
if (query.value(0).toInt() != 0)
|
if (query.value(0).toInt() != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
query.prepare(QStringLiteral("INSERT INTO Entries VALUES (:feed, :id, :title, :content, :created, :updated, :link, 0, :hasEnclosure);"));
|
query.prepare(QStringLiteral("INSERT INTO Entries VALUES (:feed, :id, :title, :content, :created, :updated, :link, 0, :hasEnclosure, :image);"));
|
||||||
query.bindValue(QStringLiteral(":feed"), url);
|
query.bindValue(QStringLiteral(":feed"), url);
|
||||||
query.bindValue(QStringLiteral(":id"), entry->id());
|
query.bindValue(QStringLiteral(":id"), entry->id());
|
||||||
query.bindValue(QStringLiteral(":title"), QTextDocumentFragment::fromHtml(entry->title()).toPlainText());
|
query.bindValue(QStringLiteral(":title"), QTextDocumentFragment::fromHtml(entry->title()).toPlainText());
|
||||||
|
@ -126,29 +158,44 @@ void Fetcher::processEntry(Syndication::ItemPtr entry, const QString &url)
|
||||||
else
|
else
|
||||||
query.bindValue(QStringLiteral(":content"), entry->description());
|
query.bindValue(QStringLiteral(":content"), entry->description());
|
||||||
|
|
||||||
|
// Look for image in itunes tags
|
||||||
|
QString image;
|
||||||
|
if (otherItems.value(QStringLiteral("http://www.itunes.com/dtds/podcast-1.0.dtdimage")).hasAttribute(QStringLiteral("href"))) {
|
||||||
|
image = otherItems.value(QStringLiteral("http://www.itunes.com/dtds/podcast-1.0.dtdimage")).attribute(QStringLiteral("href"));
|
||||||
|
}
|
||||||
|
if (image.startsWith(QStringLiteral("/")))
|
||||||
|
image = QUrl(url).adjusted(QUrl::RemovePath).toString() + image;
|
||||||
|
query.bindValue(QStringLiteral(":image"), image);
|
||||||
|
//qDebug() << "Entry image found" << image;
|
||||||
|
|
||||||
Database::instance().execute(query);
|
Database::instance().execute(query);
|
||||||
|
|
||||||
for (const auto &author : entry->authors()) {
|
if (entry->authors().count() > 0) {
|
||||||
processAuthor(author, entry->id(), url);
|
for (const auto &author : entry->authors()) {
|
||||||
|
processAuthor(url, entry->id(), author->name(), author->uri(), author->email());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// As fallback, check if there is itunes "author" information
|
||||||
|
QString authorName = otherItems.value(QStringLiteral("http://www.itunes.com/dtds/podcast-1.0.dtdauthor")).text();
|
||||||
|
if (!authorName.isEmpty()) processAuthor(url, entry->id(), authorName, QLatin1String(""), QLatin1String(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &enclosure : entry->enclosures()) {
|
for (const auto &enclosure : entry->enclosures()) {
|
||||||
processEnclosure(enclosure, entry, url);
|
processEnclosure(enclosure, entry, url);
|
||||||
}
|
}
|
||||||
QMultiMap<QString, QDomElement> otherItems = entry->additionalProperties();
|
|
||||||
qDebug() << "other items" << otherItems.value(QStringLiteral("http://www.itunes.com/dtds/podcast-1.0.dtdimage")).attribute(QStringLiteral("href"));
|
|
||||||
Q_EMIT entryAdded(url, entry->id());
|
Q_EMIT entryAdded(url, entry->id());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Fetcher::processAuthor(Syndication::PersonPtr author, const QString &entryId, const QString &url)
|
void Fetcher::processAuthor(const QString &url, const QString &entryId, const QString &authorName, const QString &authorUri, const QString &authorEmail)
|
||||||
{
|
{
|
||||||
QSqlQuery query;
|
QSqlQuery query;
|
||||||
query.prepare(QStringLiteral("INSERT INTO Authors VALUES(:feed, :id, :name, :uri, :email);"));
|
query.prepare(QStringLiteral("INSERT INTO Authors VALUES(:feed, :id, :name, :uri, :email);"));
|
||||||
query.bindValue(QStringLiteral(":feed"), url);
|
query.bindValue(QStringLiteral(":feed"), url);
|
||||||
query.bindValue(QStringLiteral(":id"), entryId);
|
query.bindValue(QStringLiteral(":id"), entryId);
|
||||||
query.bindValue(QStringLiteral(":name"), author->name());
|
query.bindValue(QStringLiteral(":name"), authorName);
|
||||||
query.bindValue(QStringLiteral(":uri"), author->uri());
|
query.bindValue(QStringLiteral(":uri"), authorUri);
|
||||||
query.bindValue(QStringLiteral(":email"), author->email());
|
query.bindValue(QStringLiteral(":email"), authorEmail);
|
||||||
Database::instance().execute(query);
|
Database::instance().execute(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ private:
|
||||||
|
|
||||||
void processFeed(Syndication::FeedPtr feed, const QString &url);
|
void processFeed(Syndication::FeedPtr feed, const QString &url);
|
||||||
void processEntry(Syndication::ItemPtr entry, const QString &url);
|
void processEntry(Syndication::ItemPtr entry, const QString &url);
|
||||||
void processAuthor(Syndication::PersonPtr author, const QString &entryId, const QString &url);
|
void processAuthor(const QString &url, const QString &entryId, const QString &authorName, const QString &authorUri, const QString &authorEmail);
|
||||||
void processEnclosure(Syndication::EnclosurePtr enclosure, Syndication::ItemPtr entry, const QString &feedUrl);
|
void processEnclosure(Syndication::EnclosurePtr enclosure, Syndication::ItemPtr entry, const QString &feedUrl);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue