1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-09-16 08:56:40 +02:00

Various cli changes

This commit is contained in:
Laurent Cozic
2017-03-01 21:01:03 +00:00
parent 964c3997fe
commit 1d6a6c5134
11 changed files with 379 additions and 225 deletions

View File

@@ -19,9 +19,7 @@
using namespace jop;
Application::Application(int &argc, char **argv) :
QGuiApplication(argc, argv),
db_(jop::db()),
synchronizer_(db_)
QGuiApplication(argc, argv)
{

View File

@@ -26,7 +26,6 @@ public:
private:
Window view_;
Database& db_;
FolderModel folderModel_;
NoteModel noteModel_;
QString selectedFolderId() const;

View File

@@ -47,24 +47,50 @@ CliApplication::CliApplication(int &argc, char **argv) : QCoreApplication(argc,
// Client ID should be unique per instance of a program
settings.setValue("clientId", uuid::createUuid());
}
connect(&api_, SIGNAL(requestDone(const QJsonObject&, const QString&)), this, SLOT(api_requestDone(const QJsonObject&, const QString&)));
connect(&synchronizer_, SIGNAL(started()), this, SLOT(synchronizer_started()));
connect(&synchronizer_, SIGNAL(finished()), this, SLOT(synchronizer_finished()));
}
CliApplication::~CliApplication() {
jop::db().close();
}
// void CliApplication::processCommand(const Command& command) {
// qDebug() << "Command" << command.name();
// qDebug() << "Flags" << command.flags();
// qDebug() << "Args" << command.args();
void CliApplication::api_requestDone(const QJsonObject& response, const QString& tag) {
// TODO: handle errors
// Handle expired sessions
// // if (command == "mkdir") {
if (tag == "getSession") {
if (response.contains("error")) {
qStderr() << "Could not login: " << response.value("error").toString() << endl;
emit synchronizationDone();
} else {
QString sessionId = response.value("id").toString();
Settings settings;
settings.setValue("session.id", sessionId);
startSynchronization();
}
}
}
// // //Folder folder;
// // //folder.setValue("title", args[
// Call this only once the API base URL has been defined and the session has been set.
void CliApplication::startSynchronization() {
Settings settings;
synchronizer_.api().setBaseUrl(api_.baseUrl());
synchronizer_.setSessionId(settings.value("session.id").toString());
synchronizer_.unfreeze();
synchronizer_.start();
}
// // }
// }
void CliApplication::synchronizer_started() {
qDebug() << "Synchronization started...";
}
void CliApplication::synchronizer_finished() {
qDebug() << "Synchronization finished...";
emit synchronizationDone();
}
bool CliApplication::filePutContents(const QString& filePath, const QString& content) const {
QFile file(filePath);
@@ -199,14 +225,20 @@ int CliApplication::exec() {
parser.addVersionOption();
// mkdir "new_folder"
// rm "new_folder"
// ls
// ls new_folder
// touch new_folder/new_note
// edit new_folder/new_note
// config editor "subl -w %1"
// sync
// TODO: implement mv "new_folder"
if (command == "mkdir") {
parser.addPositionalArgument("path", "Folder path.");
} else if (command == "rm") {
parser.addPositionalArgument("path", "Folder path.");
} else if (command == "ls") {
parser.addPositionalArgument("path", "Folder path.");
} else if (command == "touch") {
@@ -217,6 +249,8 @@ int CliApplication::exec() {
parser.addPositionalArgument("key", "Key of the config property.");
parser.addPositionalArgument("value", "Value of the config property.");
parser.addOption(QCommandLineOption(QStringList() << "unset", "Unset the given <key>.", "key"));
} else if (command == "sync") {
} else if (command == "help") {
} else {
@@ -255,6 +289,23 @@ int CliApplication::exec() {
folder.save();
}
if (command == "rm") {
QString path = args.size() ? args[0] : QString();
if (path.isEmpty()) {
qStderr() << "Please provide a path or name for the folder.";
return 1;
}
std::vector<std::unique_ptr<Folder>> folders = Folder::pathToFolders(path, true, errorCode);
if (errorCode || !folders.size()) {
qStderr() << "Invalid path: " << path << endl;
return 1;
}
folders[folders.size() - 1]->dispose();
}
if (command == "ls") {
QString path = args.size() ? args[0] : QString();
std::vector<std::unique_ptr<Folder>> folders = Folder::pathToFolders(path, true, errorCode);
@@ -344,25 +395,27 @@ int CliApplication::exec() {
QDateTime originalLastModified = fileInfo.lastModified();
qStdout() << QString("Editing note \"%1\" (Either close the editor or press Ctrl+C when done)").arg(path) << endl;
qDebug() << "File:" << noteFilePath;
QProcess* process = new QProcess();
qint64* processId = new qint64();
qint64 processId = 0;
QString editorCommandPath = editorCommand.takeFirst();
editorCommand << noteFilePath;
if (!process->startDetached(editorCommandPath, editorCommand, QString(), processId)) {
if (!process->startDetached(editorCommandPath, editorCommand, QString(), &processId)) {
qStderr() << QString("Could not start command: %1").arg(editorCommandPath + " " + commandLineArgsToString(editorCommand)) << endl;
return 1;
}
while (kill(*processId, 0) == 0) {
while (kill(processId, 0) == 0) { // While the process still exist
QThread::sleep(2);
saveNoteIfFileChanged(note, originalLastModified, noteFilePath);
}
delete processId; processId = NULL;
saveNoteIfFileChanged(note, originalLastModified, noteFilePath);
// TODO: delete note file
delete process; process = NULL;
QFile::remove(noteFilePath);
}
}
@@ -391,6 +444,40 @@ int CliApplication::exec() {
settings.setValue(propKey, propValue);
}
if (command == "sync") {
QString sessionId = settings.value("session.id").toString();
qDebug() << "Session ID:" << sessionId;
// TODO: ask user
api_.setBaseUrl("http://127.0.0.1:8000");
QEventLoop loop;
connect(this, SIGNAL(synchronizationDone()), &loop, SLOT(quit()));
if (sessionId == "") {
QTextStream qtin(stdin);
qStdout() << "Enter email:" << endl;
QString email = qtin.readLine();
qStdout() << "Enter password:" << endl;
QString password = qtin.readLine();
qDebug() << email << password;
Settings settings;
QUrlQuery postData;
postData.addQueryItem("email", email);
postData.addQueryItem("password", password);
postData.addQueryItem("client_id", settings.value("clientId").toString());
api_.post("sessions", QUrlQuery(), postData, "getSession");
} else {
startSynchronization();
}
loop.exec();
qDebug() << "Synchronization done";
}
qDebug() << "=========================================== END";
return 0;

View File

@@ -5,6 +5,8 @@
#include "command.h"
#include "models/note.h"
#include "webapi.h"
#include "synchronizer.h"
namespace jop {
@@ -36,6 +38,8 @@ inline StderrHandler& qStderr() {
class CliApplication : public QCoreApplication {
Q_OBJECT
public:
CliApplication(int &argc, char **argv);
@@ -43,13 +47,26 @@ public:
void processCommand(const Command &command);
int exec();
public slots:
void api_requestDone(const QJsonObject& response, const QString& tag);
void synchronizer_started();
void synchronizer_finished();
signals:
void synchronizationDone();
private:
bool filePutContents(const QString& filePath, const QString& content) const;
void startSynchronization();
QString fileGetContents(const QString& filePath) const;
void saveNoteIfFileChanged(Note& note, const QDateTime& originalLastModified, const QString& noteFilePath);
QStringList parseCommandLinePath(const QString& commandLine) const;
QString commandLineArgsToString(const QStringList& args) const;
WebApi api_;
Synchronizer synchronizer_;
};

View File

@@ -11,7 +11,7 @@ Change::Change() : BaseModel() {
table_ = jop::ChangesTable;
}
QVector<Change> Change::all(int limit) {
std::vector<Change*> Change::all(int limit) {
QString sql = QString("SELECT %1 FROM %2 ORDER BY id ASC LIMIT %3")
.arg(BaseModel::tableFieldNames(jop::ChangesTable).join(","))
.arg(BaseModel::tableName(jop::ChangesTable))
@@ -20,68 +20,82 @@ QVector<Change> Change::all(int limit) {
QSqlQuery q(sql);
jop::db().execQuery(q);
QVector<Change> output;
std::vector<Change*> output;
qWarning() << "TODO: fix change iteration";
// while (q.next()) {
// Change change;
// change.loadSqlQuery(q);
// output.push_back(change);
// }
while (q.next()) {
Change* change(new Change());
change->loadSqlQuery(q);
output.push_back(change);
}
return output;
}
QVector<Change> Change::mergedChanges(const QVector<Change>& changes) {
void Change::mergedChanges(std::vector<Change*>& changes) {
QStringList createdItems;
QStringList deletedItems;
QHash<QString, Change> itemChanges;
QHash<QString, Change*> itemChanges;
qWarning() << "TODO: fix change iteration";
for (size_t i = 0; i < changes.size(); i++) {
Change* change = changes[i];
// foreach (Change change, changes) {
// QString itemId = change.value("item_id").toString();
// Change::Type type = (Change::Type)change.value("type").toInt();
QString itemId = change->value("item_id").toString();
Change::Type type = (Change::Type)change->value("type").toInt();
// if (type == Change::Create) {
// createdItems.push_back(itemId);
// } else if (type == Change::Delete) {
// deletedItems.push_back(itemId);
// }
if (type == Change::Create) {
createdItems.push_back(itemId);
} else if (type == Change::Delete) {
deletedItems.push_back(itemId);
}
// if (itemChanges.contains(itemId) && type == Change::Update) {
// // Merge all the "Update" event into one.
// Change& existingChange = itemChanges[itemId];
// existingChange.addMergedField(change.value("item_field").toString());
// } else {
// itemChanges[itemId] = change;
// }
// }
if (itemChanges.contains(itemId) && type == Change::Update) {
// Merge all the "Update" event into one.
Change* existingChange = itemChanges[itemId];
existingChange->addMergedField(change->value("item_field").toString());
} else {
itemChanges[itemId] = change;
}
}
QVector<Change> output;
std::vector<Change*> output;
// for (QHash<QString, Change>::iterator it = itemChanges.begin(); it != itemChanges.end(); ++it) {
// QString itemId = it.key();
// Change& change = it.value();
for (QHash<QString, Change*>::iterator it = itemChanges.begin(); it != itemChanges.end(); ++it) {
QString itemId = it.key();
Change* change = it.value();
// if (createdItems.contains(itemId) && deletedItems.contains(itemId)) {
// // Item both created then deleted - skip
// continue;
// }
if (createdItems.contains(itemId) && deletedItems.contains(itemId)) {
// Item both created then deleted - skip
continue;
}
// if (deletedItems.contains(itemId)) {
// // Item was deleted at some point - just return one 'delete' event
// change.setValue("type", Change::Delete);
// } else if (createdItems.contains(itemId)) {
// // Item was created then updated - just return one 'create' event with the latest changes
// change.setValue("type", Change::Create);
// }
if (deletedItems.contains(itemId)) {
// Item was deleted at some point - just return one 'delete' event
change->setValue("type", Change::Delete);
} else if (createdItems.contains(itemId)) {
// Item was created then updated - just return one 'create' event with the latest changes
change->setValue("type", Change::Create);
}
// output.push_back(change);
// }
output.push_back(change);
}
return output;
// Delete the changes that are now longer needed (have been merged)
for (size_t i = 0; i < changes.size(); i++) {
Change* c1 = changes[i];
bool found = false;
for (size_t j = 0; j < output.size(); j++) {
Change* c2 = output[i];
if (c1 == c2) {
found = true;
break;
}
}
if (!found) {
delete c1; c1 = NULL;
}
}
changes = output;
}
void Change::addMergedField(const QString &name) {

View File

@@ -13,11 +13,9 @@ public:
enum Type { Undefined, Create, Update, Delete };
//Table table() const;
Change();
static QVector<Change> all(int limit = 100);
static QVector<Change> mergedChanges(const QVector<Change> &changes);
static std::vector<Change*> all(int limit = 100);
static void mergedChanges(std::vector<Change*> &changes);
static void disposeByItemId(const QString& itemId);
void addMergedField(const QString& name);

View File

@@ -5,7 +5,7 @@
using namespace jop;
Synchronizer::Synchronizer(Database &database) : db_(database) {
Synchronizer::Synchronizer() {
state_ = Idle;
uploadsRemaining_ = 0;
connect(&api_, SIGNAL(requestDone(QJsonObject,QString)), this, SLOT(api_requestDone(QJsonObject,QString)));
@@ -22,6 +22,8 @@ void Synchronizer::start() {
return;
}
emit started();
qInfo() << "Starting synchronizer...";
switchState(UploadingChanges);
@@ -50,47 +52,52 @@ WebApi &Synchronizer::api() {
QUrlQuery Synchronizer::valuesToUrlQuery(const QHash<QString, Change::Value>& values) const {
QUrlQuery query;
for (QHash<QString, Change::Value>::const_iterator it = values.begin(); it != values.end(); ++it) {
if (it.key() == "id") continue;
query.addQueryItem(it.key(), it.value().toString());
}
return query;
}
void Synchronizer::checkNextState() {
qDebug() << "Synchronizer::checkNextState from state" << state_;
switch (state_) {
case UploadingChanges:
case UploadingChanges:
if (uploadsRemaining_ < 0) qCritical() << "Mismatch on upload operations done" << uploadsRemaining_;
if (uploadsRemaining_ < 0) qCritical() << "Mismatch on upload operations done" << uploadsRemaining_;
if (uploadsRemaining_ <= 0) {
uploadsRemaining_ = 0;
switchState(DownloadingChanges);
}
break;
break;
case DownloadingChanges:
case DownloadingChanges:
switchState(Idle);
break;
switchState(Idle);
emit finished();
break;
case Idle:
case Idle:
break;
break;
case Aborting:
case Aborting:
switchState(Idle);
break;
switchState(Idle);
emit finished();
break;
case Frozen:
case Frozen:
break;
break;
default:
default:
qCritical() << "Synchronizer has invalid state" << state_;
break;
qCritical() << "Synchronizer has invalid state" << state_;
break;
}
}
@@ -117,45 +124,56 @@ void Synchronizer::switchState(Synchronizer::SynchronizationState state) {
// UPLOADING STATE
// =============================================================================================
QVector<Change> changes = Change::all();
changes = Change::mergedChanges(changes);
std::vector<Change*> changes = Change::all();
Change::mergedChanges(changes);
uploadsRemaining_ = changes.size();
qWarning() << "TODO: fix change iteration";
for (size_t i = 0; i < changes.size(); i++) {
Change* change = changes[i];
// foreach (Change change, changes) {
// jop::Table itemType = (jop::Table)change.value("item_type").toInt();
// QString itemId = change.value("item_id").toString();
// Change::Type type = (Change::Type)change.value("type").toInt();
jop::Table itemType = (jop::Table)change->value("item_type").toInt();
QString itemId = change->value("item_id").toString();
Change::Type type = (Change::Type)change->value("type").toInt();
// if (itemType == jop::FoldersTable) {
qDebug() << "Change" << change->idString() << itemId << itemType;
// if (type == Change::Create) {
if (itemType == jop::FoldersTable) {
// Folder folder;
// folder.load(itemId);
// QUrlQuery data = valuesToUrlQuery(folder.values());
// api_.put("folders/" + folder.id().toString(), QUrlQuery(), data, "upload:putFolder:" + folder.id().toString());
if (type == Change::Create) {
// } else if (type == Change::Update) {
Folder folder;
folder.load(itemId);
QUrlQuery data = valuesToUrlQuery(folder.values());
api_.put("folders/" + folder.idString(), QUrlQuery(), data, "upload:putFolder:" + folder.idString());
// Folder folder;
// folder.load(itemId);
// QStringList mergedFields = change.mergedFields();
// QUrlQuery data;
// foreach (QString field, mergedFields) {
// data.addQueryItem(field, folder.value(field).toString());
// }
// api_.patch("folders/" + folder.id().toString(), QUrlQuery(), data, "upload:patchFolder:" + folder.id().toString());
} else if (type == Change::Update) {
// } else if (type == Change::Delete) {
Folder folder;
folder.load(itemId);
QStringList mergedFields = change->mergedFields();
QUrlQuery data;
foreach (QString field, mergedFields) {
data.addQueryItem(field, folder.value(field).toString());
}
api_.patch("folders/" + folder.idString(), QUrlQuery(), data, "upload:patchFolder:" + folder.idString());
// api_.del("folders/" + itemId, QUrlQuery(), QUrlQuery(), "upload:deleteFolder:" + itemId);
} else if (type == Change::Delete) {
// }
// }
// }
api_.del("folders/" + itemId, QUrlQuery(), QUrlQuery(), "upload:deleteFolder:" + itemId);
}
} else {
qFatal("Unsupported item type: %d", itemType);
}
}
for (size_t i = 0; i < changes.size(); i++) {
delete changes[i];
}
changes.clear();
checkNextState();

View File

@@ -16,7 +16,7 @@ public:
enum SynchronizationState { Idle, UploadingChanges, DownloadingChanges, Aborting, Frozen };
Synchronizer(Database& database);
Synchronizer();
void start();
void setSessionId(const QString& v);
void abort();
@@ -28,7 +28,6 @@ private:
QUrlQuery valuesToUrlQuery(const QHash<QString, BaseModel::Value> &values) const;
WebApi api_;
Database& db_;
SynchronizationState state_;
int uploadsRemaining_;
void checkNextState();
@@ -38,6 +37,11 @@ public slots:
void api_requestDone(const QJsonObject& response, const QString& tag);
signals:
void started();
void finished();
};
}

216
composer.lock generated
View File

@@ -9,16 +9,16 @@
"packages": [
{
"name": "doctrine/annotations",
"version": "v1.3.1",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
"reference": "bd4461328621bde0ae6b1b2675fbc6aca4ceb558"
"reference": "54cacc9b81758b14e3ce750f205a393d52339e97"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/bd4461328621bde0ae6b1b2675fbc6aca4ceb558",
"reference": "bd4461328621bde0ae6b1b2675fbc6aca4ceb558",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/54cacc9b81758b14e3ce750f205a393d52339e97",
"reference": "54cacc9b81758b14e3ce750f205a393d52339e97",
"shasum": ""
},
"require": {
@@ -27,7 +27,7 @@
},
"require-dev": {
"doctrine/cache": "1.*",
"phpunit/phpunit": "^5.6.1"
"phpunit/phpunit": "^5.7"
},
"type": "library",
"extra": {
@@ -73,7 +73,7 @@
"docblock",
"parser"
],
"time": "2016-12-30 15:59:45"
"time": "2017-02-24 16:22:25"
},
{
"name": "doctrine/cache",
@@ -147,28 +147,29 @@
},
{
"name": "doctrine/collections",
"version": "v1.3.0",
"version": "v1.4.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/collections.git",
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a"
"reference": "1a4fb7e902202c33cce8c55989b945612943c2ba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a",
"url": "https://api.github.com/repos/doctrine/collections/zipball/1a4fb7e902202c33cce8c55989b945612943c2ba",
"reference": "1a4fb7e902202c33cce8c55989b945612943c2ba",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
"php": "^5.6 || ^7.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
"doctrine/coding-standard": "~0.1@dev",
"phpunit/phpunit": "^5.7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2.x-dev"
"dev-master": "1.3.x-dev"
}
},
"autoload": {
@@ -209,7 +210,7 @@
"collections",
"iterator"
],
"time": "2015-04-14 22:21:58"
"time": "2017-01-03 10:49:41"
},
{
"name": "doctrine/common",
@@ -286,16 +287,16 @@
},
{
"name": "doctrine/dbal",
"version": "v2.5.7",
"version": "v2.5.12",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "3a351369582dade60c750e2cef540eb7b568e6b3"
"reference": "7b9e911f9d8b30d43b96853dab26898c710d8f44"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/3a351369582dade60c750e2cef540eb7b568e6b3",
"reference": "3a351369582dade60c750e2cef540eb7b568e6b3",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/7b9e911f9d8b30d43b96853dab26898c710d8f44",
"reference": "7b9e911f9d8b30d43b96853dab26898c710d8f44",
"shasum": ""
},
"require": {
@@ -353,20 +354,20 @@
"persistence",
"queryobject"
],
"time": "2017-01-14 21:05:28"
"time": "2017-02-08 12:53:47"
},
{
"name": "doctrine/doctrine-bundle",
"version": "1.6.6",
"version": "1.6.7",
"source": {
"type": "git",
"url": "https://github.com/doctrine/DoctrineBundle.git",
"reference": "0f0c4df366bd1d36d38a27e2f5ff128e118ac969"
"reference": "a01d99bc6c9a6c8a8ace0012690099dd957ce9b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/0f0c4df366bd1d36d38a27e2f5ff128e118ac969",
"reference": "0f0c4df366bd1d36d38a27e2f5ff128e118ac969",
"url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/a01d99bc6c9a6c8a8ace0012690099dd957ce9b9",
"reference": "a01d99bc6c9a6c8a8ace0012690099dd957ce9b9",
"shasum": ""
},
"require": {
@@ -434,7 +435,7 @@
"orm",
"persistence"
],
"time": "2017-01-07 21:47:22"
"time": "2017-01-16 12:01:26"
},
{
"name": "doctrine/doctrine-cache-bundle",
@@ -777,26 +778,26 @@
},
{
"name": "illuminate/container",
"version": "v5.3.23",
"version": "v5.4.13",
"source": {
"type": "git",
"url": "https://github.com/illuminate/container.git",
"reference": "8047b47e1f731c975d9aa0fe0b269064d3f1346d"
"reference": "ccbfa2c69369a11b419d071ad11147b59eb9f052"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/container/zipball/8047b47e1f731c975d9aa0fe0b269064d3f1346d",
"reference": "8047b47e1f731c975d9aa0fe0b269064d3f1346d",
"url": "https://api.github.com/repos/illuminate/container/zipball/ccbfa2c69369a11b419d071ad11147b59eb9f052",
"reference": "ccbfa2c69369a11b419d071ad11147b59eb9f052",
"shasum": ""
},
"require": {
"illuminate/contracts": "5.3.*",
"illuminate/contracts": "5.4.*",
"php": ">=5.6.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.3-dev"
"dev-master": "5.4-dev"
}
},
"autoload": {
@@ -816,20 +817,20 @@
],
"description": "The Illuminate Container package.",
"homepage": "https://laravel.com",
"time": "2016-10-02 01:14:30"
"time": "2017-01-28 17:55:54"
},
{
"name": "illuminate/contracts",
"version": "v5.3.23",
"version": "v5.4.13",
"source": {
"type": "git",
"url": "https://github.com/illuminate/contracts.git",
"reference": "ce5d73c6015b2054d32f3f8530767847b358ae4e"
"reference": "dd256891c80fd94a58ab83d7989d6da2f50e30ea"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/contracts/zipball/ce5d73c6015b2054d32f3f8530767847b358ae4e",
"reference": "ce5d73c6015b2054d32f3f8530767847b358ae4e",
"url": "https://api.github.com/repos/illuminate/contracts/zipball/dd256891c80fd94a58ab83d7989d6da2f50e30ea",
"reference": "dd256891c80fd94a58ab83d7989d6da2f50e30ea",
"shasum": ""
},
"require": {
@@ -838,7 +839,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.3-dev"
"dev-master": "5.4-dev"
}
},
"autoload": {
@@ -858,41 +859,41 @@
],
"description": "The Illuminate Contracts package.",
"homepage": "https://laravel.com",
"time": "2016-09-26 20:36:27"
"time": "2017-02-21 14:21:59"
},
{
"name": "illuminate/database",
"version": "v5.3.23",
"version": "v5.4.13",
"source": {
"type": "git",
"url": "https://github.com/illuminate/database.git",
"reference": "8db1197b3d3e8a7393153643774d2924cdc6d906"
"reference": "607d5e1c8e2ecc61d312a455a5e93d6793f694df"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/database/zipball/8db1197b3d3e8a7393153643774d2924cdc6d906",
"reference": "8db1197b3d3e8a7393153643774d2924cdc6d906",
"url": "https://api.github.com/repos/illuminate/database/zipball/607d5e1c8e2ecc61d312a455a5e93d6793f694df",
"reference": "607d5e1c8e2ecc61d312a455a5e93d6793f694df",
"shasum": ""
},
"require": {
"illuminate/container": "5.3.*",
"illuminate/contracts": "5.3.*",
"illuminate/support": "5.3.*",
"illuminate/container": "5.4.*",
"illuminate/contracts": "5.4.*",
"illuminate/support": "5.4.*",
"nesbot/carbon": "~1.20",
"php": ">=5.6.4"
},
"suggest": {
"doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).",
"doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.5).",
"fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).",
"illuminate/console": "Required to use the database commands (5.3.*).",
"illuminate/events": "Required to use the observers with Eloquent (5.3.*).",
"illuminate/filesystem": "Required to use the migrations (5.3.*).",
"illuminate/pagination": "Required to paginate the result set (5.3.*)."
"illuminate/console": "Required to use the database commands (5.4.*).",
"illuminate/events": "Required to use the observers with Eloquent (5.4.*).",
"illuminate/filesystem": "Required to use the migrations (5.4.*).",
"illuminate/pagination": "Required to paginate the result set (5.4.*)."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.3-dev"
"dev-master": "5.4-dev"
}
},
"autoload": {
@@ -918,26 +919,26 @@
"orm",
"sql"
],
"time": "2016-11-14 15:37:58"
"time": "2017-02-22 14:16:49"
},
{
"name": "illuminate/support",
"version": "v5.3.23",
"version": "v5.4.13",
"source": {
"type": "git",
"url": "https://github.com/illuminate/support.git",
"reference": "050d0ed3e1c0e1d129d73b2eaa14044e46a66f77"
"reference": "904f63003fd67ede2ec3be018b322d1c29415465"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/support/zipball/050d0ed3e1c0e1d129d73b2eaa14044e46a66f77",
"reference": "050d0ed3e1c0e1d129d73b2eaa14044e46a66f77",
"url": "https://api.github.com/repos/illuminate/support/zipball/904f63003fd67ede2ec3be018b322d1c29415465",
"reference": "904f63003fd67ede2ec3be018b322d1c29415465",
"shasum": ""
},
"require": {
"doctrine/inflector": "~1.0",
"ext-mbstring": "*",
"illuminate/contracts": "5.3.*",
"illuminate/contracts": "5.4.*",
"paragonie/random_compat": "~1.4|~2.0",
"php": ">=5.6.4"
},
@@ -946,13 +947,13 @@
},
"suggest": {
"illuminate/filesystem": "Required to use the composer class (5.2.*).",
"symfony/process": "Required to use the composer class (3.1.*).",
"symfony/var-dumper": "Required to use the dd function (3.1.*)."
"symfony/process": "Required to use the composer class (~3.2).",
"symfony/var-dumper": "Required to use the dd function (~3.2)."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.3-dev"
"dev-master": "5.4-dev"
}
},
"autoload": {
@@ -975,7 +976,7 @@
],
"description": "The Illuminate Support package.",
"homepage": "https://laravel.com",
"time": "2016-11-03 15:25:28"
"time": "2017-02-15 19:29:24"
},
{
"name": "incenteev/composer-parameter-handler",
@@ -1211,16 +1212,16 @@
},
{
"name": "paragonie/random_compat",
"version": "v2.0.4",
"version": "v2.0.7",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e"
"reference": "b5ea1ef3d8ff10c307ba8c5945c2f134e503278f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e",
"reference": "a9b97968bcde1c4de2a5ec6cbd06a0f6c919b46e",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/b5ea1ef3d8ff10c307ba8c5945c2f134e503278f",
"reference": "b5ea1ef3d8ff10c307ba8c5945c2f134e503278f",
"shasum": ""
},
"require": {
@@ -1255,7 +1256,7 @@
"pseudorandom",
"random"
],
"time": "2016-11-07 23:38:38"
"time": "2017-02-27 17:11:23"
},
{
"name": "psr/cache",
@@ -1404,16 +1405,16 @@
},
{
"name": "sensio/framework-extra-bundle",
"version": "v3.0.19",
"version": "v3.0.22",
"source": {
"type": "git",
"url": "https://github.com/sensiolabs/SensioFrameworkExtraBundle.git",
"reference": "d57c2f297d17ee82baf8cae0b16dae34a9378784"
"reference": "1c66c2e3b8f17f06178142386aff5a9f8057a104"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/d57c2f297d17ee82baf8cae0b16dae34a9378784",
"reference": "d57c2f297d17ee82baf8cae0b16dae34a9378784",
"url": "https://api.github.com/repos/sensiolabs/SensioFrameworkExtraBundle/zipball/1c66c2e3b8f17f06178142386aff5a9f8057a104",
"reference": "1c66c2e3b8f17f06178142386aff5a9f8057a104",
"shasum": ""
},
"require": {
@@ -1422,6 +1423,8 @@
"symfony/framework-bundle": "~2.3|~3.0"
},
"require-dev": {
"doctrine/doctrine-bundle": "~1.5",
"doctrine/orm": "~2.4,>=2.4.5",
"symfony/asset": "~2.7|~3.0",
"symfony/browser-kit": "~2.3|~3.0",
"symfony/dom-crawler": "~2.3|~3.0",
@@ -1434,7 +1437,7 @@
"symfony/translation": "~2.3|~3.0",
"symfony/twig-bundle": "~2.3|~3.0",
"symfony/yaml": "~2.3|~3.0",
"twig/twig": "~1.11|~2.0",
"twig/twig": "~1.12|~2.0",
"zendframework/zend-diactoros": "^1.3"
},
"suggest": {
@@ -1468,20 +1471,20 @@
"annotations",
"controllers"
],
"time": "2017-01-10 19:42:56"
"time": "2017-02-15 06:52:30"
},
{
"name": "sensiolabs/security-checker",
"version": "v4.0.0",
"version": "v4.0.1",
"source": {
"type": "git",
"url": "https://github.com/sensiolabs/security-checker.git",
"reference": "116027b57b568ed61b7b1c80eeb4f6ee9e8c599c"
"reference": "f2ce0035fc512287978510ca1740cd111d60f89f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sensiolabs/security-checker/zipball/116027b57b568ed61b7b1c80eeb4f6ee9e8c599c",
"reference": "116027b57b568ed61b7b1c80eeb4f6ee9e8c599c",
"url": "https://api.github.com/repos/sensiolabs/security-checker/zipball/f2ce0035fc512287978510ca1740cd111d60f89f",
"reference": "f2ce0035fc512287978510ca1740cd111d60f89f",
"shasum": ""
},
"require": {
@@ -1512,20 +1515,20 @@
}
],
"description": "A security checker for your composer.lock",
"time": "2016-09-23 18:09:57"
"time": "2017-02-18 17:53:25"
},
{
"name": "swiftmailer/swiftmailer",
"version": "v5.4.5",
"version": "v5.4.6",
"source": {
"type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "cd142238a339459b10da3d8234220963f392540c"
"reference": "81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/cd142238a339459b10da3d8234220963f392540c",
"reference": "cd142238a339459b10da3d8234220963f392540c",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e",
"reference": "81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e",
"shasum": ""
},
"require": {
@@ -1566,7 +1569,7 @@
"mail",
"mailer"
],
"time": "2016-12-29 10:02:40"
"time": "2017-02-13 07:52:53"
},
{
"name": "symfony/monolog-bundle",
@@ -2026,16 +2029,16 @@
},
{
"name": "symfony/symfony",
"version": "v3.1.9",
"version": "v3.1.10",
"source": {
"type": "git",
"url": "https://github.com/symfony/symfony.git",
"reference": "8d80e330acaad0780028ecb93fa8e902eb1e9abb"
"reference": "96e7dede3ddc9e3b3392f5cc93e26eca77545a89"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/symfony/zipball/8d80e330acaad0780028ecb93fa8e902eb1e9abb",
"reference": "8d80e330acaad0780028ecb93fa8e902eb1e9abb",
"url": "https://api.github.com/repos/symfony/symfony/zipball/96e7dede3ddc9e3b3392f5cc93e26eca77545a89",
"reference": "96e7dede3ddc9e3b3392f5cc93e26eca77545a89",
"shasum": ""
},
"require": {
@@ -2117,6 +2120,7 @@
"ocramius/proxy-manager": "~0.4|~1.0|~2.0",
"phpdocumentor/reflection-docblock": "^3.0",
"predis/predis": "~1.0",
"sensio/framework-extra-bundle": "^3.0.2",
"symfony/phpunit-bridge": "~3.2",
"symfony/polyfill-apcu": "~1.1",
"symfony/security-acl": "~2.8|~3.0"
@@ -2163,33 +2167,34 @@
"keywords": [
"framework"
],
"time": "2017-01-12 20:44:00"
"time": "2017-01-28 02:53:38"
},
{
"name": "twig/twig",
"version": "v1.31.0",
"version": "v1.32.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7"
"reference": "9935b662e24d6e634da88901ab534cc12e8c728f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/ddc9e3e20ee9c0b6908f401ac8353635b750eca7",
"reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/9935b662e24d6e634da88901ab534cc12e8c728f",
"reference": "9935b662e24d6e634da88901ab534cc12e8c728f",
"shasum": ""
},
"require": {
"php": ">=5.2.7"
},
"require-dev": {
"psr/container": "^1.0",
"symfony/debug": "~2.7",
"symfony/phpunit-bridge": "~3.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.31-dev"
"dev-master": "1.32-dev"
}
},
"autoload": {
@@ -2224,20 +2229,20 @@
"keywords": [
"templating"
],
"time": "2017-01-11 19:36:15"
"time": "2017-02-27 00:07:03"
},
{
"name": "yetanotherape/diff-match-patch",
"version": "v1.0.0",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/yetanotherape/diff-match-patch.git",
"reference": "8096755ec6592b154ceb2b577577477ce69aadb4"
"reference": "b00d838a320a20f98aeda69b15086ee3d0eeaba0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yetanotherape/diff-match-patch/zipball/8096755ec6592b154ceb2b577577477ce69aadb4",
"reference": "8096755ec6592b154ceb2b577577477ce69aadb4",
"url": "https://api.github.com/repos/yetanotherape/diff-match-patch/zipball/b00d838a320a20f98aeda69b15086ee3d0eeaba0",
"reference": "b00d838a320a20f98aeda69b15086ee3d0eeaba0",
"shasum": ""
},
"require": {
@@ -2246,12 +2251,12 @@
"php": ">=5.3"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
"phpunit/phpunit": "4.*"
},
"type": "library",
"autoload": {
"psr-0": {
"DiffMatchPatch": "src/"
"psr-4": {
"DiffMatchPatch\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2277,7 +2282,7 @@
"diff",
"patch"
],
"time": "2014-11-24 06:47:22"
"time": "2017-02-11 19:39:59"
}
],
"packages-dev": [
@@ -2335,22 +2340,23 @@
},
{
"name": "symfony/phpunit-bridge",
"version": "v3.2.2",
"version": "v3.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/phpunit-bridge.git",
"reference": "d32e4062c3a3dfb95709d2ca6dd89a327ae51c3b"
"reference": "996374975357b569ea319ec1c98c5ca0f7dda610"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/d32e4062c3a3dfb95709d2ca6dd89a327ae51c3b",
"reference": "d32e4062c3a3dfb95709d2ca6dd89a327ae51c3b",
"url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/996374975357b569ea319ec1c98c5ca0f7dda610",
"reference": "996374975357b569ea319ec1c98c5ca0f7dda610",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-zip": "Zip support is required when using bin/simple-phpunit",
"symfony/debug": "For tracking deprecated interfaces usages at runtime with DebugClassLoader"
},
"bin": [
@@ -2389,7 +2395,7 @@
],
"description": "Symfony PHPUnit Bridge",
"homepage": "https://symfony.com",
"time": "2017-01-06 17:19:17"
"time": "2017-01-21 17:06:35"
}
],
"aliases": [],

View File

@@ -13,10 +13,20 @@ function initialize() {
function config($name) {
$host = $_SERVER['HTTP_HOST'];
$baseUrl = 'https://joplin.cozic.net';
if ($host == 'joplinclient.local') {
$baseUrl = 'http://joplin.local';
}
if ($host == 'note_debug.local') {
$baseUrl = 'http://127.0.0.1:8000';
}
$config = array(
'host' => $host,
'baseUrl' => $host == 'joplinclient.local' ? 'http://joplin.local' : 'https://joplin.cozic.net',
'baseUrl' => $baseUrl,
'clientId' => 'E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3E3',
'email' => 'laurent@cozic.net',
'password' => '123456789',
);
if (isset($config[$name])) return $config[$name];
throw new Exception('Unknown config: ' . $name);
@@ -119,11 +129,13 @@ function redirect($path) {
initialize();
$session = execRequest('POST', 'sessions', null, array(
'email' => 'laurent@cozic.net',
'password' => '12345678',
'email' => config('email'),
'password' => config('password'),
'client_id' => config('clientId'),
));
if (isset($session['error'])) throw new Exception('Could not login. Please check credentials. ' . json_encode($session));
$_SESSION['sessionId'] = $session['id'];
$action = isset($_GET['action']) ? $_GET['action'] : 'folders';
@@ -159,10 +171,11 @@ switch ($action) {
// Hack so that all the changes are returned, as if the client requesting them
// was completely new.
$session = execRequest('POST', 'sessions', null, array(
'email' => 'laurent@cozic.net',
'password' => '12345678',
'email' => config('email'),
'password' => config('password'),
'client_id' => 'ABCDABCDABCDABCDABCDABCDABCDABCD',
));
if (isset($session['error'])) throw new Exception('Could not login. Please check credentials. ' . json_encode($session));
$changes = execRequest('GET', 'synchronizer', array('session' => $session['id']));
$pageParams['contentHtml'] = renderView('changes', array('changes' => $changes));
break;

View File

@@ -24,7 +24,7 @@ class Session extends BaseModel {
static public function login($email, $password, $clientId) {
$user = User::byEmail($email);
if (!$user) throw new NotFoundException();
if (!$user) throw new NotFoundException("User not found");
$ok = self::verifyPassword($password, $user->password);
if (!$ok) throw new AuthException();