Pull to refresh

Передаем через DropBox большие объемы данных

Коротко о главном



Как всем известно, есть такой замечательный сервис как DropBox. И всем он хорош, только в бесплатной версии для пользователя отводится “всего-ничего” от 2 до 5 гигабайт.
Посидел я, подумал, и решил обойти это ограничение, по крайней мере для некоторых нужд, а именно, для передачи больших объемов данных (превышающих доступный объем) от одного пользователя, одному или нескольким адресатам.

Решение было придумано самое простое: запихиваем требуемые файлы в многотомный архив и передаем через каталог My DropBox по кусочку.
В каких случаях можно использовать такой способ? Ну, например, если требуется передавать много всего разного на несколько компьютеров сразу, либо если нет возможности (желания) открывать прямой доступ к одному из компьютеров участвующих в передаче.

Для реализации функционала была написана программка на Python’е (2.6). Текущая версия работает только под win32.Дистрибутив сконвертированный py2exe в комплекте с readme и исходным кодом здесь — move_big_files.zip (7 мегабайт). В комплекте два исполняемых файла — move_file.exe работающий в консольном режиме и move_file_invis.exe не создающий никаких окон. Последний можно убить только из менеджера процессов, либо при перезагрузке.

Исходный код состоит из двух файлов: move_file.py (основной файл) и single_instance.py (вспомогательная библиотека).



Чуть больше подробностей



Основная задача поставленная при разработке программы: надежная и максимально автоматизированная работа, по возможности устойчивая к внешним воздействиям. Желательно, чтобы программу мог установить неподготовленный пользователь, получая ЦУ по телефону. При этом реализована только минимально-необходимая функциональность. Развитие следует…

У каждого из участников процесса устанавливается по экземпляру программы. В настройках всех
экземпляров задается подкаталог каталога My DropBox через которую происходит обмен (подкаталог должен быть расшарен между пользователями-участниками).
Обмен производится через два каталога обмена — каталог передачи (Outbox) и каталог приема (Inbox)
Как только в Outbox одного из клиентов поступают файлы, данный клиент становится передающим, а остальные- принимающими. После передачи файлы складываются в Inbox принимающих клиентов.
Допускается перезапуск клиентов в процессе передачи, при этом передача приостанавливается до повторного подключения клиента
Можно работать на одном компьютере с несколькими обменными папками, запустив несколько экземпляров программы с разными настройками.

Особенности реализации программы


  • Для архивации данных использовался стандартный модуль ZipFile, чтобы не привязываться к архиваторам установленным на компьютере (для упрощения установки неподготовленным пользователем). К сожалению, модуль не поддерживает многотомные архивы, поэтому пришлось создавать один большой архив и разбивать его на куски.
    Это приводит к двум ограничениям: если используется файловая система FAT32, то невозможно передавать объемы больше 4 гигабайт за раз и свободное место на диске должно быть как-минимум в два раза больше объема передаваемых данных;
  • Как уже говорилось выше, пока работаем только под Win32;
  • Если в процессе передачи кто-нибудь из клиентов-получателей «зависает» (например, если был выключен компьютер и больше не включался), то передача тоже зависнет, в ожидании получателя. Спасет только ручное удаление флага получения данных (см. ниже) зависшего клиента и перезапуск передающей программы;
  • Настройки программы хранятся в файле config.conf в одной папке с программой. Там задаются основные таймауты, названия каталогов и т.д.


Как это работает (много букв!)



Примеров кода приводить не буду в целях экономии места,
подробности можно посмотреть в исходных файлах.

На первый взгляд принцип работы программы очень прост:
На компьютере создаются две папки: Inbox и Outbox. В Outbox кидаем файлы на передачу, в Inbox поступают входящие файлы. Вся обработка файлов идет в промежуточном каталоге Temp.
Обмен файлами идет через общий каталог в каталоге My DropBox. Управляющая информация между клиентами передается флагами. В каталоге передачи создаются 4 каталога для флаг-файлов. Каждая программа может создавать в этих каталогах флаги с именем = id хоста в DropBox (уникальное значение). Всего четыре флага: передачи, приема, завершения приема файла и флаг обработки принятых файлов (склейка томов, распаковка данных).

Режимы работы программы


Программа работает в трех основных режимах:

  • Ожидание. Спим и приглядываем за папками. Если в Outbox поступают файлы, начинаем передачу, если появился чужой флаг передачи – начинаем прием;
  • Передача. Ставим флаг передачи, пакуем все файлы в Outbox в один многотомный архив (или делаем один архив и бьем на кусочки) и передаем по кусочку принимающим сторонам.
    Для этого:

    1. Получаем список получателей (по флагам приема), перед получением списка нужно выдержать паузу, чтобы получатели успели подключится, освободились от обработки предыдущих пришедших данных (флаг обработки) и т.д.;
    2. Кидаем кусочек в папку обмена;
    3. Ждем, пока все получатели не выставят флаги окончания приема файла;
    4. убиваем флаги приема файла и кусочек в папке обмена и возвращаемся к 2, пока не закончатся файлы
      как файлы закончатся, убиваем флаг передачи и переходим к ожиданию.


  • Прием:

    1. Ставим флаг приема;
    2. Ожидаем поступления кусочка;
    3. По приходе очередного кусочка копируем во временную папку и ставим флажок приема файла;
    4. По приходе очередного кусочка копируем во временную папку и ставим флажок приема файла;
    5. Как только флажок удален передающим, переходим к п.2 и так до удаления флага передачи;
    6. Как только флаг передачи удаляется, удаляем флаг приема, ставим флаг обработки и распаковываем пришедшие файлы в inbox;
    7. Удаляем флаг обработки и возвращаемся в режим ожидания.



Все просто и достаточно скучно, но как всегда в процессе реализации возникло несколько задач, которые показались мне интересными. Остановлюсь на них чуть подробнее:

  • Нужно чтобы для конкретной обменной папки можно было запустить только один экземпляр программы.
    Для решения этой задачи используем мьютексы (модуль SingleInstance). Рецепт взят здесь
  • Нужно получать конфигурационные параметры DropBox – в частности расположение каталога My DropBox и id хоста.
    Решение было найдено в аддонах к DropBox – здесь (подробнее см. метод _get_dropbox_info класса MoveFiles в файле move_file.py );
  • Есть некоторая вероятность что процесс передачи одновременно начнут несколько клиентов, необходимо разрешать такие коллизии.
    Ставим флаг передачи и ждем отведенный тайм-аут, затем проверяем, есть ли другие флаги передачи. Если флаги есть, передачу продолжает обладатель самого «толстого» id (метод _mark_sending );
  • Предполагается передача больших объемов данных, в т.ч. больших файлов, т.е. при создании архива на отправку нужно проверять, закончилось ли копирование конкретного файла в каталог обмена.
    Копируемые файлы блокируются в каталоге-приемнике до окончания процесса передачи, поэтому по очереди проверяем все файлы в каталоге-приемнике и готовим к передаче и удаляем все незаблокированные. Файлы которые докопируются позже будут переданы следующей итерацией процесса передачи (метод _prepare_to_send );
  • Требуется реализовать подключение к каналу клиентов-получателей только в начале раздачи, поскольку если получатель подключится на раздаче второго и более куска, то он не сможет собрать итоговый файл.
    Для этого перед началом передачи дожидаемся пока клиенты не закончат обработку предыдущей передачи ждем отведенный интервал времени с момента постановки флага передачи, после чего дожидаемся пока подключится хоть кто-нибудь и ставим флагу передачи расширение .busy.
    Если у флага передачи расширение .busy, никто подключаться не будет… (метод _sending_process ).


Идеи для развития



  • Кроссплатформенность;
  • Использование многотомных архивов;
  • Интеллектуальное разбиение файлов, в зависимости от их размера и формата:
    маленькие собираем в кучу, большие разбиваем на кусочки и т.д.;
  • Иконка в трее и (возможно) GUI, дроплет;
  • многофайловая передача для ускорения процесса;
  • Многозадачность (многопапочность), т.е. возможность одновременной работы одной программы с несколькими обменными папками.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.