mirror of
https://github.com/abraunegg/onedrive
synced 2024-06-04 06:52:18 +02:00
real time changes
This commit is contained in:
parent
22b1107a10
commit
54e60d4528
6
Makefile
6
Makefile
|
@ -1,10 +1,14 @@
|
||||||
DC = dmd
|
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 = \
|
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/cache.d \
|
||||||
src/config.d \
|
src/config.d \
|
||||||
src/main.d \
|
src/main.d \
|
||||||
|
src/monitor.d \
|
||||||
src/onedrive.d \
|
src/onedrive.d \
|
||||||
src/sqlite.d \
|
src/sqlite.d \
|
||||||
src/sync.d \
|
src/sync.d \
|
||||||
|
|
32
src/main.d
32
src/main.d
|
@ -1,5 +1,5 @@
|
||||||
import std.file;
|
import std.file;
|
||||||
import config, onedrive, sync;
|
import config, monitor, onedrive, sync;
|
||||||
|
|
||||||
private string configFile = "./onedrive.conf";
|
private string configFile = "./onedrive.conf";
|
||||||
private string refreshTokenFile = "refresh_token";
|
private string refreshTokenFile = "refresh_token";
|
||||||
|
@ -19,12 +19,28 @@ void main()
|
||||||
|
|
||||||
auto sync = new SyncEngine(cfg, onedrive);
|
auto sync = new SyncEngine(cfg, onedrive);
|
||||||
sync.applyDifferences();
|
sync.applyDifferences();
|
||||||
|
sync.uploadDifferences();
|
||||||
|
|
||||||
/*import std.stdio;
|
Monitor m;
|
||||||
import std.net.curl;
|
import std.stdio;
|
||||||
try {
|
m.onDirCreated = delegate(string path) {
|
||||||
onedrive.simpleUpload("a.txt", "a.txt", "error").toPrettyString.writeln;
|
writeln("Directory created: ", path);
|
||||||
} catch (CurlException e) {
|
sync.createFolderItem(path);
|
||||||
writeln("exc ", e.msg);
|
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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,10 +38,10 @@ struct Monitor
|
||||||
// buffer to receive the inotify events
|
// buffer to receive the inotify events
|
||||||
private void[] buffer;
|
private void[] buffer;
|
||||||
|
|
||||||
void function(string path) onDirCreated;
|
void delegate(string path) onDirCreated;
|
||||||
void function(string path) onFileChanged;
|
void delegate(string path) onFileChanged;
|
||||||
void function(string path) onDelete;
|
void delegate(string path) onDelete;
|
||||||
void function(string from, string to) onMove;
|
void delegate(string from, string to) onMove;
|
||||||
|
|
||||||
@disable this(this);
|
@disable this(this);
|
||||||
|
|
||||||
|
|
121
src/sync.d
121
src/sync.d
|
@ -1,5 +1,5 @@
|
||||||
import core.exception: RangeError;
|
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;
|
import cache, config, onedrive, util;
|
||||||
|
|
||||||
private string statusTokenFile = "status_token";
|
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)
|
private void applyDelete(Item item)
|
||||||
{
|
{
|
||||||
if (exists(item.path)) {
|
if (exists(item.path)) {
|
||||||
|
@ -314,6 +346,19 @@ final class SyncEngine
|
||||||
chdir(currDir);
|
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)
|
private void uploadDifference(Item item)
|
||||||
{
|
{
|
||||||
writeln(item.path);
|
writeln(item.path);
|
||||||
|
@ -333,16 +378,8 @@ final class SyncEngine
|
||||||
} else {
|
} else {
|
||||||
deleteItem(item);
|
deleteItem(item);
|
||||||
writeln("Uploading ...");
|
writeln("Uploading ...");
|
||||||
JSONValue returnedItem = onedrive.simpleUpload(item.path, item.path);
|
auto res = onedrive.simpleUpload(item.path, item.path);
|
||||||
string id = returnedItem["id"].str;
|
cacheItem(res);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
break;
|
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)
|
private void deleteItem(Item item)
|
||||||
{
|
{
|
||||||
writeln("Deleting ...");
|
writeln("Deleting ...");
|
||||||
onedrive.deleteById(item.id, item.eTag);
|
onedrive.deleteById(item.id, item.eTag);
|
||||||
|
itemCache.deleteById(item.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateItem(Item item)
|
private void updateItem(Item item)
|
||||||
|
@ -377,9 +427,10 @@ final class SyncEngine
|
||||||
if (item.type == ItemType.file && !testCrc32(item.path, item.crc32)) {
|
if (item.type == ItemType.file && !testCrc32(item.path, item.crc32)) {
|
||||||
assert(isFile(item.path));
|
assert(isFile(item.path));
|
||||||
writeln("Uploading ...");
|
writeln("Uploading ...");
|
||||||
JSONValue returnedItem = onedrive.simpleUpload(item.path, item.path, item.eTag);
|
JSONValue res = onedrive.simpleUpload(item.path, item.path, item.eTag);
|
||||||
id = returnedItem["id"].str;
|
cacheItem(res);
|
||||||
eTag = returnedItem["eTag"].str;
|
id = res["id"].str;
|
||||||
|
eTag = res["eTag"].str;
|
||||||
}
|
}
|
||||||
updateItemLastModifiedTime(id, eTag, localModifiedTime.toUTC());
|
updateItemLastModifiedTime(id, eTag, localModifiedTime.toUTC());
|
||||||
} else {
|
} 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 ...");
|
writeln("Creating folder ...");
|
||||||
folderItem["name"] = baseName(path).idup;
|
folderItem["name"] = baseName(path).idup;
|
||||||
folderItem["fileSystemInfo"].object["lastModifiedDateTime"] = timeLastModified(path).toUTC().toISOExtString();
|
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)
|
private void updateItemLastModifiedTime(const(char)[] id, const(char)[] eTag, SysTime mtime)
|
||||||
|
@ -404,7 +455,8 @@ final class SyncEngine
|
||||||
"lastModifiedDateTime": mtime.toISOExtString()
|
"lastModifiedDateTime": mtime.toISOExtString()
|
||||||
])
|
])
|
||||||
];
|
];
|
||||||
onedrive.updateById(id, mtimeJson, eTag);
|
auto res = onedrive.updateById(id, mtimeJson, eTag);
|
||||||
|
cacheItem(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadNewItem(const(char)[] path)
|
private void uploadNewItem(const(char)[] path)
|
||||||
|
@ -412,12 +464,39 @@ final class SyncEngine
|
||||||
assert(exists(path));
|
assert(exists(path));
|
||||||
if (isFile(path)) {
|
if (isFile(path)) {
|
||||||
writeln("Uploading file ...");
|
writeln("Uploading file ...");
|
||||||
JSONValue returnedItem = onedrive.simpleUpload(path.dup, path);
|
JSONValue res = onedrive.simpleUpload(path.dup, path);
|
||||||
string id = returnedItem["id"].str;
|
cacheItem(res);
|
||||||
string eTag = returnedItem["eTag"].str;
|
string id = res["id"].str;
|
||||||
|
string eTag = res["eTag"].str;
|
||||||
updateItemLastModifiedTime(id, eTag, timeLastModified(path).toUTC());
|
updateItemLastModifiedTime(id, eTag, timeLastModified(path).toUTC());
|
||||||
} else {
|
} else {
|
||||||
createFolderItem(path);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue