diff --git a/.gitignore b/.gitignore
index 30f5bca5a..81c9c7307 100755
--- a/.gitignore
+++ b/.gitignore
@@ -18,4 +18,4 @@
database.sqlite
QtClient/build-*-Debug/
*.pro.user
-notes.sqlite
\ No newline at end of file
+notes*.sqlite
\ No newline at end of file
diff --git a/QtClient/JoplinQtClient/JoplinQtClient.pro b/QtClient/JoplinQtClient/JoplinQtClient.pro
index 1a39236c5..c3832d686 100755
--- a/QtClient/JoplinQtClient/JoplinQtClient.pro
+++ b/QtClient/JoplinQtClient/JoplinQtClient.pro
@@ -18,7 +18,8 @@ SOURCES += \
services/notecache.cpp \
models/qmlnote.cpp
-RESOURCES += qml.qrc
+RESOURCES += qml.qrc \
+ database.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
diff --git a/QtClient/JoplinQtClient/build.bat b/QtClient/JoplinQtClient/build.bat
new file mode 100755
index 000000000..aaaf3a436
--- /dev/null
+++ b/QtClient/JoplinQtClient/build.bat
@@ -0,0 +1,3 @@
+"C:\Qt\5.7\msvc2015\bin\qmake.exe" D:\Web\www\joplin\QtClient\JoplinQtClient\JoplinQtClient.pro -spec win32-msvc2015 "CONFIG+=debug" "CONFIG+=qml_debug"
+"C:\Qt\Tools\QtCreator\bin\jom.exe" qmake_all
+"C:\Qt\Tools\QtCreator\bin\jom.exe"
\ No newline at end of file
diff --git a/QtClient/JoplinQtClient/database.cpp b/QtClient/JoplinQtClient/database.cpp
index 9316c4df1..8016e913e 100755
--- a/QtClient/JoplinQtClient/database.cpp
+++ b/QtClient/JoplinQtClient/database.cpp
@@ -5,7 +5,7 @@ using namespace jop;
Database::Database(const QString &path) {
version_ = -1;
- //QFile::remove(path);
+ QFile::remove(path);
db_ = QSqlDatabase::addDatabase("QSQLITE");
db_.setDatabaseName(path);
@@ -16,7 +16,7 @@ Database::Database(const QString &path) {
qDebug() << "Database: connection ok";
}
- //upgrade();
+ upgrade();
}
Database::Database() {}
@@ -52,6 +52,23 @@ int Database::version() const {
return version_;
}
+QStringList Database::sqlStringToLines(const QString& sql) {
+ QStringList statements;
+ QStringList lines = sql.split("\n");
+ QString statement;
+ foreach (QString line, lines) {
+ line = line.trimmed();
+ if (line == "") continue;
+ if (line.left(2) == "--") continue;
+ statement += line;
+ if (line[line.length() - 1] == ';') {
+ statements.append(statement);
+ statement = "";
+ }
+ }
+ return statements;
+}
+
void Database::upgrade() {
// INSTRUCTIONS TO UPGRADE THE DATABASE:
//
@@ -75,19 +92,18 @@ void Database::upgrade() {
case 1:
- db_.exec("CREATE TABLE version (version INT)");
- db_.exec("INSERT INTO version (version) VALUES (1)");
+ QFile f(":/schema.sql");
+ if (!f.open(QFile::ReadOnly | QFile::Text)) {
+ qFatal("Cannot open database schema file");
+ return;
+ }
+ QTextStream in(&f);
+ QString schemaSql = in.readAll();
- db_.exec("CREATE TABLE folders (id TEXT PRIMARY KEY, title TEXT, created_time INT)");
-
-// for (int i = 1; i < 100; i++) {
-// QUuid uuid = QUuid::createUuid();
-// QString title = QString::number(i);
-// db_.exec(QString("INSERT INTO folders (id, title, created_time) VALUES (\"%1\", \"%2\", 1481235571)").arg(uuid.toString(), title.repeated(10)));
-// }
-
- //db_.exec("INSERT INTO folders (id, title, created_time) VALUES (\"ed735d55415bee976b771989be8f7005\", \"bbbb\", 1481235571)");
- //db_.exec("INSERT INTO folders (id, title, created_time) VALUES (\"5d41402abc4b2a76b9719d911017c592\", \"cccc\", 1481235571)");
+ QStringList lines = sqlStringToLines(schemaSql);
+ foreach (const QString& line, lines) {
+ db_.exec(line);
+ }
break;
diff --git a/QtClient/JoplinQtClient/database.h b/QtClient/JoplinQtClient/database.h
index face1dd91..1461ef11a 100755
--- a/QtClient/JoplinQtClient/database.h
+++ b/QtClient/JoplinQtClient/database.h
@@ -20,6 +20,7 @@ private:
void upgrade();
int version() const;
mutable int version_;
+ QStringList sqlStringToLines(const QString& sql);
};
diff --git a/QtClient/JoplinQtClient/database.qrc b/QtClient/JoplinQtClient/database.qrc
new file mode 100755
index 000000000..b601fdcb0
--- /dev/null
+++ b/QtClient/JoplinQtClient/database.qrc
@@ -0,0 +1,5 @@
+
+
+ schema.sql
+
+
diff --git a/QtClient/JoplinQtClient/schema.sql b/QtClient/JoplinQtClient/schema.sql
new file mode 100755
index 000000000..7154f4c4c
--- /dev/null
+++ b/QtClient/JoplinQtClient/schema.sql
@@ -0,0 +1,23 @@
+CREATE TABLE folders (
+ id INTEGER PRIMARY KEY,
+ title TEXT,
+ created_time INT,
+ updated_time INT,
+ remote_id TEXT
+);
+
+CREATE TABLE notes (
+ id INTEGER PRIMARY KEY,
+ title TEXT,
+ body TEXT,
+ parent_id INT,
+ created_time INT,
+ updated_time INT,
+ remote_id TEXT
+);
+
+CREATE TABLE version (
+ version INT
+);
+
+INSERT INTO version (version) VALUES (1);
\ No newline at end of file
diff --git a/QtClient/JoplinQtClient/stable.h b/QtClient/JoplinQtClient/stable.h
index e4491a2c7..afd68b3de 100755
--- a/QtClient/JoplinQtClient/stable.h
+++ b/QtClient/JoplinQtClient/stable.h
@@ -19,6 +19,7 @@
#include
#include
#include
+#include
#endif // __cplusplus
diff --git a/QtClient/database.sql b/QtClient/database.sql
new file mode 100755
index 000000000..7154f4c4c
--- /dev/null
+++ b/QtClient/database.sql
@@ -0,0 +1,23 @@
+CREATE TABLE folders (
+ id INTEGER PRIMARY KEY,
+ title TEXT,
+ created_time INT,
+ updated_time INT,
+ remote_id TEXT
+);
+
+CREATE TABLE notes (
+ id INTEGER PRIMARY KEY,
+ title TEXT,
+ body TEXT,
+ parent_id INT,
+ created_time INT,
+ updated_time INT,
+ remote_id TEXT
+);
+
+CREATE TABLE version (
+ version INT
+);
+
+INSERT INTO version (version) VALUES (1);
\ No newline at end of file
diff --git a/QtClient/dependencies/dll-debug/Qt5Cored.dll b/QtClient/dependencies/dll-debug/Qt5Cored.dll
new file mode 100755
index 000000000..0722daf93
Binary files /dev/null and b/QtClient/dependencies/dll-debug/Qt5Cored.dll differ
diff --git a/QtClient/dependencies/dll-debug/Qt5Guid.dll b/QtClient/dependencies/dll-debug/Qt5Guid.dll
new file mode 100755
index 000000000..02c451d30
Binary files /dev/null and b/QtClient/dependencies/dll-debug/Qt5Guid.dll differ
diff --git a/QtClient/dependencies/dll-debug/Qt5Networkd.dll b/QtClient/dependencies/dll-debug/Qt5Networkd.dll
new file mode 100755
index 000000000..ec5163d59
Binary files /dev/null and b/QtClient/dependencies/dll-debug/Qt5Networkd.dll differ
diff --git a/QtClient/dependencies/dll-debug/Qt5Qmld.dll b/QtClient/dependencies/dll-debug/Qt5Qmld.dll
new file mode 100755
index 000000000..a10187e7f
Binary files /dev/null and b/QtClient/dependencies/dll-debug/Qt5Qmld.dll differ
diff --git a/QtClient/dependencies/dll-debug/Qt5Quickd.dll b/QtClient/dependencies/dll-debug/Qt5Quickd.dll
new file mode 100755
index 000000000..ad0022c57
Binary files /dev/null and b/QtClient/dependencies/dll-debug/Qt5Quickd.dll differ
diff --git a/QtClient/dependencies/dll-debug/Qt5Sqld.dll b/QtClient/dependencies/dll-debug/Qt5Sqld.dll
new file mode 100755
index 000000000..a4862b2c1
Binary files /dev/null and b/QtClient/dependencies/dll-debug/Qt5Sqld.dll differ
diff --git a/QtClient/dependencies/dll-debug/ucrtbased.dll b/QtClient/dependencies/dll-debug/ucrtbased.dll
new file mode 100755
index 000000000..e8e28e0ee
Binary files /dev/null and b/QtClient/dependencies/dll-debug/ucrtbased.dll differ
diff --git a/QtClient/evernote-import/build.sh b/QtClient/evernote-import/build.sh
new file mode 100755
index 000000000..155e6f36d
--- /dev/null
+++ b/QtClient/evernote-import/build.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+set -e
+
+"/opt/Qt/5.7/gcc_64/bin/qmake" /home/laurent/src/notes/evernote-import-qt/evernote-import-qt.pro -spec linux-g++ CONFIG+=debug CONFIG+=qml_debug
+"/usr/bin/make" qmake_all
+make
+
+echo "============================================="
+./evernote-import-qt
\ No newline at end of file
diff --git a/QtClient/evernote-import/evernote-import-qt b/QtClient/evernote-import/evernote-import-qt
new file mode 100755
index 000000000..390c8dffb
Binary files /dev/null and b/QtClient/evernote-import/evernote-import-qt differ
diff --git a/QtClient/evernote-import/evernote-import-qt.pro b/QtClient/evernote-import/evernote-import-qt.pro
new file mode 100755
index 000000000..fa41b2d05
--- /dev/null
+++ b/QtClient/evernote-import/evernote-import-qt.pro
@@ -0,0 +1,23 @@
+QT += core sql
+QT -= gui
+
+CONFIG += c++11
+
+TARGET = evernote-import-qt
+CONFIG += console
+CONFIG -= app_bundle
+
+TEMPLATE = app
+
+SOURCES += main.cpp
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
diff --git a/QtClient/evernote-import/main.cpp b/QtClient/evernote-import/main.cpp
new file mode 100755
index 000000000..2742636be
--- /dev/null
+++ b/QtClient/evernote-import/main.cpp
@@ -0,0 +1,256 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+struct Resource {
+ QString id;
+ QString mime;
+ QString filename;
+ QByteArray data;
+ time_t timestamp;
+
+ Resource() : timestamp(0) {}
+};
+
+struct Note {
+ int id;
+ QString title;
+ QString content;
+ time_t created;
+ time_t updated;
+ QStringList tags;
+ QString longitude;
+ QString latitude;
+ QString altitude;
+ QString source;
+ QString author;
+ QString sourceUrl;
+ QString reminderOrder;
+ QString reminderDoneTime;
+ QString reminderTime;
+ QString sourceApplication;
+ QString applicationData;
+ std::vector resources;
+
+ Note() : created(0), updated(0) {}
+};
+
+time_t dateStringToTimestamp(const QString& s) {
+ QDateTime d = QDateTime::fromString(s, "yyyyMMddThhmmssZ");
+ d.setTimeSpec(Qt::UTC);
+ if (!d.isValid()) return 0;
+ return d.toTime_t();
+}
+
+void parseAttributes(QXmlStreamReader& reader, Note& note) {
+ while (reader.readNextStartElement()) {
+ if (reader.name() == "longitude") {
+ note.longitude = reader.readElementText();
+ } else if (reader.name() == "latitude") {
+ note.latitude = reader.readElementText();
+ } else if (reader.name() == "altitude") {
+ note.altitude = reader.readElementText();
+ } else if (reader.name() == "source") {
+ note.source = reader.readElementText();
+ } else if (reader.name() == "author") {
+ note.author = reader.readElementText();
+ } else if (reader.name() == "source-url") {
+ note.sourceUrl = reader.readElementText();
+ } else if (reader.name() == "source-application") {
+ note.sourceApplication = reader.readElementText();
+ } else if (reader.name() == "reminder-order") {
+ note.reminderOrder = reader.readElementText();
+ } else if (reader.name() == "reminder-time") {
+ note.reminderTime = reader.readElementText();
+ } else if (reader.name() == "reminder-done-time") {
+ note.reminderDoneTime = reader.readElementText();
+ } else if (reader.name() == "application-data") {
+ note.applicationData = reader.readElementText();
+ } else {
+ qWarning() << "Unsupported element:" << reader.name();
+ reader.skipCurrentElement();
+ }
+ }
+}
+
+//
+//
+// ...........
+// ...........
+//
+// image/png
+// 500
+// 326
+//
+//
+//
+// ]]>
+//
+//
+// NoeudDeChaise.png
+//
+//
+
+void parseResourceAttributes(QXmlStreamReader& reader, Resource& resource) {
+ while (reader.readNextStartElement()) {
+ if (reader.name() == "file-name") {
+ resource.filename = reader.readElementText();
+ } else if (reader.name() == "timestamp") {
+ resource.timestamp = dateStringToTimestamp(reader.readElementText());
+ } else if (reader.name() == "camera-make" || reader.name() == "source-url" || reader.name() == "attachment" || reader.name() == "longitude" || reader.name() == "latitude") {
+ // Ignore it
+ reader.skipCurrentElement();
+ } else {
+ qWarning() << "Unsupported element:" << reader.name();
+ reader.skipCurrentElement();
+ }
+ }
+}
+
+void parseResourceRecognition(QXmlStreamReader& reader, Resource& resource) {
+ QString recognitionXml = reader.readElementText();
+
+ QXmlStreamReader r(recognitionXml.toUtf8());
+
+ if (r.readNextStartElement()) {
+ if (r.name() == "recoIndex") {
+ QString objID;
+ foreach (const QXmlStreamAttribute &attr, r.attributes()) {
+ if (attr.name().toString() == "objID") {
+ objID = attr.value().toString();
+ break;
+ }
+ }
+
+ resource.id = objID;
+
+ r.skipCurrentElement();
+ } else {
+ qWarning() << "Unsupported element:" << r.name();
+ r.skipCurrentElement();
+ }
+ }
+}
+
+Resource parseResource(QXmlStreamReader& reader) {
+ Resource output;
+ while (reader.readNextStartElement()) {
+ if (reader.name() == "data") {
+ QString encoding = "";
+ foreach (const QXmlStreamAttribute &attr, reader.attributes()) {
+ if (attr.name().toString() == "encoding") {
+ encoding = attr.value().toString();
+ break;
+ }
+ }
+ if (encoding != "base64") {
+ qWarning() << "Unsupported encoding:" << encoding;
+ return Resource();
+ }
+
+ output.data = QByteArray::fromBase64(reader.readElementText().toUtf8());
+ } else if (reader.name() == "mime") {
+ output.mime = reader.readElementText();
+ } else if (reader.name() == "resource-attributes") {
+ parseResourceAttributes(reader, output);
+ } else if (reader.name() == "width" || reader.name() == "height") {
+ // Ignore it
+ reader.skipCurrentElement();
+ } else if (reader.name() == "recognition") {
+ parseResourceRecognition(reader, output);
+ } else {
+ qWarning() << "Unsupported element:" << reader.name();
+ reader.skipCurrentElement();
+ }
+ }
+
+ //qDebug() << output.id << output.mime << output.filename << output.timestamp;
+
+ return output;
+}
+
+Note parseNote(QXmlStreamReader& reader) {
+ Note note;
+
+ while (reader.readNextStartElement()) {
+ if (reader.name() == "title") {
+ note.title = reader.readElementText();
+ } else if (reader.name() == "content") {
+ note.content = reader.readElementText();
+ } else if (reader.name() == "created") {
+ note.created = dateStringToTimestamp(reader.readElementText());
+ } else if (reader.name() == "updated") {
+ note.updated = dateStringToTimestamp(reader.readElementText());
+ } else if (reader.name() == "tag") {
+ note.tags.append(reader.readElementText());
+ } else if (reader.name() == "resource") {
+ note.resources.push_back(parseResource(reader));
+ } else if (reader.name() == "note-attributes") {
+ parseAttributes(reader, note);
+ } else {
+ qWarning() << "Unsupported element:" << reader.name();
+ reader.skipCurrentElement();
+ }
+ }
+
+ //qDebug() << title << created << updated;
+
+ //qDebug() << note.longitude << note.latitude << note.source << note.author << note.sourceUrl;
+
+ //qDebug() << note.sourceApplication << note.reminderOrder << note.reminderDoneTime;
+
+ return note;
+}
+
+std::vector parseXmlFile(const QString& filePath) {
+ std::vector output;
+
+ QFile file(filePath);
+ if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ qWarning() << "Cannot open file" << filePath;
+ return output;
+ }
+
+ QByteArray fileData = file.readAll();
+
+ QXmlStreamReader reader(fileData);
+
+ if (reader.readNextStartElement()) {
+ while (reader.readNextStartElement()) {
+ if (reader.name() == "note") {
+ Note note = parseNote(reader);
+ output.push_back(note);
+ } else {
+ qWarning() << "Unsupported element:" << reader.name();
+ reader.skipCurrentElement();
+ }
+ }
+ }
+
+ return output;
+}
+
+
+int main(int argc, char *argv[]) {
+ QCoreApplication a(argc, argv);
+
+// QString dbPath = "D:/Web/www/joplin/QtClient/evernote-import/notes.sqlite";
+
+// QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+// db.setDatabaseName(path);
+
+// if (!db_.open()) {
+// qDebug() << "Error: connection with database fail";
+// } else {
+// qDebug() << "Database: connection ok";
+// }
+
+
+ //std::vector notes = parseXmlFile("/home/laurent/Downloads/Notes/Laurent.enex");
+ std::vector notes = parseXmlFile("/home/laurent/Downloads/Notes/a_faire.enex");
+}
diff --git a/src/AppBundle/Eloquent.php b/src/AppBundle/Eloquent.php
index 6554340cc..3c6bb2ba4 100755
--- a/src/AppBundle/Eloquent.php
+++ b/src/AppBundle/Eloquent.php
@@ -11,10 +11,10 @@ class Eloquent {
$this->capsule_->addConnection([
'driver' => 'mysql',
- 'host' => 'localhost',
+ 'host' => '127.0.0.1',
'database' => 'notes',
'username' => 'root',
- 'password' => 'pass',
+ 'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',