Work on loading of gmail messages.

This commit is contained in:
Martin Rotter 2017-10-19 10:43:34 +02:00
parent 5d51b8d28d
commit b072d41d84
8 changed files with 82 additions and 27 deletions

View File

@ -136,7 +136,13 @@ bool FeedsProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right
// Moreover, sort everything alphabetically or
// by item counts, depending on the sort column.
if (left_item->kind() == right_item->kind()) {
if (left_item->keepOnTop()) {
return sortOrder() == Qt::AscendingOrder;
}
else if (right_item->keepOnTop()) {
return sortOrder() == Qt::DescendingOrder;
}
else if (left_item->kind() == right_item->kind()) {
// Both items are feeds or both items are categories.
if (left.column() == FDS_MODEL_COUNTS_INDEX) {
// User wants to sort according to counts.

View File

@ -13,7 +13,7 @@
RootItem::RootItem(RootItem* parent_item)
: QObject(nullptr), m_kind(RootItemKind::Root), m_id(NO_PARENT_CATEGORY), m_customId(QSL("")),
m_title(QString()), m_description(QString()), m_icon(QIcon()), m_creationDate(QDateTime()),
m_childItems(QList<RootItem*>()), m_parentItem(parent_item) {}
m_keepOnTop(false), m_childItems(QList<RootItem*>()), m_parentItem(parent_item) {}
RootItem::RootItem(const RootItem& other) : RootItem(nullptr) {
setTitle(other.title());
@ -438,6 +438,14 @@ ServiceRoot* RootItem::toServiceRoot() const {
return static_cast<ServiceRoot*>(const_cast<RootItem*>(this));
}
bool RootItem::keepOnTop() const {
return m_keepOnTop;
}
void RootItem::setKeepOnTop(bool keep_on_top) {
m_keepOnTop = keep_on_top;
}
int RootItem::countOfUnreadMessages() const {
int total_count = 0;

View File

@ -54,6 +54,7 @@ class RootItem : public QObject {
explicit RootItem(const RootItem& other);
virtual ~RootItem();
// Determines if this item should be kept always in the beginning of feeds list.
virtual QString hashCode() const;
virtual QString additionalTooltip() const;
@ -202,6 +203,9 @@ class RootItem : public QObject {
Feed* toFeed() const;
ServiceRoot* toServiceRoot() const;
bool keepOnTop() const;
void setKeepOnTop(bool keep_on_top);
private:
RootItemKind::Kind m_kind;
int m_id;
@ -210,6 +214,7 @@ class RootItem : public QObject {
QString m_description;
QIcon m_icon;
QDateTime m_creationDate;
bool m_keepOnTop;
QList<RootItem*> m_childItems;
RootItem* m_parentItem;

View File

@ -8,6 +8,7 @@
#define GMAIL_OAUTH_SCOPE "https://mail.google.com/"
#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_DEFAULT_BATCH_SIZE 100
#define GMAIL_MAX_BATCH_SIZE 999

View File

@ -23,15 +23,14 @@ GmailServiceRoot* GmailFeed::serviceRoot() const {
QList<Message> GmailFeed::obtainNewMessages(bool* error_during_obtaining) {
Feed::Status error;
QList<Message> messages = serviceRoot()->network()->messages(customId(), error);
// TODO: dodělat
QList<Message> messages;/* = serviceRoot()->network()->messages(customId(), error);
setStatus(error);
setStatus(error);
if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError) {
* error_during_obtaining = true;
}*/
if (error == Feed::Status::NetworkError || error == Feed::Status::AuthError ||
error == Feed::Status::ParsingError) {
*error_during_obtaining = true;
}
return messages;
}

View File

@ -48,7 +48,11 @@ void GmailServiceRoot::updateTitle() {
}
void GmailServiceRoot::loadFromDatabase() {
appendChild(new GmailFeed(tr("Inbox"), QSL("INBOX"), qApp->icons()->fromTheme(QSL("mail-inbox")), this));
GmailFeed* inbox = new GmailFeed(tr("Inbox"), QSL("INBOX"), qApp->icons()->fromTheme(QSL("mail-inbox")), this);
inbox->setKeepOnTop(true);
appendChild(inbox);
appendChild(new GmailFeed(tr("Sent"), QSL("SENT"), qApp->icons()->fromTheme(QSL("mail-sent")), this));
appendChild(new GmailFeed(tr("Drafts"), QSL("DRAFT"), qApp->icons()->fromTheme(QSL("gtk-edit")), this));
appendChild(new GmailFeed(tr("Spam"), QSL("SPAM"), qApp->icons()->fromTheme(QSL("mail-mark-junk")), this));

View File

@ -101,33 +101,60 @@ void GmailNetworkFactory::setUsername(const QString& username) {
QList<Message> GmailNetworkFactory::messages(const QString& stream_id, Feed::Status& error) {
Downloader downloader;
QEventLoop loop;
QString target_url;// TODO: dodělat
// = INOREADER_API_FEED_CONTENTS;
QString bearer = m_oauth2->bearer().toLocal8Bit();
QString next_page_token;
QList<Message> messages;
if (bearer.isEmpty()) {
error = Feed::Status::AuthError;
return QList<Message>();
}
target_url += QSL("/") + QUrl::toPercentEncoding(stream_id) + QString("?n=%1").arg(batchSize());
downloader.appendRawHeader(QString("Authorization").toLocal8Bit(), bearer.toLocal8Bit());
downloader.appendRawHeader(QString(HTTP_HEADERS_AUTHORIZATION).toLocal8Bit(), bearer.toLocal8Bit());
// We need to quit event loop when the download finishes.
connect(&downloader, &Downloader::completed, &loop, &QEventLoop::quit);
downloader.manipulateData(target_url, QNetworkAccessManager::Operation::GetOperation);
loop.exec();
QString target_url;
if (downloader.lastOutputError() != QNetworkReply::NetworkError::NoError) {
error = Feed::Status::NetworkError;
return QList<Message>();
}
else {
QString messages_data = downloader.lastOutputData();
do {
target_url = GMAIL_API_MSGS_LIST;
target_url += QString("?labelIds=%1").arg(stream_id);
error = Feed::Status::Normal;
return decodeMessages(messages_data, stream_id);
}
if (batchSize() > 0) {
target_url += QString("&maxResults=%1").arg(batchSize());
}
if (!next_page_token.isEmpty()) {
target_url += QString("&pageToken=%1").arg(next_page_token);
}
downloader.manipulateData(target_url, QNetworkAccessManager::Operation::GetOperation);
loop.exec();
if (downloader.lastOutputError() == QNetworkReply::NetworkError::NoError) {
// We parse this chunk.
QString messages_data = downloader.lastOutputData();
QList<Message> more_messages = decodeLiteMessages(messages_data, stream_id);
// Now, we via batch HTTP request obtain full data for each message.
bool obtained = obtainAndDecodeFullMessages(more_messages);
if (obtained) {
messages.append(more_messages);
error = Feed::Status::NetworkError;
return messages;
}
}
else {
error = Feed::Status::NetworkError;
return messages;
}
} while (!next_page_token.isEmpty());
error = Feed::Status::Normal;
return messages;
}
void GmailNetworkFactory::markMessagesRead(RootItem::ReadStatus status, const QStringList& custom_ids, bool async) {
@ -292,7 +319,11 @@ void GmailNetworkFactory::onAuthFailed() {
});
}
QList<Message> GmailNetworkFactory::decodeMessages(const QString& messages_json_data, const QString& stream_id) {
bool GmailNetworkFactory::obtainAndDecodeFullMessages(const QList<Message>& lite_messages) {
return false;
}
QList<Message> GmailNetworkFactory::decodeLiteMessages(const QString& messages_json_data, const QString& stream_id) {
QList<Message> messages;
QJsonArray json = QJsonDocument::fromJson(messages_json_data.toUtf8()).object()["items"].toArray();

View File

@ -47,7 +47,8 @@ class GmailNetworkFactory : public QObject {
void onAuthFailed();
private:
QList<Message> decodeMessages(const QString& messages_json_data, const QString& stream_id);
bool obtainAndDecodeFullMessages(const QList<Message>& lite_messages);
QList<Message> decodeLiteMessages(const QString& messages_json_data, const QString& stream_id);
//RootItem* decodeFeedCategoriesData(const QString& categories);