ubuntu-touch-coreapps-reviewers team mailing list archive
-
ubuntu-touch-coreapps-reviewers team
-
Mailing list archive
-
Message #03004
[Merge] lp:~mzanetti/reminders-app/fix-enable-push into lp:reminders-app
Michael Zanetti has proposed merging lp:~mzanetti/reminders-app/fix-enable-push into lp:reminders-app.
Commit message:
Fix the remaining issues in the push notification integration and enable it.
Requested reviews:
Ubuntu Reminders app developers (reminders-app-dev)
For more details, see:
https://code.launchpad.net/~mzanetti/reminders-app/fix-enable-push/+merge/262541
--
Your team Ubuntu Reminders app developers is requested to review the proposed merge of lp:~mzanetti/reminders-app/fix-enable-push into lp:reminders-app.
=== modified file 'src/account-plugin/qml/evernote/Main.qml.in'
--- src/account-plugin/qml/evernote/Main.qml.in 2015-02-20 21:18:01 +0000
+++ src/account-plugin/qml/evernote/Main.qml.in 2015-06-21 16:30:06 +0000
@@ -24,7 +24,7 @@
creationComponent: OAuth {
Connections {
target: UserStore
- onUsernameChanged: saveUsername()
+ onUserChanged: saveUsername()
}
function completeCreation(reply) {
@@ -37,7 +37,7 @@
}
function saveUsername() {
- account.updateDisplayName(UserStore.username)
+ account.updateDisplayName(UserStore.userName)
account.synced.connect(finished)
account.sync()
}
=== modified file 'src/app/preferences.cpp'
--- src/app/preferences.cpp 2015-02-23 18:00:46 +0000
+++ src/app/preferences.cpp 2015-06-21 16:30:06 +0000
@@ -80,3 +80,19 @@
m_settings.endGroup();
return colorName;
}
+
+QString Preferences::tokenForUser(const QString &user)
+{
+ QString token;
+ m_settings.beginGroup("accounts");
+ token = m_settings.value(user).toString();
+ m_settings.endGroup();
+ return token;
+}
+
+void Preferences::setTokenForUser(const QString &user, const QString &token)
+{
+ m_settings.beginGroup("accounts");
+ m_settings.setValue(user, token);
+ m_settings.endGroup();
+}
=== modified file 'src/app/preferences.h'
--- src/app/preferences.h 2015-03-06 00:47:45 +0000
+++ src/app/preferences.h 2015-06-21 16:30:06 +0000
@@ -45,6 +45,9 @@
Q_INVOKABLE QString colorForNotebook(const QString ¬ebookGuid);
+ Q_INVOKABLE QString tokenForUser(const QString &user);
+ Q_INVOKABLE void setTokenForUser(const QString &user, const QString &token);
+
signals:
void accountNameChanged();
void haveLocalUserChanged();
=== modified file 'src/app/qml/reminders.qml'
--- src/app/qml/reminders.qml 2015-06-12 09:48:22 +0000
+++ src/app/qml/reminders.qml 2015-06-21 16:30:06 +0000
@@ -280,9 +280,13 @@
}
function registerPushClient() {
- console.log("Registering push client");
+ console.log("Registering push client", JSON.stringify({
+ "userId" : "" + UserStore.userId,
+ "appId": root.applicationName + "_reminders",
+ "token": pushClient.token
+ }));
var req = new XMLHttpRequest();
- req.open("post", "http://162.213.35.108/register", true);
+ req.open("post", "https://push.ubuntu.com/gateway/register", true);
req.setRequestHeader("content-type", "application/json");
req.onreadystatechange = function() {//Call a function when the state changes.
print("push client register response")
@@ -295,7 +299,7 @@
}
}
req.send(JSON.stringify({
- "userId" : UserStore.username,
+ "userId" : "" + UserStore.userId,
"appId": root.applicationName + "_reminders",
"token": pushClient.token
}))
@@ -324,18 +328,30 @@
onNotificationsChanged: {
print("PushClient notification:", notifications)
var notification = JSON.parse(notifications)["payload"];
- print("user", notification["userId"])
- if (notification["userId"] !== UserStore.username) {
- console.warn("user mismatch:", notification["userId"], "!=", UserStore.username)
+
+ if (notification["userId"] != UserStore.userId) { // Yes, we want type coercion here.
+ console.warn("user mismatch:", notification["userId"], "!=", UserStore.userId)
return;
}
- if (notification["notebookGUID"] !== undefined) {
+ switch(notification["reason"]) {
+ case "update":
+ print("Note updated on server:", notification["guid"])
+ if (NotesStore.note(notification["guid"]) === null) {
+ NotesStore.refreshNotes();
+ } else {
+ NotesStore.refreshNoteContent(notification["guid"]);
+ }
+ break;
+ case "create":
+ print("New note appeared on server:", notification["guid"])
+ NotesStore.refreshNotes();
+ break;
+ case "notebook_update":
NotesStore.refreshNotebooks();
- NotesStore.refreshNotes(notification["notebookGUID"]);
- }
- if (notification["noteGUID"] !== undefined) {
- NotesStore.refreshNoteContent(notification["noteGUID"]);
+ break;
+ default:
+ console.warn("Unhandled push notification:", notification["reason"])
}
}
@@ -412,10 +428,10 @@
Connections {
target: UserStore
- onUsernameChanged: {
- print("Logged in as user:", UserStore.username);
- // Disabling push notifications as we haven't had a chance to properly test that yet
- //registerPushClient();
+ onUserChanged: {
+ print("Logged in as user:", UserStore.userId, UserStore.userName);
+ preferences.setTokenForUser(UserStore.userId, EvernoteConnection.token);
+ registerPushClient();
}
}
=== modified file 'src/libqtevernote/jobs/fetchusernamejob.cpp'
--- src/libqtevernote/jobs/fetchusernamejob.cpp 2014-09-19 21:31:39 +0000
+++ src/libqtevernote/jobs/fetchusernamejob.cpp 2015-06-21 16:30:06 +0000
@@ -42,12 +42,10 @@
void FetchUsernameJob::startJob()
{
- evernote::edam::User user;
- client()->getUser(user, token().toStdString());
- m_result = QString::fromStdString(user.username);
+ client()->getUser(m_user, token().toStdString());
}
void FetchUsernameJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
{
- emit jobDone(errorCode, errorMessage, m_result);
+ emit jobDone(errorCode, errorMessage, m_user.id, QString::fromStdString(m_user.username));
}
=== modified file 'src/libqtevernote/jobs/fetchusernamejob.h'
--- src/libqtevernote/jobs/fetchusernamejob.h 2014-09-19 21:31:39 +0000
+++ src/libqtevernote/jobs/fetchusernamejob.h 2015-06-21 16:30:06 +0000
@@ -33,14 +33,14 @@
virtual void attachToDuplicate(const EvernoteJob *other) override;
signals:
- void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &result);
+ void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const int userId, const QString &userName);
protected:
void startJob();
void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
private:
- QString m_result;
+ evernote::edam::User m_user;
};
#endif // FETCHUSERNAMEJOB_H
=== modified file 'src/libqtevernote/notesstore.cpp'
--- src/libqtevernote/notesstore.cpp 2015-06-12 09:48:22 +0000
+++ src/libqtevernote/notesstore.cpp 2015-06-21 16:30:06 +0000
@@ -61,7 +61,7 @@
m_tagsLoading(false)
{
qCDebug(dcNotesStore) << "Creating NotesStore instance.";
- connect(UserStore::instance(), &UserStore::usernameChanged, this, &NotesStore::userStoreConnected);
+ connect(UserStore::instance(), &UserStore::userChanged, this, &NotesStore::userStoreConnected);
qRegisterMetaType<evernote::edam::NotesMetadataList>("evernote::edam::NotesMetadataList");
qRegisterMetaType<evernote::edam::Note>("evernote::edam::Note");
@@ -98,7 +98,7 @@
// We don't accept an empty username.
return;
}
- if (!UserStore::instance()->username().isEmpty() && username != UserStore::instance()->username()) {
+ if (!UserStore::instance()->userName().isEmpty() && username != UserStore::instance()->userName()) {
qCWarning(dcNotesStore) << "Logged in to Evernote. Can't change account manually. User EvernoteConnection to log in to another account or log out and change this manually.";
return;
}
@@ -118,8 +118,9 @@
return QStandardPaths::standardLocations(QStandardPaths::DataLocation).first() + "/" + m_username + "/";
}
-void NotesStore::userStoreConnected(const QString &username)
+void NotesStore::userStoreConnected()
{
+ QString username = UserStore::instance()->userName();
qCDebug(dcNotesStore) << "User store connected! Using username:" << username;
setUsername(username);
@@ -738,10 +739,12 @@
connect(job, &SaveNoteJob::jobDone, this, &NotesStore::saveNoteJobDone);
EvernoteConnection::instance()->enqueue(job);
} else {
- qCWarning(dcSync) << "CONFLICT: Note has been changed on server and locally!";
- qCWarning(dcSync) << "local note sequence:" << note->updateSequenceNumber();
- qCWarning(dcSync) << "last synced sequence:" << note->lastSyncedSequenceNumber();
- qCWarning(dcSync) << "remote sequence:" << result.updateSequenceNum;
+ qCWarning(dcSync) << "********************************************************";
+ qCWarning(dcSync) << "* CONFLICT: Note has been changed on server and locally!";
+ qCWarning(dcSync) << "* local note sequence:" << note->updateSequenceNumber();
+ qCWarning(dcSync) << "* last synced sequence:" << note->lastSyncedSequenceNumber();
+ qCWarning(dcSync) << "* remote update sequence:" << result.updateSequenceNum;
+ qCWarning(dcSync) << "********************************************************";
note->setConflicting(true);
changedRoles << RoleConflicting;
@@ -826,19 +829,7 @@
if (note->synced()) {
qCDebug(dcSync) << "Note has been deleted from the server and not changed locally. Deleting local note:" << note->guid();
- beginRemoveRows(QModelIndex(), idx, idx);
- m_notes.removeAt(idx);
- m_notesHash.remove(note->guid());
- endRemoveRows();
- emit noteRemoved(note->guid(), note->notebookGuid());
- emit countChanged();
-
- QSettings settings(m_cacheFile, QSettings::IniFormat);
- settings.beginGroup("notes");
- settings.remove(note->guid());
- settings.endGroup();
-
- note->deleteLater();
+ removeNote(note->guid());
} else {
qCDebug(dcSync) << "CONFLICT: Note has been deleted from the server but we have unsynced local changes for note:" << note->guid();
FetchNoteJob::LoadWhatFlags flags = 0x0;
@@ -902,6 +893,12 @@
return;
}
+ if (result.deleted > 0) {
+ qCDebug(dcSync) << "Note has been deleted on server. Deleting locally.";
+ removeNote(note->guid());
+ return;
+ }
+
if (note->notebookGuid() != QString::fromStdString(result.notebookGuid)) {
note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
roles << RoleGuid;
@@ -914,6 +911,18 @@
note->setUpdated(QDateTime::fromMSecsSinceEpoch(result.updated));
roles << RoleUpdated << RoleUpdatedString;
}
+ QStringList tagGuids;
+ for (quint32 i = 0; i < result.tagGuids.size(); i++) {
+ QString tag = QString::fromStdString(result.tagGuids.at(i));
+ if (m_tagsHash.contains(tag)) {
+ refreshTags();
+ }
+ tagGuids << tag;
+ }
+ if (note->tagGuids() != tagGuids) {
+ note->setTagGuids(tagGuids);
+ roles << RoleTagGuids;
+ }
// Notes are fetched without resources by default. if we discover one or more resources where we don't have
// data in the cache, let's refresh the note again with resource data.
@@ -948,11 +957,14 @@
if (what == FetchNoteJob::LoadContent) {
note->setEnmlContent(QString::fromStdString(result.content));
note->setUpdateSequenceNumber(result.updateSequenceNum);
+ note->setLastSyncedSequenceNumber(result.updateSequenceNum);
roles << RoleHtmlContent << RoleEnmlContent << RoleTagline << RolePlaintextContent;
}
+ bool syncReminders = false;
if (note->reminderOrder() != result.attributes.reminderOrder) {
note->setReminderOrder(result.attributes.reminderOrder);
roles << RoleReminder;
+ syncReminders = true;
}
QDateTime reminderTime;
if (result.attributes.reminderTime > 0) {
@@ -961,6 +973,7 @@
if (note->reminderTime() != reminderTime) {
note->setReminderTime(reminderTime);
roles << RoleReminderTime << RoleReminderTimeString;
+ syncReminders = true;
}
QDateTime reminderDoneTime;
if (result.attributes.reminderDoneTime > 0) {
@@ -969,6 +982,10 @@
if (note->reminderDoneTime() != reminderDoneTime) {
note->setReminderDoneTime(reminderDoneTime);
roles << RoleReminderDone << RoleReminderDoneTime;
+ syncReminders = true;
+ }
+ if (syncReminders) {
+ m_organizerAdapter->startSync();
}
note->setLoading(false);
@@ -1456,14 +1473,7 @@
int idx = m_notes.indexOf(note);
if (note->lastSyncedSequenceNumber() == 0) {
- emit noteRemoved(note->guid(), note->notebookGuid());
- beginRemoveRows(QModelIndex(), idx, idx);
- m_notes.takeAt(idx);
- m_notesHash.take(guid);
- endRemoveRows();
- emit countChanged();
- deleteFromCacheFile(note);
- note->deleteLater();
+ removeNote(guid);
} else {
qCDebug(dcNotesStore) << "Setting note to deleted:" << note->guid();
@@ -1516,18 +1526,7 @@
qCWarning(dcSync) << "Cannot delete note from server:" << errorMessage;
return;
}
- Note *note = m_notesHash.value(guid);
- int noteIndex = m_notes.indexOf(note);
-
- emit noteRemoved(guid, note->notebookGuid());
-
- beginRemoveRows(QModelIndex(), noteIndex, noteIndex);
- m_notes.takeAt(noteIndex);
- m_notesHash.take(guid);
- endRemoveRows();
- emit countChanged();
- deleteFromCacheFile(note);
- note->deleteLater();
+ removeNote(guid);
}
void NotesStore::expungeNotebookJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid)
@@ -1786,6 +1785,26 @@
return true;
}
+void NotesStore::removeNote(const QString &guid)
+{
+ Note *note = m_notesHash.value(guid);
+ int idx = m_notes.indexOf(note);
+
+ emit noteRemoved(note->guid(), note->notebookGuid());
+
+ beginRemoveRows(QModelIndex(), idx, idx);
+ m_notes.removeAt(idx);
+ m_notesHash.remove(note->guid());
+ endRemoveRows();
+ emit countChanged();
+
+ QSettings settings(m_cacheFile, QSettings::IniFormat);
+ settings.beginGroup("notes");
+ settings.remove(note->guid());
+ settings.endGroup();
+
+ note->deleteLater();
+}
void NotesStore::expungeTag(const QString &guid)
{
=== modified file 'src/libqtevernote/notesstore.h'
--- src/libqtevernote/notesstore.h 2015-06-11 18:55:24 +0000
+++ src/libqtevernote/notesstore.h 2015-06-21 16:30:06 +0000
@@ -205,7 +205,7 @@
void syncToCacheFile(Tag *tag);
void loadFromCacheFile();
- void userStoreConnected(const QString &username);
+ void userStoreConnected();
void emitDataChanged();
void clear();
@@ -215,6 +215,8 @@
bool handleUserError(EvernoteConnection::ErrorCode errorCode);
+ void removeNote(const QString &guid);
+
private:
explicit NotesStore(QObject *parent = 0);
static NotesStore *s_instance;
=== modified file 'src/libqtevernote/userstore.cpp'
--- src/libqtevernote/userstore.cpp 2015-03-06 00:47:45 +0000
+++ src/libqtevernote/userstore.cpp 2015-06-21 16:30:06 +0000
@@ -57,9 +57,13 @@
return s_instance;
}
-QString UserStore::username() const
-{
- return m_username;
+qint32 UserStore::userId() const
+{
+ return m_userId;
+}
+QString UserStore::userName() const
+{
+ return m_userName;
}
void UserStore::fetchUsername()
@@ -69,18 +73,21 @@
connect(job, &FetchUsernameJob::jobDone, this, &UserStore::fetchUsernameJobDone);
EvernoteConnection::instance()->enqueue(job);
} else {
- m_username.clear();
- emit usernameChanged(m_username);
+ m_userId = -1;
+ m_userName.clear();
+ emit userChanged();
}
}
-void UserStore::fetchUsernameJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &result)
+void UserStore::fetchUsernameJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const int userId, const QString &userName)
{
if (errorCode != EvernoteConnection::ErrorCodeNoError) {
qCWarning(dcConnection) << "Error fetching username:" << errorMessage;
return;
}
- m_username = result;
- emit usernameChanged(m_username);
+ qCDebug(dcConnection) << "FetchUsername done. User ID:" << userId << "User name:" << userName;
+ m_userId = userId;
+ m_userName = userName;
+ emit userChanged();
}
=== modified file 'src/libqtevernote/userstore.h'
--- src/libqtevernote/userstore.h 2014-12-08 10:25:48 +0000
+++ src/libqtevernote/userstore.h 2015-06-21 16:30:06 +0000
@@ -33,26 +33,29 @@
Q_OBJECT
// TODO: Once we need more than just the username, turn this into a class User
- Q_PROPERTY(QString username READ username NOTIFY usernameChanged)
+ Q_PROPERTY(qint32 userId READ userId NOTIFY userChanged)
+ Q_PROPERTY(QString userName READ userName NOTIFY userChanged)
public:
static UserStore* instance();
- QString username() const;
+ qint32 userId() const;
+ QString userName() const;
signals:
- void usernameChanged(const QString &username);
+ void userChanged();
private slots:
void fetchUsername();
- void fetchUsernameJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &result);
+ void fetchUsernameJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const int userId, const QString &userName);
private:
static UserStore* s_instance;
explicit UserStore(QObject *parent = 0);
- QString m_username;
+ qint32 m_userId;
+ QString m_userName;
};
#endif // USERSTORE_H
=== modified file 'src/push-helper/core.cpp'
--- src/push-helper/core.cpp 2014-12-08 10:25:48 +0000
+++ src/push-helper/core.cpp 2015-06-21 16:30:06 +0000
@@ -4,35 +4,48 @@
#include "notesstore.h"
#include "note.h"
+#include <Accounts/Manager>
+#include <Accounts/AccountService>
+
#include <QDebug>
#include <QOrganizerEvent>
+#include <QStandardPaths>
+#include <QJsonDocument>
Core::Core(QObject *parent):
QObject(parent)
{
- qDebug() << "Core starting up";
connect(EvernoteConnection::instance(), &EvernoteConnection::isConnectedChanged, this, &Core::connectedChanged);
- qDebug() << "EvernoteConnection created";
connect(NotesStore::instance(), &NotesStore::loadingChanged, this, &Core::notesLoaded);
- qDebug() << "notestore created";
-// connect(&m_oaSetup, &OnlineAccountsClient::Setup::finished, this, &Core::oaRequestFinished);
-
-
-// m_oaSetup.setApplicationId("com.ubuntu.reminders_reminders");
-// m_oaSetup.setServiceTypeId("evernote");
-// m_oaSetup.exec();
-// qDebug() << "OA request started";
-
- EvernoteConnection::instance()->setToken("S=s358:U=39eb980:E=1516e9a3575:C=14a16e90690:P=185:A=canonicalis:V=2:H=737f36850d4943e61ff2fcf7b4c809e2");
+}
+
+bool Core::process(const QByteArray &pushNotification)
+{
+ qDebug() << "should process:" << pushNotification;
+
+ QJsonParseError error;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(pushNotification, &error);
+ if (error.error != QJsonParseError::NoError) {
+ qDebug() << "Error parsing notification json:" << error.errorString();
+ return false;
+ }
+ QVariantMap notification = jsonDoc.toVariant().toMap().value("payload").toMap();
+
+ QSettings settings(QStandardPaths::standardLocations(QStandardPaths::ConfigLocation).first() + "/com.ubuntu.reminders/reminders.conf", QSettings::IniFormat);
+ settings.beginGroup("accounts");
+ QString token = settings.value(notification.value("userId").toString()).toString();
+ settings.endGroup();
+
+ if (token.isEmpty()) {
+ qDebug() << "No token found for this userId in " + settings.fileName() + ". Discarding push notification...";
+ return false;
+ }
+
+ EvernoteConnection::instance()->setToken(token);
EvernoteConnection::instance()->setHostname("www.evernote.com");
EvernoteConnection::instance()->connectToEvernote();
- qDebug() << "Core created";
-}
-
-void Core::process(const QByteArray &pushNotification)
-{
- qDebug() << "should process:" << pushNotification;
+ return true;
}
void Core::connectedChanged()
@@ -48,13 +61,5 @@
void Core::notesLoaded()
{
qDebug() << "notes loading changed:" << NotesStore::instance()->loading();
- foreach (Note *note, NotesStore::instance()->notes()) {
- qDebug() << "have note" << note->title();
- qDebug() << "content:" << note->plaintextContent();
- }
}
-void Core::oaRequestFinished(const QVariantMap &reply)
-{
- qDebug() << "OA reply" << reply;
-}
=== modified file 'src/push-helper/core.h'
--- src/push-helper/core.h 2014-12-14 02:40:47 +0000
+++ src/push-helper/core.h 2015-06-21 16:30:06 +0000
@@ -9,7 +9,7 @@
public:
Core(QObject *parent = 0);
- void process(const QByteArray &pushNotification);
+ bool process(const QByteArray &pushNotification);
signals:
=== modified file 'src/push-helper/main.cpp'
--- src/push-helper/main.cpp 2014-12-06 22:35:01 +0000
+++ src/push-helper/main.cpp 2015-06-21 16:30:06 +0000
@@ -23,6 +23,7 @@
Core core;
QObject::connect(&core, &Core::finished, &a, &QCoreApplication::exit);
+
core.process(data);
a.exec();
Follow ups