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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
|
import os
import tempfile
import logging
import requests
import discord
import re
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
URL_PATTERN = re.compile(
r'https://(?:[A-Za-z0-9-]+\.)*[A-Za-z0-9-]{1,63}\.[A-Za-z]{2,63}/\S*'
)
@commands.message_command(
name="download",
description="Download and convert video/audio from internet"
)
async def message_download(self, ctx, message: discord.Message):
# check if message has a valid url
url = [m.group(0) for m in self.URL_PATTERN.finditer(message.content)]
if url:
for url in url:
await self.download(ctx, url, "mp4")
else:
await ctx.respond("Brak załączników w wiadomości", ephemeral=True)
@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:
# Configure yt-dlp to use the original filename
ydl_opts = {
'outtmpl': os.path.join(temp_dir, '%(title)s.%(ext)s'),
'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 (should be the only file in the temp directory)
files = [f for f in os.listdir(temp_dir) if os.path.isfile(os.path.join(temp_dir, f))]
if not files:
raise Exception(f"No file was downloaded")
actual_file = os.path.join(temp_dir, files[0])
if not os.path.exists(actual_file):
raise Exception(f"Downloaded file not found: {actual_file}")
if os.path.getsize(actual_file) > 1024*1024*10:
try:
# Get file info
filename = f"output.{fformat}"
# Upload to Copyparty
with open(actual_file, 'rb') as f:
files = {
'f': (filename, f, 'application/octet-stream')
}
headers = {
'Cookie': f'cppwd={os.getenv("COPYPARTY_PASSWORD")}'
}
params = {
'j': '1', # Return JSON response
'ck': 'b2' # Use blake2b checksum
}
# Ensure the URL ends with a single slash
base_url = "https://catbox.2137697.xyz/sperma/"
response = requests.post(
base_url,
files=files,
headers=headers,
params=params
)
if response.status_code == 200 or response.status_code == 201:
try:
result = response.json()
if 'fileurl' in result:
dl_url = result['fileurl']
await ctx.followup.send(
f"wysyłon\n"
f"{dl_url}\n"
)
else:
await ctx.followup.send(
f"Odpowiedź serwera nie zawiera wymaganych danych: {result}")
except ValueError:
await ctx.followup.send(f"Nieprawidłowa odpowiedź z serwera: {response.text}")
else:
error_msg = response.text if response.text else 'Unknown error'
await ctx.followup.send(
f"nie udało się wysłać pliku (HTTP {response.status_code}): {error_msg}")
except Exception as upload_error:
await ctx.followup.send(f"copyparty mnie nienawidzi :cccc\n {str(upload_error)}")
logger.error(f"copyparty upload error: {upload_error}", exc_info=True)
else:
await ctx.followup.send("wysyłon na discord\n", file=discord.File(actual_file))
logger.info(f"File processed: {actual_file}")
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))
|