Merge branch 'KanjiSearch'

This commit is contained in:
Robert 2020-08-11 18:33:12 +02:00
commit f67d8d0106
4 changed files with 182 additions and 8 deletions

3
.gitignore vendored
View file

@ -1,3 +1,4 @@
.vscode
__pycache__
*.json
*.json
*.html

91
cogs/kanji.py Normal file
View file

@ -0,0 +1,91 @@
import discord
from discord.ext import commands
from utils import jisho
class JishoKanjiObject():
def __init__(self, query, owner):
self.response = jisho.JishoKanji(query)
self.total_pages = self.response.entries
self.page = 0
self.owner = owner
def prev(self):
self.page -= 1
if self.page < 0:
self.page = self.total_pages - 1
def next(self):
self.page += 1
if self.page >= self.total_pages:
self.page = 0
class Kanji(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.activeObject = None
self.latestMessage = 0
async def createEmbed(self):
response = self.activeObject.response
node = response.nodes[self.activeObject.page]
embed = discord.Embed(
title = node.kanji,
url = node.url,
description = node.meaning,
colour = 0x56d926
)
if node.kun:
embed.add_field(name="Kun", value="".join(node.kun), inline=False)
if node.on:
embed.add_field(name="On", value="".join(node.on), inline=False)
embed.add_field(name=f"Radical: {node.radical[0]}", value=node.radical[1], inline=False)
embed.set_footer(text=f"Jōyō kanji (Grade {node.grade}) | JLPT level {node.jlpt}\t\t{self.activeObject.page + 1}/{self.activeObject.total_pages}")
return embed
@commands.Cog.listener()
async def on_reaction_add(self, reaction, user):
message = reaction.message
if message.id != self.latestMessage:
return
if user == self.bot.user:
return
if user.id != self.activeObject.owner:
return
if reaction.me:
if reaction.emoji == "⬅️":
self.activeObject.prev()
await reaction.remove(user)
if reaction.emoji == "➡️":
self.activeObject.next()
await reaction.remove(user)
embed = await self.createEmbed()
await message.edit(embed=embed)
@commands.command(name="kanji", description="Performs a Kanji search", usage="<kanji>", aliases=["k"])
@commands.cooldown(1, 5)
async def kanji(self, ctx, *, kanji: str = None):
if kanji is None:
return
self.activeObject = JishoKanjiObject(kanji, ctx.author.id)
embed = await self.createEmbed()
message = await ctx.send(embed=embed)
self.latestMessage = message.id
if self.activeObject.total_pages > 1:
await message.add_reaction("⬅️")
await message.add_reaction("➡️")
def setup(bot):
bot.add_cog(Kanji(bot))

View file

@ -3,10 +3,11 @@ from discord.ext import commands
from utils import jisho
class JishoObject():
def __init__(self, query):
def __init__(self, query, owner):
self.response = jisho.JishoResponse(query)
self.total_pages = self.response.entries
self.page = 0
self.owner = owner
def prev(self):
self.page -= 1
@ -71,18 +72,21 @@ class Search(commands.Cog):
if user == self.bot.user:
return
if user.id != self.activeObject.owner:
return
if reaction.me:
if reaction.emoji == "⬅️":
self.activeObject.prev()
await reaction.remove(user)
if reaction.emoji == "➡️":
self.activeObject.next()
await reaction.remove(user)
embed = await self.createEmbed()
await message.edit(embed=embed)
await reaction.remove(user)
@commands.command(name="search", description="Searches Jisho", usage="<query>", aliases=["s"])
@commands.cooldown(1, 5)
@ -90,7 +94,7 @@ class Search(commands.Cog):
if query == None:
return
self.activeObject = JishoObject(query)
self.activeObject = JishoObject(query, ctx.author.id)
embed = await self.createEmbed()
message = await ctx.send(embed=embed)
self.latestMessage = message.id

View file

@ -1,14 +1,17 @@
import requests
import urllib.parse
import json
import re
from bs4 import BeautifulSoup
TEMPLATE_URL = "https://jisho.org/api/v1/search/words?keyword={0}"
TEMPLATE_KANJI_URL = "https://jisho.org/search/{0}"
HEADER = {
"User-Agent": "Jisho Bot",
"From": "https://github.com/Lauchmelder23/JishoBot"
}
class JishoSenses():
class JishoSense():
def __init__(self, sense):
self.english_definitions = sense["english_definitions"]
self.fenglish_definitions = "; ".join(self.english_definitions)
@ -52,7 +55,7 @@ class JishoNode():
self.senses = []
for sense in node["senses"]:
self.senses.append(JishoSenses(sense))
self.senses.append(JishoSense(sense))
class JishoResponse():
def __init__(self, query: str):
@ -63,7 +66,7 @@ class JishoResponse():
def query(self):
url = TEMPLATE_URL.format(urllib.parse.quote_plus(self.query_string))
r = requests.get(url)
r = requests.get(url, headers=HEADER)
if r.status_code != 200:
print(f"ERROR: Failed to access Jisho API... {r.status_code}")
@ -78,3 +81,78 @@ class JishoResponse():
for node in self.raw["data"]:
self.nodes.append(JishoNode(node))
class JishoKanjiNode():
def __init__(self):
# Information about the Kanji
self.kanji = ""
self.url = "https://jisho.org/search/"
self.meaning = ""
self.kun = []
self.on = []
self.radical = []
self.grade = ""
self.jlpt = ""
class JishoKanji():
def __init__(self, query):
self.query_string = query
# List of JishoKanjiNodes
self.nodes = []
self.entries = 0
self.query()
def query(self):
self.url = TEMPLATE_KANJI_URL.format(urllib.parse.quote_plus(self.query_string + "#kanji"))
r = requests.get(self.url, headers=HEADER)
if r.status_code != 200:
print(f"ERROR: Failed to access Jisho API... {r.status_code}")
return None
body = BeautifulSoup(r.text, features="html.parser")
info_blocks = body.find_all("div", {"class": "kanji details"})
for info in info_blocks:
self.entries += 1
self.nodes.append(JishoKanjiNode())
self.nodes[-1].kanji = info.findChild("h1").string
self.nodes[-1].url += urllib.parse.quote_plus(self.nodes[-1].kanji + "#kanji")
# Meanings
self.nodes[-1].meaning = info.findChild("div", {"class": "kanji-details__main-meanings"}, recursive=True).string
readings_block = info.findChild("div", {"class": "kanji-details__main-readings"}, recursive=True)
# Kun Yomi
kun_block = readings_block.findChild("dl", {"class": "dictionary_entry kun_yomi"}, recursive=True)
if kun_block != None:
readings = kun_block.findChildren("a", recursive=True)
for reading in readings:
self.nodes[-1].kun.append(reading.string)
# On Yomi
on_block = readings_block.findChild("dl", {"class": "dictionary_entry on_yomi"}, recursive=True)
if on_block != None:
readings = on_block.findChildren("a", recursive=True)
for reading in readings:
self.nodes[-1].on.append(reading.string)
# Radical
radical_block = info.findChild("div", {"class": "radicals"}, recursive=True).findChild("span")
self.nodes[-1].radical.append(re.sub(r'[ \n"]', "", radical_block.contents[2].string))
self.nodes[-1].radical.append(re.sub(r'[ \n"]', "", radical_block.contents[1].string))
# JLPT/Grade info
grade_block = info.findChild("div", {"class": "grade"}, recursive=True)
if grade_block != None:
self.nodes[-1].grade = grade_block.findChild("strong").string[-1]
self.nodes[-1].jlpt = info.findChild("div", {"class": "jlpt"}, recursive=True).findChild("strong").string