mirror of
https://github.com/abraunegg/onedrive
synced 2024-06-02 05:52:16 +02:00
Merge 'master' into PR and resolve conflicts
* Merge 'master' into PR and resolve conflicts
This commit is contained in:
commit
7e153e0ba3
29
CHANGELOG.md
29
CHANGELOG.md
|
@ -2,6 +2,35 @@
|
|||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
## 2.4.5 - 2020-08-13
|
||||
### Fixed
|
||||
* Fixed fish auto completions installation destination
|
||||
|
||||
## 2.4.4 - 2020-08-11
|
||||
### Fixed
|
||||
* Fix 'skip_dir' & 'skip_file' pattern matching to ensure correct matching is performed
|
||||
* Fix 'skip_dir' & 'skip_file' so that each directive is only used against directories or files as requried in --monitor
|
||||
* Fix client hand when attempting to sync a Unix pipe file
|
||||
* Fix --single-directory & 'sync_list' performance
|
||||
* Fix erroneous 'return' statements which could prematurely end processing all changes returned from OneDrive
|
||||
* Fix segfault when attempting to perform a comparison on an inotify event when determining if event path is directory or file
|
||||
* Fix handling of Shared Folders to ensure these are checked against 'skip_dir' entries
|
||||
* Fix 'Skipping uploading this new file as parent path is not in the database' when uploading to a Personal Shared Folder
|
||||
* Fix how available free space is tracked when uploading files to OneDrive and Shared Folders
|
||||
* Fix --single-directory handling of parent path matching if path is being seen for first time
|
||||
|
||||
### Added
|
||||
* Added Fish auto completions
|
||||
|
||||
### Updated
|
||||
* Increase maximum individual file size to 100GB due to Microsoft file limit increase
|
||||
* Update Docker build files and align version of compiler across all Docker builds
|
||||
* Update Docker documentation
|
||||
* Update NixOS build information
|
||||
* Update the 'Processing XXXX' output to display the full path
|
||||
* Update logging output when a sync starts and completes when using --monitor
|
||||
* Update Office 365 / SharePoint site search query and response if query return zero match
|
||||
|
||||
## 2.4.3 - 2020-06-29
|
||||
### Fixed
|
||||
* Check if symbolic link is relative to location path
|
||||
|
|
|
@ -28,6 +28,7 @@ notify_LIBS = @notify_LIBS@
|
|||
COMPLETIONS = @COMPLETIONS@
|
||||
BASH_COMPLETION_DIR = @BASH_COMPLETION_DIR@
|
||||
ZSH_COMPLETION_DIR = @ZSH_COMPLETION_DIR@
|
||||
FISH_COMPLETION_DIR = @FISH_COMPLETION_DIR@
|
||||
DEBUG = @DEBUG@
|
||||
|
||||
DC = @DC@
|
||||
|
@ -127,6 +128,7 @@ endif
|
|||
ifeq ($(COMPLETIONS),yes)
|
||||
$(INSTALL) -D -m 644 contrib/completions/complete.zsh $(DESTDIR)$(ZSH_COMPLETION_DIR)/_onedrive
|
||||
$(INSTALL) -D -m 644 contrib/completions/complete.bash $(DESTDIR)$(BASH_COMPLETION_DIR)/onedrive
|
||||
$(INSTALL) -D -m 644 contrib/completions/complete.fish $(DESTDIR)$(FISH_COMPLETION_DIR)/onedrive.fish
|
||||
endif
|
||||
|
||||
|
||||
|
@ -151,6 +153,7 @@ endif
|
|||
ifeq ($(COMPLETIONS),yes)
|
||||
rm -f $(DESTDIR)$(ZSH_COMPLETION_DIR)/_onedrive
|
||||
rm -f $(DESTDIR)$(BASH_COMPLETION_DIR)/onedrive
|
||||
rm -f $(DESTDIR)$(FISH_COMPLETION_DIR)/onedrive.fish
|
||||
endif
|
||||
|
||||
|
||||
|
|
45
README.md
45
README.md
|
@ -7,7 +7,7 @@
|
|||
|
||||
A free Microsoft OneDrive Client which supports OneDrive Personal, OneDrive for Business, OneDrive for Office365 and Sharepoint.
|
||||
|
||||
This powerful and highly configurable client can run on all major Linux distributions, as a Docker container and on FreeBSD. It supports one-way and two-way sync capabilities and securely connects to Microsoft OneDrive services.
|
||||
This powerful and highly configurable client can run on all major Linux distributions, FreeBSD, or as a Docker container. It supports one-way and two-way sync capabilities and securely connects to Microsoft OneDrive services.
|
||||
|
||||
This client is a 'fork' of the [skilion](https://github.com/skilion/onedrive) client which was abandoned in 2018.
|
||||
|
||||
|
@ -25,26 +25,10 @@ This client is a 'fork' of the [skilion](https://github.com/skilion/onedrive) cl
|
|||
* Support for National cloud deployments (Microsoft Cloud for US Government, Microsoft Cloud Germany, Azure and Office 365 operated by 21Vianet in China)
|
||||
|
||||
## What's missing
|
||||
* While local changes are uploaded right away, remote changes are delayed until next sync when using --monitor
|
||||
* No GUI
|
||||
|
||||
## Building and Installation
|
||||
See [docs/INSTALL.md](https://github.com/abraunegg/onedrive/blob/master/docs/INSTALL.md)
|
||||
|
||||
## Configuration and Usage
|
||||
See [docs/USAGE.md](https://github.com/abraunegg/onedrive/blob/master/docs/USAGE.md)
|
||||
|
||||
## Docker support
|
||||
See [docs/Docker.md](https://github.com/abraunegg/onedrive/blob/master/docs/Docker.md)
|
||||
|
||||
## OneDrive Business Shared Folders
|
||||
See [docs/BusinessSharedFolders.md](https://github.com/abraunegg/onedrive/blob/master/docs/BusinessSharedFolders.md)
|
||||
|
||||
## SharePoint / Office 365 Shared Libraries (Business or Education)
|
||||
See [docs/Office365.md](https://github.com/abraunegg/onedrive/blob/master/docs/Office365.md)
|
||||
|
||||
## National Cloud support
|
||||
See [docs/national-cloud-deployments.md](https://github.com/abraunegg/onedrive/blob/master/docs/national-cloud-deployments.md)
|
||||
* While local changes are uploaded right away, remote changes are delayed until next automated sync cycle when using --monitor
|
||||
* Ability to encrypt/decrpyt files on-the-fly when uploading/downloading files from OneDrive
|
||||
* Support for Windows 'On-Demand' functionality so file is only downloaded when accessed locally
|
||||
* A GUI for configuration management
|
||||
|
||||
## Reporting issues
|
||||
If you encounter any bugs you can report them here on Github. Before filing an issue be sure to:
|
||||
|
@ -56,3 +40,22 @@ If you encounter any bugs you can report them here on Github. Before filing an i
|
|||
|
||||
## Known issues
|
||||
See [docs/known-issues.md](https://github.com/abraunegg/onedrive/blob/master/docs/known-issues.md)
|
||||
|
||||
## Documentation and Configuration Assistance
|
||||
### Building and Installation
|
||||
See [docs/INSTALL.md](https://github.com/abraunegg/onedrive/blob/master/docs/INSTALL.md)
|
||||
|
||||
### Configuration and Usage
|
||||
See [docs/USAGE.md](https://github.com/abraunegg/onedrive/blob/master/docs/USAGE.md)
|
||||
|
||||
### Configure OneDrive Business Shared Folders
|
||||
See [docs/BusinessSharedFolders.md](https://github.com/abraunegg/onedrive/blob/master/docs/BusinessSharedFolders.md)
|
||||
|
||||
### Configure SharePoint / Office 365 Shared Libraries (Business or Education)
|
||||
See [docs/Office365.md](https://github.com/abraunegg/onedrive/blob/master/docs/Office365.md)
|
||||
|
||||
### Configure National Cloud support
|
||||
See [docs/national-cloud-deployments.md](https://github.com/abraunegg/onedrive/blob/master/docs/national-cloud-deployments.md)
|
||||
|
||||
### Docker support
|
||||
See [docs/Docker.md](https://github.com/abraunegg/onedrive/blob/master/docs/Docker.md)
|
||||
|
|
43
configure
vendored
43
configure
vendored
|
@ -1,6 +1,6 @@
|
|||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for onedrive v2.4.4-dev.
|
||||
# Generated by GNU Autoconf 2.69 for onedrive v2.4.6-dev.
|
||||
#
|
||||
# Report bugs to <https://github.com/abraunegg/onedrive>.
|
||||
#
|
||||
|
@ -579,8 +579,8 @@ MAKEFLAGS=
|
|||
# Identity of this package.
|
||||
PACKAGE_NAME='onedrive'
|
||||
PACKAGE_TARNAME='onedrive'
|
||||
PACKAGE_VERSION='v2.4.4-dev'
|
||||
PACKAGE_STRING='onedrive v2.4.4-dev'
|
||||
PACKAGE_VERSION='v2.4.6-dev'
|
||||
PACKAGE_STRING='onedrive v2.4.6-dev'
|
||||
PACKAGE_BUGREPORT='https://github.com/abraunegg/onedrive'
|
||||
PACKAGE_URL=''
|
||||
|
||||
|
@ -588,6 +588,7 @@ ac_unique_file="src/main.d"
|
|||
ac_subst_vars='LTLIBOBJS
|
||||
LIBOBJS
|
||||
DEBUG
|
||||
FISH_COMPLETION_DIR
|
||||
ZSH_COMPLETION_DIR
|
||||
BASH_COMPLETION_DIR
|
||||
bashcompdir
|
||||
|
@ -660,6 +661,7 @@ enable_notifications
|
|||
enable_completions
|
||||
with_bash_completion_dir
|
||||
with_zsh_completion_dir
|
||||
with_fish_completion_dir
|
||||
enable_debug
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
|
@ -1217,7 +1219,7 @@ if test "$ac_init_help" = "long"; then
|
|||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures onedrive v2.4.4-dev to adapt to many kinds of systems.
|
||||
\`configure' configures onedrive v2.4.6-dev to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
|
@ -1278,7 +1280,7 @@ fi
|
|||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of onedrive v2.4.4-dev:";;
|
||||
short | recursive ) echo "Configuration of onedrive v2.4.6-dev:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
|
@ -1289,7 +1291,7 @@ Optional Features:
|
|||
--disable-version-check Disable checks of compiler version during configure
|
||||
time
|
||||
--enable-notifications Enable desktop notifications via libnotify
|
||||
--enable-completions Install shell completions for bash and zsh
|
||||
--enable-completions Install shell completions for bash, zsh, and fish
|
||||
--enable-debug Pass debug option to the compiler
|
||||
|
||||
Optional Packages:
|
||||
|
@ -1303,6 +1305,8 @@ Optional Packages:
|
|||
Directory for bash completion files
|
||||
--with-zsh-completion-dir=DIR
|
||||
Directory for zsh completion files
|
||||
--with-fish-completion-dir=DIR
|
||||
Directory for fish completion files
|
||||
|
||||
Some influential environment variables:
|
||||
DC D compiler executable
|
||||
|
@ -1389,7 +1393,7 @@ fi
|
|||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
onedrive configure v2.4.4-dev
|
||||
onedrive configure v2.4.6-dev
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
|
@ -1406,7 +1410,7 @@ cat >config.log <<_ACEOF
|
|||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by onedrive $as_me v2.4.4-dev, which was
|
||||
It was created by onedrive $as_me v2.4.6-dev, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
|
@ -2158,7 +2162,7 @@ fi
|
|||
|
||||
|
||||
|
||||
PACKAGE_DATE="June 2020"
|
||||
PACKAGE_DATE="August 2020"
|
||||
|
||||
|
||||
|
||||
|
@ -2579,6 +2583,23 @@ fi
|
|||
ZSH_COMPLETION_DIR=$with_zsh_completion_dir
|
||||
|
||||
|
||||
|
||||
# Check whether --with-fish-completion-dir was given.
|
||||
if test "${with_fish_completion_dir+set}" = set; then :
|
||||
withval=$with_fish_completion_dir;
|
||||
else
|
||||
with_fish_completion_dir=auto
|
||||
fi
|
||||
|
||||
if test "x$with_fish_completion_dir" = "xyes" -o "x$with_fish_completion_dir" = "xauto"; then :
|
||||
|
||||
with_fish_completion_dir="/usr/local/share/fish/completions"
|
||||
|
||||
fi
|
||||
FISH_COMPLETION_DIR=$with_fish_completion_dir
|
||||
|
||||
|
||||
|
||||
fi
|
||||
|
||||
# Check whether --enable-debug was given.
|
||||
|
@ -3138,7 +3159,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by onedrive $as_me v2.4.4-dev, which was
|
||||
This file was extended by onedrive $as_me v2.4.6-dev, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
|
@ -3191,7 +3212,7 @@ _ACEOF
|
|||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
onedrive config.status v2.4.4-dev
|
||||
onedrive config.status v2.4.6-dev
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
|
14
configure.ac
14
configure.ac
|
@ -9,7 +9,7 @@ dnl - commit the changed files (configure.ac, configure)
|
|||
dnl - tag the release
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
AC_INIT([onedrive],[v2.4.4-dev], [https://github.com/abraunegg/onedrive], [onedrive])
|
||||
AC_INIT([onedrive],[v2.4.6-dev], [https://github.com/abraunegg/onedrive], [onedrive])
|
||||
AC_CONFIG_SRCDIR([src/main.d])
|
||||
|
||||
|
||||
|
@ -228,7 +228,7 @@ dnl
|
|||
dnl Completion support
|
||||
dnl First determine whether completions are requested, pass that to Makefile
|
||||
AC_ARG_ENABLE([completions],
|
||||
AS_HELP_STRING([--enable-completions], [Install shell completions for bash and zsh]))
|
||||
AS_HELP_STRING([--enable-completions], [Install shell completions for bash, zsh, and fish]))
|
||||
|
||||
AS_IF([test "x$enable_completions" = "xyes"], [enable_completions=yes], [enable_completions=no])
|
||||
|
||||
|
@ -258,6 +258,16 @@ AS_IF([test "x$enable_completions" = "xyes"],[
|
|||
with_zsh_completion_dir="/usr/local/share/zsh/site-functions"
|
||||
])
|
||||
AC_SUBST([ZSH_COMPLETION_DIR], $with_zsh_completion_dir)
|
||||
|
||||
AC_ARG_WITH([fish-completion-dir],
|
||||
[AS_HELP_STRING([--with-fish-completion-dir=DIR], [Directory for fish completion files])],,
|
||||
[with_fish_completion_dir=auto])
|
||||
AS_IF([test "x$with_fish_completion_dir" = "xyes" -o "x$with_fish_completion_dir" = "xauto"],
|
||||
[
|
||||
with_fish_completion_dir="/usr/local/share/fish/completions"
|
||||
])
|
||||
AC_SUBST([FISH_COMPLETION_DIR], $with_fish_completion_dir)
|
||||
|
||||
])
|
||||
|
||||
dnl
|
||||
|
|
35
contrib/completions/complete.fish
Normal file
35
contrib/completions/complete.fish
Normal file
|
@ -0,0 +1,35 @@
|
|||
# FISH completions for OneDrive Linux Client
|
||||
# License: GPLv3+ (as with the rest of the OneDrive Linux client project)
|
||||
|
||||
complete -c onedrive -f
|
||||
|
||||
complete -c onedrive -l check-for-nomount -d 'Check for the presence of .nosync in the syncdir root. If found, do not perform sync.'
|
||||
complete -c onedrive -l check-for-nosync -d 'Check for the presence of .nosync in each directory. If found, skip directory from sync.'
|
||||
complete -c onedrive -l create-directory -d 'Create a directory on OneDrive - no sync will be performed.'
|
||||
complete -c onedrive -l debug-https -d 'Debug OneDrive HTTPS communication.'
|
||||
complete -c onedrive -l disable-notifications -d 'Do not use desktop notifications in monitor mode.'
|
||||
complete -c onedrive -l disable-upload-validation -d 'Disable upload validation when uploading to OneDrive.'
|
||||
complete -c onedrive -l display-config -d 'Display what options the client will use as currently configured - no sync will be performed.'
|
||||
complete -c onedrive -l display-sync-status -d 'Display the sync status of the client - no sync will be performed.'
|
||||
complete -c onedrive -l download-only -d 'Only download remote changes.'
|
||||
complete -c onedrive -l dry-run -d 'Perform a trial sync with no changes made.'
|
||||
complete -c onedrive -l enable-logging -d 'Enable client activity to a separate log file.'
|
||||
complete -c onedrive -l force-http-1.1 -d 'Force the use of HTTP 1.1 for all operations.'
|
||||
complete -c onedrive -l force-http-2 -d 'Force the use of HTTP 2 for all operations.'
|
||||
complete -c onedrive -l get-O365-drive-id -d 'Query and return the Office 365 Drive ID for a given Office 365 SharePoint Shared Library.'
|
||||
complete -c onedrive -s h -l help -d 'Print help information.'
|
||||
complete -c onedrive -l local-first -d 'Synchronize from the local directory source first, before downloading changes from OneDrive.'
|
||||
complete -c onedrive -l logout -d 'Logout the current user.'
|
||||
complete -c onedrive -n "not __fish_seen_subcommand_from --synchronize" -a "-m --monitor" -d 'Keep monitoring for local and remote changes.'
|
||||
complete -c onedrive -l no-remote-delete -d 'Do not delete local file deletes from OneDrive when using --upload-only.'
|
||||
complete -c onedrive -l print-token -d 'Print the access token, useful for debugging.'
|
||||
complete -c onedrive -l remote-directory -d 'Remove a directory on OneDrive - no sync will be performed.'
|
||||
complete -c onedrive -l resync -d 'Forget the last saved state, perform a full sync.'
|
||||
complete -c onedrive -l single-directory -d 'Specify a single local directory within the OneDrive root to sync.'
|
||||
complete -c onedrive -l skip-dot-files -d 'Skip dot files and folders from syncing.'
|
||||
complete -c onedrive -l skip-symlinks -d 'Skip syncing of symlinks.'
|
||||
complete -c onedrive -l source-directory -d 'Source directory to rename or move on OneDrive - no sync will be performed.'
|
||||
complete -c onedrive -n "not __fish_seen_subcommand_from --monitor; and not __fish_seen_subcommand_from -m" -l synchronize -d 'Perform a synchronization.'
|
||||
complete -c onedrive -l upload-only -d 'Only upload to OneDrive, do not sync changes from OneDrive locally'
|
||||
complete -c onedrive -s v -l verbose -d 'Print more details, useful for debugging (repeat for extra debugging).'
|
||||
complete -c onedrive -l version -d 'Print the version and exit.'
|
|
@ -6,7 +6,7 @@
|
|||
%endif
|
||||
|
||||
Name: onedrive
|
||||
Version: 2.4.3
|
||||
Version: 2.4.5
|
||||
Release: 1%{?dist}
|
||||
Summary: Microsoft OneDrive Client
|
||||
Group: System Environment/Network
|
||||
|
|
|
@ -11,7 +11,7 @@ This container offers simple monitoring-mode service for 'Free Client for OneDri
|
|||
### 1. Pull the image
|
||||
|
||||
```bash
|
||||
docker pull driveone/onedrive
|
||||
docker pull driveone/onedrive:latest
|
||||
```
|
||||
|
||||
**NOTE:** SELinux context needs to be configured or disabled for Docker, to be able to write to OneDrive host directory.
|
||||
|
@ -34,11 +34,12 @@ The second docker volume is for your data folder and is created in the next step
|
|||
|
||||
### 3. First run
|
||||
|
||||
Onedrive needs to be authorized with your Microsoft account. This is achieved by running docker in interactive mode. Run the docker image with the two commands below and **make sure to change `onedriveDir` to the onedrive data directory on your filesystem (e.g. `"/home/abraunegg/OneDrive"`)**
|
||||
Onedrive needs to be authorized with your Microsoft account. This is achieved by running docker in interactive mode. Run the docker image with the two commands below and **make sure to change `onedriveDir` to the onedrive data directory on your filesystem (e.g. `"/home/abraunegg/OneDrive"`)**.
|
||||
Additionally, the user id and group id should be added to remove any potential user conflicts, denoted by the environment variables `${ONEDRIVE_UID}` and `${ONEDRIVE_GID}`.
|
||||
|
||||
```bash
|
||||
onedriveDir="${HOME}/OneDrive"
|
||||
docker run -it --restart unless-stopped --name onedrive -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" driveone/onedrive
|
||||
docker run -it --name onedrive -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" -e "ONEDRIVE_UID:${ONEDRIVE_UID}" -e "ONEDRIVE_GID:${ONEDRIVE_GID}" driveone/onedrive:latest
|
||||
```
|
||||
|
||||
- You will be asked to open a specific link using your web browser
|
||||
|
@ -81,7 +82,29 @@ docker rm -f onedrive
|
|||
```
|
||||
## Advanced Setup
|
||||
|
||||
### 5. Edit the config
|
||||
### 5. Docker-compose
|
||||
|
||||
Also supports docker-compose schemas > 3.
|
||||
In the following example it is assumed you have a `onedriveDir` environment variable and a `onedrive_conf` volume.
|
||||
However, you can also use bind mounts for the configuration folder, e.g. `export ONEDRIVE_CONF="${HOME}/OneDriveConfig"`.
|
||||
|
||||
```
|
||||
version: "3"
|
||||
services:
|
||||
onedrive:
|
||||
image: driveone/onedrive:latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- ONEDRIVE_UID=${PUID}
|
||||
- ONEDRIVE_GID=${PGID}
|
||||
volumes:
|
||||
- onedrive_conf:/onedrive/conf
|
||||
- ${onedriveDir}:/onedrive/data
|
||||
```
|
||||
|
||||
Note that you still have to perform step 3: First Run.
|
||||
|
||||
### 6. Edit the config
|
||||
|
||||
Onedrive should run in default configuration, however you can change your configuration by placing a custom config file in the `onedrive_conf` docker volume. First download the default config from [here](https://raw.githubusercontent.com/abraunegg/onedrive/master/config)
|
||||
Then put it into your onedrive_conf volume path, which can be found with:
|
||||
|
@ -94,14 +117,14 @@ Or you can map your own config folder to the config volume. Make sure to copy al
|
|||
|
||||
The detailed document for the config can be found here: [additional-configuration](https://github.com/abraunegg/onedrive#additional-configuration)
|
||||
|
||||
### 6. Sync multiple accounts
|
||||
### 7. Sync multiple accounts
|
||||
|
||||
There are many ways to do this, the easiest is probably to
|
||||
1. Create a second docker config volume (replace `Work` with your desired name): `docker volume create onedrive_conf_Work`
|
||||
2. And start a second docker monitor container (again replace `Work` with your desired name):
|
||||
```
|
||||
onedriveDirWork="/home/abraunegg/OneDriveWork"
|
||||
docker run -it --restart unless-stopped --name onedrive_Work -v onedrive_conf_Work:/onedrive/conf -v "${onedriveDirWork}:/onedrive/data" driveone/onedrive
|
||||
docker run -it --restart unless-stopped --name onedrive_Work -v onedrive_conf_Work:/onedrive/conf -v "${onedriveDirWork}:/onedrive/data" driveone/onedrive:latest
|
||||
```
|
||||
|
||||
## Run or update with one script
|
||||
|
@ -113,10 +136,10 @@ If you are experienced with docker and onedrive, you can use the following scrip
|
|||
onedriveDir="${HOME}/OneDrive"
|
||||
|
||||
firstRun='-d'
|
||||
docker pull driveone/onedrive
|
||||
docker pull driveone/onedrive:latest
|
||||
docker inspect onedrive_conf > /dev/null || { docker volume create onedrive_conf; firstRun='-it'; }
|
||||
docker inspect onedrive > /dev/null && docker rm -f onedrive
|
||||
docker run $firstRun --restart unless-stopped --name onedrive -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" driveone/onedrive
|
||||
docker run $firstRun --restart unless-stopped --name onedrive -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" driveone/onedrive:latest
|
||||
```
|
||||
|
||||
|
||||
|
@ -134,19 +157,19 @@ docker run $firstRun --restart unless-stopped --name onedrive -v onedrive_conf:/
|
|||
### Usage Examples
|
||||
**Verbose Output:**
|
||||
```bash
|
||||
docker container run -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" driveone/onedrive
|
||||
docker container run -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" driveone/onedrive:latest
|
||||
```
|
||||
**Debug Output:**
|
||||
```bash
|
||||
docker container run -e ONEDRIVE_DEBUG=1 -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" driveone/onedrive
|
||||
docker container run -e ONEDRIVE_DEBUG=1 -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" driveone/onedrive:latest
|
||||
```
|
||||
**Perform a --resync:**
|
||||
```bash
|
||||
docker container run -e ONEDRIVE_RESYNC=1 -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" driveone/onedrive
|
||||
docker container run -e ONEDRIVE_RESYNC=1 -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" driveone/onedrive:latest
|
||||
```
|
||||
**Perform a --resync and --verbose:**
|
||||
```bash
|
||||
docker container run -e ONEDRIVE_RESYNC=1 -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" driveone/onedrive
|
||||
docker container run -e ONEDRIVE_RESYNC=1 -e ONEDRIVE_VERBOSE=1 -v onedrive_conf:/onedrive/conf -v "${onedriveDir}:/onedrive/data" driveone/onedrive:latest
|
||||
```
|
||||
|
||||
## Build instructions
|
||||
|
|
|
@ -6,8 +6,8 @@ This project has been packaged for the following Linux distributions:
|
|||
* Arch Linux, available from AUR as [onedrive-abraunegg](https://aur.archlinux.org/packages/onedrive-abraunegg/)
|
||||
* Debian, available from the package repository as [onedrive](https://packages.debian.org/sid/net/onedrive)
|
||||
* Fedora, available via package repositories as [onedrive](https://koji.fedoraproject.org/koji/packageinfo?packageID=26044)
|
||||
* NixOS, available on unstable channel (and stable since 20.03). Use package `onedrive` either by adding it to `configuration.nix` or by using the command `nix-env -iA <channel name>.onedrive`. This does not install a service. There is a [PR](https://github.com/NixOS/nixpkgs/pull/77734) (which needs work) which has code which can be used to install a service. See documentation in the same PR.
|
||||
* openSUSE, available for Tumbleweed as [onedrive](https://software.opensuse.org/package/onedrive) - just install using: `zypper in onedrive`
|
||||
* NixOS, use package `onedrive` either by adding it to `configuration.nix` or by using the command `nix-env -iA <channel name>.onedrive`. This does not install a service. To install a service, use unstable channel (will stabilize in 20.09) and add `services.onedrive.enable=true` in `configuration.nix`. You can also add a custom package using the `services.onedrive.package` option (recommended since package lags upstream). Enabling the service installs a default package too (based on the channel). You can also add multiple onedrive accounts trivially, see [documentation](https://github.com/NixOS/nixpkgs/pull/77734#issuecomment-575874225)`.
|
||||
* openSUSE, available for Tumbleweed as [onedrive](https://software.opensuse.org/package/onedrive)
|
||||
* Slackware, available from the slackbuilds.org repository as [onedrive](https://slackbuilds.org/repository/14.2/network/onedrive/)
|
||||
* Solus, available from the package repository as [onedrive](https://dev.getsol.us/search/query/FB7PIf1jG9Z9/#R)
|
||||
* Ubuntu, available as a package from the following PPA [onedrive](https://launchpad.net/~yann1ck/+archive/ubuntu/onedrive)
|
||||
|
@ -16,16 +16,27 @@ This project has been packaged for the following Linux distributions:
|
|||
Distribution packages may be of an older release when compared to the latest release that is [available](https://github.com/abraunegg/onedrive/releases). If a package is out of date, please contact the package maintainer for resolution.
|
||||
|
||||
#### Important information for Ubuntu users:
|
||||
Whilst there are [onedrive](https://packages.ubuntu.com/search?keywords=onedrive&searchon=names&suite=all§ion=all) packages available for Ubuntu, do not install 'onedrive' from these packages. These packages are out of date and should not be used. If you wish to use a package, use the PPA listed above.
|
||||
Whilst there are [onedrive](https://packages.ubuntu.com/search?keywords=onedrive&searchon=names&suite=all§ion=all) packages available for Ubuntu, do not install 'onedrive' from these packages via `apt install onedrive`. These packages are out-of-date and should not be used. If you wish to use a package, it is highly recommended that you utilise the PPA listed above or build from source using the instructions below for Ubuntu and those distributions (such as Lubuntu) which are derived from Ubuntu.
|
||||
|
||||
## Build Requirements
|
||||
* Build environment must have at least 1GB of memory & 1GB swap space
|
||||
* [libcurl](http://curl.haxx.se/libcurl/)
|
||||
* [SQLite 3](https://www.sqlite.org/) >= 3.7.15
|
||||
* [Digital Mars D Compiler (DMD)](http://dlang.org/download.html)
|
||||
* [Digital Mars D Compiler (DMD)](http://dlang.org/download.html) or [LDC – the LLVM-based D Compiler](https://github.com/ldc-developers/ldc)
|
||||
|
||||
**Note:** DMD version >= 2.083.1 or LDC version >= 1.12.0 is required to compile this application
|
||||
|
||||
### Example for installing DMD Compiler
|
||||
```text
|
||||
curl -fsS https://dlang.org/install.sh | bash -s dmd
|
||||
```
|
||||
|
||||
### Example for installing LDC Compiler
|
||||
```text
|
||||
curl -fsS https://dlang.org/install.sh | bash -s ldc
|
||||
```
|
||||
|
||||
## Distribution Package Dependencies
|
||||
### Dependencies: Ubuntu 16.x - i386 / i686 (less than 1GB Memory)
|
||||
**Important:** Build environment must have at least 512 of memory & 1GB swap space
|
||||
|
||||
|
@ -292,6 +303,7 @@ as far as possible automatically, but can be overridden by passing
|
|||
|
||||
### Building using a different compiler (for example [LDC](https://wiki.dlang.org/LDC))
|
||||
#### ARMHF Architecture
|
||||
**Note:** Build environment must have at least 1GB of memory & 1GB swap space. Check with `swapon -s`
|
||||
```text
|
||||
git clone https://github.com/abraunegg/onedrive.git
|
||||
cd onedrive
|
||||
|
@ -301,6 +313,7 @@ sudo make install
|
|||
```
|
||||
|
||||
#### ARM64 Architecture
|
||||
**Note:** Build environment must have at least 1GB of memory & 1GB swap space. Check with `swapon -s`
|
||||
```text
|
||||
git clone https://github.com/abraunegg/onedrive.git
|
||||
cd onedrive
|
||||
|
|
|
@ -340,6 +340,17 @@ Patterns are case insensitive. `*` and `?` [wildcards characters](https://techne
|
|||
|
||||
**Important:** Entries under `skip_dir` are relative to your `sync_dir` path.
|
||||
|
||||
**Note:** The `skip_dir` can be specified multiple times, for example:
|
||||
```text
|
||||
skip_dir = "SomeDir|OtherDir|ThisDir|ThatDir"
|
||||
skip_dir = "/Path/To/A/Directory"
|
||||
skip_dir = "/Another/Path/To/Different/Directory"
|
||||
```
|
||||
This will be interpreted the same as:
|
||||
```text
|
||||
skip_dir = "SomeDir|OtherDir|ThisDir|ThatDir|/Path/To/A/Directory|/Another/Path/To/Different/Directory"
|
||||
```
|
||||
|
||||
**Note:** After changing `skip_dir`, you must perform a full re-synchronization by adding `--resync` to your existing command line - for example: `onedrive --synchronize --resync`
|
||||
|
||||
#### skip_file
|
||||
|
@ -368,6 +379,17 @@ By default, the following files will be skipped:
|
|||
|
||||
**Important:** Do not use a skip_file entry of `.*` as this will prevent correct searching of local changes to process.
|
||||
|
||||
**Note:** The `skip_file` can be specified multiple times, for example:
|
||||
```text
|
||||
skip_file = "~*|.~*|*.tmp|*.swp"
|
||||
skip_file = "*.blah"
|
||||
skip_file = "never_sync.file"
|
||||
```
|
||||
This will be interpreted the same as:
|
||||
```text
|
||||
skip_file = "~*|.~*|*.tmp|*.swp|*.blah|never_sync.file"
|
||||
```
|
||||
|
||||
**Note:** after changing `skip_file`, you must perform a full re-synchronization by adding `--resync` to your existing command line - for example: `onedrive --synchronize --resync`
|
||||
|
||||
#### skip_dotfiles
|
||||
|
@ -421,20 +443,32 @@ Each line of the file represents a relative path from your `sync_dir`. All files
|
|||
Here is an example of `sync_list`:
|
||||
```text
|
||||
# sync_list supports comments
|
||||
# Exclude my Backup folder
|
||||
# Include my Backup folder
|
||||
Backup
|
||||
# Exclude this single document
|
||||
# Include Documents folder
|
||||
Documents/
|
||||
# Exclude temp folders under Documents
|
||||
!Documents/temp*
|
||||
# Include all PDF documents
|
||||
Documents/*.pdf
|
||||
# Include this single document
|
||||
Documents/latest_report.docx
|
||||
# Exclude all Work/Project directories
|
||||
# Include all Work/Project directories
|
||||
Work/Project*
|
||||
notes.txt
|
||||
# Exclude /Blender in the ~OneDrive root but not if elsewhere
|
||||
# Include /Blender in the ~OneDrive root but not if elsewhere
|
||||
/Blender
|
||||
# Include these names if they match any file or folder
|
||||
Cinema Soc
|
||||
Codes
|
||||
Textbooks
|
||||
Year 2
|
||||
```
|
||||
The following are supported for pattern matching and exclusion rules:
|
||||
* Use the `*` to wildcard select any characters to match for the item to be included
|
||||
* Use either `!` or `-` characters at the start of the line to exclude an otherwise included item
|
||||
|
||||
|
||||
**Note:** after changing the sync_list, you must perform a full re-synchronization by adding `--resync` to your existing command line - for example: `onedrive --synchronize --resync`
|
||||
|
||||
### How to 'skip' directories from syncing?
|
||||
|
@ -595,6 +629,8 @@ onedrive --monitor --verbose --confdir="~/.config/onedriveWork" &
|
|||
* `--monitor` keeps the application running and monitoring for changes both local and remote
|
||||
* `&` puts the application in background and leaves the terminal interactive
|
||||
|
||||
**Important:** For each configuration, change the 'sync_dir' to a new value, unique for each specific configuration. Leaving this at the default of `sync_dir = "~/OneDrive"` will cause all data from both accounts to be synced to the same folder, then to each other.
|
||||
|
||||
### Automatic syncing of both OneDrive accounts
|
||||
In order to automatically start syncing your OneDrive accounts, you will need to create a service file for each account. From the applicable 'user systemd folder':
|
||||
* RHEL / CentOS: `/usr/lib/systemd/system`
|
||||
|
@ -686,6 +722,8 @@ Options:
|
|||
Set the directory used to store the configuration files
|
||||
--create-directory ARG
|
||||
Create a directory on OneDrive - no sync will be performed.
|
||||
--create-share-link ARG
|
||||
Create a shareable link for an existing file on OneDrive
|
||||
--debug-https
|
||||
Debug OneDrive HTTPS communication.
|
||||
--destination-directory ARG
|
||||
|
|
|
@ -44,6 +44,9 @@ Set the directory used to store the configuration files
|
|||
\fB\-\-create\-directory\fP ARG
|
||||
Create a directory on OneDrive \- no sync will be performed.
|
||||
.TP
|
||||
\fB\-\-create\-share\-link\fP ARG
|
||||
Create a shareable link for an existing file on OneDrive
|
||||
.TP
|
||||
\fB\-\-debug\-https\fP
|
||||
Debug OneDrive HTTPS communication.
|
||||
.br
|
||||
|
|
31
src/config.d
31
src/config.d
|
@ -249,6 +249,7 @@ final class Config
|
|||
{
|
||||
// Add additional options that are NOT configurable via config file
|
||||
stringValues["create_directory"] = "";
|
||||
stringValues["create_share_link"] = "";
|
||||
stringValues["destination_directory"] = "";
|
||||
stringValues["get_file_link"] = "";
|
||||
stringValues["get_o365_drive_id"] = "";
|
||||
|
@ -293,6 +294,9 @@ final class Config
|
|||
"create-directory",
|
||||
"Create a directory on OneDrive - no sync will be performed.",
|
||||
&stringValues["create_directory"],
|
||||
"create-share-link",
|
||||
"Create a shareable link for an existing file on OneDrive",
|
||||
&stringValues["create_share_link"],
|
||||
"debug-https",
|
||||
"Debug OneDrive HTTPS communication.",
|
||||
&boolValues["debug_https"],
|
||||
|
@ -540,8 +544,29 @@ final class Config
|
|||
// --skip-file ARG
|
||||
// --skip-dir ARG
|
||||
if (key == "sync_dir") configFileSyncDir = c.front.dup;
|
||||
if (key == "skip_file") configFileSkipFile = c.front.dup;
|
||||
if (key == "skip_dir") configFileSkipDir = c.front.dup;
|
||||
if (key == "skip_file") {
|
||||
// Handle multiple entries of skip_file
|
||||
if (configFileSkipFile.empty) {
|
||||
// currently no entry exists
|
||||
configFileSkipFile = c.front.dup;
|
||||
} else {
|
||||
// add to existing entry
|
||||
configFileSkipFile = configFileSkipFile ~ "|" ~ to!string(c.front.dup);
|
||||
setValueString("skip_file", configFileSkipFile);
|
||||
}
|
||||
}
|
||||
if (key == "skip_dir") {
|
||||
// Handle multiple entries of skip_dir
|
||||
if (configFileSkipDir.empty) {
|
||||
// currently no entry exists
|
||||
configFileSkipDir = c.front.dup;
|
||||
} else {
|
||||
// add to existing entry
|
||||
configFileSkipDir = configFileSkipDir ~ "|" ~ to!string(c.front.dup);
|
||||
setValueString("skip_dir", configFileSkipDir);
|
||||
}
|
||||
}
|
||||
|
||||
// Azure AD Configuration
|
||||
if (key == "azure_ad_endpoint") {
|
||||
string azureConfigValue = c.front.dup;
|
||||
|
@ -591,7 +616,9 @@ void outputLongHelp(Option[] opt)
|
|||
auto argsNeedingOptions = [
|
||||
"--confdir",
|
||||
"--create-directory",
|
||||
"--create-share-link",
|
||||
"--destination-directory",
|
||||
"--get-file-link",
|
||||
"--get-O365-drive-id",
|
||||
"--log-dir",
|
||||
"--min-notify-changes",
|
||||
|
|
|
@ -248,7 +248,7 @@ final class ItemDatabase
|
|||
}
|
||||
|
||||
// same as selectByPath() but it does not traverse remote folders
|
||||
bool selectByPathWithRemote(const(char)[] path, string rootDriveId, out Item item)
|
||||
bool selectByPathWithoutRemote(const(char)[] path, string rootDriveId, out Item item)
|
||||
{
|
||||
Item currItem = { driveId: rootDriveId };
|
||||
|
||||
|
|
28
src/main.d
28
src/main.d
|
@ -565,7 +565,7 @@ int main(string[] args)
|
|||
|
||||
// create-directory, remove-directory, source-directory, destination-directory
|
||||
// these are activities that dont perform a sync, so to not generate an error message for these items either
|
||||
if (((cfg.getValueString("create_directory") != "") || (cfg.getValueString("remove_directory") != "")) || ((cfg.getValueString("source_directory") != "") && (cfg.getValueString("destination_directory") != "")) || (cfg.getValueString("get_file_link") != "") || (cfg.getValueString("get_o365_drive_id") != "") || cfg.getValueBool("display_sync_status") || cfg.getValueBool("list_business_shared_folders")) {
|
||||
if (((cfg.getValueString("create_directory") != "") || (cfg.getValueString("remove_directory") != "")) || ((cfg.getValueString("source_directory") != "") && (cfg.getValueString("destination_directory") != "")) || (cfg.getValueString("get_file_link") != "") || (cfg.getValueString("create_share_link") != "") || (cfg.getValueString("get_o365_drive_id") != "") || cfg.getValueBool("display_sync_status") || cfg.getValueBool("list_business_shared_folders")) {
|
||||
performSyncOK = true;
|
||||
}
|
||||
|
||||
|
@ -700,8 +700,8 @@ int main(string[] args)
|
|||
// Use exit scopes to shutdown API
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
if (cfg.getValueString("get_file_link") == "") {
|
||||
// Print out that we are initializing the engine only if we are not grabbing the file link
|
||||
if ((cfg.getValueString("get_file_link") == "") && (cfg.getValueString("create_share_link") == "")) {
|
||||
// Print out that we are initializing the engine only if we are not grabbing the file link or creating a shareable link
|
||||
log.logAndNotify("Initializing the Synchronization Engine ...");
|
||||
}
|
||||
}
|
||||
|
@ -790,8 +790,18 @@ int main(string[] args)
|
|||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Are we createing an anonymous read-only shareable link for an existing file on OneDrive?
|
||||
if (cfg.getValueString("create_share_link") != "") {
|
||||
// Query OneDrive for the file, and if valid, create a shareable link for the file
|
||||
sync.createShareableLinkForFile(cfg.getValueString("create_share_link"));
|
||||
// Exit application
|
||||
// Use exit scopes to shutdown API
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// Are we obtaining the URL path for a synced file?
|
||||
if (cfg.getValueString("get_file_link") != "") {
|
||||
// Query OneDrive for the file link
|
||||
sync.queryOneDriveForFileURL(cfg.getValueString("get_file_link"), syncDir);
|
||||
// Exit application
|
||||
// Use exit scopes to shutdown API
|
||||
|
@ -846,10 +856,10 @@ int main(string[] args)
|
|||
if (cfg.getValueString("single_directory") != "") {
|
||||
// Does the directory we want to sync actually exist?
|
||||
if (!exists(cfg.getValueString("single_directory"))) {
|
||||
// the requested directory does not exist ..
|
||||
log.logAndNotify("ERROR: The requested local directory does not exist. Please check ~/OneDrive/ for requested path");
|
||||
// Use exit scopes to shutdown API
|
||||
return EXIT_FAILURE;
|
||||
// The requested path to use with --single-directory does not exist locally within the configured 'sync_dir'
|
||||
log.logAndNotify("WARNING: The requested path for --single-directory does not exist locally. Creating requested path within ", syncDir);
|
||||
// Make the required path locally
|
||||
mkdirRecurse(cfg.getValueString("single_directory"));
|
||||
}
|
||||
}
|
||||
// perform a --synchronize sync
|
||||
|
@ -1029,7 +1039,7 @@ int main(string[] args)
|
|||
}
|
||||
try {
|
||||
// perform a --monitor sync
|
||||
if (logMonitorCounter == logInterval) log.log("Starting a sync with OneDrive");
|
||||
if ((cfg.getValueLong("verbose") > 0) || (logMonitorCounter == logInterval)) log.log("Starting a sync with OneDrive");
|
||||
performSync(sync, cfg.getValueString("single_directory"), cfg.getValueBool("download_only"), cfg.getValueBool("local_first"), cfg.getValueBool("upload_only"), (logMonitorCounter == logInterval ? MONITOR_LOG_QUIET : MONITOR_LOG_SILENT), fullScanRequired, syncListConfiguredFullScanOverride, displaySyncOptions, cfg.getValueBool("monitor"), m);
|
||||
if (!cfg.getValueBool("download_only")) {
|
||||
// discard all events that may have been generated by the sync that have not already been handled
|
||||
|
@ -1040,7 +1050,7 @@ int main(string[] args)
|
|||
log.error("ERROR: The following inotify error was generated: ", e.msg);
|
||||
}
|
||||
}
|
||||
if (logMonitorCounter == logInterval) log.log("Sync with OneDrive is complete");
|
||||
if ((cfg.getValueLong("verbose") > 0) || (logMonitorCounter == logInterval)) log.log("Sync with OneDrive is complete");
|
||||
} catch (CurlException e) {
|
||||
// we already tried three times in the performSync routine
|
||||
// if we still have problems, then the sync handle might have
|
||||
|
|
|
@ -84,19 +84,27 @@ final class Monitor
|
|||
return;
|
||||
}
|
||||
|
||||
// skip monitoring any filtered items
|
||||
// Skip the monitoring of any user filtered items
|
||||
if (dirname != ".") {
|
||||
// is the directory name a match to a skip_dir entry?
|
||||
if (selectiveSync.isDirNameExcluded(dirname.strip('.').strip('/'))) {
|
||||
// dont add a watch for this item
|
||||
log.vdebug("Skipping monitoring due to skip_dir match: ", dirname);
|
||||
return;
|
||||
// Is the directory name a match to a skip_dir entry?
|
||||
// The path that needs to be checked needs to include the '/'
|
||||
// This due to if the user has specified in skip_dir an exclusive path: '/path' - that is what must be matched
|
||||
if (isDir(dirname)) {
|
||||
if (selectiveSync.isDirNameExcluded(dirname.strip('.'))) {
|
||||
// dont add a watch for this item
|
||||
log.vdebug("Skipping monitoring due to skip_dir match: ", dirname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// is the filename a match to a skip_file entry?
|
||||
if (selectiveSync.isFileNameExcluded(baseName(dirname))) {
|
||||
// dont add a watch for this item
|
||||
log.vdebug("Skipping monitoring due to skip_file match: ", dirname);
|
||||
return;
|
||||
if (isFile(dirname)) {
|
||||
// Is the filename a match to a skip_file entry?
|
||||
// The path that needs to be checked needs to include the '/'
|
||||
// This due to if the user has specified in skip_file an exclusive path: '/path/file' - that is what must be matched
|
||||
if (selectiveSync.isFileNameExcluded(dirname.strip('.'))) {
|
||||
// dont add a watch for this item
|
||||
log.vdebug("Skipping monitoring due to skip_file match: ", dirname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// is the path exluded by sync_list?
|
||||
if (selectiveSync.isPathExcludedViaSyncList(buildNormalizedPath(dirname))) {
|
||||
|
@ -231,6 +239,7 @@ final class Monitor
|
|||
while (i < length) {
|
||||
inotify_event *event = cast(inotify_event*) &buffer[i];
|
||||
string path;
|
||||
string evalPath;
|
||||
// inotify event debug
|
||||
log.vdebug("inotify event wd: ", event.wd);
|
||||
log.vdebug("inotify event mask: ", event.mask);
|
||||
|
@ -272,19 +281,38 @@ final class Monitor
|
|||
|
||||
// if the event is not to be ignored, obtain path
|
||||
path = getPath(event);
|
||||
// configure the skip_dir & skip skip_file comparison item
|
||||
evalPath = path.strip('.');
|
||||
|
||||
// skip events that should be excluded based on application configuration
|
||||
if (selectiveSync.isDirNameExcluded(path.strip('.').strip('/'))) {
|
||||
goto skip;
|
||||
}
|
||||
if (selectiveSync.isFileNameExcluded(path.strip('.').strip('/'))) {
|
||||
goto skip;
|
||||
// Skip events that should be excluded based on application configuration
|
||||
// We cant use isDir or isFile as this information is missing from the inotify event itself
|
||||
// Thus this causes a segfault when attempting to query this - https://github.com/abraunegg/onedrive/issues/995
|
||||
|
||||
// Based on the 'type' of event & object type (directory or file) check that path against the 'right' user exclusions
|
||||
// Directory events should only be compared against skip_dir and file events should only be compared against skip_file
|
||||
if (event.mask & IN_ISDIR) {
|
||||
// The event in question contains IN_ISDIR event mask, thus highly likely this is an event on a directory
|
||||
// This due to if the user has specified in skip_dir an exclusive path: '/path' - that is what must be matched
|
||||
if (selectiveSync.isDirNameExcluded(evalPath)) {
|
||||
// The path to evaluate matches a path that the user has configured to skip
|
||||
goto skip;
|
||||
}
|
||||
} else {
|
||||
// The event in question missing the IN_ISDIR event mask, thus highly likely this is an event on a file
|
||||
// This due to if the user has specified in skip_file an exclusive path: '/path/file' - that is what must be matched
|
||||
if (selectiveSync.isFileNameExcluded(evalPath)) {
|
||||
// The path to evaluate matches a file that the user has configured to skip
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
|
||||
// is the path, excluded via sync_list
|
||||
if (selectiveSync.isPathExcludedViaSyncList(path)) {
|
||||
// The path to evaluate matches a directory or file that the user has configured not to include in the sync
|
||||
goto skip;
|
||||
}
|
||||
|
||||
// handle events
|
||||
// handle the inotify events
|
||||
if (event.mask & IN_MOVED_FROM) {
|
||||
log.vdebug("event IN_MOVED_FROM: ", path);
|
||||
cookieToPath[event.cookie] = path;
|
||||
|
|
|
@ -491,6 +491,16 @@ final class OneDriveApi
|
|||
return get(url);
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/drive_get
|
||||
JSONValue getDriveQuota(const(char)[] driveId)
|
||||
{
|
||||
checkAccessTokenExpired();
|
||||
const(char)[] url;
|
||||
url = driveByIdUrl ~ driveId ~ "/";
|
||||
url ~= "?select=quota";
|
||||
return get(url);
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_delta
|
||||
JSONValue viewChangesByItemId(const(char)[] driveId, const(char)[] id, const(char)[] deltaLink)
|
||||
{
|
||||
|
@ -628,7 +638,7 @@ final class OneDriveApi
|
|||
return get(url);
|
||||
}
|
||||
|
||||
// Return the requested details of the specified file id
|
||||
// Return the requested details of the specified item id
|
||||
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_get
|
||||
JSONValue getFileDetails(const(char)[] driveId, const(char)[] id)
|
||||
{
|
||||
|
@ -639,6 +649,17 @@ final class OneDriveApi
|
|||
return get(url);
|
||||
}
|
||||
|
||||
// Create an anonymous read-only shareable link for an existing file on OneDrive
|
||||
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createlink
|
||||
JSONValue createShareableLink(const(char)[] driveId, const(char)[] id, JSONValue accessScope)
|
||||
{
|
||||
checkAccessTokenExpired();
|
||||
const(char)[] url;
|
||||
url = driveByIdUrl ~ driveId ~ "/items/" ~ id ~ "/createLink";
|
||||
http.addRequestHeader("Content-Type", "application/json");
|
||||
return post(url, accessScope.toString());
|
||||
}
|
||||
|
||||
// https://dev.onedrive.com/items/move.htm
|
||||
JSONValue moveByPath(const(char)[] sourcePath, JSONValue moveData)
|
||||
{
|
||||
|
@ -703,10 +724,10 @@ final class OneDriveApi
|
|||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/site_search?view=odsp-graph-online
|
||||
JSONValue o365SiteSearch(string o365SharedLibraryName){
|
||||
JSONValue o365SiteSearch(){
|
||||
checkAccessTokenExpired();
|
||||
const(char)[] url;
|
||||
url = siteSearchUrl ~ "=" ~ o365SharedLibraryName;
|
||||
url = siteSearchUrl ~ "=*";
|
||||
return get(url);
|
||||
}
|
||||
|
||||
|
@ -1063,8 +1084,8 @@ final class OneDriveApi
|
|||
}
|
||||
} catch (CurlException e) {
|
||||
// Parse and display error message received from OneDrive
|
||||
log.vdebug("onedrive.perform() Generated a OneDrive CurlException");
|
||||
log.error("ERROR: OneDrive returned an error with the following message:");
|
||||
|
||||
auto errorArray = splitLines(e.msg);
|
||||
string errorMessage = errorArray[0];
|
||||
|
||||
|
|
103
src/selective.d
103
src/selective.d
|
@ -4,7 +4,9 @@ import std.file;
|
|||
import std.path;
|
||||
import std.regex;
|
||||
import std.stdio;
|
||||
import std.string;
|
||||
import util;
|
||||
import log;
|
||||
|
||||
final class SelectiveSync
|
||||
{
|
||||
|
@ -83,6 +85,7 @@ final class SelectiveSync
|
|||
// Does the directory name match skip_dir config entry?
|
||||
// Returns true if the name matches a skip_dir config entry
|
||||
// Returns false if no match
|
||||
log.vdebug("skip_dir evaluation for: ", name);
|
||||
|
||||
// Try full path match first
|
||||
if (!name.matchFirst(dirmask).empty) {
|
||||
|
@ -91,8 +94,8 @@ final class SelectiveSync
|
|||
// Do we check the base name as well?
|
||||
if (!skipDirStrictMatch) {
|
||||
// check just the basename in the path
|
||||
string filename = baseName(name);
|
||||
if(!filename.matchFirst(dirmask).empty) {
|
||||
string parent = baseName(name);
|
||||
if(!parent.matchFirst(dirmask).empty) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +110,7 @@ final class SelectiveSync
|
|||
// Does the file name match skip_file config entry?
|
||||
// Returns true if the name matches a skip_file config entry
|
||||
// Returns false if no match
|
||||
log.vdebug("skip_file evaluation for: ", name);
|
||||
|
||||
// Try full path match first
|
||||
if (!name.matchFirst(mask).empty) {
|
||||
|
@ -125,6 +129,7 @@ final class SelectiveSync
|
|||
// Match against sync_list only
|
||||
bool isPathExcludedViaSyncList(string path)
|
||||
{
|
||||
// Debug output that we are performing a 'sync_list' inclusion / exclusion test
|
||||
return .isPathExcluded(path, paths);
|
||||
}
|
||||
|
||||
|
@ -191,24 +196,104 @@ final class SelectiveSync
|
|||
// if there are no allowed paths always return false
|
||||
private bool isPathExcluded(string path, string[] allowedPaths)
|
||||
{
|
||||
// function variables
|
||||
bool exclude = false;
|
||||
bool finalResult = true; // will get updated to false, if pattern matched to sync_list entry
|
||||
int offset;
|
||||
string wildcard = "*";
|
||||
|
||||
// always allow the root
|
||||
if (path == ".") return false;
|
||||
// if there are no allowed paths always return false
|
||||
if (allowedPaths.empty) return false;
|
||||
|
||||
path = buildNormalizedPath(path);
|
||||
foreach (allowed; allowedPaths) {
|
||||
auto comm = commonPrefix(path, allowed);
|
||||
log.vdebug("Evaluation against 'sync_list' for: ", path);
|
||||
|
||||
// unless path is an exact match, entire sync_list entries need to be processed to ensure
|
||||
// negative matches are also correctly detected
|
||||
foreach (allowedPath; allowedPaths) {
|
||||
// is this an inclusion path or finer grained exclusion?
|
||||
switch (allowedPath[0]) {
|
||||
case '-':
|
||||
// allowed path starts with '-', this user wants to exclude this path
|
||||
exclude = true;
|
||||
offset = 1;
|
||||
break;
|
||||
case '!':
|
||||
// allowed path starts with '!', this user wants to exclude this path
|
||||
exclude = true;
|
||||
offset = 1;
|
||||
break;
|
||||
case '/':
|
||||
// allowed path starts with '/', this user wants to include this path
|
||||
// but a '/' at the start causes matching issues, so use the offset for comparison
|
||||
exclude = false;
|
||||
offset = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
// no negative pattern, default is to not exclude
|
||||
exclude = false;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
// What are we comparing against?
|
||||
log.vdebug("Evaluation against 'sync_list' entry: ", allowedPath);
|
||||
|
||||
// Generate the common prefix from the path vs the allowed path
|
||||
auto comm = commonPrefix(path, allowedPath[offset..$]);
|
||||
|
||||
// is path is an exact match of the allowed path
|
||||
if (comm.length == path.length) {
|
||||
// the given path is contained in an allowed path
|
||||
return false;
|
||||
if (!exclude) {
|
||||
log.vdebug("Evaluation against 'sync_list' result: direct match");
|
||||
finalResult = false;
|
||||
// direct match, break and go sync
|
||||
break;
|
||||
} else {
|
||||
log.vdebug("Evaluation against 'sync_list' result: direct match but to be excluded");
|
||||
finalResult = true;
|
||||
}
|
||||
}
|
||||
if (comm.length == allowed.length && path[comm.length] == '/') {
|
||||
|
||||
// is path is a subitem of the allowed path
|
||||
if (comm.length == allowedPath[offset..$].length) {
|
||||
// the given path is a subitem of an allowed path
|
||||
return false;
|
||||
if (!exclude) {
|
||||
log.vdebug("Evaluation against 'sync_list' result: parental path match");
|
||||
finalResult = false;
|
||||
} else {
|
||||
log.vdebug("Evaluation against 'sync_list' result: parental path match but to be excluded");
|
||||
finalResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
// does the allowed path contain a wildcard? (*)
|
||||
if (canFind(allowedPath[offset..$], wildcard)) {
|
||||
// allowed path contains a wildcard
|
||||
// manually replace '*' for '.*' to be compatible with regex
|
||||
string regexCompatiblePath = replace(allowedPath[offset..$], "*", ".*");
|
||||
auto allowedMask = regex(regexCompatiblePath);
|
||||
if (matchAll(path, allowedMask)) {
|
||||
// regex wildcard evaluation matches
|
||||
if (!exclude) {
|
||||
log.vdebug("Evaluation against 'sync_list' result: wildcard pattern match");
|
||||
finalResult = false;
|
||||
} else {
|
||||
log.vdebug("Evaluation against 'sync_list' result: wildcard pattern match but to be excluded");
|
||||
finalResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
// results
|
||||
if (finalResult) {
|
||||
log.vdebug("Evaluation against 'sync_list' final result: EXCLUDED");
|
||||
} else {
|
||||
log.vdebug("Evaluation against 'sync_list' final result: included for sync");
|
||||
}
|
||||
return finalResult;
|
||||
}
|
||||
|
||||
// test if the given path is matched by the regex expression.
|
||||
|
|
686
src/sync.d
686
src/sync.d
File diff suppressed because it is too large
Load diff
|
@ -195,7 +195,6 @@ bool isValidName(string path)
|
|||
matched = m.empty;
|
||||
|
||||
// Additional explicit validation checks
|
||||
if (itemName == "Icon") {matched = false;}
|
||||
if (itemName == ".lock") {matched = false;}
|
||||
if (itemName == "desktop.ini") {matched = false;}
|
||||
// _vti_ cannot appear anywhere in a file or folder name
|
||||
|
|
Loading…
Reference in a new issue