use view.delta instead of view.changes

removed dependency on client_secret
This commit is contained in:
skilion 2016-06-27 19:23:14 +02:00
parent a927f74626
commit 0efc2fe382
4 changed files with 31 additions and 28 deletions

View file

@ -31,7 +31,7 @@ cp /usr/local/etc/onedrive.conf ~/.config/onedrive/config
Available options:
* `client_id` & `client_secret`: application identifiers necessary during the [authentication][2]
* `client_id`: application identifier necessary for the [authentication][2]
* `sync_dir`: directory where the files will be synced
* `skip_file`: any files that match this pattern will be skipped during sync
* `skip_dir`: any directories that match this pattern will be skipped during sync

View file

@ -1,5 +1,4 @@
client_id = "000000004C15842F"
client_secret = "5vWj5xi6rYZM61X81Z9OyXAmjGhVS6Py"
sync_dir = "~/OneDrive"
skip_file = ".*|~*"
skip_dir = ".*"

View file

@ -6,7 +6,7 @@ import config;
private immutable {
string authUrl = "https://login.live.com/oauth20_authorize.srf";
string redirectUrl = "https://login.live.com/oauth20_desktop.srf";
string redirectUrl = "https://login.live.com/oauth20_desktop.srf"; // "urn:ietf:wg:oauth:2.0:oob";
string tokenUrl = "https://login.live.com/oauth20_token.srf";
string itemByIdUrl = "https://api.onedrive.com/v1.0/drive/items/";
string itemByPathUrl = "https://api.onedrive.com/v1.0/drive/root:/";
@ -32,7 +32,7 @@ class OneDriveException: Exception
final class OneDriveApi
{
private string clientId, clientSecret;
private string clientId;
private string refreshToken, accessToken;
private SysTime accessTokenExpiration;
/* private */ HTTP http;
@ -42,7 +42,6 @@ final class OneDriveApi
this(Config cfg, bool verbose)
{
this.clientId = cfg.get("client_id");
this.clientSecret = cfg.get("client_secret");
http = HTTP();
//http.verbose = verbose;
}
@ -50,7 +49,7 @@ final class OneDriveApi
void authorize()
{
import std.stdio, std.regex;
string url = authUrl ~ "?client_id=" ~ clientId ~ "&scope=wl.offline_access%20onedrive.readwrite&response_type=code&redirect_uri=" ~ redirectUrl;
string url = authUrl ~ "?client_id=" ~ clientId ~ "&scope=onedrive.readwrite%20offline_access&response_type=code&redirect_uri=" ~ redirectUrl;
writeln("Authorize this app visiting:\n");
writeln(url, "\n");
@ -72,21 +71,22 @@ final class OneDriveApi
this.refreshToken = refreshToken;
}
// https://dev.onedrive.com/items/view_changes.htm
// https://dev.onedrive.com/items/view_delta.htm
JSONValue viewChangesById(const(char)[] id, const(char)[] statusToken)
{
checkAccessTokenExpired();
char[] url = itemByIdUrl ~ id ~ "/view.changes";
const(char)[] url = itemByIdUrl ~ id ~ "/view.delta";
url ~= "?select=id,name,eTag,cTag,deleted,file,folder,fileSystemInfo,remoteItem,parentReference";
if (statusToken) url ~= "?token=" ~ statusToken;
return get(url);
}
// https://dev.onedrive.com/items/view_changes.htm
// https://dev.onedrive.com/items/view_delta.htm
JSONValue viewChangesByPath(const(char)[] path, const(char)[] statusToken)
{
checkAccessTokenExpired();
string url = itemByPathUrl ~ encodeComponent(path) ~ ":/view.changes";
url ~= "?select=id,name,eTag,cTag,deleted,file,folder,fileSystemInfo,parentReference";
string url = itemByPathUrl ~ encodeComponent(path) ~ ":/view.delta";
url ~= "?select=id,name,eTag,cTag,deleted,file,folder,fileSystemInfo,remoteItem,parentReference";
if (statusToken) url ~= "&token=" ~ statusToken;
return get(url);
}
@ -99,7 +99,7 @@ final class OneDriveApi
import std.file;
if (exists(saveToPath)) remove(saveToPath);
}
char[] url = itemByIdUrl ~ id ~ "/content?AVOverride=1";
const(char)[] url = itemByIdUrl ~ id ~ "/content";
download(url, saveToPath);
}
@ -183,15 +183,21 @@ final class OneDriveApi
private void redeemToken(const(char)[] authCode)
{
string postData = "client_id=" ~ clientId ~ "&redirect_uri=" ~ redirectUrl ~ "&client_secret=" ~ clientSecret;
postData ~= "&code=" ~ authCode ~ "&grant_type=authorization_code";
const(char)[] postData =
"client_id=" ~ clientId ~
"&redirect_uri=" ~ redirectUrl ~
"&code=" ~ authCode ~
"&grant_type=authorization_code";
acquireToken(postData);
}
private void newToken()
{
string postData = "client_id=" ~ clientId ~ "&redirect_uri=" ~ redirectUrl ~ "&client_secret=" ~ clientSecret;
postData ~= "&refresh_token=" ~ refreshToken ~ "&grant_type=refresh_token";
string postData =
"client_id=" ~ clientId ~
"&redirect_uri=" ~ redirectUrl ~
"&refresh_token=" ~ refreshToken ~
"&grant_type=refresh_token";
acquireToken(postData);
}

View file

@ -95,9 +95,9 @@ final class SyncEngine
foreach (item; changes["value"].array) {
applyDifference(item);
}
statusToken = changes["@changes.token"].str;
statusToken = changes["@delta.token"].str;
onStatusToken(statusToken);
} while (changes["@changes.hasMoreChanges"].type == JSON_TYPE.TRUE);
} while (("@odata.nextLink" in changes.object) !is null);
} catch (ErrnoException e) {
throw new SyncException(e.msg, e);
} catch (FileException e) {
@ -146,11 +146,9 @@ final class SyncEngine
}
// compute the path of the item
string path;
string path = ".";
if (parentId) {
path = itemdb.computePath(parentId) ~ "/" ~ name;
} else {
path = ".";
}
ItemType type;
@ -181,13 +179,13 @@ final class SyncEngine
}
string cTag;
try {
cTag = item["cTag"].str;
} catch (JSONException e) {
// cTag is not returned if the Item is a folder
// https://dev.onedrive.com/resources/item.htm
cTag = "";
}
try {
cTag = item["cTag"].str;
} catch (JSONException e) {
// cTag is not returned if the Item is a folder
// https://dev.onedrive.com/resources/item.htm
cTag = "";
}
string mtime = item["fileSystemInfo"]["lastModifiedDateTime"].str;