Files
Chef_mu/chef_mou.py
2022-09-26 17:16:42 +02:00

130 lines
5.6 KiB
Python

from mautrix.util.config import BaseProxyConfig, ConfigUpdateHelper
from maubot import Plugin, MessageEvent
from maubot.handlers import command
import aiohttp
import asyncio
from bs4 import BeautifulSoup
import random
import re
from difflib import SequenceMatcher
from heapq import nlargest as _nlargest
class ChefMou(Plugin):
listRemove = ["", "Souba", "Basse", "Trombone", "Trompette", "Sax Mib", "Clarinette", "Midi", "Original", "Enregistrement", "Paroles", "Commentaire"]
async def start(self) -> None:
self.on_external_config_update()
def get_close_matches_indexes(self, word, possibilities, n=3, cutoff=0.6):
if not n > 0:
raise ValueError("n must be > 0: %r" % (n,))
if not 0.0 <= cutoff <= 1.0:
raise ValueError("cutoff must be in [0.0, 1.0]: %r" % (cutoff,))
result = []
s = SequenceMatcher()
s.set_seq2(word)
for idx, x in enumerate(possibilities):
s.set_seq1(x)
if s.real_quick_ratio() >= cutoff and \
s.quick_ratio() >= cutoff and \
s.ratio() >= cutoff:
result.append((s.ratio(), idx))
# Move the best scorers to head of list
result = _nlargest(n, result)
# Strip scores for the best n matches
return [x for score, x in result]
async def get_site_content(self):
async with aiohttp.ClientSession() as session:
async with session.get("https://partoches.pustule.org") as resp:
text = await resp.read()
return BeautifulSoup(text.decode('iso-8859-1'), 'html.parser')
@command.new("chefmou")
@command.argument("pattern", pass_raw=True, required=False)
async def morceau(self, evt: MessageEvent, pattern: str) -> None:
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
if not pattern:
await evt.respond(
"""
!chefmou morceau -> Donne un morceau aléatoire
!chefmou partition instru titre -> Renvoi le lien vers la partition de ce morceau pour cet instrument
"""
)
else:
self.log.info("Commande : " + pattern)
if pattern == "morceau":
soup = await self.get_site_content()
s = soup.findAll('th', background='/fond3.gif')
ps = random.choice(s)
await evt.respond(ps.text)
elif pattern.__contains__("part"):
chunks = pattern.split(None, 2)
if len(chunks) != 3 :
await evt.respond(
"""
!chefmou morceau -> Donne un morceau aléatoire
!chefmou partition instru titre -> Renvoi le lien vers la partition de ce morceau pour cet instrument
"""
)
loop.close()
return
soup = await self.get_site_content()
# Récuperer liste morceaux
#s = soup.select('th', background='/fond3.gif')
s = soup.select('th')
# Object bts en str
parsedList=[]
originalList=[]
for ts in s:
if ts.text in self.listRemove :
continue
fullTitre = ts.text
#Supression des ()
parsedList.append(re.sub("[\(\[].*?[\)\]]", "", fullTitre))
#On garde une copie pour la recherche
originalList.append(ts.text)
# Fonction qui retourne l'index du string le plus proche
idxTitre = self.get_close_matches_indexes(chunks[2], parsedList, cutoff=0.4)
# Si trouvé le chercher sinon erreur
if len(idxTitre) > 0 :
for el in idxTitre :
self.log.info(originalList[el] + ': ' + str(SequenceMatcher(None, chunks[2], parsedList[el]).ratio()))
#Et on recherche dans la liste originale avec le titre original
s = soup.find('th', string=originalList[idxTitre[0]])
t = s.parent.findAll('a')
idx = 25
if chunks[1].lower() == "souba" or chunks[1].lower() == "soubassophone" or chunks[1].lower() == "sb":
idx = 0
elif chunks[1].lower() == "basse" or chunks[1].lower() == "bs" :
idx = 1
elif chunks[1].lower() == "trombone" or chunks[1].lower() == "tb":
idx = 2
elif chunks[1].lower() == "trompette" or chunks[1].lower() == "tp":
idx = 3
elif chunks[1].lower() == "sax" or chunks[1].lower() == "saxophone":
idx = 4
elif chunks[1].lower() == "clarinette" or chunks[1].lower() == "cl":
idx = 5
else:
await evt.respond("Pas trouvé cet instru")
loop.close()
return
try :
await evt.respond("["+originalList[idxTitre[0]]+ " " + chunks[1]+"]"+"(<https://partoches.pustule.org"+t[idx].get("href")+">)")
except IndexError:
await evt.respond("Le morceau "+ originalList[idxTitre[0]] + " existe mais pas ta partoche")
else:
await evt.respond("Morceau non trouvé")
else:
await evt.respond("Nope !")
loop.close()