From 0c1804db263a229cc9804af9e1d2b6e4655289c8 Mon Sep 17 00:00:00 2001 From: Flavio Tordini Date: Sun, 9 Aug 2015 10:20:54 +0200 Subject: [PATCH] Optimized aggregator --- src/channelaggregator.cpp | 60 ++++++++++++++++++++++++++++++++------- src/channelaggregator.h | 7 +++++ src/ytchannel.cpp | 11 +++++++ src/ytchannel.h | 2 ++ 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/src/channelaggregator.cpp b/src/channelaggregator.cpp index b660c38..97b369d 100644 --- a/src/channelaggregator.cpp +++ b/src/channelaggregator.cpp @@ -27,12 +27,18 @@ $END_LICENSE */ #ifdef APP_MAC #include "macutils.h" #endif +#include "networkaccess.h" + +namespace The { + NetworkAccess* http(); +} ChannelAggregator::ChannelAggregator(QObject *parent) : QObject(parent), unwatchedCount(-1), running(false), - stopped(false) { - checkInterval = 3600; + stopped(false), + currentChannel(0) { + checkInterval = 1800; timer = new QTimer(this); timer->setInterval(60000 * 5); @@ -88,22 +94,54 @@ void ChannelAggregator::processNextChannel() { running = false; return; } - qApp->processEvents(); YTChannel* channel = getChannelToCheck(); if (channel) { - SearchParams *params = new SearchParams(); - params->setChannelId(channel->getChannelId()); - params->setSortBy(SearchParams::SortByNewest); - params->setTransient(true); - params->setPublishedAfter(channel->getChecked()); - YTSearch *videoSource = new YTSearch(params, this); - connect(videoSource, SIGNAL(gotVideos(QList)), SLOT(videosLoaded(QList))); - videoSource->loadVideos(50, 1); + checkWebPage(channel); channel->updateChecked(); } else finish(); } +void ChannelAggregator::checkWebPage(YTChannel *channel) { + currentChannel = channel; + QString url = "https://www.youtube.com/channel/" + channel->getChannelId() + "/videos"; + QObject *reply = The::http()->get(url); + + connect(reply, SIGNAL(data(QByteArray)), SLOT(parseWebPage(QByteArray))); + connect(reply, SIGNAL(error(QNetworkReply*)), SLOT(errorWebPage(QNetworkReply*))); +} + +void ChannelAggregator::parseWebPage(const QByteArray &bytes) { + bool hasNewVideos = true; + QRegExp re = QRegExp("[\\?&]v=([0-9A-Za-z_-]+)"); + if (re.indexIn(bytes) != -1) { + QString videoId = re.cap(1); + QString latestVideoId = currentChannel->latestVideoId(); + // qDebug() << "Comparing" << videoId << latestVideoId; + hasNewVideos = videoId != latestVideoId; + } + if (hasNewVideos) reallyProcessChannel(currentChannel); + else processNextChannel(); +} + +void ChannelAggregator::errorWebPage(QNetworkReply *reply) { + Q_UNUSED(reply); + reallyProcessChannel(currentChannel); +} + +void ChannelAggregator::reallyProcessChannel(YTChannel *channel) { + SearchParams *params = new SearchParams(); + params->setChannelId(channel->getChannelId()); + params->setSortBy(SearchParams::SortByNewest); + params->setTransient(true); + params->setPublishedAfter(channel->getChecked()); + YTSearch *videoSource = new YTSearch(params, this); + connect(videoSource, SIGNAL(gotVideos(QList)), SLOT(videosLoaded(QList))); + videoSource->loadVideos(50, 1); +} + void ChannelAggregator::finish() { + currentChannel = 0; + /* foreach (YTChannel *channel, updatedChannels) if (channel->updateNotifyCount()) diff --git a/src/channelaggregator.h b/src/channelaggregator.h index 288ce82..bb92227 100644 --- a/src/channelaggregator.h +++ b/src/channelaggregator.h @@ -22,6 +22,7 @@ $END_LICENSE */ #define CHANNELAGGREGATOR_H #include +#include class YTChannel; class Video; @@ -50,6 +51,10 @@ signals: private slots: void videosLoaded(const QList &videos); void processNextChannel(); + void checkWebPage(YTChannel *channel); + void parseWebPage(const QByteArray &bytes); + void errorWebPage(QNetworkReply *reply); + void reallyProcessChannel(YTChannel *channel); private: ChannelAggregator(QObject *parent = 0); @@ -66,6 +71,8 @@ private: QTimer *timer; bool stopped; + + YTChannel *currentChannel; }; #endif // CHANNELAGGREGATOR_H diff --git a/src/ytchannel.cpp b/src/ytchannel.cpp index c2b33aa..bcebcfe 100644 --- a/src/ytchannel.cpp +++ b/src/ytchannel.cpp @@ -199,6 +199,17 @@ QString YTChannel::getThumbnailLocation() { return getThumbnailDir() + channelId; } +QString YTChannel::latestVideoId() { + QSqlDatabase db = Database::instance().getConnection(); + QSqlQuery query(db); + query.prepare("select video_id from subscriptions_videos where user_id=? order by published desc limit 1"); + query.bindValue(0, channelId); + bool success = query.exec(); + if (!success) qWarning() << query.lastQuery() << query.lastError().text(); + if (!query.next()) return QString(); + return query.value(0).toString(); +} + void YTChannel::unsubscribe() { YTChannel::unsubscribe(channelId); } diff --git a/src/ytchannel.h b/src/ytchannel.h index 25a9fca..fea95aa 100644 --- a/src/ytchannel.h +++ b/src/ytchannel.h @@ -62,6 +62,8 @@ public: QString getThumbnailLocation(); const QPixmap & getThumbnail() { return thumbnail; } + QString latestVideoId(); + static QList getCachedChannels() { return cache.values(); } public slots: -- 2.39.5