init commit

This commit is contained in:
2025-09-28 09:18:03 +09:00
commit a8076bc9d0
78 changed files with 11035 additions and 0 deletions

View File

@@ -0,0 +1,155 @@
#!/usr/bin/env python3
"""
YouTube Downloader - Приложение для скачивания видео с YouTube
Автор: GitHub Copilot
"""
import sys
import click
from colorama import Fore, Style
from downloader import YouTubeDownloader
from config import Config
@click.command()
@click.argument('url', required=True)
@click.option('--quality', '-q', default='best',
help='Качество видео (best, 1080p, 720p, 480p, 360p)')
@click.option('--audio-only', '-a', is_flag=True,
help='Скачать только аудио')
@click.option('--output', '-o', default=None,
help='Папка для сохранения файлов')
@click.option('--playlist', '-p', is_flag=True,
help='Скачать весь плейлист')
@click.option('--info', '-i', is_flag=True,
help='Показать информацию о видео без загрузки')
@click.option('--formats', '-f', is_flag=True,
help='Показать доступные форматы')
@click.option('--config', '-c', default='config.json',
help='Путь к файлу конфигурации')
def main(url, quality, audio_only, output, playlist, info, formats, config):
"""
YouTube Downloader - скачивание видео с YouTube
URL: Ссылка на YouTube видео или плейлист
"""
# Вывод заголовка
print(f"{Fore.CYAN}{'='*60}{Style.RESET_ALL}")
print(f"{Fore.CYAN}{'YouTube Downloader':^60}{Style.RESET_ALL}")
print(f"{Fore.CYAN}{'='*60}{Style.RESET_ALL}")
try:
# Инициализация конфигурации и загрузчика
app_config = Config(config)
downloader = YouTubeDownloader(app_config)
# Проверка URL
if not downloader.validate_url(url):
print(f"{Fore.RED}Ошибка: Некорректный URL YouTube{Style.RESET_ALL}")
sys.exit(1)
# Показать информацию о видео
if info:
video_info = downloader.get_video_info(url)
if video_info:
print(f"\n{Fore.GREEN}Информация о видео:{Style.RESET_ALL}")
print(f"{Fore.YELLOW}Название:{Style.RESET_ALL} {video_info['title']}")
print(f"{Fore.YELLOW}Автор:{Style.RESET_ALL} {video_info['uploader']}")
if video_info['duration']:
duration_str = f"{video_info['duration']//60}:{video_info['duration']%60:02d}"
print(f"{Fore.YELLOW}Длительность:{Style.RESET_ALL} {duration_str}")
if video_info['view_count']:
print(f"{Fore.YELLOW}Просмотров:{Style.RESET_ALL} {video_info['view_count']:,}")
if video_info['upload_date']:
date_str = video_info['upload_date']
formatted_date = f"{date_str[6:8]}.{date_str[4:6]}.{date_str[:4]}"
print(f"{Fore.YELLOW}Дата загрузки:{Style.RESET_ALL} {formatted_date}")
if video_info['description']:
desc = video_info['description'][:200] + "..." if len(video_info['description']) > 200 else video_info['description']
print(f"{Fore.YELLOW}Описание:{Style.RESET_ALL} {desc}")
return
# Показать доступные форматы
if formats:
print(f"\n{Fore.GREEN}Получение доступных форматов...{Style.RESET_ALL}")
available_formats = downloader.get_available_formats(url)
if available_formats:
print(f"\n{Fore.GREEN}Доступные форматы:{Style.RESET_ALL}")
for fmt in available_formats:
size_str = f" ({fmt['filesize']//1024//1024} MB)" if fmt['filesize'] else ""
print(f"{fmt['quality']} ({fmt['ext']}){size_str}")
else:
print(f"{Fore.RED}Не удалось получить информацию о форматах{Style.RESET_ALL}")
return
# Скачивание
print(f"\n{Fore.GREEN}Начинаю обработку...{Style.RESET_ALL}")
success = False
if playlist:
success = downloader.download_playlist(url, quality, audio_only, output)
else:
success = downloader.download_video(url, quality, audio_only, output)
if success:
print(f"\n{Fore.GREEN}{'='*60}{Style.RESET_ALL}")
print(f"{Fore.GREEN}Загрузка успешно завершена!{Style.RESET_ALL}")
output_path = output or app_config.get("output_directory", "downloads")
print(f"{Fore.CYAN}Файлы сохранены в: {output_path}{Style.RESET_ALL}")
print(f"{Fore.GREEN}{'='*60}{Style.RESET_ALL}")
else:
print(f"\n{Fore.RED}Загрузка завершилась с ошибкой{Style.RESET_ALL}")
sys.exit(1)
except KeyboardInterrupt:
print(f"\n{Fore.YELLOW}Загрузка прервана пользователем{Style.RESET_ALL}")
sys.exit(0)
except Exception as e:
print(f"\n{Fore.RED}Произошла неожиданная ошибка: {str(e)}{Style.RESET_ALL}")
sys.exit(1)
@click.group()
def cli():
"""YouTube Downloader - управление настройками и загрузка видео"""
pass
@cli.command()
@click.option('--output-dir', default='downloads', help='Папка для загрузок по умолчанию')
@click.option('--video-quality', default='best', help='Качество видео по умолчанию')
@click.option('--audio-format', default='mp3', help='Формат аудио по умолчанию')
@click.option('--video-format', default='mp4', help='Формат видео по умолчанию')
def configure(output_dir, video_quality, audio_format, video_format):
"""Настройка параметров по умолчанию"""
config = Config()
config.set('output_directory', output_dir)
config.set('video_quality', video_quality)
config.set('audio_format', audio_format)
config.set('video_format', video_format)
config.save_config()
print(f"{Fore.GREEN}Конфигурация сохранена:{Style.RESET_ALL}")
print(f" Папка загрузок: {output_dir}")
print(f" Качество видео: {video_quality}")
print(f" Формат аудио: {audio_format}")
print(f" Формат видео: {video_format}")
@cli.command()
def show_config():
"""Показать текущие настройки"""
config = Config()
print(f"{Fore.CYAN}Текущая конфигурация:{Style.RESET_ALL}")
for key, value in config.config.items():
print(f" {key}: {value}")
if __name__ == '__main__':
# Если запущен без команды, используем основную функцию
if len(sys.argv) == 1 or (len(sys.argv) > 1 and not sys.argv[1] in ['configure', 'show-config']):
main()
else:
cli()