aboutsummaryrefslogtreecommitdiffstats
path: root/cogs/downloader.py
blob: e67857562d3eec0f4a1b79303f8dc4a9f17e56de (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import os
import tempfile
import logging
import requests
import discord
import yt_dlp
from discord.ext import commands
from dotenv import load_dotenv

logger = logging.getLogger(__name__)

# Load environment variables
load_dotenv()


class Downloader(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.slash_command(
        name="download",
        description="Download and convert video/audio from internet"
    )
    async def download(
            self,
            ctx: discord.ApplicationContext,
            url: discord.Option(str, "URL of the video to download", required=True),
            fformat: discord.Option(str, "Output format (mp4, mp3, wav, etc.)", 
                                 required=False, 
                                 default="mp4")
    ):
        """Download and convert media from a URL to the specified format"""
        await ctx.defer()
        try:
            logger.info(f"Downloading {url} as {fformat}")
            
            with tempfile.TemporaryDirectory() as temp_dir:
                base_filename = os.path.join(temp_dir, 'output')
                input_file = f"{base_filename}.%(ext)s"
                output_file = f"{base_filename}.{fformat}"
                
                # Configure yt-dlp
                ydl_opts = {
                    'outtmpl': input_file,
                    'format': 'bestaudio/best' if fformat in ['mp3', 'wav', 'm4a'] else 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best',
                    'merge_output_format': 'mp4',
                    'postprocessors': [],
                }
                
                # Add post-processing for audio formats
                if fformat in ['mp3', 'wav', 'm4a']:
                    ydl_opts['postprocessors'].append({
                        'key': 'FFmpegExtractAudio',
                        'preferredcodec': fformat,
                        'preferredquality': '192',
                    })
                elif fformat != 'mp4':  # For other video formats
                    ydl_opts['postprocessors'].append({
                        'key': 'FFmpegVideoConvertor',
                        'preferedformat': fformat,
                    })

                with yt_dlp.YoutubeDL(ydl_opts) as ydl:
                    ydl.download([url])
                    
                # Find the downloaded file (yt-dlp might add a number if filename exists)
                actual_file = None
                for file in os.listdir(temp_dir):
                    if file.startswith('output') and file.endswith(fformat):
                        actual_file = os.path.join(temp_dir, file)
                        break
                        
                if not actual_file or not os.path.exists(actual_file):
                    raise Exception(f"{fformat} ze mno wygroł...")

                # Check file size and handle accordingly
                file_size = os.path.getsize(actual_file)
                if file_size < 10 * 1024 * 1024:  # Under 10MB
                    file = discord.File(actual_file, filename=f"output.{fformat}")
                    await ctx.followup.send("pobran", file=file)
                else:  # 10MB or larger - upload to Pixeldrain
                    try:
                        # Get file info
                        filename = f"output.{fformat}"
                        file_size_mb = file_size / (1024 * 1024)
                        
                        # Upload to Litterbox Catbox
                        with open(actual_file, 'rb') as f:
                            files = {
                                'reqtype': (None, 'fileupload'),
                                'time': (None, '24h'),
                                'fileToUpload': (filename, f, 'application/octet-stream')
                            }
                            
                            await ctx.followup.send(f"plik jest {file_size_mb:.1f} megabajtów... wysyłanie do gorzowa...")
                            
                            response = requests.post(
                                'https://litterbox.catbox.moe/resources/internals/api.php',
                                files=files
                            )
                            
                            if response.status_code == 200 and response.text.startswith('http'):
                                dl_url = response.text.strip()
                                await ctx.followup.send(
                                    f"wysyłon\n"
                                    f"pobrań: {dl_url}\n"
                                )
                            else:
                                error_msg = response.text if response.text else 'Unknown error'
                                await ctx.followup.send(f"nie udało się wysłać pliku: {error_msg}")
                                
                    except Exception as upload_error:
                        await ctx.followup.send(f"litterbox mnie nienawidzi :cccc\n {str(upload_error)}")
                        logger.error(f"litterbox upload error: {upload_error}", exc_info=True)
                
                logger.info(f"File processed: {actual_file} ({file_size} bytes)")
                
        except Exception as e:
            await ctx.followup.send(f":(\n{str(e)}")
            logger.error(f"Error in download command: {e}", exc_info=True)


def setup(bot):
    bot.add_cog(Downloader(bot))