Work on gmail attachments.

This commit is contained in:
Martin Rotter 2017-10-23 13:04:57 +02:00
parent b69a615136
commit fc1f821144
21 changed files with 119 additions and 43 deletions

View file

@ -88,6 +88,7 @@
#define INTERNAL_URL_BLANK "http://rssguard.blank" #define INTERNAL_URL_BLANK "http://rssguard.blank"
#define INTERNAL_URL_MESSAGE_HOST "rssguard.message" #define INTERNAL_URL_MESSAGE_HOST "rssguard.message"
#define INTERNAL_URL_BLANK_HOST "rssguard.blank" #define INTERNAL_URL_BLANK_HOST "rssguard.blank"
#define INTERNAL_URL_PASSATTACHMENT "http://rssguard.passattachment"
#define FEED_INITIAL_OPML_PATTERN "feeds-%1.opml" #define FEED_INITIAL_OPML_PATTERN "feeds-%1.opml"

View file

@ -41,28 +41,28 @@ void FormAbout::loadSettingsAndPaths() {
void FormAbout::loadLicenseAndInformation() { void FormAbout::loadLicenseAndInformation() {
try { 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 (...) { catch (...) {
m_ui.m_txtLicenseGnu->setText(tr("License not found.")); m_ui.m_txtLicenseGnu->setText(tr("License not found."));
} }
try { 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 (...) { catch (...) {
m_ui.m_txtLicenseGnu->setText(tr("License not found.")); m_ui.m_txtLicenseGnu->setText(tr("License not found."));
} }
try { 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 (...) { catch (...) {
m_ui.m_txtChangelog->setText(tr("Changelog not found.")); m_ui.m_txtChangelog->setText(tr("Changelog not found."));
} }
try { 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 (...) { catch (...) {
m_ui.m_txtLicenseBsd->setText(tr("License not found.")); m_ui.m_txtLicenseBsd->setText(tr("License not found."));

View file

@ -110,7 +110,7 @@ void WebBrowser::loadMessages(const QList<Message>& messages, RootItem* root) {
m_root = root; m_root = root;
if (!m_root.isNull()) { if (!m_root.isNull()) {
m_webView->loadMessages(messages); m_webView->loadMessages(messages, root);
show(); show();
} }
} }

View file

@ -15,7 +15,7 @@
#include <QWheelEvent> #include <QWheelEvent>
WebViewer::WebViewer(QWidget* parent) : QWebEngineView(parent) { WebViewer::WebViewer(QWidget* parent) : QWebEngineView(parent), m_root(nullptr) {
WebPage* page = new WebPage(this); WebPage* page = new WebPage(this);
connect(page, &WebPage::messageStatusChangeRequested, this, &WebViewer::messageStatusChangeRequested); 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(); Skin skin = qApp->skins()->currentSkin();
QString messages_layout; QString messages_layout;
QString single_message_layout = skin.m_layoutMarkup; QString single_message_layout = skin.m_layoutMarkup;
@ -80,7 +80,17 @@ void WebViewer::loadMessages(const QList<Message>& messages) {
QString enclosure_images; QString enclosure_images;
foreach (const Enclosure& enclosure, message.m_enclosures) { 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/"))) { if (enclosure.m_mimeType.startsWith(QSL("image/"))) {
// Add thumbnail image. // Add thumbnail image.
@ -106,6 +116,7 @@ void WebViewer::loadMessages(const QList<Message>& messages) {
.arg(enclosure_images)); .arg(enclosure_images));
} }
m_root = root;
m_messageContents = skin.m_layoutMarkupWrapper.arg(messages.size() == 1 ? messages.at(0).m_title : tr("Newspaper view"), m_messageContents = skin.m_layoutMarkupWrapper.arg(messages.size() == 1 ? messages.at(0).m_title : tr("Newspaper view"),
messages_layout); messages_layout);
bool previously_enabled = isEnabled(); bool previously_enabled = isEnabled();
@ -115,10 +126,6 @@ void WebViewer::loadMessages(const QList<Message>& messages) {
setEnabled(previously_enabled); setEnabled(previously_enabled);
} }
void WebViewer::loadMessage(const Message& message) {
loadMessages(QList<Message>() << message);
}
void WebViewer::clear() { void WebViewer::clear() {
bool previously_enabled = isEnabled(); bool previously_enabled = isEnabled();
@ -163,3 +170,7 @@ void WebViewer::wheelEvent(QWheelEvent* event) {
} }
} }
} }
RootItem* WebViewer::root() const {
return m_root;
}

View file

@ -8,6 +8,8 @@
#include "core/message.h" #include "core/message.h"
#include "network-web/webpage.h" #include "network-web/webpage.h"
class RootItem;
class WebViewer : public QWebEngineView { class WebViewer : public QWebEngineView {
Q_OBJECT Q_OBJECT
@ -22,6 +24,7 @@ class WebViewer : public QWebEngineView {
} }
WebPage* page() const; WebPage* page() const;
RootItem* root() const;
public slots: public slots:
@ -31,8 +34,7 @@ class WebViewer : public QWebEngineView {
bool resetWebPageZoom(); bool resetWebPageZoom();
void displayMessage(); void displayMessage();
void loadMessages(const QList<Message>& messages); void loadMessages(const QList<Message>& messages, RootItem* root);
void loadMessage(const Message& message);
void clear(); void clear();
protected: protected:
@ -45,6 +47,7 @@ class WebViewer : public QWebEngineView {
void messageStatusChangeRequested(int message_id, WebPage::MessageStatusChange change); void messageStatusChangeRequested(int message_id, WebPage::MessageStatusChange change);
private: private:
RootItem* m_root;
QString m_messageContents; QString m_messageContents;
}; };

View file

@ -5,12 +5,12 @@
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include "exceptions/ioexception.h" #include "exceptions/ioexception.h"
#include <QDataStream>
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QFileInfo> #include <QFileInfo>
#include <QObject> #include <QObject>
#include <QTemporaryFile> #include <QTemporaryFile>
#include <QTextStream>
IOFactory::IOFactory() {} IOFactory::IOFactory() {}
@ -68,7 +68,7 @@ QString IOFactory::filterBadCharsFromFilename(const QString& name) {
return value; return value;
} }
QByteArray IOFactory::readTextFile(const QString& file_path) { QByteArray IOFactory::readFile(const QString& file_path) {
QFile input_file(file_path); QFile input_file(file_path);
QByteArray input_data; 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) { void IOFactory::writeFile(const QString& file_path, const QByteArray& data) {
Q_UNUSED(encoding)
QFile input_file(file_path); QFile input_file(file_path);
QTextStream stream(&input_file);
if (input_file.open(QIODevice::Text | QIODevice::WriteOnly)) { if (input_file.open(QIODevice::WriteOnly)) {
stream << data; input_file.write(data);
stream.flush();
input_file.flush();
input_file.close(); input_file.close();
} }
else { else {

View file

@ -30,8 +30,8 @@ class IOFactory {
// Returns contents of a file. // Returns contents of a file.
// Throws exception when no such file exists. // Throws exception when no such file exists.
static QByteArray readTextFile(const QString& file_path); static QByteArray readFile(const QString& file_path);
static void writeTextFile(const QString& file_path, const QByteArray& data, const QString& encoding = QSL("UTF-8")); static void writeFile(const QString& file_path, const QByteArray& data);
// Copies file, overwrites destination. // Copies file, overwrites destination.
static bool copyFile(const QString& source, const QString& destination); static bool copyFile(const QString& source, const QString& destination);

View file

@ -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 // So if one uses "##/images/border.png" in QSS then it is
// replaced by fully absolute path and target file can // replaced by fully absolute path and target file can
// be safely loaded. // 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_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_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_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_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_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) { if (ok != nullptr) {
*ok = !skin.m_author.isEmpty() && !skin.m_version.isEmpty() && *ok = !skin.m_author.isEmpty() && !skin.m_version.isEmpty() &&

View file

@ -124,12 +124,12 @@ quint64 TextFactory::initializeSecretEncryptionKey() {
QString encryption_file_path = qApp->settings()->pathName() + QDir::separator() + ENCRYPTION_FILE_NAME; QString encryption_file_path = qApp->settings()->pathName() + QDir::separator() + ENCRYPTION_FILE_NAME;
try { try {
s_encryptionKey = (quint64) QString(IOFactory::readTextFile(encryption_file_path)).toLongLong(); s_encryptionKey = (quint64) QString(IOFactory::readFile(encryption_file_path)).toLongLong();
} }
catch (ApplicationException) { catch (ApplicationException) {
// Well, key does not exist or is invalid, generate and save one. // Well, key does not exist or is invalid, generate and save one.
s_encryptionKey = generateSecretEncryptionKey(); s_encryptionKey = generateSecretEncryptionKey();
IOFactory::writeTextFile(encryption_file_path, QString::number(s_encryptionKey).toLocal8Bit()); IOFactory::writeFile(encryption_file_path, QString::number(s_encryptionKey).toLocal8Bit());
} }
} }

View file

@ -281,7 +281,7 @@ void AdBlockCustomList::loadSubscription(const QStringList& disabledRules) {
QString rules; QString rules;
try { try {
rules = QString::fromUtf8(IOFactory::readTextFile(filePath())); rules = QString::fromUtf8(IOFactory::readFile(filePath()));
} }
catch (ApplicationException&) {} catch (ApplicationException&) {}

View file

@ -4,9 +4,12 @@
#include "definitions/definitions.h" #include "definitions/definitions.h"
#include "gui/webviewer.h" #include "gui/webviewer.h"
#include "services/abstract/rootitem.h"
#include "services/abstract/serviceroot.h"
#include <QString> #include <QString>
#include <QStringList> #include <QStringList>
#include <QUrl>
WebPage::WebPage(QObject* parent) : QWebEnginePage(parent) { WebPage::WebPage(QObject* parent) : QWebEnginePage(parent) {
setBackgroundColor(Qt::transparent); 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) { 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) { if (url.host() == INTERNAL_URL_MESSAGE_HOST) {
setHtml(view()->messageContents(), QUrl(INTERNAL_URL_MESSAGE)); setHtml(view()->messageContents(), QUrl(INTERNAL_URL_MESSAGE));
return true; return true;

View file

@ -61,6 +61,11 @@ RecycleBin* ServiceRoot::recycleBin() const {
return m_recycleBin; return m_recycleBin;
} }
bool ServiceRoot::downloadAttachmentOnMyOwn(const QUrl& url) const {
Q_UNUSED(url)
return false;
}
QList<QAction*> ServiceRoot::contextMenu() { QList<QAction*> ServiceRoot::contextMenu() {
return serviceMenu(); return serviceMenu();
} }

View file

@ -33,6 +33,7 @@ class ServiceRoot : public RootItem {
bool deleteViaGui(); bool deleteViaGui();
bool markAsReadUnread(ReadStatus status); bool markAsReadUnread(ReadStatus status);
virtual RecycleBin* recycleBin() const; virtual RecycleBin* recycleBin() const;
virtual bool downloadAttachmentOnMyOwn(const QUrl& url) const;
QList<Message> undeletedMessages() const; QList<Message> undeletedMessages() const;
virtual bool supportsFeedAdding() const; virtual bool supportsFeedAdding() const;

View file

@ -7,10 +7,13 @@
#define GMAIL_OAUTH_TOKEN_URL "https://accounts.google.com/o/oauth2/token" #define GMAIL_OAUTH_TOKEN_URL "https://accounts.google.com/o/oauth2/token"
#define GMAIL_OAUTH_SCOPE "https://mail.google.com/" #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_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_MSGS_LIST "https://www.googleapis.com/gmail/v1/users/me/messages"
#define GMAIL_API_BATCH "https://www.googleapis.com/batch" #define GMAIL_API_BATCH "https://www.googleapis.com/batch"
#define GMAIL_ATTACHMENT_SEP "####"
#define GMAIL_DEFAULT_BATCH_SIZE 50 #define GMAIL_DEFAULT_BATCH_SIZE 50
#define GMAIL_MAX_BATCH_SIZE 999 #define GMAIL_MAX_BATCH_SIZE 999
#define GMAIL_MIN_BATCH_SIZE 20 #define GMAIL_MIN_BATCH_SIZE 20

View file

@ -10,8 +10,12 @@
#include "services/gmail/definitions.h" #include "services/gmail/definitions.h"
#include "services/gmail/gmailentrypoint.h" #include "services/gmail/gmailentrypoint.h"
#include "services/gmail/gmailfeed.h" #include "services/gmail/gmailfeed.h"
#include "services/gmail/gui/formeditgmailaccount.h"
#include "services/gmail/network/gmailnetworkfactory.h" #include "services/gmail/network/gmailnetworkfactory.h"
#include <QJsonDocument>
#include <QJsonObject>
GmailServiceRoot::GmailServiceRoot(GmailNetworkFactory* network, RootItem* parent) : ServiceRoot(parent), GmailServiceRoot::GmailServiceRoot(GmailNetworkFactory* network, RootItem* parent) : ServiceRoot(parent),
CacheForServiceRoot(), m_serviceMenu(QList<QAction*>()), m_network(network) { CacheForServiceRoot(), m_serviceMenu(QList<QAction*>()), m_network(network) {
if (network == nullptr) { 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 { bool GmailServiceRoot::canBeEdited() const {
return true; return true;
} }
bool GmailServiceRoot::editViaGui() { bool GmailServiceRoot::editViaGui() {
//FormEditInoreaderAccount form_pointer(qApp->mainFormWidget()); FormEditGmailAccount form_pointer(qApp->mainFormWidget());
// TODO: dodělat
//form_pointer.execForEdit(this); form_pointer.execForEdit(this);
return true; return true;
} }

View file

@ -17,6 +17,8 @@ class GmailServiceRoot : public ServiceRoot, public CacheForServiceRoot {
void saveAccountDataToDatabase(); void saveAccountDataToDatabase();
bool downloadAttachmentOnMyOwn(const QUrl& url) const;
void setNetwork(GmailNetworkFactory* network); void setNetwork(GmailNetworkFactory* network);
GmailNetworkFactory* network() const; GmailNetworkFactory* network() const;

View file

@ -100,6 +100,22 @@ void GmailNetworkFactory::setUsername(const QString& username) {
return decodeFeedCategoriesData(category_data); 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) { QList<Message> GmailNetworkFactory::messages(const QString& stream_id, Feed::Status& error) {
Downloader downloader; Downloader downloader;
QEventLoop loop; QEventLoop loop;
@ -402,9 +418,7 @@ bool GmailNetworkFactory::fillFullMessage(Message& msg, const QJsonObject& json,
} }
else { else {
// We have attachment. // We have attachment.
// TODO: pokračovat tady, přidat způsob jak dát userovi možnost msg.m_enclosures.append(Enclosure(filename + QL1S(GMAIL_ATTACHMENT_SEP) + body["attachmentId"].toString(),
// stahnout prilohy
msg.m_enclosures.append(Enclosure(QL1S("##") + body["attachmentId"].toString(),
filename + QString(" (%1 KB)").arg(QString::number(body["size"].toInt() / 1000.0)))); filename + QString(" (%1 KB)").arg(QString::number(body["size"].toInt() / 1000.0))));
} }
} }

View file

@ -15,6 +15,7 @@
class RootItem; class RootItem;
class GmailServiceRoot; class GmailServiceRoot;
class OAuth2Service; class OAuth2Service;
class Downloader;
class GmailNetworkFactory : public QObject { class GmailNetworkFactory : public QObject {
Q_OBJECT Q_OBJECT
@ -38,6 +39,8 @@ class GmailNetworkFactory : public QObject {
// Returned items do not have primary IDs assigned. // Returned items do not have primary IDs assigned.
//RootItem* feedsCategories(); //RootItem* feedsCategories();
Downloader* downloadAttachment(const QString& attachment_id);
QList<Message> messages(const QString& stream_id, Feed::Status& error); QList<Message> messages(const QString& stream_id, Feed::Status& error);
void markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids, bool async = true); void markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids, bool async = true);
void markMessagesStarred(RootItem::Importance importance, const QStringList& custom_ids, bool async = true); void markMessagesStarred(RootItem::Importance importance, const QStringList& custom_ids, bool async = true);

View file

@ -257,7 +257,7 @@ void FormStandardImportExport::exportFeeds() {
if (result_export) { if (result_export) {
try { 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.")); m_ui->m_lblResult->setStatus(WidgetWithStatus::Ok, tr("Feeds were exported successfully."), tr("Feeds were exported successfully."));
} }
catch (IOException& ex) { catch (IOException& ex) {

View file

@ -63,7 +63,7 @@ void StandardServiceRoot::start(bool freshly_activated) {
QString output_msg; QString output_msg;
try { try {
model.importAsOPML20(IOFactory::readTextFile(file_to_load), false); model.importAsOPML20(IOFactory::readFile(file_to_load), false);
model.checkAllItems(); model.checkAllItems();
if (mergeImportExportModel(&model, this, output_msg)) { if (mergeImportExportModel(&model, this, output_msg)) {

View file

@ -225,7 +225,7 @@ TtRssGetHeadlinesResponse TtRssNetworkFactory::getHeadlines(int feed_id, int lim
result = TtRssGetHeadlinesResponse(QString::fromUtf8(result_raw)); result = TtRssGetHeadlinesResponse(QString::fromUtf8(result_raw));
} }
IOFactory::writeTextFile("aaa", result_raw); IOFactory::writeFile("aaa", result_raw);
if (network_reply.first != QNetworkReply::NoError) { if (network_reply.first != QNetworkReply::NoError) {
qWarning("TT-RSS: getHeadlines failed with error %d.", network_reply.first); qWarning("TT-RSS: getHeadlines failed with error %d.", network_reply.first);