mirror of
https://github.com/abraunegg/onedrive
synced 2024-05-01 21:52:50 +02:00
implement the recommended way to enumerate changes
This commit is contained in:
parent
3d8daa086d
commit
691862b18f
|
@ -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";
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
37
src/sync.d
37
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);
|
||||
|
|
Loading…
Reference in a new issue