Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[flake8]
ignore = F403
max-line-length = 88
ignore = B005,W503
23 changes: 23 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Taken from https://github.com/szskill/omnia
# Shameless promo?!
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.3.0
hooks:
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace

- repo: https://github.com/psf/black
rev: 21.12b0
hooks:
- id: black

- repo: https://github.com/pycqa/flake8
rev: 4.0.1
hooks:
- id: flake8
additional_dependencies:
- flake8-bugbear
- flake8-comprehensions
- flake8-simplify
1 change: 0 additions & 1 deletion .replit
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
run = "python3.8 -m pip install --disable-pip-version-check -r requirements.txt && python3.8 main.py"

18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,18 @@
# Phebe
A discord bot made by Python for the [Pythonic Hangout server](https://discord.gg/Q8kU6sB45K)

A Discord bot made by Python for the [Pythonic Hangout server](https://discord.gg/Q8kU6sB45K)

## Setting up a development environment

To set up an environment for development, just do `pre-commit install` and that
will install the pre-commit configurations in `.pre-commit-config.yaml`, which
will make sure all code is clean/valid.

## Running

To run, simply do `python main.py`.

## Creators

_on GitHub_
greyblue9, was07, szskill, Akshat-unt, Sarthak2143
2 changes: 1 addition & 1 deletion StayAlive.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def log_request(request):
for k, v in inspect.getmembers(request):
try:
log.info("%s=%s", k, v)
except:
except Exception:
log.info("%s=%s", k, type(v).__qualname__)


Expand Down
38 changes: 13 additions & 25 deletions base.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import inspect
import sys
from typing import Union

import disnake
from disnake import Role
from disnake.channel import ChannelType
from disnake.embeds import Embed
from disnake.ext import commands
Expand All @@ -12,7 +12,8 @@
from disnake.member import Member
from disnake.message import Message
from disnake.user import User
# for replit

# For repl.it
disnake
commands
Bot
Expand All @@ -26,34 +27,17 @@


def member_for(user: Union[User, Member]) -> Member:
"Return the full Member object corresponding to `user`."
print(f"member_for({user})")
"""Returns the full Member object corresponding to `user`."""

if isinstance(user, Member):
return user
from __main__ import bot

return
print(f"member_for(user={user}): looking for member with ID {user.id}")
for g in bot.guilds:
ids = [int(str(m.id)) for m in g.members]
if int(str(user.id)) in ids:
print(f"{g }{ids}")
matching = [m for m in g.members if m.id == user.id]
if matching:
return matching[0]
raise RuntimeError(f"uid {user} not found.")

def role_ames(user: Union[User, Member]) -> dict[str, Role]:
"Return a dict mapping role names to Role objects."
return {r.name: r for r in member_for(user).roles}


def setup(bot: commands.Bot):
"""
Needed for dynamic modules to work with load_extension
"""Needed for dynamic modules to work with load_extension
without requiring each to have a boilerplate setup()
function
"""
function"""

import builtins

if bot and "bot" not in vars(builtins):
Expand All @@ -62,7 +46,11 @@ def setup(bot: commands.Bot):
module_name = [k for k in sys.modules.keys() if k.startswith("commands")][-1]
class_name = module_name.split(".")[-1]
module = sys.modules.get(module_name)
cog_cls = getattr(module, class_name)
cog_cls = next(
v
for k, v in inspect.getmembers(module)
if k.lower() == class_name.lower() and inspect.isclass(v)
)
cog_obj = cog_cls(bot)
print(f"Loading extension comand: {class_name} ...", end="")
bot.add_cog(cog_obj)
Expand Down
41 changes: 0 additions & 41 deletions commands/Ban.py

This file was deleted.

51 changes: 51 additions & 0 deletions commands/ban.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
from base import Bot, commands, Context, Member, setup # noqa: F401


class Ban(commands.Cog):
"""The cog for (un)banning people"""

def __init__(self, bot: Bot) -> None:
self.bot = bot

@commands.command()
@commands.has_permissions(ban_members=True)
async def ban(
self, ctx: Context, member: Member, *, reason="No reason provided."
) -> None:
"""Bans a member."""

try:
await member.send(
f"You got banned from {ctx.guild.name} by {ctx.author} for reason: "
+ reason
)
except Exception:
await ctx.send("Can't send DM to the user")
finally:
await member.ban(reason=reason)
await ctx.send(f"**{member.name}** got banned successfully!")

@commands.command()
@commands.has_permissions(
ban_members=True,
)
async def unban(
self, ctx: Context, member_id: int = 0, *, reason="No reason provided."
) -> None:
"""Unbans a member."""
banned_users = await ctx.guild.bans()

for ban_entry in banned_users:
if member_id == ban_entry.user.id:
await ctx.guild.unban(ban_entry.user)
await ctx.guild.unban(
member_id,
reason=(
f"Unbanned by {ctx.author.display_name}"
+ f" (id={ctx.author.id})"
),
)

return await ctx.send(
f"Member with ID **{member_id}** got unbanned successfully!"
)
9 changes: 5 additions & 4 deletions commands/Fact.py → commands/fact.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
from disnake import Color
from base import *

from base import Bot, commands, Embed, Context, setup # noqa: F401
from factgen import random_fact


class Fact(commands.Cog):
"""The cog for facts."""

def __init__(self, bot: Bot):
super().__init__()
def __init__(self, bot: Bot) -> None:
self.bot = bot

@commands.command()
async def fact(self, ctx):
async def fact(self, ctx: Context) -> None:
"""Shows you a random fact."""

text, source = random_fact()
Expand All @@ -22,5 +22,6 @@ async def fact(self, ctx):
url=source,
color=Color.yellow(),
)

embed.set_footer(text=f"Source: {source}")
await ctx.reply("Here's your random fact!", embed=embed)
46 changes: 22 additions & 24 deletions commands/Help.py → commands/help.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,58 @@
from base import *
from init import Config
from logging import getLogger

import disnake
from disnake.ext.commands.help import Paginator
from disnake.ext.commands.core import Command

log = getLogger(__name__)

from base import commands, Embed, Bot, setup # noqa: F401
from init import Config

def override(func):
return func
log = getLogger(__name__)


class MyHelpCommand(commands.DefaultHelpCommand):
class PhebeHelpCommand(commands.DefaultHelpCommand):
"""The cog for the help command."""

def __init__(self, **options):
def __init__(self, **options) -> None:
self.clean_prefix = options.pop("prefix")
self.width = options.pop("width", 80)
self.indent = options.pop("indent", 2)
self.sort_commands = options.pop("sort_commands", False)
self.commands_heading = options.pop("commands_heading", "Commands:")
self.no_category = options.pop("no_category", "Python")
self.paginator = options.pop("paginator", Paginator())

super().__init__(**options)
self.context.bot = bot

@override
def get_command_signature(self, command):
self.context.bot = bot # noqa: F821

def get_command_signature(self, command) -> None:
return (
f"{self.clean_prefix}" f"{command.qualified_name} " f"{command.signature}"
)

async def send_bot_help(self, mapping):
async def send_bot_help(self, mapping) -> None:
embed = disnake.Embed(title="Help Panel")

for cog, commands in mapping.items():
commands = await self.filter_commands(commands, sort=True)
command_signatures = [self.get_command_signature(c) for c in commands]
for cog, cmds in mapping.items():
cmds = await self.filter_commands(commands, sort=True)
command_signatures = [self.get_command_signature(c) for c in cmds]
if command_signatures:
cog_name = getattr(cog, "qualified_name", "No Category")
txt = ""
for c in commands:
for c in cmds:
txt += "\n`" + self.get_command_signature(c) + "`"
embed.add_field(name=cog_name, value=txt)

channel = self.get_destination()
await channel.send(embed=embed)

async def send_cog_help(self, cog):
async def send_cog_help(self, cog) -> None:
commands: list[Command] = cog.get_commands()
print(commands)
return await super().send_cog_help(cog)

async def send_command_help(self, command):
async def send_command_help(self, command) -> None:
embed = disnake.Embed(title=self.get_command_signature(command))
embed.add_field(name="Help", value=command.help)
alias = command.aliases
Expand All @@ -62,7 +62,7 @@ async def send_command_help(self, command):
channel = self.get_destination()
await channel.send(embed=embed)

async def send_group_help(self, group):
async def send_group_help(self, group) -> None:
commands: list[Command] = group.commands
print(commands)

Expand All @@ -74,16 +74,14 @@ async def send_group_help(self, group):


class Help(commands.Cog):
@override
def __init__(self, bot: Bot):
def __init__(self, bot: Bot) -> None:
log.info("loading %s cog", type(self).__name__)
log.info("original help cmd: %s", bot.help_command)
self._original_help_command = bot.help_command
new_help_command = MyHelpCommand(prefix=Config.prefix)
new_help_command = PhebeHelpCommand(prefix=Config.prefix)
log.info("new help cmd: %s", new_help_command)
bot.help_command = new_help_command
bot.help_command.cog = self

@override
def cog_unload(self):
def cog_unload(self) -> None:
self.bot.help_command = self._original_help_command
Loading