Статья Работа с облаком MailRu с помощью Python. Часть 01

Хранить бэкапы в бесплатных облаках, как показывает практика, занятие довольно рискованное, так как это чревато потерей всех ваших данных в один прекрасный момент. Но вот пользоваться облаками в качестве неких перевалочных пунктов, в которых можно временно и под рукой держать различные документы или прочие файлы – почему нет? Давайте сегодня напишем небольшое приложение, с помощью которого можно будет выполнять простые действия, например: копирование, скачивание, перемещение, загрузка в облаке от MailRu с помощью Python. Почему именно в нем? Об этом немного ниже.

cloud.png

Думаю, что нужно начать с небольшой предыстории. Около десяти лет назад, когда Облако от MailRu только начинало свою работу, ими был представлен аттракцион невиданной щедрости – давали хранилище объемом 1 Тб. Конечно же, грех было не воспользоваться таким щедрым предложением. Хотя, на тот момент, оно особо и не было нужно. Жаль, что у меня отсутствует коммерческая жилка. Слышал, что многие в тот момент, получали кучу этих облаков, а после, когда лавочку прикрыли, успешно торговали аккаунтами с терабайтом.

Это сейчас они стали совсем жадными и, дают всего лишь 8 бесплатных гигабайт. Хочешь больше – плати. Впрочем, тогда было не совсем понятно, что делать с этим облаком. Ну фото залить, видео. Так как внятных способов взаимодействия вроде протокола WebDEV для халявы не было, а предоставлялся он только на платных аккаунтах, в отличие от того же Яндекса. Правда появлялись экзотические способы, с помощью которых можно было подключить облако по этому протоколу, но работали они не особо стабильно. Чуть позже появилось их странное приложение «Диск O:», которое было несколько сыроватым. Потому, попользовавшись им пару дней, снес и не устанавливал больше никогда.

Но, времена меняются. И теперь, даже на бесплатных тарифах появилась возможность подключить Облако от MailRu по протоколу WebDEV. Как это сделать, подробнее можно узнать в этой . Нас же интересует тот момент, что теперь стало можно взаимодействовать с Облаком из скрипта Python. Что же, с предысторией нужно заканчивать и приступать к кодированию.

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

02.png

Я не «гуру» дизайна, потому, за внешний вид прошу, заранее, прощения. А теперь, давайте начинать.

Настоятельно рекомендую ознакомиться с , так как в ней сказано, как получить пароль для внешнего приложения. Именно с помощью вашего логина и полученного пароля у вас получиться авторизоваться в облаке по протоколу WebDEV, равно как и в приложении для отправки почты, если вы таковое будете писать. С помощью обычного логина и пароля авторизация больше не проходит.

Таким образом, первым шагом будет получение данного пароля.


Создание модуля для работы с Облаком

Для начала создадим новый файл mail_tools.py. Установим библиотеки, которые будут нужны для его работы. А именно, библиотеку webdavclient3, которая предоставляет простые методы взаимодействия с «облаками» по протоколу WebDAV и библиотеку cryptocode, с помощью которой мы будем шифровать и дешифровать логин и пароль доступа к облаку, которые будем, в свою очередь, хранить в файле setting.ini. Для их установки пишем в терминале команду:

pip install webdavclient3 cryptocode

После установки библиотек импортируем их в наш скрипт:

Python:
from pathlib import Path

from cryptocode import decrypt
from webdav3.client import Client


Создадим функцию decrypt_word(word: str, psw: str) -> str, с помощью которой будем дешифровать логин и пароль прочитанные из файла setting.ini. Как видите, библиотека лишним функционалом не перегружена от слова совсем. Передаем в функцию слово или фразу, которые нужно дешифровать и на выходе получаем дешифрованное сообщение. Это, если пароль правильный.

Python:
def decrypt_word(word: str, psw: str) -> str:
    """
    Дешифрование слова, переданного в функцию.
    """
    return decrypt(word, psw)


Создадим функцию def authorize(psw: str) -> Client, в которую передадим пароль для дешифровки логина и пароля от облака. На выходе, после авторизации получаем клиента, с помощью которого будем взаимодействовать с другими функциями.
Для начала читаем данные из файла setting.ini.
В данном случае проверки на наличие или отсутствие этого файла не требуется потому, что делается это в другой функции и проверка запускается из модуля основного приложения.
Получаем список из двух элементов, логина и пароля. После чего дешифруем их и передаем в словарь для авторизации. Создаем объект клиента, куда передаем словарь с данными авторизации и возвращаем этот объект из функции.

Python:
def authorize(psw: str) -> (Client, bool):
    """
    Авторизация в облаке. Декодирование логина и пароля.
    Создание клиента с авторизацией.
    Возвращение клиента из функции для использования в других функциях.
    """
    datas = [x.strip() for x in open('setting.ini', 'r', encoding='utf-8') if x.strip()]
    login = decrypt_word(datas[0], psw)
    password = decrypt_word(datas[1], psw)
    if login:
        data = {
            'webdav_hostname': "https://webdav.cloud.mail.ru",
            'webdav_login': login,
            'webdav_password': password
        }

        client = Client(data)
        return client
    return False


Создадим функцию check_setting() -> bool, которая, собственно и будет проверять наличие или отсутствие файла setting.ini. В случае наличия возвращает True, в случае отсутствия False.

Python:
def check_setting() -> bool:
    """
    Проверка существования файла настроек.
    """
    if not Path('setting.ini').exists():
        return False
    return True


Создадим функцию def connect_cloud_folder(client: Client, path: str) -> dict, которая будет получать объект клиента, а также директорию, содержимое которой необходимо показать. Данная функция выполняет сканирование переданной в нее директории и возвращает ее содержимое в виде словаря. Выполняется это с помощью метода client.list, в котором нужно указать параметр get_info=True, чтобы возвращались расширенные сведения о файле или директории, такие как: размер, путь к фалу/директории, название и прочие. В противном случае функция вернет список с названиями файлов и папок. Из-за того, что библиотека предоставляет общий функционал для взаимодействия с облаками, размера директорий или файлов, к сожалению, получить не удастся. После, полученный словарь возвращается из функции. Эту функцию мы будем использовать для чтения содержимого всех директорий, которые будут передаваться в нее из основного приложения.

Python:
def connect_cloud_folder(client: Client, path: str) -> dict:
    """
    Читает содержимое переданной директории в облаке.
    Возвращает словарь с полученными значениями.
    """
    my_files = client.list(path, get_info=True)
    return my_files


Создадим функцию def create_cloud_folder(client, path: str) -> bool, которая получает в качестве параметров объект клиента, а также путь к директории. Возвращает True, в случае удачи. Данную функцию мы будем использовать для создания папок в Облаке. Если папка была создана удачно, возвращается True.

Python:
def create_cloud_folder(client, path: str) -> bool:
    """
    Создание директории в облаке. Возвращает True,
    если создание директории прошло успешно.
    """
    return client.mkdir(path)


Создадим функцию для удаления файлов или папок из облака: def delete_cloud_folder(client: Client, path: str). На входе она также, как и другие функции по взаимодействию с облаком, получает объект клиента и путь к папке, которую нужно удалить. К сожалению, данная функция ничего не возвращает. Поэтому, удаление директории можно проконтролировать только визуально.

Python:
def delete_cloud_folder(client: Client, path: str):
    """
    Удаление переданной директории в облаке.
    """
    client.clean(path)


Создадим функцию для загрузки файлов или папок в облако: def upload_cloud_file(client: Client, remote_path: str, local_path: str). На входе она получает объект клиента, путь к папке в облаке, куда нужно загрузить папку/файл, путь к папке/файлу, которые нужно загрузить.

Python:
def upload_cloud_file(client: Client, remote_path: str, local_path: str):
    """
    Загрузка файла в облако.
    """
    client.upload_sync(remote_path, local_path)


Создадим функцию для скачивания файлов/папок из облака на локальный компьютер: def download_cloud_file(client: Client, remote_path: str, local_path: str) -> bool. Она также получает объект клиента, путь к папке/файлу в облаке, которые нужно загрузить и путь к директории на локальном компьютере, куда нужно загрузить скачиваемый объект.

Python:
def download_cloud_file(client: Client, remote_path: str, local_path: str) -> bool:
    """
    Скачивание файла из облака.
    """
    client.download_sync(remote_path, local_path)
    return True


Создадим функцию def move_cloud_object(client: Client, remote_path_from: str, remote_path_to: str). С ее помощью мы будем перемещать файлы/папки внутри облака. Передаем в функцию объект клиента, путь к папке/файлу в облаке, которые нужно переместить, путь в облаке к папке, куда нужно переместить.

Python:
def move_cloud_object(client: Client, remote_path_from: str, remote_path_to: str):
    """
    Перемещение файла в облаке.
    """
    client.move(remote_path_from, remote_path_to)


Создадим функцию def copy_cloud_object(client: Client, remote_path_from: str, remote_path_to: str). С ее помощью мы будем копировать файлы/папки в облаке. В нее необходимо передать клиента, путь к файлу/папке в облаке, которые необходимо скопировать. Путь к папке, куда нужно скопировать.

Python:
def copy_cloud_object(client: Client, remote_path_from: str, remote_path_to: str):
    """
    Копирование файла в облаке.
    """
    client.copy(remote_path_from, remote_path_to)


Python:
"""
Набор функций для работы с облаком.
Для работы требует установки библиотеки:
pip install webdavclient3 cryptocode
"""

from pathlib import Path

from cryptocode import decrypt
from webdav3.client import Client


def decrypt_word(word: str, psw: str) -> str:
    """
    Дешифрование слова, переданного в функцию.
    """
    return decrypt(word, psw)


def authorize(psw: str) -> (Client, bool):
    """
    Авторизация в облаке. Декодирование логина и пароля.
    Создание клиента с авторизацией.
    Возвращение клиента из функции для использования в других функциях.
    """
    datas = [x.strip() for x in open('setting.ini', 'r', encoding='utf-8') if x.strip()]
    login = decrypt_word(datas[0], psw)
    password = decrypt_word(datas[1], psw)
    if login:
        data = {
            'webdav_hostname': "https://webdav.cloud.mail.ru",
            'webdav_login': login,
            'webdav_password': password
        }

        client = Client(data)
        return client
    return False


def check_setting() -> bool:
    """
    Проверка существования файла настроек.
    """
    if not Path('setting.ini').exists():
        return False
    return True


def connect_cloud_folder(client: Client, path: str) -> dict:
    """
    Читает содержимое переданной директории в облаке.
    Возвращает словарь с полученными значениями.
    """
    my_files = client.list(path, get_info=True)
    return my_files


def create_cloud_folder(client, path: str) -> bool:
    """
    Создание директории в облаке. Возвращает True,
    если создание директории прошло успешно.
    """
    return client.mkdir(path)


def delete_cloud_folder(client: Client, path: str):
    """
    Удаление переданной директории в облаке.
    """
    client.clean(path)


def upload_cloud_file(client: Client, remote_path: str, local_path: str):
    """
    Загрузка файла в облако.
    """
    client.upload_sync(remote_path, local_path)


def download_cloud_file(client: Client, remote_path: str, local_path: str) -> bool:
    """
    Скачивание файла из облака.
    """
    client.download_sync(remote_path, local_path)
    return True


def move_cloud_object(client: Client, remote_path_from: str, remote_path_to: str):
    """
    Перемещение файла в облаке.
    """
    client.move(remote_path_from, remote_path_to)


def copy_cloud_object(client: Client, remote_path_from: str, remote_path_to: str):
    """
    Копирование файла в облаке.
    """
    client.copy(remote_path_from, remote_path_to)


А на сегодня – все. В следующей статье продолжим создание приложения, вспомогательную (ну и основную) функцию которого для работы с облаком мы создали сегодня.
Вот небольшое видео того, что у меня получилось в итоге и как это у меня работает:





Спасибо за внимание. Надеюсь, данная информация будет вам полезна
 

Вложения

  • mail_tools.zip
    1,2 КБ · Просмотры: 224
Последнее редактирование модератором:
  • Нравится
Реакции: InternetMC
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!