Как загрузить файлы на облако Mail.ru используя Python и WebDAV

Как загрузить файлы на облако Mail.ru используя Python и WebDAV

Автор: Рамис | Статьи 28 августа 2022

В этой небольшой статье Вы узнаете как загрузить файлы на облако от Mail.ru, используя Python и протокол WebDAV.

Настройки приложения

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

Настройки WebDAV

Подключение к WebDAV

Для работы с протоколом есть готовая библиотека webdavclient3, установите командой:

pip install webdavclient3

Укажите свои данные (webdav_login: почтовый адрес, и webdav_password: ранее сгенерированный пароль) и попробуйте подключиться.

from webdav3.client import Client

data = {
 'webdav_hostname': "https://webdav.cloud.mail.ru",
 'webdav_login':    "MAIL@mail.ru",
 'webdav_password': "PASSWORD"
}
client = Client(data)

my_files = client.list()
print(my_files)

Данный код выведет список всех файлов хранящихся в главном каталоге облака. В моем случаем результат:

['Горное озеро.jpg', 'Долина реки.jpg']

Если подключение прошло успешно, можете переходить к следующему этапу, и рассмотреть несколько самых интересных методов.

Методы WebDAV Сlient

Создать папку:

client.mkdir("folder")
client.mkdir("folder/files")

Удалить:

client.clean("folder")
Скачать с облака:

client.download_sync(remote_path="Долина реки.jpg", local_path="Долина реки.jpg")
client.download_sync(remote_path="Горное озеро.jpg", local_path=r"C:\Users\username\Downloads\Горное озеро.jpg")
Загрузить в облако:

client.upload_sync(remote_path="/my.txt", local_path="my.txt")
client.upload_sync(remote_path="folder/", local_path=r"C:\Users\username\Downloads\test")

Пример

Для примера разработаем небольшую программу для загрузки файлов в облако.

import sys
from datetime import datetime
from webdav3.client import Client

data = {
 'webdav_hostname': "https://webdav.cloud.mail.ru",
 'webdav_login':    "MAIL@mail.ru",
 'webdav_password': "PASSWORD"
}
client = Client(data)

if not client.check('backup'):
    client.mkdir('backup')

date = datetime.now().strftime("%d%m%Y-%H%M%S")
new_folder = sys.argv[1].split('\\')[-2]
client.upload_sync(remote_path=f"backup/{new_folder}_{date}", local_path=sys.argv[1])
Запустим и укажем каталог для загрузки.

python main.py 'C:\Documents\Project\'

Результат:

загрузка файлов в облако

Дополнительно

Дополнительную информацию можете найти в документации webdavclient3.

Комментарии

AlexSoy
@AlexSoy
09 сентября 2022

Спасибо, то что искал. Подскажите как сделать файл публичным?

Ответить
Рамис
@ramas
12 сентября 2022

@AlexSoy, Пожалуйста. Сразу не обратил внимания, в webdavclient3 есть информация о методах publish and unpublish, но они не реализованы в коде. Попробуйте воспользоваться другой библиотекой https://github.com/CloudPolis/webdav-client-python (webdavclient3 основан на нем).

Ответить
max_rbb
@max_rbb
11 ноября 2022

Привет!

Кажется, что-то поломалось, потому что при попытке вызвать upload_sync возвращает исключение MethodNotSupported.

"Method 'upload' not supported for https://webdav.cloud.mail.ru"

@ramas, подскажи, пожалуйста, ранее таких ситуаций не возникало? Быть может я не учел какой-то момент

Ответить
Рамис
@ramas
11 ноября 2022

@max_rbb, Здравствуйте. Перепроверил, файлы загрузились, все работает.

test>python -m venv env
test>env\scripts\activate
(env) test>python -V
Python 3.9.9
(env) test>pip install webdavclient3
(env) test>python main.py "C:\test"

Ответить
max_rbb
@max_rbb
11 ноября 2022

@ramas, Благодарю за ответ!

Проблема решилась более внимательным прочтением статьи.

client.upload_sync(remote_path=f"users_downloads/{username}_{date}/{filename}.mp4", local_path=f"{filename}")

Дополнил remote_path до полного пути добавлением /{filename}.mp4 и все заработало :)

Ответить
Рамис
@ramas
11 ноября 2022

@max_rbb, Пожалуйста :), обращайтесь.

Ответить
max_rbb
@max_rbb
11 ноября 2022

@ramas, А вот насчет метода publish все еще остались надежды на успех)

В Справке у Я.Диска есть четкая формулировка: "Признак публичности устанавливается и редактируется с помощью метода PROPPATCH. Чтобы опубликовать файл или папку, свойству public_url в пространстве имен urn:yandex:disk:meta следует присвоить любое непустое значение."

Такую же или похожую формулировку до сих пор не удается найти для Мейла.

В настоящий момент создал в библиотеке метод: def publish(self, remote_path): d = {

  }
  urn = Urn(remote_path)
  data = WebDavXmlUtils.create_set_property_batch_request_content(options=d)
  response = self.execute_request(action='publish', path=urn.quote(), data=data)

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

Ответить
max_rbb
@max_rbb
11 ноября 2022

И беда в том, что у одной и другой библиотеки webdavclient одинаковая настройка

meta_xmlns = { 'https://webdav.yandex.ru': "urn:yandex:disk:meta", }

Для Я.Диска) Насчет webdav.cloud.mail.ru можно догадаться, а вот urn нигде не нашел

Ответить
max_rbb
@max_rbb
11 ноября 2022

В библиотеке увидел комментарий:

"namespace: (optional) the namespace for XML property which will be set, name: the name of property which will be set, value: (optional) the value of property which will be set. Defaults is empty string."

и попробовал в таком виде, без неймспейса:

def publish(self, remote_path):
  myList = [
    {
      'name': 'public_url',
      'value': 'true'
    }
  ]

  urn = Urn(remote_path)
  data = WebDavXmlUtils.create_set_property_batch_request_content(options=myList)
  response = self.execute_request(action='publish', path=urn.quote(), data=data)

Получил ответ: failed with code 501 and message: b'Not implemented'

Ответить
Markdown
Войти