Compare commits

..

No commits in common. "425f921be7ac683ce3b2beaed729634cd829ad0e" and "feb10e85f34f83bd8f77a2368c22a0188e530655" have entirely different histories.

9 changed files with 21 additions and 144 deletions

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "pyzxz"]
path = pyzxz
url = https://git.yuki.k4w411.net/yuki/pyzxz

View file

@ -12,7 +12,5 @@ dead simple last.fm bot
- add database username checker to utils.py
- add collage generation
- fix attachment generation and upload
- ~~**temporary fix**: upload and link to catbox urls~~ the asynchronous catbox library does not accept byte arrays
- ~~**temporary fix**: construct the attachment object from scratch and upload manually(?)~~ its still broken
- **temporary fix:** use 0x0.st
- **permanent fix**: fork and update nerimity library
- temporary fix: upload and link to catbox urls
- permanent fix: fork and update nerimity library

25
bot.py
View file

@ -1,20 +1,13 @@
import os
import importlib
import aiosqlite
import nerimity
import pylast
import aiosqlite
from pyzxz.pyzxz.pyzxz import ZeroXZero # :sob:
from lastfmcollagegenerator.collage_generator import CollageGenerator
# from catbox_async_uploader.catbox_async_uploader.core import CatboxAsyncUploader
class Bot(nerimity.Client):
"""Extended client class for extra functionality."""
def __init__(self, lastfm_api_key: str, lastfm_api_secret: str,
owner_id: int = None, db_file: str = "database.db",
*args, **kwargs):
def __init__(self, lastfm_api_key: str, lastfm_api_secret: str, owner_id: int = None, db_file: str = "database.db", *args, **kwargs):
super().__init__(*args, **kwargs)
self.owner_id = owner_id
@ -25,22 +18,10 @@ class Bot(nerimity.Client):
api_secret = lastfm_api_secret
)
# initialize collage generator
self.collage_generator = CollageGenerator(
lastfm_api_key=lastfm_api_key,
lastfm_api_secret=lastfm_api_secret
)
# initialize catbox client
# self.catbox_uploader = CatboxAsyncUploader(userhash=catbox_hash)
# initialize 0x0 client
self.zxz = ZeroXZero("https://x0.at")
# database
self.db = None
self.db_file = db_file
def load_commands(self, commands_dir: str):
for filename in os.listdir(commands_dir):
if filename.endswith(".py") and not filename.startswith("_"):

View file

@ -6,6 +6,7 @@ import utils as u
def setup(bot: bot.Bot):
@bot.command(name="echo")
async def echo(ctx: nerimity.Context, *text: str):
print(bot.is_owner(ctx.author))
if not bot.is_owner(ctx.author):
print("returned")
return
@ -18,19 +19,9 @@ def setup(bot: bot.Bot):
print(e)
await ctx.send(u.error_msg(f"Unknown error:\n`{e}`"))
@bot.command(name="servercount", aliases=["sc"])
async def servercount(ctx: nerimity.Context):
if not bot.is_owner(ctx.author):
print("returned")
return
try: await ctx.send(f"I'm in {len(bot.servers)} servers!!")
except Exception as e:
print(e)
await ctx.send(u.error_msg(f"Unknown error:\n`{e}`"))
@bot.command(name="post")
async def post(ctx: nerimity.Context, *text: str):
print(bot.is_owner(ctx.author))
if not bot.is_owner(ctx.author):
print("returned")
return
@ -40,7 +31,6 @@ def setup(bot: bot.Bot):
try:
await ctx.send(f"Creating post:\n```markdown\n{" ".join(text)}\n```")
# TODO: post removal command :p
# post = nerimity.Post.create_post(content=" ".join(text))
# print(post)
await ctx.send(u.good_msg(f"Post created!!"))

View file

@ -1,64 +0,0 @@
import io
import nerimity
import bot
import utils as u
# from catbox_async_uploader.catbox_async_uploader.enums import LitterboxDuration
# from pyzxz import ZeroXZero
def setup(bot: bot.Bot):
@bot.command(name="chart", aliases=["c", "chartalbum", "albumchart", "collage"])
@bot.slash_command(name="chartalbum", description="Generate an album collage.")
async def chart_album(ctx: nerimity.Context, size: str = "5x5", timeframe: str = "7day", username: str = None):
if 'x' not in size:
await ctx.send(u.error_msg("Please provide a valid size.\nie `/chart album 5x5`"))
return
if not username:
try: username = await bot.get_lastfm(ctx.author.id)
except Exception as e:
print(e)
await ctx.send(u.error_msg(f"Unknown database error:\n{e}"))
if not username:
await ctx.send(u.error_msg("Please provide a Last.fm username (or set yours with `/setfm`)."))
print("returned")
return
try:
temp_msg = await ctx.send(f"Generating album chart for **{username}**...")
image = bot.collage_generator.generate(
entity = "album",
username = username,
rows = int(size.split(sep="x")[0]),
cols = int(size.split(sep="x")[1]),
period = timeframe
)
img_bytes = io.BytesIO()
image.save(fp=img_bytes, format="png")
# link = await bot.catbox_uploader.upload_to_litterbox(
# file_path_or_bytes = img_bytes,
# file_name = "collage.png",
# duration = LitterboxDuration.H12
# )
# attachment = await u.construct_attachment_from_bytes(
# filename = "chart",
# file_type = "png",
# bytes_arr = img_bytes,
# ).upload()
link = await bot.zxz.upload_from_bytes(img_bytes.getvalue(), "chart.png")
await ctx.send(u.good_msg(f"{size} Chart for {username} successfully generated:\n{link}"))
temp_msg.delete()
except Exception as e:
if temp_msg: temp_msg.delete()
print(e)
await ctx.send(u.error_msg(f"Unknown error:\n`{e}`"))

View file

@ -4,17 +4,16 @@ import bot
import utils as u
def setup(bot: bot.Bot):
@bot.command(name="setfm", aliases=["set", "setuser", "setlastfm"])
@bot.command(name="setfm", aliases=["setuser", "setlastfm"])
@bot.slash_command(name="setfm", description="Sets your Last.fm username.")
async def setfm(ctx: nerimity.Context, username: str = None):
if not username:
await ctx.send(u.error_msg("Please provide your Last.fm username.\n\
usage: `/fm <your last.fm username>`"))
return
try:
await bot.set_lastfm(ctx.author.id, username)
await ctx.send(u.good_msg(f"Your Last.fm user has been set to **{username}**!"))
except Exception as e:
print(e)
await ctx.send(u.error_msg("Unknown database error."))
else:
try:
await bot.set_lastfm(ctx.author.id, username)
await ctx.send(u.good_msg(f"Your Last.fm user has been set to **{username}**!"))
except Exception as e:
print(e)
await ctx.send(u.error_msg("Unknown database error."))

1
pyzxz

@ -1 +0,0 @@
Subproject commit 26559dd2707d92fc8f1740befb97ed0c32555e65

View file

@ -1,38 +1,30 @@
aiofiles==24.1.0
aiohappyeyeballs==2.6.1
aiohttp==3.10.10
aiohttp==3.13.0
aiosignal==1.4.0
aiosqlite==0.21.0
anyio==4.11.0
astroid==3.3.11
attrs==25.4.0
beautifulsoup4==4.12.3
certifi==2025.10.5
charset-normalizer==3.4.3
dill==0.4.0
frozenlist==1.8.0
h11==0.16.0
html5lib==1.1
httpcore==1.0.9
httpx==0.28.1
idna==3.10
isort==6.1.0
lastfmcollagegenerator==0.4.13
mccabe==0.7.0
multidict==6.7.0
nerimity==1.4.1
pillow==10.4.0
platformdirs==4.4.0
propcache==0.4.0
pylast==5.3.0
pylast==6.0.0
pylint==3.3.9
requests==2.32.3
six==1.17.0
requests==2.32.5
sniffio==1.3.1
soupsieve==2.8
tomlkit==0.13.3
typing_extensions==4.15.0
urllib3==2.5.0
webencodings==0.5.1
websockets==15.0.1
yarl==1.22.0

View file

@ -1,10 +1,9 @@
# import io
# import requests
# import mimetypes
import nerimity
# def construct_attachment_from_url(url: str = None) -> nerimity.Attachment | None:
# def construct_attachment_from_url(url: str = None):
# if not url: return None
# content = requests.get(url).content
@ -18,22 +17,8 @@ import nerimity
# return attachment
# def construct_attachment_from_bytes(filename: str = "file", bytes_arr: io.BytesIO = None, file_type: str = None) -> nerimity.Attachment | None:
# if not bytes_arr: return None
# if not file_type: return None
# attachment = nerimity.Attachment()
# attachment.internal_type = nerimity.AttachmentTypes.OUTGOING
# attachment.data = bytes_arr.read()
# attachment.data_type = file_type
# attachment.size = len(attachment.data)
# attachment.name = filename
# return attachment
def error_msg(message: str) -> str:
def error_msg(message: str):
return f"[#e5323b][Error] [#reset]{message}"
def good_msg(message: str) -> str:
def good_msg(message: str):
return f"[#52ff54][Success] [#reset]{message}"