real time changes

This commit is contained in:
skilion 2015-09-11 18:33:22 +02:00
parent 22b1107a10
commit 54e60d4528
4 changed files with 133 additions and 34 deletions

View file

@ -1,10 +1,14 @@
DC = dmd
DFLAGS = -unittest -debug -g -od./bin -of./bin/$@ -L-lcurl -L-lsqlite3
DFLAGS = -debug -g -gs -od./bin -of./bin/$@ -L-lcurl -L-lsqlite3 -L-ldl
SOURCES = \
/usr/include/dlang/dmd/core/sys/posix/poll.d \
/usr/include/dlang/dmd/etc/c/curl.d \
/usr/include/dlang/dmd/std/net/curl.d \
src/cache.d \
src/config.d \
src/main.d \
src/monitor.d \
src/onedrive.d \
src/sqlite.d \
src/sync.d \

View file

@ -1,5 +1,5 @@
import std.file;
import config, onedrive, sync;
import config, monitor, onedrive, sync;
private string configFile = "./onedrive.conf";
private string refreshTokenFile = "refresh_token";
@ -19,12 +19,28 @@ void main()
auto sync = new SyncEngine(cfg, onedrive);
sync.applyDifferences();
sync.uploadDifferences();
/*import std.stdio;
import std.net.curl;
try {
onedrive.simpleUpload("a.txt", "a.txt", "error").toPrettyString.writeln;
} catch (CurlException e) {
writeln("exc ", e.msg);
}*/
Monitor m;
import std.stdio;
m.onDirCreated = delegate(string path) {
writeln("Directory created: ", path);
sync.createFolderItem(path);
sync.uploadDifferences(path);
};
m.onFileChanged = delegate(string path) {
writeln("File changed: ", path);
sync.uploadDifference2(path);
};
m.onDelete = delegate(string path) {
sync.deleteByPath(path);
};
m.onMove = delegate(string from, string to) {
sync.moveItem(from, to);
};
m.init();
string syncDir = cfg.get("sync_dir");
chdir(syncDir);
m.addRecursive("test");
while (true) m.update();
}

View file

@ -38,10 +38,10 @@ struct Monitor
// buffer to receive the inotify events
private void[] buffer;
void function(string path) onDirCreated;
void function(string path) onFileChanged;
void function(string path) onDelete;
void function(string from, string to) onMove;
void delegate(string path) onDirCreated;
void delegate(string path) onFileChanged;
void delegate(string path) onDelete;
void delegate(string from, string to) onMove;
@disable this(this);

View file

@ -1,5 +1,5 @@
import core.exception: RangeError;
import std.stdio, std.file, std.json;
import std.file, std.json, std.path, std.stdio;
import cache, config, onedrive, util;
private string statusTokenFile = "status_token";
@ -162,6 +162,38 @@ final class SyncEngine
}
}
private void cacheItem(JSONValue item)
{
string id = item["id"].str;
ItemType type;
if (isItemDeleted(item)) {
itemCache.deleteById(id);
} else if (isItemFile(item)) {
type = ItemType.file;
} else if (isItemFolder(item)) {
type = ItemType.dir;
} else {
writeln("The item is neither a file nor a directory, skipping");
return;
}
string name = item["name"].str;
string eTag = item["eTag"].str;
string cTag = item["cTag"].str;
string mtime = item["fileSystemInfo"].object["lastModifiedDateTime"].str;
string parentId = item["parentReference"].object["id"].str;
string crc32;
if (type == ItemType.file) {
try {
crc32 = item["file"].object["hashes"].object["crc32Hash"].str;
} catch (JSONException e) {
writeln("The hash is not available");
} catch (RangeError e) {
writeln("The crc32 hash is not available");
}
}
itemCache.insert(id, name, type, eTag, cTag, mtime, parentId, crc32);
}
private void applyDelete(Item item)
{
if (exists(item.path)) {
@ -314,6 +346,19 @@ final class SyncEngine
chdir(currDir);
}
public void uploadDifferences(string path)
{
assert(isDir(path));
Item item;
foreach (DirEntry entry; dirEntries(path, SpanMode.breadth, false)) {
if (itemCache.selectByPath(entry.name, item)) {
uploadDifference(item);
} else {
uploadNewItem(entry.name);
}
}
}
private void uploadDifference(Item item)
{
writeln(item.path);
@ -333,16 +378,8 @@ final class SyncEngine
} else {
deleteItem(item);
writeln("Uploading ...");
JSONValue returnedItem = onedrive.simpleUpload(item.path, item.path);
string id = returnedItem["id"].str;
string eTag = returnedItem["eTag"].str;
writeln("Updating last modified time ...");
JSONValue mtime = [
"fileSystemInfo": JSONValue([
"lastModifiedDateTime": timeLastModified(item.path).toUTC().toISOExtString()
])
];
onedrive.updateById(id, mtime, eTag);
auto res = onedrive.simpleUpload(item.path, item.path);
cacheItem(res);
}
break;
}
@ -360,10 +397,23 @@ final class SyncEngine
}
}
// HACK
void uploadDifference2(const(char)[] path)
{
assert(isFile(path));
Item item;
if (itemCache.selectByPath(path, item)) {
uploadDifference(item);
} else {
uploadNewItem(path);
}
}
private void deleteItem(Item item)
{
writeln("Deleting ...");
onedrive.deleteById(item.id, item.eTag);
itemCache.deleteById(item.id);
}
private void updateItem(Item item)
@ -377,9 +427,10 @@ final class SyncEngine
if (item.type == ItemType.file && !testCrc32(item.path, item.crc32)) {
assert(isFile(item.path));
writeln("Uploading ...");
JSONValue returnedItem = onedrive.simpleUpload(item.path, item.path, item.eTag);
id = returnedItem["id"].str;
eTag = returnedItem["eTag"].str;
JSONValue res = onedrive.simpleUpload(item.path, item.path, item.eTag);
cacheItem(res);
id = res["id"].str;
eTag = res["eTag"].str;
}
updateItemLastModifiedTime(id, eTag, localModifiedTime.toUTC());
} else {
@ -387,13 +438,13 @@ final class SyncEngine
}
}
private void createFolderItem(const(char)[] path)
void createFolderItem(const(char)[] path)
{
import std.path;
writeln("Creating folder ...");
folderItem["name"] = baseName(path).idup;
folderItem["fileSystemInfo"].object["lastModifiedDateTime"] = timeLastModified(path).toUTC().toISOExtString();
onedrive.createByPath(dirName(path), folderItem);
auto res = onedrive.createByPath(dirName(path), folderItem);
cacheItem(res);
}
private void updateItemLastModifiedTime(const(char)[] id, const(char)[] eTag, SysTime mtime)
@ -404,7 +455,8 @@ final class SyncEngine
"lastModifiedDateTime": mtime.toISOExtString()
])
];
onedrive.updateById(id, mtimeJson, eTag);
auto res = onedrive.updateById(id, mtimeJson, eTag);
cacheItem(res);
}
private void uploadNewItem(const(char)[] path)
@ -412,12 +464,39 @@ final class SyncEngine
assert(exists(path));
if (isFile(path)) {
writeln("Uploading file ...");
JSONValue returnedItem = onedrive.simpleUpload(path.dup, path);
string id = returnedItem["id"].str;
string eTag = returnedItem["eTag"].str;
JSONValue res = onedrive.simpleUpload(path.dup, path);
cacheItem(res);
string id = res["id"].str;
string eTag = res["eTag"].str;
updateItemLastModifiedTime(id, eTag, timeLastModified(path).toUTC());
} else {
createFolderItem(path);
}
}
void moveItem(const(char)[] from, string to)
{
writeln("Moving ", from, " to ", to, " ...");
Item item;
if (!itemCache.selectByPath(from, item)) {
throw new SyncException("Can't move a non synced item");
}
JSONValue diff = ["name": baseName(to)];
diff["parentReference"] = JSONValue([
"path": "/drive/root:/" ~ dirName(to)
]);
writeln(diff.toPrettyString());
auto res = onedrive.updateById(item.id, diff, item.eTag);
cacheItem(res);
}
void deleteByPath(const(char)[] path)
{
writeln("Deleting: ", path);
Item item;
if (!itemCache.selectByPath(path, item)) {
throw new SyncException("Can't delete a non synced item");
}
deleteItem(item);
}
}