• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

Статья Загружаем видео в плейлисты ВК с помощью VK API и Python

Как и у большинства тех, кто занимается изучением какого-либо языка программирования, у меня скопилось довольно много курсов по различным его аспектам. Какие-то я просмотрел, до каких-то еще не дошли руки, так как это все же много часов видео. Так или иначе, объем занимаемый этими видео на диске стал превышать критический. А потому было решено их куда-нибудь убрать. Просто потому, что вроде бы и удалять жалко, и оставлять накладно. Немного подумав, я вспомнил, что ВК позволяет загружать достаточно большие объемы видео. Чем не облачный диск, да еще с удобным плеером? Сначала я грузил видео вручную. А это довольно трудоемкий процесс, который занимает достаточно много времени. Немного помучившись, я решил сделать небольшой скрипт, который будет делать эту задачу за меня – создавать плейлисты, выставлять на них права доступа и загружать видео.

000.jpg


Что потребуется?

Так как мы будем работать с методами ВК API, будет разумно использовать специальную библиотеку предназначенную для этих целей - vk-api. В процессе работы скрипта довольно удобно наблюдать выводимую в терминал информацию в цвете, поэтому, для раскрашивания вывода в терминале установим библиотеку colorama. Для их установки необходимо открыть терминал вашей IDE, если вы пользуетесь IDE, ну или просто открыть терминал и ввести команду:

pip install vk-api colorama

Также, для того, чтобы работать с ВК API необходимо получить токен. Процесс получения токена я описал в этой статье, в самом ее начале.
Единственное – не забудьте отметить права доступа к видео, так как скрипт именно для этого и предназначен.
После этого я создал файл set_vk.py, куда поместил полученный токен, а также пользовательский ID. Если у вас отображаемое имя не состоит из вашего ID, узнать его можно с помощью этого . Заходите на свою страницу, копируете адрес, вставляете в поле и жмете кнопку «Определить ID». После копируете ID и добавляете в созданный файл. Его структура, в моем случае такова:

Python:
user_vk_id = 'ваш_id'
token_vk = 'ваш_token'

После того, как установлены необходимые библиотеки и сделаны приготовления, создадим файл скрипта - vk_video_upload.py и импортируем в него необходимые для его работы библиотеки, а также ID и token.

Python:
import os
import sys
import time
from pathlib import Path

from colorama import Fore, init
from vk_api import VkApi, VkUpload

from set_vk import token_vk, user_vk_id

Затем инициализируем colorama, создадим объект VkApi, в который передадим полученный токен. Данный объект будет нам необходим для авторизации. Также создадим объект VkUpload, куда передадим созданную сессию VkApi. Данный объект нам будет необходим для загрузки видео в плейлист.

Создадим глобальную переменную NAMES, которую определим как словарь. Сюда мы будем складывать полученные названия плейлистов и их ID, если таковые имеются у пользователя, для проверки на существование плейлиста с тем названием, который вы хотите создать. Создадим переменную TITLES, которую определим как множество и которая, также будет глобальной. Сюда мы поместим, при необходимости, названия видео в существующем плейлисте. Как вы уже, наверное, поняли, скрипт будет уметь докачивать недогруженные видео.

Python:
init()
session = VkApi(token=token_vk)
upload = VkUpload(session)
NAMES = dict()
TITLES = set()


Конвертирование размеров. Вспомогательная функция

Создадим функцию def get_size(bts: int, ending='B') -> str, которая будет принимать целове число, а также при необходимости суффикс и конвертировать данное число в удобочитаемый формат. Биты, байты, кило-мега байты и так далее. Итерируемся по списку с величинами и проверяем, является ли переданное в функцию число меньше 1024. Если да, возвращаем его из функции с добавлением значения из списка и суффикса. Если нет, делим на 1024.

Python:
def get_size(bts: int, ending='B') -> str:
    """
    Конвертация размера.
    :param bts: Размер.
    :param ending: Суффикс.
    :return: Конвертированное значение с суффиксом.
    """
    for item in ["", "K", "M", "G", "T", "P"]:
        if bts < 1024:
            return f"{bts:.2f} {item}{ending}"
        bts /= 1024


Получение списка видеофайлов в директории

Создадим функцию def get_files_dir(path: str) -> (list, bool). На входе она получает путь к директории, список файлов в которой необходимо получить. А возвращает список с путями к найденным файлам или False, в случае неудачи.

Создадим список files_path, в который будем помещать полученные пути к файлам видео. С помощью os.walk рекурсивно обойдем переданную в функцию директорию. Это сделано для того, чтобы проверить на наличие видео все вложенные папки директории, если таковые присутствуют в ней. Ну и после итерируемся по найденным файлам, составляем путь к ним с помощью Path и добавляем в список. Затем, после окончания цикла проверяем, не является ли список с путями пустым и если нет, возвращаем его из функции. Если же список пуст, возвращаем из функции False.

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

Python:
def get_files_dir(path: str) -> (list, bool):
    """
    Чтение файлов в директории. Операция выполняется рекурсивно.
    Файлы будут прочитаны также из всех субдиректорий.
    :param path: Путь к директории для чтения.
    :return: Список с путями файлов.
    """
    files_path = []
    for path, dirs, files in os.walk(path):
        for file in files:
            if (Path(path) / file).suffix in [".mp4", ".avi", ".mov"]:
                files_path.append(str(Path(path) / file))
    return files_path if files_path else False


Получение названия альбомов и ID

Создадим функцию def albums_name() -> None. Она ничего не получает и не возвращает. Её работа заключается в том, чтобы получить список названий плейлистов пользователя и их ID. Названия плейлистов будут необходимы для того, чтобы выполнять проверку, существует ли создаваемый плейлист у пользователя. А если существует, то, так как функция также получает ID и добавляет название плейлиста и ID в словарь, то забирать полученный ID для выполнения последующих операций. Хотя, создание плейлистов с одинаковым названием не является критичным для ВК, так как их идентификация идет по ID, все же, хотелось бы избежать дублирования.

Выводим в терминал информацию для пользователя о том, что получаем список плейлистов. Затем необходимо получить количество плейлистов, чтобы понимать, сколько их всего и составить диапазон для итерации по ним. Поэтому, используем метод ВК API video.getAlbums, куда передаем токен, ID владельца плейлиста (это мы), смещение по которому необходимо получить информацию и количество возвращаемых данных. В ответ мы получаем json-файл, в котором один из ключей – count, в котором и содержится общее количество плейлистов. А так как мы указали параметр count равным 0, то дополнительной информации получено не будет. Да и незачем, в данном случае перегружать запрос.

Затем проверяем, не является ли полученное количество плейлистов 0. Если да, сообщаем об этом пользователю и выходим из функции. В этом случае проверка будет происходить по пустому глобальному словарю NAMES, а так как значений в нем нет, любое название плейлиста будет принято для создания. Если же количество плейлистов не является нулевым, сообщаем пользователю, сколько плейлистов у пользователя. После итерируемся по диапазону с полученным значением. Дело в том, что данный метод за один запрос возвращает не более 100 плейлистов. Поэтому, необходимо в запросе указывать смещение, по которому необходимо получать информацию, чтобы получить названия всех плейлистов пользователя. Выполняем запрос к ВК API, получаем json с данными. Забираем из него по ключу items названия плейлистов, которые содержаться в ключах title, а также их ID, которые содержатся в ключах id и помещаем это в словарь NAMES.

Python:
def albums_name() -> None:
    """
    Получение названий уже существующих альбомов в ВК.
    Добавление названий альбомов в глобальное множество NAMES.
    :return: Функция ничего не возвращает.
    """
    global NAMES
    print(f"\n{Fore.YELLOW}[*] Получаю названия альбомов")
    count = session.get_api().video.getAlbums(access_token=token_vk, owner_id=user_vk_id, offset=0, count=0, v=5.131)
    if count['count'] == 0:
        print(f"{Fore.BLUE}[!] Альбомов не получено: {count['count']}")
        return
    print(f"{Fore.GREEN}[*] Получено альбомов: {count['count']}")
    for offset in range(0, count['count'], 100):
        albums = session.get_api().video.getAlbums(access_token=token_vk, owner_id=user_vk_id, offset=offset, count=100,
                                                   v=5.131)
        for item in albums.get('items'):
            NAMES.update({item.get('title').strip(): item.get('id')})


Получаем название видео из плейлиста

Создадим функцию def get_video_title(album_id: int) -> None. На входе она получает id плейлиста, информацию из которого необходимо получить. Если вы помните, то данный id мы получали в предыдущей созданной функции. Эта же функция будет работать только тогда, когда плейлист создаваемый пользователем существует. В этом случае нам будет необходимо получить названия видео в плейлисте, чтобы потом можно было проверять, не существует ли в нем уже загружаемое видео. А если нет, загрузку не производить. Выполняем запрос к методу ВК API video.get, куда передаем токен, ID владельца плейлиста, ID плейлиста информацию из которого необходимо получить. В ответ возвращается json, в котором содержаться все названия видео, которые есть в плейлисте.Итерируемся по ключу items из которого по ключу title забираем название и добавляем в множество TITLES. Но есть видео, у которых названия, как такового нет. А значит нет и ключа title. Поэтому, возникнет исключение, которое необходимо обработать. Заключаем код обращения к ключу title в блок try – except и, если исключение возникает, просто продолжаем работу цикла.

Python:
def get_video_title(album_id: int) -> None:
    """
    Получение заголовков видео в альбоме, если альбом существует.
    :param album_id: ID альбома с видео.
    :return: Функция ничего не возвращает.
    """
    global TITLES
    title = session.get_api().video.get(access_token=token_vk, owner_id=user_vk_id, album_id=album_id, v=5.131)
    for item in title.get("items"):
        try:
            TITLES.add(item.get('title').strip())
        except Exception:
            continue


Создание плейлиста

Создадим функцию def album_create_id_get(title: str) -> (int, bool). В нее передается название создаваемого плейлиста, а возвращает она его ID или False в случае неудачи.

Для начала проверяем, существует ли переданное в функцию название в словаре NAMES. Если название существует, значит, плейлист уже есть, а, следовательно, создавать его повторно не нужно. Поэтому, получаем названия видео в плейлисте. Выводим в терминал информацию для пользователя, что плейлист существует и, что мы получаем название видео в нем. После чего возвращаем из функции ID плейлиста полученное из словаря NAMES.

Если же плейлиста нет, необходимо его создать. Поэтому, обращаемся к методу ВК API video.addAlbum, в который передаем токен, название плейлиста, уровень приватности. Подробнее об уровнях приватности можно почитать в документации . После чего выводим информацию для пользователя, что плейлист создан и возвращаем из функции 'album_id', который возвращается в виде json. Если же 'album_id' получен не был, возвращаем False. Если же возникло исключение – также возвращаем False, так как без созданного альбома продолжать дальнейшие действия не имеет смысла.

Python:
def album_create_id_get(title: str) -> (int, bool):
    """
    Создание пустого альбома для видео в ВК.
    Проверка имени альбома на существование. Если существует, добавляем суффикс.
    :param title: Название для альбома.
    :return: ID созданного альбома.
    """
    global NAMES
    if title in NAMES:
        get_video_title(NAMES.get(title))
        print(f'{Fore.YELLOW}[*] Альбом существует: "{title}"')
        print(f'{Fore.YELLOW}[*] Загружаю названия видео из альбома: "{title}"')
        return NAMES.get(title)
    else:
        print(f'\n{Fore.YELLOW}[*] Создаю альбом: "{title}"')
        try:
            album = session.get_api().video.addAlbum(access_token=token_vk, title=title, privacy='only_me', v=5.131)
            print(f'{Fore.GREEN}[*] Альбом: "{title}" создан')
            return album.get('album_id') if album.get('album_id') else False
        except Exception:
            return False


Итерация по файлам видео

Созадим функцию def get_upload_url(album_id: int, files_path: list) -> None. Она ничего не возвращает, но принимет ID плейлиста, а также список с путями к видеофайлам, которые были найдены ранее.

Создадим список err, в который будем помещать пути к файлам видео в случае возникновения ошибки загрузки. Итерируемся по списку путей к файлам. Получаем имя файла, которое будет необходимо для передачи в функцию загрузки. Проверяем, существует ли такое имя в файла в множестве TITLES, если да, переходим к следующему файлу. Если нет, получаем его размер (особого функционала не несет; служит больше для вывода информации пользователю). Выводим в терминал информацию для пользователя о номере загружаемого видео из существующих, название видео и его размер. Проверяем, если функция загрузки вернула True, выводим сообщение о том, что видео загружено. Если False, сообщаем, что оно не загружено и добавляем путь к видео в список err. Ждем секунду между итерациями. Это позволит немного снизить нагрузку на сервера ВК. Хотя и такая себе забота )).

После окончания итерации по списку путей проверяем, есть ли что-то в списке err. Если есть, выводим эти данные для пользователя в терминал. Если нет, выводим сообщение, что все видео загружены.

Python:
def get_upload_url(album_id: int, files_path: list) -> None:
    """
    Итерация по файлам из директории для загрузки.
    Получение ссылки на загрузку видео в альбом.
    Передача данных в функцию загрузки видео.
    Если видео не загружено, оно добавляется в список ошибок, и,
    после завершения работы скрипта этот список, если он не пуст,
    выводиться в терминал.
    :param album_id: ID альбома для загрузки.
    :param files_path: Список путей к видео для загрузки.
    :return: Функция ничего не возвращает.
    """
    global TITLES
    err = []
    for nm, file in enumerate(files_path):
        file_name = Path(file).name.split(Path(file).suffix)[0]
        if file_name in TITLES:
            continue
        size = get_size(Path(file).stat().st_size)
        print(f'{Fore.YELLOW}Загружаю видео: "{file_name}" | {nm + 1}/{len(files_path)} | {size}')

        if video_file_upload(file, album_id):
            print(f'{Fore.GREEN}   [!] Видео: "{file_name}" загружено')
        else:
            print(f'{Fore.RED}   [~] Видео: "{file_name}" не загружено\n')
            err.append(str(file))
        time.sleep(1)
    if err:
        print(f"\n{Fore.BLUE}[-] Не загруженные видео:")
        for er in err:
            print(f"{Fore.RESET}   - {er}")
    else:
        print(f"\n{Fore.GREEN}{'-'*31}\n[!] Все видео успешно загружены\n{'-'*31}")


Функция загрузки видео в плейлист

Создадим функцию video_file_upload(file: str, album_id: int) -> bool, в которую передаем путь к файлу видео и ID плейлиста. Получаем из пути к файлу имя загружаемого видео.

Для загрузки видео будем использовать метод video из класса VkUpload. Для того, чтобы загрузить видео ему необходимо передать путь к загружаемому файлу, имя файла, ID плейлиста, в который нужно загрузить видео, а также уровни приватности для видео и комментариев. После чего выполняется загрузка. По окончании загрузки возвращается json, в котором один из ключей size, содержит размер загруженного видео. Проверяем, существует ли такой ключ, если да, возвращаем True, если нет – False. Также обработаем прерывание функции с клавиатуры. Здесь не торопитесь закрывать терминал, если после нажатия комбинации клавиш «Ctrl + C» ничего не произошло. Это лишь значит, что скрипт завершит свою работу после загрузки последнего видео, на котором он был прерван. Ну и в случае с возникновением иных исключений возвращаем False.

Python:
def video_file_upload(file: str, album_id: int) -> bool:
    """

    :param file: Путь к файлу для загрузки.
    :param album_id: ID альбома для загрузки.
    :return: True, если загрузка прошла успешно и был получен размер видео.
             И False, если загрузка окончилась неудачей.
    """
    name = str(Path(file).name.split(Path(file).suffix)[0])
    try:
        upl = upload.video(video_file=file, name=name, album_id=album_id, privacy_view='only_me',
                           privacy_comment='only_me')
        return True if upl.get('size') else False
    except KeyboardInterrupt:
        print("До свидания!")
        sys.exit(0)
    except Exception:
        return False

Здесь следуем сказать, что реализовать функцию загрузки видео можно несколько иначе. Однако, в этом случае вам придется самостоятельно выполнить получение ссылки на загрузку видео, после чего с помощью requests.post выполнить загрузку по полученной ссылке, где в качестве параметра нужно будет указать путь к видео. Ниже покажу кусочек кода, в котором получается ссылка на загрузку и выполняется загрузка с помощью данного метода. На мой взгляд, различия здесь минимальны, за исключением того, что метод video берет на себя все функции по получению ссылки и загрузке видео.

Python:
def get_upload_url(album_id: int, files_path: list) -> None:
    """
    Итерация по файлам из директории для загрузки.
    Получение ссылки на загрузку видео в альбом.
    Передача данных в функцию загрузки видео.
    Если видео не загружено, оно добавляется в список ошибок, и,
    после завершения работы скрипта этот список, если он не пуст,
    выводиться в терминал.
    :param album_id: ID альбома для загрузки.
    :param files_path: Список путей к видео для загрузки.
    :return: Функция ничего не возвращает.
    """
    err = []
    for nm, file in enumerate(files_path):
        file_name = Path(file).name.split(Path(file).suffix)[0]
        size = get_size(Path(file).stat().st_size)
        print(f'\n{Fore.YELLOW}Загружаю видео: "{file_name}" | {nm + 1}/{len(files_path)} | {size}')
        upload_data = session.get_api().video.save(access_token=token_vk, name=file_name, album_id=album_id,
                                                   privacy_view='only_me', privacy_comment='only_me', v=5.131)
        if upload_data.get('upload_url'):
            upload = video_file_upload(file, upload_data.get('upload_url'))
            if not upload:
                print(f'{Fore.RED}[~] Видео: "{file_name}" не загружено\n')
                err.append(str(file))
            else:
                print(f'{Fore.GREEN}[!] Видео: "{file_name}" загружено')
        time.sleep(1)
    if err:
        print(f"\n{Fore.BLUE}Не загруженные видео:")
        for er in err:
            print(f"{Fore.RESET}   - {er}")
    else:
        print(f"\n{Fore.GREEN}[!] Все видео успешно загружены")


def video_file_upload(file: str, upload_url: str) -> bool:
    with open(file, 'rb') as file:
        try:
            res = requests.post(upload_url, files={'video_file': file})
            return True if res.json().get('size') else False
        except Exception:
            return False


Запрос пути к директории с видео

Создадим функцию def main() -> None, в которой будем запрашивать путь к директории с видео.

Запрашиваем у пользователя путь к директории. Проверяем, есть ли такой путь и является ли он директорией, а также, не ввел ли пользователь пустое значение. Если проверка на проходит, сообщаем пользователю информацию, чтобы он проверил путь и выходим из скрипта. Если все в порядке, получаем название для плейлиста из имени директории. Я посчитал, так как у меня курсы, что это будет практичнее и быстрее. Вы же можете запросить у пользователя данную информацию с помощью input. Затем получаем список путей к видео в директории. Если список не пуст, получаем названия плейлистов пользователя. Создаем плейлист с полученным названием. После чего запускаем функцию для загрузки найденного в директории видео. Если что-то пошло не так, сообщаем об этом пользователю.

Python:
def main() -> None:
    """
    Запрос названия альбома и директории с видео для загрузки.
    Проверка директории на существование.
    Запуск функции получения названия альбомов пользователя.
    Запуск функции создания альбома и получения его ID.
    Запуск функции загрузки видео.
    """

    path = input("Введите директорию для загрузки: ")
    if not Path(path).exists() or not Path(path).is_dir() or not path:
        print(f"{Fore.RED}[!] Проверьте правильность ввода директории")
        sys.exit(0)
    title = Path(path).name.strip()
    if files_path := get_files_dir(path):
        albums_name()
        if album_id := album_create_id_get(title):
            get_upload_url(album_id, files_path)
        else:
            print(f'{Fore.RED}[!] Не удалось создать альбом: "{title}".\n   - Завершение работы')
            sys.exit(0)
    else:
        print("Не найдено файлов для выгрузки")
        sys.exit(0)


if __name__ == "__main__":
    main()

Что ж, такой вот небольшой скрипт получился. Я уже проверил его работу. И в качестве демонстрации создал небольшое видео, в котором его работа показана в самом конце.




Python:
# pip install vk-api colorama

import os
import sys
import time
from pathlib import Path

from colorama import Fore, init
from vk_api import VkApi, VkUpload

from set_vk import token_vk, user_vk_id

init()
session = VkApi(token=token_vk)
upload = VkUpload(session)
NAMES = dict()
TITLES = set()


def get_size(bts: int, ending='B') -> str:
    """
    Конвертация размера.
    :param bts: Размер.
    :param ending: Суффикс.
    :return: Конвертированное значение с суффиксом.
    """
    for item in ["", "K", "M", "G", "T", "P"]:
        if bts < 1024:
            return f"{bts:.2f} {item}{ending}"
        bts /= 1024


def get_files_dir(path: str) -> (list, bool):
    """
    Чтение файлов в директории. Операция выполняется рекурсивно.
    Файлы будут прочитаны также из всех субдиректорий.
    :param path: Путь к директории для чтения.
    :return: Список с путями файлов.
    """
    files_path = []
    for path, dirs, files in os.walk(path):
        for file in files:
            if (Path(path) / file).suffix in [".mp4", ".avi", ".mov"]:
                files_path.append(str(Path(path) / file))
    return files_path if files_path else False


def albums_name() -> None:
    """
    Получение названий уже существующих альбомов в ВК.
    Добавление названий альбомов в глобальное множество NAMES.
    :return: Функция ничего не возвращает.
    """
    global NAMES
    print(f"\n{Fore.YELLOW}[*] Получаю названия альбомов")
    count = session.get_api().video.getAlbums(access_token=token_vk, owner_id=user_vk_id, offset=0, count=0, v=5.131)
    if count['count'] == 0:
        print(f"{Fore.BLUE}[!] Альбомов не получено: {count['count']}")
        return
    print(f"{Fore.GREEN}[*] Получено альбомов: {count['count']}")
    for offset in range(0, count['count'], 100):
        albums = session.get_api().video.getAlbums(access_token=token_vk, owner_id=user_vk_id, offset=offset, count=100,
                                                   v=5.131)
        for item in albums.get('items'):
            NAMES.update({item.get('title').strip(): item.get('id')})


def get_video_title(album_id: int) -> None:
    """
    Получение заголовков видео в альбоме, если альбом существует.
    :param album_id: ID альбома с видео.
    :return: Функция ничего не возвращает.
    """
    global TITLES
    title = session.get_api().video.get(access_token=token_vk, owner_id=user_vk_id, album_id=album_id, v=5.131)
    for item in title.get("items"):
        try:
            TITLES.add(item.get('title').strip())
        except Exception:
            continue


def album_create_id_get(title: str) -> (int, bool):
    """
    Создание пустого альбома для видео в ВК.
    Проверка имени альбома на существование. Если существует, добавляем суффикс.
    :param title: Название для альбома.
    :return: ID созданного альбома.
    """
    global NAMES
    if title in NAMES:
        get_video_title(NAMES.get(title))
        print(f'{Fore.YELLOW}[*] Альбом существует: "{title}"')
        print(f'{Fore.YELLOW}[*] Загружаю названия видео из альбома: "{title}"')
        return NAMES.get(title)
    else:
        print(f'\n{Fore.YELLOW}[*] Создаю альбом: "{title}"')
        try:
            album = session.get_api().video.addAlbum(access_token=token_vk, title=title, privacy='only_me', v=5.131)
            print(f'{Fore.GREEN}[*] Альбом: "{title}" создан')
            return album.get('album_id') if album.get('album_id') else False
        except Exception:
            return False


def get_upload_url(album_id: int, files_path: list) -> None:
    """
    Итерация по файлам из директории для загрузки.
    Получение ссылки на загрузку видео в альбом.
    Передача данных в функцию загрузки видео.
    Если видео не загружено, оно добавляется в список ошибок, и,
    после завершения работы скрипта этот список, если он не пуст,
    выводиться в терминал.
    :param album_id: ID альбома для загрузки.
    :param files_path: Список путей к видео для загрузки.
    :return: Функция ничего не возвращает.
    """
    global TITLES
    err = []
    for nm, file in enumerate(files_path):
        file_name = Path(file).name.split(Path(file).suffix)[0]
        if file_name in TITLES:
            continue
        size = get_size(Path(file).stat().st_size)
        print(f'{Fore.YELLOW}Загружаю видео: "{file_name}" | {nm + 1}/{len(files_path)} | {size}')

        if video_file_upload(file, album_id):
            print(f'{Fore.GREEN}   [!] Видео: "{file_name}" загружено')
        else:
            print(f'{Fore.RED}   [~] Видео: "{file_name}" не загружено\n')
            err.append(str(file))
        time.sleep(1)
    if err:
        print(f"\n{Fore.BLUE}[-] Не загруженные видео:")
        for er in err:
            print(f"{Fore.RESET}   - {er}")
    else:
        print(f"\n{Fore.GREEN}{'-'*31}\n[!] Все видео успешно загружены\n{'-'*31}")


def video_file_upload(file: str, album_id: int) -> bool:
    """

    :param file: Путь к файлу для загрузки.
    :param album_id: ID альбома для загрузки.
    :return: True, если загрузка прошла успешно и был получен размер видео.
             И False, если загрузка окончилась неудачей.
    """
    name = str(Path(file).name.split(Path(file).suffix)[0])
    try:
        upl = upload.video(video_file=file, name=name, album_id=album_id, privacy_view='only_me',
                           privacy_comment='only_me')
        return True if upl.get('size') else False
    except KeyboardInterrupt:
        print("До свидания!")
        sys.exit(0)
    except Exception:
        return False


def main() -> None:
    """
    Запрос названия альбома и директории с видео для загрузки.
    Проверка директории на существование.
    Запуск функции получения названия альбомов пользователя.
    Запуск функции создания альбома и получения его ID.
    Запуск функции загрузки видео.
    """

    path = input("Введите директорию для загрузки: ")
    if not Path(path).exists() or not Path(path).is_dir() or not path:
        print(f"{Fore.RED}[!] Проверьте правильность ввода директории")
        sys.exit(0)
    title = Path(path).name.strip()
    if files_path := get_files_dir(path):
        albums_name()
        if album_id := album_create_id_get(title):
            get_upload_url(album_id, files_path)
        else:
            print(f'{Fore.RED}[!] Не удалось создать альбом: "{title}".\n   - Завершение работы')
            sys.exit(0)
    else:
        print("Не найдено файлов для выгрузки")
        sys.exit(0)


if __name__ == "__main__":
    main()

А на этом, пожалуй, всё.

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

Вложения

  • vk_video_upload.zip
    3,1 КБ · Просмотры: 82
Мы в соцсетях:

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