Merge branch 'dev'

This commit is contained in:
Martin Rotter 2016-08-25 12:44:54 +02:00
commit 99e53c3309
18 changed files with 176 additions and 93 deletions

46
.appveyor.yml Executable file
View File

@ -0,0 +1,46 @@
version: 666.{build}
skip_tags: true
image: Visual Studio 2013
clone_depth: 1
clone_folder: c:\rssguard
branches:
only:
- master
- dev
except:
- build-artifacts
environment:
QTDIR: 'C:\Qt\5.7\msvc2013'
QMAKESPEC: win32-msvc2013
COMPILERBAT: '"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86'
access_token:
secure: XCWdr9wPgK4gm6289WXCg2vtMA02eBSnj6eKHC+ps6Z5lgw0jsK09UQ5y9E9ZFwS
build_script:
- git submodule update --init --recursive
- set "QT_PLUGIN_PATH=%QTDIR%\plugins"
- set "PATH=%QTDIR%\bin;%PATH%"
- '%COMPILERBAT%'
- dir
- cd ..
- mkdir rssguard-build
- cd rssguard-build
- C:\Qt\5.7\msvc2013\bin\qmake.exe C:\rssguard
- nmake
- nmake windows_all
on_success:
- dir
- git clone -q --depth=1 --branch=build-artifacts https://github.com/martinrotter/rssguard.git c:\rssguard-artifacts
- git config --global credential.helper store
- ps: Add-Content "$env:USERPROFILE\.git-credentials" "https://$($env:access_token):x-oauth-basic@github.com`n"
- git config --global user.email "rotter.martinos@gmail.com"
- git config --global user.name "martinrotter"
- cd ..\rssguard-build
- for /f "tokens=*" %%F in ('dir /s /b *.7z') do curl --upload-file %%F https://transfer.sh/rssguard-win32.7z --silent >> ..\rssguard-artifacts\windows-builds.txt
- cd ..\rssguard-artifacts
- git add *.*
- git commit -m "New files."
- git push origin build-artifacts

View File

@ -1,10 +1,12 @@
dist: trusty
language: cpp
osx_image: xcode7.3
sudo: required
dist: trusty
os:
- linux
- osx
compiler:
- gcc
@ -12,15 +14,10 @@ git:
submodules: false
depth: 3
before_install:
- sudo add-apt-repository ppa:beineri/opt-qt57-trusty -y
- sudo apt-get update
- sudo apt-get -y install qt57tools qt57base qt57webengine
before_install: ./resources/scripts/.travis-before-install.sh
install: true
script:
- source /opt/qt57/bin/qt57-env.sh
- mkdir rssguard-build && cd rssguard-build
- qmake ..
- make
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./resources/scripts/.travis-install-linux.sh ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./resources/scripts/.travis-install-osx.sh ; fi

View File

@ -1,7 +1,8 @@
RSS Guard
=========
[![Build status](https://img.shields.io/travis/martinrotter/rssguard.svg?maxAge=360)](https://travis-ci.org/martinrotter/rssguard)
[![AppVeyor](https://img.shields.io/appveyor/ci/martinrotter/rssguard.svg?maxAge=360)](https://ci.appveyor.com/project/martinrotter/rssguard)
[![Travis CI](https://img.shields.io/travis/martinrotter/rssguard.svg?maxAge=360)](https://travis-ci.org/martinrotter/rssguard)
[![Total downloads](https://img.shields.io/github/downloads/martinrotter/rssguard/total.svg?maxAge=360)](#)
[![Version](https://img.shields.io/github/release/martinrotter/rssguard.svg?maxAge=360)](#)
[![GitHub issues](https://img.shields.io/github/issues/martinrotter/rssguard.svg?maxAge=360)](#)
@ -61,6 +62,7 @@ Downloads
* [official downloads](https://github.com/martinrotter/rssguard/releases),
* alternative downloads:
* [Archlinux AUR package](https://aur.archlinux.org/packages/rssguard/),
* [Automatically generated test builds](https://github.com/martinrotter/rssguard/tree/build-artifacts),
* [OBS/development releases](https://build.opensuse.org/package/show/home:skunkos:rssguard/rssguard-git) (click "Download package" in top/right corner of the website).
[![Alternative RSS Guard downloads.](http://www.instalki.pl/img/buttons/en/download_dark.png)](http://www.instalki.pl/programy/download/Windows/czytniki_RSS/RSS_Guard.html)
@ -73,7 +75,7 @@ Features
--------
RSS Guard is simple (yet powerful) feed reader. It is able to fetch the most known feed formats, including RSS/RDF and ATOM. RSS Guard is developed on top of the [Qt library](http://qt-project.org/) and it supports these operating systems:
* Windows XP and newer,
* Windows Vista and newer,
* GNU/Linux,
* Mac OS X,
* xBSD (possibly),

View File

@ -2176,10 +2176,6 @@ Přesto chcete soubor smazat?</translation>
<source>&lt;p&gt;Qt is a C++ toolkit for cross-platform application development.&lt;/p&gt;&lt;p&gt;Qt provides single-source portability across all major desktop operating systems. It is also available for embedded Linux and other embedded and mobile operating systems.&lt;/p&gt;&lt;p&gt;Qt is available under three different licensing options designed to accommodate the needs of our various users.&lt;/p&gt;&lt;p&gt;Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications provided you can comply with the terms and conditions of the GNU LGPL version 2.1.&lt;/p&gt;&lt;p&gt;Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;Please see &lt;a href=&quot;http://qt.io/licensing/&quot;&gt;qt.io/licensing&lt;/a&gt; for an overview of Qt licensing.&lt;/p&gt;&lt;p&gt;Copyright (C) 2015 The Qt Company Ltd and other contributors.&lt;/p&gt;&lt;p&gt;Qt and the Qt logo are trademarks of Digia Plc and/or its subsidiary(-ies).&lt;/p&gt;&lt;p&gt;Qt is developed as an open source project on &lt;a href=&quot;http://qt-project.org/&quot;&gt;qt-project.org&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Qt is a Digia product. See &lt;a href=&quot;http://qt.io/&quot;&gt;qt.io&lt;/a&gt; for more information.&lt;/p&gt;</source>
<translation>&lt;p&gt;Qt je sadou softwarových nástrojů C++ určených pro víceplatformní vývoj aplikací.&lt;/p&gt;&lt;p&gt;Qt poskytuje snadnou přenositelnost a jednotný zdrojový kód pro MS&amp;nbsp;Windows, Mac&amp;nbsp;OS&amp;nbsp;X, Linux a všechny hlavní prodejní varianty systému Unix. Qt je rovněž dostupné pro vestavěná zařízení jako Qt pro Embedded Linux a Qt pro Windows CE.&lt;/p&gt;&lt;p&gt;Qt je dostupné s třemi rozdílnými licencemi, aby vyhovělo širokým řadám našich uživatelů.&lt;/p&gt;Qt s naší obchodní licenční smlouvou je vhodné pro vývoj soukromého/obchodního software, u kterého si nepřejete sdílet jakýkoli zdrojový kód se třetími stranami anebo z jiného důvodu nemůžete vyhovět podmínkám GNU LGPL ve verzi 2.1 nebo GNU GPL ve verzi 3.0.&lt;/p&gt;&lt;p&gt;Qt s licencí GNU LGPL ve verzi 2.1 je vhodné pro vývoj Qt aplikací (soukromých nebo s otevřeným zdrojovým kódem) za předpokladu, že můžete souhlasit s požadavky a podmínkami GNU LGPL verze 2.1.&lt;/p&gt;&lt;p&gt;Qt s licencí GNU General Public License ve verzi 3.0 je vhodné pro vývoj aplikací Qt, u nichž si přejete použít takovou aplikaci ve spojení se software, který podléhá požadavkům GNU GPL ve verzi 3.0, nebo kde jste jinak ochotni souhlasit s podmínkami GNU GPL ve verzi 3.0.&lt;/p&gt;&lt;p&gt;Více informací najdete na &lt;a href=&quot;http://qt.io/licensing/&quot;&gt;qt.nokia.com/products/licensing&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Autorské právo (C) 2015 The Qt Company Ltd a/nebo její dceřinná(é) společnost(i) a další přispěvatelé.&lt;/p&gt;&lt;p&gt;Qt a logo Qt jsou obchodní značky Digia Plc a/nebo její dceřinná(é) společnost(i).&lt;/p&gt;&lt;p&gt;Qt je vyvíjeno jako projekt s otevřeným zdrojovým kódem na &lt;a href=&quot;http://qt-project.org/&quot;&gt;qt-project.org&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Qt je výrobkem společnosti Digia. Další informace najdete na &lt;a href=&quot;http://qt.io/&quot;&gt;qt.io&lt;/a&gt;. href=&quot;http://qt.io/&quot;&gt;qt.nokia.com&lt;/a&gt;.&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;Qt is a C++ toolkit for cross-platform application development.&lt;/p&gt;&lt;p&gt;Qt provides single-source portability across all major desktop operating systems. It is also available for embedded Linux and other embedded and mobile operating systems.&lt;/p&gt;&lt;p&gt;Qt is available under three different licensing options designed to accommodate the needs of our various users.&lt;/p&gt;&lt;p&gt;Qt licensed under our commercial license agreement is appropriate for development of proprietary/commercial software where you do not want to share any source code with third parties or otherwise cannot comply with the terms of the GNU LGPL version 2.1 or GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;Qt licensed under the GNU LGPL version 2.1 is appropriate for the development of Qt applications provided you can comply with the terms and conditions of the GNU LGPL version 2.1.&lt;/p&gt;&lt;p&gt;Qt licensed under the GNU General Public License version 3.0 is appropriate for the development of Qt applications where you wish to use such applications in combination with software subject to the terms of the GNU GPL version 3.0 or where you are otherwise willing to comply with the terms of the GNU GPL version 3.0.&lt;/p&gt;&lt;p&gt;Please see &lt;a href=&quot;http://qt.io/licensing/&quot;&gt;qt.io/licensing&lt;/a&gt; for an overview of Qt licensing.&lt;/p&gt;&lt;p&gt;Copyright (C) 2015 The Qt Company Ltd and other contributors.&lt;/p&gt;&lt;p&gt;Qt and the Qt logo are trademarks of Digia Plc and/or its subsidiary(-ies).&lt;/p&gt;&lt;p&gt;Qt is developed as an open source project on &lt;a href=&quot;http://qt-project.org/&quot;&gt;qt-project.org&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Qt is a Digia product. See &lt;a href=&quot;http://qt.io/&quot;&gt;qt.io&lt;/a&gt; for more information.&lt;/p&gt;</source>
<translation>&lt;p&gt;Qt je sadou softwarových nástrojů C++ určených pro víceplatformní vývoj aplikací.&lt;/p&gt;&lt;p&gt;Qt poskytuje snadnou přenositelnost a jednotný zdrojový kód pro MS&amp;nbsp;Windows, Mac&amp;nbsp;OS&amp;nbsp;X, Linux a všechny hlavní prodejní varianty systému Unix. Qt je rovněž dostupné pro vestavěná zařízení jako Qt pro Embedded Linux a Qt pro Windows CE.&lt;/p&gt;&lt;p&gt;Qt je dostupné s třemi rozdílnými licencemi, aby vyhovělo širokým řadám našich uživatelů.&lt;/p&gt;Qt s naší obchodní licenční smlouvou je vhodné pro vývoj soukromého/obchodního software, u kterého si nepřejete sdílet jakýkoli zdrojový kód se třetími stranami anebo z jiného důvodu nemůžete vyhovět podmínkám GNU LGPL ve verzi 2.1 nebo GNU GPL ve verzi 3.0.&lt;/p&gt;&lt;p&gt;Qt s licencí GNU LGPL ve verzi 2.1 je vhodné pro vývoj Qt aplikací (soukromých nebo s otevřeným zdrojovým kódem) za předpokladu, že můžete souhlasit s požadavky a podmínkami GNU LGPL verze 2.1.&lt;/p&gt;&lt;p&gt;Qt s licencí GNU General Public License ve verzi 3.0 je vhodné pro vývoj aplikací Qt, u nichž si přejete použít takovou aplikaci ve spojení se software, který podléhá požadavkům GNU GPL ve verzi 3.0, nebo kde jste jinak ochotni souhlasit s podmínkami GNU GPL ve verzi 3.0.&lt;/p&gt;&lt;p&gt;Více informací najdete na &lt;a href=&quot;http://qt.io/licensing/&quot;&gt;qt.nokia.com/products/licensing&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Autorské právo (C) 2015 The Qt Company Ltd a/nebo její dceřinná(é) společnost(i).&lt;/p&gt;&lt;p&gt;Qt je výrobkem společnosti Nokia. Další informace najdete na &lt;a href=&quot;http://qt.io/&quot;&gt;qt.nokia.com&lt;/a&gt;.&lt;/p&gt;</translation>
</message>
<message>
<source>About Qt</source>
<translation>O Qt</translation>

View File

@ -15,7 +15,7 @@
<key>CFBundleIconFile</key>
<string>@ICON@</string>
<key>CFBundleIdentifier</key>
<string>org.rssguard.RSSGuard</string>
<string>org.martinrotter.rssguard</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>

View File

@ -25,5 +25,5 @@
!define MUI_ICON "@PWD@\resources\graphics\@APP_LOW_NAME@.ico"
!define MUI_UNICON "@PWD@\resources\graphics\@APP_LOW_NAME@.ico"
!define PATCH "0"
!define OUTPUT_FILE "@OUT_PWD@\@APP_LOW_NAME@-@APP_VERSION@-win32.exe"
!define OUTPUT_FILE "@OUT_PWD@\@APP_LOW_NAME@-@APP_VERSION@-@APP_REVISION@-win32.exe"
!define BINARY_TREE "@OUT_PWD@\app"

View File

@ -0,0 +1,15 @@
#!/bin/sh
if test "$TRAVIS_OS_NAME" = "osx"; then
# Mac OS X.
brew update
brew install qt5
brew link --force qt5
brew install curl
brew link --force curl
else
# Linux.
sudo add-apt-repository ppa:beineri/opt-qt57-trusty -y
sudo apt-get update
sudo apt-get -y install qt57tools qt57base qt57webengine
fi

View File

@ -0,0 +1,7 @@
#!/bin/bash
source /opt/qt57/bin/qt57-env.sh
mkdir rssguard-build && cd rssguard-build
qmake ..
make
make install

View File

@ -0,0 +1,9 @@
#!/bin/sh
mkdir rssguard-build && cd rssguard-build
qmake ..
make
make install
macdeployqt rssguard.app -dmg
ls -lha
curl --upload-file ./*.dmg https://transfer.sh/rssguard.dmg

View File

@ -8,7 +8,9 @@ Changed:
▪ Big application core refactoring. Many functions rewritten, some bad code removed.
Fixed:
▪ RSS Guard could not stop ongoing feed updates. (bug #52)
▪ RSS Guard was not launchable in Windows XP. (bug #53)
▪ RSS Guard crashed when switching msg status during feed updates. (bug #41)
3.3.3
—————

View File

@ -135,7 +135,7 @@ exists(.git) {
}
isEmpty(APP_REVISION) {
APP_REVISION = "-"
APP_REVISION = ""
}
DEFINES += APP_REVISION='"\\\"$$APP_REVISION\\\""'
@ -537,11 +537,11 @@ QMAKE_EXTRA_COMPILERS += lrelease
win32 {
seven_zip.target = 7zip
seven_zip.depends = install
seven_zip.commands = $$shell_path($$shell_quote($$PWD/resources/scripts/7za/7za.exe)) a -t7z $$TARGET-$$APP_VERSION-win32.7z $$shell_path($$PREFIX/*)
seven_zip.commands = $$shell_path($$shell_quote($$PWD/resources/scripts/7za/7za.exe)) a -t7z $$TARGET-$$APP_VERSION-$$APP_REVISION-win32.7z $$shell_path($$PREFIX/*)
zip.target = zip
zip.depends = install
zip.commands = $$shell_path($$shell_quote($$PWD/resources/scripts/7za/7za.exe)) a -tzip $$TARGET-$$APP_VERSION-win32.zip $$shell_path($$PREFIX/*)
zip.commands = $$shell_path($$shell_quote($$PWD/resources/scripts/7za/7za.exe)) a -tzip $$TARGET-$$APP_VERSION-$$APP_REVISION-win32.zip $$shell_path($$PREFIX/*)
QMAKE_EXTRA_TARGETS += seven_zip zip
}
@ -551,7 +551,7 @@ win32 {
nsis.target = nsis
nsis.depends = install
nsis.commands = \
$$shell_path($$shell_quote($$PWD/resources/scripts/sed/sed.exe)) -e \"s|@APP_VERSION@|$$APP_VERSION|g; s|@APP_NAME@|$$APP_NAME|g; s|@APP_LOW_NAME@|$$APP_LOW_NAME|g; s|@EXE_NAME@|$${APP_LOW_NAME}.exe|g; s|@PWD@|$$replace(PWD, /, \\\\)|g; s|@OUT_PWD@|$$replace(OUT_PWD, /, \\\\)|g\" $$shell_path($$shell_quote($$PWD/resources/nsis/NSIS.definitions.nsh.in)) > $$shell_path($$shell_quote($$OUT_PWD/NSIS.definitions.nsh)) && \
$$shell_path($$shell_quote($$PWD/resources/scripts/sed/sed.exe)) -e \"s|@APP_VERSION@|$$APP_VERSION|g; s|@APP_REVISION@|$$APP_REVISION|g; s|@APP_NAME@|$$APP_NAME|g; s|@APP_LOW_NAME@|$$APP_LOW_NAME|g; s|@EXE_NAME@|$${APP_LOW_NAME}.exe|g; s|@PWD@|$$replace(PWD, /, \\\\)|g; s|@OUT_PWD@|$$replace(OUT_PWD, /, \\\\)|g\" $$shell_path($$shell_quote($$PWD/resources/nsis/NSIS.definitions.nsh.in)) > $$shell_path($$shell_quote($$OUT_PWD/NSIS.definitions.nsh)) && \
xcopy /Y $$shell_path($$shell_quote($$PWD/resources/nsis/NSIS.template.in)) $$shell_path($$shell_quote($$OUT_PWD/)) && \
$$shell_path($$shell_quote($$PWD/resources/scripts/nsis/makensis.exe)) $$shell_path($$shell_quote($$OUT_PWD/NSIS.template.in))

View File

@ -23,99 +23,103 @@
#include <QThread>
#include <QDebug>
#include <QThreadPool>
#include <QMutexLocker>
#include <QString>
FeedDownloader::FeedDownloader(QObject *parent)
: QObject(parent), m_results(FeedDownloadResults()), m_feedsUpdated(0), m_feedsToUpdate(0),
m_feedsUpdating(0), m_feedsTotalCount(0), m_stopUpdate(false) {
: QObject(parent), m_feeds(QList<Feed*>()), m_mutex(new QMutex()), m_threadPool(new QThreadPool(this)),
m_results(FeedDownloadResults()), m_feedsUpdated(0),
m_feedsUpdating(0), m_feedsOriginalCount(0) {
qRegisterMetaType<FeedDownloadResults>("FeedDownloadResults");
m_threadPool->setMaxThreadCount(FEED_DOWNLOADER_MAX_THREADS);
}
FeedDownloader::~FeedDownloader() {
m_mutex->tryLock();
m_mutex->unlock();
delete m_mutex;
qDebug("Destroying FeedDownloader instance.");
}
bool FeedDownloader::isUpdateRunning() const {
return m_feedsToUpdate > 0 || m_feedsUpdating > 0;
return !m_feeds.isEmpty() || m_feedsUpdating > 0;
}
void FeedDownloader::updateAvailableFeeds() {
while (!m_feeds.isEmpty()) {
connect(m_feeds.first(), &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished,
(Qt::ConnectionType) (Qt::UniqueConnection | Qt::AutoConnection));
if (m_threadPool->tryStart(m_feeds.first())) {
m_feeds.removeFirst();
m_feedsUpdating++;
}
else {
// We want to start update of some feeds but all working threads are occupied.
break;
}
}
}
void FeedDownloader::updateFeeds(const QList<Feed*> &feeds) {
QMutexLocker locker(m_mutex);
if (feeds.isEmpty()) {
qDebug("No feeds to update in worker thread, aborting update.");
finalizeUpdate();
return;
}
else {
qDebug().nospace() << "Starting feed updates from worker in thread: \'" << QThread::currentThreadId() << "\'.";
qDebug().nospace() << "Starting feed updates from worker in thread: \'" << QThread::currentThreadId() << "\'.";
m_feeds = feeds;
m_feedsOriginalCount = m_feeds.size();
m_results.clear();
m_feedsUpdated = m_feedsUpdating = 0;
// It may be good to disable "stop" action when batch feed update
// starts.
m_stopUpdate = false;
m_results.clear();
m_feedsUpdated = 0;
m_feedsUpdating = 0;
m_feedsToUpdate = feeds.size();
m_feedsTotalCount = m_feedsToUpdate;
// Job starts now.
emit updateStarted();
for (int i = 0; i < m_feedsTotalCount; i++) {
if (m_stopUpdate) {
qDebug("Stopping batch feed update now.");
// We want indicate that no more feeds will be updated in this queue.
m_feedsToUpdate = 0;
if (m_feedsUpdating <= 0) {
// User forced to stop, no more feeds will start updating.
// If also no feeds are updating right now, finish.
finalizeUpdate();
}
break;
}
connect(feeds.at(i), &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished,
(Qt::ConnectionType) (Qt::UniqueConnection | Qt::AutoConnection));
QThreadPool::globalInstance()->start(feeds.at(i));
m_feedsUpdating++;
m_feedsToUpdate--;
// Job starts now.
emit updateStarted();
updateAvailableFeeds();
}
}
void FeedDownloader::stopRunningUpdate() {
m_stopUpdate = true;
m_threadPool->clear();
m_feeds.clear();
}
void FeedDownloader::oneFeedUpdateFinished(const QList<Message> &messages) {
QMutexLocker locker(m_mutex);
m_feedsUpdated++;
m_feedsUpdating--;
Feed *feed = qobject_cast<Feed*>(sender());
disconnect(feed, &Feed::messagesObtained, this, &FeedDownloader::oneFeedUpdateFinished);
m_feedsUpdated++;
m_feedsUpdating--;
// Now, we check if there are any feeds we would like to update too.
updateAvailableFeeds();
// Now make sure, that messages are actually stored to SQL in a locked state.
qDebug().nospace() << "Saving messages of feed "
<< feed->id() << " in thread: \'"
<< QThread::currentThreadId() << "\'.";
if (!m_stopUpdate) {
int updated_messages = messages.isEmpty() ? 0 : feed->updateMessages(messages);
int updated_messages;
if (updated_messages > 0) {
m_results.appendUpdatedFeed(QPair<QString,int>(feed->title(), updated_messages));
}
QMetaObject::invokeMethod(feed, "updateMessages", Qt::BlockingQueuedConnection,
Q_RETURN_ARG(int, updated_messages),
Q_ARG(QList<Message>, messages));
if (updated_messages > 0) {
m_results.appendUpdatedFeed(QPair<QString,int>(feed->title(), updated_messages));
}
qDebug("Made progress in feed updates, total feeds count %d/%d (id of feed is %d).", m_feedsUpdated, m_feedsTotalCount, feed->id());
emit updateProgress(feed, m_feedsUpdated, m_feedsTotalCount);
qDebug("Made progress in feed updates, total feeds count %d/%d (id of feed is %d).", m_feedsUpdated, m_feedsOriginalCount, feed->id());
emit updateProgress(feed, m_feedsUpdated, m_feedsOriginalCount);
if (m_feedsToUpdate <= 0 && m_feedsUpdating <= 0) {
if (m_feeds.isEmpty() && m_feedsUpdating <= 0) {
finalizeUpdate();
}
}
@ -125,9 +129,6 @@ void FeedDownloader::finalizeUpdate() {
m_results.sort();
// Make sure that there is not "stop" action pending.
m_stopUpdate = false;
// Update of feeds has finished.
// NOTE: This means that now "update lock" can be unlocked
// and feeds can be added/edited/deleted and application

View File

@ -26,6 +26,8 @@
class Feed;
class QThreadPool;
class QMutex;
// Represents results of batch feed updates.
class FeedDownloadResults {
@ -86,16 +88,17 @@ class FeedDownloader : public QObject {
void updateProgress(const Feed *feed, int current, int total);
private:
void updateAvailableFeeds();
void finalizeUpdate();
QList<Feed*> m_feeds;
QMutex *m_mutex;
QThreadPool *m_threadPool;
FeedDownloadResults m_results;
int m_feedsUpdated;
int m_feedsToUpdate;
int m_feedsUpdating;
int m_feedsTotalCount;
bool m_stopUpdate;
int m_feedsOriginalCount;
};
#endif // FEEDDOWNLOADER_H

View File

@ -49,6 +49,7 @@
#define DOWNLOAD_TIMEOUT 5000
#define MESSAGES_VIEW_DEFAULT_COL 170
#define FEEDS_VIEW_COLUMN_COUNT 2
#define FEED_DOWNLOADER_MAX_THREADS 6
#define DEFAULT_DAYS_TO_DELETE_MSG 14
#define ELLIPSIS_LENGTH 3
#define MIN_CATEGORY_NAME_LENGTH 1

View File

@ -84,9 +84,7 @@ void FeedReader::updateFeeds(const QList<Feed*> &feeds) {
qRegisterMetaType<QList<Feed*> >("QList<Feed*>");
m_feedDownloader->moveToThread(m_feedDownloaderThread);
connect(this, &FeedReader::feedsUpdateRequested, m_feedDownloader, &FeedDownloader::updateFeeds);
connect(m_feedDownloaderThread, &QThread::finished, m_feedDownloaderThread, &QThread::deleteLater);
connect(m_feedDownloader, &FeedDownloader::updateFinished, this, &FeedReader::feedUpdatesFinished);
connect(m_feedDownloader, &FeedDownloader::updateProgress, this, &FeedReader::feedUpdatesProgress);
connect(m_feedDownloader, &FeedDownloader::updateStarted, this, &FeedReader::feedUpdatesStarted);
@ -96,7 +94,7 @@ void FeedReader::updateFeeds(const QList<Feed*> &feeds) {
m_feedDownloaderThread->start();
}
emit feedsUpdateRequested(feeds);
QMetaObject::invokeMethod(m_feedDownloader, "updateFeeds", Q_ARG(QList<Feed*>, feeds));
}
void FeedReader::updateAutoUpdateStatus() {
@ -126,7 +124,7 @@ void FeedReader::updateAllFeeds() {
void FeedReader::stopRunningFeedUpdate() {
if (m_feedDownloader != nullptr) {
m_feedDownloader->stopRunningUpdate();
QMetaObject::invokeMethod(m_feedDownloader, "stopRunningUpdate");
}
}
@ -209,6 +207,12 @@ void FeedReader::stop() {
if (m_feedDownloaderThread != nullptr && m_feedDownloaderThread->isRunning()) {
m_feedDownloader->stopRunningUpdate();
if (m_feedDownloader->isUpdateRunning()) {
QEventLoop loop(this);
connect(m_feedDownloader, &FeedDownloader::updateFinished, &loop, &QEventLoop::quit);
loop.exec();
}
qDebug("Quitting feed downloader thread.");
m_feedDownloaderThread->quit();

View File

@ -72,9 +72,6 @@ class FeedReader : public QObject {
void executeNextAutoUpdate();
signals:
// Emitted when model requests update of some feeds.
void feedsUpdateRequested(QList<Feed*> feeds);
void feedUpdatesStarted();
void feedUpdatesFinished(FeedDownloadResults updated_feeds);
void feedUpdatesProgress(const Feed *feed, int current, int total);

View File

@ -144,11 +144,13 @@ void Feed::run() {
<< QThread::currentThreadId() << "\'.";
QList<Message> msgs = obtainNewMessages();
emit messagesObtained(msgs);
}
int Feed::updateMessages(const QList<Message> &messages) {
qDebug().nospace() << "Updating messages in DB. Main thread: " <<
(QThread::currentThread() == qApp->thread() ? "true." : "false.");
int custom_id = customId();
int account_id = getParentServiceRoot()->accountId();
bool anything_updated = false;

View File

@ -78,12 +78,13 @@ class Feed : public RootItem, public QRunnable {
QString url() const;
void setUrl(const QString &url);
int updateMessages(const QList<Message> &messages);
void updateCounts(bool including_total_count);
// Runs update in thread (thread pooled).
void run();
public slots:
void updateCounts(bool including_total_count);
int updateMessages(const QList<Message> &messages);
private:
// Performs synchronous obtaining of new messages for this feed.
virtual QList<Message> obtainNewMessages() = 0;