Merge pull request 'switch to commands bot' (#8) from commands-bot into main
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Garfbot CI/CD Deployment / Deploy (push) Successful in 16s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Garfbot CI/CD Deployment / Deploy (push) Successful in 16s
				
			Reviewed-on: #8 hopefully this works!
This commit is contained in:
		
							
								
								
									
										121
									
								
								garfmain.py
									
									
									
									
									
								
							
							
						
						
									
										121
									
								
								garfmain.py
									
									
									
									
									
								
							| @@ -1,6 +1,7 @@ | ||||
| import config | ||||
| import asyncio | ||||
| import discord | ||||
| from discord.ext import commands | ||||
|  | ||||
| from garfpy import ( | ||||
|     help, | ||||
| @@ -24,7 +25,8 @@ intents = discord.Intents.default() | ||||
| intents.members = True | ||||
| intents.messages = True | ||||
| intents.message_content = True | ||||
| garfbot = discord.Client(intents=intents) | ||||
|  | ||||
| garfbot = commands.Bot(command_prefix=["garfbot ", "garf", "$"], intents=intents) | ||||
|  | ||||
| garf_respond = GarfbotRespond() | ||||
| garfield = GarfAI() | ||||
| @@ -39,12 +41,82 @@ async def on_ready(): | ||||
|         garf_respond.load_responses() | ||||
|         asyncio.create_task(garfield.process_image_requests()) | ||||
|         logger.info( | ||||
|             f"Logged in as {garfbot.user.name} running {txtmodel} and {imgmodel}." | ||||
|             f"Logged in as {garfbot.user.name} running {txtmodel} and {imgmodel}."  # type: ignore | ||||
|         ) | ||||
|     except Exception as e: | ||||
|         logger.error(e) | ||||
|  | ||||
|  | ||||
| @garfbot.command(name="ping") | ||||
| async def ping(ctx, *, target): | ||||
|     """Ping a target""" | ||||
|     logger.info( | ||||
|         f"Ping Request - User: {ctx.author.name}, Server: {ctx.guild.name}, Target: {target}" | ||||
|     ) | ||||
|     await iputils.ping(ctx, target) | ||||
|  | ||||
|  | ||||
| @garfbot.command(name="dns") | ||||
| async def dns(ctx, *, target): | ||||
|     """DNS lookup for a target""" | ||||
|     logger.info( | ||||
|         f"NSLookup Request - User: {ctx.author.name}, Server: {ctx.guild.name}, Target: {target}" | ||||
|     ) | ||||
|     await iputils.dns(ctx, target) | ||||
|  | ||||
|  | ||||
| @garfbot.command(name="hack") | ||||
| async def hack(ctx, *, target): | ||||
|     """Nmap scan a target""" | ||||
|     logger.info( | ||||
|         f"Nmap Request - User: {ctx.author.name}, Server: {ctx.guild.name}, Target: {target}" | ||||
|     ) | ||||
|     await iputils.scan(ctx, target) | ||||
|  | ||||
|  | ||||
| @garfbot.command(name="qr") | ||||
| async def garfbot_qr(ctx, *, text): | ||||
|     logger.info( | ||||
|         f"QR Code Request - User: {ctx.author.name}, Server: {ctx.guild.name}, Text: {text}" | ||||
|     ) | ||||
|     if len(text) > 1000: | ||||
|         await ctx.send("❌ Text too long! Maximum 1000 characters.") | ||||
|     else: | ||||
|         try: | ||||
|             qr_code = await generate_qr(text) | ||||
|             sendfile = discord.File(fp=qr_code, filename="qrcode.png") | ||||
|             await ctx.send(file=sendfile) | ||||
|         except Exception as e: | ||||
|             logger.error(e) | ||||
|             await ctx.send(e) | ||||
|  | ||||
|  | ||||
| @garfbot.command(name="wiki") | ||||
| async def garfbot_wiki(ctx, *, query): | ||||
|     summary = await garfield.wikisum(query) | ||||
|     await ctx.send(summary) | ||||
|  | ||||
|  | ||||
| @garfbot.command(name="shop") | ||||
| async def garfbot_shop(ctx, *, query): | ||||
|     try: | ||||
|         response = kroger.garfshop(query) | ||||
|         await ctx.send(response) | ||||
|     except Exception as e: | ||||
|         await ctx.send(f"`GarfBot Error: {str(e)}`") | ||||
|  | ||||
|  | ||||
| @garfbot.command(name="weather") | ||||
| async def garfbot_weather(ctx, *, location): | ||||
|     embed = await weather.weather(location) | ||||
|     await ctx.send(embed=embed) | ||||
|  | ||||
|  | ||||
| # @garfbot.command(name="help") | ||||
| # async def garfbot_help(ctx): | ||||
| #     await help(ctx) | ||||
|  | ||||
|  | ||||
| @garfbot.event | ||||
| async def on_message(message): | ||||
|     if message.author == garfbot.user: | ||||
| @@ -56,41 +128,8 @@ async def on_message(message): | ||||
|     guild_id = message.guild.id | ||||
|     guild_name = message.guild.name if message.guild else "Direct Message" | ||||
|  | ||||
|     # IP utils | ||||
|     if message.guild and lower.startswith(("garfping ", "garfdns ", "garfhack ")): | ||||
|         await iputils.scan(message, user_name, guild_name, lower) | ||||
|  | ||||
|     # Wikipedia | ||||
|     if lower.startswith("garfwiki "): | ||||
|         query = message.content[9:] | ||||
|         summary = await garfield.wikisum(query) | ||||
|         await message.channel.send(summary) | ||||
|  | ||||
|     # QR codes | ||||
|     if lower.startswith("garfqr "): | ||||
|         text = message.content[7:] | ||||
|         if len(text) > 1000: | ||||
|             await message.channel.send("❌ Text too long! Maximum 1000 characters.") | ||||
|         else: | ||||
|             try: | ||||
|                 qr_code = await generate_qr(text) | ||||
|                 sendfile = discord.File(fp=qr_code, filename="qrcode.png") | ||||
|                 await message.channel.send(file=sendfile) | ||||
|             except Exception as e: | ||||
|                 logger.error(e) | ||||
|                 await message.channel.send(e) | ||||
|  | ||||
|     # Kroger Shopping | ||||
|     if lower.startswith("garfshop "): | ||||
|         try: | ||||
|             query = message.content[9:] | ||||
|             response = kroger.garfshop(query) | ||||
|             await message.channel.send(response) | ||||
|         except Exception as e: | ||||
|             await message.channel.send(f"`GarfBot Error: {str(e)}`") | ||||
|  | ||||
|     # Chats & pics | ||||
|     elif lower.startswith("hey garfield") or isinstance( | ||||
|     if lower.startswith("hey garfield") or isinstance( | ||||
|         message.channel, discord.DMChannel | ||||
|     ): | ||||
|         prompt = content[12:] if lower.startswith("hey garfield") else message.content | ||||
| @@ -100,7 +139,7 @@ async def on_message(message): | ||||
|         ) | ||||
|         await message.channel.send(answer) | ||||
|  | ||||
|     elif lower.startswith("garfpic "): | ||||
|     if lower.startswith("garfpic "): | ||||
|         prompt = content[8:] | ||||
|         logger.info( | ||||
|             f"Image Request - User: {user_name}, Server: {guild_name}, Prompt: {prompt}" | ||||
| @@ -110,12 +149,6 @@ async def on_message(message): | ||||
|         ) | ||||
|         await garfield.garfpic(message, prompt) | ||||
|  | ||||
|     # Weather | ||||
|     elif lower.startswith("garfbot weather "): | ||||
|         location = lower[16:] | ||||
|         embed = await weather.weather(location) | ||||
|         await message.channel.send(embed=embed) | ||||
|  | ||||
|     # GarfBot help | ||||
|     elif lower.strip() == "garfbot help": | ||||
|         await help(message) | ||||
| @@ -137,6 +170,8 @@ async def on_message(message): | ||||
|                 await message.channel.send(response) | ||||
|                 break | ||||
|  | ||||
|     await garfbot.process_commands(message) | ||||
|  | ||||
|  | ||||
| # Run GarfBot | ||||
| async def garfbot_connect(): | ||||
|   | ||||
| @@ -1,7 +1,6 @@ | ||||
| import discord | ||||
| import ipaddress | ||||
| import subprocess | ||||
| from garfpy import logger | ||||
|  | ||||
|  | ||||
| class IPUtils: | ||||
| @@ -23,63 +22,52 @@ class IPUtils: | ||||
|                 return True | ||||
|         return False | ||||
|  | ||||
|     async def scan(self, message, user, guild, query): | ||||
|         split = query.split() | ||||
|         target = split[-1] | ||||
|     async def ping(self, ctx, target): | ||||
|         if self.is_private(target): | ||||
|             return | ||||
|  | ||||
|         if query.startswith("garfping "): | ||||
|         try: | ||||
|                 logger.info( | ||||
|                     f"Ping Request - User: {user}, Server: {guild}, Target: {target}" | ||||
|                 ) | ||||
|                 await message.channel.send(f"`Pinging {target}...`") | ||||
|             await ctx.send(f"`Pinging {target}...`") | ||||
|             result = subprocess.run( | ||||
|                 ["ping", "-c", "4", target], capture_output=True, text=True | ||||
|             ) | ||||
|             embed = discord.Embed( | ||||
|                 title=f"Ping result: {target}", | ||||
|                     color=0x4D4D4D, | ||||
|                 color=discord.Color.light_gray(), | ||||
|                 description=f"```{result.stdout}```", | ||||
|             ) | ||||
|                 await message.channel.send(embed=embed) | ||||
|             await ctx.send(embed=embed) | ||||
|         except Exception as e: | ||||
|                 await message.channel.send(f"`GarfBot Error: {str(e)}`") | ||||
|             await ctx.send(f"`GarfBot Error: {str(e)}`") | ||||
|  | ||||
|         if query.startswith("garfdns "): | ||||
|     async def dns(self, ctx, target): | ||||
|         if self.is_private(target): | ||||
|             return | ||||
|         try: | ||||
|                 logger.info( | ||||
|                     f"NSLookup Request - User: {user}, Server: {guild}, Target: {target}" | ||||
|                 ) | ||||
|                 await message.channel.send(f"`Requesting {target}...`") | ||||
|             await ctx.send(f"`Requesting {target}...`") | ||||
|             result = subprocess.run( | ||||
|                 ["nslookup", target], capture_output=True, text=True | ||||
|             ) | ||||
|             embed = discord.Embed( | ||||
|                 title=f"NSLookup result: {target}", | ||||
|                     color=0x4D4D4D, | ||||
|                 color=discord.Color.light_gray(), | ||||
|                 description=f"```{result.stdout}```", | ||||
|             ) | ||||
|                 await message.channel.send(embed=embed) | ||||
|             await ctx.send(embed=embed) | ||||
|         except Exception as e: | ||||
|                 await message.channel.send(f"`GarfBot Error: {str(e)}`") | ||||
|             await ctx.send(f"`GarfBot Error: {str(e)}`") | ||||
|  | ||||
|         if query.startswith("garfhack "): | ||||
|     async def scan(self, ctx, target): | ||||
|         try: | ||||
|                 logger.info( | ||||
|                     f"Nmap Request - User: {user}, Server: {guild}, Target: {target}" | ||||
|                 ) | ||||
|                 await message.channel.send(f"`Scanning {target}...`") | ||||
|             await ctx.send(f"`Scanning {target}...`") | ||||
|             result = subprocess.run( | ||||
|                 ["nmap", "-Pn", "-O", "-v", target], capture_output=True, text=True | ||||
|             ) | ||||
|             embed = discord.Embed( | ||||
|                 title=f"Nmap scan result: {target}", | ||||
|                     color=0x4D4D4D, | ||||
|                 color=discord.Color.light_gray(), | ||||
|                 description=f"```{result.stdout}```", | ||||
|             ) | ||||
|             embed.set_footer(text="https://nmap.org/") | ||||
|                 await message.channel.send(embed=embed) | ||||
|             await ctx.send(embed=embed) | ||||
|         except Exception as e: | ||||
|                 await message.channel.send(f"`GarfBot Error: {str(e)}`") | ||||
|             await ctx.send(f"`GarfBot Error: {str(e)}`") | ||||
|   | ||||
| @@ -47,7 +47,7 @@ async def generate_qr(text): | ||||
|  | ||||
|     qr = qrcode.QRCode( | ||||
|         version=version, | ||||
|         error_correction=qrcode.constants.ERROR_CORRECT_L, | ||||
|         error_correction=qrcode.constants.ERROR_CORRECT_L, # type: ignore | ||||
|         box_size=box_size, | ||||
|         border=4, | ||||
|     ) | ||||
| @@ -58,7 +58,7 @@ async def generate_qr(text): | ||||
|     qr_image = qr.make_image(fill_color="black", back_color="white") | ||||
|  | ||||
|     img_buffer = BytesIO() | ||||
|     qr_image.save(img_buffer, format="PNG") | ||||
|     qr_image.save(img_buffer, format="PNG") # type: ignore | ||||
|     img_buffer.seek(0) | ||||
|  | ||||
|     return img_buffer | ||||
|   | ||||
| @@ -18,13 +18,13 @@ class WeatherAPI: | ||||
|             else: | ||||
|                 return {"zip": location} | ||||
|  | ||||
|         parts = location.split() | ||||
|         params = location.split() | ||||
|  | ||||
|         if len(parts) == 1: | ||||
|             return {"q": f"{parts[0]},US"} | ||||
|         if len(params) == 1: | ||||
|             return {"q": f"{params[0]},US"} | ||||
|  | ||||
|         elif len(parts) == 2: | ||||
|             city, second = parts | ||||
|         elif len(params) == 2: | ||||
|             city, second = params | ||||
|  | ||||
|             if len(second) == 2 and second.upper() not in [ | ||||
|                 "AK", | ||||
| @@ -88,26 +88,26 @@ class WeatherAPI: | ||||
|             else: | ||||
|                 return {"q": f"{city},{second},US"} | ||||
|  | ||||
|         elif len(parts) == 3: | ||||
|             city, state, country = parts | ||||
|         elif len(params) == 3: | ||||
|             city, state, country = params | ||||
|             return {"q": f"{city},{state},{country.upper()}"} | ||||
|  | ||||
|         else: | ||||
|             if len(parts[-1]) == 2: | ||||
|                 city_parts = parts[:-1] | ||||
|                 country = parts[-1] | ||||
|             if len(params[-1]) == 2: | ||||
|                 city_parts = params[:-1] | ||||
|                 country = params[-1] | ||||
|                 city_name = " ".join(city_parts) | ||||
|                 return {"q": f"{city_name},{country.upper()}"} | ||||
|  | ||||
|             elif len(parts) >= 2 and len(parts[-1]) == 2 and len(parts[-2]) <= 2: | ||||
|                 city_parts = parts[:-2] | ||||
|                 state = parts[-2] | ||||
|                 country = parts[-1] | ||||
|             elif len(params) >= 2 and len(params[-1]) == 2 and len(params[-2]) <= 2: | ||||
|                 city_parts = params[:-2] | ||||
|                 state = params[-2] | ||||
|                 country = params[-1] | ||||
|                 city_name = " ".join(city_parts) | ||||
|                 return {"q": f"{city_name},{state},{country.upper()}"} | ||||
|  | ||||
|             else: | ||||
|                 city_name = " ".join(parts) | ||||
|                 city_name = " ".join(params) | ||||
|                 return {"q": f"{city_name},US"} | ||||
|  | ||||
|     async def get_weather(self, location, units="metric"): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user