Merge lp:~mzanetti/reminders-app/notesdelegate into lp:reminders-app

Proposed by Michael Zanetti
Status: Superseded
Proposed branch: lp:~mzanetti/reminders-app/notesdelegate
Merge into: lp:reminders-app
Diff against target: 3403 lines (+1845/-702)
49 files modified
src/app/app.pro (+4/-1)
src/app/qml/components/NotesDelegate.qml (+56/-0)
src/app/qml/components/ToolbarSpacer.qml (+45/-0)
src/app/qml/reminders-app.qml (+8/-1)
src/app/qml/ui/AccountSelectorPage.qml (+1/-1)
src/app/qml/ui/NotePage.qml (+2/-0)
src/app/qml/ui/NotebooksPage.qml (+9/-0)
src/app/qml/ui/NotesPage.qml (+21/-7)
src/app/qml/ui/RemindersPage.qml (+9/-10)
src/app/qml/ui/SearchNotesPage.qml (+80/-0)
src/plugin/Evernote/Evernote.pro (+14/-2)
src/plugin/Evernote/evernoteconnection.cpp (+190/-0)
src/plugin/Evernote/evernoteconnection.h (+101/-0)
src/plugin/Evernote/evernoteplugin.cpp (+14/-2)
src/plugin/Evernote/jobs/createnotebookjob.cpp (+41/-0)
src/plugin/Evernote/jobs/createnotebookjob.h (+46/-0)
src/plugin/Evernote/jobs/createnotejob.cpp (+26/-32)
src/plugin/Evernote/jobs/createnotejob.h (+13/-8)
src/plugin/Evernote/jobs/deletenotejob.cpp (+9/-10)
src/plugin/Evernote/jobs/deletenotejob.h (+7/-5)
src/plugin/Evernote/jobs/evernotejob.cpp (+50/-17)
src/plugin/Evernote/jobs/evernotejob.h (+22/-8)
src/plugin/Evernote/jobs/expungenotebookjob.cpp (+39/-0)
src/plugin/Evernote/jobs/expungenotebookjob.h (+43/-0)
src/plugin/Evernote/jobs/fetchnotebooksjob.cpp (+13/-17)
src/plugin/Evernote/jobs/fetchnotebooksjob.h (+10/-5)
src/plugin/Evernote/jobs/fetchnotejob.cpp (+7/-17)
src/plugin/Evernote/jobs/fetchnotejob.h (+10/-4)
src/plugin/Evernote/jobs/fetchnotesjob.cpp (+27/-18)
src/plugin/Evernote/jobs/fetchnotesjob.h (+10/-6)
src/plugin/Evernote/jobs/fetchusernamejob.cpp (+38/-0)
src/plugin/Evernote/jobs/fetchusernamejob.h (+43/-0)
src/plugin/Evernote/jobs/notesstorejob.cpp (+39/-0)
src/plugin/Evernote/jobs/notesstorejob.h (+44/-0)
src/plugin/Evernote/jobs/savenotejob.cpp (+36/-33)
src/plugin/Evernote/jobs/savenotejob.h (+9/-5)
src/plugin/Evernote/jobs/userstorejob.cpp (+39/-0)
src/plugin/Evernote/jobs/userstorejob.h (+46/-0)
src/plugin/Evernote/note.cpp (+115/-11)
src/plugin/Evernote/note.h (+55/-4)
src/plugin/Evernote/notebooks.cpp (+0/-1)
src/plugin/Evernote/notes.cpp (+58/-80)
src/plugin/Evernote/notes.h (+17/-25)
src/plugin/Evernote/notesstore.cpp (+245/-231)
src/plugin/Evernote/notesstore.h (+53/-41)
src/plugin/Evernote/userstore.cpp (+38/-95)
src/plugin/Evernote/userstore.h (+19/-5)
src/plugin/Evernote/utils/html2enmlconverter.cpp (+22/-0)
src/plugin/Evernote/utils/html2enmlconverter.h (+2/-0)
To merge this branch: bzr merge lp:~mzanetti/reminders-app/notesdelegate
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Needs Fixing
Ubuntu Notes app developers Pending
Review via email: mp+199011@code.launchpad.net

This proposal has been superseded by a proposal from 2013-12-14.

Commit message

Added a NotesDelegate to roughly reflect design wireframe

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
25. By Michael Zanetti

don't automatically fetch notes content to avoid hitting the rate limit

26. By Michael Zanetti

merge prerequisite branch

27. By Michael Zanetti

added missing file

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/app/app.pro'
--- src/app/app.pro 2013-11-22 21:35:34 +0000
+++ src/app/app.pro 2013-12-14 00:07:45 +0000
@@ -10,7 +10,10 @@
10 qml/ui/RemindersPage.qml \10 qml/ui/RemindersPage.qml \
11 qml/ui/NotesPage.qml \11 qml/ui/NotesPage.qml \
12 qml/ui/AccountSelectorPage.qml \12 qml/ui/AccountSelectorPage.qml \
13 qml/ui/NotePage.qml13 qml/ui/NotePage.qml \
14 qml/ui/SearchNotesPage.qml \
15 qml/components/ToolbarSpacer.qml \
16 qml/components/NotesDelegate.qml \
1417
15# Copy qml to build dir for running with qtcreator18# Copy qml to build dir for running with qtcreator
16qmlfolder.source = src/app/qml19qmlfolder.source = src/app/qml
1720
=== added directory 'src/app/qml/components'
=== added file 'src/app/qml/components/NotesDelegate.qml'
--- src/app/qml/components/NotesDelegate.qml 1970-01-01 00:00:00 +0000
+++ src/app/qml/components/NotesDelegate.qml 2013-12-14 00:07:45 +0000
@@ -0,0 +1,56 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.0
20import Ubuntu.Components 0.1
21import Ubuntu.Components.ListItems 0.1
22
23Empty {
24 id: root
25 height: units.gu(9)
26
27 property string title
28 property date creationDate
29 property string content
30
31 Column {
32 id: contentColumn
33 spacing: units.gu(1)
34 anchors {
35 top: parent.top
36 topMargin: units.gu(1)
37 left: parent.left
38 leftMargin: units.gu(2)
39 right: parent.right
40 rightMargin: units.gu(2)
41 }
42 Label {
43 anchors { left: parent.left; right: parent.right }
44 text: root.title
45 font.bold: true
46 elide: Text.ElideRight
47 }
48 Label {
49 anchors { left: parent.left; right: parent.right }
50 text: "<font color=\"#dd4814\">"+ Qt.formatDate(root.creationDate) + "</font> " + root.content
51 wrapMode: Text.WordWrap
52 textFormat: Text.StyledText
53 maximumLineCount: 2
54 }
55 }
56}
057
=== added file 'src/app/qml/components/ToolbarSpacer.qml'
--- src/app/qml/components/ToolbarSpacer.qml 1970-01-01 00:00:00 +0000
+++ src/app/qml/components/ToolbarSpacer.qml 2013-12-14 00:07:45 +0000
@@ -0,0 +1,45 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.0
20import Ubuntu.Components 0.1
21import Ubuntu.Components.Popups 0.1
22
23Item {
24 id: spacerItem
25 objectName: "__ToolBarItems.SpacerItem"
26 height: parent.height
27 width: {
28 var othersWidth = 0;
29
30 // Hack: the autogenerated back button
31 if (pageStack != null && pageStack.depth > 1) {
32 othersWidth = units.gu(6)
33 }
34
35 for (var i = 0; i < parent.children.length; ++i) {
36 var otherItem = parent.children[i];
37 if (otherItem.objectName !== "__ToolBarItems.SpacerItem") {
38 if (otherItem.visible) {
39 othersWidth += otherItem.width + parent.spacing;
40 }
41 }
42 }
43 return parent.parent.width - othersWidth - units.gu(4);
44 }
45}
046
=== modified file 'src/app/qml/reminders-app.qml'
--- src/app/qml/reminders-app.qml 2013-11-26 17:18:33 +0000
+++ src/app/qml/reminders-app.qml 2013-12-14 00:07:45 +0000
@@ -47,11 +47,18 @@
4747
48 Component.onCompleted: {48 Component.onCompleted: {
49 pagestack.push(rootTabs)49 pagestack.push(rootTabs)
50 if (NotesStore.token.length === 0) {50 if (EvernoteConnection.token.length === 0) {
51 pagestack.push(Qt.resolvedUrl("ui/AccountSelectorPage.qml"));51 pagestack.push(Qt.resolvedUrl("ui/AccountSelectorPage.qml"));
52 }52 }
53 }53 }
5454
55 Connections {
56 target: UserStore
57 onUsernameChanged: {
58 print("Logged in as user:", UserStore.username)
59 }
60 }
61
55 PageStack {62 PageStack {
56 id: pagestack63 id: pagestack
5764
5865
=== modified file 'src/app/qml/ui/AccountSelectorPage.qml'
--- src/app/qml/ui/AccountSelectorPage.qml 2013-11-26 17:18:33 +0000
+++ src/app/qml/ui/AccountSelectorPage.qml 2013-12-14 00:07:45 +0000
@@ -51,7 +51,7 @@
51 // Print the access token on the console51 // Print the access token on the console
52 onAuthenticated: {52 onAuthenticated: {
53 console.log("Access token is " + reply.AccessToken)53 console.log("Access token is " + reply.AccessToken)
54 NotesStore.token = reply.AccessToken;54 EvernoteConnection.token = reply.AccessToken;
55 pagestack.pop();55 pagestack.pop();
56 }56 }
57 onAuthenticationError: { console.log("Authentication failed, code " + error.code) }57 onAuthenticationError: { console.log("Authentication failed, code " + error.code) }
5858
=== modified file 'src/app/qml/ui/NotePage.qml'
--- src/app/qml/ui/NotePage.qml 2013-11-26 17:18:33 +0000
+++ src/app/qml/ui/NotePage.qml 2013-12-14 00:07:45 +0000
@@ -24,6 +24,8 @@
24 title: note.title24 title: note.title
25 property var note25 property var note
2626
27 Component.onCompleted: NotesStore.refreshNoteContent(note.guid)
28
27 Column {29 Column {
28 anchors.fill: parent30 anchors.fill: parent
29 spacing: units.gu(1)31 spacing: units.gu(1)
3032
=== modified file 'src/app/qml/ui/NotebooksPage.qml'
--- src/app/qml/ui/NotebooksPage.qml 2013-11-26 17:18:33 +0000
+++ src/app/qml/ui/NotebooksPage.qml 2013-12-14 00:07:45 +0000
@@ -30,6 +30,15 @@
30 }30 }
31 }31 }
3232
33 tools: ToolbarItems {
34 ToolbarButton {
35 text: "add notebook"
36 onTriggered: {
37 NotesStore.createNotebook("new notebook");
38 }
39 }
40 }
41
33 Notebooks {42 Notebooks {
34 id: notebooks43 id: notebooks
35 }44 }
3645
=== modified file 'src/app/qml/ui/NotesPage.qml'
--- src/app/qml/ui/NotesPage.qml 2013-11-26 17:18:33 +0000
+++ src/app/qml/ui/NotesPage.qml 2013-12-14 00:07:45 +0000
@@ -20,6 +20,7 @@
20import Ubuntu.Components 0.120import Ubuntu.Components 0.1
21import Ubuntu.Components.ListItems 0.121import Ubuntu.Components.ListItems 0.1
22import Evernote 0.122import Evernote 0.1
23import "../components"
2324
24Page {25Page {
25 id: notesPage26 id: notesPage
@@ -28,14 +29,23 @@
2829
29 onActiveChanged: {30 onActiveChanged: {
30 if (active) {31 if (active) {
31 print("refreshing notes")32 NotesStore.refreshNotes();
32 notes.refresh();
33 }33 }
34 }34 }
3535
36 // Just for testing36 // Just for testing
37 tools: ToolbarItems {37 tools: ToolbarItems {
38 ToolbarButton {38 ToolbarButton {
39 text: "search"
40 iconName: "search"
41 onTriggered: {
42 pagestack.push(Qt.resolvedUrl("SearchNotesPage.qml"))
43 }
44 }
45
46 ToolbarSpacer { }
47
48 ToolbarButton {
39 text: "add note"49 text: "add note"
40 enabled: notes.filterNotebookGuid.length > 050 enabled: notes.filterNotebookGuid.length > 0
41 onTriggered: {51 onTriggered: {
@@ -52,18 +62,22 @@
52 }62 }
5363
54 ListView {64 ListView {
55 anchors.fill: parent65 anchors { left: parent.left; right: parent.right }
66 height: parent.height - y
56 model: notes67 model: notes
68 clip: true
5769
58 delegate: Standard {70 delegate: NotesDelegate {
59 text: title71 title: model.title
72 creationDate: model.created
73 content: NotesStore.note(model.guid).plaintextContent
6074
61 onClicked: {75 onClicked: {
62 pageStack.push(Qt.resolvedUrl("NotePage.qml"), {note: notes.note(guid)})76 pageStack.push(Qt.resolvedUrl("NotePage.qml"), {note: NotesStore.note(guid)})
63 }77 }
6478
65 onPressAndHold: {79 onPressAndHold: {
66 notes.note(guid).remove();80 NotesStore.deleteNote(guid);
67 }81 }
68 }82 }
69 }83 }
7084
=== modified file 'src/app/qml/ui/RemindersPage.qml'
--- src/app/qml/ui/RemindersPage.qml 2013-11-26 17:18:33 +0000
+++ src/app/qml/ui/RemindersPage.qml 2013-12-14 00:07:45 +0000
@@ -19,28 +19,27 @@
19import QtQuick 2.019import QtQuick 2.0
20import Ubuntu.Components 0.120import Ubuntu.Components 0.1
21import Ubuntu.Components.ListItems 0.121import Ubuntu.Components.ListItems 0.1
22//import "../components"22import Evernote 0.1
2323
24Page {24Page {
25 id: remindersPage25 id: remindersPage
2626
27 Label {27 Notes {
28 id: developmentWarning28 id: notes
29 anchors.centerIn: parent29 onlyReminders: true
30 text: i18n.tr("This page is still in development")
31 }30 }
3231
33 ListView {32 ListView {
3433
35 width: parent.width; height: parent.height34 anchors.fill: parent
3635
37 delegate: Subtitled {36 delegate: Subtitled {
38 text: '<b>Name:</b> ' + model.name37 text: '<b>Name:</b> ' + model.title
39 subText: '<b>Date:</b> ' + model.date38 subText: '<b>Date:</b> ' + Qt.formatDateTime(model.created) +
39 (model.reminderDone ? " - <b>Done:</b> " + Qt.formatDate(model.reminderDoneTime) : "")
40 }40 }
4141
42// model: RemindersModel {}42 model: notes
43
44 }43 }
4544
46}45}
4746
=== added file 'src/app/qml/ui/SearchNotesPage.qml'
--- src/app/qml/ui/SearchNotesPage.qml 1970-01-01 00:00:00 +0000
+++ src/app/qml/ui/SearchNotesPage.qml 2013-12-14 00:07:45 +0000
@@ -0,0 +1,80 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19import QtQuick 2.0
20import Ubuntu.Components 0.1
21import Ubuntu.Components.ListItems 0.1
22import Evernote 0.1
23import "../components"
24
25Page {
26 Column {
27 anchors { fill: parent; topMargin: units.gu(2); bottomMargin: units.gu(2) }
28 spacing: units.gu(2)
29
30 Row {
31 anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
32 spacing: units.gu(1)
33
34 TextField {
35 id: searchField
36 width: parent.width - searchButton.width - parent.spacing
37 anchors.verticalCenter: parent.verticalCenter
38
39 primaryItem: Icon {
40 height: searchField.height - units.gu(1)
41 width: height
42 name: "search"
43 }
44
45 onAccepted: {
46 NotesStore.findNotes(searchField.text + "*")
47 }
48 }
49 Button {
50 id: searchButton
51 height: searchField.height
52 text: "search"
53 onClicked: {
54 NotesStore.findNotes(searchField.text + "*")
55 }
56 }
57 }
58
59 ListView {
60 anchors { left: parent.left; right: parent.right }
61 height: parent.height - y
62 clip: true
63
64 model: Notes {
65 onlySearchResults: true
66 }
67
68 delegate: NotesDelegate {
69 title: model.title
70 creationDate: model.created
71 content: NotesStore.note(model.guid).plaintextContent
72
73 onClicked: {
74 pageStack.push(Qt.resolvedUrl("NotePage.qml"), {note: NotesStore.note(guid)})
75 }
76 }
77 }
78
79 }
80}
081
=== modified file 'src/plugin/Evernote/Evernote.pro'
--- src/plugin/Evernote/Evernote.pro 2013-11-27 17:33:36 +0000
+++ src/plugin/Evernote/Evernote.pro 2013-12-14 00:07:45 +0000
@@ -23,7 +23,13 @@
23 jobs/evernotejob.cpp \23 jobs/evernotejob.cpp \
24 jobs/savenotejob.cpp \24 jobs/savenotejob.cpp \
25 jobs/deletenotejob.cpp \25 jobs/deletenotejob.cpp \
26 utils/html2enmlconverter.cpp26 utils/html2enmlconverter.cpp \
27 evernoteconnection.cpp \
28 jobs/userstorejob.cpp \
29 jobs/notesstorejob.cpp \
30 jobs/fetchusernamejob.cpp \
31 jobs/createnotebookjob.cpp \
32 jobs/expungenotebookjob.cpp
2733
28HEADERS += evernoteplugin.h \34HEADERS += evernoteplugin.h \
29 notesstore.h \35 notesstore.h \
@@ -39,7 +45,13 @@
39 jobs/evernotejob.h \45 jobs/evernotejob.h \
40 jobs/savenotejob.h \46 jobs/savenotejob.h \
41 jobs/deletenotejob.h \47 jobs/deletenotejob.h \
42 utils/html2enmlconverter.h48 utils/html2enmlconverter.h \
49 evernoteconnection.h \
50 jobs/userstorejob.h \
51 jobs/notesstorejob.h \
52 jobs/fetchusernamejob.h \
53 jobs/createnotebookjob.h \
54 jobs/expungenotebookjob.h
4355
44message(building in $$OUT_PWD)56message(building in $$OUT_PWD)
45LIBS += -L$$OUT_PWD/../../../3rdParty/evernote-sdk-cpp/ -L$$OUT_PWD/../../../3rdParty/libthrift/ -levernote-sdk-cpp -llibthrift -lssl -lcrypto57LIBS += -L$$OUT_PWD/../../../3rdParty/evernote-sdk-cpp/ -L$$OUT_PWD/../../../3rdParty/libthrift/ -levernote-sdk-cpp -llibthrift -lssl -lcrypto
4658
=== added file 'src/plugin/Evernote/evernoteconnection.cpp'
--- src/plugin/Evernote/evernoteconnection.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/evernoteconnection.cpp 2013-12-14 00:07:45 +0000
@@ -0,0 +1,190 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#include "evernoteconnection.h"
22#include "jobs/evernotejob.h"
23
24// Thrift
25#include <arpa/inet.h> // seems thrift forgot this one
26#include <protocol/TBinaryProtocol.h>
27#include <transport/THttpClient.h>
28#include <transport/TSSLSocket.h>
29#include <Thrift.h>
30
31// Evernote SDK
32#include <NoteStore.h>
33#include <NoteStore_constants.h>
34#include <UserStore.h>
35#include <UserStore_constants.h>
36#include <Errors_types.h>
37
38#include <QDebug>
39
40using namespace apache::thrift;
41using namespace apache::thrift::protocol;
42using namespace apache::thrift::transport;
43
44EvernoteConnection* EvernoteConnection::s_instance = 0;
45
46// FIXME: need to populate this string from the system
47// The structure should be:
48// application/version; platform/version; [ device/version ]
49// E.g. "Evernote Windows/3.0.1; Windows/XP SP3"
50QString EDAM_CLIENT_NAME = QStringLiteral("Reminders/0.1; Ubuntu/13.10");
51QString EVERNOTE_HOST = QStringLiteral("sandbox.evernote.com");
52QString EDAM_USER_STORE_PATH = QStringLiteral("/edam/user");
53QString EDAM_NOTE_STORE_PATH = QStringLiteral("/edam/note");
54
55EvernoteConnection::EvernoteConnection(QObject *parent) :
56 QObject(parent),
57 m_currentJob(0),
58 m_useSSL(true)
59{
60 setupUserStore();
61 setupNotesStore();
62}
63
64bool EvernoteConnection::setupUserStore()
65{
66 bool versionOK = false;
67 try {
68 boost::shared_ptr<TSocket> socket;
69
70 if (m_useSSL) {
71 boost::shared_ptr<TSSLSocketFactory> sslSocketFactory(new TSSLSocketFactory());
72 socket = sslSocketFactory->createSocket(EVERNOTE_HOST.toStdString(), 443);
73 qDebug() << "created UserStore SSL socket";
74 } else {
75 // Create a non-secure socket
76 socket = boost::shared_ptr<TSocket> (new TSocket(EVERNOTE_HOST.toStdString(), 80));
77 qDebug() << "created insecure UserStore socket";
78 }
79
80 boost::shared_ptr<TBufferedTransport> bufferedTransport(new TBufferedTransport(socket));
81 m_userStoreHttpClient = boost::shared_ptr<THttpClient>(new THttpClient(bufferedTransport,
82 EVERNOTE_HOST.toStdString(),
83 EDAM_USER_STORE_PATH.toStdString()));
84 m_userStoreHttpClient->open();
85 boost::shared_ptr<TProtocol> iprot(new TBinaryProtocol(m_userStoreHttpClient));
86 m_userstoreClient = new evernote::edam::UserStoreClient(iprot);
87 evernote::edam::UserStoreConstants constants;
88 versionOK = m_userstoreClient->checkVersion(EDAM_CLIENT_NAME.toStdString(),
89 constants.EDAM_VERSION_MAJOR,
90 constants.EDAM_VERSION_MINOR);
91 qDebug() << "UserStoreClient created. Version check:" << versionOK;
92
93 } catch (const TTransportException & e) {
94 qWarning() << "Failed to create Transport for UserStore:" << e.what();
95 } catch (const TException & e) {
96 qWarning() << "Generic Thrift exception in UserStore setup:" << e.what();
97 }
98 return versionOK;
99}
100
101bool EvernoteConnection::setupNotesStore()
102{
103 try {
104 boost::shared_ptr<TSocket> socket;
105
106 if (m_useSSL) {
107 boost::shared_ptr<TSSLSocketFactory> sslSocketFactory(new TSSLSocketFactory());
108 socket = sslSocketFactory->createSocket(EVERNOTE_HOST.toStdString(), 443);
109 qDebug() << "created NotesStore SSL socket";
110 } else {
111 // Create a non-secure socket
112 socket = boost::shared_ptr<TSocket> (new TSocket(EVERNOTE_HOST.toStdString(), 80));
113 qDebug() << "created insecure NotesStore socket";
114 }
115
116 // setup UserStore
117 boost::shared_ptr<TBufferedTransport> bufferedTransport(new TBufferedTransport(socket));
118 m_notesStoreHttpClient = boost::shared_ptr<THttpClient>(new THttpClient(bufferedTransport,
119 EVERNOTE_HOST.toStdString(),
120 EDAM_NOTE_STORE_PATH.toStdString()));
121 m_notesStoreHttpClient->open();
122 boost::shared_ptr<TProtocol> iprot(new TBinaryProtocol(m_notesStoreHttpClient));
123
124 // setup notesstore
125 m_notesStoreClient = new evernote::edam::NoteStoreClient(iprot);
126
127 qDebug() << "NoteStore client created.";
128
129 } catch (const TTransportException & e) {
130 qWarning() << "Failed to create Transport for NotesStore:" << e.what();
131 return false;
132 } catch (const TException & e) {
133 qWarning() << "Generic Thrift exception in NotesStore setup:" << e.what();
134 return false;
135 }
136 return true;
137}
138
139EvernoteConnection *EvernoteConnection::instance()
140{
141 if (!s_instance) {
142 s_instance = new EvernoteConnection();
143 }
144 return s_instance;
145}
146
147EvernoteConnection::~EvernoteConnection()
148{
149 delete m_notesStoreClient;
150}
151
152QString EvernoteConnection::token() const
153{
154 return m_token;
155}
156
157void EvernoteConnection::setToken(const QString &token)
158{
159 if (token != m_token) {
160 m_token = token;
161 emit tokenChanged();
162 }
163}
164
165void EvernoteConnection::enqueue(EvernoteJob *job)
166{
167 connect(job, &EvernoteJob::finished, this, &EvernoteConnection::startNextJob);
168
169 m_jobQueue.append(job);
170 startJobQueue();
171}
172
173void EvernoteConnection::startJobQueue()
174{
175 if (m_jobQueue.isEmpty()) {
176 return;
177 }
178
179 if (m_currentJob) {
180 return;
181 }
182 m_currentJob = m_jobQueue.takeFirst();
183 m_currentJob->start();
184}
185
186void EvernoteConnection::startNextJob()
187{
188 m_currentJob = 0;
189 startJobQueue();
190}
0191
=== added file 'src/plugin/Evernote/evernoteconnection.h'
--- src/plugin/Evernote/evernoteconnection.h 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/evernoteconnection.h 2013-12-14 00:07:45 +0000
@@ -0,0 +1,101 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#ifndef EVERNOTECONNECTION_H
22#define EVERNOTECONNECTION_H
23
24#include <boost/shared_ptr.hpp>
25
26// Thrift
27#include <transport/THttpClient.h>
28
29#include <QObject>
30
31namespace evernote {
32namespace edam {
33class NoteStoreClient;
34class UserStoreClient;
35}
36}
37
38using namespace apache::thrift::transport;
39
40class EvernoteJob;
41
42class EvernoteConnection : public QObject
43{
44 Q_OBJECT
45 Q_PROPERTY(QString token READ token WRITE setToken NOTIFY tokenChanged)
46
47 friend class NotesStoreJob;
48 friend class UserStoreJob;
49
50public:
51 enum ErrorCode {
52 ErrorCodeNoError,
53 ErrorCodeUserException,
54 ErrorCodeSystemException,
55 ErrorCodeNotFoundExcpetion,
56 ErrorCodeConnectionLost
57 };
58
59 static EvernoteConnection* instance();
60 ~EvernoteConnection();
61
62 QString token() const;
63 void setToken(const QString &token);
64
65 void enqueue(EvernoteJob *job);
66
67signals:
68 void tokenChanged();
69
70private slots:
71 void startJobQueue();
72 void startNextJob();
73
74private:
75 explicit EvernoteConnection(QObject *parent = 0);
76 static EvernoteConnection *s_instance;
77
78 bool setupUserStore();
79 bool setupNotesStore();
80
81 bool m_useSSL;
82
83 QString m_token;
84
85 // There must be only one job running at a time
86 // Do not start jobs other than with startJobQueue()
87 QList<EvernoteJob*> m_jobQueue;
88 EvernoteJob *m_currentJob;
89
90 // Those 4 are accessed from the job thread.
91 // Make sure to not access them while any jobs are running
92 // or we need to mutex them.
93 evernote::edam::NoteStoreClient *m_notesStoreClient;
94 boost::shared_ptr<THttpClient> m_notesStoreHttpClient;
95
96 evernote::edam::UserStoreClient *m_userstoreClient;
97 boost::shared_ptr<THttpClient> m_userStoreHttpClient;
98
99};
100
101#endif // EVERNOTECONNECTION_H
0102
=== modified file 'src/plugin/Evernote/evernoteplugin.cpp'
--- src/plugin/Evernote/evernoteplugin.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/evernoteplugin.cpp 2013-12-14 00:07:45 +0000
@@ -20,6 +20,7 @@
2020
21#include "evernoteplugin.h"21#include "evernoteplugin.h"
2222
23#include "evernoteconnection.h"
23#include "userstore.h"24#include "userstore.h"
24#include "notesstore.h"25#include "notesstore.h"
25#include "notes.h"26#include "notes.h"
@@ -28,16 +29,27 @@
2829
29#include <QtQml>30#include <QtQml>
3031
32static QObject* userStoreProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */)
33{
34 return UserStore::instance();
35}
36
31static QObject* notesStoreProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */)37static QObject* notesStoreProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */)
32{38{
33 return NotesStore::instance();39 return NotesStore::instance();
34}40}
3541
42static QObject* connectionProvider(QQmlEngine* /* engine */, QJSEngine* /* scriptEngine */)
43{
44 return EvernoteConnection::instance();
45}
46
36void FitBitPlugin::registerTypes(const char *uri)47void FitBitPlugin::registerTypes(const char *uri)
37{48{
38 qmlRegisterType<UserStore>("Evernote", 0, 1, "UserStore");49 qmlRegisterSingletonType<UserStore>("Evernote", 0, 1, "UserStore", userStoreProvider);
39
40 qmlRegisterSingletonType<NotesStore>("Evernote", 0, 1, "NotesStore", notesStoreProvider);50 qmlRegisterSingletonType<NotesStore>("Evernote", 0, 1, "NotesStore", notesStoreProvider);
51 qmlRegisterSingletonType<EvernoteConnection>("Evernote", 0, 1, "EvernoteConnection", connectionProvider);
52
41 qmlRegisterType<Notes>("Evernote", 0, 1, "Notes");53 qmlRegisterType<Notes>("Evernote", 0, 1, "Notes");
42 qmlRegisterType<Notebooks>("Evernote", 0, 1, "Notebooks");54 qmlRegisterType<Notebooks>("Evernote", 0, 1, "Notebooks");
43 qmlRegisterUncreatableType<Note>("Evernote", 0, 1, "Note", "Cannot create Notes in QML. Use NotesStore.createNote() instead.");55 qmlRegisterUncreatableType<Note>("Evernote", 0, 1, "Note", "Cannot create Notes in QML. Use NotesStore.createNote() instead.");
4456
=== added file 'src/plugin/Evernote/jobs/createnotebookjob.cpp'
--- src/plugin/Evernote/jobs/createnotebookjob.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/jobs/createnotebookjob.cpp 2013-12-14 00:07:45 +0000
@@ -0,0 +1,41 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#include "createnotebookjob.h"
22
23#include <QDebug>
24
25CreateNotebookJob::CreateNotebookJob(const QString &name, QObject *parent) :
26 NotesStoreJob(parent),
27 m_name(name)
28{
29}
30
31void CreateNotebookJob::startJob()
32{
33 m_result.name = m_name.toStdString();
34 m_result.__isset.name = true;
35 client()->createNotebook(m_result, token().toStdString(), m_result);
36}
37
38void CreateNotebookJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
39{
40 emit jobDone(errorCode, errorMessage, m_result);
41}
042
=== added file 'src/plugin/Evernote/jobs/createnotebookjob.h'
--- src/plugin/Evernote/jobs/createnotebookjob.h 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/jobs/createnotebookjob.h 2013-12-14 00:07:45 +0000
@@ -0,0 +1,46 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#ifndef CREATENOTEBOOKJOB_H
22#define CREATENOTEBOOKJOB_H
23
24#include "notesstorejob.h"
25
26class CreateNotebookJob : public NotesStoreJob
27{
28 Q_OBJECT
29public:
30 explicit CreateNotebookJob(const QString &name, QObject *parent = 0);
31
32 virtual void startJob() override;
33
34signals:
35 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Notebook &result);
36
37private slots:
38 void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
39
40private:
41 QString m_name;
42
43 evernote::edam::Notebook m_result;
44};
45
46#endif // CREATENOTEBOOKJOB_H
047
=== modified file 'src/plugin/Evernote/jobs/createnotejob.cpp'
--- src/plugin/Evernote/jobs/createnotejob.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/jobs/createnotejob.cpp 2013-12-14 00:07:45 +0000
@@ -22,36 +22,30 @@
2222
23#include <QDebug>23#include <QDebug>
2424
25CreateNoteJob::CreateNoteJob(Note *note, QObject *parent) :25CreateNoteJob::CreateNoteJob(const QString &title, const QString &notebookGuid, const QString &content, QObject *parent) :
26 EvernoteJob(parent),26 NotesStoreJob(parent),
27 m_note(note)27 m_title(title),
28{28 m_notebookGuid(notebookGuid),
29}29 m_content(content)
3030{
31void CreateNoteJob::run()31}
32{32
33 NotesStore::ErrorCode errorCode = NotesStore::ErrorCodeNoError;33void CreateNoteJob::startJob()
3434{
35 try {35 evernote::edam::Note input;
36 evernote::edam::Note input;36 input.title = m_title.toStdString();
37 input.title = m_note->title().toStdString();37 input.__isset.title = true;
38 input.__isset.title = true;38 input.notebookGuid = m_notebookGuid.toStdString();
39 input.notebookGuid = m_note->notebookGuid().toStdString();39 input.__isset.notebookGuid = true;
40 input.__isset.notebookGuid = true;40 input.content = m_content.toStdString();
41 input.content = m_note->content().toStdString();41 input.__isset.content = true;
42 input.__isset.content = true;42 input.contentLength = m_content.length();
43 input.contentLength = m_note->content().length();43 input.__isset.contentLength = true;
44 input.__isset.contentLength = true;44
4545 client()->createNote(m_resultNote, token().toStdString(), input);
46 evernote::edam::Note result;46}
47 client()->createNote(result, token().toStdString(), input);47
4848void CreateNoteJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
49 m_note->setGuid(QString::fromStdString(result.guid));49{
5050 emit jobDone(errorCode, errorMessage, m_resultNote);
51 } catch(evernote::edam::EDAMUserException e) {
52 errorCode = NotesStore::ErrorCodeUserException;
53 } catch(evernote::edam::EDAMSystemException) {
54 errorCode = NotesStore::ErrorCodeSystemException;
55 }
56 emit resultReady(errorCode, m_note);
57}51}
5852
=== modified file 'src/plugin/Evernote/jobs/createnotejob.h'
--- src/plugin/Evernote/jobs/createnotejob.h 2013-11-25 00:49:48 +0000
+++ src/plugin/Evernote/jobs/createnotejob.h 2013-12-14 00:07:45 +0000
@@ -1,22 +1,27 @@
1#ifndef CREATENOTEJOB_H1#ifndef CREATENOTEJOB_H
2#define CREATENOTEJOB_H2#define CREATENOTEJOB_H
33
4#include "evernotejob.h"4#include "notesstorejob.h"
5#include "note.h"
65
7class CreateNoteJob : public EvernoteJob6class CreateNoteJob : public NotesStoreJob
8{7{
9 Q_OBJECT8 Q_OBJECT
10public:9public:
11 explicit CreateNoteJob(Note *note, QObject *parent = 0);10 explicit CreateNoteJob(const QString &title, const QString &notebookGuid, const QString &content, QObject *parent = 0);
12
13 void run();
1411
15signals:12signals:
16 void resultReady(NotesStore::ErrorCode errorCode, Note *note);13 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, evernote::edam::Note note);
14
15protected:
16 void startJob();
17 void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
1718
18private:19private:
19 Note *m_note;20 QString m_title;
21 QString m_notebookGuid;
22 QString m_content;
23
24 evernote::edam::Note m_resultNote;
20};25};
2126
22#endif // CREATENOTEJOB_H27#endif // CREATENOTEJOB_H
2328
=== modified file 'src/plugin/Evernote/jobs/deletenotejob.cpp'
--- src/plugin/Evernote/jobs/deletenotejob.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/jobs/deletenotejob.cpp 2013-12-14 00:07:45 +0000
@@ -21,18 +21,17 @@
21#include "deletenotejob.h"21#include "deletenotejob.h"
2222
23DeleteNoteJob::DeleteNoteJob(const QString &guid, QObject *parent):23DeleteNoteJob::DeleteNoteJob(const QString &guid, QObject *parent):
24 EvernoteJob(parent),24 NotesStoreJob(parent),
25 m_guid(guid)25 m_guid(guid)
26{26{
27}27}
2828
29void DeleteNoteJob::run()29void DeleteNoteJob::startJob()
30{30{
31 NotesStore::ErrorCode errorCode = NotesStore::ErrorCodeNoError;31 client()->deleteNote(token().toStdString(), m_guid.toStdString());
32 try {32}
33 client()->deleteNote(token().toStdString(), m_guid.toStdString());33
34 } catch(...) {34void DeleteNoteJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
35 catchTransportException();35{
36 }36 emit jobDone(errorCode, errorMessage, m_guid);
37 emit resultReady(errorCode, m_guid);
38}37}
3938
=== modified file 'src/plugin/Evernote/jobs/deletenotejob.h'
--- src/plugin/Evernote/jobs/deletenotejob.h 2013-11-25 00:49:48 +0000
+++ src/plugin/Evernote/jobs/deletenotejob.h 2013-12-14 00:07:45 +0000
@@ -1,18 +1,20 @@
1#ifndef DELETENOTEJOB_H1#ifndef DELETENOTEJOB_H
2#define DELETENOTEJOB_H2#define DELETENOTEJOB_H
33
4#include "evernotejob.h"4#include "notesstorejob.h"
55
6class DeleteNoteJob : public EvernoteJob6class DeleteNoteJob : public NotesStoreJob
7{7{
8 Q_OBJECT8 Q_OBJECT
9public:9public:
10 DeleteNoteJob(const QString &guid, QObject *parent = 0);10 DeleteNoteJob(const QString &guid, QObject *parent = 0);
1111
12 void run();
13
14signals:12signals:
15 void resultReady(NotesStore::ErrorCode errorCode, const QString &guid);13 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid);
14
15protected:
16 void startJob();
17 void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
1618
17private:19private:
18 QString m_guid;20 QString m_guid;
1921
=== modified file 'src/plugin/Evernote/jobs/evernotejob.cpp'
--- src/plugin/Evernote/jobs/evernotejob.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/jobs/evernotejob.cpp 2013-12-14 00:07:45 +0000
@@ -19,6 +19,7 @@
19 */19 */
2020
21#include "evernotejob.h"21#include "evernotejob.h"
22#include "evernoteconnection.h"
2223
23// Thrift24// Thrift
24#include <arpa/inet.h> // seems thrift forgot this one25#include <arpa/inet.h> // seems thrift forgot this one
@@ -35,35 +36,67 @@
3536
36EvernoteJob::EvernoteJob(QObject *parent) :37EvernoteJob::EvernoteJob(QObject *parent) :
37 QThread(parent),38 QThread(parent),
38 m_token(NotesStore::instance()->token())39 m_token(EvernoteConnection::instance()->token())
39{40{
40 connect(this, &EvernoteJob::finished, this, &EvernoteJob::deleteLater);41 connect(this, &EvernoteJob::finished, this, &EvernoteJob::deleteLater);
41}42}
4243
43EvernoteJob::~EvernoteJob()44EvernoteJob::~EvernoteJob()
44{45{
45
46}46}
4747
48evernote::edam::NoteStoreClient *EvernoteJob::client()48void EvernoteJob::run()
49{49{
50 return NotesStore::instance()->m_client;50 if (m_token.isEmpty()) {
51 qWarning() << "No token set. Cannot execute job. (" << this->metaObject()->className() << ")";
52 emitJobDone(EvernoteConnection::ErrorCodeUserException, QStringLiteral("No token set."));
53 return;
54 }
55
56 try {
57 startJob();
58 } catch (const TTransportException & e) {
59
60 // The connection broke down. libthrift + evernote servers seem to be quite flaky
61 // so lets try to start the job once more.
62 qWarning() << "Got a transport exception:" << e.what() << ". Trying to reestablish connection...";
63 try {
64 resetConnection();
65 startJob();
66 } catch (const TTransportException &e) {
67 // Giving up... the connection seems to be down for real.
68 qWarning() << "Cannot reestablish connection:" << e.what();
69 emitJobDone(EvernoteConnection::ErrorCodeConnectionLost, e.what());
70 } catch (const TApplicationException &e) {
71 qWarning() << "Cannot reestablish connection:" << e.what();
72 emitJobDone(EvernoteConnection::ErrorCodeConnectionLost, e.what());
73 } catch (const evernote::edam::EDAMUserException &e) {
74 qWarning() << "EDAMUserException" << e.what();
75 emitJobDone(EvernoteConnection::ErrorCodeUserException, e.what());
76 } catch (const evernote::edam::EDAMSystemException &e) {
77 qWarning() << "EDAMSystemException" << e.what();
78 emitJobDone(EvernoteConnection::ErrorCodeSystemException, e.what());
79 } catch (const evernote::edam::EDAMNotFoundException &e) {
80 qWarning() << "EDAMNotFoundException" << e.what();
81 emitJobDone(EvernoteConnection::ErrorCodeNotFoundExcpetion, e.what());
82 }
83
84
85 } catch (const evernote::edam::EDAMUserException &e) {
86 qWarning() << "EDAMUserException" << e.what();
87 emitJobDone(EvernoteConnection::ErrorCodeUserException, e.what());
88 } catch (const evernote::edam::EDAMSystemException &e) {
89 qWarning() << "EDAMSystemException" << e.what();
90 emitJobDone(EvernoteConnection::ErrorCodeSystemException, e.what());
91 } catch (const evernote::edam::EDAMNotFoundException &e) {
92 qWarning() << "EDAMNotFoundException" << e.what();
93 emitJobDone(EvernoteConnection::ErrorCodeNotFoundExcpetion, e.what());
94 }
95
96 emitJobDone(EvernoteConnection::ErrorCodeNoError, QString());
51}97}
5298
53QString EvernoteJob::token()99QString EvernoteJob::token()
54{100{
55 return m_token;101 return m_token;
56}102}
57
58void EvernoteJob::catchTransportException()
59{
60 try {
61 // this function is meant to be called from a catch block
62 // rethrow the exception to catch it again
63 throw;
64 } catch (const TTransportException & e) {
65 qDebug() << e.what();
66 } catch (const TException & e) {
67 qDebug() << e.what();
68 }
69}
70103
=== modified file 'src/plugin/Evernote/jobs/evernotejob.h'
--- src/plugin/Evernote/jobs/evernotejob.h 2013-11-25 00:49:48 +0000
+++ src/plugin/Evernote/jobs/evernotejob.h 2013-12-14 00:07:45 +0000
@@ -3,13 +3,21 @@
33
4#include "notesstore.h"4#include "notesstore.h"
55
6// Evernote SDK
7#include <NoteStore.h>
8#include <NoteStore_constants.h>
9#include <Errors_types.h>
10
11#include <QThread>6#include <QThread>
127
8/* How to create a new Job type:
9 * - Subclass EvernoteJob
10 * - Implement startJob() in which you do the call to evernote.
11 * - No need to catch exceptions, EvernoteJob will deal with those.
12 * - Define a jobDone() signal with the result parameters you need.
13 * - Keep the convention of jobDone(EvernoteConnection::ErrorCode errorCode, const QString &message [, ...])
14 * - Emit jobDone() in your implementation of emitJobDone().
15 * - NOTE: emitJobDone() might be called with an error even before startJob() is triggered.
16 *
17 * Jobs can be enqueue()d in NotesStore.
18 * They will destroy themselves when finished.
19 * The jobqueue will take care about starting them.
20 */
13class EvernoteJob : public QThread21class EvernoteJob : public QThread
14{22{
15 Q_OBJECT23 Q_OBJECT
@@ -17,12 +25,18 @@
17 explicit EvernoteJob(QObject *parent = 0);25 explicit EvernoteJob(QObject *parent = 0);
18 virtual ~EvernoteJob();26 virtual ~EvernoteJob();
1927
28 void run() final;
29
30signals:
31 void connectionLost(const QString &errorMessage);
32
20protected:33protected:
21 evernote::edam::NoteStoreClient* client();34 virtual void resetConnection() = 0;
35 virtual void startJob() = 0;
36 virtual void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage) = 0;
37
22 QString token();38 QString token();
2339
24 void catchTransportException();
25
26private:40private:
27 QString m_token;41 QString m_token;
28};42};
2943
=== added file 'src/plugin/Evernote/jobs/expungenotebookjob.cpp'
--- src/plugin/Evernote/jobs/expungenotebookjob.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/jobs/expungenotebookjob.cpp 2013-12-14 00:07:45 +0000
@@ -0,0 +1,39 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#include "expungenotebookjob.h"
22
23#include <QDebug>
24
25ExpungeNotebookJob::ExpungeNotebookJob(const QString &guid, QObject *parent) :
26 NotesStoreJob(parent),
27 m_guid(guid)
28{
29}
30
31void ExpungeNotebookJob::startJob()
32{
33 client()->expungeNotebook(token().toStdString(), m_guid.toStdString());
34}
35
36void ExpungeNotebookJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
37{
38 emit jobDone(errorCode, errorMessage, m_guid);
39}
040
=== added file 'src/plugin/Evernote/jobs/expungenotebookjob.h'
--- src/plugin/Evernote/jobs/expungenotebookjob.h 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/jobs/expungenotebookjob.h 2013-12-14 00:07:45 +0000
@@ -0,0 +1,43 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#ifndef DELETENOTEBOOKJOB_H
22#define DELETENOTEBOOKJOB_H
23
24#include "notesstorejob.h"
25
26class ExpungeNotebookJob : public NotesStoreJob
27{
28 Q_OBJECT
29public:
30 explicit ExpungeNotebookJob(const QString &guid, QObject *parent = 0);
31
32signals:
33 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid);
34
35private slots:
36 void startJob();
37 void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
38
39private:
40 QString m_guid;
41};
42
43#endif // DELETENOTEBOOKJOB_H
044
=== modified file 'src/plugin/Evernote/jobs/fetchnotebooksjob.cpp'
--- src/plugin/Evernote/jobs/fetchnotebooksjob.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/jobs/fetchnotebooksjob.cpp 2013-12-14 00:07:45 +0000
@@ -23,21 +23,17 @@
23#include <QDebug>23#include <QDebug>
2424
25FetchNotebooksJob::FetchNotebooksJob(QObject *parent) :25FetchNotebooksJob::FetchNotebooksJob(QObject *parent) :
26 EvernoteJob(parent)26 NotesStoreJob(parent)
27{27{
28}28}
2929
3030
31void FetchNotebooksJob::run()31void FetchNotebooksJob::startJob()
32{32{
33 NotesStore::ErrorCode errorCode = NotesStore::ErrorCodeNoError;33 client()->listNotebooks(m_results, token().toStdString());
34 std::vector<evernote::edam::Notebook> results;34}
35 try {35
36 client()->listNotebooks(results, token().toStdString());36void FetchNotebooksJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
37 } catch(evernote::edam::EDAMUserException) {37{
38 errorCode = NotesStore::ErrorCodeUserException;38 emit jobDone(errorCode, errorMessage, m_results);
39 } catch(evernote::edam::EDAMSystemException) {
40 errorCode = NotesStore::ErrorCodeSystemException;
41 }
42 emit resultReady(errorCode, results);
43}39}
4440
=== modified file 'src/plugin/Evernote/jobs/fetchnotebooksjob.h'
--- src/plugin/Evernote/jobs/fetchnotebooksjob.h 2013-11-25 00:49:48 +0000
+++ src/plugin/Evernote/jobs/fetchnotebooksjob.h 2013-12-14 00:07:45 +0000
@@ -1,18 +1,23 @@
1#ifndef FETCHNOTEBOOKSJOB_H1#ifndef FETCHNOTEBOOKSJOB_H
2#define FETCHNOTEBOOKSJOB_H2#define FETCHNOTEBOOKSJOB_H
33
4#include "evernotejob.h"4#include "notesstorejob.h"
55
6class FetchNotebooksJob : public EvernoteJob6class FetchNotebooksJob : public NotesStoreJob
7{7{
8 Q_OBJECT8 Q_OBJECT
9public:9public:
10 explicit FetchNotebooksJob(QObject *parent = 0);10 explicit FetchNotebooksJob(QObject *parent = 0);
1111
12 void run();
13
14signals:12signals:
15 void resultReady(NotesStore::ErrorCode errorCode, const std::vector<evernote::edam::Notebook> &results);13 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const std::vector<evernote::edam::Notebook> &results);
14
15protected:
16 void startJob();
17 void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
18
19private:
20 std::vector<evernote::edam::Notebook> m_results;
16};21};
1722
18#endif // FETCHNOTEBOOKSJOB_H23#endif // FETCHNOTEBOOKSJOB_H
1924
=== modified file 'src/plugin/Evernote/jobs/fetchnotejob.cpp'
--- src/plugin/Evernote/jobs/fetchnotejob.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/jobs/fetchnotejob.cpp 2013-12-14 00:07:45 +0000
@@ -21,27 +21,17 @@
21#include "fetchnotejob.h"21#include "fetchnotejob.h"
2222
23FetchNoteJob::FetchNoteJob(const QString &guid, QObject *parent) :23FetchNoteJob::FetchNoteJob(const QString &guid, QObject *parent) :
24 EvernoteJob(parent),24 NotesStoreJob(parent),
25 m_guid(guid)25 m_guid(guid)
26{26{
27}27}
2828
29void FetchNoteJob::run()29void FetchNoteJob::startJob()
30{30{
31 NotesStore::ErrorCode errorCode = NotesStore::ErrorCodeNoError;31 client()->getNote(m_result, token().toStdString(), m_guid.toStdString(), true, false, false, false);
32 evernote::edam::Note result;32}
33 try {
34 client()->getNote(result, token().toStdString(), m_guid.toStdString(), true, true, false, false);
35 } catch (evernote::edam::EDAMUserException) {
36 errorCode = NotesStore::ErrorCodeUserException;
37 } catch (evernote::edam::EDAMSystemException) {
38 errorCode = NotesStore::ErrorCodeSystemException;
39 } catch (evernote::edam::EDAMNotFoundException) {
40 errorCode = NotesStore::ErrorCodeNotFoundExcpetion;
41 } catch (...) {
42 catchTransportException();
43 errorCode = NotesStore::ErrorCodeConnectionLost;
44 }
4533
46 emit resultReady(errorCode, result);34void FetchNoteJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
35{
36 emit resultReady(errorCode, errorMessage, m_result);
47}37}
4838
=== modified file 'src/plugin/Evernote/jobs/fetchnotejob.h'
--- src/plugin/Evernote/jobs/fetchnotejob.h 2013-11-25 00:49:48 +0000
+++ src/plugin/Evernote/jobs/fetchnotejob.h 2013-12-14 00:07:45 +0000
@@ -1,22 +1,28 @@
1#ifndef FETCHNOTEJOB_H1#ifndef FETCHNOTEJOB_H
2#define FETCHNOTEJOB_H2#define FETCHNOTEJOB_H
33
4#include "evernotejob.h"4#include "notesstorejob.h"
55
6class FetchNoteJob : public EvernoteJob6class FetchNoteJob : public NotesStoreJob
7{7{
8 Q_OBJECT8 Q_OBJECT
9public:9public:
10 explicit FetchNoteJob(const QString &guid, QObject *parent = 0);10 explicit FetchNoteJob(const QString &guid, QObject *parent = 0);
1111
12 void run();
13signals:12signals:
14 void resultReady(NotesStore::ErrorCode error, const evernote::edam::Note &note);13 void resultReady(EvernoteConnection::ErrorCode error, const QString &errorMessage, const evernote::edam::Note &note);
14
15protected:
16 void startJob();
17 void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
1518
16private:19private:
17 evernote::edam::NoteStoreClient *m_client;20 evernote::edam::NoteStoreClient *m_client;
18 QString m_token;21 QString m_token;
19 QString m_guid;22 QString m_guid;
23
24 evernote::edam::Note m_result;
25
20};26};
2127
22#endif // FETCHNOTEJOB_H28#endif // FETCHNOTEJOB_H
2329
=== modified file 'src/plugin/Evernote/jobs/fetchnotesjob.cpp'
--- src/plugin/Evernote/jobs/fetchnotesjob.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/jobs/fetchnotesjob.cpp 2013-12-14 00:07:45 +0000
@@ -22,43 +22,52 @@
2222
23#include "notesstore.h"23#include "notesstore.h"
2424
25// evernote sdk
26#include "Limits_constants.h"
27
25#include <QDebug>28#include <QDebug>
2629
27FetchNotesJob::FetchNotesJob( const QString &filterNotebookGuid, QObject *parent) :30FetchNotesJob::FetchNotesJob(const QString &filterNotebookGuid, const QString &searchWords, QObject *parent) :
28 EvernoteJob(parent),31 NotesStoreJob(parent),
29 m_filterNotebookGuid(filterNotebookGuid)32 m_filterNotebookGuid(filterNotebookGuid),
33 m_searchWords(searchWords)
30{34{
31}35}
3236
33void FetchNotesJob::run()37void FetchNotesJob::startJob()
34{38{
35 // TODO: fix start/end (use smaller chunks and continue fetching if there are more notes available)39 // TODO: fix start/end (use smaller chunks and continue fetching if there are more notes available)
36 int32_t start = 0;40 int32_t start = 0;
37 int32_t end = 10000;41 evernote::limits::LimitsConstants limits;
42 int32_t end = limits.EDAM_USER_NOTES_MAX;
3843
39 // Prepare filter44 // Prepare filter
40 evernote::edam::NoteFilter filter;45 evernote::edam::NoteFilter filter;
41 filter.notebookGuid = m_filterNotebookGuid.toStdString();46 filter.notebookGuid = m_filterNotebookGuid.toStdString();
42 filter.__isset.notebookGuid = !m_filterNotebookGuid.isEmpty();47 filter.__isset.notebookGuid = !m_filterNotebookGuid.isEmpty();
4348
49 filter.words = m_searchWords.toStdString();
50 filter.__isset.words = !m_searchWords.isEmpty();
51
44 // Prepare ResultSpec52 // Prepare ResultSpec
45 evernote::edam::NotesMetadataResultSpec resultSpec;53 evernote::edam::NotesMetadataResultSpec resultSpec;
54
46 resultSpec.includeNotebookGuid = true;55 resultSpec.includeNotebookGuid = true;
47 resultSpec.__isset.includeNotebookGuid = true;56 resultSpec.__isset.includeNotebookGuid = true;
57
58 resultSpec.includeCreated = true;
59 resultSpec.__isset.includeCreated = true;
60
48 resultSpec.includeTitle = true;61 resultSpec.includeTitle = true;
49 resultSpec.__isset.includeTitle = true;62 resultSpec.__isset.includeTitle = true;
5063
51 NotesStore::ErrorCode errorCode = NotesStore::ErrorCodeNoError;64 resultSpec.includeAttributes = true;
52 evernote::edam::NotesMetadataList results;65 resultSpec.__isset.includeAttributes = true;
5366
54 try {67 client()->findNotesMetadata(m_results, token().toStdString(), filter, start, end, resultSpec);
55 client()->findNotesMetadata(results, token().toStdString(), filter, start, end, resultSpec);68}
56 } catch(evernote::edam::EDAMUserException) {69
57 errorCode = NotesStore::ErrorCodeUserException;70void FetchNotesJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
58 } catch(evernote::edam::EDAMSystemException) {71{
59 errorCode = NotesStore::ErrorCodeSystemException;72 emit jobDone(errorCode, errorMessage, m_results);
60 } catch(evernote::edam::EDAMNotFoundException) {
61 errorCode = NotesStore::ErrorCodeNotFoundExcpetion;
62 }
63 emit resultReady(errorCode, results);
64}73}
6574
=== modified file 'src/plugin/Evernote/jobs/fetchnotesjob.h'
--- src/plugin/Evernote/jobs/fetchnotesjob.h 2013-11-25 00:49:48 +0000
+++ src/plugin/Evernote/jobs/fetchnotesjob.h 2013-12-14 00:07:45 +0000
@@ -1,21 +1,25 @@
1#ifndef FETCHNOTESJOB_H1#ifndef FETCHNOTESJOB_H
2#define FETCHNOTESJOB_H2#define FETCHNOTESJOB_H
33
4#include "evernotejob.h"4#include "notesstorejob.h"
55
6class FetchNotesJob : public EvernoteJob6class FetchNotesJob : public NotesStoreJob
7{7{
8 Q_OBJECT8 Q_OBJECT
9public:9public:
10 explicit FetchNotesJob(const QString &filterNotebookGuid, QObject *parent = 0);10 explicit FetchNotesJob(const QString &filterNotebookGuid = QString(), const QString &searchWords = QString(), QObject *parent = 0);
11
12 void run();
1311
14signals:12signals:
15 void resultReady(NotesStore::ErrorCode errorCode, const evernote::edam::NotesMetadataList &results);13 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::NotesMetadataList &results);
14
15protected:
16 void startJob();
17 void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
1618
17private:19private:
18 QString m_filterNotebookGuid;20 QString m_filterNotebookGuid;
21 QString m_searchWords;
22 evernote::edam::NotesMetadataList m_results;
19};23};
2024
21#endif // FETCHNOTESJOB_H25#endif // FETCHNOTESJOB_H
2226
=== added file 'src/plugin/Evernote/jobs/fetchusernamejob.cpp'
--- src/plugin/Evernote/jobs/fetchusernamejob.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/jobs/fetchusernamejob.cpp 2013-12-14 00:07:45 +0000
@@ -0,0 +1,38 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#include "fetchusernamejob.h"
22
23FetchUsernameJob::FetchUsernameJob(QObject *parent) :
24 UserStoreJob(parent)
25{
26}
27
28void FetchUsernameJob::startJob()
29{
30 evernote::edam::User user;
31 client()->getUser(user, token().toStdString());
32 m_result = QString::fromStdString(user.username);
33}
34
35void FetchUsernameJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
36{
37 emit jobDone(errorCode, errorMessage, m_result);
38}
039
=== added file 'src/plugin/Evernote/jobs/fetchusernamejob.h'
--- src/plugin/Evernote/jobs/fetchusernamejob.h 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/jobs/fetchusernamejob.h 2013-12-14 00:07:45 +0000
@@ -0,0 +1,43 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#ifndef FETCHUSERNAMEJOB_H
22#define FETCHUSERNAMEJOB_H
23
24#include "userstorejob.h"
25
26class FetchUsernameJob : public UserStoreJob
27{
28 Q_OBJECT
29public:
30 explicit FetchUsernameJob(QObject *parent = 0);
31
32signals:
33 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &result);
34
35protected:
36 void startJob();
37 void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
38
39private:
40 QString m_result;
41};
42
43#endif // FETCHUSERNAMEJOB_H
044
=== added file 'src/plugin/Evernote/jobs/notesstorejob.cpp'
--- src/plugin/Evernote/jobs/notesstorejob.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/jobs/notesstorejob.cpp 2013-12-14 00:07:45 +0000
@@ -0,0 +1,39 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#include "notesstorejob.h"
22
23#include "evernoteconnection.h"
24
25NotesStoreJob::NotesStoreJob(QObject *parent) :
26 EvernoteJob(parent)
27{
28}
29
30void NotesStoreJob::resetConnection()
31{
32 EvernoteConnection::instance()->m_notesStoreHttpClient->close();
33 EvernoteConnection::instance()->m_notesStoreHttpClient->open();
34}
35
36evernote::edam::NoteStoreClient *NotesStoreJob::client() const
37{
38 return EvernoteConnection::instance()->m_notesStoreClient;
39}
040
=== added file 'src/plugin/Evernote/jobs/notesstorejob.h'
--- src/plugin/Evernote/jobs/notesstorejob.h 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/jobs/notesstorejob.h 2013-12-14 00:07:45 +0000
@@ -0,0 +1,44 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#ifndef NOTESSTOREJOB_H
22#define NOTESSTOREJOB_H
23
24#include "evernotejob.h"
25
26// Evernote SDK
27#include <NoteStore.h>
28#include <NoteStore_constants.h>
29#include <Errors_types.h>
30
31class NotesStoreJob : public EvernoteJob
32{
33 Q_OBJECT
34public:
35 explicit NotesStoreJob(QObject *parent = 0);
36
37protected:
38 void resetConnection() final;
39
40 evernote::edam::NoteStoreClient *client() const;
41
42};
43
44#endif // NOTESSTOREJOB_H
045
=== modified file 'src/plugin/Evernote/jobs/savenotejob.cpp'
--- src/plugin/Evernote/jobs/savenotejob.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/jobs/savenotejob.cpp 2013-12-14 00:07:45 +0000
@@ -24,37 +24,40 @@
24#include <QDebug>24#include <QDebug>
2525
26SaveNoteJob::SaveNoteJob(Note *note, QObject *parent) :26SaveNoteJob::SaveNoteJob(Note *note, QObject *parent) :
27 EvernoteJob(parent),27 NotesStoreJob(parent)
28 m_note(note)28{
29{29 // Need to clone it. As startJob() will run in another thread we can't access the real note from there.
30}30 m_note = note->clone();
3131
32void SaveNoteJob::run()32 // Make sure we delete the clone when done
33{33 m_note->setParent(this);
34 NotesStore::ErrorCode errorCode = NotesStore::ErrorCodeNoError;34}
35 try {35
36 evernote::edam::Note note;36void SaveNoteJob::startJob()
37 note.guid = m_note->guid().toStdString();37{
38 note.__isset.guid = true;38 evernote::edam::Note note;
39 note.title = m_note->title().toStdString();39 note.guid = m_note->guid().toStdString();
40 note.__isset.title = true;40 note.__isset.guid = true;
41 note.notebookGuid = m_note->notebookGuid().toStdString();41 note.title = m_note->title().toStdString();
42 note.__isset.notebookGuid = true;42 note.__isset.title = true;
43 note.content = m_note->content().toStdString();43 note.notebookGuid = m_note->notebookGuid().toStdString();
44 note.__isset.content = true;44 note.__isset.notebookGuid = true;
45 note.contentLength = m_note->content().length();45 note.content = m_note->content().toStdString();
4646 note.__isset.content = true;
47 client()->updateNote(note, token().toStdString(), note);47 note.contentLength = m_note->content().length();
4848
49 } catch (evernote::edam::EDAMUserException e) {49 note.__isset.attributes = true;
50 errorCode = NotesStore::ErrorCodeUserException;50 note.attributes.reminderOrder = m_note->reminderOrder();
51 qDebug() << QString::fromStdString(e.parameter);51 note.attributes.__isset.reminderOrder = true;
52 } catch (evernote::edam::EDAMSystemException) {52 note.attributes.reminderTime = m_note->reminderTime().toMSecsSinceEpoch();
53 errorCode = NotesStore::ErrorCodeSystemException;53 note.attributes.__isset.reminderTime = true;
54 } catch (...) {54 note.attributes.reminderDoneTime = m_note->reminderDoneTime().toMSecsSinceEpoch();
55 catchTransportException();55 note.attributes.__isset.reminderDoneTime = true;
56 errorCode = NotesStore::ErrorCodeConnectionLost;56
57 }57 client()->updateNote(m_resultNote, token().toStdString(), note);
5858}
59 emit resultReady(errorCode, m_note);59
60void SaveNoteJob::emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage)
61{
62 emit jobDone(errorCode, errorMessage, m_resultNote);
60}63}
6164
=== modified file 'src/plugin/Evernote/jobs/savenotejob.h'
--- src/plugin/Evernote/jobs/savenotejob.h 2013-11-25 00:49:48 +0000
+++ src/plugin/Evernote/jobs/savenotejob.h 2013-12-14 00:07:45 +0000
@@ -1,20 +1,24 @@
1#ifndef SAVENOTEJOB_H1#ifndef SAVENOTEJOB_H
2#define SAVENOTEJOB_H2#define SAVENOTEJOB_H
33
4#include "evernotejob.h"4#include "notesstorejob.h"
55
6class SaveNoteJob : public EvernoteJob6class SaveNoteJob : public NotesStoreJob
7{7{
8 Q_OBJECT8 Q_OBJECT
9public:9public:
10 explicit SaveNoteJob(Note *note, QObject *parent = 0);10 explicit SaveNoteJob(Note *note, QObject *parent = 0);
1111
12 void run();
13signals:12signals:
14 void resultReady(NotesStore::ErrorCode errorCode, Note *note);13 void jobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Note &note);
14
15protected:
16 void startJob();
17 void emitJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage);
1518
16private:19private:
17 Note *m_note;20 Note* m_note;
21 evernote::edam::Note m_resultNote;
18};22};
1923
20#endif // SAVENOTEJOB_H24#endif // SAVENOTEJOB_H
2125
=== added file 'src/plugin/Evernote/jobs/userstorejob.cpp'
--- src/plugin/Evernote/jobs/userstorejob.cpp 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/jobs/userstorejob.cpp 2013-12-14 00:07:45 +0000
@@ -0,0 +1,39 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#include "userstorejob.h"
22
23#include "evernoteconnection.h"
24
25UserStoreJob::UserStoreJob(QObject *parent) :
26 EvernoteJob(parent)
27{
28}
29
30void UserStoreJob::resetConnection()
31{
32 EvernoteConnection::instance()->m_userStoreHttpClient->close();
33 EvernoteConnection::instance()->m_userStoreHttpClient->open();
34}
35
36evernote::edam::UserStoreClient *UserStoreJob::client() const
37{
38 return EvernoteConnection::instance()->m_userstoreClient;
39}
040
=== added file 'src/plugin/Evernote/jobs/userstorejob.h'
--- src/plugin/Evernote/jobs/userstorejob.h 1970-01-01 00:00:00 +0000
+++ src/plugin/Evernote/jobs/userstorejob.h 2013-12-14 00:07:45 +0000
@@ -0,0 +1,46 @@
1/*
2 * Copyright: 2013 Canonical, Ltd
3 *
4 * This file is part of reminders-app
5 *
6 * reminders-app is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 3.
9 *
10 * reminders-app is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * Authors: Michael Zanetti <michael.zanetti@canonical.com>
19 */
20
21#ifndef USERSTOREJOB_H
22#define USERSTOREJOB_H
23
24#include "evernotejob.h"
25
26// Evernote SDK
27#include <UserStore.h>
28#include <UserStore_constants.h>
29#include <Errors_types.h>
30
31class UserStoreJob : public EvernoteJob
32{
33 Q_OBJECT
34public:
35 explicit UserStoreJob(QObject *parent = 0);
36
37protected:
38 void resetConnection() final;
39
40 evernote::edam::UserStoreClient* client() const;
41
42public slots:
43
44};
45
46#endif // USERSTOREJOB_H
047
=== modified file 'src/plugin/Evernote/note.cpp'
--- src/plugin/Evernote/note.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/note.cpp 2013-12-14 00:07:45 +0000
@@ -21,10 +21,16 @@
21#include "note.h"21#include "note.h"
2222
23#include "notesstore.h"23#include "notesstore.h"
2424#include "utils/html2enmlconverter.h"
25Note::Note(const QString &guid, QObject *parent) :25
26#include <QDateTime>
27#include <QDebug>
28
29Note::Note(const QString &guid, const QDateTime &created, QObject *parent) :
26 QObject(parent),30 QObject(parent),
27 m_guid(guid)31 m_guid(guid),
32 m_created(created),
33 m_isSearchResult(false)
28{34{
29}35}
3036
@@ -33,14 +39,6 @@
33 return m_guid;39 return m_guid;
34}40}
3541
36void Note::setGuid(const QString &guid)
37{
38 if (m_guid == guid) {
39 m_guid = guid;
40 emit guidChanged();
41 }
42}
43
44QString Note::notebookGuid() const42QString Note::notebookGuid() const
45{43{
46 return m_notebookGuid;44 return m_notebookGuid;
@@ -54,6 +52,11 @@
54 }52 }
55}53}
5654
55QDateTime Note::created() const
56{
57 return m_created;
58}
59
57QString Note::title() const60QString Note::title() const
58{61{
59 return m_title;62 return m_title;
@@ -76,10 +79,111 @@
76{79{
77 if (m_content != content) {80 if (m_content != content) {
78 m_content = content;81 m_content = content;
82 m_plaintextContent = Html2EnmlConverter::enml2plaintext(content);
83 qDebug() << "plaintext content is" << m_plaintextContent;
79 emit contentChanged();84 emit contentChanged();
80 }85 }
81}86}
8287
88QString Note::plaintextContent() const
89{
90 return m_plaintextContent;
91}
92
93bool Note::reminder() const
94{
95 return m_reminderOrder > 0;
96}
97
98void Note::setReminder(bool reminder)
99{
100 if (reminder && m_reminderOrder == 0) {
101 m_reminderOrder = QDateTime::currentMSecsSinceEpoch();
102 emit reminderChanged();
103 } else if (!reminder && m_reminderOrder > 0) {
104 m_reminderOrder = 0;
105 emit reminderChanged();
106 }
107}
108
109qint64 Note::reminderOrder() const
110{
111 return m_reminderOrder;
112}
113
114void Note::setReminderOrder(qint64 reminderOrder)
115{
116 if (m_reminderOrder != reminderOrder) {
117 m_reminderOrder = reminderOrder;
118 emit reminderChanged();
119 }
120}
121
122QDateTime Note::reminderTime() const
123{
124 return m_reminderTime;
125}
126
127void Note::setReminderTime(const QDateTime &reminderTime)
128{
129 if (m_reminderTime != reminderTime) {
130 m_reminderTime = reminderTime;
131 emit reminderTimeChanged();
132 }
133}
134
135bool Note::reminderDone() const
136{
137 return !m_reminderDoneTime.isNull();
138}
139
140void Note::setReminderDone(bool reminderDone)
141{
142 if (reminderDone && m_reminderDoneTime.isNull()) {
143 m_reminderDoneTime = QDateTime::currentDateTime();
144 emit reminderDoneChanged();
145 }
146}
147
148QDateTime Note::reminderDoneTime() const
149{
150 return m_reminderDoneTime;
151}
152
153void Note::setReminderDoneTime(const QDateTime &reminderDoneTime)
154{
155 if (m_reminderDoneTime != reminderDoneTime) {
156 m_reminderDoneTime = reminderDoneTime;
157 emit reminderDoneChanged();
158 }
159}
160
161bool Note::isSearchResult() const
162{
163 return m_isSearchResult;
164}
165
166void Note::setIsSearchResult(bool isSearchResult)
167{
168 if (m_isSearchResult != isSearchResult) {
169 m_isSearchResult = isSearchResult;
170 emit isSearchResultChanged();
171 }
172}
173
174Note *Note::clone()
175{
176 Note *note = new Note(m_guid, m_created);
177 note->setNotebookGuid(m_notebookGuid);
178 note->setTitle(m_title);
179 note->setContent(m_content);
180 note->setReminderOrder(m_reminderOrder);
181 note->setReminderTime(m_reminderTime);
182 note->setReminderDoneTime(m_reminderDoneTime);
183 note->setIsSearchResult(m_isSearchResult);
184 return note;
185}
186
83void Note::save()187void Note::save()
84{188{
85 NotesStore::instance()->saveNote(m_guid);189 NotesStore::instance()->saveNote(m_guid);
86190
=== modified file 'src/plugin/Evernote/note.h'
--- src/plugin/Evernote/note.h 2013-11-25 00:49:48 +0000
+++ src/plugin/Evernote/note.h 2013-12-14 00:07:45 +0000
@@ -2,45 +2,96 @@
2#define NOTE_H2#define NOTE_H
33
4#include <QObject>4#include <QObject>
5#include <QDateTime>
6#include <QStringList>
57
6class Note : public QObject8class Note : public QObject
7{9{
8 Q_OBJECT10 Q_OBJECT
911
10 Q_PROPERTY(QString guid READ guid NOTIFY guidChanged)12 // Don't forget to update clone() if you add properties!
13 Q_PROPERTY(QString guid READ guid CONSTANT)
11 Q_PROPERTY(QString notebookGuid READ notebookGuid WRITE setNotebookGuid NOTIFY notebookGuidChanged)14 Q_PROPERTY(QString notebookGuid READ notebookGuid WRITE setNotebookGuid NOTIFY notebookGuidChanged)
15 Q_PROPERTY(QDateTime created READ created CONSTANT)
12 Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)16 Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
13 Q_PROPERTY(QString content READ content WRITE setContent NOTIFY contentChanged)17 Q_PROPERTY(QString content READ content WRITE setContent NOTIFY contentChanged)
18 Q_PROPERTY(QString plaintextContent READ plaintextContent NOTIFY contentChanged)
19 Q_PROPERTY(bool reminder READ reminder WRITE setReminder NOTIFY reminderChanged)
20 Q_PROPERTY(QDateTime reminderTime READ reminderTime WRITE setReminderTime NOTIFY reminderTimeChanged)
21 Q_PROPERTY(bool reminderDone READ reminderDone WRITE setReminderDone NOTIFY reminderDoneChanged)
22 Q_PROPERTY(QDateTime reminderDoneTime READ reminderDoneTime WRITE setReminderDoneTime NOTIFY reminderDoneChanged)
23 Q_PROPERTY(bool isSearchResult READ isSearchResult NOTIFY isSearchResultChanged)
24 // Don't forget to update clone() if you add properties!
25
14public:26public:
15 explicit Note(const QString &guid = QString(), QObject *parent = 0);27 explicit Note(const QString &guid, const QDateTime &created, QObject *parent = 0);
1628
17 QString guid() const;29 QString guid() const;
18 void setGuid(const QString &guid);
1930
20 QString notebookGuid() const;31 QString notebookGuid() const;
21 void setNotebookGuid(const QString &notebookGuid);32 void setNotebookGuid(const QString &notebookGuid);
2233
34 QDateTime created() const;
35
23 QString title() const;36 QString title() const;
24 void setTitle(const QString &title);37 void setTitle(const QString &title);
2538
26 QString content() const;39 QString content() const;
27 void setContent(const QString &content);40 void setContent(const QString &content);
2841
42 QString plaintextContent() const;
43 void setPlaintextContent(const QString &plaintextContent);
44
45 // This is the QML representation as we don't want to deal with timestamps there.
46 // setting it to false will reset the reminderOrder to 0, setting it to true will
47 // create a new timestamp for it.
48 bool reminder() const;
49 void setReminder(bool reminder);
50
51 qint64 reminderOrder() const;
52 void setReminderOrder(qint64 reminderOrder);
53
54 QDateTime reminderTime() const;
55 void setReminderTime(const QDateTime &reminderTime);
56
57 // This is the QML representation as we don't want to deal with timestamps there.
58 // setting it to false will reset reminderDoneTime to 0, setting it to true will
59 // create a new timestamp for it.
60 bool reminderDone() const;
61 void setReminderDone(bool reminderDone);
62
63 QDateTime reminderDoneTime() const;
64 void setReminderDoneTime(const QDateTime &reminderDoneTime);
65
66 bool isSearchResult() const;
67 void setIsSearchResult(bool isSearchResult);
68
69 Note* clone();
70
29public slots:71public slots:
30 void save();72 void save();
31 void remove();73 void remove();
3274
33signals:75signals:
34 void guidChanged();
35 void titleChanged();76 void titleChanged();
36 void notebookGuidChanged();77 void notebookGuidChanged();
37 void contentChanged();78 void contentChanged();
79 void reminderChanged();
80 void reminderTimeChanged();
81 void reminderDoneChanged();
82 void isSearchResultChanged();
3883
39private:84private:
40 QString m_guid;85 QString m_guid;
41 QString m_notebookGuid;86 QString m_notebookGuid;
87 QDateTime m_created;
42 QString m_title;88 QString m_title;
43 QString m_content;89 QString m_content;
90 QString m_plaintextContent;
91 qint64 m_reminderOrder;
92 QDateTime m_reminderTime;
93 QDateTime m_reminderDoneTime;
94 bool m_isSearchResult;
44};95};
4596
46#endif // NOTE_H97#endif // NOTE_H
4798
=== modified file 'src/plugin/Evernote/notebooks.cpp'
--- src/plugin/Evernote/notebooks.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/notebooks.cpp 2013-12-14 00:07:45 +0000
@@ -35,7 +35,6 @@
3535
36QVariant Notebooks::data(const QModelIndex &index, int role) const36QVariant Notebooks::data(const QModelIndex &index, int role) const
37{37{
38
39 Notebook *notebook = NotesStore::instance()->notebook(m_list.at(index.row()));38 Notebook *notebook = NotesStore::instance()->notebook(m_list.at(index.row()));
40 switch(role) {39 switch(role) {
41 case RoleGuid:40 case RoleGuid:
4241
=== modified file 'src/plugin/Evernote/notes.cpp'
--- src/plugin/Evernote/notes.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/notes.cpp 2013-12-14 00:07:45 +0000
@@ -24,37 +24,12 @@
24#include <QDebug>24#include <QDebug>
2525
26Notes::Notes(QObject *parent) :26Notes::Notes(QObject *parent) :
27 QAbstractListModel(parent)27 QSortFilterProxyModel(parent),
28{28 m_onlyReminders(false)
29 connect(NotesStore::instance(), &NotesStore::noteAdded, this, &Notes::noteAdded);29{
30 connect(NotesStore::instance(), &NotesStore::noteRemoved, this, &Notes::noteRemoved);30 setSourceModel(NotesStore::instance());
31 connect(NotesStore::instance(), &NotesStore::noteChanged, this, &Notes::noteChanged);31 setSortRole(NotesStore::RoleCreated);
32}32 sort(0, Qt::DescendingOrder);
33
34QVariant Notes::data(const QModelIndex &index, int role) const
35{
36 Note *note = NotesStore::instance()->note(m_list.at(index.row()));
37 switch(role) {
38 case RoleGuid:
39 return note->guid();
40 case RoleTitle:
41 return note->title();
42 }
43
44 return QVariant();
45}
46
47int Notes::rowCount(const QModelIndex &parent) const
48{
49 return m_list.count();
50}
51
52QHash<int, QByteArray> Notes::roleNames() const
53{
54 QHash<int, QByteArray> roles;
55 roles.insert(RoleGuid, "guid");
56 roles.insert(RoleTitle, "title");
57 return roles;
58}33}
5934
60QString Notes::filterNotebookGuid() const35QString Notes::filterNotebookGuid() const
@@ -67,53 +42,56 @@
67 if (m_filterNotebookGuid != notebookGuid) {42 if (m_filterNotebookGuid != notebookGuid) {
68 m_filterNotebookGuid = notebookGuid;43 m_filterNotebookGuid = notebookGuid;
69 emit filterNotebookGuidChanged();44 emit filterNotebookGuidChanged();
70 }45 invalidateFilter();
71}46 }
7247}
73Note* Notes::note(const QString &guid)48
74{49bool Notes::onlyReminders() const
75 NotesStore::instance()->refreshNoteContent(guid);50{
76 return NotesStore::instance()->note(guid);51 return m_onlyReminders;
77}52}
7853
79void Notes::componentComplete()54void Notes::setOnlyReminders(bool onlyReminders)
80{55{
81 foreach (Note *note, NotesStore::instance()->notes()) {56 if (m_onlyReminders != onlyReminders) {
82 if (m_filterNotebookGuid.isEmpty() || note->notebookGuid() == m_filterNotebookGuid) {57 m_onlyReminders = onlyReminders;
83 m_list.append(note->guid());58 emit onlyRemindersChanged();
84 }59 invalidateFilter();
85 }60 }
86 beginInsertRows(QModelIndex(), 0, m_list.count() - 1);61}
87 endInsertRows();62
88 refresh();63bool Notes::onlySearchResults() const
89}64{
9065 return m_onlySearchResults;
91void Notes::refresh()66}
92{67
93 NotesStore::instance()->refreshNotes(m_filterNotebookGuid);68void Notes::setOnlySearchResults(bool onlySearchResults)
94}69{
9570 if (m_onlySearchResults != onlySearchResults) {
96void Notes::noteAdded(const QString &guid)71 m_onlySearchResults = onlySearchResults;
97{72 emit onlySearchResultsChanged();
98 beginInsertRows(QModelIndex(), m_list.count(), m_list.count());73 invalidateFilter();
99 m_list.append(guid);74 }
100 endInsertRows();75}
101}76
10277bool Notes::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
103void Notes::noteChanged(const QString &guid)78{
104{79 QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
105 int row = m_list.indexOf(guid);80 if (!m_filterNotebookGuid.isEmpty()) {
106 if (row >= 0) {81 if (sourceModel()->data(sourceIndex, NotesStore::RoleNotebookGuid).toString() != m_filterNotebookGuid) {
107 emit dataChanged(index(row), index(row));82 return false;
108 }83 }
109}84 }
11085 if (m_onlyReminders) {
111void Notes::noteRemoved(const QString &guid)86 if (!sourceModel()->data(sourceIndex, NotesStore::RoleReminder).toBool()) {
112{87 return false;
113 int index = m_list.indexOf(guid);88 }
114 if (index >= 0) {89 }
115 beginRemoveRows(QModelIndex(), index, index);90 if (m_onlySearchResults) {
116 m_list.removeAt(index);91 Note *note = NotesStore::instance()->note(sourceModel()->data(sourceIndex, NotesStore::RoleGuid).toString());
117 endRemoveRows();92 if (!note->isSearchResult()) {
118 }93 return false;
94 }
95 }
96 return true;
119}97}
12098
=== modified file 'src/plugin/Evernote/notes.h'
--- src/plugin/Evernote/notes.h 2013-11-25 00:49:48 +0000
+++ src/plugin/Evernote/notes.h 2013-12-14 00:07:45 +0000
@@ -3,47 +3,39 @@
33
4#include "notesstore.h"4#include "notesstore.h"
55
6#include <QAbstractListModel>6#include <QSortFilterProxyModel>
7#include <QQmlParserStatus>
87
9class Notes : public QAbstractListModel, public QQmlParserStatus8class Notes : public QSortFilterProxyModel
10{9{
11 Q_OBJECT10 Q_OBJECT
12 Q_PROPERTY(QString filterNotebookGuid READ filterNotebookGuid WRITE setFilterNotebookGuid NOTIFY filterNotebookGuidChanged)11 Q_PROPERTY(QString filterNotebookGuid READ filterNotebookGuid WRITE setFilterNotebookGuid NOTIFY filterNotebookGuidChanged)
12 Q_PROPERTY(bool onlyReminders READ onlyReminders WRITE setOnlyReminders NOTIFY onlyRemindersChanged)
13 Q_PROPERTY(bool onlySearchResults READ onlySearchResults WRITE setOnlySearchResults NOTIFY onlySearchResultsChanged)
14
13public:15public:
14 enum Roles {
15 RoleGuid,
16 RoleTitle
17 };
18 explicit Notes(QObject *parent = 0);16 explicit Notes(QObject *parent = 0);
1917
20 QVariant data(const QModelIndex &index, int role) const;
21 int rowCount(const QModelIndex &parent) const;
22 QHash<int, QByteArray> roleNames() const;
23
24 QString filterNotebookGuid() const;18 QString filterNotebookGuid() const;
25 void setFilterNotebookGuid(const QString &notebookGuid);19 void setFilterNotebookGuid(const QString &notebookGuid);
2620
27 Q_INVOKABLE Note* note(const QString &guid);21 bool onlyReminders() const;
2822 void setOnlyReminders(bool onlyReminders);
29 void classBegin() {}23
30 void componentComplete();24 bool onlySearchResults() const;
3125 void setOnlySearchResults(bool onlySearchResults);
32public slots:26
33 void refresh();27protected:
3428 bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
35private slots:
36 void noteAdded(const QString &guid);
37 void noteChanged(const QString &guid);
38 void noteRemoved(const QString &guid);
3929
40signals:30signals:
41 void filterNotebookGuidChanged();31 void filterNotebookGuidChanged();
32 void onlyRemindersChanged();
33 void onlySearchResultsChanged();
4234
43private:35private:
44 QList<QString> m_list;
45 QString m_filterNotebookGuid;36 QString m_filterNotebookGuid;
4637 bool m_onlyReminders;
38 bool m_onlySearchResults;
47};39};
4840
49#endif // NOTES_H41#endif // NOTES_H
5042
=== modified file 'src/plugin/Evernote/notesstore.cpp'
--- src/plugin/Evernote/notesstore.cpp 2013-11-27 17:33:36 +0000
+++ src/plugin/Evernote/notesstore.cpp 2013-12-14 00:07:45 +0000
@@ -19,6 +19,7 @@
19 */19 */
2020
21#include "notesstore.h"21#include "notesstore.h"
22#include "evernoteconnection.h"
22#include "notebooks.h"23#include "notebooks.h"
23#include "notebook.h"24#include "notebook.h"
24#include "note.h"25#include "note.h"
@@ -30,73 +31,24 @@
30#include "jobs/createnotejob.h"31#include "jobs/createnotejob.h"
31#include "jobs/savenotejob.h"32#include "jobs/savenotejob.h"
32#include "jobs/deletenotejob.h"33#include "jobs/deletenotejob.h"
3334#include "jobs/createnotebookjob.h"
34// Thrift35#include "jobs/expungenotebookjob.h"
35#include <arpa/inet.h> // seems thrift forgot this one
36#include <protocol/TBinaryProtocol.h>
37#include <transport/THttpClient.h>
38#include <transport/TSSLSocket.h>
39#include <Thrift.h>
4036
41#include <QDebug>37#include <QDebug>
4238
43using namespace apache::thrift;
44using namespace apache::thrift::protocol;
45using namespace apache::thrift::transport;
46
47NotesStore* NotesStore::s_instance = 0;39NotesStore* NotesStore::s_instance = 0;
4840
49NotesStore::NotesStore(QObject *parent) :41NotesStore::NotesStore(QObject *parent) :
50 QObject(parent),42 QAbstractListModel(parent)
51 m_currentJob(0)
52{43{
53 try {44 connect(EvernoteConnection::instance(), &EvernoteConnection::tokenChanged, this, &NotesStore::refreshNotebooks);
54 // FIXME: need to populate this string from the system45 connect(EvernoteConnection::instance(), SIGNAL(tokenChanged()), this, SLOT(refreshNotes()));
55 // The structure should be:46
56 // application/version; platform/version; [ device/version ]47 qRegisterMetaType<EvernoteConnection::ErrorCode>("EvernoteConnection::ErrorCode");
57 // E.g. "Evernote Windows/3.0.1; Windows/XP SP3"
58 QString EDAM_CLIENT_NAME = QStringLiteral("Reminders/0.1; Ubuntu/13.10");
59 QString EVERNOTE_HOST = QStringLiteral("sandbox.evernote.com");
60 QString EDAM_USER_STORE_PATH = QStringLiteral("/edam/note");
61 boost::shared_ptr<TSocket> socket;
62 bool use_SSL = true;
63
64 if (use_SSL) {
65 // Create an SSL socket
66 // FIXME: this fails with the following error:
67 // Thrift: Fri Nov 15 12:47:31 2013 SSL_shutdown: error code: 0
68 // SSL_get_verify_result(), unable to get local issuer certificate
69 // Additionally, the UI blocks and does not load for about 2 minutes
70 boost::shared_ptr<TSSLSocketFactory> sslSocketFactory(new TSSLSocketFactory());
71 socket = sslSocketFactory->createSocket(EVERNOTE_HOST.toStdString(), 443);
72 qDebug() << "created SSL socket";
73 } else {
74 // Create a non-secure socket
75 socket = boost::shared_ptr<TSocket> (new TSocket(EVERNOTE_HOST.toStdString(), 80));
76 qDebug() << "created insecure socket";
77 }
78
79 boost::shared_ptr<TBufferedTransport> bufferedTransport(new TBufferedTransport(socket));
80 boost::shared_ptr<THttpClient> userStoreHttpClient (new THttpClient(bufferedTransport,
81 EVERNOTE_HOST.toStdString(),
82 EDAM_USER_STORE_PATH.toStdString()));
83 userStoreHttpClient->open();
84
85 boost::shared_ptr<TProtocol> iprot(new TBinaryProtocol(userStoreHttpClient));
86 m_client = new evernote::edam::NoteStoreClient(iprot);
87
88 qDebug() << "NoteStore client created.";
89
90 } catch (const TTransportException & e) {
91 qWarning() << "Failed to create Transport:" << e.what();
92 } catch (const TException & e) {
93 qWarning() << "Generic Thrift exception:" << e.what();
94 }
95
96 qRegisterMetaType<NotesStore::ErrorCode>("NotesStore::ErrorCode");
97 qRegisterMetaType<evernote::edam::NotesMetadataList>("evernote::edam::NotesMetadataList");48 qRegisterMetaType<evernote::edam::NotesMetadataList>("evernote::edam::NotesMetadataList");
98 qRegisterMetaType<evernote::edam::Note>("evernote::edam::Note");49 qRegisterMetaType<evernote::edam::Note>("evernote::edam::Note");
99 qRegisterMetaType<std::vector<evernote::edam::Notebook> >("std::vector<evernote::edam::Notebook>");50 qRegisterMetaType<std::vector<evernote::edam::Notebook> >("std::vector<evernote::edam::Notebook>");
51 qRegisterMetaType<evernote::edam::Notebook>("evernote::edam::Notebook");
10052
101}53}
10254
@@ -108,255 +60,317 @@
108 return s_instance;60 return s_instance;
109}61}
11062
111QString NotesStore::errorCodeToString(NotesStore::ErrorCode errorCode)63int NotesStore::rowCount(const QModelIndex &parent) const
112{64{
113 switch(errorCode) {65 return m_notes.count();
114 case ErrorCodeNoError:66}
115 return QStringLiteral("No error");67
116 case ErrorCodeUserException:68QVariant NotesStore::data(const QModelIndex &index, int role) const
117 return QStringLiteral("User exception");69{
118 case ErrorCodeSystemException:70 switch (role) {
119 return QStringLiteral("System exception");71 case RoleGuid:
120 case ErrorCodeNotFoundExcpetion:72 return m_notes.at(index.row())->guid();
121 return QStringLiteral("Not found");73 case RoleNotebookGuid:
74 return m_notes.at(index.row())->notebookGuid();
75 case RoleCreated:
76 return m_notes.at(index.row())->created();
77 case RoleTitle:
78 return m_notes.at(index.row())->title();
79 case RoleReminder:
80 return m_notes.at(index.row())->reminder();
81 case RoleReminderTime:
82 return m_notes.at(index.row())->reminderTime();
83 case RoleReminderDone:
84 return m_notes.at(index.row())->reminderDone();
85 case RoleReminderDoneTime:
86 return m_notes.at(index.row())->reminderDoneTime();
122 }87 }
123 return QString();88 return QVariant();
89}
90
91QHash<int, QByteArray> NotesStore::roleNames() const
92{
93 QHash<int, QByteArray> roles;
94 roles.insert(RoleGuid, "guid");
95 roles.insert(RoleNotebookGuid, "notebookGuid");
96 roles.insert(RoleCreated, "created");
97 roles.insert(RoleTitle, "title");
98 roles.insert(RoleReminder, "reminder");
99 roles.insert(RoleReminderTime, "reminderTime");
100 roles.insert(RoleReminderDone, "reminderDone");
101 roles.insert(RoleReminderDoneTime, "reminderDoneTime");
102 return roles;
124}103}
125104
126NotesStore::~NotesStore()105NotesStore::~NotesStore()
127{106{
128 delete m_client;
129}
130
131QString NotesStore::token() const
132{
133 return m_token;
134}
135
136void NotesStore::setToken(const QString &token)
137{
138 if (token != m_token) {
139 m_token = token;
140 emit tokenChanged();
141 refreshNotebooks();
142 refreshNotes();
143 }
144}107}
145108
146QList<Note*> NotesStore::notes() const109QList<Note*> NotesStore::notes() const
147{110{
148 return m_notes.values();111 return m_notes;
149}112}
150113
151Note *NotesStore::note(const QString &guid)114Note *NotesStore::note(const QString &guid)
152{115{
153 return m_notes.value(guid);116 return m_notesHash.value(guid);
154}
155
156void NotesStore::saveNote(const QString &guid)
157{
158 Note *note = m_notes.value(guid);
159
160 QString enml = Html2EnmlConverter::html2enml(note->content());
161 note->setContent(enml);
162
163 SaveNoteJob *job = new SaveNoteJob(note, this);
164 connect(job, &SaveNoteJob::resultReady, this, &NotesStore::saveNoteJobDone);
165 m_jobQueue.append(job);
166 startJobQueue();
167}
168
169void NotesStore::deleteNote(const QString &guid)
170{
171 DeleteNoteJob *job = new DeleteNoteJob(guid, this);
172 connect(job, &DeleteNoteJob::resultReady, this, &NotesStore::deleteNoteJobDone);
173 m_jobQueue.append(job);
174 startJobQueue();
175}117}
176118
177QList<Notebook *> NotesStore::notebooks() const119QList<Notebook *> NotesStore::notebooks() const
178{120{
179 return m_notebooks.values();121 return m_notebooks;
180}122}
181123
182Notebook *NotesStore::notebook(const QString &guid)124Notebook *NotesStore::notebook(const QString &guid)
183{125{
184 return m_notebooks.value(guid);126 return m_notebooksHash.value(guid);
185}127}
186128
187void NotesStore::startJobQueue()129void NotesStore::createNotebook(const QString &name)
188{130{
189 if (m_jobQueue.isEmpty()) {131 CreateNotebookJob *job = new CreateNotebookJob(name);
190 return;132 connect(job, &CreateNotebookJob::jobDone, this, &NotesStore::createNotebookJobDone);
191 }133 EvernoteConnection::instance()->enqueue(job);
192134}
193 if (m_currentJob) {135
194 return;136void NotesStore::expungeNotebook(const QString &guid)
195 }137{
196 m_currentJob = m_jobQueue.takeFirst();138 ExpungeNotebookJob *job = new ExpungeNotebookJob(guid);
197 m_currentJob->start();139 connect(job, &ExpungeNotebookJob::jobDone, this, &NotesStore::expungeNotebookJobDone);
198}140 EvernoteConnection::instance()->enqueue(job);
199
200void NotesStore::startNextJob()
201{
202 m_currentJob = 0;
203 startJobQueue();
204}141}
205142
206void NotesStore::refreshNotes(const QString &filterNotebookGuid)143void NotesStore::refreshNotes(const QString &filterNotebookGuid)
207{144{
208 if (m_token.isEmpty()) {
209 qWarning() << "No token set. Cannot fetch notes.";
210 return;
211 }
212
213 FetchNotesJob *job = new FetchNotesJob(filterNotebookGuid);145 FetchNotesJob *job = new FetchNotesJob(filterNotebookGuid);
214 connect(job, &FetchNotesJob::resultReady, this, &NotesStore::fetchNotesJobDone);146 connect(job, &FetchNotesJob::jobDone, this, &NotesStore::fetchNotesJobDone);
215147 EvernoteConnection::instance()->enqueue(job);
216 m_jobQueue.append(job);
217 startJobQueue();
218}148}
219149
220void NotesStore::fetchNotesJobDone(ErrorCode errorCode, const evernote::edam::NotesMetadataList &results)150void NotesStore::fetchNotesJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::NotesMetadataList &results)
221{151{
222 if (errorCode != ErrorCodeNoError) {152 if (errorCode != EvernoteConnection::ErrorCodeNoError) {
223 qWarning() << "Failed to fetch notes list:" << errorCodeToString(errorCode);153 qWarning() << "Failed to fetch notes list:" << errorMessage;
224 startNextJob();
225 return;154 return;
226 }155 }
227156
228 for (int i = 0; i < results.notes.size(); ++i) {157 for (int i = 0; i < results.notes.size(); ++i) {
229 evernote::edam::NoteMetadata result = results.notes.at(i);158 evernote::edam::NoteMetadata result = results.notes.at(i);
230 Note *note = m_notes.value(QString::fromStdString(result.guid));159 Note *note = m_notesHash.value(QString::fromStdString(result.guid));
231 if (note) {160 bool newNote = note == 0;
232 note->setTitle(QString::fromStdString(result.title));161 if (newNote) {
233 note->setNotebookGuid(QString::fromStdString(result.notebookGuid));162 QString guid = QString::fromStdString(result.guid);
163 QDateTime created = QDateTime::fromMSecsSinceEpoch(result.created);
164 note = new Note(guid, created, this);
165 }
166
167 note->setTitle(QString::fromStdString(result.title));
168 note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
169 note->setReminderOrder(result.attributes.reminderOrder);
170
171 if (!results.searchedWords.empty()) {
172 note->setIsSearchResult(true);
173 }
174
175 QDateTime reminderDoneTime;
176 if (result.attributes.reminderDoneTime > 0) {
177 reminderDoneTime = QDateTime::fromMSecsSinceEpoch(result.attributes.reminderDoneTime);
178 }
179 note->setReminderDoneTime(reminderDoneTime);
180
181 if (newNote) {
182 beginInsertRows(QModelIndex(), m_notes.count(), m_notes.count());
183 m_notesHash.insert(note->guid(), note);
184 m_notes.append(note);
185 endInsertRows();
186 emit noteAdded(note->guid());
187 } else {
188 QModelIndex noteIndex = index(m_notes.indexOf(note));
189 emit dataChanged(noteIndex, noteIndex);
234 emit noteChanged(note->guid());190 emit noteChanged(note->guid());
235 } else {
236 note = new Note(QString::fromStdString(result.guid), this);
237 note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
238 note->setTitle(QString::fromStdString(result.title));
239 m_notes.insert(note->guid(), note);
240 emit noteAdded(note->guid());
241 }191 }
242 }192 }
243
244 startNextJob();
245}193}
246194
247void NotesStore::refreshNoteContent(const QString &guid)195void NotesStore::refreshNoteContent(const QString &guid)
248{196{
249 if (m_token.isEmpty()) {
250 qWarning() << "No token set. Cannot fetch note.";
251 return;
252 }
253
254 FetchNoteJob *job = new FetchNoteJob(guid, this);197 FetchNoteJob *job = new FetchNoteJob(guid, this);
255 connect(job, &FetchNoteJob::resultReady, this, &NotesStore::fetchNoteJobDone);198 connect(job, &FetchNoteJob::resultReady, this, &NotesStore::fetchNoteJobDone);
256 m_jobQueue.append(job);199 EvernoteConnection::instance()->enqueue(job);
257
258 startJobQueue();
259}200}
260201
261void NotesStore::fetchNoteJobDone(ErrorCode errorCode, const evernote::edam::Note &result)202void NotesStore::fetchNoteJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Note &result)
262{203{
263 if (errorCode != ErrorCodeNoError) {204 if (errorCode != EvernoteConnection::ErrorCodeNoError) {
264 qWarning() << "Error fetching note:" << errorCode;205 qWarning() << "Error fetching note:" << errorMessage;
265 startNextJob();
266 return;206 return;
267 }207 }
268208
269 Note *note = m_notes.value(QString::fromStdString(result.guid));209 Note *note = m_notesHash.value(QString::fromStdString(result.guid));
270 note->setNotebookGuid(QString::fromStdString(result.notebookGuid));210 note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
271 note->setTitle(QString::fromStdString(result.title));211 note->setTitle(QString::fromStdString(result.title));
272 note->setContent(QString::fromStdString(result.content));212 note->setContent(QString::fromStdString(result.content));
213 note->setReminderOrder(result.attributes.reminderOrder);
214 QDateTime reminderDoneTime;
215 if (result.attributes.reminderDoneTime > 0) {
216 reminderDoneTime = QDateTime::fromMSecsSinceEpoch(result.attributes.reminderDoneTime);
217 }
218 note->setReminderDoneTime(reminderDoneTime);
273 emit noteChanged(note->guid());219 emit noteChanged(note->guid());
274220
275 startNextJob();221 QModelIndex noteIndex = index(m_notes.indexOf(note));
222 emit dataChanged(noteIndex, noteIndex);
276}223}
277224
278void NotesStore::refreshNotebooks()225void NotesStore::refreshNotebooks()
279{226{
280 if (m_token.isEmpty()) {
281 qWarning() << "No token set. Cannot refresh notebooks.";
282 return;
283 }
284
285 FetchNotebooksJob *job = new FetchNotebooksJob();227 FetchNotebooksJob *job = new FetchNotebooksJob();
286 connect(job, &FetchNotebooksJob::resultReady, this, &NotesStore::fetchNotebooksJobDone);228 connect(job, &FetchNotebooksJob::jobDone, this, &NotesStore::fetchNotebooksJobDone);
287229 EvernoteConnection::instance()->enqueue(job);
288 m_jobQueue.append(job);
289 startJobQueue();
290}230}
291231
292void NotesStore::fetchNotebooksJobDone(ErrorCode errorCode, const std::vector<evernote::edam::Notebook> &results)232void NotesStore::fetchNotebooksJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const std::vector<evernote::edam::Notebook> &results)
293{233{
294 if (errorCode != ErrorCodeNoError) {234 if (errorCode != EvernoteConnection::ErrorCodeNoError) {
295 qWarning() << "Error fetching notebooks:" << errorCodeToString(errorCode);235 qWarning() << "Error fetching notebooks:" << errorMessage;
296 startNextJob();
297 return;236 return;
298 }237 }
299238
300 for (int i = 0; i < results.size(); ++i) {239 for (int i = 0; i < results.size(); ++i) {
301 evernote::edam::Notebook result = results.at(i);240 evernote::edam::Notebook result = results.at(i);
302 Notebook *notebook = m_notebooks.value(QString::fromStdString(result.guid));241 Notebook *notebook = m_notebooksHash.value(QString::fromStdString(result.guid));
303 if (notebook) {242 bool newNoteNotebook = notebook == 0;
304 qDebug() << "got notebook update";243 if (newNoteNotebook) {
305 notebook->setName(QString::fromStdString(result.name));
306 emit notebookChanged(notebook->guid());
307 } else {
308 notebook = new Notebook(QString::fromStdString(result.guid), this);244 notebook = new Notebook(QString::fromStdString(result.guid), this);
309 notebook->setName(QString::fromStdString(result.name));245 }
310 m_notebooks.insert(notebook->guid(), notebook);246 notebook->setName(QString::fromStdString(result.name));
247
248 if (newNoteNotebook) {
249 m_notebooksHash.insert(notebook->guid(), notebook);
250 m_notebooks.append(notebook);
311 emit notebookAdded(notebook->guid());251 emit notebookAdded(notebook->guid());
312 qDebug() << "got new notebook" << notebook->guid();252 } else {
253 emit notebookChanged(notebook->guid());
313 }254 }
314 }255 }
315
316 startNextJob();
317}256}
318257
319void NotesStore::createNote(const QString &title, const QString &notebookGuid, const QString &content)258void NotesStore::createNote(const QString &title, const QString &notebookGuid, const QString &content)
320{259{
321 Note *note = new Note();260 CreateNoteJob *job = new CreateNoteJob(title, notebookGuid, content);
322 note->setTitle(title);261 connect(job, &CreateNoteJob::jobDone, this, &NotesStore::createNoteJobDone);
323 note->setNotebookGuid(notebookGuid);262 EvernoteConnection::instance()->enqueue(job);
324 note->setContent(content);263}
325 CreateNoteJob *job = new CreateNoteJob(note);264
326 connect(job, &CreateNoteJob::resultReady, this, &NotesStore::createNoteJobDone);265void NotesStore::createNoteJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Note &result)
327266{
328 m_jobQueue.append(job);267 if (errorCode != EvernoteConnection::ErrorCodeNoError) {
329 startJobQueue();268 qWarning() << "Error creating note:" << errorMessage;
330}269 return;
331270 }
332void NotesStore::createNoteJobDone(NotesStore::ErrorCode errorCode, Note *note)271
333{272 QString guid = QString::fromStdString(result.guid);
334 if (errorCode != ErrorCodeNoError) {273 QDateTime created = QDateTime::fromMSecsSinceEpoch(result.created);
335 qWarning() << "Error creating note:" << errorCodeToString(errorCode);274 Note *note = new Note(guid, created, this);
336 delete note;275 note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
337 startNextJob();276 note->setTitle(QString::fromStdString(result.title));
338 return;277 note->setContent(QString::fromStdString(result.content));
339 }278
340279 beginInsertRows(QModelIndex(), m_notes.count(), m_notes.count());
341 m_notes.insert(note->guid(), note);280 m_notesHash.insert(note->guid(), note);
342 noteAdded(note->guid());281 m_notes.append(note);
343 startNextJob();282 endInsertRows();
344}283
345284 emit noteAdded(note->guid());
346void NotesStore::saveNoteJobDone(NotesStore::ErrorCode errorCode, Note *note)285}
347{286
348 startNextJob();287void NotesStore::saveNote(const QString &guid)
349}288{
350289 Note *note = m_notesHash.value(guid);
351void NotesStore::deleteNoteJobDone(NotesStore::ErrorCode errorCode, const QString &guid)290
352{291 QString enml = Html2EnmlConverter::html2enml(note->content());
353 if (errorCode != ErrorCodeNoError) {292 note->setContent(enml);
354 qWarning() << "Cannot delete note:" << errorCodeToString(errorCode);293
355 startNextJob();294 SaveNoteJob *job = new SaveNoteJob(note, this);
295 connect(job, &SaveNoteJob::jobDone, this, &NotesStore::saveNoteJobDone);
296 EvernoteConnection::instance()->enqueue(job);
297}
298
299void NotesStore::saveNoteJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Note &result)
300{
301 if (errorCode != EvernoteConnection::ErrorCodeNoError) {
302 qWarning() << "error saving note" << errorMessage;
303 return;
304 }
305
306 Note *note = m_notesHash.value(QString::fromStdString(result.guid));
307 if (note) {
308 note->setTitle(QString::fromStdString(result.title));
309 note->setNotebookGuid(QString::fromStdString(result.notebookGuid));
310
311 emit noteChanged(note->guid());
312
313 QModelIndex noteIndex = index(m_notes.indexOf(note));
314 emit dataChanged(noteIndex, noteIndex);
315 }
316}
317
318void NotesStore::deleteNote(const QString &guid)
319{
320 DeleteNoteJob *job = new DeleteNoteJob(guid, this);
321 connect(job, &DeleteNoteJob::jobDone, this, &NotesStore::deleteNoteJobDone);
322 EvernoteConnection::instance()->enqueue(job);
323}
324
325void NotesStore::findNotes(const QString &searchWords)
326{
327 foreach (Note *note, m_notes) {
328 note->setIsSearchResult(false);
329 }
330 emit dataChanged(index(0), index(m_notes.count()), QVector<int>() << RoleIsSearchResult);
331
332 FetchNotesJob *job = new FetchNotesJob(QString(), searchWords);
333 connect(job, &FetchNotesJob::jobDone, this, &NotesStore::fetchNotesJobDone);
334 EvernoteConnection::instance()->enqueue(job);
335}
336
337void NotesStore::deleteNoteJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid)
338{
339 if (errorCode != EvernoteConnection::ErrorCodeNoError) {
340 qWarning() << "Cannot delete note:" << errorMessage;
356 return;341 return;
357 }342 }
358 emit noteRemoved(guid);343 emit noteRemoved(guid);
359 m_notes.take(guid)->deleteLater();344
360 startNextJob();345 Note *note = m_notesHash.value(guid);
361}346 int noteIndex = m_notes.indexOf(note);
362347 beginRemoveRows(QModelIndex(), noteIndex, noteIndex);
348 m_notes.takeAt(noteIndex);
349 m_notesHash.take(guid)->deleteLater();
350 endRemoveRows();
351}
352
353void NotesStore::createNotebookJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Notebook &result)
354{
355 if (errorCode != EvernoteConnection::ErrorCodeNoError) {
356 qWarning() << "Error creating notebook:" << errorMessage;
357 return;
358 }
359 Notebook *notebook = new Notebook(QString::fromStdString(result.guid));
360 notebook->setName(QString::fromStdString(result.name));
361 m_notebooks.append(notebook);
362 m_notebooksHash.insert(notebook->guid(), notebook);
363 emit notebookAdded(notebook->guid());
364}
365
366void NotesStore::expungeNotebookJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid)
367{
368 if (errorCode != EvernoteConnection::ErrorCodeNoError) {
369 qWarning() << "Error expunging notebook:" << errorMessage;
370 return;
371 }
372 emit notebookRemoved(guid);
373 Notebook *notebook = m_notebooksHash.take(guid);
374 m_notebooks.removeAll(notebook);
375 notebook->deleteLater();
376}
363377
=== modified file 'src/plugin/Evernote/notesstore.h'
--- src/plugin/Evernote/notesstore.h 2013-11-25 00:49:48 +0000
+++ src/plugin/Evernote/notesstore.h 2013-12-14 00:07:45 +0000
@@ -1,53 +1,67 @@
1#ifndef NOTESSTORE_H1#ifndef NOTESSTORE_H
2#define NOTESSTORE_H2#define NOTESSTORE_H
33
4#include "evernoteconnection.h"
5
6// Thrift
7#include <arpa/inet.h> // seems thrift forgot this one
8#include <protocol/TBinaryProtocol.h>
9#include <transport/THttpClient.h>
10#include <transport/TSSLSocket.h>
11#include <Thrift.h>
12
4// Evernote SDK13// Evernote SDK
5#include <NoteStore.h>14#include <NoteStore.h>
6#include <NoteStore_constants.h>15#include <NoteStore_constants.h>
7#include <Errors_types.h>16#include <Errors_types.h>
817
9#include <QObject>18#include <QAbstractListModel>
10#include <QHash>19#include <QHash>
1120
12class EvernoteJob;
13
14class Notebook;21class Notebook;
15class Note;22class Note;
1623
17class NotesStore : public QObject24using namespace apache::thrift::transport;
25
26class NotesStore : public QAbstractListModel
18{27{
19 Q_OBJECT28 Q_OBJECT
20 Q_PROPERTY(QString token READ token WRITE setToken NOTIFY tokenChanged)
21
22 friend class EvernoteJob;
2329
24public:30public:
25 enum ErrorCode {31 enum Roles {
26 ErrorCodeNoError,32 RoleGuid,
27 ErrorCodeUserException,33 RoleNotebookGuid,
28 ErrorCodeSystemException,34 RoleCreated,
29 ErrorCodeNotFoundExcpetion,35 RoleTitle,
30 ErrorCodeConnectionLost36 RoleReminder,
37 RoleReminderTime,
38 RoleReminderDone,
39 RoleReminderDoneTime,
40 RoleIsSearchResult
31 };41 };
3242
33 Q_INVOKABLE void createNote(const QString &title, const QString &notebookGuid, const QString &content);43 ~NotesStore();
34
35 static NotesStore *instance();44 static NotesStore *instance();
36 static QString errorCodeToString(ErrorCode errorCode);45
3746 // reimplemented from QAbstractListModel
38 ~NotesStore();47 int rowCount(const QModelIndex &parent) const;
3948 QVariant data(const QModelIndex &index, int role) const;
40 QString token() const;49 QHash<int, QByteArray> roleNames() const;
41 void setToken(const QString &token);
4250
43 QList<Note*> notes() const;51 QList<Note*> notes() const;
44 Note* note(const QString &guid);52
45 void saveNote(const QString &guid);53 Q_INVOKABLE Note* note(const QString &guid);
46 void deleteNote(const QString &guid);54 Q_INVOKABLE void createNote(const QString &title, const QString &notebookGuid, const QString &content);
55 Q_INVOKABLE void saveNote(const QString &guid);
56 Q_INVOKABLE void deleteNote(const QString &guid);
57 Q_INVOKABLE void findNotes(const QString &searchWords);
4758
48 QList<Notebook*> notebooks() const;59 QList<Notebook*> notebooks() const;
49 Notebook* notebook(const QString &guid);60 Notebook* notebook(const QString &guid);
61 Q_INVOKABLE void createNotebook(const QString &name);
62 Q_INVOKABLE void expungeNotebook(const QString &guid);
5063
64public slots:
51 void refreshNotes(const QString &filterNotebookGuid = QString());65 void refreshNotes(const QString &filterNotebookGuid = QString());
52 void refreshNoteContent(const QString &guid);66 void refreshNoteContent(const QString &guid);
53 void refreshNotebooks();67 void refreshNotebooks();
@@ -61,30 +75,28 @@
6175
62 void notebookAdded(const QString &guid);76 void notebookAdded(const QString &guid);
63 void notebookChanged(const QString &guid);77 void notebookChanged(const QString &guid);
78 void notebookRemoved(const QString &guid);
6479
65private slots:80private slots:
66 void fetchNotesJobDone(ErrorCode errorCode, const evernote::edam::NotesMetadataList &results);81 void fetchNotesJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::NotesMetadataList &results);
67 void fetchNotebooksJobDone(ErrorCode errorCode, const std::vector<evernote::edam::Notebook> &results);82 void fetchNotebooksJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const std::vector<evernote::edam::Notebook> &results);
68 void fetchNoteJobDone(ErrorCode errorCode, const evernote::edam::Note &result);83 void fetchNoteJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Note &result);
69 void createNoteJobDone(ErrorCode errorCode, Note *note);84 void createNoteJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Note &result);
70 void saveNoteJobDone(ErrorCode errorCode, Note *note);85 void saveNoteJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Note &result);
71 void deleteNoteJobDone(ErrorCode errorCode, const QString &guid);86 void deleteNoteJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid);
7287 void createNotebookJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const evernote::edam::Notebook &result);
73 void startJobQueue();88 void expungeNotebookJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &guid);
74 void startNextJob();
7589
76private:90private:
77 explicit NotesStore(QObject *parent = 0);91 explicit NotesStore(QObject *parent = 0);
78 static NotesStore *s_instance;92 static NotesStore *s_instance;
7993
80 QString m_token;94 QList<Note*> m_notes;
81 evernote::edam::NoteStoreClient *m_client;95 QList<Notebook*> m_notebooks;
8296
83 QHash<QString, Notebook*> m_notebooks;97 // Keep hashes for faster lookups as we always identify notes via guid
84 QHash<QString, Note*> m_notes;98 QHash<QString, Note*> m_notesHash;
8599 QHash<QString, Notebook*> m_notebooksHash;
86 QList<EvernoteJob*> m_jobQueue;
87 QThread *m_currentJob;
88};100};
89101
90#endif // NOTESSTORE_H102#endif // NOTESSTORE_H
91103
=== modified file 'src/plugin/Evernote/userstore.cpp'
--- src/plugin/Evernote/userstore.cpp 2013-11-26 17:18:33 +0000
+++ src/plugin/Evernote/userstore.cpp 2013-12-14 00:07:45 +0000
@@ -19,6 +19,8 @@
19 */19 */
2020
21#include "userstore.h"21#include "userstore.h"
22#include "evernoteconnection.h"
23#include "jobs/fetchusernamejob.h"
2224
23// Evernote sdk25// Evernote sdk
24#include <UserStore.h>26#include <UserStore.h>
@@ -34,106 +36,47 @@
3436
35#include <QDebug>37#include <QDebug>
3638
37using namespace evernote::edam;
38using namespace apache::thrift;39using namespace apache::thrift;
39using namespace apache::thrift::protocol;40using namespace apache::thrift::protocol;
40using namespace apache::thrift::transport;41using namespace apache::thrift::transport;
4142
43UserStore* UserStore::s_instance = 0;
44
42UserStore::UserStore(QObject *parent) :45UserStore::UserStore(QObject *parent) :
43 QObject(parent)46 QObject(parent)
44{47{
4548 connect(EvernoteConnection::instance(), &EvernoteConnection::tokenChanged, this, &UserStore::fetchUsername);
46 try {49
47 // FIXME: need to populate this string from the system50 fetchUsername();
48 // The structure should be:51}
49 // application/version; platform/version; [ device/version ]52
50 // E.g. "Evernote Windows/3.0.1; Windows/XP SP3"53UserStore *UserStore::instance()
51 QString EDAM_CLIENT_NAME = QStringLiteral("Reminders/0.1; Ubuntu/13.10");54{
52 QString EVERNOTE_HOST = QStringLiteral("sandbox.evernote.com");55 if (!s_instance) {
53 QString EDAM_USER_STORE_PATH = QStringLiteral("/edam/user");56 s_instance = new UserStore();
54 boost::shared_ptr<TSocket> socket;57 }
55 bool use_SSL = false;58 return s_instance;
5659}
57 if (use_SSL) {60
58 // Create an SSL socket61QString UserStore::username() const
59 // FIXME: this fails with the following error:62{
60 // Thrift: Fri Nov 15 12:47:31 2013 SSL_shutdown: error code: 063 return m_username;
61 // SSL_get_verify_result(), unable to get local issuer certificate64}
62 // Additionally, the UI blocks and does not load for about 2 minutes65
63 boost::shared_ptr<TSSLSocketFactory> sslSocketFactory(new TSSLSocketFactory());66void UserStore::fetchUsername()
64 socket = sslSocketFactory->createSocket(EVERNOTE_HOST.toStdString(), 443);67{
65 } else {68 FetchUsernameJob *job = new FetchUsernameJob();
66 // Create a non-secure socket69 connect(job, &FetchUsernameJob::jobDone, this, &UserStore::fetchUsernameJobDone);
67 socket = boost::shared_ptr<TSocket> (new TSocket(EVERNOTE_HOST.toStdString(), 80));70 EvernoteConnection::instance()->enqueue(job);
68 }71}
6972
70 boost::shared_ptr<TBufferedTransport> bufferedTransport(new TBufferedTransport(socket));73void UserStore::fetchUsernameJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &result)
71 boost::shared_ptr<THttpClient> userStoreHttpClient (new THttpClient(bufferedTransport,74{
72 EVERNOTE_HOST.toStdString(),75 if (errorCode != EvernoteConnection::ErrorCodeNoError) {
73 EDAM_USER_STORE_PATH.toStdString()));76 qWarning() << "Error fetching username:" << errorMessage;
74 userStoreHttpClient->open();77 return;
7578 }
76 boost::shared_ptr<TProtocol> iprot(new TBinaryProtocol(userStoreHttpClient));79
77 UserStoreClient m_client(iprot);80 m_username = result;
78 UserStoreConstants constants;81 emit usernameChanged();
79
80 // checkVersion returns true if the client is capable of talking to the service,
81 // false otherwise
82 qDebug() << "version check:" << m_client.checkVersion(EDAM_CLIENT_NAME.toStdString(),
83 constants.EDAM_VERSION_MAJOR,
84 constants.EDAM_VERSION_MINOR);
85
86 } catch(...) {
87 displayException();
88 }
89}
90
91void UserStore::getPublicUserInfo(const QString &user)
92{
93 qDebug() << "should get public user info for user" << user;
94 // PublicUserInfo userInfo;
95
96}
97
98// TODO: move to a common place instead of copying it through *store.cpps
99void UserStore::displayException()
100{
101 QString error_message = "Unknown Exception";
102 try
103 {
104 // this function is meant to be called from a catch block
105 // rethrow the exception to catch it again
106 throw;
107 }
108 catch (const EDAMNotFoundException & e)
109 {
110 qDebug() << e.what();
111 }
112 catch (const EDAMSystemException & e)
113 {
114 qDebug() << e.what();
115 }
116 catch (const EDAMUserException & e)
117 {
118 qDebug() << e.what();
119 }
120 catch (const TTransportException & e)
121 {
122 qDebug() << e.what();
123 }
124 catch (const TException & e)
125 {
126 qDebug() << e.what();
127 }
128 catch (const std::exception & e)
129 {
130 qDebug() << e.what();
131 }
132 catch (...)
133 {
134 error_message = "Tried to sync, but something went wrong.\n Unknown exception.";
135 }
136
137 qDebug() << error_message;
138 disconnect();
139}82}
14083
=== modified file 'src/plugin/Evernote/userstore.h'
--- src/plugin/Evernote/userstore.h 2013-11-24 17:03:28 +0000
+++ src/plugin/Evernote/userstore.h 2013-12-14 00:07:45 +0000
@@ -1,6 +1,9 @@
1#ifndef USERSTORE_H1#ifndef USERSTORE_H
2#define USERSTORE_H2#define USERSTORE_H
33
4#include "evernoteconnection.h"
5
6//Evernote SDK
4#include "UserStore.h"7#include "UserStore.h"
58
6#include <QObject>9#include <QObject>
@@ -8,17 +11,28 @@
8class UserStore : public QObject11class UserStore : public QObject
9{12{
10 Q_OBJECT13 Q_OBJECT
14
15 // TODO: Once we need more than just the username, turn this into a class User
16 Q_PROPERTY(QString username READ username NOTIFY usernameChanged)
17
11public:18public:
12 explicit UserStore(QObject *parent = 0);19 static UserStore* instance();
20
21 QString username() const;
1322
14signals:23signals:
1524 void usernameChanged();
16public slots:25
17 void getPublicUserInfo(const QString &user);26private slots:
27 void fetchUsername();
28
29 void fetchUsernameJobDone(EvernoteConnection::ErrorCode errorCode, const QString &errorMessage, const QString &result);
1830
19private:31private:
32 static UserStore* s_instance;
33 explicit UserStore(QObject *parent = 0);
2034
21 void displayException();35 QString m_username;
22};36};
2337
24#endif // USERSTORE_H38#endif // USERSTORE_H
2539
=== modified file 'src/plugin/Evernote/utils/html2enmlconverter.cpp'
--- src/plugin/Evernote/utils/html2enmlconverter.cpp 2013-11-25 19:06:38 +0000
+++ src/plugin/Evernote/utils/html2enmlconverter.cpp 2013-12-14 00:07:45 +0000
@@ -82,3 +82,25 @@
8282
83 return evml;83 return evml;
84}84}
85
86QString Html2EnmlConverter::enml2plaintext(const QString &enml)
87{
88 // output
89 QString plaintext;
90
91 // input
92 QXmlStreamReader reader(enml);
93
94 while (!reader.atEnd() && !reader.hasError()) {
95 QXmlStreamReader::TokenType token = reader.readNext();
96
97 // Write all normal text inside <body> </body> to output
98 if (token == QXmlStreamReader::Characters) {
99 plaintext.append(reader.text().toString());
100 plaintext.append(' ');
101 }
102 }
103
104 plaintext.remove('\n');
105 return plaintext;
106}
85107
=== modified file 'src/plugin/Evernote/utils/html2enmlconverter.h'
--- src/plugin/Evernote/utils/html2enmlconverter.h 2013-11-25 19:06:38 +0000
+++ src/plugin/Evernote/utils/html2enmlconverter.h 2013-12-14 00:07:45 +0000
@@ -9,6 +9,8 @@
9 Html2EnmlConverter();9 Html2EnmlConverter();
1010
11 static QString html2enml(const QString &html);11 static QString html2enml(const QString &html);
12
13 static QString enml2plaintext(const QString &enml);
12};14};
1315
14#endif // HTML2ENMLCONVERTER_H16#endif // HTML2ENMLCONVERTER_H

Subscribers

People subscribed via source and target branches