Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Additions to bot plugins. #16

Open
wants to merge 10 commits into
base: dev
Choose a base branch
from
2 changes: 1 addition & 1 deletion hawkeye/core/bot.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
from asyncio.subprocess import STDOUT
import hikari
import lightbulb
from hawkeye.core.utils.Activity import Activity
Expand Down Expand Up @@ -41,7 +42,6 @@ async def on_started(self, _: hikari.StartedEvent) -> None:
asyncio.create_task(Activity(self).change_status())
print("Bot has started sucessfully.")


async def on_stopping(self, _: hikari.StoppingEvent) -> None:
print("Bot is stopping...")

Expand Down
30 changes: 30 additions & 0 deletions hawkeye/core/plugins/admin/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from bisect import insort_right
import logging
import hikari
import lightbulb

from hawkeye.core.bot import Hawkeye
# from hawkeye.core.utils.Activity import Activity

adminPlugin= lightbulb.Plugin("admin", description="Handles Admin Plugins")
adminPlugin.add_checks(
lightbulb.has_guild_permissions(hikari.Permissions.ADMINISTRATOR)
)

## Ping
@adminPlugin.command
@lightbulb.command("ping", "Shares bot latency.")
async def ping(ctx: lightbulb.Context) -> None:
await ctx.respond(f"Latency: {ctx.bot.heartbeat_latency * 1_000:,.0f} ms.")

## Shutdown
@adminPlugin.command
@lightbulb.command("shutdown", "Shuts down the bot.")
async def shutdown(ctx: lightbulb.Context) -> None:
await ctx.bot.close(force=False)

def load(bot: lightbulb.BotApp) -> None:
bot.add_plugin(adminPlugin)

def unload(bot: lightbulb.BotApp) -> None:
bot.remove_plugin(adminPlugin)
37 changes: 37 additions & 0 deletions hawkeye/core/plugins/admin/error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import logging

import hikari
import lightbulb
from lightbulb import plugins
from hawkeye.core.bot import Hawkeye

errorPlugin = lightbulb.Plugin("error")

@errorPlugin.command
@plugins.listener()
async def on_error(self, event: hikari.ExceptionEvent) -> None:
logging.error("An error has occured.")

async def on_command_error(self, event: lightbulb.CommandErrorEvent) -> None:
if isinstance(event.exception, lightbulb.errors.CommandNotFound):
return None

if isinstance(event.exception, lightbulb.errors.NotEnoughArguments):
return await event.context.respond(
"There are some missing arguments: " + ", ".join(event.exception.missing_options)
)

if isinstance(event.exception, lightbulb.errors.CommandIsOnCooldown):
return await event.context.respond(f"Command is on cooldown. Try again in {event.exception.retry_after:.0f} seconds.")

if isinstance(event.exception, lightbulb.errors.CommandInvocationError):
raise event.exception.original

await event.context.respond("An error has occured. Reponses not found.")
raise event.exception

def load(bot: lightbulb.BotApp) -> None:
bot.add_plugin(errorPlugin)

def unload(bot: lightbulb.BotApp) -> None:
bot.remove_plugin(errorPlugin)
63 changes: 63 additions & 0 deletions hawkeye/core/plugins/admin/moderation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from typing import Tuple
import hikari
import lightbulb
import re
import datetime

from time import time
from datetime import timedelta
from lightbulb import commands, context

modPlugin = lightbulb.Plugin("Mod")

## Mute
@modPlugin.command
@lightbulb.add_checks(lightbulb.has_guild_permissions(hikari.Permissions.MODERATE_MEMBERS))
@lightbulb.option("reason", "Reason for mute. Will show up in Audit log.", type = str, modifier = lightbulb.OptionModifier.CONSUME_REST, required = True)
@lightbulb.option("duration", "Time muted for.", str, required = True)
@lightbulb.option("user", "User to mute.", hikari.User, required = True)
@lightbulb.command("mute", "Mutes a user.", auto_defer = True)
@lightbulb.implements(commands.PrefixCommand, commands.SlashCommand)
async def mute(ctx : context.Context) -> None:
target = ctx.options.user
reason = ctx.options.reason
duration = ctx.options.duration
target = ctx.get_guild().get_member(target)

time_pattern = r"(\d+\.?\d?[s|m|h|d|w]{1})\s?"

units = {
's': 'seconds',
'm': 'minutes',
'h': 'hours',
'd': 'days',
'w': 'weeks'
}

def parse(time_string: str) -> Tuple[str, float]:
unit = time_string[-1]
amount = float(time_string[:-1])
return units[unit], amount

if matched := re.findall(time_pattern, duration, flags=re.I):
time_dict = dict(parse(match) for match in matched)
time_s = int(timedelta(**time_dict).total_seconds())
else:
raise ("Invalid string format. Time must be in the form <number>[s|m|h|d|w].")

if not 1 <= time_s <= 2_419_200:
await ctx.respond("Mute duration must be between 1 second and 28 days.")
return

await target.edit(
communication_disabled_until = (datetime.datetime.utcnow() + datetime.timedelta(seconds=time_s)).isoformat(),
reason = reason
)

await ctx.respond(f"Muted {target.mention} until <t:{int(time())+time_s}>")

def load(bot: lightbulb.BotApp) -> None:
bot.add_plugin(modPlugin)

def unload(bot: lightbulb.BotApp) -> None:
bot.remove_plugin(modPlugin)
23 changes: 0 additions & 23 deletions hawkeye/core/plugins/admin/testingExtension.py

This file was deleted.

157 changes: 157 additions & 0 deletions hawkeye/core/plugins/common/external.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import hikari
from hikari import Color
import lightbulb
import wikipedia

import datetime as dt
from datetime import datetime, time, timedelta
from wikipedia import exceptions

from wikipedia.wikipedia import languages


externalPlugin = lightbulb.Plugin("External")

##Hawkye Github repo
@externalPlugin.command
@lightbulb.command("src", "Returns main Hawkeye repo.")
@lightbulb.implements(lightbulb.PrefixCommand, lightbulb.SlashCommand)
async def src(ctx: lightbulb.Context) -> None:
await ctx.respond(f"<https://github.com/MU-Enigma/Hawkeye>")
async def src(ctx: lightbulb.SlashContext) -> None:
await ctx.respond(f"<https://github.com/MU-Enigma/Hawkeye>")

## Sends link to Enigma Github
@externalPlugin.command
@lightbulb.command("git", "Returns the Enigma Github")
@lightbulb.implements(lightbulb.PrefixCommand, lightbulb.SlashCommand)
async def src(ctx: lightbulb.Context) -> None:
await ctx.respond(f"<https://github.com/MU-Enigma/>")
async def src(ctx: lightbulb.SlashContext) -> None:
await ctx.respond(f"<https://github.com/MU-Enigma/>")

## Sends link to Enigma website
@externalPlugin.command
@lightbulb.command("website", "Returns the Enigma website")
@lightbulb.implements(lightbulb.PrefixCommand, lightbulb.SlashCommand)
async def src(ctx: lightbulb.Context) -> None:
await ctx.respond(f"<https://mu-enigma.github.io/>")
async def src(ctx: lightbulb.SlashContext) -> None:
await ctx.respond(f"<https://mu-enigma.github.io/>")

## Google search
@externalPlugin.command
@lightbulb.option("query", "The thing to search.")
@lightbulb.command("google", "Let me Google that for you...")
@lightbulb.implements(lightbulb.PrefixCommand, lightbulb.SlashCommand)
async def google(ctx: lightbulb.Context) -> None:
q = ctx.options.query

if len(q) > 500:
await ctx.respond("Your query should be no longer than 500 characters.")
return

await ctx.respond(f"<https://letmegooglethat.com/?q={q.replace(' ', '+')}>")

async def google(ctx: lightbulb.SlashContext) -> None:
q = ctx.options.query

if len(q) > 500:
await ctx.respond("Your query should be no longer than 500 characters.")
return

await ctx.respond(f"<https://letmegooglethat.com/?q={q.replace(' ', '+')}>")

## DuckDuckGo search
@externalPlugin.command
@lightbulb.option("query", "The thing to search.")
@lightbulb.command("duckduckgo", "Let me Duck Duck Go that for you...")
@lightbulb.implements(lightbulb.PrefixCommand, lightbulb.SlashCommand)
async def duckduckgo(ctx: lightbulb.Context) -> None:
q = ctx.options.query

if len(q) > 500:
await ctx.respond("Your query should be no longer than 500 characters.")
return

await ctx.respond(f"<https://lmddgtfy.net/?q={q.replace(' ', '+')}>")

async def duckduckgo(ctx: lightbulb.SlashContext) -> None:
q = ctx.options.query

if len(q) > 500:
await ctx.respond("Your query should be no longer than 500 characters.")
return

await ctx.respond(f"<https://lmddgtfy.net/?q={q.replace(' ', '+')}>")

## Wikipedia search
@externalPlugin.command()
@lightbulb.set_help("Search wikipedia.")
@lightbulb.option("query", "The thing to search.")
@lightbulb.command(name="wikipedia", aliases=("wiki","wk"), description="Search a target in wikipedia.")
@lightbulb.implements(lightbulb.SlashCommand)
async def command_wikipedia(ctx: lightbulb.SlashContext) -> None:
try:
message = await ctx.respond("Searching...")
page = wikipedia.page(ctx.options.search)
image = page.images[0]
title = page.title
content = page.content

if len(content) > 600:
content = content[:600] + "...(READ MORE click on the title)"

else:
content = content

title_link = title.replace(" ", "_")
embed = (hikari.Embed(
colour=Color(0x3B9DFF),
description=content,
timestamp=dt.datetime.now().astimezone()

)
.set_image(image)
.set_author(name=title,url=f"https://en.wikipedia.org/wiki/{title_link}")
)
await ctx.respond(embed, reply=True)
await message.delete()

except(wikipedia.exceptions.DisambiguationError):
await message.edit(content="Try to be clearer with the search, multiple results found.")

except(wikipedia.exceptions.PageError):
await message.edit(content="Page not found.")

except(wikipedia.exceptions.HTTPTimeoutError):
await message.edit(content="The servers seem to be down. Please try again later.")

## Reddit search
@externalPlugin.command
@lightbulb.option("query", "The thing to search.")
@lightbulb.command("reddit", "Searching on Reddit.")
@lightbulb.implements(lightbulb.PrefixCommand, lightbulb.SlashCommand)
async def reddit(ctx: lightbulb.Context) -> None:
q = ctx.options.query

if len(q) > 50:
await ctx.respond("Your query should be no longer than 50 characters.")
return

await ctx.respond(f"<https://www.reddit.com/search.json?q={q.replace(' ', '+')}>")

async def duckduckgo(ctx: lightbulb.SlashContext) -> None:
q = ctx.options.query

if len(q) > 50:
await ctx.respond("Your query should be no longer than 50 characters.")
return

await ctx.respond(f"<https://www.reddit.com/search.json?q={q.replace(' ', '+')}>")

def load(bot: lightbulb.BotApp) -> None:
bot.add_plugin(externalPlugin)

def unload(bot: lightbulb.BotApp) -> None:
bot.remove_plugin(externalPlugin)
Loading