implement the recommended way to enumerate changes

This commit is contained in:
skilion 2017-05-28 20:54:57 +02:00
parent 3d8daa086d
commit 691862b18f
4 changed files with 23 additions and 28 deletions

View file

@ -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";

View file

@ -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);

View file

@ -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);
}

View file

@ -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);