This repository has been archived by the owner on Dec 17, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathradio.py
418 lines (323 loc) · 18.5 KB
/
radio.py
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
import discord, json, random, asyncio, requests
from discord.ext import commands
from discord.ui import Button, View
from decouple import config
from cogs.fungsi.func import Fungsi, owner_ids
radio_stations = {}
default_volume = 50
guild_volumes = {}
class Radio(commands.Cog):
def __init__(self, bot):
self.bot: discord.Bot = bot
self.invoke_channel = {}
self.invoke_messages = {}
self.invoke_message_ids = {}
self.default_volume = default_volume
self.owner_ids = owner_ids
self.leave_on_empty = False
self.radio_stations = radio_stations
radio = discord.SlashCommandGroup(
name="radio",
description="Menampilkan daftar channel pilihan.",
)
async def send_radio_info(self, ctx, station_name, station_logo_url):
guild_id = ctx.guild.id
volume = guild_volumes.get(guild_id, default_volume) / 100
embed = discord.Embed(color=discord.Color.from_rgb(*Fungsi.hex_to_rgb(Fungsi.generate_random_color())))
embed.title = f"Radio Diputar: {station_name}"
if station_logo_url:
embed.set_image(url=station_logo_url)
embed.set_footer(text=f"🔊 {volume * 100} | Gunakan /radio refresh jika buffering.")
message = await ctx.respond(embed=embed)
# Store the message content as an indicator of being an invoke message
self.invoke_messages[ctx.guild.id] = message
# Store the message ID for later reference
self.invoke_message_ids[ctx.guild.id] = message.id
@radio.command(name='volume', description='Mengatur volume radio.')
async def adjust_volume(self, ctx, volume: int):
"""Adjust the volume of the radio."""
if volume < 0 or volume > 100:
return await ctx.respond("> Volume harus dalam rentang 0 hingga 100.", delete_after=5)
guild_id = ctx.guild.id
guild_volumes[guild_id] = volume
if ctx.guild.id in radio_stations:
voice_channel = ctx.guild.voice_client
if voice_channel and voice_channel.is_playing():
if volume == int(voice_channel.source.volume * 100):
await ctx.respond(f"> Volume saat ini adalah {volume}.", delete_after=5)
else:
voice_channel.source.volume = volume / 100
await ctx.respond(f"> Volume radio telah diatur menjadi {volume}.", delete_after=5)
else:
await ctx.respond("> Tidak ada radio yang sedang diputar.", delete_after=5)
else:
await ctx.respond("> Tidak ada radio yang sedang diputar.", delete_after=5)
@radio.command(name='play', description='Memutar radio.')
async def play_radio(self, ctx, nama_radio: str, keluar_otomatis: discord.Option(bool, default=False, description="Bot meninggalkan channel suara jika channel suara kosong.", choices=[discord.OptionChoice(name="Ya", value=True), discord.OptionChoice(name="Tidak", value=False)])):
await ctx.defer()
if not await Fungsi.has_voted(self, ctx.author.id):
button1 = Button(
emoji="<:charis:1237457208774496266>",
label="VOTE",
url=f"https://top.gg/bot/{self.bot.user.id}/vote"
)
view = View()
view.add_item(button1)
embed = discord.Embed(
description=f"Silahkan [vote](https://top.gg/bot/{self.bot.user.id}/vote) bot terlebih dahulu untuk menggunakan perintah ini!",
color=discord.Color.from_rgb(*Fungsi.hex_to_rgb(Fungsi.generate_random_color()))
)
return await ctx.respond(embed=embed, view=view, delete_after=60, ephemeral=True)
if isinstance(ctx.channel, discord.DMChannel):
return await ctx.respond("Kamu tidak bisa menggunakan perintah ini di DM!", delete_after=10)
if ctx.author.voice is None or ctx.author.voice.channel is None:
return await ctx.respond("> Kamu harus berada di dalam voice channel!", delete_after=5)
guild_id = ctx.guild.id
self.invoke_channel[guild_id] = ctx.channel
try:
radio_data_file = 'radio/radio_data.json'
with open(radio_data_file, 'r') as file:
radio_data = json.load(file)
matching_stations = {}
for station_id, station_info in radio_data.items():
station_name = station_info['name'].lower()
if nama_radio in station_name:
matching_stations[station_id] = station_info
if not matching_stations:
return await ctx.respond("> Nama radio tidak ditemukan.", delete_after=5)
radio_id, station_info = matching_stations.popitem()
station_name = station_info['name']
station_url = station_info['url']
station_logo_url = station_info.get('logo')
if guild_id in self.radio_stations:
current_station = self.radio_stations[guild_id]
if (current_station != radio_id) or (hasattr(self, 'leave_on_empty') and self.leave_on_empty != keluar_otomatis):
# Change radio station
channel = ctx.author.voice.channel
voice_channel = ctx.guild.voice_client
# Stop playback if the bot is playing
if voice_channel and voice_channel.is_playing():
voice_channel.stop()
self.radio_stations[guild_id] = radio_id
volume = guild_volumes.get(guild_id, default_volume) / 100
voice_channel.play(discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(station_url), volume=volume),
after=lambda e: print('Sudah.'))
# Update leaveOnEmpty configuration
self.leave_on_empty = keluar_otomatis
await channel.set_status(f"<:radio:1230396943377629216> **{station_name}**")
# Delete previous radio info message if exists
if guild_id in self.invoke_message_ids:
try:
await self.invoke_messages[ctx.guild.id].delete()
except discord.HTTPException as e:
pass
except discord.NotFound:
pass
# Send new radio info message
await self.send_radio_info(ctx, station_name, station_logo_url)
else:
await ctx.respond(
f"> Radio {station_name} sedang diputar dengan pengaturan `keluar otomatis` yang sama. Coba gunakan pengaturan `keluar otomatis` atau gunakan `/radio refresh` jika terjadi error.",
delete_after=15)
else:
# Connect to voice channel and play the radio
channel = ctx.author.voice.channel
voice_channel = await channel.connect()
volume = guild_volumes.get(guild_id, default_volume) / 100
voice_channel.play(discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(station_url), volume=volume),
after=lambda e: print('Sudah.'))
if guild_id in self.invoke_message_ids:
try:
await self.invoke_messages[ctx.guild.id].delete()
except discord.HTTPException as e:
pass
except discord.NotFound:
pass
# Update leaveOnEmpty configuration
self.leave_on_empty = keluar_otomatis
await channel.set_status(f"<:radio:1230396943377629216> **{station_name}**")
# Store the station being played in the server
self.radio_stations[guild_id] = radio_id
# Send radio info
await self.send_radio_info(ctx, station_name, station_logo_url)
except FileNotFoundError:
await ctx.respond("> Data radio tidak ditemukan. ", delete_after=5)
@radio.command(name='refresh', description='Refresh radio error.')
async def refresh_command(self, ctx):
guild_id = ctx.guild.id
self.invoke_channel[guild_id] = ctx.channel
if isinstance(ctx.channel, discord.DMChannel):
return await ctx.respond("Kamu tidak bisa menggunakan perintah ini di DM!", delete_after=10)
voice_channel = ctx.guild.voice_client
if voice_channel is None: # Check if bot is not connected to any voice channel
# Get the member's voice channel
member_voice_channel = ctx.author.voice.channel
if member_voice_channel:
# Connect to the member's voice channel
voice_channel = await member_voice_channel.connect()
else:
# If member is not in a voice channel, return error message
embed = discord.Embed(color=discord.Color.red())
embed.description = "Kamu harus berada di voice channel untuk menggunakan perintah ini."
return await ctx.respond(embed=embed, delete_after=5)
if guild_id in radio_stations:
current_radio_id = radio_stations[guild_id]
radio_data_file = 'radio/radio_data.json'
try:
with open(radio_data_file, 'r') as file:
radio_data = json.load(file)
if current_radio_id in radio_data:
station_info = radio_data[current_radio_id]
station_name = station_info['name']
station_url = station_info['url']
station_logo_url = station_info.get('logo')
await voice_channel.channel.set_status(None)
# Stop any currently playing audio
if voice_channel.is_playing():
voice_channel.stop()
volume = guild_volumes.get(guild_id, default_volume) / 100
voice_channel.play(discord.PCMVolumeTransformer(discord.FFmpegPCMAudio(station_url), volume=volume),
after=lambda e: print('Sudah.'))
await voice_channel.channel.set_status(f"<:radio:1230396943377629216> **{station_name}**")
embed = discord.Embed(color=discord.Color.from_rgb(*Fungsi.hex_to_rgb(Fungsi.generate_random_color())))
embed.title = f"Memutar Ulang: {station_name}"
if station_logo_url:
embed.set_image(url=station_logo_url)
await ctx.respond(embed=embed, delete_after=5)
else:
embed = discord.Embed(color=discord.Color.red())
embed.description = "Tidak ada radio yang sedang diputar."
await ctx.respond(embed=embed, delete_after=5)
except FileNotFoundError:
embed = discord.Embed(color=discord.Color.red())
embed.description = "Data radio tidak ditemukan."
await ctx.respond(embed=embed, delete_after=5)
else:
embed = discord.Embed(color=discord.Color.red())
embed.description = "Bot sedang tidak memainkan radio apapun. Gunakan **`/radio play`** untuk memutar radio setelah bot terputus dari voice channel."
await ctx.respond(embed=embed, delete_after=15)
await asyncio.sleep(3)
await voice_channel.disconnect()
@radio.command(name='stop', description='Menghentikan pemutaran radio.')
async def disconnect_command(self, ctx):
guild_id = ctx.guild.id
await ctx.defer()
if isinstance(ctx.channel, discord.DMChannel):
return await ctx.respond("Kamu tidak bisa menggunakan perintah ini di DM!", delete_after=10)
# Check if the bot is connected to a voice channel
voice_channel = ctx.guild.voice_client
if voice_channel is None:
embed = discord.Embed(color=discord.Color.red())
embed.description = "Bot tidak sedang terhubung ke channel suara."
if hasattr(ctx, 'respond') and callable(ctx.respond):
await ctx.respond(embed=embed, delete_after=5)
else:
await ctx.send(embed=embed, delete_after=5)
else:
channel = ctx.author.voice.channel
voice_channel.stop()
await channel.set_status(None)
await voice_channel.disconnect()
if guild_id in radio_stations:
del radio_stations[guild_id]
if guild_id in self.invoke_message_ids:
try:
await self.invoke_messages[ctx.guild.id].delete()
except discord.HTTPException as e:
pass
except discord.NotFound:
pass
embed = discord.Embed(color=discord.Color.from_rgb(*Fungsi.hex_to_rgb(Fungsi.generate_random_color())))
embed.description = f"Radio dihentikan oleh {ctx.author.display_name}."
await ctx.respond(embed=embed)
@radio.command(name='upload', description='Menambah daftar radio baru.')
async def update_radio(self, ctx, name: str, url: str, logo: discord.Attachment = None):
await ctx.defer()
try:
radio_data_file = 'radio/radio_data.json'
with open(radio_data_file, 'r') as file:
radio_data = json.load(file)
# Find the next available ID
next_id = str(len(radio_data) + 1)
# Get logo URL if attachment is provided
logo_url = None
if logo:
# Upload the logo to imgbb album
upload_url = "https://api.imgbb.com/1/upload"
imgbb_key = config("IMGBB_KEY") # Replace "your_imgbb_key" with your actual imgbb API key
album_url = "https://ibb.co/album/0mBm9v" # Replace "your_album_url" with the URL of your imgbb album
# Read the attachment data
logo_data = await logo.read()
# Make the POST request with the attachment data
logo_response = requests.post(upload_url, params={"key": imgbb_key, "album": album_url, "expiration": 0}, files={'image': logo_data})
if logo_response.status_code == 200:
logo_url = logo_response.json()['data']['url']
else:
raise Exception("Failed to upload logo to imgbb")
# Create a new entry
radio_data[next_id] = {
'name': name,
'url': url,
'logo': logo_url
}
# Write the updated data back to the file
with open(radio_data_file, 'w') as file:
json.dump(radio_data, file, indent=2)
await ctx.respond("> Berhasil menambahkan radio baru!", delete_after=5)
except Exception as e:
await ctx.respond(f'An error occurred: {e}')
@radio.command(name='delete', description='Menghapus entri data radio berdasarkan nama.')
async def delete_radio(self, ctx, nama_radio: str):
await ctx.defer()
bot_creator_id = (await self.bot.application_info()).owner.id
if not (ctx.author.id == bot_creator_id or ctx.author.id in owner_ids):
embed = discord.Embed(
description=f"Hanya pemilik bot yang bisa menggunakan perintah ini!",
color=discord.Color.red())
return await ctx.respond(embed=embed, delete_after=10)
try:
radio_data_file = 'radio/radio_data.json'
with open(radio_data_file, 'r') as file:
radio_data = json.load(file)
matching_stations = {}
for station_id, station_info in radio_data.items():
station_name = station_info['name'].lower()
if nama_radio.lower() in station_name:
matching_stations[station_id] = station_info
if not matching_stations:
return await ctx.respond(f"Tidak ada radio dengan nama **`{nama_radio}`**.", delete_after=5)
# Deleting matching stations
for station_id in matching_stations:
del radio_data[station_id]
with open(radio_data_file, 'w') as file:
json.dump(radio_data, file, indent=2)
await ctx.respond(f"Berhasil menghapus radio **`{station_info['name']}`**.", delete_after=5)
except FileNotFoundError:
await ctx.respond("> Data radio tidak ditemukan.", delete_after=5)
except Exception as e:
await ctx.respond(f'An error occurred: {e}', delete_after=5)
@radio.command(
name='list',
description='Menampilkan daftar stasiun radio.',
)
async def radio_list(self, ctx):
radio_data_file = 'radio/radio_data.json'
try:
with open(radio_data_file, 'r') as file:
radio_data = json.load(file)
except FileNotFoundError:
radio_data = {}
if radio_data:
radio_list = [f"{index + 1}. {station_info['name']}" for index, station_info in enumerate(radio_data.values())]
midpoint = len(radio_list) // 2
column1 = radio_list[:midpoint]
column2 = radio_list[midpoint:]
embed = discord.Embed(title="Daftar Stasiun Radio", color=discord.Color.from_rgb(*Fungsi.hex_to_rgb(Fungsi.generate_random_color())))
embed.add_field(name="Radio 1", value="\n".join(column1), inline=True)
embed.add_field(name="Radio 2", value="\n".join(column2), inline=True)
else:
embed = discord.Embed(description="Tidak ada stasiun radio yang tersedia.", color=discord.Color.red())
if hasattr(ctx, 'respond') and callable(ctx.respond):
await ctx.respond(embed=embed, delete_after=60)
else:
await ctx.send(embed=embed, delete_after=60)