第一部分:我知道pyinotify。
我想要的是使用Dropbox向我的家庭服务器上传服务。
我的家庭服务器上有一个Dropbox的共享文件夹。每当共享该文件夹的其他人将任何东西放入该文件夹时,我希望我的家庭服务器等到它完全上传并将所有文件移动到另一个文件夹,并从Dropbox文件夹中删除这些文件,从而节省Dropbox空间。
这里的问题是,我不能只跟踪文件夹中的更改并立即移动文件,因为如果有人上传大文件,Dropbox就会开始下载,因此在我的家庭服务器上显示文件夹中的更改
有一些解决方法吗? Dropbox API能以某种方式实现吗?
我自己没有尝试过,但Dropbox CLI version似乎有'filestatus'方法来检查当前文件状态。当我自己尝试时会报告。
答案 0 :(得分: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中输错了,你可能会丢失你的文件系统。
答案 1 :(得分:1)
您可以运行incrond并让它等待Dropbox文件夹中的IN_CLOSE_WRITE事件。然后只有在文件传输完成时才会触发它。
答案 2 :(得分:1)
这是一个不等待Dropbox空闲的Ruby版本,因此实际上可以开始移动文件,同时它仍在同步。它也会忽略.
和..
。它实际上检查给定目录中每个文件的filestatus。
然后我会将此脚本作为cronjob或单独的screen运行。
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