diff --git a/localization/rssguard_pt_BR.ts b/localization/rssguard_pt_BR.ts index c64afa5c6..e62ba3c87 100755 --- a/localization/rssguard_pt_BR.ts +++ b/localization/rssguard_pt_BR.ts @@ -135,7 +135,7 @@ Erro: %1 New articles fetched - + Novos artigos buscados @@ -216,27 +216,27 @@ Erro: %1 Removing read articles... - + Removendo artigos lidos... Read articles purged... - + Artigos lidos removidos... Removing old articles... - + Removendo artigos antigos... Old articles purged... - + Artigos antigos removidos... Removing starred articles... - + Removendo artigos com estrela... Starred articles purged... - + Artigos com estrela removidos... @@ -449,25 +449,25 @@ Status: %3 does not use auto-fetching of articles Describes feed auto-update status. - + não usa a busca automática de artigos uses global settings (%n minute(s) to next auto-fetch of articles) Describes feed auto-update status. - + usa configurações globais (%n minuto(s) para próxima busca automática de artigos)usa configurações globais (%n minuto(s) para próxima busca automática de artigos) uses global settings (global auto-fetching of articles is disabled) - + usa configurações globais (busca automática de artigos global desativada) uses specific settings (%n minute(s) to next auto-fetching of new articles) Describes feed auto-update status. - + usa configurações específicas (%n minuto(s) para próxima busca automática de artigos)usa configurações específicas (%n minuto(s) para próxima busca automática de artigos) has new articles - + possui novos artigos @@ -478,26 +478,26 @@ Status: %3 Toolbar for articles - + Barra de ferramentas para artigos FeedReader Cannot fetch articles for all items - + Não foi possível buscar artigos para todos os itens You cannot fetch new articles for your items because another critical operation is ongoing. - + Você não pode buscar novos artigos para seus itens pois outra operação crítica está em andamento. Starting auto-download of some feeds' articles - + Iniciando download automático de alguns artigos de feeds I will auto-download new articles for %n feed(s). - + Farei o download automático de novos artigos para%n feed(s).Farei o download automático de novos artigos para%n feed(s). @@ -600,7 +600,7 @@ Status: %3 Beware of downloading too many articles, because Feedly permanently caches ALL articles of the feed forever so you might end up with thousands of articles which you will never read anyway. - + Cuidado para não baixar muitos artigos, porque o Feedly armazena em cache permanentemente TODOS os artigos do feed para sempre, então você pode acabar com milhares de artigos que nunca irá ler de qualquer maneira. @@ -757,7 +757,7 @@ ou esta função ainda não foi implementada. Context menu for important articles - + Menu de contexto para artigos importantes @@ -1119,7 +1119,7 @@ ou esta função ainda não foi implementada. Edit "%1" - + Editar "%1" @@ -1134,7 +1134,7 @@ ou esta função ainda não foi implementada. day(s) - dia(s)dia(s) + dia(s) dia(s) Shrink database file @@ -1270,19 +1270,19 @@ ou esta função ainda não foi implementada. Edit "%1" - + Editar "%1" Fetch articles using global interval - + Buscar artigos usando intervalo global Fetch articles every - + Buscar artigos a cada Disable auto-fetching of articles - + Desativar busca automática de artigos @@ -1726,19 +1726,19 @@ ou esta função ainda não foi implementada. F&eeds - + F&eeds Art&icles - + Art&igos &Web browser && tabs - + Navegador &web && abas Ta&bs - + A&bas @@ -1885,22 +1885,25 @@ ou esta função ainda não foi implementada. Filter articles like this - + Filtrar artigos como este New article filter - + Novo filtro de artigos EXISTING articles filtering error: '%1'. - + Erro ao filtrar artigos EXISTENTES: "%1". + Article will be %1. - + O artigo será %1. + + Output (modified) article is: @@ -1911,12 +1914,20 @@ ou esta função ainda não foi implementada. Created on = '%6' Contents = '%7' RAW contents = '%8' - + O artigo de saída (modificado) é: + Título = '%1' + URL = '%2' + Autor = '%3' + Foi lido/é importante = '%4/%5' + Criado em = '%6' + Conteúdo = '%7' + Conteúdo RAW = '%8' SAMPLE article filtering error: '%1'. - + Erro ao filtrar artigos de AMOSTRA: "%1". + @@ -2543,7 +2554,7 @@ Expiração dos tokens de login: %2 Yeah. - Legal + Legal. Username cannot be empty. @@ -2579,7 +2590,7 @@ Expiração dos tokens de login: %2 Limiting the number of fetched articles per feed makes fetching of articles faster, but if your feed contains more articles than specified limit, then some older articles might not be fetched at all. - + Limitar o número de artigos buscados por feed forna a busca de artigos mais rápida, mas se seu feed contém mais artigos que o limite especificado, então alguns artigos mais antigos podem não ser buscados. @@ -2864,26 +2875,26 @@ Expiração dos tokens de login: %2 article - + artigo articles - + artigos MessagePreviewer Mark article read - + Marcar artigo como lido Mark article unread - + Marcar artigo como não lido Switch article importance - + Alterar importância do artigo @@ -3008,79 +3019,79 @@ Expiração dos tokens de login: %2 Loading of articles from item '%1' failed. - + Falha ao carregar artigos do item '%1'. Loading of articles failed, maybe messages could not be downloaded. - + Falha ao carregar artigos, talvez as mensagens não puderam ser baixadas. ID of the article. - + ID do artigo. Is article read? - + O artigo foi lido? Is article important? - + O artigo é importante? Is article deleted? - + O artigo foi excluído? Is article permanently deleted from recycle bin? - + O artigo foi permanentemente excluído da Lixeira? ID of feed which this article belongs to. - + ID do feed ao qual este artigo pertence. Title of the article. - + Título do artigo. Url of the article. - + URL do artigo. Author of the article. - + Autor do artigo. Creation date of the article. - + Data de criação do artigo. Contents of the article. - + Conteúdo do artigo. Score of the article. - + Nota do artigo. Account ID of the article. - + ID da conta do artigo. Custom ID of the article - + ID personalizado do artigo Custom hash of the article. - + Hash personalizado do artigo. Custom ID of feed of the article. - + ID personalizado do feed do artigo. Indication of enclosures presence within the article. - + Indicação da presença de anexos dentro do artigo. @@ -3095,31 +3106,31 @@ Expiração dos tokens de login: %2 Search articles - + Pesquisar artigos Article search box - + Caixa de pesquisa de artigos Menu for highlighting articles - + Menu para destacar artigos Highlight unread articles - + Destacar artigos não lidos Highlight important articles - + Destacar artigos importantes Display all articles - + Exibir todos os artigos Article highlighter - + Destacador de artigos @@ -3150,7 +3161,7 @@ Expiração dos tokens de login: %2 Context menu for articles - + Menu de contexto para artigos @@ -3306,15 +3317,15 @@ Expiração dos tokens de login: %2 Show more articles (%n remaining) - + Exibir mais artigos (%n restante(s))Exibir mais artigos (%n restante(s)) Cannot show more articles - + Não é possível mostrar mais artigos Cannot show more articles because parent feed was removed. - + Não é possível mostrar mais artigos pois o feed principal foi removido. @@ -3464,7 +3475,7 @@ Expiração dos tokens de login: %2 articles - + artigos @@ -3565,31 +3576,31 @@ O Feedly é um espaço seguro onde você pode organizar e pesquisar com privacid Cannot insert article filter, because current database cannot return last inserted row ID. - + Não é possível inserir o filtro do artigo, pois o banco de dados atual não pode retornar o último ID de linha inserido. New articles fetched - + Novos artigos buscados Fetching articles right now - + Buscando artigos agora mesmo Login data refreshed - + Dados de login atualizados New %1 version is available - + Nova versão %1 disponível Miscellaneous events - + Eventos diversos Unknown event - + Evento desconhecido @@ -3608,11 +3619,11 @@ O Feedly é um espaço seguro onde você pode organizar e pesquisar com privacid Recycle bin contains all deleted articles from all feeds. - + A Lixeira contém todos os artigos excluídos de todos os feeds. %n deleted article(s). - + %n artigo(s) excluído(s).%n artigo(s) excluído(s). @@ -3620,7 +3631,7 @@ O Feedly é um espaço seguro onde você pode organizar e pesquisar com privacid %n unread article(s). Tooltip for "unread" column of feed list. - + %n artigo(s) não lido(s).%n artigo(s) não lido(s). @@ -3673,7 +3684,7 @@ O Feedly é um espaço seguro onde você pode organizar e pesquisar com privacid Synchronize article cache - + Sincronizar cache dos artigos @@ -4275,11 +4286,11 @@ Os autores deste aplicativo NÃO são responsáveis pela perda de dados. Tray area - + Área de notificação Toolbar for articles list - + Barra de ferramentas para lista de artigos @@ -4317,7 +4328,7 @@ Os autores deste aplicativo NÃO são responsáveis pela perda de dados. You must have "tray icon" activated to have balloon notifications working. - + Você precisa ter o "ícone da área de notificação" ativado para que as janelas de notificação funcionem. @@ -4346,15 +4357,15 @@ Os autores deste aplicativo NÃO são responsáveis pela perda de dados.SingleNotificationEditor Sound - + Som Full path to your WAV sound file - + Caminho completo para arquivo de som WAV &Clear - + &Limpar &Browse @@ -4362,19 +4373,19 @@ Os autores deste aplicativo NÃO são responsáveis pela perda de dados. &Play - + &Tocar Balloon notification - + Balão de notificação Select sound file - + Selecionar arquivo de som WAV files (*.wav) - + Arquivos WAV (*.wav) @@ -4832,7 +4843,7 @@ Notícias não lidas: %2 Browse your feeds and articles - + Procurar seus feeds e artigos diff --git a/resources/desktop/com.github.rssguard.appdata.xml b/resources/desktop/com.github.rssguard.appdata.xml index 6dc193f27..c390f987d 100644 --- a/resources/desktop/com.github.rssguard.appdata.xml +++ b/resources/desktop/com.github.rssguard.appdata.xml @@ -30,7 +30,7 @@ https://martinrotter.github.io/donate/ - + none diff --git a/src/librssguard/core/feeddownloader.cpp b/src/librssguard/core/feeddownloader.cpp index 932a3ad89..563f7a2f6 100644 --- a/src/librssguard/core/feeddownloader.cpp +++ b/src/librssguard/core/feeddownloader.cpp @@ -6,6 +6,7 @@ #include "core/feedsmodel.h" #include "core/messagefilter.h" #include "definitions/definitions.h" +#include "exceptions/feedfetchexception.h" #include "exceptions/filteringexception.h" #include "miscellaneous/application.h" #include "services/abstract/cacheforserviceroot.h" @@ -117,192 +118,209 @@ void FeedDownloader::updateOneFeed(Feed* feed) { << feed->customId() << "' URL: '" << feed->source() << "' title: '" << feed->title() << "' in thread: '" << QThread::currentThreadId() << "'."; - bool error_during_obtaining = false; int acc_id = feed->getParentServiceRoot()->accountId(); QElapsedTimer tmr; tmr.start(); - QList msgs = feed->getParentServiceRoot()->obtainNewMessages({ feed }, &error_during_obtaining); - qDebugNN << LOGSEC_FEEDDOWNLOADER << "Downloaded " << msgs.size() << " messages for feed ID '" - << feed->customId() << "' URL: '" << feed->source() << "' title: '" << feed->title() << "' in thread: '" - << QThread::currentThreadId() << "'. Operation took " << tmr.nsecsElapsed() / 1000 << " microseconds."; + try { + QList msgs = feed->getParentServiceRoot()->obtainNewMessages({ feed }); - // Now, sanitize messages (tweak encoding etc.). - for (auto& msg : msgs) { - msg.m_accountId = acc_id; - msg.sanitize(); - } + qDebugNN << LOGSEC_FEEDDOWNLOADER << "Downloaded " << msgs.size() << " messages for feed ID '" + << feed->customId() << "' URL: '" << feed->source() << "' title: '" << feed->title() << "' in thread: '" + << QThread::currentThreadId() << "'. Operation took " << tmr.nsecsElapsed() / 1000 << " microseconds."; - if (!feed->messageFilters().isEmpty()) { - tmr.restart(); + // Now, sanitize messages (tweak encoding etc.). + for (auto& msg : msgs) { + msg.m_accountId = acc_id; + msg.sanitize(); + } - bool is_main_thread = QThread::currentThread() == qApp->thread(); - QSqlDatabase database = is_main_thread ? - qApp->database()->driver()->connection(metaObject()->className()) : - qApp->database()->driver()->connection(QSL("feed_upd")); - - // Perform per-message filtering. - QJSEngine filter_engine; - - // Create JavaScript communication wrapper for the message. - MessageObject msg_obj(&database, - feed->customId(), - feed->getParentServiceRoot()->accountId(), - feed->getParentServiceRoot()->labelsNode()->labels()); - - MessageFilter::initializeFilteringEngine(filter_engine, &msg_obj); - - qDebugNN << LOGSEC_FEEDDOWNLOADER << "Setting up JS evaluation took " << tmr.nsecsElapsed() / 1000 << " microseconds."; - - QList read_msgs, important_msgs; - - for (int i = 0; i < msgs.size(); i++) { - Message msg_backup(msgs[i]); - Message* msg_orig = &msgs[i]; - - // Attach live message object to wrapper. + if (!feed->messageFilters().isEmpty()) { tmr.restart(); - msg_obj.setMessage(msg_orig); - qDebugNN << LOGSEC_FEEDDOWNLOADER << "Hooking message took " << tmr.nsecsElapsed() / 1000 << " microseconds."; - auto feed_filters = feed->messageFilters(); - bool remove_msg = false; + bool is_main_thread = QThread::currentThread() == qApp->thread(); + QSqlDatabase database = is_main_thread ? + qApp->database()->driver()->connection(metaObject()->className()) : + qApp->database()->driver()->connection(QSL("feed_upd")); - for (int j = 0; j < feed_filters.size(); j++) { - QPointer filter = feed_filters.at(j); + // Perform per-message filtering. + QJSEngine filter_engine; - if (filter.isNull()) { - qCriticalNN << LOGSEC_FEEDDOWNLOADER - << "Message filter was probably deleted, removing its pointer from list of filters."; - feed_filters.removeAt(j--); - continue; + // Create JavaScript communication wrapper for the message. + MessageObject msg_obj(&database, + feed->customId(), + feed->getParentServiceRoot()->accountId(), + feed->getParentServiceRoot()->labelsNode()->labels()); + + MessageFilter::initializeFilteringEngine(filter_engine, &msg_obj); + + qDebugNN << LOGSEC_FEEDDOWNLOADER << "Setting up JS evaluation took " << tmr.nsecsElapsed() / 1000 << " microseconds."; + + QList read_msgs, important_msgs; + + for (int i = 0; i < msgs.size(); i++) { + Message msg_backup(msgs[i]); + Message* msg_orig = &msgs[i]; + + // Attach live message object to wrapper. + tmr.restart(); + msg_obj.setMessage(msg_orig); + qDebugNN << LOGSEC_FEEDDOWNLOADER << "Hooking message took " << tmr.nsecsElapsed() / 1000 << " microseconds."; + + auto feed_filters = feed->messageFilters(); + bool remove_msg = false; + + for (int j = 0; j < feed_filters.size(); j++) { + QPointer filter = feed_filters.at(j); + + if (filter.isNull()) { + qCriticalNN << LOGSEC_FEEDDOWNLOADER + << "Message filter was probably deleted, removing its pointer from list of filters."; + feed_filters.removeAt(j--); + continue; + } + + MessageFilter* msg_filter = filter.data(); + + tmr.restart(); + + try { + MessageObject::FilteringAction decision = msg_filter->filterMessage(&filter_engine); + + qDebugNN << LOGSEC_FEEDDOWNLOADER + << "Running filter script, it took " << tmr.nsecsElapsed() / 1000 << " microseconds."; + + switch (decision) { + case MessageObject::FilteringAction::Accept: + // Message is normally accepted, it could be tweaked by the filter. + continue; + + case MessageObject::FilteringAction::Ignore: + case MessageObject::FilteringAction::Purge: + default: + // Remove the message, we do not want it. + remove_msg = true; + break; + } + } + catch (const FilteringException& ex) { + qCriticalNN << LOGSEC_FEEDDOWNLOADER + << "Error when evaluating filtering JS function: " + << QUOTE_W_SPACE_DOT(ex.message()) + << " Accepting message."; + continue; + } + + // If we reach this point. Then we ignore the message which is by now + // already removed, go to next message. + break; } - MessageFilter* msg_filter = filter.data(); + if (!msg_backup.m_isRead && msg_orig->m_isRead) { + qDebugNN << LOGSEC_FEEDDOWNLOADER << "Message with custom ID: '" << msg_backup.m_customId << "' was marked as read by message scripts."; - tmr.restart(); + read_msgs << *msg_orig; + } - try { - MessageObject::FilteringAction decision = msg_filter->filterMessage(&filter_engine); + if (!msg_backup.m_isImportant && msg_orig->m_isImportant) { + qDebugNN << LOGSEC_FEEDDOWNLOADER << "Message with custom ID: '" << msg_backup.m_customId << "' was marked as important by message scripts."; - qDebugNN << LOGSEC_FEEDDOWNLOADER - << "Running filter script, it took " << tmr.nsecsElapsed() / 1000 << " microseconds."; + important_msgs << *msg_orig; + } - switch (decision) { - case MessageObject::FilteringAction::Accept: - // Message is normally accepted, it could be tweaked by the filter. - continue; + // Process changed labels. + for (Label* lbl : qAsConst(msg_backup.m_assignedLabels)) { + if (!msg_orig->m_assignedLabels.contains(lbl)) { + // Label is not there anymore, it was deassigned. + lbl->deassignFromMessage(*msg_orig); - case MessageObject::FilteringAction::Ignore: - case MessageObject::FilteringAction::Purge: - default: - // Remove the message, we do not want it. - remove_msg = true; - break; + qDebugNN << LOGSEC_FEEDDOWNLOADER + << "It was detected that label" << QUOTE_W_SPACE(lbl->customId()) + << "was DEASSIGNED from message" << QUOTE_W_SPACE(msg_orig->m_customId) + << "by message filter(s)."; } } - catch (const FilteringException& ex) { + + for (Label* lbl : qAsConst(msg_orig->m_assignedLabels)) { + if (!msg_backup.m_assignedLabels.contains(lbl)) { + // Label is in new message, but is not in old message, it + // was newly assigned. + lbl->assignToMessage(*msg_orig); + + qDebugNN << LOGSEC_FEEDDOWNLOADER + << "It was detected that label" << QUOTE_W_SPACE(lbl->customId()) + << "was ASSIGNED to message" << QUOTE_W_SPACE(msg_orig->m_customId) + << "by message filter(s)."; + } + } + + if (remove_msg) { + msgs.removeAt(i--); + } + } + + if (!read_msgs.isEmpty()) { + // Now we push new read states to the service. + if (feed->getParentServiceRoot()->onBeforeSetMessagesRead(feed, read_msgs, RootItem::ReadStatus::Read)) { + qDebugNN << LOGSEC_FEEDDOWNLOADER + << "Notified services about messages marked as read by message filters."; + } + else { qCriticalNN << LOGSEC_FEEDDOWNLOADER - << "Error when evaluating filtering JS function: " - << QUOTE_W_SPACE_DOT(ex.message()) - << " Accepting message."; - continue; + << "Notification of services about messages marked as read by message filters FAILED."; } - - // If we reach this point. Then we ignore the message which is by now - // already removed, go to next message. - break; } - if (!msg_backup.m_isRead && msg_orig->m_isRead) { - qDebugNN << LOGSEC_FEEDDOWNLOADER << "Message with custom ID: '" << msg_backup.m_customId << "' was marked as read by message scripts."; - - read_msgs << *msg_orig; - } - - if (!msg_backup.m_isImportant && msg_orig->m_isImportant) { - qDebugNN << LOGSEC_FEEDDOWNLOADER << "Message with custom ID: '" << msg_backup.m_customId << "' was marked as important by message scripts."; - - important_msgs << *msg_orig; - } - - // Process changed labels. - for (Label* lbl : qAsConst(msg_backup.m_assignedLabels)) { - if (!msg_orig->m_assignedLabels.contains(lbl)) { - // Label is not there anymore, it was deassigned. - lbl->deassignFromMessage(*msg_orig); + if (!important_msgs.isEmpty()) { + // Now we push new read states to the service. + auto list = boolinq::from(important_msgs).select([](const Message& msg) { + return ImportanceChange(msg, RootItem::Importance::Important); + }).toStdList(); + QList chngs = FROM_STD_LIST(QList, list); + if (feed->getParentServiceRoot()->onBeforeSwitchMessageImportance(feed, chngs)) { qDebugNN << LOGSEC_FEEDDOWNLOADER - << "It was detected that label" << QUOTE_W_SPACE(lbl->customId()) - << "was DEASSIGNED from message" << QUOTE_W_SPACE(msg_orig->m_customId) - << "by message filter(s)."; + << "Notified services about messages marked as important by message filters."; + } + else { + qCriticalNN << LOGSEC_FEEDDOWNLOADER + << "Notification of services about messages marked as important by message filters FAILED."; } } - - for (Label* lbl : qAsConst(msg_orig->m_assignedLabels)) { - if (!msg_backup.m_assignedLabels.contains(lbl)) { - // Label is in new message, but is not in old message, it - // was newly assigned. - lbl->assignToMessage(*msg_orig); - - qDebugNN << LOGSEC_FEEDDOWNLOADER - << "It was detected that label" << QUOTE_W_SPACE(lbl->customId()) - << "was ASSIGNED to message" << QUOTE_W_SPACE(msg_orig->m_customId) - << "by message filter(s)."; - } - } - - if (remove_msg) { - msgs.removeAt(i--); - } } - if (!read_msgs.isEmpty()) { - // Now we push new read states to the service. - if (feed->getParentServiceRoot()->onBeforeSetMessagesRead(feed, read_msgs, RootItem::ReadStatus::Read)) { - qDebugNN << LOGSEC_FEEDDOWNLOADER - << "Notified services about messages marked as read by message filters."; - } - else { - qCriticalNN << LOGSEC_FEEDDOWNLOADER - << "Notification of services about messages marked as read by message filters FAILED."; - } - } + // Now make sure, that messages are actually stored to SQL in a locked state. + qDebugNN << LOGSEC_FEEDDOWNLOADER << "Saving messages of feed ID '" + << feed->customId() << "' URL: '" << feed->source() << "' title: '" << feed->title() << "' in thread: '" + << QThread::currentThreadId() << "'."; - if (!important_msgs.isEmpty()) { - // Now we push new read states to the service. - auto list = boolinq::from(important_msgs).select([](const Message& msg) { - return ImportanceChange(msg, RootItem::Importance::Important); - }).toStdList(); - QList chngs = FROM_STD_LIST(QList, list); + auto updated_messages = feed->updateMessages(msgs, false); - if (feed->getParentServiceRoot()->onBeforeSwitchMessageImportance(feed, chngs)) { - qDebugNN << LOGSEC_FEEDDOWNLOADER - << "Notified services about messages marked as important by message filters."; - } - else { - qCriticalNN << LOGSEC_FEEDDOWNLOADER - << "Notification of services about messages marked as important by message filters FAILED."; - } + feed->setStatus(updated_messages.first > 0 || updated_messages.second > 0 + ? Feed::Status::NewMessages + : Feed::Status::Normal); + + qDebugNN << LOGSEC_FEEDDOWNLOADER + << updated_messages << " messages for feed " + << feed->customId() << " stored in DB."; + + if (updated_messages.first > 0) { + m_results.appendUpdatedFeed(QPair(feed->title(), updated_messages.first)); } } + catch (const FeedFetchException& feed_ex) { + // TODO: logovat chybu, todo datachanged feed + + feed->setStatus(feed_ex.feedStatus()); + } + + catch (const ApplicationException& app_ex) { + // TODO: logovat chybu, todo datachanged feed + + feed->setStatus(Feed::Status::OtherError); + } m_feedsUpdated++; - // Now make sure, that messages are actually stored to SQL in a locked state. - qDebugNN << LOGSEC_FEEDDOWNLOADER << "Saving messages of feed ID '" - << feed->customId() << "' URL: '" << feed->source() << "' title: '" << feed->title() << "' in thread: '" - << QThread::currentThreadId() << "'."; - - int updated_messages = feed->updateMessages(msgs, error_during_obtaining); - - qDebugNN << LOGSEC_FEEDDOWNLOADER - << updated_messages << " messages for feed " - << feed->customId() << " stored in DB."; - - if (updated_messages > 0) { - m_results.appendUpdatedFeed(QPair(feed->title(), updated_messages)); - } - qDebugNN << LOGSEC_FEEDDOWNLOADER << "Made progress in feed updates, total feeds count " << m_feedsUpdated << "/" << m_feedsOriginalCount << " (id of feed is " diff --git a/src/librssguard/database/databasequeries.cpp b/src/librssguard/database/databasequeries.cpp index f2f84b9c3..57e5e3c74 100755 --- a/src/librssguard/database/databasequeries.cpp +++ b/src/librssguard/database/databasequeries.cpp @@ -958,20 +958,20 @@ QList DatabaseQueries::getUndeletedMessagesForAccount(const QSqlDatabas return messages; } -int DatabaseQueries::updateMessages(QSqlDatabase db, - const QList& messages, - const QString& feed_custom_id, - int account_id, - const QString& url, - bool force_update, - bool* ok) { +QPair DatabaseQueries::updateMessages(QSqlDatabase db, + const QList& messages, + const QString& feed_custom_id, + int account_id, + const QString& url, + bool force_update, + bool* ok) { if (messages.isEmpty()) { *ok = true; - return 0; + return { 0, 0 }; } bool use_transactions = qApp->settings()->value(GROUP(Database), SETTING(Database::UseTransactions)).toBool(); - int updated_messages = 0; + QPair updated_messages = { 0, 0 }; // Prepare queries. QSqlQuery query_select_with_url(db); @@ -1198,7 +1198,12 @@ int DatabaseQueries::updateMessages(QSqlDatabase db, << "URL" << QUOTE_W_SPACE(message.m_url) << "in DB."; - updated_messages++; + + if (!message.m_isRead) { + updated_messages.first++; + } + + updated_messages.second++; } else if (query_update.lastError().isValid()) { qWarningNN << LOGSEC_DB @@ -1226,7 +1231,11 @@ int DatabaseQueries::updateMessages(QSqlDatabase db, query_insert.bindValue(QSL(":account_id"), account_id); if (query_insert.exec() && query_insert.numRowsAffected() == 1) { - updated_messages++; + if (!message.m_isRead) { + updated_messages.first++; + } + + updated_messages.second++; if (query_insert.lastInsertId().isValid()) { id_existing_message = query_insert.lastInsertId().toInt(); @@ -1289,7 +1298,7 @@ int DatabaseQueries::updateMessages(QSqlDatabase db, if (ok != nullptr) { *ok = false; - updated_messages = 0; + updated_messages = { 0, 0 }; } } else { diff --git a/src/librssguard/database/databasequeries.h b/src/librssguard/database/databasequeries.h index d85f7f8c1..6da941e6e 100644 --- a/src/librssguard/database/databasequeries.h +++ b/src/librssguard/database/databasequeries.h @@ -109,8 +109,10 @@ class DatabaseQueries { static void loadFromDatabase(ServiceRoot* root); static bool storeNewOauthTokens(const QSqlDatabase& db, const QString& refresh_token, int account_id); static void createOverwriteAccount(const QSqlDatabase& db, ServiceRoot* account); - static int updateMessages(QSqlDatabase db, const QList& messages, const QString& feed_custom_id, - int account_id, const QString& url, bool force_update, bool* ok = nullptr); + + // Returns counts of updated messages . + static QPair updateMessages(QSqlDatabase db, const QList& messages, const QString& feed_custom_id, + int account_id, const QString& url, bool force_update, bool* ok = nullptr); static bool deleteAccount(const QSqlDatabase& db, int account_id); static bool deleteAccountData(const QSqlDatabase& db, int account_id, bool delete_messages_too); static bool cleanLabelledMessages(const QSqlDatabase& db, bool clean_read_only, Label* label); diff --git a/src/librssguard/exceptions/applicationexception.h b/src/librssguard/exceptions/applicationexception.h index 98ad9a31e..b6d098ee1 100644 --- a/src/librssguard/exceptions/applicationexception.h +++ b/src/librssguard/exceptions/applicationexception.h @@ -7,7 +7,7 @@ class ApplicationException { public: - explicit ApplicationException(QString message = QString()); + explicit ApplicationException(QString message = {}); QString message() const; diff --git a/src/librssguard/exceptions/feedfetchexception.cpp b/src/librssguard/exceptions/feedfetchexception.cpp new file mode 100755 index 000000000..844b83e7a --- /dev/null +++ b/src/librssguard/exceptions/feedfetchexception.cpp @@ -0,0 +1,10 @@ +// For license of this file, see /LICENSE.md. + +#include "exceptions/feedfetchexception.h" + +FeedFetchException::FeedFetchException(Feed::Status feed_status, QString message) + : ApplicationException(message), m_feedStatus(feed_status) {} + +Feed::Status FeedFetchException::feedStatus() const { + return m_feedStatus; +} diff --git a/src/librssguard/exceptions/feedfetchexception.h b/src/librssguard/exceptions/feedfetchexception.h new file mode 100755 index 000000000..961daeb64 --- /dev/null +++ b/src/librssguard/exceptions/feedfetchexception.h @@ -0,0 +1,19 @@ +// For license of this file, see /LICENSE.md. + +#ifndef FEEDFETCHEXCEPTION_H +#define FEEDFETCHEXCEPTION_H + +#include "exceptions/applicationexception.h" +#include "services/abstract/feed.h" + +class FeedFetchException : public ApplicationException { + public: + explicit FeedFetchException(Feed::Status feed_status, QString message = {}); + + Feed::Status feedStatus() const; + + private: + Feed::Status m_feedStatus; +}; + +#endif // FEEDFETCHEXCEPTION_H diff --git a/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp b/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp index 805a4e28e..3e0f03746 100644 --- a/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp +++ b/src/librssguard/gui/dialogs/formmessagefiltersmanager.cpp @@ -422,7 +422,10 @@ void FormMessageFiltersManager::processCheckedFeeds() { } // Update messages in DB and reload selection. - it->toFeed()->updateMessages(msgs, false, true); + it->toFeed()->updateMessages(msgs, true); + + // TODO: ted hazi vyjimku, ošetřit + displayMessagesOfFeed(); } } diff --git a/src/librssguard/librssguard.pro b/src/librssguard/librssguard.pro index 7d0ac14a2..3d6871693 100644 --- a/src/librssguard/librssguard.pro +++ b/src/librssguard/librssguard.pro @@ -56,6 +56,7 @@ HEADERS += core/feeddownloader.h \ dynamic-shortcuts/dynamicshortcutswidget.h \ dynamic-shortcuts/shortcutcatcher.h \ exceptions/applicationexception.h \ + exceptions/feedfetchexception.h \ exceptions/filteringexception.h \ exceptions/ioexception.h \ exceptions/networkexception.h \ @@ -240,6 +241,7 @@ SOURCES += core/feeddownloader.cpp \ dynamic-shortcuts/dynamicshortcutswidget.cpp \ dynamic-shortcuts/shortcutcatcher.cpp \ exceptions/applicationexception.cpp \ + exceptions/feedfetchexception.cpp \ exceptions/filteringexception.cpp \ exceptions/ioexception.cpp \ exceptions/networkexception.cpp \ diff --git a/src/librssguard/miscellaneous/application.cpp b/src/librssguard/miscellaneous/application.cpp index f6baeb3ff..b29f82eb8 100755 --- a/src/librssguard/miscellaneous/application.cpp +++ b/src/librssguard/miscellaneous/application.cpp @@ -95,6 +95,8 @@ Application::Application(const QString& id, int& argc, char** argv) if (isFirstRun()) { m_notifications->save({ + Notification(Notification::Event::GeneralEvent, + true), Notification(Notification::Event::NewArticlesFetched, true, QSL("%1/rooster.wav").arg(SOUNDS_BUILTIN_DIRECTORY)), diff --git a/src/librssguard/services/abstract/feed.cpp b/src/librssguard/services/abstract/feed.cpp index 23c47f6a4..cdd4cfd93 100755 --- a/src/librssguard/services/abstract/feed.cpp +++ b/src/librssguard/services/abstract/feed.cpp @@ -188,65 +188,56 @@ bool Feed::markAsReadUnread(RootItem::ReadStatus status) { return service->markFeedsReadUnread(QList() << this, status); } -int Feed::updateMessages(const QList& messages, bool error_during_obtaining, bool force_update) { - QList items_to_update; - int updated_messages = 0; +QPair Feed::updateMessages(const QList& messages, bool force_update) { + QPair updated_messages = { 0, 0 }; - if (!error_during_obtaining) { - bool is_main_thread = QThread::currentThread() == qApp->thread(); - - qDebugNN << LOGSEC_CORE - << "Updating messages in DB. Main thread:" - << QUOTE_W_SPACE_DOT(is_main_thread ? "true" : "false"); - - bool ok = true; - - if (!messages.isEmpty()) { - qDebugNN << LOGSEC_CORE - << "There are some messages to be updated/added to DB."; - - QString custom_id = customId(); - int account_id = getParentServiceRoot()->accountId(); - QSqlDatabase database = is_main_thread ? - qApp->database()->driver()->connection(metaObject()->className()) : - qApp->database()->driver()->connection(QSL("feed_upd")); - - updated_messages = DatabaseQueries::updateMessages(database, messages, custom_id, account_id, - source(), force_update, &ok); - } - else { - qDebugNN << LOGSEC_CORE - << "There are no messages for update."; - } - - if (ok) { - setStatus(updated_messages > 0 ? Status::NewMessages : Status::Normal); - updateCounts(true); - - if (getParentServiceRoot()->recycleBin() != nullptr && updated_messages > 0) { - getParentServiceRoot()->recycleBin()->updateCounts(true); - items_to_update.append(getParentServiceRoot()->recycleBin()); - } - - if (getParentServiceRoot()->importantNode() != nullptr && updated_messages > 0) { - getParentServiceRoot()->importantNode()->updateCounts(true); - items_to_update.append(getParentServiceRoot()->importantNode()); - } - - if (getParentServiceRoot()->unreadNode() != nullptr && updated_messages > 0) { - getParentServiceRoot()->unreadNode()->updateCounts(true); - items_to_update.append(getParentServiceRoot()->unreadNode()); - } - - if (getParentServiceRoot()->labelsNode() != nullptr) { - getParentServiceRoot()->labelsNode()->updateCounts(true); - items_to_update.append(getParentServiceRoot()->labelsNode()); - } - } + if (messages.isEmpty()) { + return updated_messages; } - else { - qCriticalNN << LOGSEC_CORE - << "There is indication that there was error during messages obtaining."; + + QList items_to_update; + bool is_main_thread = QThread::currentThread() == qApp->thread(); + + qDebugNN << LOGSEC_CORE + << "Updating messages in DB. Main thread:" + << QUOTE_W_SPACE_DOT(is_main_thread); + + bool ok = false; + + qDebugNN << LOGSEC_CORE + << "There are some messages to be updated/added to DB."; + + QString custom_id = customId(); + int account_id = getParentServiceRoot()->accountId(); + QSqlDatabase database = is_main_thread ? + qApp->database()->driver()->connection(metaObject()->className()) : + qApp->database()->driver()->connection(QSL("feed_upd")); + + updated_messages = DatabaseQueries::updateMessages(database, messages, custom_id, account_id, + source(), force_update, &ok); + + if (ok && (updated_messages.first > 0 || updated_messages.second > 0)) { + updateCounts(true); + + if (getParentServiceRoot()->recycleBin() != nullptr) { + getParentServiceRoot()->recycleBin()->updateCounts(true); + items_to_update.append(getParentServiceRoot()->recycleBin()); + } + + if (getParentServiceRoot()->importantNode() != nullptr) { + getParentServiceRoot()->importantNode()->updateCounts(true); + items_to_update.append(getParentServiceRoot()->importantNode()); + } + + if (getParentServiceRoot()->unreadNode() != nullptr) { + getParentServiceRoot()->unreadNode()->updateCounts(true); + items_to_update.append(getParentServiceRoot()->unreadNode()); + } + + if (getParentServiceRoot()->labelsNode() != nullptr) { + getParentServiceRoot()->labelsNode()->updateCounts(true); + items_to_update.append(getParentServiceRoot()->labelsNode()); + } } // Some messages were really added to DB, reload feed in model. diff --git a/src/librssguard/services/abstract/feed.h b/src/librssguard/services/abstract/feed.h index b64895da4..d95b6a039 100644 --- a/src/librssguard/services/abstract/feed.h +++ b/src/librssguard/services/abstract/feed.h @@ -75,7 +75,8 @@ class Feed : public RootItem { void setMessageFilters(const QList>& messageFilters); void removeMessageFilter(MessageFilter* filter); - int updateMessages(const QList& messages, bool error_during_obtaining, bool force_update = false); + // Returns counts of updated messages . + QPair updateMessages(const QList& messages, bool force_update); public slots: virtual void updateCounts(bool including_total_count); diff --git a/src/librssguard/services/abstract/serviceroot.h b/src/librssguard/services/abstract/serviceroot.h index 149fd21ba..088add514 100644 --- a/src/librssguard/services/abstract/serviceroot.h +++ b/src/librssguard/services/abstract/serviceroot.h @@ -92,7 +92,9 @@ class ServiceRoot : public RootItem { virtual void stop(); // Obtains list of messages. - virtual QList obtainNewMessages(const QList& feeds, bool* error_during_obtaining) = 0; + // Throws exception subclassed from ApplicationException, preferably FeedFetchException + // if any problems arise. + virtual QList obtainNewMessages(const QList& feeds) = 0; // This method should prepare messages for given "item" (download them maybe?) // into predefined "Messages" table diff --git a/src/librssguard/services/feedly/feedlyserviceroot.cpp b/src/librssguard/services/feedly/feedlyserviceroot.cpp index a6a3826f7..f701beede 100755 --- a/src/librssguard/services/feedly/feedlyserviceroot.cpp +++ b/src/librssguard/services/feedly/feedlyserviceroot.cpp @@ -5,6 +5,7 @@ #include "database/databasequeries.h" #include "definitions/definitions.h" #include "exceptions/applicationexception.h" +#include "exceptions/feedfetchexception.h" #include "exceptions/networkexception.h" #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" @@ -71,25 +72,15 @@ void FeedlyServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool()); } -QList FeedlyServiceRoot::obtainNewMessages(const QList& feeds, bool* error_during_obtaining) { +QList FeedlyServiceRoot::obtainNewMessages(const QList& feeds) { QList messages; for (Feed* feed : feeds) { try { messages << m_network->streamContents(feed->customId()); - - feed->setStatus(Feed::Status::Normal); - *error_during_obtaining = false; } catch (const ApplicationException& ex) { - feed->setStatus(Feed::Status::NetworkError); - *error_during_obtaining = true; - - qCriticalNN << LOGSEC_FEEDLY - << "Problem" - << QUOTE_W_SPACE(ex.message()) - << "when obtaining messages for feed" - << QUOTE_W_SPACE_DOT(customId()); + throw FeedFetchException(Feed::Status::NetworkError, ex.message()); } } diff --git a/src/librssguard/services/feedly/feedlyserviceroot.h b/src/librssguard/services/feedly/feedlyserviceroot.h index 063f3f53f..c2a4f0c62 100755 --- a/src/librssguard/services/feedly/feedlyserviceroot.h +++ b/src/librssguard/services/feedly/feedlyserviceroot.h @@ -23,7 +23,7 @@ class FeedlyServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual LabelOperation supportedLabelOperations() const; virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, bool* error_during_obtaining); + virtual QList obtainNewMessages(const QList& feeds); FeedlyNetwork* network() const; diff --git a/src/librssguard/services/gmail/gmailserviceroot.cpp b/src/librssguard/services/gmail/gmailserviceroot.cpp index b1acd63d3..b329c4d4d 100644 --- a/src/librssguard/services/gmail/gmailserviceroot.cpp +++ b/src/librssguard/services/gmail/gmailserviceroot.cpp @@ -3,6 +3,7 @@ #include "services/gmail/gmailserviceroot.h" #include "database/databasequeries.h" +#include "exceptions/feedfetchexception.h" #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" #include "network-web/oauth2service.h" @@ -73,7 +74,7 @@ void GmailServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->oauth()->setRedirectUrl(data["redirect_uri"].toString()); } -QList GmailServiceRoot::obtainNewMessages(const QList& feeds, bool* error_during_obtaining) { +QList GmailServiceRoot::obtainNewMessages(const QList& feeds) { QList messages; for (Feed* feed : feeds) { @@ -83,7 +84,7 @@ QList GmailServiceRoot::obtainNewMessages(const QList& feeds, bo feed->setStatus(error); if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError || error == Feed::Status::ParsingError) { - *error_during_obtaining = true; + throw FeedFetchException(error); } } diff --git a/src/librssguard/services/gmail/gmailserviceroot.h b/src/librssguard/services/gmail/gmailserviceroot.h index 8e1b95c24..688b02232 100644 --- a/src/librssguard/services/gmail/gmailserviceroot.h +++ b/src/librssguard/services/gmail/gmailserviceroot.h @@ -31,7 +31,7 @@ class GmailServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual void saveAllCachedData(bool ignore_errors); virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, bool* error_during_obtaining); + virtual QList obtainNewMessages(const QList& feeds); protected: virtual RootItem* obtainNewTreeForSyncIn() const; diff --git a/src/librssguard/services/greader/greaderserviceroot.cpp b/src/librssguard/services/greader/greaderserviceroot.cpp index 043599bbc..a6f6c0739 100755 --- a/src/librssguard/services/greader/greaderserviceroot.cpp +++ b/src/librssguard/services/greader/greaderserviceroot.cpp @@ -4,6 +4,7 @@ #include "database/databasequeries.h" #include "definitions/definitions.h" +#include "exceptions/feedfetchexception.h" #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" #include "miscellaneous/mutex.h" @@ -56,7 +57,7 @@ void GreaderServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool()); } -QList GreaderServiceRoot::obtainNewMessages(const QList& feeds, bool* error_during_obtaining) { +QList GreaderServiceRoot::obtainNewMessages(const QList& feeds) { QList messages; for (Feed* feed : feeds) { @@ -66,7 +67,7 @@ QList GreaderServiceRoot::obtainNewMessages(const QList& feeds, feed->setStatus(error); if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError) { - *error_during_obtaining = true; + throw FeedFetchException(error); } } diff --git a/src/librssguard/services/greader/greaderserviceroot.h b/src/librssguard/services/greader/greaderserviceroot.h index 1012a2978..6306a1432 100755 --- a/src/librssguard/services/greader/greaderserviceroot.h +++ b/src/librssguard/services/greader/greaderserviceroot.h @@ -31,7 +31,7 @@ class GreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual LabelOperation supportedLabelOperations() const; virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, bool* error_during_obtaining); + virtual QList obtainNewMessages(const QList& feeds); GreaderNetwork* network() const; diff --git a/src/librssguard/services/inoreader/gui/inoreaderaccountdetails.cpp b/src/librssguard/services/inoreader/gui/inoreaderaccountdetails.cpp index 13e19aeb4..dd2aa2386 100755 --- a/src/librssguard/services/inoreader/gui/inoreaderaccountdetails.cpp +++ b/src/librssguard/services/inoreader/gui/inoreaderaccountdetails.cpp @@ -57,11 +57,13 @@ InoreaderAccountDetails::InoreaderAccountDetails(QWidget* parent) void InoreaderAccountDetails::testSetup(const QNetworkProxy& custom_proxy) { m_lastProxy = custom_proxy; - m_oauth->logout(); - m_oauth->setClientId(m_ui.m_txtAppId->lineEdit()->text()); - m_oauth->setClientSecret(m_ui.m_txtAppKey->lineEdit()->text()); - m_oauth->setRedirectUrl(m_ui.m_txtRedirectUrl->lineEdit()->text()); - m_oauth->login(); + if (m_oauth != nullptr) { + m_oauth->logout(); + m_oauth->setClientId(m_ui.m_txtAppId->lineEdit()->text()); + m_oauth->setClientSecret(m_ui.m_txtAppKey->lineEdit()->text()); + m_oauth->setRedirectUrl(m_ui.m_txtRedirectUrl->lineEdit()->text()); + m_oauth->login(); + } } void InoreaderAccountDetails::checkUsername(const QString& username) { @@ -96,7 +98,6 @@ void InoreaderAccountDetails::onAuthGranted() { InoreaderNetworkFactory fac; fac.setOauth(m_oauth); - auto resp = fac.userInfo(m_lastProxy); m_ui.m_txtUsername->lineEdit()->setText(resp["userEmail"].toString()); @@ -109,9 +110,11 @@ void InoreaderAccountDetails::onAuthGranted() { } void InoreaderAccountDetails::hookNetwork() { - connect(m_oauth, &OAuth2Service::tokensRetrieved, this, &InoreaderAccountDetails::onAuthGranted); - connect(m_oauth, &OAuth2Service::tokensRetrieveError, this, &InoreaderAccountDetails::onAuthError); - connect(m_oauth, &OAuth2Service::authFailed, this, &InoreaderAccountDetails::onAuthFailed); + if (m_oauth != nullptr) { + connect(m_oauth, &OAuth2Service::tokensRetrieved, this, &InoreaderAccountDetails::onAuthGranted); + connect(m_oauth, &OAuth2Service::tokensRetrieveError, this, &InoreaderAccountDetails::onAuthError); + connect(m_oauth, &OAuth2Service::authFailed, this, &InoreaderAccountDetails::onAuthFailed); + } } void InoreaderAccountDetails::registerApi() { diff --git a/src/librssguard/services/inoreader/inoreaderserviceroot.cpp b/src/librssguard/services/inoreader/inoreaderserviceroot.cpp index d5f21a2d8..47e932fbb 100644 --- a/src/librssguard/services/inoreader/inoreaderserviceroot.cpp +++ b/src/librssguard/services/inoreader/inoreaderserviceroot.cpp @@ -3,6 +3,7 @@ #include "services/inoreader/inoreaderserviceroot.h" #include "database/databasequeries.h" +#include "exceptions/feedfetchexception.h" #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" #include "network-web/oauth2service.h" @@ -55,7 +56,7 @@ void InoreaderServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->oauth()->setRedirectUrl(data["redirect_uri"].toString()); } -QList InoreaderServiceRoot::obtainNewMessages(const QList& feeds, bool* error_during_obtaining) { +QList InoreaderServiceRoot::obtainNewMessages(const QList& feeds) { QList messages; for (Feed* feed : feeds) { @@ -65,7 +66,7 @@ QList InoreaderServiceRoot::obtainNewMessages(const QList& feeds feed->setStatus(error); if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError) { - *error_during_obtaining = true; + throw FeedFetchException(error); } } diff --git a/src/librssguard/services/inoreader/inoreaderserviceroot.h b/src/librssguard/services/inoreader/inoreaderserviceroot.h index 0edecd03f..01106fdce 100644 --- a/src/librssguard/services/inoreader/inoreaderserviceroot.h +++ b/src/librssguard/services/inoreader/inoreaderserviceroot.h @@ -29,7 +29,7 @@ class InoreaderServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual void saveAllCachedData(bool ignore_errors); virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, bool* error_during_obtaining); + virtual QList obtainNewMessages(const QList& feeds); protected: virtual RootItem* obtainNewTreeForSyncIn() const; diff --git a/src/librssguard/services/owncloud/owncloudserviceroot.cpp b/src/librssguard/services/owncloud/owncloudserviceroot.cpp index 8bd436e45..be9b1fe7c 100644 --- a/src/librssguard/services/owncloud/owncloudserviceroot.cpp +++ b/src/librssguard/services/owncloud/owncloudserviceroot.cpp @@ -4,6 +4,7 @@ #include "database/databasequeries.h" #include "definitions/definitions.h" +#include "exceptions/feedfetchexception.h" #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" #include "miscellaneous/mutex.h" @@ -149,18 +150,16 @@ void OwnCloudServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool()); } -QList OwnCloudServiceRoot::obtainNewMessages(const QList& feeds, bool* error_during_obtaining) { +QList OwnCloudServiceRoot::obtainNewMessages(const QList& feeds) { QList msgs; for (Feed* feed : feeds) { OwnCloudGetMessagesResponse messages = network()->getMessages(feed->customNumericId(), networkProxy()); if (messages.networkError() != QNetworkReply::NetworkError::NoError) { - feed->setStatus(Feed::Status::NetworkError); - *error_during_obtaining = true; + throw FeedFetchException(Feed::Status::NetworkError); } else { - *error_during_obtaining = false; msgs << messages.messages(); } } diff --git a/src/librssguard/services/owncloud/owncloudserviceroot.h b/src/librssguard/services/owncloud/owncloudserviceroot.h index 1682451e2..3ec6423db 100644 --- a/src/librssguard/services/owncloud/owncloudserviceroot.h +++ b/src/librssguard/services/owncloud/owncloudserviceroot.h @@ -28,7 +28,7 @@ class OwnCloudServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual void saveAllCachedData(bool ignore_errors); virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, bool* error_during_obtaining); + virtual QList obtainNewMessages(const QList& feeds); OwnCloudNetworkFactory* network() const; diff --git a/src/librssguard/services/standard/standardserviceroot.cpp b/src/librssguard/services/standard/standardserviceroot.cpp index 7b4c60cf3..de54e4f06 100644 --- a/src/librssguard/services/standard/standardserviceroot.cpp +++ b/src/librssguard/services/standard/standardserviceroot.cpp @@ -6,6 +6,7 @@ #include "database/databasequeries.h" #include "definitions/definitions.h" #include "exceptions/applicationexception.h" +#include "exceptions/feedfetchexception.h" #include "exceptions/scriptexception.h" #include "gui/messagebox.h" #include "miscellaneous/application.h" @@ -143,7 +144,7 @@ Qt::ItemFlags StandardServiceRoot::additionalFlags() const { return Qt::ItemFlag::ItemIsDropEnabled; } -QList StandardServiceRoot::obtainNewMessages(const QList& feeds, bool* error_during_obtaining) { +QList StandardServiceRoot::obtainNewMessages(const QList& feeds) { QList msgs; for (Feed* f : feeds) { @@ -178,12 +179,7 @@ QList StandardServiceRoot::obtainNewMessages(const QList& feeds, << QUOTE_W_SPACE(feed->networkError()) << "during fetching of new messages for feed" << QUOTE_W_SPACE_DOT(feed->source()); - feed->setStatus(StandardFeed::Status::NetworkError); - *error_during_obtaining = true; - continue; - } - else { - *error_during_obtaining = false; + throw FeedFetchException(Feed::Status::NetworkError); } // Encode downloaded data for further parsing. @@ -213,9 +209,7 @@ QList StandardServiceRoot::obtainNewMessages(const QList& feeds, << "Custom script for generating feed file failed:" << QUOTE_W_SPACE_DOT(ex.message()); - feed->setStatus(Feed::Status::OtherError); - *error_during_obtaining = true; - continue; + throw FeedFetchException(Feed::Status::OtherError, ex.message()); } } @@ -234,9 +228,7 @@ QList StandardServiceRoot::obtainNewMessages(const QList& feeds, << "Post-processing script for feed file failed:" << QUOTE_W_SPACE_DOT(ex.message()); - feed->setStatus(Feed::Status::OtherError); - *error_during_obtaining = true; - continue; + throw FeedFetchException(Feed::Status::OtherError, ex.message()); } } diff --git a/src/librssguard/services/standard/standardserviceroot.h b/src/librssguard/services/standard/standardserviceroot.h index 0262bd856..65c5e7851 100644 --- a/src/librssguard/services/standard/standardserviceroot.h +++ b/src/librssguard/services/standard/standardserviceroot.h @@ -32,7 +32,7 @@ class StandardServiceRoot : public ServiceRoot { virtual bool supportsFeedAdding() const; virtual bool supportsCategoryAdding() const; virtual Qt::ItemFlags additionalFlags() const; - virtual QList obtainNewMessages(const QList& feeds, bool* error_during_obtaining); + virtual QList obtainNewMessages(const QList& feeds); QList serviceMenu(); QList getContextMenuForFeed(StandardFeed* feed); diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp index 97b826217..f58205912 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.cpp +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.cpp @@ -3,6 +3,7 @@ #include "services/tt-rss/ttrssserviceroot.h" #include "database/databasequeries.h" +#include "exceptions/feedfetchexception.h" #include "miscellaneous/application.h" #include "miscellaneous/iconfactory.h" #include "miscellaneous/mutex.h" @@ -213,7 +214,7 @@ void TtRssServiceRoot::setCustomDatabaseData(const QVariantHash& data) { m_network->setDownloadOnlyUnreadMessages(data["download_only_unread"].toBool()); } -QList TtRssServiceRoot::obtainNewMessages(const QList& feeds, bool* error_during_obtaining) { +QList TtRssServiceRoot::obtainNewMessages(const QList& feeds) { QList messages; for (Feed* feed : feeds) { @@ -228,10 +229,7 @@ QList TtRssServiceRoot::obtainNewMessages(const QList& feeds, bo networkProxy()); if (network()->lastError() != QNetworkReply::NetworkError::NoError) { - feed->setStatus(Feed::Status::NetworkError); - *error_during_obtaining = true; - itemChanged(QList() << this); - continue; + throw FeedFetchException(Feed::Status::NetworkError); } else { QList new_messages = headlines.messages(this); diff --git a/src/librssguard/services/tt-rss/ttrssserviceroot.h b/src/librssguard/services/tt-rss/ttrssserviceroot.h index 8ba5217b0..e3c21a5bf 100644 --- a/src/librssguard/services/tt-rss/ttrssserviceroot.h +++ b/src/librssguard/services/tt-rss/ttrssserviceroot.h @@ -33,7 +33,7 @@ class TtRssServiceRoot : public ServiceRoot, public CacheForServiceRoot { virtual void saveAllCachedData(bool ignore_errors); virtual QVariantHash customDatabaseData() const; virtual void setCustomDatabaseData(const QVariantHash& data); - virtual QList obtainNewMessages(const QList& feeds, bool* error_during_obtaining); + virtual QList obtainNewMessages(const QList& feeds); // Access to network. TtRssNetworkFactory* network() const;