commit fd9381e746acbd1d669c82c25c49872d622c4469 Author: Infinidoge Date: Mon Sep 16 10:46:23 2024 -0400 init diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..944d27b --- /dev/null +++ b/.envrc @@ -0,0 +1,2 @@ +watch_file "flake.nix" "pyproject.toml" +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..db7b6ab --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Secrets +.env + +# Nix +.direnv/ +result + +# Python +.ruff_cache +.ropeproject diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..49227da --- /dev/null +++ b/flake.lock @@ -0,0 +1,160 @@ +{ + "nodes": { + "devshell": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1722113426, + "narHash": "sha256-Yo/3loq572A8Su6aY5GP56knpuKYRvM2a1meP9oJZCw=", + "owner": "numtide", + "repo": "devshell", + "rev": "67cce7359e4cd3c45296fb4aaf6a19e2a9c757ae", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "devshell", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1726153070, + "narHash": "sha256-HO4zgY0ekfwO5bX0QH/3kJ/h4KvUDFZg8YpkNwIbg1U=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "bcef6817a8b2aa20a5a6dbb19b43e63c5bf8619a", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "mdbook-nixdoc": { + "inputs": { + "nix-github-actions": [ + "pyproject-nix", + "nix-github-actions" + ], + "nixpkgs": [ + "pyproject-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1708395692, + "narHash": "sha256-smf0VmxGbjJDZqKvxxG3ZVqubgbVwAWG26wPo+BT/A0=", + "owner": "adisbladis", + "repo": "mdbook-nixdoc", + "rev": "d6a71b114b9221c0b4f20d31b81766d072cc26be", + "type": "github" + }, + "original": { + "owner": "adisbladis", + "repo": "mdbook-nixdoc", + "type": "github" + } + }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "pyproject-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1720066371, + "narHash": "sha256-uPlLYH2S0ACj0IcgaK9Lsf4spmJoGejR9DotXiXSBZQ=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "622f829f5fe69310a866c8a6cd07e747c44ef820", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1726290927, + "narHash": "sha256-rYsIuLdt0veLhFuHWtGqg3mMGWBVQ5ZguoWiaW1VFkE=", + "owner": "Infinidoge", + "repo": "nixpkgs", + "rev": "ca826eb1b50f8452ae6788d69db7b7254c0268bc", + "type": "github" + }, + "original": { + "owner": "Infinidoge", + "ref": "feat/disnake", + "repo": "nixpkgs", + "type": "github" + } + }, + "pyproject-nix": { + "inputs": { + "mdbook-nixdoc": "mdbook-nixdoc", + "nix-github-actions": "nix-github-actions", + "nixpkgs": [ + "nixpkgs" + ], + "treefmt-nix": "treefmt-nix" + }, + "locked": { + "lastModified": 1726093189, + "narHash": "sha256-aPzd6M1k1H0C2zoMlSfAdTg4Za+WfB8Qj+OAbQAVAMs=", + "owner": "nix-community", + "repo": "pyproject.nix", + "rev": "6c56846759ba16382bc2bdbee42c2f56c21654be", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "pyproject.nix", + "type": "github" + } + }, + "root": { + "inputs": { + "devshell": "devshell", + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs", + "pyproject-nix": "pyproject-nix" + } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "pyproject-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1724833132, + "narHash": "sha256-F4djBvyNRAXGusJiNYInqR6zIMI3rvlp6WiKwsRISos=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "3ffd842a5f50f435d3e603312eefa4790db46af5", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..19ad4ef --- /dev/null +++ b/flake.nix @@ -0,0 +1,64 @@ +{ + inputs = { + nixpkgs.url = "github:Infinidoge/nixpkgs/feat/disnake"; + flake-parts.url = "github:hercules-ci/flake-parts"; + devshell.url = "github:numtide/devshell"; + pyproject-nix.url = "github:nix-community/pyproject.nix"; + + flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; + devshell.inputs.nixpkgs.follows = "nixpkgs"; + pyproject-nix.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ "x86_64-linux" ]; + + imports = with inputs; [ + devshell.flakeModule + ]; + + perSystem = { config, pkgs, ... }: + let + project = inputs.pyproject-nix.lib.project.loadPyproject { + projectRoot = ./.; + }; + + python = pkgs.python3; + + in + { + packages.default = (python.pkgs.buildPythonPackage ( + project.renderers.buildPythonPackage { inherit python; } + )).overrideAttrs { allowSubstitutes = false; preferLocalBuild = true; }; + + devshells.default = + let + env = python.withPackages ( + project.renderers.withPackages { + inherit python; + extraPackages = p: with p; [ + python-lsp-server + python-lsp-ruff + pylsp-rope + isort + black + ]; + } + ); + in + { + devshell = { + name = "nomen"; + motd = ""; + + packages = [ + env + ]; + }; + env = [ + { name = "PYTHONPATH"; prefix = "${env}/${env.sitePackages}"; } + ]; + }; + }; + }; +} diff --git a/nomen/__init__.py b/nomen/__init__.py new file mode 100644 index 0000000..86966d1 --- /dev/null +++ b/nomen/__init__.py @@ -0,0 +1 @@ +from .main import run diff --git a/nomen/main.py b/nomen/main.py new file mode 100644 index 0000000..dc63e32 --- /dev/null +++ b/nomen/main.py @@ -0,0 +1,137 @@ +import logging +import os +import sys + +import aiosqlite as sqlite +from disnake import Guild, Intents, Message +from disnake.ext import commands +from disnake.ext.commands import Bot +from dotenv import find_dotenv, load_dotenv + +# Logger setup +logger_disnake = logging.getLogger("disnake") +logger_disnake.setLevel(logging.INFO) + +log = logging.getLogger("nomen") +log.setLevel(logging.DEBUG) + +formatter = logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s") +handler = logging.StreamHandler(sys.stdout) +handler.setFormatter(formatter) +logger_disnake.addHandler(handler) +log.addHandler(handler) + +if load_dotenv(find_dotenv(usecwd=True)): + log.info("Loaded .env") +else: + log.debug("Didn't find .env") + +TOKEN = os.getenv("TOKEN") +DEFAULT_PREFIX = os.getenv("DEFAULT_PREFIX") or ">" + + +async def get_prefix(the_bot, message: Message): + if not message.guild: + return commands.when_mentioned_or(DEFAULT_PREFIX)(the_bot, message) + gp = await the_bot.get_guild_prefix(message.guild) + return commands.when_mentioned_or(gp)(the_bot, message) + + +class Nomen(Bot): + def __init__(self, prefix, description=None, **options): + super().__init__( + prefix, + description=description, + command_sync_flags=options.get("sync_flags"), + allowed_mentions=options.get("allowed_mentions"), + intents=options.get("intents"), + ) + + # self.db = self.loop.run_until_complete(sqlite.connect("nomen.db")) + self.prefixes = {} + + async def get_guild_prefix(self, guild: Guild): + if guild.id in self.prefixes: + return self.prefixes[guild.id] + # FIXME: Fetch with SQLite + + # self.prefixes[guild.id] = prefix + return DEFAULT_PREFIX + + async def set_guild_prefix(self, guild: Guild, prefix): + # FIXME: Fetch with SQLite + self.prefixes[guild.id] = prefix + + async def close(self): + await super().close() + await self.db.close() + + +bot = Nomen( + prefix=get_prefix, + description="Keeper of Names", + intents=Intents( + guilds=True, + messages=True, + message_content=True, + ), + sync_flags=commands.CommandSyncFlags( + sync_commands=False, + ), +) + + +@bot.event +async def on_ready(): + log.info("Logged in as:") + log.info(bot.user) + log.info(bot.user.id) + log.info("-------------") + + +@bot.event +async def on_command_error(ctx, error): + if isinstance(error, commands.CommandNotFound): + return + + +async def handle_triggers(ctx, message): + log.debug(f"Handling triggers for message '{ctx.message.content}'") + + +@bot.event +async def on_message(message): + if message.author == bot.user: + return + + ctx = await bot.get_context(message) + if ctx.valid: + await bot.invoke(ctx) + else: + await handle_triggers(ctx, message) + + +@bot.command() +@commands.check(commands.is_owner()) +async def echo(ctx, arg): + await ctx.send(arg) + + +@bot.command() +async def ping(ctx): + await ctx.send("Pong") + + +@bot.command() +@commands.check(commands.guild_only()) +async def prefix(ctx, prefix=None): + if not prefix: + prefix = await ctx.bot.get_guild_prefix(ctx.guild) + await ctx.send(f"{ctx.guild.name} prefix is `{prefix}`") + else: + await ctx.bot.set_guild_prefix(ctx.guild, prefix) + await ctx.send(f"Set {ctx.guild.name} prefix to `{prefix}`") + + +def run(): + bot.run(TOKEN) diff --git a/nomen/notifications.py b/nomen/notifications.py new file mode 100644 index 0000000..d94fdc4 --- /dev/null +++ b/nomen/notifications.py @@ -0,0 +1,15 @@ +from discord.ext.commands import Cog, command + +class User: + def __init__(self, ...): + pass + +class Notifications(Cog): + def __init__(self, bot): + self.bot = bot + + @Cog.listener() + async def on_message(self, message): + ctx = self.bot.get_context(message) + if ctx.valid: return + await handle_triggers(message) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..f22886a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,18 @@ +[project] +name = "nomen" +version = "0.0.1" +dependencies = [ + "disnake", + "python-dotenv", + "aiosqlite" +] + +[project.scripts] +nomen = "nomen:run" + +[tool.setuptools.packages] +find = {} + +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta"