Отслеживать изменения папки Dropbox на изменения

во-первых: я знаю pyinotify.

то, что я хочу, это служба загрузки на мой домашний сервер с помощью Dropbox.

У меня будет общая папка Dropbox на моем домашнем сервере. Каждый раз, когда кто-то другой, кто делится этой папкой, помещает что-либо в эту папку, я хочу, чтобы мой домашний сервер ждал, пока он не будет полностью загружен и переместит все файлы в другую папку, и удалит эти файлы из папки Dropbox, таким образом, экономя пространство Dropbox.

в дело в том, что я не могу просто отслеживать изменения в папке и сразу перемещать файлы, потому что если кто-то загружает большой файл, Dropbox уже начнет загрузку и, следовательно, покажет изменения в папке на моем домашнем сервере.

есть ли обходной путь? Возможно ли это с помощью API Dropbox?

сам не пробовал, но версия CLI Dropbox Кажется, есть метод "filestatus" для проверки текущего состояния файла. Доложит когда я сам попробую.

3 ответов


существует клиент 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, и вы можете потерять свою файловую систему.


вы можете запустить incrond и дождаться событий IN_CLOSE_WRITE в папке Dropbox. Тогда он будет срабатывать только после завершения передачи файлов.


вот версия Ruby, которая не ждет, пока Dropbox будет простаивать, поэтому может фактически начать перемещение файлов, пока он все еще синхронизируется. Также он игнорирует . и ... Он фактически проверяет filestatus каждого файла в данном каталоге.

тогда я бы запустил этот скрипт либо как 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