mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +00:00
wow it works?!?
This commit is contained in:
parent
777abfae5e
commit
b13da5b176
4 changed files with 159 additions and 42 deletions
12
db.py
12
db.py
|
@ -602,17 +602,19 @@ class CVMusic(Base):
|
||||||
__tablename__ = "cvmusic"
|
__tablename__ = "cvmusic"
|
||||||
|
|
||||||
id = Column(BigInteger, primary_key=True)
|
id = Column(BigInteger, primary_key=True)
|
||||||
title = Column(String, nullable=False)
|
url = Column(String, nullable=False)
|
||||||
timestamp = Column(DateTime, nullable=False)
|
enqueued = Column(DateTime, nullable=False)
|
||||||
|
started = Column(DateTime, nullable=False)
|
||||||
|
|
||||||
user_id = Column(Integer, ForeignKey("royals.id"))
|
user_id = Column(Integer, ForeignKey("royals.id"))
|
||||||
user = relationship("Royal")
|
user = relationship("Royal")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_and_add(title: str, user: Royal, timestamp: datetime):
|
def create_and_add(url: str, user: Royal, enqueued: datetime.datetime, started: datetime.datetime):
|
||||||
session = Session()
|
session = Session()
|
||||||
session.add(CVMusic(title=title,
|
session.add(CVMusic(url=url,
|
||||||
timestamp=timestamp,
|
enqueued=enqueued,
|
||||||
|
started=started,
|
||||||
user_id=user.id))
|
user_id=user.id))
|
||||||
session.commit()
|
session.commit()
|
||||||
session.close()
|
session.close()
|
||||||
|
|
143
discordbot.py
143
discordbot.py
|
@ -5,6 +5,7 @@ import functools
|
||||||
import db
|
import db
|
||||||
import errors
|
import errors
|
||||||
import youtube_dl
|
import youtube_dl
|
||||||
|
import sqlalchemy.exc
|
||||||
|
|
||||||
# Init the event loop
|
# Init the event loop
|
||||||
import asyncio
|
import asyncio
|
||||||
|
@ -20,28 +21,32 @@ client = discord.Client()
|
||||||
discord.opus.load_opus("libopus-0.dll")
|
discord.opus.load_opus("libopus-0.dll")
|
||||||
voice_client = None
|
voice_client = None
|
||||||
voice_player = None
|
voice_player = None
|
||||||
voice_queue = asyncio.Queue()
|
voice_queue = []
|
||||||
|
voice_playing = None
|
||||||
|
|
||||||
|
|
||||||
class Video:
|
class Video:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.user = None
|
self.user = None
|
||||||
self.info = None
|
self.info = None
|
||||||
self.timestamp = None
|
self.enqueued = None
|
||||||
|
self.channel = None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def init(author, info, timestamp):
|
async def init(author, info, enqueued, channel):
|
||||||
self = Video()
|
self = Video()
|
||||||
discord_user = await find_user(author)
|
discord_user = await find_user(author)
|
||||||
self.user = discord_user.royal
|
self.user = discord_user.royal if discord_user is not None else None
|
||||||
self.info = info
|
self.info = info
|
||||||
self.timestamp = timestamp
|
self.enqueued = enqueued
|
||||||
|
self.channel = channel
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def add_to_db(self):
|
def add_to_db(self, started):
|
||||||
db.CVMusic.create_and_add(title=self.info["title"],
|
db.CVMusic.create_and_add(url=self.info["webpage_url"],
|
||||||
user=self.user,
|
user=self.user,
|
||||||
timestamp=self.timestamp)
|
enqueued=self.enqueued,
|
||||||
|
started=started)
|
||||||
|
|
||||||
def create_embed(self):
|
def create_embed(self):
|
||||||
embed = discord.Embed(type="rich",
|
embed = discord.Embed(type="rich",
|
||||||
|
@ -69,14 +74,20 @@ class Video:
|
||||||
return embed
|
return embed
|
||||||
|
|
||||||
async def download(self):
|
async def download(self):
|
||||||
with youtube_dl.YoutubeDL({"noplaylist": True,
|
try:
|
||||||
"format": "bestaudio",
|
with youtube_dl.YoutubeDL({"noplaylist": True,
|
||||||
"postprocessors": [{
|
"format": "bestaudio",
|
||||||
"key": 'FFmpegExtractAudio',
|
"postprocessors": [{
|
||||||
"preferredcodec": 'opus'
|
"key": 'FFmpegExtractAudio',
|
||||||
}],
|
"preferredcodec": 'opus'
|
||||||
"outtmpl": "music.%(ext)s"}) as ytdl:
|
}],
|
||||||
info = await loop.run_in_executor(None, functools.partial(ytdl.extract_info, self.info["webpage_url"]))
|
"outtmpl": "music.%(ext)s"}) as ytdl:
|
||||||
|
info = await loop.run_in_executor(None, functools.partial(ytdl.extract_info, self.info["webpage_url"]))
|
||||||
|
except Exception as e:
|
||||||
|
client.send_message(self.channel, f"⚠ Errore durante il download del video:\n"
|
||||||
|
f"```"
|
||||||
|
f"{e}"
|
||||||
|
f"```", embed=self.create_embed())
|
||||||
|
|
||||||
|
|
||||||
async def find_user(user: discord.User):
|
async def find_user(user: discord.User):
|
||||||
|
@ -86,6 +97,8 @@ async def find_user(user: discord.User):
|
||||||
|
|
||||||
@client.event
|
@client.event
|
||||||
async def on_message(message: discord.Message):
|
async def on_message(message: discord.Message):
|
||||||
|
global voice_queue
|
||||||
|
global voice_player
|
||||||
if message.content.startswith("!register"):
|
if message.content.startswith("!register"):
|
||||||
await client.send_typing(message.channel)
|
await client.send_typing(message.channel)
|
||||||
session = await loop.run_in_executor(None, db.Session())
|
session = await loop.run_in_executor(None, db.Session())
|
||||||
|
@ -112,7 +125,10 @@ async def on_message(message: discord.Message):
|
||||||
await client.send_message(message.channel, "⚠ Non sei in nessun canale!")
|
await client.send_message(message.channel, "⚠ Non sei in nessun canale!")
|
||||||
return
|
return
|
||||||
global voice_client
|
global voice_client
|
||||||
voice_client = await client.join_voice_channel(message.author.voice.voice_channel)
|
if voice_client is not None and voice_client.is_connected():
|
||||||
|
await voice_client.move_to(message.author.voice.voice_channel)
|
||||||
|
else:
|
||||||
|
voice_client = await client.join_voice_channel(message.author.voice.voice_channel)
|
||||||
await client.send_message(message.channel, f"✅ Mi sono connesso in <#{message.author.voice.voice_channel.id}>.")
|
await client.send_message(message.channel, f"✅ Mi sono connesso in <#{message.author.voice.voice_channel.id}>.")
|
||||||
elif message.content.startswith("!madd"):
|
elif message.content.startswith("!madd"):
|
||||||
await client.send_typing(message.channel)
|
await client.send_typing(message.channel)
|
||||||
|
@ -136,22 +152,22 @@ async def on_message(message: discord.Message):
|
||||||
with youtube_dl.YoutubeDL({"quiet": True, "skip_download": True, "noplaylist": True, "format": "webm[abr>0]/bestaudio/best"}) as ytdl:
|
with youtube_dl.YoutubeDL({"quiet": True, "skip_download": True, "noplaylist": True, "format": "webm[abr>0]/bestaudio/best"}) as ytdl:
|
||||||
info = await loop.run_in_executor(None, functools.partial(ytdl.extract_info, url))
|
info = await loop.run_in_executor(None, functools.partial(ytdl.extract_info, url))
|
||||||
except youtube_dl.utils.DownloadError as e:
|
except youtube_dl.utils.DownloadError as e:
|
||||||
if "is not a valid URL" in str(e):
|
if "is not a valid URL" in str(e) or "Unsupported URL" in str(e):
|
||||||
await client.send_message(message.channel, f"⚠️ Il link inserito non è valido.\n"
|
await client.send_message(message.channel, f"⚠️ Il link inserito non è valido.\n"
|
||||||
f"Se vuoi cercare un video su YouTube, usa `!msearch <query>`")
|
f"Se vuoi cercare un video su YouTube, usa `!msearch <query>`")
|
||||||
return
|
return
|
||||||
if "_type" not in info:
|
if "_type" not in info:
|
||||||
# If target is a single video
|
# If target is a single video
|
||||||
video = await Video.init(author=message.author, info=info, timestamp=datetime.datetime.now())
|
video = await Video.init(author=message.author, info=info, timestamp=datetime.datetime.now(), channel=message.channel)
|
||||||
await client.send_message(message.channel, f"✅ Aggiunto alla coda:", embed=video.create_embed())
|
await client.send_message(message.channel, f"✅ Aggiunto alla coda:", embed=video.create_embed())
|
||||||
await voice_queue.put(video)
|
voice_queue.append(video)
|
||||||
elif info["_type"] == "playlist":
|
elif info["_type"] == "playlist":
|
||||||
# If target is a playlist
|
# If target is a playlist
|
||||||
if len(info["entries"]) < 20:
|
if len(info["entries"]) < 20:
|
||||||
for single_info in info["entries"]:
|
for single_info in info["entries"]:
|
||||||
video = await Video.init(author=message.author, info=single_info, timestamp=datetime.datetime.now())
|
video = await Video.init(author=message.author, info=single_info, timestamp=datetime.datetime.now(), channel=message.channel)
|
||||||
await client.send_message(message.channel, f"✅ Aggiunto alla coda:", embed=video.create_embed())
|
await client.send_message(message.channel, f"✅ Aggiunto alla coda:", embed=video.create_embed())
|
||||||
await voice_queue.put(video)
|
voice_queue.append(video)
|
||||||
else:
|
else:
|
||||||
await client.send_message(message.channel, f"ℹ La playlist contiene {len(info['entries'])} video.\n"
|
await client.send_message(message.channel, f"ℹ La playlist contiene {len(info['entries'])} video.\n"
|
||||||
f"Sei sicuro di volerli aggiungere alla coda?\n"
|
f"Sei sicuro di volerli aggiungere alla coda?\n"
|
||||||
|
@ -161,24 +177,70 @@ async def on_message(message: discord.Message):
|
||||||
if "sì" in answer.content.lower() or "si" in answer.content.lower():
|
if "sì" in answer.content.lower() or "si" in answer.content.lower():
|
||||||
for single_info in info["entries"]:
|
for single_info in info["entries"]:
|
||||||
video = await Video.init(author=message.author, info=single_info,
|
video = await Video.init(author=message.author, info=single_info,
|
||||||
timestamp=datetime.datetime.now())
|
timestamp=datetime.datetime.now(), channel=message.channel)
|
||||||
await client.send_message(message.channel, f"✅ Aggiunto alla coda:", embed=video.create_embed())
|
await client.send_message(message.channel, f"✅ Aggiunto alla coda:", embed=video.create_embed())
|
||||||
await voice_queue.put(video)
|
voice_queue.append(video)
|
||||||
elif "no" in answer.content.lower():
|
elif "no" in answer.content.lower():
|
||||||
await client.send_message(message.channel, f"ℹ Operazione annullata.")
|
await client.send_message(message.channel, f"ℹ Operazione annullata.")
|
||||||
return
|
return
|
||||||
elif message.content.startswith("!msearch"):
|
elif message.content.startswith("!msearch"):
|
||||||
raise NotImplementedError()
|
await client.send_typing(message.channel)
|
||||||
|
# The bot should be in voice chat
|
||||||
|
if voice_client is None:
|
||||||
|
await client.send_message(message.channel, "⚠️ Non sono connesso alla cv!\n"
|
||||||
|
"Fammi entrare scrivendo `!cv` mentre sei in chat vocale.")
|
||||||
|
# Find the sent text
|
||||||
|
try:
|
||||||
|
text = message.content.split(" ", 1)[1]
|
||||||
|
except IndexError:
|
||||||
|
await client.send_message(message.channel, "⚠️ Non hai specificato il titolo!\n"
|
||||||
|
"Sintassi corretta: `!msearch <titolo>`")
|
||||||
|
return
|
||||||
|
# Extract the info from the url
|
||||||
|
try:
|
||||||
|
with youtube_dl.YoutubeDL({"quiet": True, "skip_download": True, "noplaylist": True, "format": "webm[abr>0]/bestaudio/best"}) as ytdl:
|
||||||
|
info = await loop.run_in_executor(None, functools.partial(ytdl.extract_info, f"ytsearch:{text}"))
|
||||||
|
except youtube_dl.utils.DownloadError as e:
|
||||||
|
if "is not a valid URL" in str(e) or "Unsupported URL" in str(e):
|
||||||
|
await client.send_message(message.channel, f"⚠️ Il video ottenuto dalla ricerca non è valido. Prova a cercare qualcos'altro...")
|
||||||
|
return
|
||||||
|
# If target is a single video
|
||||||
|
video = await Video.init(author=message.author, info=info["entries"][0], enqueued=datetime.datetime.now(), channel=message.channel)
|
||||||
|
await client.send_message(message.channel, f"✅ Aggiunto alla coda:", embed=video.create_embed())
|
||||||
|
voice_queue.append(video)
|
||||||
elif message.content.startswith("!mskip"):
|
elif message.content.startswith("!mskip"):
|
||||||
raise NotImplementedError()
|
global voice_player
|
||||||
|
voice_player.stop()
|
||||||
|
voice_player = None
|
||||||
|
await client.send_message(message.channel, f"⏩ Video saltato.")
|
||||||
elif message.content.startswith("!mpause"):
|
elif message.content.startswith("!mpause"):
|
||||||
raise NotImplementedError()
|
if voice_player is None or not voice_player.is_playing():
|
||||||
|
await client.send_message(message.channel, f"⚠️ Non è in corso la riproduzione di un video, pertanto non c'è niente da pausare.")
|
||||||
|
return
|
||||||
|
voice_player.pause()
|
||||||
|
await client.send_message(message.channel, f"⏸ Riproduzione messa in pausa.\n"
|
||||||
|
f"Riprendi con `!mresume`.")
|
||||||
elif message.content.startswith("!mresume"):
|
elif message.content.startswith("!mresume"):
|
||||||
raise NotImplementedError()
|
if voice_player is None or voice_player.is_playing():
|
||||||
|
await client.send_message(message.channel, f"⚠️ Non c'è nulla in pausa da riprendere!")
|
||||||
|
return
|
||||||
|
voice_player.resume()
|
||||||
|
await client.send_message(message.channel, f"▶️ Riproduzione ripresa.")
|
||||||
elif message.content.startswith("!mcancel"):
|
elif message.content.startswith("!mcancel"):
|
||||||
raise NotImplementedError()
|
try:
|
||||||
|
video = voice_queue.pop()
|
||||||
|
except IndexError:
|
||||||
|
await client.send_message(message.channel, f"⚠ La playlist è vuota.")
|
||||||
|
return
|
||||||
|
await client.send_message(message.channel, f"❌ Rimosso dalla playlist:", embed=video.create_embed())
|
||||||
elif message.content.startswith("!mstop"):
|
elif message.content.startswith("!mstop"):
|
||||||
raise NotImplementedError()
|
if voice_player is None:
|
||||||
|
await client.send_message(message.channel, f"⚠ Non c'è nulla da interrompere!")
|
||||||
|
return
|
||||||
|
voice_queue = []
|
||||||
|
voice_player.stop()
|
||||||
|
voice_player = None
|
||||||
|
await client.send_message(message.channel, f"⏹ Riproduzione interrotta e playlist svuotata.")
|
||||||
|
|
||||||
|
|
||||||
async def update_users_pipe(users_connection):
|
async def update_users_pipe(users_connection):
|
||||||
|
@ -195,19 +257,28 @@ async def update_music_queue():
|
||||||
while True:
|
while True:
|
||||||
global voice_player
|
global voice_player
|
||||||
# Wait until there is nothing playing
|
# Wait until there is nothing playing
|
||||||
if voice_player is None or voice_player.is_playing():
|
if voice_client is not None and voice_player is not None and (voice_player.is_playing() and not voice_player.is_done()):
|
||||||
if voice_queue.qsize() == 0:
|
await asyncio.sleep(1)
|
||||||
await asyncio.sleep(1)
|
continue
|
||||||
continue
|
if len(voice_queue) == 0:
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
continue
|
||||||
# Get the last video in the queue
|
# Get the last video in the queue
|
||||||
video = await voice_queue.get()
|
video = voice_queue.pop(0)
|
||||||
|
# Notify the chat of the download
|
||||||
|
await client.send_message(video.channel, f"ℹ E' iniziato il download di:", embed=video.create_embed())
|
||||||
# Download the video
|
# Download the video
|
||||||
await video.download()
|
await video.download()
|
||||||
# Play the video
|
# Play the video
|
||||||
voice_player = voice_client.create_ffmpeg_player(f"music.opus")
|
voice_player = voice_client.create_ffmpeg_player(f"music.opus")
|
||||||
voice_player.start()
|
voice_player.start()
|
||||||
|
# Notify the chat of the start
|
||||||
|
await client.send_message(video.channel, f"▶ Ora in riproduzione in <#{voice_client.channel.id}>:", embed=video.create_embed())
|
||||||
# Add the video to the db
|
# Add the video to the db
|
||||||
await loop.run_in_executor(None, video.add_to_db)
|
try:
|
||||||
|
await loop.run_in_executor(None, functools.partial(video.add_to_db, started=datetime.datetime.now()))
|
||||||
|
except sqlalchemy.exc.OperationalError:
|
||||||
|
await client.send_message(video.channel, f"⚠ Ehi, <@77703771181817856>, il database si è rotto. Vallo a sistemare!")
|
||||||
|
|
||||||
|
|
||||||
def process(users_connection):
|
def process(users_connection):
|
||||||
|
|
34
templates/music.html
Normal file
34
templates/music.html
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Leaderboards - RYG</title>
|
||||||
|
<script src="{{ url_for('static', filename='sorttable.js') }}"></script>
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css"
|
||||||
|
integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='royal.css') }}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>
|
||||||
|
Top Plays
|
||||||
|
</h1>
|
||||||
|
<table class="table table-hover sortable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>URL</th>
|
||||||
|
<th>Plays</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for record in top_plays %}
|
||||||
|
<tr>
|
||||||
|
<td><a href="{{ record[0] }}">{{ record[0] }}</a></td>
|
||||||
|
<td>{{ record[1] }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
12
webserver.py
12
webserver.py
|
@ -1,6 +1,7 @@
|
||||||
from flask import Flask, render_template
|
from flask import Flask, render_template
|
||||||
from db import Session, Royal, Steam, RocketLeague, Dota, Osu, Overwatch, LeagueOfLegends
|
from db import Session, Royal, Steam, RocketLeague, Dota, Osu, Overwatch, LeagueOfLegends, CVMusic
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
from sqlalchemy import func
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
@ -18,6 +19,15 @@ def page_leaderboards():
|
||||||
session.close()
|
session.close()
|
||||||
return render_template("leaderboards.html", dota_data=dota_data, rl_data=rl_data, ow_data=ow_data, osu_data=osu_data, lol_data=lol_data)
|
return render_template("leaderboards.html", dota_data=dota_data, rl_data=rl_data, ow_data=ow_data, osu_data=osu_data, lol_data=lol_data)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/music")
|
||||||
|
def page_music():
|
||||||
|
session = Session()
|
||||||
|
top_plays = session.execute("SELECT cvmusic.url, COUNT(cvmusic.url) FROM cvmusic GROUP BY cvmusic.url ORDER BY COUNT(cvmusic.url);").fetchall()
|
||||||
|
session.close()
|
||||||
|
return render_template("music.html", top_plays=top_plays)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
try:
|
try:
|
||||||
app.run(host="0.0.0.0", port=1234, debug=True)
|
app.run(host="0.0.0.0", port=1234, debug=True)
|
||||||
|
|
Loading…
Reference in a new issue