work on discoverying feeds
This commit is contained in:
parent
075b249f23
commit
e8090ce68c
@ -38,9 +38,9 @@ set(SOURCES
|
||||
database/sqlitedriver.cpp
|
||||
database/sqlitedriver.h
|
||||
definitions/definitions.h
|
||||
definitions/typedefs.h
|
||||
definitions/globals.cpp
|
||||
definitions/globals.h
|
||||
definitions/typedefs.h
|
||||
dynamic-shortcuts/dynamicshortcuts.cpp
|
||||
dynamic-shortcuts/dynamicshortcuts.h
|
||||
dynamic-shortcuts/dynamicshortcutswidget.cpp
|
||||
@ -49,20 +49,20 @@ set(SOURCES
|
||||
dynamic-shortcuts/shortcutcatcher.h
|
||||
exceptions/applicationexception.cpp
|
||||
exceptions/applicationexception.h
|
||||
exceptions/feedrecognizedbutfailedexception.cpp
|
||||
exceptions/feedrecognizedbutfailedexception.h
|
||||
exceptions/feedfetchexception.cpp
|
||||
exceptions/feedfetchexception.h
|
||||
exceptions/feedrecognizedbutfailedexception.cpp
|
||||
exceptions/feedrecognizedbutfailedexception.h
|
||||
exceptions/filteringexception.cpp
|
||||
exceptions/filteringexception.h
|
||||
exceptions/ioexception.cpp
|
||||
exceptions/ioexception.h
|
||||
exceptions/networkexception.cpp
|
||||
exceptions/networkexception.h
|
||||
exceptions/scriptexception.cpp
|
||||
exceptions/scriptexception.h
|
||||
exceptions/processexception.cpp
|
||||
exceptions/processexception.h
|
||||
exceptions/scriptexception.cpp
|
||||
exceptions/scriptexception.h
|
||||
gui/dialogs/formabout.cpp
|
||||
gui/dialogs/formabout.h
|
||||
gui/dialogs/formaddaccount.cpp
|
||||
@ -71,10 +71,10 @@ set(SOURCES
|
||||
gui/dialogs/formbackupdatabasesettings.h
|
||||
gui/dialogs/formdatabasecleanup.cpp
|
||||
gui/dialogs/formdatabasecleanup.h
|
||||
gui/dialogs/formmain.cpp
|
||||
gui/dialogs/formmain.h
|
||||
gui/dialogs/formlog.cpp
|
||||
gui/dialogs/formlog.h
|
||||
gui/dialogs/formmain.cpp
|
||||
gui/dialogs/formmain.h
|
||||
gui/dialogs/formmessagefiltersmanager.cpp
|
||||
gui/dialogs/formmessagefiltersmanager.h
|
||||
gui/dialogs/formrestoredatabasesettings.cpp
|
||||
@ -97,14 +97,18 @@ set(SOURCES
|
||||
gui/messagepreviewer.h
|
||||
gui/messagesview.cpp
|
||||
gui/messagesview.h
|
||||
gui/notifications/articlelistnotification.cpp
|
||||
gui/notifications/articlelistnotification.h
|
||||
gui/notifications/basetoastnotification.cpp
|
||||
gui/notifications/basetoastnotification.h
|
||||
gui/notifications/notificationseditor.cpp
|
||||
gui/notifications/notificationseditor.h
|
||||
gui/notifications/singlenotificationeditor.cpp
|
||||
gui/notifications/singlenotificationeditor.h
|
||||
gui/notifications/articlelistnotification.cpp
|
||||
gui/notifications/articlelistnotification.h
|
||||
gui/notifications/toastnotification.cpp
|
||||
gui/notifications/toastnotification.h
|
||||
gui/notifications/toastnotificationsmanager.cpp
|
||||
gui/notifications/toastnotificationsmanager.h
|
||||
gui/reusable/baselineedit.cpp
|
||||
gui/reusable/baselineedit.h
|
||||
gui/reusable/basetreeview.cpp
|
||||
@ -113,6 +117,8 @@ set(SOURCES
|
||||
gui/reusable/colortoolbutton.h
|
||||
gui/reusable/comboboxwithstatus.cpp
|
||||
gui/reusable/comboboxwithstatus.h
|
||||
gui/reusable/discoverfeedsbutton.cpp
|
||||
gui/reusable/discoverfeedsbutton.h
|
||||
gui/reusable/edittableview.cpp
|
||||
gui/reusable/edittableview.h
|
||||
gui/reusable/helpspoiler.cpp
|
||||
@ -125,6 +131,8 @@ set(SOURCES
|
||||
gui/reusable/labelwithstatus.h
|
||||
gui/reusable/lineeditwithstatus.cpp
|
||||
gui/reusable/lineeditwithstatus.h
|
||||
gui/reusable/locationlineedit.cpp
|
||||
gui/reusable/locationlineedit.h
|
||||
gui/reusable/messagecountspinbox.cpp
|
||||
gui/reusable/messagecountspinbox.h
|
||||
gui/reusable/networkproxydetails.cpp
|
||||
@ -137,12 +145,12 @@ set(SOURCES
|
||||
gui/reusable/progressbarwithtext.h
|
||||
gui/reusable/resizablestackedwidget.cpp
|
||||
gui/reusable/resizablestackedwidget.h
|
||||
gui/reusable/searchlineedit.cpp
|
||||
gui/reusable/searchlineedit.h
|
||||
gui/reusable/searchtextwidget.cpp
|
||||
gui/reusable/searchtextwidget.h
|
||||
gui/reusable/squeezelabel.cpp
|
||||
gui/reusable/squeezelabel.h
|
||||
gui/reusable/searchlineedit.cpp
|
||||
gui/reusable/searchlineedit.h
|
||||
gui/reusable/styleditemdelegatewithoutfocus.cpp
|
||||
gui/reusable/styleditemdelegatewithoutfocus.h
|
||||
gui/reusable/timespinbox.cpp
|
||||
@ -151,6 +159,10 @@ set(SOURCES
|
||||
gui/reusable/treeviewcolumnsmenu.h
|
||||
gui/reusable/widgetwithstatus.cpp
|
||||
gui/reusable/widgetwithstatus.h
|
||||
gui/richtexteditor/mrichtextedit.cpp
|
||||
gui/richtexteditor/mrichtextedit.h
|
||||
gui/richtexteditor/mtextedit.cpp
|
||||
gui/richtexteditor/mtextedit.h
|
||||
gui/settings/settingsbrowsermail.cpp
|
||||
gui/settings/settingsbrowsermail.h
|
||||
gui/settings/settingsdatabase.cpp
|
||||
@ -181,15 +193,6 @@ set(SOURCES
|
||||
gui/tabcontent.h
|
||||
gui/tabwidget.cpp
|
||||
gui/tabwidget.h
|
||||
gui/notifications/toastnotification.cpp
|
||||
gui/notifications/toastnotification.h
|
||||
gui/notifications/toastnotificationsmanager.cpp
|
||||
gui/notifications/toastnotificationsmanager.h
|
||||
gui/webviewers/webviewer.h
|
||||
gui/richtexteditor/mrichtextedit.cpp
|
||||
gui/richtexteditor/mrichtextedit.h
|
||||
gui/richtexteditor/mtextedit.cpp
|
||||
gui/richtexteditor/mtextedit.h
|
||||
gui/toolbars/basetoolbar.cpp
|
||||
gui/toolbars/basetoolbar.h
|
||||
gui/toolbars/feedstoolbar.cpp
|
||||
@ -200,6 +203,9 @@ set(SOURCES
|
||||
gui/toolbars/statusbar.h
|
||||
gui/toolbars/toolbareditor.cpp
|
||||
gui/toolbars/toolbareditor.h
|
||||
gui/webbrowser.cpp
|
||||
gui/webbrowser.h
|
||||
gui/webviewers/webviewer.h
|
||||
miscellaneous/application.cpp
|
||||
miscellaneous/application.h
|
||||
miscellaneous/autosaver.cpp
|
||||
@ -236,6 +242,14 @@ set(SOURCES
|
||||
miscellaneous/templates.h
|
||||
miscellaneous/textfactory.cpp
|
||||
miscellaneous/textfactory.h
|
||||
network-web/adblock/adblockdialog.cpp
|
||||
network-web/adblock/adblockdialog.h
|
||||
network-web/adblock/adblockicon.cpp
|
||||
network-web/adblock/adblockicon.h
|
||||
network-web/adblock/adblockmanager.cpp
|
||||
network-web/adblock/adblockmanager.h
|
||||
network-web/adblock/adblockrequestinfo.cpp
|
||||
network-web/adblock/adblockrequestinfo.h
|
||||
network-web/basenetworkaccessmanager.cpp
|
||||
network-web/basenetworkaccessmanager.h
|
||||
network-web/cookiejar.cpp
|
||||
@ -244,6 +258,8 @@ set(SOURCES
|
||||
network-web/downloader.h
|
||||
network-web/downloadmanager.cpp
|
||||
network-web/downloadmanager.h
|
||||
network-web/googlesuggest.cpp
|
||||
network-web/googlesuggest.h
|
||||
network-web/httpresponse.cpp
|
||||
network-web/httpresponse.h
|
||||
network-web/networkfactory.cpp
|
||||
@ -268,32 +284,32 @@ set(SOURCES
|
||||
services/abstract/feed.h
|
||||
services/abstract/gui/authenticationdetails.cpp
|
||||
services/abstract/gui/authenticationdetails.h
|
||||
services/abstract/gui/custommessagepreviewer.cpp
|
||||
services/abstract/gui/custommessagepreviewer.h
|
||||
services/abstract/gui/formaccountdetails.cpp
|
||||
services/abstract/gui/formaccountdetails.h
|
||||
services/abstract/gui/formcategorydetails.cpp
|
||||
services/abstract/gui/formcategorydetails.h
|
||||
services/abstract/gui/formfeeddetails.cpp
|
||||
services/abstract/gui/formfeeddetails.h
|
||||
services/abstract/gui/formaddeditlabel.cpp
|
||||
services/abstract/gui/formaddeditlabel.h
|
||||
services/abstract/gui/formaddeditprobe.cpp
|
||||
services/abstract/gui/formaddeditprobe.h
|
||||
services/abstract/gui/custommessagepreviewer.h
|
||||
services/abstract/gui/custommessagepreviewer.cpp
|
||||
services/abstract/gui/formcategorydetails.cpp
|
||||
services/abstract/gui/formcategorydetails.h
|
||||
services/abstract/gui/formfeeddetails.cpp
|
||||
services/abstract/gui/formfeeddetails.h
|
||||
services/abstract/importantnode.cpp
|
||||
services/abstract/importantnode.h
|
||||
services/abstract/label.cpp
|
||||
services/abstract/label.h
|
||||
services/abstract/labelsnode.cpp
|
||||
services/abstract/labelsnode.h
|
||||
services/abstract/search.cpp
|
||||
services/abstract/search.h
|
||||
services/abstract/searchsnode.cpp
|
||||
services/abstract/searchsnode.h
|
||||
services/abstract/recyclebin.cpp
|
||||
services/abstract/recyclebin.h
|
||||
services/abstract/rootitem.cpp
|
||||
services/abstract/rootitem.h
|
||||
services/abstract/search.cpp
|
||||
services/abstract/search.h
|
||||
services/abstract/searchsnode.cpp
|
||||
services/abstract/searchsnode.h
|
||||
services/abstract/serviceentrypoint.h
|
||||
services/abstract/serviceroot.cpp
|
||||
services/abstract/serviceroot.h
|
||||
@ -317,6 +333,8 @@ set(SOURCES
|
||||
services/gmail/gmailnetworkfactory.h
|
||||
services/gmail/gmailserviceroot.cpp
|
||||
services/gmail/gmailserviceroot.h
|
||||
services/gmail/gui/emailpreviewer.cpp
|
||||
services/gmail/gui/emailpreviewer.h
|
||||
services/gmail/gui/emailrecipientcontrol.cpp
|
||||
services/gmail/gui/emailrecipientcontrol.h
|
||||
services/gmail/gui/formaddeditemail.cpp
|
||||
@ -325,8 +343,6 @@ set(SOURCES
|
||||
services/gmail/gui/formeditgmailaccount.h
|
||||
services/gmail/gui/gmailaccountdetails.cpp
|
||||
services/gmail/gui/gmailaccountdetails.h
|
||||
services/gmail/gui/emailpreviewer.h
|
||||
services/gmail/gui/emailpreviewer.cpp
|
||||
services/greader/definitions.h
|
||||
services/greader/greaderentrypoint.cpp
|
||||
services/greader/greaderentrypoint.h
|
||||
@ -367,6 +383,8 @@ set(SOURCES
|
||||
services/reddit/redditsubscription.cpp
|
||||
services/reddit/redditsubscription.h
|
||||
services/standard/definitions.h
|
||||
services/standard/gui/formdiscoverfeeds.cpp
|
||||
services/standard/gui/formdiscoverfeeds.h
|
||||
services/standard/gui/formeditstandardaccount.cpp
|
||||
services/standard/gui/formeditstandardaccount.h
|
||||
services/standard/gui/formstandardfeeddetails.cpp
|
||||
@ -375,10 +393,10 @@ set(SOURCES
|
||||
services/standard/gui/formstandardimportexport.h
|
||||
services/standard/gui/standardfeeddetails.cpp
|
||||
services/standard/gui/standardfeeddetails.h
|
||||
services/standard/parsers/feedparser.cpp
|
||||
services/standard/parsers/feedparser.h
|
||||
services/standard/parsers/atomparser.cpp
|
||||
services/standard/parsers/atomparser.h
|
||||
services/standard/parsers/feedparser.cpp
|
||||
services/standard/parsers/feedparser.h
|
||||
services/standard/parsers/jsonparser.cpp
|
||||
services/standard/parsers/jsonparser.h
|
||||
services/standard/parsers/rdfparser.cpp
|
||||
@ -417,22 +435,6 @@ set(SOURCES
|
||||
services/tt-rss/ttrssserviceentrypoint.h
|
||||
services/tt-rss/ttrssserviceroot.cpp
|
||||
services/tt-rss/ttrssserviceroot.h
|
||||
gui/reusable/discoverfeedsbutton.cpp
|
||||
gui/reusable/discoverfeedsbutton.h
|
||||
gui/reusable/locationlineedit.cpp
|
||||
gui/reusable/locationlineedit.h
|
||||
gui/webbrowser.cpp
|
||||
gui/webbrowser.h
|
||||
network-web/googlesuggest.cpp
|
||||
network-web/googlesuggest.h
|
||||
network-web/adblock/adblockdialog.cpp
|
||||
network-web/adblock/adblockdialog.h
|
||||
network-web/adblock/adblockicon.cpp
|
||||
network-web/adblock/adblockicon.h
|
||||
network-web/adblock/adblockmanager.cpp
|
||||
network-web/adblock/adblockmanager.h
|
||||
network-web/adblock/adblockrequestinfo.cpp
|
||||
network-web/adblock/adblockrequestinfo.h
|
||||
)
|
||||
|
||||
set(UI_FILES
|
||||
@ -440,21 +442,21 @@ set(UI_FILES
|
||||
gui/dialogs/formaddaccount.ui
|
||||
gui/dialogs/formbackupdatabasesettings.ui
|
||||
gui/dialogs/formdatabasecleanup.ui
|
||||
gui/dialogs/formmain.ui
|
||||
gui/dialogs/formlog.ui
|
||||
gui/dialogs/formmain.ui
|
||||
gui/dialogs/formmessagefiltersmanager.ui
|
||||
gui/dialogs/formrestoredatabasesettings.ui
|
||||
gui/dialogs/formsettings.ui
|
||||
gui/dialogs/formupdate.ui
|
||||
gui/itemdetails.ui
|
||||
gui/newspaperpreviewer.ui
|
||||
gui/notifications/articlelistnotification.ui
|
||||
gui/notifications/notificationseditor.ui
|
||||
gui/notifications/singlenotificationeditor.ui
|
||||
gui/notifications/articlelistnotification.ui
|
||||
gui/notifications/toastnotification.ui
|
||||
gui/reusable/networkproxydetails.ui
|
||||
gui/itemdetails.ui
|
||||
gui/richtexteditor/mrichtextedit.ui
|
||||
gui/newspaperpreviewer.ui
|
||||
gui/reusable/searchtextwidget.ui
|
||||
gui/richtexteditor/mrichtextedit.ui
|
||||
gui/settings/settingsbrowsermail.ui
|
||||
gui/settings/settingsdatabase.ui
|
||||
gui/settings/settingsdownloads.ui
|
||||
@ -462,44 +464,46 @@ set(UI_FILES
|
||||
gui/settings/settingsgeneral.ui
|
||||
gui/settings/settingsgui.ui
|
||||
gui/settings/settingslocalization.ui
|
||||
gui/settings/settingsnotifications.ui
|
||||
gui/settings/settingsnodejs.ui
|
||||
gui/settings/settingsnotifications.ui
|
||||
gui/settings/settingsshortcuts.ui
|
||||
gui/toolbars/toolbareditor.ui
|
||||
network-web/adblock/adblockdialog.ui
|
||||
network-web/downloaditem.ui
|
||||
network-web/downloadmanager.ui
|
||||
services/abstract/gui/authenticationdetails.ui
|
||||
services/abstract/gui/formaccountdetails.ui
|
||||
services/abstract/gui/formcategorydetails.ui
|
||||
services/abstract/gui/formfeeddetails.ui
|
||||
services/abstract/gui/formaddeditlabel.ui
|
||||
services/abstract/gui/formaddeditprobe.ui
|
||||
services/abstract/gui/formcategorydetails.ui
|
||||
services/abstract/gui/formfeeddetails.ui
|
||||
services/feedly/gui/feedlyaccountdetails.ui
|
||||
services/gmail/gui/emailpreviewer.ui
|
||||
services/gmail/gui/formaddeditemail.ui
|
||||
services/gmail/gui/gmailaccountdetails.ui
|
||||
services/gmail/gui/emailpreviewer.ui
|
||||
services/greader/gui/greaderaccountdetails.ui
|
||||
services/owncloud/gui/owncloudaccountdetails.ui
|
||||
services/reddit/gui/redditaccountdetails.ui
|
||||
services/standard/gui/formdiscoverfeeds.ui
|
||||
services/standard/gui/formstandardimportexport.ui
|
||||
services/standard/gui/standardfeeddetails.ui
|
||||
services/tt-rss/gui/formttrssnote.ui
|
||||
services/tt-rss/gui/ttrssaccountdetails.ui
|
||||
services/tt-rss/gui/ttrssfeeddetails.ui
|
||||
network-web/adblock/adblockdialog.ui)
|
||||
)
|
||||
|
||||
if(USE_WEBENGINE)
|
||||
list(APPEND SOURCES
|
||||
# WebEngine-based web (and message) browser.
|
||||
network-web/webengine/webenginepage.cpp
|
||||
network-web/webengine/webenginepage.h
|
||||
gui/webviewers/webengine/webengineviewer.cpp
|
||||
gui/webviewers/webengine/webengineviewer.h
|
||||
network-web/adblock/adblockurlinterceptor.cpp
|
||||
network-web/adblock/adblockurlinterceptor.h
|
||||
network-web/webengine/networkurlinterceptor.cpp
|
||||
network-web/webengine/networkurlinterceptor.h
|
||||
network-web/webengine/urlinterceptor.h
|
||||
network-web/adblock/adblockurlinterceptor.cpp
|
||||
network-web/adblock/adblockurlinterceptor.h
|
||||
network-web/webengine/webenginepage.cpp
|
||||
network-web/webengine/webenginepage.h
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "services/abstract/recyclebin.h"
|
||||
#include "services/abstract/serviceroot.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QCloseEvent>
|
||||
#include <QFileDialog>
|
||||
#include <QRect>
|
||||
@ -323,7 +324,7 @@ void FormMain::updateAddItemMenu() {
|
||||
|
||||
root_menu->addAction(action_new_feed);
|
||||
connect(action_new_feed, &QAction::triggered, activated_root, [activated_root]() {
|
||||
activated_root->addNewFeed(activated_root);
|
||||
activated_root->addNewFeed(activated_root, QGuiApplication::clipboard()->text(QClipboard::Mode::Clipboard));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -206,8 +206,8 @@ void MessagesView::copyUrlOfSelectedArticles() const {
|
||||
.toString();
|
||||
}
|
||||
|
||||
if (qApp->clipboard() != nullptr && !urls.isEmpty()) {
|
||||
qApp->clipboard()->setText(urls.join(TextFactory::newline()), QClipboard::Mode::Clipboard);
|
||||
if (QGuiApplication::clipboard() != nullptr && !urls.isEmpty()) {
|
||||
QGuiApplication::clipboard()->setText(urls.join(TextFactory::newline()), QClipboard::Mode::Clipboard);
|
||||
}
|
||||
}
|
||||
|
||||
|
210
src/librssguard/services/standard/gui/formdiscoverfeeds.cpp
Normal file
210
src/librssguard/services/standard/gui/formdiscoverfeeds.cpp
Normal file
@ -0,0 +1,210 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#include "services/standard/gui/formdiscoverfeeds.h"
|
||||
|
||||
#include "gui/guiutilities.h"
|
||||
#include "miscellaneous/application.h"
|
||||
#include "miscellaneous/iconfactory.h"
|
||||
#include "services/abstract/category.h"
|
||||
#include "services/abstract/serviceroot.h"
|
||||
#include "services/standard/standardfeed.h"
|
||||
|
||||
#include "services/standard/parsers/atomparser.h"
|
||||
#include "services/standard/parsers/jsonparser.h"
|
||||
#include "services/standard/parsers/rdfparser.h"
|
||||
#include "services/standard/parsers/rssparser.h"
|
||||
#include "services/standard/parsers/sitemapparser.h"
|
||||
|
||||
#include <QtConcurrentMap>
|
||||
|
||||
FormDiscoverFeeds::FormDiscoverFeeds(ServiceRoot* service_root,
|
||||
RootItem* parent_to_select,
|
||||
const QString& url,
|
||||
QWidget* parent)
|
||||
: QDialog(parent), m_serviceRoot(service_root), m_discoveredModel(new DiscoveredFeedsModel(this)) {
|
||||
m_ui.setupUi(this);
|
||||
|
||||
GuiUtilities::applyDialogProperties(*this, qApp->icons()->fromTheme(QSL("application-rss+xml")));
|
||||
|
||||
m_parsers = {new AtomParser({}), new RssParser({}), new RdfParser({}), new JsonParser({}), new SitemapParser({})};
|
||||
|
||||
m_btnImportSelectedFeeds =
|
||||
m_ui.m_buttonBox->addButton(tr("Import selected feeds"), QDialogButtonBox::ButtonRole::ActionRole);
|
||||
|
||||
m_btnImportSelectedFeeds->setIcon(qApp->icons()->fromTheme(QSL("document-import")));
|
||||
m_ui.m_btnDiscover->setIcon(qApp->icons()->fromTheme(QSL("system-search")));
|
||||
|
||||
connect(m_ui.m_txtUrl->lineEdit(), &QLineEdit::textChanged, this, &FormDiscoverFeeds::onUrlChanged);
|
||||
connect(m_btnImportSelectedFeeds, &QPushButton::clicked, this, &FormDiscoverFeeds::importSelectedFeeds);
|
||||
connect(m_ui.m_btnDiscover, &QPushButton::clicked, this, &FormDiscoverFeeds::discoverFeeds);
|
||||
|
||||
connect(&m_watcherLookup, &QFutureWatcher<QList<StandardFeed*>>::progressValueChanged, this, [=](int prog) {
|
||||
m_ui.m_pbDiscovery->setValue(prog);
|
||||
qDebugNN << "progress";
|
||||
});
|
||||
|
||||
connect(&m_watcherLookup, &QFutureWatcher<QList<StandardFeed*>>::finished, this, [=]() {
|
||||
auto res = m_watcherLookup.future().result();
|
||||
|
||||
loadDiscoveredFeeds(res);
|
||||
});
|
||||
|
||||
loadCategories(m_serviceRoot->getSubTreeCategories(), m_serviceRoot);
|
||||
|
||||
m_ui.m_tvFeeds->setModel(m_discoveredModel);
|
||||
|
||||
m_ui.m_tvFeeds->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeMode::Stretch);
|
||||
m_ui.m_tvFeeds->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeMode::ResizeToContents);
|
||||
|
||||
m_ui.m_pbDiscovery->setVisible(false);
|
||||
m_ui.m_txtUrl->lineEdit()->setText(url);
|
||||
|
||||
if (url.isEmpty()) {
|
||||
emit m_ui.m_txtUrl->lineEdit()->textChanged(url);
|
||||
}
|
||||
|
||||
m_ui.m_txtUrl->lineEdit()->selectAll();
|
||||
m_ui.m_txtUrl->setFocus();
|
||||
|
||||
if (parent_to_select != nullptr) {
|
||||
if (parent_to_select->kind() == RootItem::Kind::Category) {
|
||||
m_ui.m_cmbParentCategory
|
||||
->setCurrentIndex(m_ui.m_cmbParentCategory->findData(QVariant::fromValue((void*)parent_to_select)));
|
||||
}
|
||||
else if (parent_to_select->kind() == RootItem::Kind::Feed) {
|
||||
int target_item = m_ui.m_cmbParentCategory->findData(QVariant::fromValue((void*)parent_to_select->parent()));
|
||||
|
||||
if (target_item >= 0) {
|
||||
m_ui.m_cmbParentCategory->setCurrentIndex(target_item);
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_ui.m_cmbParentCategory->setCurrentIndex(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormDiscoverFeeds::~FormDiscoverFeeds() {
|
||||
qDeleteAll(m_parsers);
|
||||
}
|
||||
|
||||
void FormDiscoverFeeds::discoverFeeds() {
|
||||
QString url = m_ui.m_txtUrl->lineEdit()->text();
|
||||
|
||||
std::function<QList<StandardFeed*>(const FeedParser*)> func = [=](const FeedParser* parser) -> QList<StandardFeed*> {
|
||||
return parser->discoverFeeds(m_serviceRoot, url);
|
||||
};
|
||||
|
||||
std::function<QList<StandardFeed*>(QList<StandardFeed*>&, const QList<StandardFeed*>&)> reducer =
|
||||
[=](QList<StandardFeed*>& res, const QList<StandardFeed*>& interm) -> QList<StandardFeed*> {
|
||||
res.append(interm);
|
||||
return res;
|
||||
};
|
||||
|
||||
#if QT_VERSION_MAJOR == 5
|
||||
QFuture<QList<StandardFeed*>> fut = QtConcurrent::mappedReduced<QList<StandardFeed*>>(m_parsers, func, reducer);
|
||||
#else
|
||||
QFuture<QList<StandardFeed*>> fut =
|
||||
QtConcurrent::mappedReduced<QList<StandardFeed*>>(qApp->workHorsePool(), m_parsers, func, reducer);
|
||||
#endif
|
||||
|
||||
m_watcherLookup.setFuture(fut);
|
||||
|
||||
m_ui.m_pbDiscovery->setMaximum(m_parsers.size());
|
||||
m_ui.m_pbDiscovery->setValue(0);
|
||||
m_ui.m_pbDiscovery->setVisible(true);
|
||||
}
|
||||
|
||||
void FormDiscoverFeeds::onUrlChanged(const QString& new_url) {
|
||||
if (QUrl(new_url).isValid()) {
|
||||
m_ui.m_txtUrl->setStatus(WidgetWithStatus::StatusType::Ok, tr("URL is valid."));
|
||||
}
|
||||
else {
|
||||
m_ui.m_txtUrl->setStatus(WidgetWithStatus::StatusType::Error, tr("URL is NOT valid."));
|
||||
}
|
||||
}
|
||||
|
||||
void FormDiscoverFeeds::loadCategories(const QList<Category*>& categories, RootItem* root_item) {
|
||||
m_ui.m_cmbParentCategory->addItem(root_item->fullIcon(), root_item->title(), QVariant::fromValue((void*)root_item));
|
||||
|
||||
for (Category* category : categories) {
|
||||
m_ui.m_cmbParentCategory->addItem(category->fullIcon(), category->title(), QVariant::fromValue((void*)category));
|
||||
}
|
||||
}
|
||||
|
||||
void FormDiscoverFeeds::addSingleFeed(StandardFeed* feed) {
|
||||
/*
|
||||
QScopedPointer<FormStandardFeedDetails> form_pointer(new FormStandardFeedDetails(this,
|
||||
selected_item,
|
||||
feed->source(),
|
||||
qApp->mainFormWidget()));
|
||||
|
||||
form_pointer->addEditFeed<StandardFeed>();
|
||||
*/
|
||||
}
|
||||
|
||||
void FormDiscoverFeeds::importSelectedFeeds() {}
|
||||
|
||||
void FormDiscoverFeeds::loadDiscoveredFeeds(const QList<StandardFeed*>& feeds) {
|
||||
m_ui.m_pbDiscovery->setVisible(false);
|
||||
m_discoveredModel->setDiscoveredFeeds(feeds);
|
||||
|
||||
qDebugNN << "finish";
|
||||
}
|
||||
|
||||
DiscoveredFeedsModel::DiscoveredFeedsModel(QObject* parent) : QAbstractListModel(parent) {}
|
||||
|
||||
int DiscoveredFeedsModel::rowCount(const QModelIndex& parent) const {
|
||||
return m_discoveredFeeds.size();
|
||||
}
|
||||
|
||||
int DiscoveredFeedsModel::columnCount(const QModelIndex& parent) const {
|
||||
return 2;
|
||||
}
|
||||
|
||||
QVariant DiscoveredFeedsModel::data(const QModelIndex& index, int role) const {
|
||||
switch (role) {
|
||||
case Qt::ItemDataRole::DisplayRole: {
|
||||
if (index.column() == 0) {
|
||||
return m_discoveredFeeds.at(index.row())->title();
|
||||
}
|
||||
else {
|
||||
return StandardFeed::typeToString(m_discoveredFeeds.at(index.row())->type());
|
||||
}
|
||||
}
|
||||
|
||||
case Qt::ItemDataRole::DecorationRole: {
|
||||
if (index.column() == 0) {
|
||||
return m_discoveredFeeds.at(index.row())->fullIcon();
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
QList<StandardFeed*> DiscoveredFeedsModel::discoveredFeeds() const {
|
||||
return m_discoveredFeeds;
|
||||
}
|
||||
|
||||
void DiscoveredFeedsModel::setDiscoveredFeeds(const QList<StandardFeed*>& newDiscoveredFeeds) {
|
||||
m_discoveredFeeds = newDiscoveredFeeds;
|
||||
|
||||
emit layoutAboutToBeChanged();
|
||||
emit layoutChanged();
|
||||
}
|
||||
|
||||
QVariant DiscoveredFeedsModel::headerData(int section, Qt::Orientation orientation, int role) const {
|
||||
if (orientation == Qt::Orientation::Vertical) {
|
||||
return {};
|
||||
}
|
||||
|
||||
static QStringList headers = {tr("Title"), tr("Type")};
|
||||
|
||||
if (role == Qt::ItemDataRole::DisplayRole) {
|
||||
return headers.at(section);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
65
src/librssguard/services/standard/gui/formdiscoverfeeds.h
Normal file
65
src/librssguard/services/standard/gui/formdiscoverfeeds.h
Normal file
@ -0,0 +1,65 @@
|
||||
// For license of this file, see <project-root-folder>/LICENSE.md.
|
||||
|
||||
#ifndef FORMDISCOVERFEEDS_H
|
||||
#define FORMDISCOVERFEEDS_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
#include "ui_formdiscoverfeeds.h"
|
||||
|
||||
#include "services/standard/parsers/feedparser.h"
|
||||
|
||||
#include <QFutureWatcher>
|
||||
|
||||
class ServiceRoot;
|
||||
class RootItem;
|
||||
class Category;
|
||||
|
||||
class DiscoveredFeedsModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DiscoveredFeedsModel(QObject* parent = {});
|
||||
|
||||
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||
virtual int rowCount(const QModelIndex& parent) const;
|
||||
virtual int columnCount(const QModelIndex& parent) const;
|
||||
virtual QVariant data(const QModelIndex& index, int role) const;
|
||||
|
||||
QList<StandardFeed*> discoveredFeeds() const;
|
||||
void setDiscoveredFeeds(const QList<StandardFeed*>& newDiscoveredFeeds);
|
||||
|
||||
private:
|
||||
QList<StandardFeed*> m_discoveredFeeds;
|
||||
};
|
||||
|
||||
class FormDiscoverFeeds : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FormDiscoverFeeds(ServiceRoot* service_root,
|
||||
RootItem* parent_to_select = {},
|
||||
const QString& url = {},
|
||||
QWidget* parent = {});
|
||||
virtual ~FormDiscoverFeeds();
|
||||
|
||||
private slots:
|
||||
void discoverFeeds();
|
||||
void onUrlChanged(const QString& new_url);
|
||||
void addSingleFeed(StandardFeed* feed);
|
||||
void importSelectedFeeds();
|
||||
|
||||
private:
|
||||
void loadDiscoveredFeeds(const QList<StandardFeed*>& feeds);
|
||||
void loadCategories(const QList<Category*>& categories, RootItem* root_item);
|
||||
|
||||
private:
|
||||
Ui::FormDiscoverFeeds m_ui;
|
||||
QPushButton* m_btnImportSelectedFeeds;
|
||||
ServiceRoot* m_serviceRoot;
|
||||
QList<FeedParser*> m_parsers;
|
||||
QFutureWatcher<QList<StandardFeed*>> m_watcherLookup;
|
||||
DiscoveredFeedsModel* m_discoveredModel;
|
||||
};
|
||||
|
||||
#endif // FORMDISCOVERFEEDS_H
|
199
src/librssguard/services/standard/gui/formdiscoverfeeds.ui
Normal file
199
src/librssguard/services/standard/gui/formdiscoverfeeds.ui
Normal file
@ -0,0 +1,199 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FormDiscoverFeeds</class>
|
||||
<widget class="QDialog" name="FormDiscoverFeeds">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>406</width>
|
||||
<height>334</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Discover feeds</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>URL</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_txtUrl</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="LineEditWithStatus" name="m_txtUrl" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="m_btnDiscover">
|
||||
<property name="text">
|
||||
<string>Discover!</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="m_gbFeeds">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Discovered feeds</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QTableView" name="m_tvFeeds">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::SingleSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="cornerButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="horizontalHeaderVisible">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="horizontalHeaderStretchLastSection">
|
||||
<bool>true</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="m_lblParentCategory">
|
||||
<property name="text">
|
||||
<string>Target parent folder</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_cmbParentCategory</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QComboBox" name="m_cmbParentCategory">
|
||||
<property name="toolTip">
|
||||
<string>Select parent item for your feed.</string>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>12</width>
|
||||
<height>12</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="frame">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QProgressBar" name="m_pbDiscovery">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>5</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="m_buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>LineEditWithStatus</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>lineeditwithstatus.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>m_buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>FormDiscoverFeeds</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>m_buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>FormDiscoverFeeds</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -75,7 +75,7 @@ void FormStandardFeedDetails::apply() {
|
||||
StandardFeed::Type type =
|
||||
static_cast<StandardFeed::Type>(m_standardFeedDetails->m_ui.m_cmbType
|
||||
->itemData(m_standardFeedDetails->m_ui.m_cmbType->currentIndex())
|
||||
.value<int>());
|
||||
.toInt());
|
||||
|
||||
// Setup data for new_feed.
|
||||
std_feed->setTitle(m_standardFeedDetails->m_ui.m_txtTitle->lineEdit()->text().simplified());
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "services/abstract/category.h"
|
||||
#include "services/standard/definitions.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QFileDialog>
|
||||
#include <QImageReader>
|
||||
#include <QMenu>
|
||||
@ -251,30 +250,47 @@ void StandardFeedDetails::onDescriptionChanged(const QString& new_description) {
|
||||
}
|
||||
|
||||
void StandardFeedDetails::onUrlChanged(const QString& new_url) {
|
||||
if (sourceType() == StandardFeed::SourceType::Url) {
|
||||
if (QRegularExpression(QSL(URL_REGEXP)).match(new_url).hasMatch()) {
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Ok, tr("The URL is ok."));
|
||||
switch (sourceType()) {
|
||||
case StandardFeed::SourceType::Url: {
|
||||
if (QUrl(new_url).isValid()) {
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Ok, tr("The URL is ok."));
|
||||
}
|
||||
else if (!new_url.simplified().isEmpty()) {
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Warning,
|
||||
tr("The URL does not meet standard pattern. "
|
||||
"Does your URL start with \"http://\" or \"https://\" prefix."));
|
||||
}
|
||||
else {
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Error, tr("The URL is empty."));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else if (!new_url.simplified().isEmpty()) {
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Warning,
|
||||
tr("The URL does not meet standard pattern. "
|
||||
"Does your URL start with \"http://\" or \"https://\" prefix."));
|
||||
|
||||
case StandardFeed::SourceType::Script: {
|
||||
try {
|
||||
TextFactory::tokenizeProcessArguments(new_url);
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Ok, tr("Source is ok."));
|
||||
}
|
||||
catch (const ApplicationException& ex) {
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Error, tr("Error: %1").arg(ex.message()));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else {
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Error, tr("The URL is empty."));
|
||||
case StandardFeed::SourceType::LocalFile: {
|
||||
if (QFile::exists(new_url)) {
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Ok, tr("File exists."));
|
||||
}
|
||||
else {
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Error, tr("File does not exist."));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (sourceType() == StandardFeed::SourceType::Script) {
|
||||
try {
|
||||
TextFactory::tokenizeProcessArguments(new_url);
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Ok, tr("Source is ok."));
|
||||
}
|
||||
catch (const ApplicationException& ex) {
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Error, tr("Error: %1").arg(ex.message()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Ok, tr("The source is ok."));
|
||||
|
||||
default:
|
||||
m_ui.m_txtSource->setStatus(LineEditWithStatus::StatusType::Ok, tr("The source is ok."));
|
||||
}
|
||||
}
|
||||
|
||||
@ -358,9 +374,9 @@ void StandardFeedDetails::prepareForNewFeed(RootItem* parent_to_select, const QS
|
||||
if (!url.isEmpty()) {
|
||||
m_ui.m_txtSource->textEdit()->setPlainText(url);
|
||||
}
|
||||
else if (Application::clipboard()->mimeData()->hasText()) {
|
||||
/*else if (Application::clipboard()->mimeData()->hasText()) {
|
||||
m_ui.m_txtSource->textEdit()->setPlainText(Application::clipboard()->text());
|
||||
}
|
||||
}*/
|
||||
|
||||
m_ui.m_txtSource->setFocus();
|
||||
m_ui.m_txtSource->textEdit()->selectAll();
|
||||
|
@ -23,6 +23,10 @@ AtomParser::AtomParser(const QString& data) : FeedParser(data) {
|
||||
|
||||
AtomParser::~AtomParser() {}
|
||||
|
||||
QList<StandardFeed*> AtomParser::discoverFeeds(ServiceRoot* root, const QUrl& url) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
QPair<StandardFeed*, QList<IconLocation>> AtomParser::guessFeed(const QByteArray& content,
|
||||
const QString& content_type) const {
|
||||
QString xml_schema_encoding = QSL(DEFAULT_FEED_ENCODING);
|
||||
|
@ -15,6 +15,8 @@ class AtomParser : public FeedParser {
|
||||
explicit AtomParser(const QString& data);
|
||||
virtual ~AtomParser();
|
||||
|
||||
virtual QList<StandardFeed*> discoverFeeds(ServiceRoot* root, const QUrl& url) const;
|
||||
|
||||
virtual QPair<StandardFeed*, QList<IconLocation>> guessFeed(const QByteArray& content,
|
||||
const QString& content_type) const;
|
||||
|
||||
|
@ -41,7 +41,7 @@ FeedParser::FeedParser(QString data, bool is_xml)
|
||||
|
||||
FeedParser::~FeedParser() {}
|
||||
|
||||
QStringList FeedParser::discoverFeeds(const QUrl& url) const {
|
||||
QList<StandardFeed*> FeedParser::discoverFeeds(ServiceRoot* root, const QUrl& url) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -11,8 +11,7 @@
|
||||
|
||||
#include "core/message.h"
|
||||
#include "definitions/typedefs.h"
|
||||
|
||||
class StandardFeed;
|
||||
#include "services/standard/standardfeed.h"
|
||||
|
||||
// Base class for all XML-based feed parsers.
|
||||
class FeedParser {
|
||||
@ -21,7 +20,7 @@ class FeedParser {
|
||||
virtual ~FeedParser();
|
||||
|
||||
// Returns list of absolute URLs of discovered feeds from provided base URL.
|
||||
virtual QStringList discoverFeeds(const QUrl& url) const;
|
||||
virtual QList<StandardFeed*> discoverFeeds(ServiceRoot* root, const QUrl& url) const;
|
||||
|
||||
// Guesses feed.
|
||||
virtual QPair<StandardFeed*, QList<IconLocation>> guessFeed(const QByteArray& content,
|
||||
|
@ -18,6 +18,10 @@ JsonParser::JsonParser(const QString& data) : FeedParser(data, false) {}
|
||||
|
||||
JsonParser::~JsonParser() {}
|
||||
|
||||
QList<StandardFeed*> JsonParser::discoverFeeds(ServiceRoot* root, const QUrl& url) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
QPair<StandardFeed*, QList<IconLocation>> JsonParser::guessFeed(const QByteArray& content,
|
||||
const QString& content_type) const {
|
||||
if (content_type.contains(QSL("json"), Qt::CaseSensitivity::CaseInsensitive) ||
|
||||
|
@ -12,6 +12,8 @@ class JsonParser : public FeedParser {
|
||||
explicit JsonParser(const QString& data);
|
||||
virtual ~JsonParser();
|
||||
|
||||
virtual QList<StandardFeed*> discoverFeeds(ServiceRoot* root, const QUrl& url) const;
|
||||
|
||||
virtual QPair<StandardFeed*, QList<IconLocation>> guessFeed(const QByteArray& content,
|
||||
const QString& content_type) const;
|
||||
|
||||
|
@ -17,6 +17,10 @@ RdfParser::RdfParser(const QString& data)
|
||||
|
||||
RdfParser::~RdfParser() {}
|
||||
|
||||
QList<StandardFeed*> RdfParser::discoverFeeds(ServiceRoot* root, const QUrl& url) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
QPair<StandardFeed*, QList<IconLocation>> RdfParser::guessFeed(const QByteArray& content,
|
||||
const QString& content_type) const {
|
||||
QString xml_schema_encoding = QSL(DEFAULT_FEED_ENCODING);
|
||||
|
@ -14,6 +14,8 @@ class RdfParser : public FeedParser {
|
||||
explicit RdfParser(const QString& data);
|
||||
virtual ~RdfParser();
|
||||
|
||||
virtual QList<StandardFeed*> discoverFeeds(ServiceRoot* root, const QUrl& url) const;
|
||||
|
||||
virtual QPair<StandardFeed*, QList<IconLocation>> guessFeed(const QByteArray& content,
|
||||
const QString& content_type) const;
|
||||
|
||||
|
@ -3,7 +3,10 @@
|
||||
#include "services/standard/parsers/rssparser.h"
|
||||
|
||||
#include "exceptions/applicationexception.h"
|
||||
#include "miscellaneous/application.h"
|
||||
#include "miscellaneous/settings.h"
|
||||
#include "miscellaneous/textfactory.h"
|
||||
#include "network-web/networkfactory.h"
|
||||
#include "services/standard/definitions.h"
|
||||
#include "services/standard/standardfeed.h"
|
||||
|
||||
@ -15,6 +18,89 @@ RssParser::RssParser(const QString& data) : FeedParser(data) {}
|
||||
|
||||
RssParser::~RssParser() {}
|
||||
|
||||
QList<StandardFeed*> RssParser::discoverFeeds(ServiceRoot* root, const QUrl& url) const {
|
||||
QList<StandardFeed*> feeds;
|
||||
|
||||
// Download URL.
|
||||
int timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt();
|
||||
QByteArray data;
|
||||
auto res = NetworkFactory::performNetworkOperation(url.toString(),
|
||||
timeout,
|
||||
{},
|
||||
data,
|
||||
QNetworkAccessManager::Operation::GetOperation,
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
root->networkProxy());
|
||||
|
||||
if (res.m_networkError == QNetworkReply::NetworkError::NoError) {
|
||||
// Parse result, might be HTML or directly the feed file.
|
||||
try {
|
||||
auto guessed_feed = guessFeed(data, res.m_contentType);
|
||||
|
||||
guessed_feed.first->setSource(url.toString());
|
||||
|
||||
return {guessed_feed.first};
|
||||
}
|
||||
catch (...) {
|
||||
qDebugNN << LOGSEC_CORE << QUOTE_W_SPACE(url) << "is not a direct feed file.";
|
||||
}
|
||||
|
||||
QRegularExpression rx(QSL(FEED_REGEX_MATCHER), QRegularExpression::PatternOption::CaseInsensitiveOption);
|
||||
QRegularExpression rx_href(QSL(FEED_HREF_REGEX_MATCHER), QRegularExpression::PatternOption::CaseInsensitiveOption);
|
||||
|
||||
rx_href.optimize();
|
||||
|
||||
QRegularExpressionMatchIterator it_rx = rx.globalMatch(QString::fromUtf8(data));
|
||||
|
||||
while (it_rx.hasNext()) {
|
||||
QRegularExpressionMatch mat_tx = it_rx.next();
|
||||
QString link_tag = mat_tx.captured();
|
||||
QString feed_link = rx_href.match(link_tag).captured(1);
|
||||
|
||||
if (feed_link.startsWith(QL1S("//"))) {
|
||||
feed_link = QSL(URI_SCHEME_HTTP) + feed_link.mid(2);
|
||||
}
|
||||
else if (feed_link.startsWith(QL1C('/'))) {
|
||||
feed_link = url.toString(QUrl::UrlFormattingOption::RemovePath | QUrl::UrlFormattingOption::RemoveQuery |
|
||||
QUrl::UrlFormattingOption::StripTrailingSlash) +
|
||||
feed_link;
|
||||
}
|
||||
|
||||
QByteArray data;
|
||||
auto res = NetworkFactory::performNetworkOperation(feed_link,
|
||||
timeout,
|
||||
{},
|
||||
data,
|
||||
QNetworkAccessManager::Operation::GetOperation,
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
root->networkProxy());
|
||||
|
||||
if (res.m_networkError == QNetworkReply::NetworkError::NoError) {
|
||||
// Parse result, might be HTML or directly the feed file.
|
||||
try {
|
||||
auto guessed_feed = guessFeed(data, res.m_contentType);
|
||||
|
||||
guessed_feed.first->setSource(url.toString());
|
||||
|
||||
feeds.append(guessed_feed.first);
|
||||
}
|
||||
catch (const ApplicationException& ex) {
|
||||
qDebugNN << LOGSEC_CORE << QUOTE_W_SPACE(url)
|
||||
<< " should be direct link to feed file but was not recognized:" << QUOTE_W_SPACE_DOT(ex.message());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return feeds;
|
||||
}
|
||||
|
||||
QPair<StandardFeed*, QList<IconLocation>> RssParser::guessFeed(const QByteArray& content,
|
||||
const QString& content_type) const {
|
||||
QString xml_schema_encoding = QSL(DEFAULT_FEED_ENCODING);
|
||||
|
@ -14,6 +14,8 @@ class RssParser : public FeedParser {
|
||||
explicit RssParser(const QString& data);
|
||||
virtual ~RssParser();
|
||||
|
||||
virtual QList<StandardFeed*> discoverFeeds(ServiceRoot* root, const QUrl& url) const;
|
||||
|
||||
virtual QPair<StandardFeed*, QList<IconLocation>> guessFeed(const QByteArray& content,
|
||||
const QString& content_type) const;
|
||||
|
||||
|
@ -20,6 +20,10 @@ SitemapParser::SitemapParser(const QString& data) : FeedParser(data) {}
|
||||
|
||||
SitemapParser::~SitemapParser() {}
|
||||
|
||||
QList<StandardFeed*> SitemapParser::discoverFeeds(ServiceRoot* root, const QUrl& url) const {
|
||||
return {};
|
||||
}
|
||||
|
||||
QPair<StandardFeed*, QList<IconLocation>> SitemapParser::guessFeed(const QByteArray& content,
|
||||
const QString& content_type) const {
|
||||
QByteArray uncompressed_content;
|
||||
|
@ -12,6 +12,8 @@ class SitemapParser : public FeedParser {
|
||||
explicit SitemapParser(const QString& data);
|
||||
virtual ~SitemapParser();
|
||||
|
||||
virtual QList<StandardFeed*> discoverFeeds(ServiceRoot* root, const QUrl& url) const;
|
||||
|
||||
virtual QPair<StandardFeed*, QList<IconLocation>> guessFeed(const QByteArray& content,
|
||||
const QString& content_type) const;
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "network-web/networkfactory.h"
|
||||
#include "services/abstract/gui/formcategorydetails.h"
|
||||
#include "services/standard/definitions.h"
|
||||
#include "services/standard/gui/formdiscoverfeeds.h"
|
||||
#include "services/standard/gui/formeditstandardaccount.h"
|
||||
#include "services/standard/gui/formstandardfeeddetails.h"
|
||||
#include "services/standard/gui/formstandardimportexport.h"
|
||||
@ -33,7 +34,6 @@
|
||||
#endif
|
||||
|
||||
#include <QAction>
|
||||
#include <QClipboard>
|
||||
#include <QSqlTableModel>
|
||||
#include <QStack>
|
||||
#include <QTextCodec>
|
||||
@ -135,12 +135,22 @@ void StandardServiceRoot::addNewFeed(RootItem* selected_item, const QString& url
|
||||
return;
|
||||
}
|
||||
|
||||
QScopedPointer<FormDiscoverFeeds> form_discover(new FormDiscoverFeeds(this,
|
||||
selected_item,
|
||||
url,
|
||||
qApp->mainFormWidget()));
|
||||
|
||||
form_discover->exec();
|
||||
|
||||
/*
|
||||
QScopedPointer<FormStandardFeedDetails> form_pointer(new FormStandardFeedDetails(this,
|
||||
selected_item,
|
||||
url,
|
||||
qApp->mainFormWidget()));
|
||||
|
||||
form_pointer->addEditFeed<StandardFeed>();
|
||||
*/
|
||||
|
||||
qApp->feedUpdateLock()->unlock();
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "services/tt-rss/ttrssnetworkfactory.h"
|
||||
#include "services/tt-rss/ttrssserviceroot.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QMimeData>
|
||||
#include <QTimer>
|
||||
|
||||
@ -69,9 +68,11 @@ void FormTtRssFeedDetails::loadFeedData() {
|
||||
if (!m_urlToProcess.isEmpty()) {
|
||||
m_feedDetails->ui.m_txtUrl->lineEdit()->setText(m_urlToProcess);
|
||||
}
|
||||
/*
|
||||
else if (Application::clipboard()->mimeData()->hasText()) {
|
||||
m_feedDetails->ui.m_txtUrl->lineEdit()->setText(Application::clipboard()->text());
|
||||
}
|
||||
*/
|
||||
|
||||
m_feedDetails->ui.m_txtUrl->lineEdit()->selectAll();
|
||||
m_feedDetails->ui.m_txtUrl->setFocus();
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "services/tt-rss/ttrssnetworkfactory.h"
|
||||
#include "services/tt-rss/ttrssserviceentrypoint.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QPair>
|
||||
#include <QSqlTableModel>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user