working uploadDifferences

This commit is contained in:
skilion 2015-09-08 18:25:41 +02:00
parent c08706cbf8
commit 2de650d2be

View file

@ -24,6 +24,15 @@ private bool isItemDeleted(const ref JSONValue item)
return !item["deleted"].isNull(); return !item["deleted"].isNull();
} }
private bool testCrc32(string path, const(char)[] crc32)
{
if (crc32) {
string localCrc32 = computeCrc32(path);
if (crc32 == localCrc32) return true;
}
return false;
}
class SyncException: Exception class SyncException: Exception
{ {
@nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null) @nogc @safe pure nothrow this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)
@ -165,6 +174,7 @@ final class SyncEngine
} else { } else {
writeln("The local item is already deleted"); writeln("The local item is already deleted");
} }
itemCache.deleteById(item.id);
} }
private void applyNewItem(Item item) private void applyNewItem(Item item)
{ {
@ -295,85 +305,119 @@ final class SyncEngine
string currDir = getcwd(); string currDir = getcwd();
string syncDir = cfg.get("sync_dir"); string syncDir = cfg.get("sync_dir");
chdir(syncDir); chdir(syncDir);
foreach (DirEntry entry; dirEntries("test", SpanMode.breadth, false)) { foreach (Item item; itemCache.selectAll()) {
uploadDifference(entry.name); uploadDifference(item);
}
foreach (DirEntry entry; dirEntries("test", SpanMode.breadth, false)) {
uploadDifference(entry.name/*[2 .. $]*/);
} }
// TODO: check deleted files
chdir(currDir); chdir(currDir);
} }
private void uploadDifference(const(char)[] path) private void uploadDifference(Item item)
{ {
writeln(path); writeln(item.path);
assert(exists(path)); if (exists(item.path)) {
Item item;
bool needDelete, uploadFile, createDir, changedLastModifiedTime;
if (itemCache.selectByPath(path, item)) {
final switch (item.type) { final switch (item.type) {
case ItemType.file: case ItemType.file:
if (isFile(item.path)) { if (isFile(item.path)) {
SysTime localModifiedTime = timeLastModified(item.path); updateItem(item);
import core.time: Duration;
item.mtime.fracSecs = Duration.zero; // HACK
if (localModifiedTime != item.mtime) {
writeln("Different last modified time");
changedLastModifiedTime = true;
if (item.crc32) {
string localCrc32 = computeCrc32(item.path);
if (localCrc32 != item.crc32) {
writeln("Different content");
uploadFile = true;
}
} else {
writeln("The local item has no hash, assuming it's different");
uploadFile = true;
}
}
} else { } else {
writeln("The local item is changed in a directory"); deleteItem(item);
needDelete = true; createFolderItem(item.path);
createDir = true;
} }
break; break;
case ItemType.dir: case ItemType.dir:
if (isDir(item.path)) { if (isDir(item.path)) {
// ignore folder mtime updateItem(item);
} else { } else {
writeln("The local item changed in a file"); deleteItem(item);
needDelete = true; writeln("Uploading ...");
uploadFile = true; 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);
} }
break; break;
} }
} else { } else {
if (isFile(path)) uploadFile = true; deleteItem(item);
else createDir = true;
} }
}
string id = item.id; private void uploadDifference(const(char)[] path)
string eTag = item.eTag; {
if (needDelete) { Item item;
assert(id); if (!itemCache.selectByPath(path, item)) {
writeln("Deleting ..."); writeln("New item ", path);
onedrive.deleteById(id, eTag); uploadNewItem(path);
} }
if (uploadFile) { }
private void deleteItem(Item item)
{
writeln("Deleting ...");
onedrive.deleteById(item.id, item.eTag);
}
private void updateItem(Item item)
{
SysTime localModifiedTime = timeLastModified(item.path);
import core.time: Duration;
item.mtime.fracSecs = Duration.zero; // HACK
if (localModifiedTime != item.mtime) {
string id = item.id;
string eTag = item.eTag;
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;
}
updateItemLastModifiedTime(id, eTag, localModifiedTime.toUTC());
} else {
writeln("The item is not changed");
}
}
private void createFolderItem(const(char)[] path)
{
import std.path;
writeln("Creating folder ...");
folderItem["name"] = baseName(path);
folderItem["fileSystemInfo"].object["lastModifiedDateTime"] = timeLastModified(path).toUTC().toISOExtString();
onedrive.createByPath(dirName(path), folderItem);
}
private void updateItemLastModifiedTime(const(char)[] id, const(char)[] eTag, SysTime mtime)
{
writeln("Updating last modified time ...");
JSONValue mtimeJson = [
"fileSystemInfo": JSONValue([
"lastModifiedDateTime": mtime.toISOExtString()
])
];
onedrive.updateById(id, mtimeJson, eTag);
}
private void uploadNewItem(const(char)[] path)
{
assert(exists(path));
if (isFile(path)) {
writeln("Uploading file ..."); writeln("Uploading file ...");
auto returnedItem = onedrive.simpleUpload(path.dup, path, eTag); JSONValue returnedItem = onedrive.simpleUpload(path.dup, path);
id = returnedItem["id"].str; string id = returnedItem["id"].str;
eTag = returnedItem["eTag"].str; string eTag = returnedItem["eTag"].str;
} updateItemLastModifiedTime(id, eTag, timeLastModified(path).toUTC());
if (uploadFile || changedLastModifiedTime) { } else {
writeln("Updating last modified time ..."); createFolderItem(path);
JSONValue mtime = ["fileSystemInfo": JSONValue(["lastModifiedDateTime": timeLastModified(path).toUTC().toISOExtString()])];
onedrive.updateById(id, mtime, eTag);
}
if (createDir) {
writeln("Creating folder ...");
import std.path;
folderItem["name"] = baseName(path);
folderItem["fileSystemInfo"].object["lastModifiedDateTime"] = timeLastModified(path).toUTC().toISOExtString();
onedrive.createByPath(dirName(path), folderItem);
} }
} }
} }