# _____ _ # / ____| (_) # | (___ ___ __ _ _____ ___ _ __ ___ _ __ ___ ___ _ __ # \___ \ / _ \/ _` / __\ \ /\ / / | '_ ` _ \| '_ ` _ \ / _ \ '__| # ____) | __/ (_| \__ \\ V V /| | | | | | | | | | | | __/ | # |_____/ \___|\__,_|___/ \_/\_/ |_|_| |_| |_|_| |_| |_|\___|_| import aiohttp import json import logging from discord import Embed from redbot.core import commands, Config from redbot.core.bot import Red class Bible(commands.Cog): """Retrieve Bible verses from the API.bible API.""" __author__ = "SeaswimmerTheFsh" __version__ = "1.0.0" def __init__(self, bot: Red): super().__init__() self.bot = bot self.session = aiohttp.ClientSession() self.config = Config.get_conf(self, identifier=481923957134912, force_registration=True) self.logger = logging.getLogger("red.sea.bible") self.config.register_global(bible="de4e12af7f28f599-01") self.config.register_user(bible=None) async def translate_book_name(self, bible_id: str, book_name: str) -> str: """Translate a book name to a book ID.""" book_name = book_name.title() books = await self._get_books(bible_id) for book in books: if book_name == book['abbreviation'] or book_name == book['name']: return book['id'] raise ValueError(f"Book {book_name} not found.") async def _get_passage(self, bible_id: str, passage_id: str) -> dict: """Get a Bible passage from the API.bible API.""" url = f"https://api.scripture.api.bible/v1/bibles/{bible_id}/passages/{passage_id}?content-type=text&include-notes=false&include-titles=false&include-chapter-numbers=false&include-verse-numbers=true&include-verse-spans=false&use-org-id=false" headers = await self.bot.get_shared_api_tokens("api.bible") async with self.session.get(url, headers=headers) as response: data = await response.json() self.logger.debug(passage_id) self.logger.debug(json.dumps(data)) return data["data"] async def _get_books(self, bible_id: str) -> dict: """Get the books of the Bible from the API.bible API.""" url = f"https://api.scripture.api.bible/v1/bibles/{bible_id}/books" headers = await self.bot.get_shared_api_tokens("api.bible") async with self.session.get(url, headers=headers) as response: data = await response.json() return data["data"] @commands.group(autohelp=True) async def bible(self, ctx: commands.Context): """Core command for the Bible cog.""" @bible.command(name="verse") async def bible_verse(self, ctx: commands.Context, book: str, chapter: int, verse: int) -> str: """Get a Bible verse.""" bible_id = await self.config.bible() try: book_id = await self.translate_book_name(bible_id, book) except ValueError as e: await ctx.send(str(e)) return passage = await self._get_passage(bible_id, f"{book_id}.{chapter}.{verse}") embed = Embed(title=f"{passage['reference']}", description=passage["content"].replace('¶ ', ''), color=await self.bot.get_embed_color(ctx.channel)) embed.set_footer(text=f"{ctx.prefix}bible verse - Powered by API.bible") await ctx.send(embed=embed) @bible.command(name="passage") async def bible_passage(self, ctx: commands.Context, book: str, passage: str): """Get a Bible passage. Example usage: `[p]bible passage John 3:16-3:17`""" bible_id = await self.config.bible() try: book_id = await self.translate_book_name(bible_id, book) except ValueError as e: await ctx.send(str(e)) return if len(passage.split('-')) == 2: from_verse, to_verse = passage.replace(":", ".").split("-") if '.' not in to_verse: to_verse = f"{from_verse.split('.')[0]}.{to_verse}" passage = await self._get_passage(bible_id, f"{book_id}.{from_verse}-{book_id}.{to_verse}") else: passage = await self._get_passage(bible_id, f"{book_id}.{passage.replace(':', '.')}") if len(passage["content"]) > 4096: await ctx.send("The passage is too long to send.") return embed = Embed(title=f"{passage['reference']}", description=passage["content"].replace('¶ ', ''), color=await self.bot.get_embed_color(ctx.channel)) embed.set_footer(text=f"{ctx.prefix}bible passage - Powered by API.bible") await ctx.send(embed=embed)