Форум русскоязычного сообщества Ubuntu


Автор Тема: Клиент синхронизации с Yandex.disk (Python3, OpenSource)  (Прочитано 14962 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Sly_tom_cat

  • Автор темы
  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 11788
  • Xubuntu 18.04 (64bit)
    • Просмотр профиля
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #30 : 19 Октябрь 2016, 12:25:38 »
Вот какая вышла незадача с полной синхронизацией:

Есть ситуация № 1: и на локальном диске и в облаке есть файл, но хеши у облачной версии и локальной не бьются.
Что это значит?
Казалось бы какой файл имеет самую свежую дату обновления тот и должен перезаписать более старый. Но! мы же не знаем как оно было на самом деле. Допустим локальный файл более свежий. Но это вовсе не значит, что в облачный файл не вносилось изменений, может мы их просто не получил (клиент был не активен или просто комп выключен был когда файл менялся в облаке).
А если с момента последней синхронизации (после которой облачный и локальный файлы были одинаковыми) изменяли оба файла то это конфликт. Его надо разруливать руками. Но отловить этот конфликт можно только имея дополнительную историческую информацию, нужно хотя бы дату изменения во время последнего синхронного состояния.

Есть и другая ситуация: №2: исходно у нас были синхронизированные копии файлов, а потом локальный файл был удален. При полной синхронизации мы получим просто отсутствие локального файла. Это можно понять как то, что облачный надо загрузить (может он там новый появился). В локальном каталоге никаких следов того, что файл был и был удален - не осталось.

Т.е. нужен локальное хранилище, где будут хранится информация о файлах/каталогах на момент последней синхронизации (т.е. после последнего download или upload файла). Каталоги тоже нужно хранить чтобы отловить момент, когда локальный каталог был удален (возможно вместе с файлами).
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: http://help.ubuntu.ru/wiki/uefiboot

Оффлайн Sly_tom_cat

  • Автор темы
  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 11788
  • Xubuntu 18.04 (64bit)
    • Просмотр профиля
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #31 : 20 Октябрь 2016, 10:49:10 »
По ходу дела кривоватую (т.к. без исторических данных) синхронизацию с диска в облако и полную я вполне отладил, последним штрихом было заставить корректно отрабатывать каталоги исключения в процессе полной синхронизации. iNotify вотчеру можно хвост накрутить и он отдельные каталоги не будет мониторить, но в полной синхронизации я обхожу весь каталог, пришлось туда добавить дополнительные условия чтобы обходить стороной те каталоги которые добавлены в исключения.

Размышления по поводу исторических данных натолкнули меня еще на одно решение которое я уже видел у других но подзабыл что так надо делать. Дело в том что скачивание и заливка в облако - продолжительные и не атомарные действия. Может пол файла пройти, а потом сеть пропала и амба - старый файл (поверх которого закачивается) уже стерт, а новый закачан не полностью.  :-\
Решается это тем что скачивать надо не по месту, а во временный файл, и вот только после успешного получения всего файла он перезаписывается поверх старого.
Сделать такое не трудно, а нужно оно не только для целостности файлов, но и для того чтобы запоминать в истории синхронизации данные только о тех файлах, которые уже реально положены на диск, а не тех, которые только начали скачиваться и еще не известно - получится или нет.
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: http://help.ubuntu.ru/wiki/uefiboot

Punko

  • Гость
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #32 : 20 Октябрь 2016, 10:52:58 »
Sly_tom_cat, ну да, что-то типа менеджера очередей - действие выполнено - он вернул успешный ответ, если ответа нет по прошествии таймаута или ответ негативный, то задача с очереди не удачляется, а идёт попытка повторить задание.

Ну это на словах всё легко, и когда оно уже готово - пользоваться удобно :)

Как оно в плане реализации - не знаю.

Оффлайн Sly_tom_cat

  • Автор темы
  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 11788
  • Xubuntu 18.04 (64bit)
    • Просмотр профиля
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #33 : 20 Октябрь 2016, 11:16:49 »
Очередь у меня уже и так есть - ее многопоточный PoolExecutor перелопачивает.
В нем есть встроенный механизм повесть на задачу колбэк функцию, которую экзекутор запустит по окончанию (не важно какому) исполнения задачи. И я уже это активно использую т.к. мне нужно отлавливать ошибки, я же по ним запускаю полную синхронизацию. Да и состояние экзекутора я в этом коллбэке проверяю, чтобы общий статус клиента изменить с busy на idle когда он все перелопатит.
Но дело в том, что коллбэк должен только типичные ситуации обрабатывать.
Мухлеж с загрузкой с облака через временный файл удобнее сделать через переопределение метода класса Cloud (обертки вокруг REST API). Именно эти методы и отдаются в очередь екзэкутору, и я специально делал им типовые ответы для того, чтобы однотипно их обрабатывать одной коллбэк функцией. Ведь там нужно и во входных параметрах помудрить (указать как получатель временный файл) и на выходе помухлевать с копированием из темпа, но с точки зрения общего потока задач ошибки на любом этапе надо обрабатывать одинаково, т.к. именно в этом случае весь этот мухлеж с загрузкой через временный файл можно сделать атомарной операцией, подобной всем остальным. А повтор отдельных задач я не делаю - у меня на любые ошибки при общении с облаком есть универсальный рецепт: полная синхронизация. 8)

Вобщем как сделать я уже понял. Буду пилить.
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: http://help.ubuntu.ru/wiki/uefiboot

Оффлайн Sly_tom_cat

  • Автор темы
  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 11788
  • Xubuntu 18.04 (64bit)
    • Просмотр профиля
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #34 : 20 Октябрь 2016, 19:48:10 »
Допилил...

По ходу дела окончательно запутался с путями - они там были то относительные (относительно синхронизируемой папки) то абсолютные (от корня).... замучило все. Завел себе правило - все рабочие пути только абсолютные относительные только в прослойке с диском (там они нужны т.к. там на диске пути от корня диска, который на локальной машине соответствует синхронизируемому каталогу).

А так стало все логично - в самом классе Disk - все пути абсолютные, кроме того места где просто для информации вытаскивается список последних 10 синхронизированных файлов, но это - чисто для пользователя информация, она никак в работе не используются.

Как все сразу упростилось - не передать.

Попутно отлаживаю хранение исторических данных для разрешения неоднозначностей при полной синхронизации (те два кейса что выше описаны). Уже вроде работает, но данные нужно еще как-то обновлять и следить что бы они не зарастали мусором.

Пока эти данные (путь и время последнего изменения для файлов или просто True для каталогов) хранятся просто как конфигурационный файл - в JSON формате на диске в скрытой папке синхронизируемого каталога. И создаю я их походя в процессе полной синхронизации, но уже там есть места где я явно не очищаю данные после того как они перестают быть нужными.

Да всякое может быть - надо отдельно предусмотреть обновление этих данных после успешно законченной синхронизации.
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: http://help.ubuntu.ru/wiki/uefiboot

Оффлайн Sly_tom_cat

  • Автор темы
  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 11788
  • Xubuntu 18.04 (64bit)
    • Просмотр профиля
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #35 : 22 Октябрь 2016, 01:50:07 »
Нашел еще один глюк: Когда в синхронизируемый каталог переносится каталог с вложенными каталогами/файлами, то pyinotify хотя и начинает вотчить все вложенные каталоги, но вот событий на помещение всего содержимого перенесенного каталога не формирует (ну собственно же там ничего и не создается и не переносится).

Глюк только при переносе, при копировании - все отлавливается по событиям на ура (причем большие файлы еще и кучу событий об обновлении пришлют).

Первой мыслью было взвести некий флаг когда перенесен непустой каталог и по флагу запускать полную синхронизацию.....

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


Но задача рекурсивной заливки при все свой простоте довольно продолжительная (последовательное создание каталогов для избежания ситуации с гонками "кто быстрее создастся") поэтому я оформил ее как задачу, которую можно отдать PoolExecutor-у.

Собственно и процедуру полной синхронизацию я тоже переделал на выполнение через PoolExecutor, а то изначально у меня эта процедура на старте исполнялась основным потоком, а в работе потоком, основная роль, которого - отслеживание изменений статуса клиента и реакции на эти изменения.

Теперь у меня все продолжительные задачи (простые операции с облаком, полная синхронизация и рекурсивная заливка в облако) выполняются через PoolExecutor, что с одной стороны позволяет более оперативно и правильно работать потоку который занимается статусами и реакциями, и с другой стороны полная синхронизация и массовая заливка точно также отрабатываются по статусу как переход в busy на время исполнения, и возврат в idle после окончания синхронизации/заливки и всех порожденных ими задач. Это позволило убрать скачки статуса из busy в idle и обратно... да и такое изменения статуса более адекватно действительности (ведь клиент активно работает не только когда непосредственно к облаку обращается).
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: http://help.ubuntu.ru/wiki/uefiboot

Оффлайн Sly_tom_cat

  • Автор темы
  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 11788
  • Xubuntu 18.04 (64bit)
    • Просмотр профиля
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #36 : 22 Октябрь 2016, 01:58:39 »
Клиент в целом уже вполне функциональный (не хватает только заливки файлов по их появлению в облаке - они только при полной синхронизации вытягиваются). Для последнего шага нужно глубоко копать вопрос организации xmpp клиента с нестандартной авторизацией.... :o :-\

Первый мой взгляд на эту тему создал у меня удручающее впечатление:
В репах нашел только одну либу для работы по xmpp и это огромная либа в которой все довольно сильно наворочено... :idiot2: как туда впихнуть нестандартную авторизацию яндекса - просто совершенно не понятно.... По идее, то что нужно для приема событий от яндекса - там довольно простой набор команд, которые можно тупо копипастить из мануала и слать через сокет. Вот только ssl поднять - тоже как-то не тривиально (на сколько я понял при поверхностном изучении вопроса)...
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: http://help.ubuntu.ru/wiki/uefiboot

Punko

  • Гость
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #37 : 23 Октябрь 2016, 08:27:16 »
Sly_tom_cat, отлично, что почти допилил.

Сегодня потестирую новую версию, ближе к вечеру.

А что нестандартного в яндекс авторизации?

Оффлайн Sly_tom_cat

  • Автор темы
  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 11788
  • Xubuntu 18.04 (64bit)
    • Просмотр профиля
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #38 : 23 Октябрь 2016, 19:46:17 »
А что нестандартного в яндекс авторизации?
Тут пункт №5:
<auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" mechanism="X-YANDEX-OAUTH">dGVzdABjNDE4MWE3YzJjZjQ1MjE5NjRhNzJmZjU3YTM0YTA3</auth>
mechanism="X-YANDEX-OAUTH" - Как такое в купе с токеном передать в библиотеку когда там везде фигурируют логин с паролем... Это и смущает...

Я вообще с xmpp никогда дела не имел - копаю с нуля. Расходнях во всех мануалах к либам начинается с первой строки - везде сначала создает объект клиента с логином и паролем, а потом коннектят его. У яндекса сначала коннекшн, потом авторизация.
Т.е. копать мне еще и копать эту тему....

Но самое удивительное - я посмотрел какие авторизации требует стандартный их клиент - и слегка был удивлен: мало того что они по webdav файлами обмениваются (ну это то не так удивительно), так там еще нет подписки на услугу уведомлений (xmpp), зато есть подписка DataSync API - это типа облачная хранилка данных (нереляционная база данных).  :idiot2: нафига... А главное как они события с диска получают - непонятно.... они конечно по активности судя примерно раз в 20 секунд с сервером связываются (или сервер с ними, пингует например) но сокет то законекченный висит....
Вобщем странно как-то сделано... но реверсинжинирингом я заниматься не стану.... 
« Последнее редактирование: 23 Октябрь 2016, 19:47:52 от Sly_tom_cat »
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: http://help.ubuntu.ru/wiki/uefiboot

Оффлайн peregrine

  • FSM
  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 7070
  • Gentoo x64 Ubuntu 16.04.1 x64
    • Просмотр профиля
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #39 : 18 Ноябрь 2016, 23:17:33 »
Я не знаю как сейчас, но раньше я хотел сделать нечто подобное, но была проблема с токенами для яндекса, чтобы их не увели надо было делать программу с закрытым кодом. А как сейчас с этим обстоят дела?

Punko

  • Гость
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #40 : 19 Ноябрь 2016, 00:20:58 »
peregrine, выложить токен в открытый доступ решили.
Я пытаюсь пилить клиент для фоток, но времени не хватает жутко, как на работе разгребу, так продолжу. У Sly_tom_cat дела веселее идут.

Оффлайн peregrine

  • FSM
  • СуперМодератор
  • Старожил
  • *
  • Сообщений: 7070
  • Gentoo x64 Ubuntu 16.04.1 x64
    • Просмотр профиля
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #41 : 19 Ноябрь 2016, 01:30:29 »
Punko, а Яндекс не будет токен банить?

Punko

  • Гость
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #42 : 19 Ноябрь 2016, 12:12:43 »
peregrine, просто так - не должен, если токен будет использовать еще пару программ - возможно (хотя у них вроде написано, что этот токен работает и с другими сервисами яндекса).

Оффлайн Sly_tom_cat

  • Автор темы
  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 11788
  • Xubuntu 18.04 (64bit)
    • Просмотр профиля
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #43 : 19 Ноябрь 2016, 13:16:59 »
о так - не должен, если токен будет использовать еще пару программ - возможно (хотя у них вроде написано, что этот токен работает и с другими сервисами яндекса).
Там фенечка в чем - токену даются конкретные права (запрашиваемые) и если надо что-то еще - то это новый токен.
Но токен ИМХО - не столь серьезная штука что бы его прятать.

Но так, да - проблема с открытостью токена есть... но еще большая проблема - нужно открыто держать ключ и пароль от приложения (нужны для запроса токена).

Однако открытые или закрытые коды - разница не велика (закрытые просто чуть сложнее анализировать). Нету ни одного метода надежно защитить информацию, которая нужна приложению для работы. А самое печальное - простой tcpdump все равно покажет ключи/пароли/токены т.к. в запросах они идут в открытом виде. 

Пользователь добавил сообщение 19 Ноябрь 2016, 13:51:27:
У Sly_tom_cat дела веселее идут.
Да не веселее вовсе. Я как уперся в конфликты так и остановился - уже несколько недель проект стоит.  :-\ Навалилось всякое - не до него сейчас... :-[

 
« Последнее редактирование: 19 Ноябрь 2016, 13:52:30 от Sly_tom_cat »
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: http://help.ubuntu.ru/wiki/uefiboot

Оффлайн Sly_tom_cat

  • Автор темы
  • Don't worry, be happy!
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 11788
  • Xubuntu 18.04 (64bit)
    • Просмотр профиля
Re: Клиент синхронизации с Yandex.disk (Python3, OpenSource)
« Ответ #44 : 23 Ноябрь 2016, 14:51:43 »
Почистил тему от офтопа. За продолжение буду уже как модератор наказывать.
Индикатор для Yandex-Disk: https://forum.ubuntu.ru/index.php?topic=241992
UEFI-Boot - грузимся без загрузчика: http://help.ubuntu.ru/wiki/uefiboot

 

Страница сгенерирована за 0.111 секунд. Запросов: 24.