From 691862b18ff648b7a770b68f748e8fd6ea58a0d5 Mon Sep 17 00:00:00 2001 From: skilion Date: Sun, 28 May 2017 20:54:57 +0200 Subject: [PATCH] implement the recommended way to enumerate changes --- src/config.d | 4 ++-- src/main.d | 2 +- src/onedrive.d | 8 ++++---- src/sync.d | 37 ++++++++++++++++--------------------- 4 files changed, 23 insertions(+), 28 deletions(-) diff --git a/src/config.d b/src/config.d index 653982d9..e7a25dbe 100644 --- a/src/config.d +++ b/src/config.d @@ -5,7 +5,7 @@ static import log; final class Config { public string refreshTokenFilePath; - public string statusTokenFilePath; + public string deltaLinkFilePath; public string databaseFilePath; public string uploadStateFilePath; public string syncListFilePath; @@ -17,7 +17,7 @@ final class Config this(string configDirName) { refreshTokenFilePath = configDirName ~ "/refresh_token"; - statusTokenFilePath = configDirName ~ "/status_token"; + deltaLinkFilePath = configDirName ~ "/delta_link"; databaseFilePath = configDirName ~ "/items.sqlite3"; uploadStateFilePath = configDirName ~ "/resume_upload"; userConfigFilePath = configDirName ~ "/config"; diff --git a/src/main.d b/src/main.d index 26dfef8e..5709a87c 100644 --- a/src/main.d +++ b/src/main.d @@ -60,7 +60,7 @@ int main(string[] args) if (resync || logout) { log.log("Deleting the saved status ..."); safeRemove(cfg.databaseFilePath); - safeRemove(cfg.statusTokenFilePath); + safeRemove(cfg.deltaLinkFilePath); safeRemove(cfg.uploadStateFilePath); if (logout) { safeRemove(cfg.refreshTokenFilePath); diff --git a/src/onedrive.d b/src/onedrive.d index dec6126f..3f601fcf 100644 --- a/src/onedrive.d +++ b/src/onedrive.d @@ -104,24 +104,24 @@ final class OneDriveApi } // https://dev.onedrive.com/items/view_delta.htm - JSONValue viewChangesById(const(char)[] id, const(char)[] statusToken) + JSONValue viewChangesById(const(char)[] id, const(char)[] deltaLink) { checkAccessTokenExpired(); + if (deltaLink) return get(deltaLink); const(char)[] url = itemByIdUrl ~ id ~ "/delta"; url ~= "?select=id,name,eTag,cTag,deleted,file,folder,root,fileSystemInfo,remoteItem,parentReference"; - if (statusToken) url ~= "&token=" ~ statusToken; return get(url); } // https://dev.onedrive.com/items/view_delta.htm - JSONValue viewChangesByPath(const(char)[] path, const(char)[] statusToken) + JSONValue viewChangesByPath(const(char)[] path, const(char)[] deltaLink) { checkAccessTokenExpired(); + if (deltaLink) return get(deltaLink); string url = itemByPathUrl ~ encodeComponent(path) ~ ":/delta"; // HACK if (path == ".") url = driveUrl ~ "/root/delta"; url ~= "?select=id,name,eTag,cTag,deleted,file,folder,root,fileSystemInfo,remoteItem,parentReference"; - if (statusToken) url ~= "&token=" ~ statusToken; return get(url); } diff --git a/src/sync.d b/src/sync.d index 0554b4f6..8916309f 100644 --- a/src/sync.d +++ b/src/sync.d @@ -60,8 +60,6 @@ final class SyncEngine private ItemDatabase itemdb; private UploadSession session; private SelectiveSync selectiveSync; - // token representing the last status correctly synced - private string statusToken; // list of items to skip while applying the changes private string[] skippedItems; // list of items to delete after the changes has been downloaded @@ -79,12 +77,6 @@ final class SyncEngine void init() { - // restore the previous status token - try { - statusToken = readText(cfg.statusTokenFilePath); - } catch (FileException e) { - // swallow exception - } // check if there is an interrupted upload session if (session.restore()) { log.log("Continuing the upload session ..."); @@ -96,33 +88,36 @@ final class SyncEngine void applyDifferences() { log.vlog("Applying differences ..."); + + // restore the last known state + string deltaLink; + try { + deltaLink = readText(cfg.deltaLinkFilePath); + } catch (FileException e) { + // swallow exception + } + try { JSONValue changes; do { // get changes from the server try { - changes = onedrive.viewChangesByPath(".", statusToken); + changes = onedrive.viewChangesByPath(".", deltaLink); } catch (OneDriveException e) { if (e.httpStatusCode == 410) { - log.log("Status token expired, resyncing"); - statusToken = null; + log.log("Delta link expired, resyncing"); + deltaLink = null; continue; - } - else { + } else { throw e; } } foreach (item; changes["value"].array) { applyDifference(item); } - // hack to reuse old code - string url; - if ("@odata.nextLink" in changes) url = changes["@odata.nextLink"].str; - if ("@odata.deltaLink" in changes) url = changes["@odata.deltaLink"].str; - auto c = matchFirst(url, r"(?:token=)([\w\d]+)"); - c.popFront(); // skip the whole match - statusToken = c.front; - std.file.write(cfg.statusTokenFilePath, statusToken); + if ("@odata.nextLink" in changes) deltaLink = changes["@odata.nextLink"].str; + if ("@odata.deltaLink" in changes) deltaLink = changes["@odata.deltaLink"].str; + std.file.write(cfg.deltaLinkFilePath, deltaLink); } while ("@odata.nextLink" in changes); } catch (ErrnoException e) { throw new SyncException(e.msg, e);