10

首先:我知道pyinotify

我想要的是使用 Dropbox 将上传服务上传到我的家庭服务器。

我将在我的家庭服务器上有一个 Dropbox 的共享文件夹。每次共享该文件夹的其他人将任何内容放入该文件夹时,我希望我的家庭服务器等到它完全上传并将所有文件移动到另一个文件夹,然后从 Dropbox 文件夹中删除这些文件,从而保存 Dropbox空间。

这里的问题是,我不能只跟踪文件夹中的更改并立即移动文件,因为如果有人上传了一个大文件,Dropbox 将已经开始下载,因此会在我的家庭服务器上显示文件夹中的更改。

有一些解决方法吗?Dropbox API 有可能吗?

自己没有尝试过,但Dropbox CLI 版本似乎有一个“文件状态”方法来检查当前文件状态。当我自己尝试过时会报告。

4

3 回答 3

2

正如您在问题中提到的,有一个 Python Dropbox CLI 客户端。它在不主动处理文件时返回“空闲...”。我能想象的实现你想要的最简单的机制是一个 while 循环,它检查输出dropbox.py filestatus /home/directory/to/watch并执行内容的 scp,然后如果成功则删除内容。然后睡了五分钟左右。

就像是:

import time
from subprocess import check_call, check_output
DIR = "/directory/to/watch/"
REMOTE_DIR = "user@my_server.com:/folder"

While True:
    if check_output(["dropbox.py", "status", DIR]) == "\nIdle...":
        if check_call(["scp", "-r", DIR + "*", REMOTE_DIR]):
            check_call(["rm", "-rf", DIR + "*"])
    time.sleep(360)

当然,在测试这样的东西时我会非常小心,在第二个 check_call 中放错东西,你可能会丢失你的文件系统。

于 2012-09-11T20:52:39.953 回答
1

您可以运行 incrond 并让它等待 Dropbox 文件夹中的 IN_CLOSE_WRITE 事件。然后它只会在文件传输完成时触发。

于 2012-09-11T22:02:49.147 回答
1

这是一个 Ruby 版本,它不等待 Dropbox 空闲,因此实际上可以开始移动文件,同时它仍在同步。它也忽略.and ..。它实际上检查给定目录中每个文件的文件状态。

然后我会将此脚本作为 cronjob 或在单独的屏幕中运行。

directory = "path/to/dir"
destination = "location/to/move/to"

Dir.foreach(directory) do |item|
    next if item == '.' or item == '..'
    fileStatus = `~/bin/dropbox.py filestatus #{directory + "/" + item}`
    puts "processing " + item
    if (fileStatus.include? "up to date")
        puts item + " is up to date, starting to move file now."
        # cp command here. Something along this line: `cp #{directory + "/" + item + destination}`
        # rm command here. Probably you want to confirm that all copied files are correct by comparing md5 or something similar.
    else
        puts item + " is not up to date, moving on to next file."
    end
end

这是完整的脚本,我最终得到:

# runs in Ruby 1.8.x (ftools)

require 'ftools'

directory = "path/to/dir"
destination = "location/to/move/to"

Dir.glob(directory+"/**/*") do |item|
    next if item == '.' or item == '..'
    fileStatus = `~/bin/dropbox.py filestatus #{item}`
    puts "processing " + item
    puts "filestatus: " + fileStatus
    if (fileStatus.include? "up to date")
        puts item.split('/',2)[1] + " is up to date, starting to move file now."
        `cp -r #{item + " " + destination + "/" + item.split('/',2)[1]}`

        # remove file in Dropbox folder, if current item is not a directory and 
        # copied file is identical.
        if (!File.directory?(item) && File.cmp(item, destination + "/" + item.split('/',2)[1]).to_s)
            puts "remove " + item
            `rm -rf #{item}`
        end
    else
        puts item + " is not up to date, moving to next file."
    end
end
于 2012-09-12T11:15:43.520 回答