mirror of
https://github.com/abraunegg/onedrive
synced 2024-06-11 02:12:17 +02:00
working monitor
This commit is contained in:
parent
e8f7d99653
commit
35c290c4a0
54
src/itemdb.d
54
src/itemdb.d
|
@ -24,6 +24,7 @@ final class ItemDatabase
|
||||||
{
|
{
|
||||||
Database db;
|
Database db;
|
||||||
Statement insertItemStmt;
|
Statement insertItemStmt;
|
||||||
|
Statement updateItemStmt;
|
||||||
Statement selectItemByIdStmt;
|
Statement selectItemByIdStmt;
|
||||||
Statement selectItemByParentIdStmt;
|
Statement selectItemByParentIdStmt;
|
||||||
|
|
||||||
|
@ -44,11 +45,8 @@ final class ItemDatabase
|
||||||
db.exec("CREATE INDEX IF NOT EXISTS name_idx ON item (name)");
|
db.exec("CREATE INDEX IF NOT EXISTS name_idx ON item (name)");
|
||||||
db.exec("PRAGMA foreign_keys = ON");
|
db.exec("PRAGMA foreign_keys = ON");
|
||||||
db.exec("PRAGMA recursive_triggers = ON");
|
db.exec("PRAGMA recursive_triggers = ON");
|
||||||
//insertItemStmt = db.prepare("INSERT OR REPLACE INTO item (id, name, type, eTag, cTag, mtime, parentId, crc32) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
insertItemStmt = db.prepare("INSERT OR REPLACE INTO item (id, name, type, eTag, cTag, mtime, parentId, crc32) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
insertItemStmt = db.prepare("
|
updateItemStmt = db.prepare("
|
||||||
INSERT OR IGNORE
|
|
||||||
INTO item (id, name, type, eTag, cTag, mtime, parentId, crc32)
|
|
||||||
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8);
|
|
||||||
UPDATE item
|
UPDATE item
|
||||||
SET name = ?2, type = ?3, eTag = ?4, cTag = ?5, mtime = ?6, parentId = ?7, crc32 = ?8
|
SET name = ?2, type = ?3, eTag = ?4, cTag = ?5, mtime = ?6, parentId = ?7, crc32 = ?8
|
||||||
WHERE id = ?1
|
WHERE id = ?1
|
||||||
|
@ -77,6 +75,52 @@ final class ItemDatabase
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void update(const(char)[] id, const(char)[] name, ItemType type, const(char)[] eTag, const(char)[] cTag, const(char)[] mtime, const(char)[] parentId, const(char)[] crc32)
|
||||||
|
{
|
||||||
|
with (updateItemStmt) {
|
||||||
|
bind(1, id);
|
||||||
|
bind(2, name);
|
||||||
|
string typeStr = void;
|
||||||
|
final switch (type) {
|
||||||
|
case ItemType.file: typeStr = "file"; break;
|
||||||
|
case ItemType.dir: typeStr = "dir"; break;
|
||||||
|
}
|
||||||
|
bind(3, typeStr);
|
||||||
|
bind(4, eTag);
|
||||||
|
bind(5, cTag);
|
||||||
|
bind(6, mtime);
|
||||||
|
bind(7, parentId);
|
||||||
|
bind(8, crc32);
|
||||||
|
exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void upsert(const(char)[] id, const(char)[] name, ItemType type, const(char)[] eTag, const(char)[] cTag, const(char)[] mtime, const(char)[] parentId, const(char)[] crc32)
|
||||||
|
{
|
||||||
|
auto s = db.prepare("SELECT COUNT(*) FROM item WHERE id = ?");
|
||||||
|
s.bind(1, id);
|
||||||
|
auto r = s.exec();
|
||||||
|
Statement* p;
|
||||||
|
if (r.front[0] == "0") p = &insertItemStmt;
|
||||||
|
else p = &updateItemStmt;
|
||||||
|
with (p) {
|
||||||
|
bind(1, id);
|
||||||
|
bind(2, name);
|
||||||
|
string typeStr = void;
|
||||||
|
final switch (type) {
|
||||||
|
case ItemType.file: typeStr = "file"; break;
|
||||||
|
case ItemType.dir: typeStr = "dir"; break;
|
||||||
|
}
|
||||||
|
bind(3, typeStr);
|
||||||
|
bind(4, eTag);
|
||||||
|
bind(5, cTag);
|
||||||
|
bind(6, mtime);
|
||||||
|
bind(7, parentId);
|
||||||
|
bind(8, crc32);
|
||||||
|
exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// returns a range that go trough all items, depth first
|
// returns a range that go trough all items, depth first
|
||||||
auto selectAll()
|
auto selectAll()
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,7 +86,11 @@ void main(string[] args)
|
||||||
};
|
};
|
||||||
m.onFileChanged = delegate(string path) {
|
m.onFileChanged = delegate(string path) {
|
||||||
if (verbose) writeln("[M] File changed: ", path);
|
if (verbose) writeln("[M] File changed: ", path);
|
||||||
sync.uploadDifference(path);
|
try {
|
||||||
|
sync.uploadDifference(path);
|
||||||
|
} catch(SyncException e) {
|
||||||
|
writeln(e.msg);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
m.onDelete = delegate(string path) {
|
m.onDelete = delegate(string path) {
|
||||||
if (verbose) writeln("[M] Item deleted: ", path);
|
if (verbose) writeln("[M] Item deleted: ", path);
|
||||||
|
|
88
src/sync.d
88
src/sync.d
|
@ -146,8 +146,12 @@ final class SyncEngine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cached) {
|
||||||
|
itemdb.update(id, name, type, eTag, cTag, mtime, parentId, crc32);
|
||||||
|
} else {
|
||||||
|
itemdb.insert(id, name, type, eTag, cTag, mtime, parentId, crc32);
|
||||||
|
}
|
||||||
Item newItem;
|
Item newItem;
|
||||||
itemdb.insert(id, name, type, eTag, cTag, mtime, parentId, crc32);
|
|
||||||
itemdb.selectById(id, newItem);
|
itemdb.selectById(id, newItem);
|
||||||
|
|
||||||
// TODO add item in the db only if correctly downloaded
|
// TODO add item in the db only if correctly downloaded
|
||||||
|
@ -324,7 +328,25 @@ final class SyncEngine
|
||||||
final switch (item.type) {
|
final switch (item.type) {
|
||||||
case ItemType.file:
|
case ItemType.file:
|
||||||
if (isFile(item.path)) {
|
if (isFile(item.path)) {
|
||||||
uploadItemDifferences(item);
|
SysTime localModifiedTime = timeLastModified(item.path);
|
||||||
|
import core.time: Duration;
|
||||||
|
item.mtime.fracSecs = Duration.zero; // HACK
|
||||||
|
if (localModifiedTime != item.mtime) {
|
||||||
|
if (verbose) writeln("The item last modified time has changed");
|
||||||
|
string id = item.id;
|
||||||
|
string eTag = item.eTag;
|
||||||
|
if (!testCrc32(item.path, item.crc32)) {
|
||||||
|
if (verbose) writeln("The item content has changed");
|
||||||
|
writeln("Uploading: ", item.path);
|
||||||
|
auto res = onedrive.simpleUpload(item.path, item.path, item.eTag);
|
||||||
|
saveItem(res);
|
||||||
|
id = res["id"].str;
|
||||||
|
eTag = res["eTag"].str;
|
||||||
|
}
|
||||||
|
uploadLastModifiedTime(id, eTag, localModifiedTime.toUTC());
|
||||||
|
} else {
|
||||||
|
if (verbose) writeln("The item has not changed");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (verbose) writeln("The item was a file but now is a directory");
|
if (verbose) writeln("The item was a file but now is a directory");
|
||||||
uploadDeleteItem(item);
|
uploadDeleteItem(item);
|
||||||
|
@ -347,38 +369,21 @@ final class SyncEngine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: this function works only for files
|
void uploadDifference(string path)
|
||||||
void uploadDifference(string filename)
|
|
||||||
{
|
{
|
||||||
Item item;
|
try {
|
||||||
if (itemdb.selectByPath(filename, item)) {
|
Item item;
|
||||||
uploadDifference(item);
|
if (itemdb.selectByPath(path, item)) {
|
||||||
} else {
|
uploadDifference(item);
|
||||||
uploadNewFile(filename);
|
} else {
|
||||||
}
|
if (isDir(path)) {
|
||||||
}
|
uploadCreateDir(path);
|
||||||
|
} else {
|
||||||
// check if the item is changed and upload the differences
|
uploadNewFile(path);
|
||||||
private void uploadItemDifferences(Item item)
|
}
|
||||||
{
|
|
||||||
SysTime localModifiedTime = timeLastModified(item.path);
|
|
||||||
import core.time: Duration;
|
|
||||||
item.mtime.fracSecs = Duration.zero; // HACK
|
|
||||||
if (localModifiedTime != item.mtime) {
|
|
||||||
if (verbose) writeln("The item last modified time has changed");
|
|
||||||
string id = item.id;
|
|
||||||
string eTag = item.eTag;
|
|
||||||
if (item.type == ItemType.file && !testCrc32(item.path, item.crc32)) {
|
|
||||||
if (verbose) writeln("The item content has changed");
|
|
||||||
writeln("Uploading: ", item.path);
|
|
||||||
auto res = onedrive.simpleUpload(item.path, item.path, item.eTag);
|
|
||||||
saveItem(res);
|
|
||||||
id = res["id"].str;
|
|
||||||
eTag = res["eTag"].str;
|
|
||||||
}
|
}
|
||||||
uploadLastModifiedTime(id, eTag, localModifiedTime.toUTC());
|
} catch (FileException e) {
|
||||||
} else {
|
throw new SyncException(e.msg, e);
|
||||||
if (verbose) writeln("The item has not changed");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,7 +409,14 @@ final class SyncEngine
|
||||||
saveItem(res);
|
saveItem(res);
|
||||||
string id = res["id"].str;
|
string id = res["id"].str;
|
||||||
string eTag = res["eTag"].str;
|
string eTag = res["eTag"].str;
|
||||||
uploadLastModifiedTime(id, eTag, timeLastModified(path).toUTC());
|
SysTime mtime;
|
||||||
|
try {
|
||||||
|
mtime = timeLastModified(path).toUTC();
|
||||||
|
} catch (FileException e) {
|
||||||
|
writeln(e.msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uploadLastModifiedTime(id, eTag, mtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void uploadDeleteItem(Item item)
|
private void uploadDeleteItem(Item item)
|
||||||
|
@ -451,23 +463,29 @@ final class SyncEngine
|
||||||
// swallow exception
|
// swallow exception
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
itemdb.insert(id, name, type, eTag, cTag, mtime, parentId, crc32);
|
itemdb.upsert(id, name, type, eTag, cTag, mtime, parentId, crc32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uploadMoveItem(const(char)[] from, string to)
|
void uploadMoveItem(const(char)[] from, string to)
|
||||||
{
|
{
|
||||||
writeln("Moving remote item: ", from, " -> ", to);
|
writeln("Moving remote item: ", from, " -> ", to);
|
||||||
Item item;
|
Item item;
|
||||||
if (!itemdb.selectByPath(from, item)) {
|
if (!itemdb.selectByPath(from, item) || !isItemSynced(item)) {
|
||||||
writeln("Can't move an unsynced item");
|
writeln("Can't move an unsynced item");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (itemdb.selectByPath(to, item)) {
|
||||||
|
uploadDeleteItem(item);
|
||||||
|
}
|
||||||
JSONValue diff = ["name": baseName(to)];
|
JSONValue diff = ["name": baseName(to)];
|
||||||
diff["parentReference"] = JSONValue([
|
diff["parentReference"] = JSONValue([
|
||||||
"path": "/drive/root:/" ~ dirName(to)
|
"path": "/drive/root:/" ~ dirName(to)
|
||||||
]);
|
]);
|
||||||
auto res = onedrive.updateById(item.id, diff, item.eTag);
|
auto res = onedrive.updateById(item.id, diff, item.eTag);
|
||||||
saveItem(res);
|
saveItem(res);
|
||||||
|
string id = res["id"].str;
|
||||||
|
string eTag = res["eTag"].str;
|
||||||
|
uploadLastModifiedTime(id, eTag, timeLastModified(to).toUTC());
|
||||||
}
|
}
|
||||||
|
|
||||||
void deleteByPath(const(char)[] path)
|
void deleteByPath(const(char)[] path)
|
||||||
|
|
Loading…
Reference in a new issue