[Sync] Handle multiple entries having the same enclosure url

This commit is contained in:
Bart De Vries 2022-06-12 23:42:00 +02:00
parent 8123bd831b
commit 3383b6dfad
2 changed files with 27 additions and 44 deletions

View File

@ -67,51 +67,31 @@ void EpisodeActionRequest::processResults()
QDateTime::fromString(actionTimestamp.section(QStringLiteral("."), 0, 0), QStringLiteral("yyyy-MM-dd'T'hh:mm:ss")).toMSecsSinceEpoch() QDateTime::fromString(actionTimestamp.section(QStringLiteral("."), 0, 0), QStringLiteral("yyyy-MM-dd'T'hh:mm:ss")).toMSecsSinceEpoch()
/ 1000); / 1000);
// Finally we try to find the id for the entry based on the episode URL if // Now we try to find the id for the entry based on either the GUID
// no GUID is available. // or the episode download URL. We also try to match with a percent-
// decoded version of the URL.
// There can be several hits (e.g. different entries pointing to the
// same download URL; we add all of them to make sure everything's
// consistent.
// We also retrieve the feedUrl from the database to avoid problems with // We also retrieve the feedUrl from the database to avoid problems with
// different URLs pointing to the same feed (e.g. http vs https) // different URLs pointing to the same feed (e.g. http vs https)
if (!episodeAction.id.isEmpty()) { QSqlQuery query;
// First check if the GUID we got from the service is in the DB query.prepare(QStringLiteral("SELECT id, feed, url FROM Enclosures WHERE url=:url OR url=:decodeurl OR id=:id;"));
QSqlQuery query; query.bindValue(QStringLiteral(":url"), episodeAction.url);
query.prepare(QStringLiteral("SELECT id, feed FROM Entries WHERE id=:id;")); query.bindValue(QStringLiteral(":decodeurl"), cleanupUrl(episodeAction.url));
query.bindValue(QStringLiteral(":id"), episodeAction.id); query.bindValue(QStringLiteral(":id"), episodeAction.id);
Database::instance().execute(query); Database::instance().execute(query);
if (!query.next()) { if (!query.next()) {
qCDebug(kastsSync) << "cannot find episode with id:" << episodeAction.id; qCDebug(kastsSync) << "cannot find episode with url:" << episodeAction.url;
episodeAction.id.clear(); continue;
} else {
episodeAction.podcast = query.value(QStringLiteral("feed")).toString();
}
} }
do {
if (episodeAction.id.isEmpty()) { SyncUtils::EpisodeAction action = episodeAction;
// There either was no GUID specified or we couldn't find it in the DB action.id = query.value(QStringLiteral("id")).toString();
// Try to find the episode based on the enclosure URL action.podcast = query.value(QStringLiteral("feed")).toString();
QSqlQuery query; action.url = query.value(QStringLiteral("url")).toString();
query.prepare(QStringLiteral("SELECT id, feed FROM Enclosures WHERE url=:url;")); m_episodeActions += action;
query.bindValue(QStringLiteral(":url"), episodeAction.url); } while (query.next());
Database::instance().execute(query);
if (query.next()) {
episodeAction.id = query.value(QStringLiteral("id")).toString();
episodeAction.podcast = query.value(QStringLiteral("feed")).toString();
} else {
// try again with percent DEcoded URL
QSqlQuery query;
query.prepare(QStringLiteral("SELECT id, feed FROM Enclosures WHERE url=:url;"));
query.bindValue(QStringLiteral(":url"), cleanupUrl(episodeAction.url));
Database::instance().execute(query);
if (query.next()) {
episodeAction.url = cleanupUrl(episodeAction.url);
episodeAction.id = query.value(QStringLiteral("id")).toString();
episodeAction.podcast = query.value(QStringLiteral("feed")).toString();
} else {
qCDebug(kastsSync) << "cannot find episode with url:" << episodeAction.url;
continue;
}
}
}
m_episodeActions += episodeAction;
} }
m_timestamp = data.object().value(QStringLiteral("timestamp")).toInt(); m_timestamp = data.object().value(QStringLiteral("timestamp")).toInt();
} }

View File

@ -930,7 +930,8 @@ void Sync::storePlayEpisodeAction(const QString &id, const qulonglong started, c
if (entry && entry->hasEnclosure()) { if (entry && entry->hasEnclosure()) {
const qulonglong started_sec = started / 1000; // convert to seconds const qulonglong started_sec = started / 1000; // convert to seconds
const qulonglong position_sec = position / 1000; // convert to seconds const qulonglong position_sec = position / 1000; // convert to seconds
const qulonglong total = entry->enclosure()->duration(); // is already in seconds const qulonglong total =
(entry->enclosure()->duration() > 0) ? entry->enclosure()->duration() : 1; // crazy workaround for episodes with bad metadata
QSqlQuery query; QSqlQuery query;
query.prepare(QStringLiteral("INSERT INTO EpisodeActions VALUES (:podcast, :url, :id, :action, :started, :position, :total, :timestamp);")); query.prepare(QStringLiteral("INSERT INTO EpisodeActions VALUES (:podcast, :url, :id, :action, :started, :position, :total, :timestamp);"));
@ -953,7 +954,9 @@ void Sync::storePlayedEpisodeAction(const QString &id)
{ {
if (syncEnabled() && m_allowSyncActionLogging) { if (syncEnabled() && m_allowSyncActionLogging) {
if (DataManager::instance().getEntry(id)->hasEnclosure()) { if (DataManager::instance().getEntry(id)->hasEnclosure()) {
const qulonglong duration = DataManager::instance().getEntry(id)->enclosure()->duration(); Entry *entry = DataManager::instance().getEntry(id);
const qulonglong duration =
(entry->enclosure()->duration() > 0) ? entry->enclosure()->duration() : 1; // crazy workaround for episodes with bad metadata
storePlayEpisodeAction(id, duration * 1000, duration * 1000); storePlayEpisodeAction(id, duration * 1000, duration * 1000);
} }
} }