App-dropboxapi

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

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`

Changes  view on Meta::CPAN


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)

MANIFEST  view on Meta::CPAN

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

README.md  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.

README.md  view on Meta::CPAN

download /private/tmp/product/icon-32.png
download /private/tmp/product/icon-128.png
```

### sync to dropbox

dropbox-api sync &lt;source\_dir> dropbox:&lt;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

README.md  view on Meta::CPAN

    dropbox-api get dropbox:&lt;dropbox\_file> &lt;file>

### Example

```
dropbox-api get dropbox:/Public/foo.txt /tmp/foo.txt
```

## put

upload file to dropbox.

- alias

    up, upload

- syntax

    dropbox-api put &lt;file> dropbox:&lt;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') {
    &copy(@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 ($$) {



( run in 1.202 second using v1.01-cache-2.11-cpan-b16cb0d3907 )