view release on metacpan or search on metacpan
Revision history for dropbox-api
2.13 2017-05-31T11:33:47Z
- Update module version
2.12 2017-02-07T09:23:46Z
- fix typo
- use upload_session
2.11 2017-01-01T18:58:11Z
- parse_datetime is %Y-%m-%dT%TZ
- format_datetime is %Y-%m-%dT%T
2.10 2017-01-01T15:58:01Z
- Add Z for strformat
2.09 2016-07-18T10:12:03Z
- Fix bug `sync dropbox: ~/Dropbox`
1.03 Aug 14, 2012
- set modification time.
- support windows homepath.
1.02 Jan 10, 2012
- added Exception handling
1.01 Apr 5, 2012
- added sub command uid (sylvainfilteau)
- added upload-to-dropbox command (sylvainfilteau)
Build.PL
Changes
LICENSE
META.json
README.md
cpanfile
lib/App/dropboxapi.pm
minil.toml
script/dropbox-api
script/upload-to-dropbox
t/happy_cpantesters.t
META.yml
MANIFEST
Available commands:
setup get access_key and access_secret
ls list directory contents
find walk a file hierarchy
du disk usage statistics
cp copy file or directory
mv move file or directory
mkdir make directory (Create intermediate directories as required)
rm remove file or directory (Attempt to remove the file hierarchy rooted in each file argument)
put upload file
get download file
sync sync directory (local => dropbox or dropbox => local)
Common Options
-e enable env_proxy ( HTTP_PROXY, NO_PROXY )
-D enable debug
-v verbose
-s sandbox mode, but this option has been removed.
See 'dropbox-api help <command>' for more information on a specific command.
download /private/tmp/product/icon-32.png
download /private/tmp/product/icon-128.png
```
### sync to dropbox
dropbox-api sync <source\_dir> dropbox:<target\_dir> \[options\]
```
> dropbox-api sync /tmp/product dropbox:/work/src
upload background.html /work/src/background.html
upload external.png /work/src/external.png
upload icon-128.png /work/src/icon-128.png
```
### delete option ( -d )
```
> dropbox-api sync dropbox:/product/google-tasks-checker-plus/src /tmp/product -d
download /private/tmp/product/external.png
download /private/tmp/product/icon-32.png
download /private/tmp/product/icon-128.png
remove background.html.tmp
dropbox-api get dropbox:<dropbox\_file> <file>
### Example
```
dropbox-api get dropbox:/Public/foo.txt /tmp/foo.txt
```
## put
upload file to dropbox.
- alias
up, upload
- syntax
dropbox-api put <file> dropbox:<dropbox\_dir>
### Example
```
dropbox-api put /tmp/foo.txt dropbox:/Public/
```
lib/App/dropboxapi.pm view on Meta::CPAN
Available commands:
setup get access_key and access_secret
ls list directory contents
find walk a file hierarchy
du disk usage statistics
cp copy file or directory
mv move file or directory
mkdir make directory (Create intermediate directories as required)
rm remove file or directory (Attempt to remove the file hierarchy rooted in each file argument)
put upload file
get download file
sync sync directory (local => dropbox or dropbox => local)
Common Options
-e enable env_proxy ( HTTP_PROXY, NO_PROXY )
-D enable debug
-v verbose
-s sandbox mode, but this option has been removed.
See 'dropbox-api help <command>' for more information on a specific command.
lib/App/dropboxapi.pm view on Meta::CPAN
> dropbox-api sync dropbox:/product/google-tasks-checker-plus/src /tmp/product
download /private/tmp/product/external.png
download /private/tmp/product/icon-32.png
download /private/tmp/product/icon-128.png
=head3 sync to dropbox
dropbox-api sync <source_dir> dropbox:<target_dir> [options]
> dropbox-api sync /tmp/product dropbox:/work/src
upload background.html /work/src/background.html
upload external.png /work/src/external.png
upload icon-128.png /work/src/icon-128.png
=head3 delete option ( -d )
> dropbox-api sync dropbox:/product/google-tasks-checker-plus/src /tmp/product -d
download /private/tmp/product/external.png
download /private/tmp/product/icon-32.png
download /private/tmp/product/icon-128.png
remove background.html.tmp
=head3 dry run option ( -n )
lib/App/dropboxapi.pm view on Meta::CPAN
dropbox-api get dropbox:<dropbox_file> <file>
=back
=head3 Example
dropbox-api get dropbox:/Public/foo.txt /tmp/foo.txt
=head2 put
upload file to dropbox.
=over 4
=item alias
up, upload
=item syntax
dropbox-api put <file> dropbox:<dropbox_dir>
=back
=head3 Example
dropbox-api put /tmp/foo.txt dropbox:/Public/
script/dropbox-api view on Meta::CPAN
} elsif ($command eq 'du') {
&du(@args);
} elsif ($command eq 'copy' or $command eq 'cp') {
©(@args);
} elsif ($command eq 'move' or $command eq 'mv') {
&move(@args);
} elsif ($command eq 'mkdir' or $command eq 'mkpath') {
&mkdir(@args);
} elsif ($command eq 'delete' or $command eq 'rm' or $command eq 'rmtree') {
&delete(@args);
} elsif ($command eq 'upload' or $command eq 'up' or $command eq 'put') {
&upload(@args);
} elsif ($command eq 'download' or $command eq 'dl' or $command eq 'get') {
&download(@args);
} elsif ($command eq 'sync') {
&sync(@args);
} elsif ($command eq 'help' or (not length $command)) {
&help(@args);
} else {
die "unknown command $command";
}
script/dropbox-api view on Meta::CPAN
Name
dropbox-api-rm - remove file or directory (Attempt to remove the file hierarchy rooted in each file argument)
SYNOPSIS
dropbox-api rm <file_or_directory>
Example
dropbox-api rm /Public/work_bak/hoge.tmp
dropbox-api rm /Public/work_bak
};
} elsif ($command eq 'upload' or $command eq 'up' or $command eq 'put') {
$help = q{
Name
dropbox-api-put - upload file
SYNOPSIS
dropbox-api put <file> dropbox:<dropbox_file>
Example
dropbox-api put README.md dropbox:/Public/product/dropbox-api/
};
} elsif ($command eq 'download' or $command eq 'dl' or $command eq 'get') {
$help = q{
Name
script/dropbox-api view on Meta::CPAN
Available commands:
setup get access_key and access_secret
ls list directory contents
find walk a file hierarchy
du disk usage statistics
cp copy file or directory
mv move file or directory
mkdir make directory (Create intermediate directories as required)
rm remove file or directory (Attempt to remove the file hierarchy rooted in each file argument)
put upload file
get download file
sync sync directory (local => dropbox or dropbox => local)
Common Options
-e enable env_proxy ( HTTP_PROXY, NO_PROXY )
-D enable debug
-v verbose
See 'dropbox-api help <command>' for more information on a specific command.
};
script/dropbox-api view on Meta::CPAN
my $res = $box->create_folder(decode('locale_fs', slash($dir))) or die $box->error;
print pretty($res) if $verbose;
}
sub delete {
my ($file_or_dir) = @_;
my $res = $box->delete(decode('locale_fs', slash($file_or_dir))) or die $box->error;
print pretty($res) if $verbose;
}
sub upload {
my ($file, $path) = @_;
$path =~ s|^dropbox:/|/|
or die "Usage: \n dropbox-api upload /tmp/local.txt dropbox:/Public/some.txt";
my $local_path = file($file);
if ((! length $path) or $path =~ m|/$|) {
$path.= basename($file);
}
my $res = &put($local_path, decode('locale_fs', $path)) or die $box->error;
if ($verbose) {
print pretty($res);
}
script/dropbox-api view on Meta::CPAN
die "missing $local_base";
}
&sync_download($content->{path_display}, dir(abs_path($local_base)));
} else {
$local_base = -d $local_base ? dir(abs_path($local_base)) : -f $local_base ? file(abs_path($local_base)) : file($local_base);
&sync_download_file($content, file($local_base));
}
}
}
# upload
elsif ($arg1 !~ qr{ \A dropbox: }xms and $arg2 =~ qr{ \A dropbox: }xms) {
my ($local_base, $remote_base) = ($arg1, $arg2);
$remote_base = decode('locale_fs', $remote_base);
$remote_base =~ s|^dropbox:||;
if (-d $local_base) {
&sync_upload($remote_base, dir(abs_path($local_base)));
} elsif (-f $local_base) {
&sync_upload_file($remote_base, file(abs_path($local_base)));
} else {
die "missing $local_base";
}
}
# invalid command
else {
die "Usage: \n dropbox-api sync dropbox:/Public/ /tmp/pub/\n" .
"or dropbox-api sync /tmp/pub/ dropbox:/Public/";
}
script/dropbox-api view on Meta::CPAN
unlink($local_path_tmp);
chomp( my $error = $box->error );
warn "download failure " . decode('locale_fs', $local_path) . " (" . $error . ")";
$exit_code = 1;
}
} else {
printf "skip %s\n", $content->{path_display} if $verbose;
}
}
sub sync_upload {
my ($remote_base, $local_base) = @_;
if ($verbose) {
print "remote_base: $remote_base\n";
print "local_base: $local_base\n";
}
print "** upload **\n" if $verbose;
my $remote_map = {};
my $remote_path_map = {};
my $entries = _find($remote_base);
for my $content (@{ $entries }) {
my $remote_path = $content->{path_display};
my $rel_path = remote_abs2rel($remote_path, $remote_base);
unless (length $rel_path) {
next;
script/dropbox-api view on Meta::CPAN
# exists file or directory
if ($content) {
delete $remote_path_map->{ $content->{path_display} };
unless (-f $local_path) {
return;
}
if (has_change($local_path, $content)) {
printf "upload %s %s\n", $rel_path, $remote_path;
unless ($dry) {
if ($content->{size} == -s $local_path) {
$box->delete("$remote_path");
}
my $local_epoch = $local_path->stat->mtime;
&put($local_path, "$remote_path", { client_modified => $strp->format_datetime(DateTime->from_epoch( epoch => $local_epoch )) . 'Z' }) or die $box->error;
}
push @makedirs, $rel_path;
} elsif ($verbose) {
printf "skip %s\n", $rel_path;
}
}
# new file
elsif (-f $local_path) {
unless ($dry) {
my $local_epoch = $local_path->stat->mtime;
&put($local_path, "$remote_path", { client_modified => $strp->format_datetime(DateTime->from_epoch( epoch => $local_epoch )) . 'Z' });
}
if (!$dry && $box->error) {
warn "upload failure $rel_path $remote_path (" . $box->error . ")";
} else {
printf "upload %s %s\n", $rel_path, $remote_path;
push @makedirs, $rel_path;
}
}
# new directory
elsif (-d $local_path) {
if (grep { $_ =~ qr{ \A\Q$rel_path }xms } @makedirs) {
return;
}
script/dropbox-api view on Meta::CPAN
unless ($dry) {
$box->delete($content_path) or die $box->error;
}
push @deletes, $content_path;
printf "delete %s\n", remote_abs2rel($content_path, $remote_base);
}
}
sub sync_upload_file {
my ($remote_base, $local_path) = @_;
if ($verbose) {
print "remote_base: $remote_base\n";
print "local_path: $local_path\n";
}
my $remote_path;
my $content;
{
script/dropbox-api view on Meta::CPAN
}
# exists file
if ($content && $content->{'.tag'} ne 'folder') {
if ($debug) {
printf "find: %s\n", $content->{path_display};
}
$remote_path = $content->{path_display};
if (has_change($local_path, $content)) {
printf "upload %s %s\n", $local_path, $remote_path;
unless ($dry) {
if ($content->{size} == -s $local_path) {
$box->delete("$remote_path");
}
my $local_epoch = $local_path->stat->mtime;
&put($local_path, "$remote_path", { client_modified => $strp->format_datetime(DateTime->from_epoch( epoch => $local_epoch )) . 'Z' }) or die $box->error;
}
} elsif ($verbose) {
printf "skip %s\n", $local_path;
}
return;
}
unless ($dry) {
my $local_epoch = $local_path->stat->mtime;
&put($local_path, "$remote_path", { client_modified => $strp->format_datetime(DateTime->from_epoch( epoch => $local_epoch )) . 'Z' });
}
printf "upload %s %s\n", $local_path, $remote_path;
}
sub has_change ($$) {
my ($local_path, $content) = @_;
my $remote_epoch = $strpz->parse_datetime($content->{client_modified})->epoch;
my $local_epoch = $local_path->stat->mtime;
my $remote_size = $content->{size};
my $local_size = $local_path->stat->size;
script/dropbox-api view on Meta::CPAN
path => "$path",
mode => 'overwrite',
%{ $optional_params || +{} },
};
my $content = $file->openr;
my $size = -s $file;
my $threshold = 10 * 1024 * 1024;
if ($size < $threshold) {
return $box->upload("$path", $content, $commit_params);
}
my $session_id;
my $offset = 0;
my $limit = 4 * 1024 * 1024;
$| = 1;
my $upload;
$upload = sub {
my $buf;
my $total = 0;
my $chunk = 1024;
my $tmp = File::Temp->new;
my $is_last;
while (my $read = read($content, $buf, $chunk)) {
$tmp->print($buf);
$total += $read;
my $remaining = $limit - $total;
if ($chunk > $remaining) {
script/dropbox-api view on Meta::CPAN
# finish or small file
if ($total < $limit) {
if ($session_id) {
my $params = {
cursor => {
session_id => $session_id,
offset => $offset,
},
commit => $commit_params,
};
return $box->upload_session_finish($tmp, $params);
} else {
return $box->upload("$path", $tmp, $commit_params);
}
}
# append
elsif ($session_id) {
my $params = {
cursor => {
session_id => $session_id,
offset => $offset,
},
};
unless ($box->upload_session_append_v2($tmp, $params)) {
# some error
return;
}
$offset += $total;
}
# start
else {
my $res = $box->upload_session_start($tmp);
if ($res && $res->{session_id}) {
$session_id = $res->{session_id};
$offset = $total;
} else {
# some error
return;
}
}
# ProgressBar
if ($verbose) {
my $rate = sprintf('%2.1d%%', $offset / $size * 100);
my $bar = '=' x int(($cols - length($rate) - 4) * $offset / $size);
my $space = ' ' x ($cols - length($rate) - length($bar) - 4);
printf "\r%s [%s>%s]", $rate, $bar, $space;
}
$upload->();
};
$upload->();
}
sub inode ($) {
my $path = shift;
my ($dev, $inode) = stat($path);
return $dev . ':' . $inode if $inode;
return $path;
}
sub remote_abs2rel ($$) {