Work on gmail attachments.
This commit is contained in:
parent
b69a615136
commit
fc1f821144
@ -88,6 +88,7 @@
|
||||
#define INTERNAL_URL_BLANK "http://rssguard.blank"
|
||||
#define INTERNAL_URL_MESSAGE_HOST "rssguard.message"
|
||||
#define INTERNAL_URL_BLANK_HOST "rssguard.blank"
|
||||
#define INTERNAL_URL_PASSATTACHMENT "http://rssguard.passattachment"
|
||||
|
||||
#define FEED_INITIAL_OPML_PATTERN "feeds-%1.opml"
|
||||
|
||||
|
@ -41,28 +41,28 @@ void FormAbout::loadSettingsAndPaths() {
|
||||
|
||||
void FormAbout::loadLicenseAndInformation() {
|
||||
try {
|
||||
m_ui.m_txtLicenseGnu->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")));
|
||||
m_ui.m_txtLicenseGnu->setText(IOFactory::readFile(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")));
|
||||
}
|
||||
catch (...) {
|
||||
m_ui.m_txtLicenseGnu->setText(tr("License not found."));
|
||||
}
|
||||
|
||||
try {
|
||||
m_ui.m_txtLicenseGnu->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")));
|
||||
m_ui.m_txtLicenseGnu->setText(IOFactory::readFile(APP_INFO_PATH + QL1S("/COPYING_GNU_GPL_HTML")));
|
||||
}
|
||||
catch (...) {
|
||||
m_ui.m_txtLicenseGnu->setText(tr("License not found."));
|
||||
}
|
||||
|
||||
try {
|
||||
m_ui.m_txtChangelog->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/CHANGELOG")));
|
||||
m_ui.m_txtChangelog->setText(IOFactory::readFile(APP_INFO_PATH + QL1S("/CHANGELOG")));
|
||||
}
|
||||
catch (...) {
|
||||
m_ui.m_txtChangelog->setText(tr("Changelog not found."));
|
||||
}
|
||||
|
||||
try {
|
||||
m_ui.m_txtLicenseBsd->setText(IOFactory::readTextFile(APP_INFO_PATH + QL1S("/COPYING_BSD")));
|
||||
m_ui.m_txtLicenseBsd->setText(IOFactory::readFile(APP_INFO_PATH + QL1S("/COPYING_BSD")));
|
||||
}
|
||||
catch (...) {
|
||||
m_ui.m_txtLicenseBsd->setText(tr("License not found."));
|
||||
|
@ -110,7 +110,7 @@ void WebBrowser::loadMessages(const QList<Message>& messages, RootItem* root) {
|
||||
m_root = root;
|
||||
|
||||
if (!m_root.isNull()) {
|
||||
m_webView->loadMessages(messages);
|
||||
m_webView->loadMessages(messages, root);
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
#include <QWheelEvent>
|
||||
|
||||
WebViewer::WebViewer(QWidget* parent) : QWebEngineView(parent) {
|
||||
WebViewer::WebViewer(QWidget* parent) : QWebEngineView(parent), m_root(nullptr) {
|
||||
WebPage* page = new WebPage(this);
|
||||
|
||||
connect(page, &WebPage::messageStatusChangeRequested, this, &WebViewer::messageStatusChangeRequested);
|
||||
@ -70,7 +70,7 @@ bool WebViewer::resetWebPageZoom() {
|
||||
}
|
||||
}
|
||||
|
||||
void WebViewer::loadMessages(const QList<Message>& messages) {
|
||||
void WebViewer::loadMessages(const QList<Message>& messages, RootItem* root) {
|
||||
Skin skin = qApp->skins()->currentSkin();
|
||||
QString messages_layout;
|
||||
QString single_message_layout = skin.m_layoutMarkup;
|
||||
@ -80,7 +80,17 @@ void WebViewer::loadMessages(const QList<Message>& messages) {
|
||||
QString enclosure_images;
|
||||
|
||||
foreach (const Enclosure& enclosure, message.m_enclosures) {
|
||||
enclosures += skin.m_enclosureMarkup.arg(enclosure.m_url, tr("Attachment"), enclosure.m_mimeType);
|
||||
QString enc_url;
|
||||
|
||||
if (!enclosure.m_url.contains(QRegularExpression(QSL("^(http|ftp|\\/)")))) {
|
||||
enc_url = QString(INTERNAL_URL_PASSATTACHMENT) + QL1S("/?") + enclosure.m_url;
|
||||
}
|
||||
else {
|
||||
enc_url = enclosure.m_url;
|
||||
}
|
||||
|
||||
enclosures += skin.m_enclosureMarkup.arg(enc_url,
|
||||
tr("Attachment"), enclosure.m_mimeType);
|
||||
|
||||
if (enclosure.m_mimeType.startsWith(QSL("image/"))) {
|
||||
// Add thumbnail image.
|
||||
@ -106,6 +116,7 @@ void WebViewer::loadMessages(const QList<Message>& messages) {
|
||||
.arg(enclosure_images));
|
||||
}
|
||||
|
||||
m_root = root;
|
||||
m_messageContents = skin.m_layoutMarkupWrapper.arg(messages.size() == 1 ? messages.at(0).m_title : tr("Newspaper view"),
|
||||
messages_layout);
|
||||
bool previously_enabled = isEnabled();
|
||||
@ -115,10 +126,6 @@ void WebViewer::loadMessages(const QList<Message>& messages) {
|
||||
setEnabled(previously_enabled);
|
||||
}
|
||||
|
||||
void WebViewer::loadMessage(const Message& message) {
|
||||
loadMessages(QList<Message>() << message);
|
||||
}
|
||||
|
||||
void WebViewer::clear() {
|
||||
bool previously_enabled = isEnabled();
|
||||
|
||||
@ -163,3 +170,7 @@ void WebViewer::wheelEvent(QWheelEvent* event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RootItem* WebViewer::root() const {
|
||||
return m_root;
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "core/message.h"
|
||||
#include "network-web/webpage.h"
|
||||
|
||||
class RootItem;
|
||||
|
||||
class WebViewer : public QWebEngineView {
|
||||
Q_OBJECT
|
||||
|
||||
@ -22,6 +24,7 @@ class WebViewer : public QWebEngineView {
|
||||
}
|
||||
|
||||
WebPage* page() const;
|
||||
RootItem* root() const;
|
||||
|
||||
public slots:
|
||||
|
||||
@ -31,8 +34,7 @@ class WebViewer : public QWebEngineView {
|
||||
bool resetWebPageZoom();
|
||||
|
||||
void displayMessage();
|
||||
void loadMessages(const QList<Message>& messages);
|
||||
void loadMessage(const Message& message);
|
||||
void loadMessages(const QList<Message>& messages, RootItem* root);
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
@ -45,6 +47,7 @@ class WebViewer : public QWebEngineView {
|
||||
void messageStatusChangeRequested(int message_id, WebPage::MessageStatusChange change);
|
||||
|
||||
private:
|
||||
RootItem* m_root;
|
||||
QString m_messageContents;
|
||||
};
|
||||
|
||||
|
@ -5,12 +5,12 @@
|
||||
#include "definitions/definitions.h"
|
||||
#include "exceptions/ioexception.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QObject>
|
||||
#include <QTemporaryFile>
|
||||
#include <QTextStream>
|
||||
|
||||
IOFactory::IOFactory() {}
|
||||
|
||||
@ -68,7 +68,7 @@ QString IOFactory::filterBadCharsFromFilename(const QString& name) {
|
||||
return value;
|
||||
}
|
||||
|
||||
QByteArray IOFactory::readTextFile(const QString& file_path) {
|
||||
QByteArray IOFactory::readFile(const QString& file_path) {
|
||||
QFile input_file(file_path);
|
||||
QByteArray input_data;
|
||||
|
||||
@ -82,15 +82,11 @@ QByteArray IOFactory::readTextFile(const QString& file_path) {
|
||||
}
|
||||
}
|
||||
|
||||
void IOFactory::writeTextFile(const QString& file_path, const QByteArray& data, const QString& encoding) {
|
||||
Q_UNUSED(encoding)
|
||||
void IOFactory::writeFile(const QString& file_path, const QByteArray& data) {
|
||||
QFile input_file(file_path);
|
||||
QTextStream stream(&input_file);
|
||||
|
||||
if (input_file.open(QIODevice::Text | QIODevice::WriteOnly)) {
|
||||
stream << data;
|
||||
stream.flush();
|
||||
input_file.flush();
|
||||
if (input_file.open(QIODevice::WriteOnly)) {
|
||||
input_file.write(data);
|
||||
input_file.close();
|
||||
}
|
||||
else {
|
||||
|
@ -30,8 +30,8 @@ class IOFactory {
|
||||
|
||||
// Returns contents of a file.
|
||||
// Throws exception when no such file exists.
|
||||
static QByteArray readTextFile(const QString& file_path);
|
||||
static void writeTextFile(const QString& file_path, const QByteArray& data, const QString& encoding = QSL("UTF-8"));
|
||||
static QByteArray readFile(const QString& file_path);
|
||||
static void writeFile(const QString& file_path, const QByteArray& data);
|
||||
|
||||
// Copies file, overwrites destination.
|
||||
static bool copyFile(const QString& source, const QString& destination);
|
||||
|
@ -122,17 +122,17 @@ Skin SkinFactory::skinInfo(const QString& skin_name, bool* ok) const {
|
||||
// So if one uses "##/images/border.png" in QSS then it is
|
||||
// replaced by fully absolute path and target file can
|
||||
// be safely loaded.
|
||||
skin.m_layoutMarkupWrapper = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_wrapper.html")));
|
||||
skin.m_layoutMarkupWrapper = QString::fromUtf8(IOFactory::readFile(skin_folder + QL1S("html_wrapper.html")));
|
||||
skin.m_layoutMarkupWrapper = skin.m_layoutMarkupWrapper.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
skin.m_enclosureImageMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_image.html")));
|
||||
skin.m_enclosureImageMarkup = QString::fromUtf8(IOFactory::readFile(skin_folder + QL1S("html_enclosure_image.html")));
|
||||
skin.m_enclosureImageMarkup = skin.m_enclosureImageMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
skin.m_layoutMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_single_message.html")));
|
||||
skin.m_layoutMarkup = QString::fromUtf8(IOFactory::readFile(skin_folder + QL1S("html_single_message.html")));
|
||||
skin.m_layoutMarkup = skin.m_layoutMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
skin.m_enclosureMarkup = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_enclosure_every.html")));
|
||||
skin.m_enclosureMarkup = QString::fromUtf8(IOFactory::readFile(skin_folder + QL1S("html_enclosure_every.html")));
|
||||
skin.m_enclosureMarkup = skin.m_enclosureMarkup.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
skin.m_rawData = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("theme.css")));
|
||||
skin.m_rawData = QString::fromUtf8(IOFactory::readFile(skin_folder + QL1S("theme.css")));
|
||||
skin.m_rawData = skin.m_rawData.replace(QSL("##"), APP_SKIN_PATH + QL1S("/") + skin_name);
|
||||
skin.m_adblocked = QString::fromUtf8(IOFactory::readTextFile(skin_folder + QL1S("html_adblocked.html")));
|
||||
skin.m_adblocked = QString::fromUtf8(IOFactory::readFile(skin_folder + QL1S("html_adblocked.html")));
|
||||
|
||||
if (ok != nullptr) {
|
||||
*ok = !skin.m_author.isEmpty() && !skin.m_version.isEmpty() &&
|
||||
|
@ -124,12 +124,12 @@ quint64 TextFactory::initializeSecretEncryptionKey() {
|
||||
QString encryption_file_path = qApp->settings()->pathName() + QDir::separator() + ENCRYPTION_FILE_NAME;
|
||||
|
||||
try {
|
||||
s_encryptionKey = (quint64) QString(IOFactory::readTextFile(encryption_file_path)).toLongLong();
|
||||
s_encryptionKey = (quint64) QString(IOFactory::readFile(encryption_file_path)).toLongLong();
|
||||
}
|
||||
catch (ApplicationException) {
|
||||
// Well, key does not exist or is invalid, generate and save one.
|
||||
s_encryptionKey = generateSecretEncryptionKey();
|
||||
IOFactory::writeTextFile(encryption_file_path, QString::number(s_encryptionKey).toLocal8Bit());
|
||||
IOFactory::writeFile(encryption_file_path, QString::number(s_encryptionKey).toLocal8Bit());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,7 +281,7 @@ void AdBlockCustomList::loadSubscription(const QStringList& disabledRules) {
|
||||
QString rules;
|
||||
|
||||
try {
|
||||
rules = QString::fromUtf8(IOFactory::readTextFile(filePath()));
|
||||
rules = QString::fromUtf8(IOFactory::readFile(filePath()));
|
||||
}
|
||||
catch (ApplicationException&) {}
|
||||
|
||||
|
@ -4,9 +4,12 @@
|
||||
|
||||
#include "definitions/definitions.h"
|
||||
#include "gui/webviewer.h"
|
||||
#include "services/abstract/rootitem.h"
|
||||
#include "services/abstract/serviceroot.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QUrl>
|
||||
|
||||
WebPage::WebPage(QObject* parent) : QWebEnginePage(parent) {
|
||||
setBackgroundColor(Qt::transparent);
|
||||
@ -45,6 +48,14 @@ void WebPage::javaScriptAlert(const QUrl& securityOrigin, const QString& msg) {
|
||||
}
|
||||
|
||||
bool WebPage::acceptNavigationRequest(const QUrl& url, NavigationType type, bool isMainFrame) {
|
||||
const RootItem* root = view()->root();
|
||||
|
||||
if (url.toString().startsWith(INTERNAL_URL_PASSATTACHMENT) &&
|
||||
root != nullptr &&
|
||||
root->getParentServiceRoot()->downloadAttachmentOnMyOwn(url)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (url.host() == INTERNAL_URL_MESSAGE_HOST) {
|
||||
setHtml(view()->messageContents(), QUrl(INTERNAL_URL_MESSAGE));
|
||||
return true;
|
||||
|
@ -61,6 +61,11 @@ RecycleBin* ServiceRoot::recycleBin() const {
|
||||
return m_recycleBin;
|
||||
}
|
||||
|
||||
bool ServiceRoot::downloadAttachmentOnMyOwn(const QUrl& url) const {
|
||||
Q_UNUSED(url)
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<QAction*> ServiceRoot::contextMenu() {
|
||||
return serviceMenu();
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ class ServiceRoot : public RootItem {
|
||||
bool deleteViaGui();
|
||||
bool markAsReadUnread(ReadStatus status);
|
||||
virtual RecycleBin* recycleBin() const;
|
||||
virtual bool downloadAttachmentOnMyOwn(const QUrl& url) const;
|
||||
|
||||
QList<Message> undeletedMessages() const;
|
||||
virtual bool supportsFeedAdding() const;
|
||||
|
@ -7,10 +7,13 @@
|
||||
#define GMAIL_OAUTH_TOKEN_URL "https://accounts.google.com/o/oauth2/token"
|
||||
#define GMAIL_OAUTH_SCOPE "https://mail.google.com/"
|
||||
|
||||
#define GMAIL_API_GET_ATTACHMENT "https://www.googleapis.com/gmail/v1/users/me/messages/%20/attachments/"
|
||||
#define GMAIL_API_LABELS_LIST "https://www.googleapis.com/gmail/v1/users/me/labels"
|
||||
#define GMAIL_API_MSGS_LIST "https://www.googleapis.com/gmail/v1/users/me/messages"
|
||||
#define GMAIL_API_BATCH "https://www.googleapis.com/batch"
|
||||
|
||||
#define GMAIL_ATTACHMENT_SEP "####"
|
||||
|
||||
#define GMAIL_DEFAULT_BATCH_SIZE 50
|
||||
#define GMAIL_MAX_BATCH_SIZE 999
|
||||
#define GMAIL_MIN_BATCH_SIZE 20
|
||||
|
@ -10,8 +10,12 @@
|
||||
#include "services/gmail/definitions.h"
|
||||
#include "services/gmail/gmailentrypoint.h"
|
||||
#include "services/gmail/gmailfeed.h"
|
||||
#include "services/gmail/gui/formeditgmailaccount.h"
|
||||
#include "services/gmail/network/gmailnetworkfactory.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
GmailServiceRoot::GmailServiceRoot(GmailNetworkFactory* network, RootItem* parent) : ServiceRoot(parent),
|
||||
CacheForServiceRoot(), m_serviceMenu(QList<QAction*>()), m_network(network) {
|
||||
if (network == nullptr) {
|
||||
@ -100,14 +104,36 @@ void GmailServiceRoot::saveAccountDataToDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
bool GmailServiceRoot::downloadAttachmentOnMyOwn(const QUrl& url) const {
|
||||
QString str_url = url.toString();
|
||||
QString attachment_id = str_url.mid(str_url.indexOf(QL1C('?')) + 1);
|
||||
QStringList parts = attachment_id.split(QL1S(GMAIL_ATTACHMENT_SEP));
|
||||
Downloader* down = network()->downloadAttachment(parts.at(1));
|
||||
|
||||
connect(down, &Downloader::completed, [parts, down](QNetworkReply::NetworkError status, QByteArray contents) {
|
||||
if (status == QNetworkReply::NetworkError::NoError) {
|
||||
QString data = QJsonDocument::fromJson(contents).object()["data"].toString();
|
||||
|
||||
if (!data.isEmpty()) {
|
||||
IOFactory::writeFile(parts.at(0), QByteArray::fromBase64(data.toLocal8Bit(),
|
||||
QByteArray::Base64Option::Base64UrlEncoding));
|
||||
}
|
||||
}
|
||||
|
||||
down->deleteLater();
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GmailServiceRoot::canBeEdited() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GmailServiceRoot::editViaGui() {
|
||||
//FormEditInoreaderAccount form_pointer(qApp->mainFormWidget());
|
||||
// TODO: dodělat
|
||||
//form_pointer.execForEdit(this);
|
||||
FormEditGmailAccount form_pointer(qApp->mainFormWidget());
|
||||
|
||||
form_pointer.execForEdit(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@ class GmailServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
||||
|
||||
void saveAccountDataToDatabase();
|
||||
|
||||
bool downloadAttachmentOnMyOwn(const QUrl& url) const;
|
||||
|
||||
void setNetwork(GmailNetworkFactory* network);
|
||||
GmailNetworkFactory* network() const;
|
||||
|
||||
|
@ -100,6 +100,22 @@ void GmailNetworkFactory::setUsername(const QString& username) {
|
||||
return decodeFeedCategoriesData(category_data);
|
||||
}*/
|
||||
|
||||
Downloader* GmailNetworkFactory::downloadAttachment(const QString& attachment_id) {
|
||||
Downloader* downloader = new Downloader();
|
||||
QString bearer = m_oauth2->bearer().toLocal8Bit();
|
||||
|
||||
if (bearer.isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString target_url = QString(GMAIL_API_GET_ATTACHMENT) + attachment_id;
|
||||
|
||||
downloader->appendRawHeader(QString(HTTP_HEADERS_AUTHORIZATION).toLocal8Bit(), bearer.toLocal8Bit());
|
||||
downloader->downloadFile(target_url);
|
||||
|
||||
return downloader;
|
||||
}
|
||||
|
||||
QList<Message> GmailNetworkFactory::messages(const QString& stream_id, Feed::Status& error) {
|
||||
Downloader downloader;
|
||||
QEventLoop loop;
|
||||
@ -402,9 +418,7 @@ bool GmailNetworkFactory::fillFullMessage(Message& msg, const QJsonObject& json,
|
||||
}
|
||||
else {
|
||||
// We have attachment.
|
||||
// TODO: pokračovat tady, přidat způsob jak dát userovi možnost
|
||||
// stahnout prilohy
|
||||
msg.m_enclosures.append(Enclosure(QL1S("##") + body["attachmentId"].toString(),
|
||||
msg.m_enclosures.append(Enclosure(filename + QL1S(GMAIL_ATTACHMENT_SEP) + body["attachmentId"].toString(),
|
||||
filename + QString(" (%1 KB)").arg(QString::number(body["size"].toInt() / 1000.0))));
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
class RootItem;
|
||||
class GmailServiceRoot;
|
||||
class OAuth2Service;
|
||||
class Downloader;
|
||||
|
||||
class GmailNetworkFactory : public QObject {
|
||||
Q_OBJECT
|
||||
@ -38,6 +39,8 @@ class GmailNetworkFactory : public QObject {
|
||||
// Returned items do not have primary IDs assigned.
|
||||
//RootItem* feedsCategories();
|
||||
|
||||
Downloader* downloadAttachment(const QString& attachment_id);
|
||||
|
||||
QList<Message> messages(const QString& stream_id, Feed::Status& error);
|
||||
void markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids, bool async = true);
|
||||
void markMessagesStarred(RootItem::Importance importance, const QStringList& custom_ids, bool async = true);
|
||||
|
@ -257,7 +257,7 @@ void FormStandardImportExport::exportFeeds() {
|
||||
|
||||
if (result_export) {
|
||||
try {
|
||||
IOFactory::writeTextFile(m_ui->m_lblSelectFile->label()->text(), result_data);
|
||||
IOFactory::writeFile(m_ui->m_lblSelectFile->label()->text(), result_data);
|
||||
m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Feeds were exported successfully."), tr("Feeds were exported successfully."));
|
||||
}
|
||||
catch (IOException& ex) {
|
||||
|
@ -63,7 +63,7 @@ void StandardServiceRoot::start(bool freshly_activated) {
|
||||
QString output_msg;
|
||||
|
||||
try {
|
||||
model.importAsOPML20(IOFactory::readTextFile(file_to_load), false);
|
||||
model.importAsOPML20(IOFactory::readFile(file_to_load), false);
|
||||
model.checkAllItems();
|
||||
|
||||
if (mergeImportExportModel(&model, this, output_msg)) {
|
||||
|
@ -225,7 +225,7 @@ TtRssGetHeadlinesResponse TtRssNetworkFactory::getHeadlines(int feed_id, int lim
|
||||
result = TtRssGetHeadlinesResponse(QString::fromUtf8(result_raw));
|
||||
}
|
||||
|
||||
IOFactory::writeTextFile("aaa", result_raw);
|
||||
IOFactory::writeFile("aaa", result_raw);
|
||||
|
||||
if (network_reply.first != QNetworkReply::NoError) {
|
||||
qWarning("TT-RSS: getHeadlines failed with error %d.", network_reply.first);
|
||||
|
Loading…
x
Reference in New Issue
Block a user