158 lines
6.6 KiB
Python
158 lines
6.6 KiB
Python
import discord
|
|
import aiohttp
|
|
from datetime import datetime, timedelta
|
|
import asyncio
|
|
from redbot.core import commands, Config, checks
|
|
|
|
BASE_URL = "https://api.modrinth.com/v2"
|
|
|
|
class ModrinthTracker(commands.Cog):
|
|
def __init__(self, bot):
|
|
self.bot = bot
|
|
self.config = Config.get_conf(self, identifier=1234567890, force_registration=True)
|
|
self.config.register_guild(tracked_projects={})
|
|
self.session = None
|
|
self.bg_task = None
|
|
|
|
async def cog_load(self):
|
|
self.session = aiohttp.ClientSession()
|
|
self.bg_task = self.bot.loop.create_task(self.update_checker())
|
|
|
|
async def cog_unload(self):
|
|
if self.session:
|
|
await self.session.close()
|
|
if self.bg_task:
|
|
self.bg_task.cancel()
|
|
|
|
@commands.group()
|
|
@checks.admin()
|
|
async def modrinth(self, ctx):
|
|
"""Commands for tracking Modrinth projects"""
|
|
if ctx.invoked_subcommand is None:
|
|
await ctx.send_help()
|
|
|
|
@modrinth.command()
|
|
async def add(self, ctx, project_id: str, channel: discord.TextChannel):
|
|
"""Add a Modrinth project to track
|
|
|
|
Arguments:
|
|
project_id: The Modrinth project ID or slug
|
|
channel: The channel to send updates to
|
|
"""
|
|
try:
|
|
# Verify the project exists and get its info
|
|
async with self.session.get(f"{BASE_URL}/project/{project_id}") as response:
|
|
if response.status != 200:
|
|
await ctx.send(f"Error: Project `{project_id}` not found on Modrinth.")
|
|
return
|
|
project_data = await response.json()
|
|
|
|
# Get the latest version
|
|
async with self.session.get(f"{BASE_URL}/project/{project_id}/version") as response:
|
|
if response.status != 200:
|
|
await ctx.send("Error: Could not fetch version information.")
|
|
return
|
|
versions = await response.json()
|
|
latest_version = versions[0] if versions else None
|
|
|
|
tracked_projects = await self.config.guild(ctx.guild).tracked_projects()
|
|
if project_id in tracked_projects:
|
|
await ctx.send("This project is already being tracked.")
|
|
return
|
|
|
|
tracked_projects[project_id] = {
|
|
"channel": channel.id,
|
|
"latest_version": latest_version["id"] if latest_version else None,
|
|
"name": project_data["title"]
|
|
}
|
|
await self.config.guild(ctx.guild).tracked_projects.set(tracked_projects)
|
|
await ctx.send(f"Now tracking {project_data['title']} (`{project_id}`) in {channel.mention}.")
|
|
|
|
except Exception as e:
|
|
await ctx.send(f"An error occurred while adding the project: {str(e)}")
|
|
|
|
@modrinth.command()
|
|
async def remove(self, ctx, project_id: str):
|
|
"""Remove a tracked Modrinth project
|
|
|
|
Arguments:
|
|
project_id: The Modrinth project ID or slug to stop tracking
|
|
"""
|
|
tracked_projects = await self.config.guild(ctx.guild).tracked_projects()
|
|
if project_id not in tracked_projects:
|
|
await ctx.send("This project is not being tracked.")
|
|
return
|
|
|
|
project_name = tracked_projects[project_id].get("name", project_id)
|
|
del tracked_projects[project_id]
|
|
await self.config.guild(ctx.guild).tracked_projects.set(tracked_projects)
|
|
await ctx.send(f"Stopped tracking {project_name} (`{project_id}`).")
|
|
|
|
@modrinth.command()
|
|
async def list(self, ctx):
|
|
"""List all tracked Modrinth projects"""
|
|
tracked_projects = await self.config.guild(ctx.guild).tracked_projects()
|
|
if not tracked_projects:
|
|
await ctx.send("No projects are currently being tracked.")
|
|
return
|
|
|
|
embed = discord.Embed(title="Tracked Modrinth Projects", color=discord.Color.blue())
|
|
for project_id, data in tracked_projects.items():
|
|
channel = self.bot.get_channel(data["channel"])
|
|
channel_mention = channel.mention if channel else "Unknown channel"
|
|
embed.add_field(
|
|
name=data.get("name", project_id),
|
|
value=f"ID: `{project_id}`\nChannel: {channel_mention}",
|
|
inline=False
|
|
)
|
|
await ctx.send(embed=embed)
|
|
|
|
async def update_checker(self):
|
|
await self.bot.wait_until_ready()
|
|
while True:
|
|
try:
|
|
all_guilds = await self.config.all_guilds()
|
|
for guild_id, guild_data in all_guilds.items():
|
|
guild = self.bot.get_guild(guild_id)
|
|
if not guild:
|
|
continue
|
|
|
|
tracked_projects = guild_data.get("tracked_projects", {})
|
|
for project_id, data in tracked_projects.items():
|
|
try:
|
|
async with self.session.get(f"{BASE_URL}/project/{project_id}/version") as response:
|
|
if response.status != 200:
|
|
continue
|
|
|
|
versions = await response.json()
|
|
if not versions:
|
|
continue
|
|
|
|
latest_version = versions[0]
|
|
if latest_version["id"] == data.get("latest_version"):
|
|
continue
|
|
|
|
channel = self.bot.get_channel(data["channel"])
|
|
if channel:
|
|
embed = discord.Embed(
|
|
title=f"New Update for {data.get('name', project_id)}!",
|
|
description=f"Version: {latest_version.get('version_number', 'Unknown')}\n\n{latest_version.get('changelog', 'No changelog provided')}",
|
|
url=f"https://modrinth.com/project/{project_id}",
|
|
color=discord.Color.green(),
|
|
timestamp=datetime.now()
|
|
)
|
|
await channel.send(embed=embed)
|
|
|
|
tracked_projects[project_id]["latest_version"] = latest_version["id"]
|
|
await self.config.guild(guild).tracked_projects.set(tracked_projects)
|
|
|
|
except Exception as e:
|
|
continue
|
|
|
|
except Exception as e:
|
|
pass
|
|
|
|
await asyncio.sleep(300) # Check every 5 minutes
|
|
|
|
async def setup(bot):
|
|
await bot.add_cog(ModrinthTracker(bot))
|