mirror of
https://github.com/nexy7574/LCC-bot.git
synced 2024-09-20 02:26:32 +01:00
did shit
This commit is contained in:
parent
947f57d334
commit
f48eb699e7
1 changed files with 54 additions and 41 deletions
|
@ -4,10 +4,11 @@ import os
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import textwrap
|
import textwrap
|
||||||
|
import traceback
|
||||||
|
|
||||||
import dns.resolver
|
import dns.resolver
|
||||||
import aiofiles
|
import aiofiles
|
||||||
from time import sleep as time_sleep
|
from time import time
|
||||||
from typing import Literal
|
from typing import Literal
|
||||||
from typing import Tuple, Optional, Dict
|
from typing import Tuple, Optional, Dict
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
@ -19,10 +20,12 @@ import psutil
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from rich.tree import Tree
|
from rich.tree import Tree
|
||||||
from selenium import webdriver
|
from selenium import webdriver
|
||||||
|
from selenium.common.exceptions import WebDriverException
|
||||||
from selenium.webdriver.chrome.options import Options as ChromeOptions
|
from selenium.webdriver.chrome.options import Options as ChromeOptions
|
||||||
from selenium.webdriver.chrome.service import Service as ChromeService
|
from selenium.webdriver.chrome.service import Service as ChromeService
|
||||||
from selenium.webdriver.firefox.options import Options as FirefoxOptions
|
from selenium.webdriver.firefox.options import Options as FirefoxOptions
|
||||||
from selenium.webdriver.firefox.service import Service as FirefoxService
|
from selenium.webdriver.firefox.service import Service as FirefoxService
|
||||||
|
# from selenium.webdriver.ie
|
||||||
|
|
||||||
from utils import console
|
from utils import console
|
||||||
|
|
||||||
|
@ -41,7 +44,7 @@ class OtherCog(commands.Cog):
|
||||||
window_height: int = 1920,
|
window_height: int = 1920,
|
||||||
window_width: int = 1080,
|
window_width: int = 1080,
|
||||||
full_screenshot: bool = False,
|
full_screenshot: bool = False,
|
||||||
) -> discord.File:
|
) -> Tuple[discord.File, str, int, int]:
|
||||||
async def _blocking(*args):
|
async def _blocking(*args):
|
||||||
return await self.bot.loop.run_in_executor(None, *args)
|
return await self.bot.loop.run_in_executor(None, *args)
|
||||||
|
|
||||||
|
@ -51,10 +54,8 @@ class OtherCog(commands.Cog):
|
||||||
"firefox": [
|
"firefox": [
|
||||||
"/usr/bin/firefox-esr",
|
"/usr/bin/firefox-esr",
|
||||||
"/usr/bin/firefox",
|
"/usr/bin/firefox",
|
||||||
# '/usr/bin/geckodriver'
|
|
||||||
],
|
],
|
||||||
"chrome": [
|
"chrome": [
|
||||||
# '/usr/bin/chromedriver',
|
|
||||||
"/usr/bin/chromium",
|
"/usr/bin/chromium",
|
||||||
"/usr/bin/chrome",
|
"/usr/bin/chrome",
|
||||||
"/usr/bin/chrome-browser",
|
"/usr/bin/chrome-browser",
|
||||||
|
@ -87,7 +88,6 @@ class OtherCog(commands.Cog):
|
||||||
return driver, driver_path
|
return driver, driver_path
|
||||||
|
|
||||||
driver, driver_path = find_driver()
|
driver, driver_path = find_driver()
|
||||||
original_driver_name = driver
|
|
||||||
console.log(
|
console.log(
|
||||||
"Using driver '{}' with binary '{}' to screenshot '{}', as requested by {}.".format(
|
"Using driver '{}' with binary '{}' to screenshot '{}', as requested by {}.".format(
|
||||||
driver, driver_path, website, ctx.user
|
driver, driver_path, website, ctx.user
|
||||||
|
@ -123,31 +123,45 @@ class OtherCog(commands.Cog):
|
||||||
# Is it overkill to cast this to a thread? yes
|
# Is it overkill to cast this to a thread? yes
|
||||||
# Do I give a flying fuck? kinda
|
# Do I give a flying fuck? kinda
|
||||||
# Why am I doing this? I suspect setup is causing a ~10-second block of the event loop
|
# Why am I doing this? I suspect setup is causing a ~10-second block of the event loop
|
||||||
|
driver_name = driver
|
||||||
|
start_init = time()
|
||||||
driver, friendly_url = await asyncio.to_thread(_setup)
|
driver, friendly_url = await asyncio.to_thread(_setup)
|
||||||
|
end_init = time()
|
||||||
|
console.log(
|
||||||
|
"Driver '{}' initialised in {} seconds.".format(
|
||||||
|
driver_name, round(end_init - start_init, 2)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
async def _edit(content: str):
|
async def _edit(content: str):
|
||||||
self.bot.loop.create_task(ctx.interaction.edit_original_response(content=content))
|
self.bot.loop.create_task(ctx.interaction.edit_original_response(content=content))
|
||||||
|
|
||||||
await _edit(content=f"Screenshotting {friendly_url}... (49%)")
|
await _edit(content=f"Screenshotting <{friendly_url}>... (49%)")
|
||||||
await _blocking(driver.set_page_load_timeout, render_time)
|
await _blocking(driver.set_page_load_timeout, render_time)
|
||||||
|
start = time()
|
||||||
await _blocking(driver.get, website)
|
await _blocking(driver.get, website)
|
||||||
await _edit(content=f"Screenshotting {friendly_url}... (66%)")
|
end = time()
|
||||||
|
get_time = round((end - start) * 1000)
|
||||||
|
await _edit(content=f"Screenshotting <{friendly_url}>... (66%)")
|
||||||
await asyncio.sleep(render_time)
|
await asyncio.sleep(render_time)
|
||||||
await _edit(content=f"Screenshotting {friendly_url}... (83%)")
|
await _edit(content=f"Screenshotting <{friendly_url}>... (83%)")
|
||||||
domain = re.sub(r"https?://", "", website)
|
domain = re.sub(r"https?://", "", website)
|
||||||
|
|
||||||
screenshot_method = driver.get_screenshot_as_png
|
screenshot_method = driver.get_screenshot_as_png
|
||||||
if full_screenshot and original_driver_name == "firefox":
|
if full_screenshot and driver_name == "firefox":
|
||||||
screenshot_method = driver.get_full_page_screenshot_as_png
|
screenshot_method = driver.get_full_page_screenshot_as_png
|
||||||
|
|
||||||
|
start = time()
|
||||||
data = await _blocking(screenshot_method)
|
data = await _blocking(screenshot_method)
|
||||||
_io = io.BytesIO()
|
_io = io.BytesIO()
|
||||||
# Write the data async because HAHAHAHAHAHAHA
|
# Write the data async because HAHAHAHAHAHAHA
|
||||||
# We'll do it in the existing event loop though because less overhead
|
# We'll do it in the existing event loop though because less overhead
|
||||||
await _blocking(_io.write, data)
|
await _blocking(_io.write, data)
|
||||||
_io.seek(0)
|
_io.seek(0)
|
||||||
|
end = time()
|
||||||
|
screenshot_time = round((end - start) * 1000)
|
||||||
driver.quit()
|
driver.quit()
|
||||||
return discord.File(_io, f"{domain}.png")
|
return discord.File(_io, f"{domain}.png"), driver_name, get_time, screenshot_time
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
async def get_interface_ip_addresses() -> Dict[str, list[Dict[str, str | bool | int]]]:
|
async def get_interface_ip_addresses() -> Dict[str, list[Dict[str, str | bool | int]]]:
|
||||||
|
@ -429,10 +443,12 @@ class OtherCog(commands.Cog):
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
"""Takes a screenshot of a URL"""
|
"""Takes a screenshot of a URL"""
|
||||||
|
window_width = max(min(1080 * 6, window_width), 1080 // 6)
|
||||||
|
window_height = max(min(1920 * 6, window_height), 1920 // 6)
|
||||||
await ctx.defer()
|
await ctx.defer()
|
||||||
if ctx.user.id == 1019233057519177778:
|
# if ctx.user.id == 1019233057519177778:
|
||||||
if getattr(self.bot, "ALLOW_MATTHEW", False) is False:
|
# if getattr(self.bot, "ALLOW_MATTHEW", False) is False:
|
||||||
return await ctx.respond("No.")
|
# return await ctx.respond("No.")
|
||||||
url = urlparse(url)
|
url = urlparse(url)
|
||||||
if not url.scheme:
|
if not url.scheme:
|
||||||
if "/" in url.path:
|
if "/" in url.path:
|
||||||
|
@ -444,7 +460,7 @@ class OtherCog(commands.Cog):
|
||||||
|
|
||||||
friendly_url = textwrap.shorten(url.geturl(), 100)
|
friendly_url = textwrap.shorten(url.geturl(), 100)
|
||||||
|
|
||||||
await ctx.edit(content=f"Preparing to screenshot {friendly_url}... (0%)")
|
await ctx.edit(content=f"Preparing to screenshot <{friendly_url}>... (0%)")
|
||||||
|
|
||||||
async def blacklist_check() -> bool | str:
|
async def blacklist_check() -> bool | str:
|
||||||
async with aiofiles.open("domains.txt") as blacklist:
|
async with aiofiles.open("domains.txt") as blacklist:
|
||||||
|
@ -486,7 +502,7 @@ class OtherCog(commands.Cog):
|
||||||
)
|
)
|
||||||
|
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
await ctx.edit(content=f"Preparing to screenshot {friendly_url}... (16%)")
|
await ctx.edit(content=f"Preparing to screenshot <{friendly_url}>... (16%)")
|
||||||
okay = await (pending or done_tasks).pop()
|
okay = await (pending or done_tasks).pop()
|
||||||
if okay is not True:
|
if okay is not True:
|
||||||
return await ctx.edit(
|
return await ctx.edit(
|
||||||
|
@ -497,16 +513,35 @@ class OtherCog(commands.Cog):
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
await ctx.edit(content=f"Screenshotting {textwrap.shorten(url.geturl(), 100)}... (33%)")
|
await ctx.edit(content=f"Screenshotting {textwrap.shorten(url.geturl(), 100)}... (33%)")
|
||||||
try:
|
try:
|
||||||
screenshot = await self.screenshot_website(
|
screenshot, driver, fetch_time, screenshot_time = await self.screenshot_website(
|
||||||
ctx, url.geturl(), browser, render_timeout, window_height, window_width, capture_whole_page
|
ctx, url.geturl(), browser, render_timeout, window_height, window_width, capture_whole_page
|
||||||
)
|
)
|
||||||
|
except TimeoutError:
|
||||||
|
return await ctx.edit(content="Rendering screenshot timed out. Try using a smaller resolution.")
|
||||||
|
except WebDriverException as e:
|
||||||
|
paginator = commands.Paginator(prefix="```", suffix="```")
|
||||||
|
paginator.add_line("WebDriver Error (did you pass extreme or invalid command options?)")
|
||||||
|
paginator.add_line("Traceback:", empty=True)
|
||||||
|
for line in e.msg.splitlines():
|
||||||
|
paginator.add_line(line)
|
||||||
|
for page in paginator.pages:
|
||||||
|
await ctx.respond(page)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
console.print_exception()
|
console.print_exception()
|
||||||
return await ctx.edit(content=f"Error: {e}", delete_after=30)
|
return await ctx.edit(content=f"Failed: {e}", delete_after=30)
|
||||||
else:
|
else:
|
||||||
await ctx.edit(content=f"Screenshotting {friendly_url}... (99%)")
|
await ctx.edit(content=f"Screenshotting <{friendly_url}>... (99%)")
|
||||||
await asyncio.sleep(0.5)
|
await asyncio.sleep(0.5)
|
||||||
await ctx.edit(content="Here's your screenshot!", file=screenshot)
|
await ctx.edit(
|
||||||
|
content="Here's your screenshot!\n"
|
||||||
|
"Details:\n"
|
||||||
|
f"\\* Browser: {driver}\n"
|
||||||
|
f"\\* Resolution: {window_height}x{window_width} ({window_width*window_height:,} pixels)\n"
|
||||||
|
f"\\* URL: <{friendly_url}>\n"
|
||||||
|
f"\\* Load time: {fetch_time:.2f}ms\n"
|
||||||
|
f"\\* Screenshot render time: {screenshot_time:.2f}ms\n",
|
||||||
|
file=screenshot
|
||||||
|
)
|
||||||
|
|
||||||
domains = discord.SlashCommandGroup("domains", "Commands for managing domains")
|
domains = discord.SlashCommandGroup("domains", "Commands for managing domains")
|
||||||
|
|
||||||
|
@ -534,28 +569,6 @@ class OtherCog(commands.Cog):
|
||||||
await blacklist.write(line)
|
await blacklist.write(line)
|
||||||
await ctx.respond("Removed domain from blacklist.")
|
await ctx.respond("Removed domain from blacklist.")
|
||||||
|
|
||||||
@commands.group(name="matthew", invoke_without_command=True)
|
|
||||||
@commands.is_owner()
|
|
||||||
async def matthew_group(self, ctx: commands.Context):
|
|
||||||
"""Commands for managing domains"""
|
|
||||||
await ctx.send_help(ctx.command)
|
|
||||||
|
|
||||||
@matthew_group.command(name="enable")
|
|
||||||
async def enable_matthew(self, ctx: commands.Context):
|
|
||||||
"""Enables Matthew"""
|
|
||||||
if not await self.bot.is_owner(ctx.author):
|
|
||||||
return await ctx.reply("You are not allowed to do that.")
|
|
||||||
self.bot.ALLOW_MATTHEW = True
|
|
||||||
await ctx.reply("Matthew enabled.")
|
|
||||||
|
|
||||||
@matthew_group.command(name="disable")
|
|
||||||
async def disable_matthew(self, ctx: commands.Context):
|
|
||||||
"""Disables Matthew"""
|
|
||||||
if not await self.bot.is_owner(ctx.author):
|
|
||||||
return await ctx.reply("You are not allowed to do that.")
|
|
||||||
self.bot.ALLOW_MATTHEW = False
|
|
||||||
await ctx.reply("Matthew disabled.")
|
|
||||||
|
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
bot.add_cog(OtherCog(bot))
|
bot.add_cog(OtherCog(bot))
|
||||||
|
|
Loading…
Reference in a new issue