mirror of
https://github.com/abraunegg/onedrive
synced 2024-06-08 08:52:15 +02:00
more playing around
This commit is contained in:
parent
7c9ea56293
commit
25b09775ab
372
src/config.d
372
src/config.d
|
@ -13,7 +13,28 @@ final class Config
|
||||||
|
|
||||||
private string userConfigFilePath;
|
private string userConfigFilePath;
|
||||||
// hashmap for the values found in the user config file
|
// hashmap for the values found in the user config file
|
||||||
private string[string] values;
|
private string[string] values = [
|
||||||
|
"upload_only": "false",
|
||||||
|
"check_for_nomount": "false",
|
||||||
|
"download_only": "false",
|
||||||
|
"disable_notifications": "false",
|
||||||
|
"disable_upload_validation": "false",
|
||||||
|
"enable_logging": "false",
|
||||||
|
"force_http_11": "false",
|
||||||
|
"local_first": "false",
|
||||||
|
"no_remote_delete": "false",
|
||||||
|
"skip_symlinks": "false",
|
||||||
|
"debug_https": "false",
|
||||||
|
"verbose": "0",
|
||||||
|
"monitor_interval" : "45",
|
||||||
|
"min_notif_changes": "5",
|
||||||
|
"single_directory": "",
|
||||||
|
"sync_dir": "~/OneDrive",
|
||||||
|
"skip_file": "~*",
|
||||||
|
"log_dir": "/var/log/onedrive/",
|
||||||
|
"drive_id": ""
|
||||||
|
]:
|
||||||
|
|
||||||
|
|
||||||
this(string configDirName)
|
this(string configDirName)
|
||||||
{
|
{
|
||||||
|
@ -82,26 +103,8 @@ final class Config
|
||||||
syncListFilePath = configDirName ~ "/sync_list";
|
syncListFilePath = configDirName ~ "/sync_list";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init()
|
bool initialize()
|
||||||
{
|
{
|
||||||
// Default configuration directory
|
|
||||||
setValue("sync_dir", "~/OneDrive");
|
|
||||||
// Configure to skip ONLY temp files (~*.doc etc) by default
|
|
||||||
// Prior configuration was: .*|~*
|
|
||||||
setValue("skip_file", "~*");
|
|
||||||
// By default symlinks are not skipped (using string type
|
|
||||||
// instead of boolean because hashmap only stores string types)
|
|
||||||
setValue("skip_symlinks", "false");
|
|
||||||
// Configure the monitor mode loop - the number of seconds by which
|
|
||||||
// each sync operation is undertaken when idle under monitor mode
|
|
||||||
setValue("monitor_interval", "45");
|
|
||||||
// Configure the default logging directory to be /var/log/onedrive/
|
|
||||||
setValue("log_dir", "/var/log/onedrive/");
|
|
||||||
// Configure a default empty value for drive_id
|
|
||||||
setValue("drive_id", "");
|
|
||||||
// Minimal changes that trigger a log and notification on sync
|
|
||||||
setValue("min_notif_changes", "5");
|
|
||||||
|
|
||||||
if (!load(userConfigFilePath)) {
|
if (!load(userConfigFilePath)) {
|
||||||
// What was the reason for failure?
|
// What was the reason for failure?
|
||||||
if (!exists(userConfigFilePath)) {
|
if (!exists(userConfigFilePath)) {
|
||||||
|
@ -115,6 +118,72 @@ final class Config
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool update_from_args(string[] args)
|
||||||
|
{
|
||||||
|
// Debug the HTTPS submit operations if required
|
||||||
|
bool debugHttp = cfg.getValue("debug_https") == "false" ? false : true;
|
||||||
|
// Do not use notifications in monitor mode
|
||||||
|
bool disableNotifications = cfg.getValue("disable_notifications") == "false" ? false : true;
|
||||||
|
// only download remote changes
|
||||||
|
bool downloadOnly = cfg.getValue("download_only") == "false" ? false : true;
|
||||||
|
// Does the user want to disable upload validation - https://github.com/abraunegg/onedrive/issues/205
|
||||||
|
// SharePoint will associate some metadata from the library the file is uploaded to directly in the file - thus change file size & checksums
|
||||||
|
bool disableUploadValidation = cfg.getValue("disable_upload_validation") == "false" ? false : true;
|
||||||
|
// Do we enable a log file
|
||||||
|
bool enableLogFile = cfg.getValue("enable_logging") == "false" ? false : true;
|
||||||
|
// Force the use of HTTP 1.1 to overcome curl => 7.62.0 where some operations are now sent via HTTP/2
|
||||||
|
// Whilst HTTP/2 operations are handled, in some cases the handling of this outside of the client is not being done correctly (router, other) thus the client breaks
|
||||||
|
// This flag then allows the user to downgrade all HTTP operations to HTTP 1.1 for maximum network path compatibility
|
||||||
|
bool forceHTTP11 = cfg.getValue("force_http_11") == "false" ? false : true;
|
||||||
|
// Local sync - Upload local changes first before downloading changes from OneDrive
|
||||||
|
bool localFirst = cfg.getValue("local_first") == "false" ? false : true;
|
||||||
|
// Add option for no remote delete
|
||||||
|
bool noRemoteDelete = cfg.getValue("no_remote_delete") == "false" ? false : true;
|
||||||
|
// Add option to skip symlinks
|
||||||
|
bool skipSymlinks = cfg.getValue("skip_symlinks") == "false" ? false : true;
|
||||||
|
// override the sync directory
|
||||||
|
string syncDirName = cfg.getValue("sync_dir");
|
||||||
|
// Upload Only
|
||||||
|
bool uploadOnly = cfg.getValue("upload_only") == "false" ? false : true;
|
||||||
|
|
||||||
|
|
||||||
|
// Application Startup option validation
|
||||||
|
try {
|
||||||
|
auto opt = getopt(
|
||||||
|
args,
|
||||||
|
std.getopt.config.bundling,
|
||||||
|
std.getopt.config.caseSensitive,
|
||||||
|
"check-for-nomount", "Check for the presence of .nosync in the syncdir root. If found, do not perform sync.", &checkMount,
|
||||||
|
"debug-https", "Debug OneDrive HTTPS communication.", &debugHttp,
|
||||||
|
"disable-notifications", "Do not use desktop notifications in monitor mode.", &disableNotifications,
|
||||||
|
"download-only|d", "Only download remote changes", &downloadOnly,
|
||||||
|
"disable-upload-validation", "Disable upload validation when uploading to OneDrive", &disableUploadValidation,
|
||||||
|
"enable-logging", "Enable client activity to a separate log file", &enableLogFile,
|
||||||
|
"force-http-1.1", "Force the use of HTTP 1.1 for all operations", &forceHTTP11,
|
||||||
|
"local-first", "Synchronize from the local directory source first, before downloading changes from OneDrive.", &localFirst,
|
||||||
|
"no-remote-delete", "Do not delete local file 'deletes' from OneDrive when using --upload-only", &noRemoteDelete,
|
||||||
|
"skip-symlinks", "Skip syncing of symlinks", &skipSymlinks,
|
||||||
|
"syncdir", "Specify the local directory used for synchronization to OneDrive", &syncDirName,
|
||||||
|
"upload-only", "Only upload to OneDrive, do not sync changes from OneDrive locally", &uploadOnly,
|
||||||
|
);
|
||||||
|
if (opt.helpWanted) {
|
||||||
|
outputLongHelp(opt.options);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
} catch (GetOptException e) {
|
||||||
|
log.error(e.msg);
|
||||||
|
log.error("Try 'onedrive -h' for more information");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// error
|
||||||
|
log.error(e.msg);
|
||||||
|
log.error("Try 'onedrive -h' for more information");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
string getValue(string key)
|
string getValue(string key)
|
||||||
{
|
{
|
||||||
auto p = key in values;
|
auto p = key in values;
|
||||||
|
@ -155,6 +224,7 @@ final class Config
|
||||||
auto p = key in values;
|
auto p = key in values;
|
||||||
if (p) {
|
if (p) {
|
||||||
c.popFront();
|
c.popFront();
|
||||||
|
// TODO add check for correct format (numbers, booleans)
|
||||||
setValue(key, c.front.dup);
|
setValue(key, c.front.dup);
|
||||||
} else {
|
} else {
|
||||||
log.log("Unknown key in config file: ", key);
|
log.log("Unknown key in config file: ", key);
|
||||||
|
@ -167,268 +237,6 @@ final class Config
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool updateConfigFromCmdLine(string[] args) {
|
|
||||||
|
|
||||||
auto cfg2settingBool = [
|
|
||||||
"upload_only": &uploadOnly,
|
|
||||||
"check_for_nomount": &checkMount,
|
|
||||||
"download_only": &downloadOnly,
|
|
||||||
"disable_notifications": &disableNotifications,
|
|
||||||
"disable_upload_validation": &disableUploadValidation,
|
|
||||||
"enable_logging": &enableLogFile,
|
|
||||||
"force_http_11": &forceHTTP11,
|
|
||||||
"local_first": &localFirst,
|
|
||||||
"no_remote_delete": &noRemoteDelete,
|
|
||||||
"skip_symlinks": &skipSymlinks,
|
|
||||||
"verbose": &verbose
|
|
||||||
];
|
|
||||||
auto cfg2settingString = [
|
|
||||||
"single_directory": &singleDirectory,
|
|
||||||
"syncdir": &syncDirName
|
|
||||||
];
|
|
||||||
|
|
||||||
void boolHandler(string option) {
|
|
||||||
switch (option) {
|
|
||||||
case "upload_only":
|
|
||||||
case "check_for_nomount":
|
|
||||||
case "download_only":
|
|
||||||
case "disable_notifications":
|
|
||||||
case "disable_upload_validation":
|
|
||||||
case "enable_logging":
|
|
||||||
case "force_http_11":
|
|
||||||
case "local_first":
|
|
||||||
case "no_remote_delete":
|
|
||||||
case "skip_symlinks":
|
|
||||||
case "verbose":
|
|
||||||
setValue(option, "true");
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
case "quiet": verbosityLevel = 0; break;
|
|
||||||
case "verbose": verbosityLevel = 2; break;
|
|
||||||
case "shouting": verbosityLevel = verbosityLevel.max; break;
|
|
||||||
default:
|
|
||||||
stderr.writeln("Unknown verbosity level ", value);
|
|
||||||
handlerFailed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Application Option Variables
|
|
||||||
// Add a check mounts option to resolve https://github.com/abraunegg/onedrive/issues/8
|
|
||||||
bool checkMount = false;
|
|
||||||
// Create a single root directory on OneDrive
|
|
||||||
string createDirectory;
|
|
||||||
// The destination directory if we are using the OneDrive client to rename a directory
|
|
||||||
string destinationDirectory;
|
|
||||||
// Debug the HTTPS submit operations if required
|
|
||||||
bool debugHttp = false;
|
|
||||||
// Do not use notifications in monitor mode
|
|
||||||
bool disableNotifications = false;
|
|
||||||
// Display application configuration but do not sync
|
|
||||||
bool displayConfiguration = false;
|
|
||||||
// Display sync status
|
|
||||||
bool displaySyncStatus = false;
|
|
||||||
// only download remote changes
|
|
||||||
bool downloadOnly = false;
|
|
||||||
// Does the user want to disable upload validation - https://github.com/abraunegg/onedrive/issues/205
|
|
||||||
// SharePoint will associate some metadata from the library the file is uploaded to directly in the file - thus change file size & checksums
|
|
||||||
bool disableUploadValidation = false;
|
|
||||||
// Do we enable a log file
|
|
||||||
bool enableLogFile = false;
|
|
||||||
// Force the use of HTTP 1.1 to overcome curl => 7.62.0 where some operations are now sent via HTTP/2
|
|
||||||
// Whilst HTTP/2 operations are handled, in some cases the handling of this outside of the client is not being done correctly (router, other) thus the client breaks
|
|
||||||
// This flag then allows the user to downgrade all HTTP operations to HTTP 1.1 for maximum network path compatibility
|
|
||||||
bool forceHTTP11 = false;
|
|
||||||
// SharePoint / Office 365 Shared Library name to query
|
|
||||||
string o365SharedLibraryName;
|
|
||||||
// Local sync - Upload local changes first before downloading changes from OneDrive
|
|
||||||
bool localFirst = false;
|
|
||||||
// remove the current user and sync state
|
|
||||||
bool logout = false;
|
|
||||||
// enable monitor mode
|
|
||||||
bool monitor = false;
|
|
||||||
// Add option for no remote delete
|
|
||||||
bool noRemoteDelete = false;
|
|
||||||
// print the access token
|
|
||||||
bool printAccessToken = false;
|
|
||||||
// force a full resync
|
|
||||||
bool resync = false;
|
|
||||||
// Remove a single directory on OneDrive
|
|
||||||
string removeDirectory;
|
|
||||||
// This allows for selective directory syncing instead of everything under ~/OneDrive/
|
|
||||||
string singleDirectory;
|
|
||||||
// Add option to skip symlinks
|
|
||||||
bool skipSymlinks = false;
|
|
||||||
// The source directory if we are using the OneDrive client to rename a directory
|
|
||||||
string sourceDirectory;
|
|
||||||
// override the sync directory
|
|
||||||
string syncDirName;
|
|
||||||
// Configure a flag to perform a sync
|
|
||||||
// This is beneficial so that if just running the client itself - without any options, or sync check, the client does not perform a sync
|
|
||||||
bool synchronize = false;
|
|
||||||
// Upload Only
|
|
||||||
bool uploadOnly = false;
|
|
||||||
// enable verbose logging
|
|
||||||
bool verbose = false;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// IDEA TODO TODO
|
|
||||||
// first run of getopt that leaves options (passThrough etc) only for the conffile
|
|
||||||
// then load config files
|
|
||||||
// then second getopt run with all other options overwriting config files options
|
|
||||||
|
|
||||||
// Application Startup option validation
|
|
||||||
try {
|
|
||||||
auto opt = getopt(
|
|
||||||
args,
|
|
||||||
std.getopt.config.bundling,
|
|
||||||
std.getopt.config.caseSensitive,
|
|
||||||
"check-for-nomount", "Check for the presence of .nosync in the syncdir root. If found, do not perform sync.", &checkMount,
|
|
||||||
"confdir", "Set the directory used to store the configuration files", &configDirName,
|
|
||||||
"create-directory", "Create a directory on OneDrive - no sync will be performed.", &createDirectory,
|
|
||||||
"destination-directory", "Destination directory for renamed or move on OneDrive - no sync will be performed.", &destinationDirectory,
|
|
||||||
"debug-https", "Debug OneDrive HTTPS communication.", &debugHttp,
|
|
||||||
"disable-notifications", "Do not use desktop notifications in monitor mode.", &disableNotifications,
|
|
||||||
"display-config", "Display what options the client will use as currently configured - no sync will be performed.", &displayConfiguration,
|
|
||||||
"display-sync-status", "Display the sync status of the client - no sync will be performed.", &displaySyncStatus,
|
|
||||||
"download-only|d", "Only download remote changes", &downloadOnly,
|
|
||||||
"disable-upload-validation", "Disable upload validation when uploading to OneDrive", &disableUploadValidation,
|
|
||||||
"enable-logging", "Enable client activity to a separate log file", &enableLogFile,
|
|
||||||
"force-http-1.1", "Force the use of HTTP 1.1 for all operations", &forceHTTP11,
|
|
||||||
"get-O365-drive-id", "Query and return the Office 365 Drive ID for a given Office 365 SharePoint Shared Library", &o365SharedLibraryName,
|
|
||||||
"local-first", "Synchronize from the local directory source first, before downloading changes from OneDrive.", &localFirst,
|
|
||||||
"logout", "Logout the current user", &logout,
|
|
||||||
"monitor|m", "Keep monitoring for local and remote changes", &monitor,
|
|
||||||
"no-remote-delete", "Do not delete local file 'deletes' from OneDrive when using --upload-only", &noRemoteDelete,
|
|
||||||
"print-token", "Print the access token, useful for debugging", &printAccessToken,
|
|
||||||
"resync", "Forget the last saved state, perform a full sync", &resync,
|
|
||||||
"remove-directory", "Remove a directory on OneDrive - no sync will be performed.", &removeDirectory,
|
|
||||||
"single-directory", "Specify a single local directory within the OneDrive root to sync.", &singleDirectory,
|
|
||||||
"skip-symlinks", "Skip syncing of symlinks", &skipSymlinks,
|
|
||||||
"source-directory", "Source directory to rename or move on OneDrive - no sync will be performed.", &sourceDirectory,
|
|
||||||
"syncdir", "Specify the local directory used for synchronization to OneDrive", &syncDirName,
|
|
||||||
"synchronize", "Perform a synchronization", &synchronize,
|
|
||||||
"upload-only", "Only upload to OneDrive, do not sync changes from OneDrive locally", &uploadOnly,
|
|
||||||
"verbose|v+", "Print more details, useful for debugging (repeat for extra debugging)", &log.verbose,
|
|
||||||
);
|
|
||||||
if (opt.helpWanted) {
|
|
||||||
outputLongHelp(opt.options);
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
} catch (GetOptException e) {
|
|
||||||
log.error(e.msg);
|
|
||||||
log.error("Try 'onedrive -h' for more information");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
} catch (Exception e) {
|
|
||||||
// error
|
|
||||||
log.error(e.msg);
|
|
||||||
log.error("Try 'onedrive -h' for more information");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main function variables
|
|
||||||
string homePath = "";
|
|
||||||
string configDirBase = "";
|
|
||||||
// Debug the HTTPS response operations if required
|
|
||||||
bool debugHttpSubmit;
|
|
||||||
// Are we able to reach the OneDrive Service
|
|
||||||
bool online = false;
|
|
||||||
|
|
||||||
auto cfg = new config.Config(configDirName);
|
|
||||||
if(!cfg.init()){
|
|
||||||
// There was an error loading the configuration
|
|
||||||
// Error message already printed
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
config.updateConfigFromCmdLine(args);
|
|
||||||
|
|
||||||
|
|
||||||
foreach (cfgKey, p; cfg2settingBool) {
|
|
||||||
if (*p) {
|
|
||||||
// the user passed in an alternate setting via cmd line
|
|
||||||
log.vdebug("CLI override to set", cfgKey, "to true");
|
|
||||||
cfg.setValue(cfgKey, "true");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (cfgKey, p; cfg2settingString) {
|
|
||||||
if (*p) {
|
|
||||||
// the user passed in an alternate setting via cmd line
|
|
||||||
log.vdebug("CLI override to set", cfgKey, "to", *p);
|
|
||||||
cfg.setValue(cfgKey, *p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// command line parameters to override default 'config' & take precedence
|
|
||||||
// Set the client to skip symbolic links if --skip-symlinks was passed in
|
|
||||||
if (skipSymlinks) {
|
|
||||||
// The user passed in an alternate skip_symlinks as to what was either in 'config' file or application default
|
|
||||||
log.vdebug("CLI override to set skip_symlinks to: true");
|
|
||||||
cfg.setValue("skip_symlinks", "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the OneDrive Local Sync Directory if was passed in via --syncdir
|
|
||||||
if (syncDirName) {
|
|
||||||
// The user passed in an alternate sync_dir as to what was either in 'config' file or application default
|
|
||||||
// Do not expandTilde here as we do not know if we reliably can
|
|
||||||
log.vdebug("CLI override to set sync_dir to: ", syncDirName);
|
|
||||||
cfg.setValue("sync_dir", syncDirName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// sync_dir environment handling to handle ~ expansion properly
|
|
||||||
string syncDir;
|
|
||||||
if ((environment.get("SHELL") == "") && (environment.get("USER") == "")){
|
|
||||||
log.vdebug("sync_dir: No SHELL or USER environment variable configuration detected");
|
|
||||||
// No shell or user set, so expandTilde() will fail - usually headless system running under init.d / systemd or potentially Docker
|
|
||||||
// Does the 'currently configured' sync_dir include a ~
|
|
||||||
if (canFind(cfg.getValue("sync_dir"),"~")) {
|
|
||||||
// A ~ was found
|
|
||||||
log.vdebug("sync_dir: A '~' was found in sync_dir, using the calculated 'homePath' to replace '~'");
|
|
||||||
syncDir = homePath ~ strip(cfg.getValue("sync_dir"),"~","~");
|
|
||||||
} else {
|
|
||||||
// No ~ found in sync_dir, use as is
|
|
||||||
log.vdebug("sync_dir: Getting syncDir from config value sync_dir");
|
|
||||||
syncDir = cfg.getValue("sync_dir");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// A shell and user is set, expand any ~ as this will be expanded correctly if present
|
|
||||||
log.vdebug("sync_dir: Getting syncDir from config value sync_dir");
|
|
||||||
if (canFind(cfg.getValue("sync_dir"),"~")) {
|
|
||||||
log.vdebug("sync_dir: A '~' was found in configured sync_dir, automatically expanding as SHELL and USER environment variable is set");
|
|
||||||
syncDir = expandTilde(cfg.getValue("sync_dir"));
|
|
||||||
} else {
|
|
||||||
syncDir = cfg.getValue("sync_dir");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// vdebug syncDir as set and calculated
|
|
||||||
log.vdebug("syncDir: ", syncDir);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
|
|
96
src/main.d
96
src/main.d
|
@ -49,43 +49,50 @@ int main(string[] args)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load configuration file if available
|
||||||
|
auto cfg = new config.Config(configDirName);
|
||||||
|
if(!cfg.initialize()){
|
||||||
|
// There was an error loading the configuration
|
||||||
|
// Error message already printed
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Application Option Variables
|
// Application Option Variables
|
||||||
// Add a check mounts option to resolve https://github.com/abraunegg/onedrive/issues/8
|
|
||||||
bool checkMount = false;
|
|
||||||
// Create a single root directory on OneDrive
|
// Create a single root directory on OneDrive
|
||||||
string createDirectory;
|
string createDirectory;
|
||||||
// The destination directory if we are using the OneDrive client to rename a directory
|
// The destination directory if we are using the OneDrive client to rename a directory
|
||||||
string destinationDirectory;
|
string destinationDirectory;
|
||||||
// Debug the HTTPS submit operations if required
|
// Debug the HTTPS submit operations if required
|
||||||
bool debugHttp = false;
|
bool debugHttp = cfg.getValue("debug_https") == "false" ? false : true;
|
||||||
// Do not use notifications in monitor mode
|
// Do not use notifications in monitor mode
|
||||||
bool disableNotifications = false;
|
bool disableNotifications = cfg.getValue("disable_notifications") == "false" ? false : true;
|
||||||
// Display application configuration but do not sync
|
// Display application configuration but do not sync
|
||||||
bool displayConfiguration = false;
|
bool displayConfiguration = false;
|
||||||
// Display sync status
|
// Display sync status
|
||||||
bool displaySyncStatus = false;
|
bool displaySyncStatus = false;
|
||||||
// only download remote changes
|
// only download remote changes
|
||||||
bool downloadOnly = false;
|
bool downloadOnly = cfg.getValue("download_only") == "false" ? false : true;
|
||||||
// Does the user want to disable upload validation - https://github.com/abraunegg/onedrive/issues/205
|
// Does the user want to disable upload validation - https://github.com/abraunegg/onedrive/issues/205
|
||||||
// SharePoint will associate some metadata from the library the file is uploaded to directly in the file - thus change file size & checksums
|
// SharePoint will associate some metadata from the library the file is uploaded to directly in the file - thus change file size & checksums
|
||||||
bool disableUploadValidation = false;
|
bool disableUploadValidation = cfg.getValue("disable_upload_validation") == "false" ? false : true;
|
||||||
// Do we enable a log file
|
// Do we enable a log file
|
||||||
bool enableLogFile = false;
|
bool enableLogFile = cfg.getValue("enable_logging") == "false" ? false : true;
|
||||||
// Force the use of HTTP 1.1 to overcome curl => 7.62.0 where some operations are now sent via HTTP/2
|
// Force the use of HTTP 1.1 to overcome curl => 7.62.0 where some operations are now sent via HTTP/2
|
||||||
// Whilst HTTP/2 operations are handled, in some cases the handling of this outside of the client is not being done correctly (router, other) thus the client breaks
|
// Whilst HTTP/2 operations are handled, in some cases the handling of this outside of the client is not being done correctly (router, other) thus the client breaks
|
||||||
// This flag then allows the user to downgrade all HTTP operations to HTTP 1.1 for maximum network path compatibility
|
// This flag then allows the user to downgrade all HTTP operations to HTTP 1.1 for maximum network path compatibility
|
||||||
bool forceHTTP11 = false;
|
bool forceHTTP11 = cfg.getValue("force_http_11") == "false" ? false : true;
|
||||||
// SharePoint / Office 365 Shared Library name to query
|
// SharePoint / Office 365 Shared Library name to query
|
||||||
string o365SharedLibraryName;
|
string o365SharedLibraryName;
|
||||||
// Local sync - Upload local changes first before downloading changes from OneDrive
|
// Local sync - Upload local changes first before downloading changes from OneDrive
|
||||||
bool localFirst = false;
|
bool localFirst = cfg.getValue("local_first") == "false" ? false : true;
|
||||||
// remove the current user and sync state
|
// remove the current user and sync state
|
||||||
bool logout = false;
|
bool logout = false;
|
||||||
// enable monitor mode
|
// enable monitor mode
|
||||||
bool monitor = false;
|
bool monitor = false;
|
||||||
// Add option for no remote delete
|
// Add option for no remote delete
|
||||||
bool noRemoteDelete = false;
|
bool noRemoteDelete = cfg.getValue("no_remote_delete") == "false" ? false : true;
|
||||||
// print the access token
|
// print the access token
|
||||||
bool printAccessToken = false;
|
bool printAccessToken = false;
|
||||||
// force a full resync
|
// force a full resync
|
||||||
|
@ -95,45 +102,18 @@ int main(string[] args)
|
||||||
// This allows for selective directory syncing instead of everything under ~/OneDrive/
|
// This allows for selective directory syncing instead of everything under ~/OneDrive/
|
||||||
string singleDirectory;
|
string singleDirectory;
|
||||||
// Add option to skip symlinks
|
// Add option to skip symlinks
|
||||||
bool skipSymlinks = false;
|
bool skipSymlinks = cfg.getValue("skip_symlinks") == "false" ? false : true;
|
||||||
// The source directory if we are using the OneDrive client to rename a directory
|
// The source directory if we are using the OneDrive client to rename a directory
|
||||||
string sourceDirectory;
|
string sourceDirectory;
|
||||||
// override the sync directory
|
// override the sync directory
|
||||||
string syncDirName;
|
string syncDirName = cfg.getValue("sync_dir");
|
||||||
// Configure a flag to perform a sync
|
// Configure a flag to perform a sync
|
||||||
// This is beneficial so that if just running the client itself - without any options, or sync check, the client does not perform a sync
|
// This is beneficial so that if just running the client itself - without any options, or sync check, the client does not perform a sync
|
||||||
bool synchronize = false;
|
bool synchronize = false;
|
||||||
// Upload Only
|
// Upload Only
|
||||||
bool uploadOnly = false;
|
bool uploadOnly = cfg.getValue("upload_only") == "false" ? false : true;
|
||||||
// enable verbose logging
|
|
||||||
bool verbose = false;
|
|
||||||
|
|
||||||
|
|
||||||
auto cfg2settingBool = [
|
|
||||||
"upload_only": &uploadOnly,
|
|
||||||
"check_for_nomount": &checkMount,
|
|
||||||
"download_only": &downloadOnly,
|
|
||||||
"disable_notifications": &disableNotifications,
|
|
||||||
"disable_upload_validation": &disableUploadValidation,
|
|
||||||
"enable_logging": &enableLogFile,
|
|
||||||
"force_http_11": &forceHTTP11,
|
|
||||||
"local_first": &localFirst,
|
|
||||||
"no_remote_delete": &noRemoteDelete,
|
|
||||||
"skip_symlinks": &skipSymlinks,
|
|
||||||
"verbose": &verbose
|
|
||||||
];
|
|
||||||
auto cfg2settingString = [
|
|
||||||
"single_directory": &singleDirectory,
|
|
||||||
"syncdir": &syncDirName
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// IDEA TODO TODO
|
|
||||||
// first run of getopt that leaves options (passThrough etc) only for the conffile
|
|
||||||
// then load config files
|
|
||||||
// then second getopt run with all other options overwriting config files options
|
|
||||||
|
|
||||||
// Application Startup option validation
|
// Application Startup option validation
|
||||||
try {
|
try {
|
||||||
auto opt = getopt(
|
auto opt = getopt(
|
||||||
|
@ -183,39 +163,9 @@ int main(string[] args)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main function variables
|
|
||||||
string homePath = "";
|
|
||||||
string configDirBase = "";
|
|
||||||
// Debug the HTTPS response operations if required
|
|
||||||
bool debugHttpSubmit;
|
|
||||||
// Are we able to reach the OneDrive Service
|
// Are we able to reach the OneDrive Service
|
||||||
bool online = false;
|
bool online = false;
|
||||||
|
|
||||||
auto cfg = new config.Config(configDirName);
|
|
||||||
if(!cfg.init()){
|
|
||||||
// There was an error loading the configuration
|
|
||||||
// Error message already printed
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
config.updateConfigFromCmdLine(args);
|
|
||||||
|
|
||||||
|
|
||||||
foreach (cfgKey, p; cfg2settingBool) {
|
|
||||||
if (*p) {
|
|
||||||
// the user passed in an alternate setting via cmd line
|
|
||||||
log.vdebug("CLI override to set", cfgKey, "to true");
|
|
||||||
cfg.setValue(cfgKey, "true");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach (cfgKey, p; cfg2settingString) {
|
|
||||||
if (*p) {
|
|
||||||
// the user passed in an alternate setting via cmd line
|
|
||||||
log.vdebug("CLI override to set", cfgKey, "to", *p);
|
|
||||||
cfg.setValue(cfgKey, *p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// command line parameters to override default 'config' & take precedence
|
// command line parameters to override default 'config' & take precedence
|
||||||
// Set the client to skip symbolic links if --skip-symlinks was passed in
|
// Set the client to skip symbolic links if --skip-symlinks was passed in
|
||||||
if (skipSymlinks) {
|
if (skipSymlinks) {
|
||||||
|
@ -241,7 +191,7 @@ int main(string[] args)
|
||||||
if (canFind(cfg.getValue("sync_dir"),"~")) {
|
if (canFind(cfg.getValue("sync_dir"),"~")) {
|
||||||
// A ~ was found
|
// A ~ was found
|
||||||
log.vdebug("sync_dir: A '~' was found in sync_dir, using the calculated 'homePath' to replace '~'");
|
log.vdebug("sync_dir: A '~' was found in sync_dir, using the calculated 'homePath' to replace '~'");
|
||||||
syncDir = homePath ~ strip(cfg.getValue("sync_dir"),"~","~");
|
syncDir = cfg.homePath ~ strip(cfg.getValue("sync_dir"),"~","~");
|
||||||
} else {
|
} else {
|
||||||
// No ~ found in sync_dir, use as is
|
// No ~ found in sync_dir, use as is
|
||||||
log.vdebug("sync_dir: Getting syncDir from config value sync_dir");
|
log.vdebug("sync_dir: Getting syncDir from config value sync_dir");
|
||||||
|
@ -427,7 +377,7 @@ int main(string[] args)
|
||||||
if(disableUploadValidation) sync.setDisableUploadValidation();
|
if(disableUploadValidation) sync.setDisableUploadValidation();
|
||||||
|
|
||||||
// Do we need to validate the syncDir to check for the presence of a '.nosync' file
|
// Do we need to validate the syncDir to check for the presence of a '.nosync' file
|
||||||
if (checkMount) {
|
if (cfg.getValue("check_for_nomount") == "true") {
|
||||||
// we were asked to check the mounts
|
// we were asked to check the mounts
|
||||||
if (exists(syncDir ~ "/.nosync")) {
|
if (exists(syncDir ~ "/.nosync")) {
|
||||||
log.logAndNotify("ERROR: .nosync file found. Aborting synchronization process to safeguard data.");
|
log.logAndNotify("ERROR: .nosync file found. Aborting synchronization process to safeguard data.");
|
||||||
|
@ -551,7 +501,7 @@ int main(string[] args)
|
||||||
|
|
||||||
// initialise the monitor class
|
// initialise the monitor class
|
||||||
if (cfg.getValue("skip_symlinks") == "true") skipSymlinks = true;
|
if (cfg.getValue("skip_symlinks") == "true") skipSymlinks = true;
|
||||||
if (!downloadOnly) m.init(cfg, verbose, skipSymlinks);
|
if (!downloadOnly) m.init(cfg, verbose > 0, skipSymlinks);
|
||||||
// monitor loop
|
// monitor loop
|
||||||
immutable auto checkInterval = dur!"seconds"(to!long(cfg.getValue("monitor_interval")));
|
immutable auto checkInterval = dur!"seconds"(to!long(cfg.getValue("monitor_interval")));
|
||||||
auto lastCheckTime = MonoTime.currTime();
|
auto lastCheckTime = MonoTime.currTime();
|
||||||
|
|
Loading…
Reference in a new issue