Beta 1
* Screenshot (unpolished, functional) * Dig * Traceroute * Whois * Ping * yt-dl * Docker file
This commit is contained in:
parent
4c4ddbf6c1
commit
fb705abf7c
8 changed files with 67 additions and 209 deletions
|
@ -4,19 +4,12 @@
|
|||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="aa6d62a8-d64d-4a60-a85f-8d9fa52b6b49" name="Changes" comment="Update gitignore">
|
||||
<change afterPath="$PROJECT_DIR$/.idea/college-bot-2.0.iml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/profiles_settings.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/modules.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/cogs/net.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/cogs/screenshot.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/cogs/ytdl.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/config.example.toml" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/requirements.txt" afterDir="false" />
|
||||
<list default="true" id="aa6d62a8-d64d-4a60-a85f-8d9fa52b6b49" name="Changes" comment="Beta 1 * Screenshot (unpolished, functional) * Dig * Traceroute * Whois * Ping * yt-dl">
|
||||
<change afterPath="$PROJECT_DIR$/Dockerfile" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/cogs/screenshot.py" beforeDir="false" afterPath="$PROJECT_DIR$/cogs/screenshot.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/config.example.toml" beforeDir="false" afterPath="$PROJECT_DIR$/config.example.toml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/requirements.txt" beforeDir="false" afterPath="$PROJECT_DIR$/requirements.txt" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
|
@ -78,7 +71,7 @@
|
|||
<workItem from="1704140854074" duration="30000" />
|
||||
<workItem from="1704140889356" duration="166000" />
|
||||
<workItem from="1704141061129" duration="2495000" />
|
||||
<workItem from="1704224862150" duration="9650000" />
|
||||
<workItem from="1704224862150" duration="11351000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="Update gitignore">
|
||||
<option name="closed" value="true" />
|
||||
|
@ -88,7 +81,15 @@
|
|||
<option name="project" value="LOCAL" />
|
||||
<updated>1704234449168</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="2" />
|
||||
<task id="LOCAL-00002" summary="Beta 1 * Screenshot (unpolished, functional) * Dig * Traceroute * Whois * Ping * yt-dl">
|
||||
<option name="closed" value="true" />
|
||||
<created>1704234565095</created>
|
||||
<option name="number" value="00002" />
|
||||
<option name="presentableId" value="LOCAL-00002" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1704234565095</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="3" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
|
@ -97,6 +98,7 @@
|
|||
<component name="VcsManagerConfiguration">
|
||||
<option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
|
||||
<MESSAGE value="Update gitignore" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="Update gitignore" />
|
||||
<MESSAGE value="Beta 1 * Screenshot (unpolished, functional) * Dig * Traceroute * Whois * Ping * yt-dl" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="Beta 1 * Screenshot (unpolished, functional) * Dig * Traceroute * Whois * Ping * yt-dl" />
|
||||
</component>
|
||||
</project>
|
16
Dockerfile
Normal file
16
Dockerfile
Normal file
|
@ -0,0 +1,16 @@
|
|||
FROM python:3.11-bookworm
|
||||
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get update
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y traceroute iputils-ping dnsutils net-tools git chromium chromium-driver chromium-sandbox chromium-shell
|
||||
|
||||
RUN pip install --upgrade --break-system-packages pip wheel setuptools
|
||||
|
||||
COPY requirements.txt /tmp/requirements.txt
|
||||
RUN pip install -Ur /tmp/requirements.txt --break-system-packages --no-input
|
||||
|
||||
WORKDIR /app
|
||||
COPY main.py /app
|
||||
COPY cookies.txt /app
|
||||
COPY cogs/ /app/cogs/
|
||||
|
||||
CMD ["python", "main.py"]
|
12
cogs/net.py
12
cogs/net.py
|
@ -1,15 +1,15 @@
|
|||
import asyncio
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
import typing
|
||||
|
||||
import discord
|
||||
from rich.console import Console
|
||||
import time
|
||||
import re
|
||||
from dns import asyncresolver
|
||||
from rich.tree import Tree
|
||||
import asyncio
|
||||
from discord.ext import commands
|
||||
from dns import asyncresolver
|
||||
from rich.console import Console
|
||||
from rich.tree import Tree
|
||||
|
||||
|
||||
class NetworkCog(commands.Cog):
|
||||
|
|
|
@ -1,21 +1,16 @@
|
|||
import asyncio
|
||||
import datetime
|
||||
import io
|
||||
import logging
|
||||
import shutil
|
||||
import os
|
||||
import tempfile
|
||||
import time
|
||||
import zipfile
|
||||
from urllib.parse import urlparse
|
||||
from PIL import Image
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
import asyncio
|
||||
import aiohttp
|
||||
from pathlib import Path
|
||||
|
||||
from PIL import Image
|
||||
from selenium import webdriver
|
||||
from selenium.common.exceptions import WebDriverException
|
||||
from selenium.webdriver.chrome.options import Options as ChromeOptions
|
||||
from selenium.webdriver.chrome.service import Service as ChromeService
|
||||
|
||||
|
@ -30,174 +25,22 @@ class ScreenshotCog(commands.Cog):
|
|||
# self.chrome_options.add_argument("--disable-gpu")
|
||||
self.chrome_options.add_argument("--disable-extensions")
|
||||
self.chrome_options.add_argument("--incognito")
|
||||
if os.getuid() == 0:
|
||||
self.chrome_options.add_argument("--no-sandbox")
|
||||
|
||||
prefs = {
|
||||
# "download.open_pdf_in_system_reader": False,
|
||||
"download.open_pdf_in_system_reader": False,
|
||||
# "download.prompt_for_download": True,
|
||||
# "download.default_directory": "/dev/null",
|
||||
# "plugins.always_open_pdf_externally": False,
|
||||
"plugins.always_open_pdf_externally": False,
|
||||
"download_restrictions": 3,
|
||||
}
|
||||
self.chrome_options.add_experimental_option(
|
||||
"prefs", prefs
|
||||
)
|
||||
|
||||
self.dir = Path(__file__).parent.parent / "chrome"
|
||||
self.dir.mkdir(mode=0o775, exist_ok=True)
|
||||
|
||||
self.chrome_dir = self.dir / "chrome-headless-shell-linux64"
|
||||
self.chrome_bin = self.chrome_dir / "chrome-headless-shell"
|
||||
self.chromedriver_dir = self.dir / "chromedriver-linux64"
|
||||
self.chromedriver_bin = self.chromedriver_dir / "chromedriver"
|
||||
|
||||
self.chrome_options.binary_location = str(self.chrome_bin.resolve())
|
||||
|
||||
self.log = logging.getLogger("jimmy.cogs.screenshot")
|
||||
|
||||
def clear_directories(self):
|
||||
shutil.rmtree(self.chrome_dir, ignore_errors=True)
|
||||
shutil.rmtree(self.chromedriver_dir, ignore_errors=True)
|
||||
self.chrome_dir.mkdir(mode=0o775, exist_ok=True)
|
||||
self.chromedriver_dir.mkdir(mode=0o775, exist_ok=True)
|
||||
|
||||
async def download_latest_chrome(self, current: str = None, *, channel: str = "Stable"):
|
||||
async with aiohttp.ClientSession(raise_for_status=True) as session:
|
||||
async with session.get(
|
||||
"https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json",
|
||||
) as response:
|
||||
versions = await response.json()
|
||||
self.log.debug("Got chrome versions: %r", versions)
|
||||
downloads = versions["channels"][channel]["downloads"]
|
||||
version = versions["channels"][channel]["version"]
|
||||
if version == current:
|
||||
self.log.debug(f"Chrome is up to date ({versions} == {current})")
|
||||
return
|
||||
|
||||
self.log.debug("Downloading chrome...")
|
||||
chrome_zip_url = filter(lambda x: x["platform"] == "linux64", downloads["chrome-headless-shell"])
|
||||
if not chrome_zip_url:
|
||||
self.log.critical("No chrome zip url found for linux64 in %r.", downloads["chrome-headless-shell"])
|
||||
raise RuntimeError("No chrome zip url found for linux64.")
|
||||
chrome_zip_url = next(chrome_zip_url)["url"]
|
||||
self.log.debug("Chrome zip url: %s", chrome_zip_url)
|
||||
|
||||
self.clear_directories()
|
||||
|
||||
chrome_target = (self.chrome_dir.parent / f"chrome-download-{version}.zip")
|
||||
chromedriver_target = (self.chromedriver_dir.parent / f"chromedriver-download-{version}.zip")
|
||||
if chrome_target.exists():
|
||||
chrome_target.unlink()
|
||||
if chromedriver_target.exists():
|
||||
chromedriver_target.unlink()
|
||||
with chrome_target.open("wb+") as file:
|
||||
async with session.get(chrome_zip_url) as response:
|
||||
async for data in response.content.iter_any():
|
||||
self.log.debug("Read %d bytes from chrome zip.", len(data))
|
||||
file.write(data)
|
||||
|
||||
self.log.debug("Extracting chrome...")
|
||||
with zipfile.ZipFile(chrome_target) as zip_file:
|
||||
await asyncio.get_event_loop().run_in_executor(
|
||||
None,
|
||||
zip_file.extractall,
|
||||
self.chrome_dir.parent
|
||||
)
|
||||
self.log.debug("Finished extracting chrome.")
|
||||
|
||||
self.log.debug("Downloading chromedriver...")
|
||||
chromedriver_zip_url = filter(lambda x: x["platform"] == "linux64", downloads["chromedriver"])
|
||||
if not chromedriver_zip_url:
|
||||
self.log.critical("No chromedriver zip url found for linux64 in %r.", downloads["chromedriver"])
|
||||
raise RuntimeError("No chromedriver zip url found for linux64.")
|
||||
chromedriver_zip_url = next(chromedriver_zip_url)["url"]
|
||||
self.log.debug("Chromedriver zip url: %s", chromedriver_zip_url)
|
||||
|
||||
with chromedriver_target.open("wb+") as file:
|
||||
async with session.get(chromedriver_zip_url) as response:
|
||||
async for data in response.content.iter_any():
|
||||
self.log.debug("Read %d bytes from chromedriver zip.", len(data))
|
||||
file.write(data)
|
||||
|
||||
self.log.debug("Extracting chromedriver...")
|
||||
with zipfile.ZipFile(chromedriver_target) as zip_file:
|
||||
await asyncio.get_event_loop().run_in_executor(
|
||||
None,
|
||||
zip_file.extractall,
|
||||
self.chromedriver_dir.parent
|
||||
)
|
||||
self.log.debug("Finished extracting chromedriver.")
|
||||
|
||||
self.log.debug("Making binaries executable.")
|
||||
await asyncio.get_event_loop().run_in_executor(
|
||||
None,
|
||||
self.chrome_bin.chmod,
|
||||
0o775
|
||||
)
|
||||
await asyncio.get_event_loop().run_in_executor(
|
||||
None,
|
||||
self.chromedriver_bin.chmod,
|
||||
0o775
|
||||
)
|
||||
self.log.debug("Finished making binaries executable.")
|
||||
|
||||
async def get_version(self, full: bool = False) -> str:
|
||||
proc = await asyncio.create_subprocess_exec(
|
||||
str(self.chromedriver_bin),
|
||||
"--version",
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE
|
||||
)
|
||||
stdout, stderr = await proc.communicate()
|
||||
if proc.returncode != 0:
|
||||
raise RuntimeError(f"Error getting chromedriver version: {stderr.decode()}")
|
||||
if full:
|
||||
return stdout.decode().strip()
|
||||
return stdout.decode().strip().split(" ")[1]
|
||||
|
||||
async def is_up_to_date(self, channel: str = "Stable"):
|
||||
try:
|
||||
current = await self.get_version(False)
|
||||
except (RuntimeError, FileNotFoundError):
|
||||
return False
|
||||
async with aiohttp.ClientSession(raise_for_status=True) as session:
|
||||
async with session.get(
|
||||
"https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json",
|
||||
) as response:
|
||||
versions = await response.json()
|
||||
self.log.debug("Got chrome versions: %r", versions)
|
||||
version = versions["channels"][channel]["version"]
|
||||
if version == current:
|
||||
self.log.debug(f"Chrome is up to date ({versions} == {current})")
|
||||
return True
|
||||
return False
|
||||
|
||||
@commands.command(name="update-chrome")
|
||||
async def update_chrome(self, ctx: commands.Context, channel: str = "Stable"):
|
||||
channel = channel.title()
|
||||
if await self.is_up_to_date(channel):
|
||||
await ctx.reply("Chrome is already up to date. Updating anyway.")
|
||||
async with ctx.channel.typing():
|
||||
try:
|
||||
await self.download_latest_chrome(channel)
|
||||
except RuntimeError as e:
|
||||
return await ctx.reply(f"\N{cross mark} Error downloading chrome: {e}")
|
||||
|
||||
chrome_okay = self.chrome_bin.exists() and self.chrome_bin.is_file()
|
||||
chromedriver_okay = self.chromedriver_bin.exists() and self.chromedriver_bin.is_file()
|
||||
|
||||
try:
|
||||
chromedriver_version = await self.get_version(True)
|
||||
except RuntimeError as e:
|
||||
chromedriver_version = str(e)
|
||||
|
||||
return await ctx.reply(
|
||||
f"\N{white heavy check mark} Done.\n"
|
||||
f"CHANNEL: {channel}\n"
|
||||
f"CHROME OKAY: {chrome_okay}\n"
|
||||
f"CHROMEDRIVER OKAY: {chromedriver_okay}\n"
|
||||
f"CHROMEDRIVER VERSION: {chromedriver_version}"
|
||||
)
|
||||
|
||||
def compress_png(self, input_file: io.BytesIO) -> io.BytesIO:
|
||||
img = Image.open(input_file)
|
||||
img = img.convert("RGB")
|
||||
|
@ -220,6 +63,7 @@ class ScreenshotCog(commands.Cog):
|
|||
raise RuntimeError("Couldn't compress image.")
|
||||
return value
|
||||
|
||||
# noinspection PyTypeChecker
|
||||
@commands.slash_command()
|
||||
async def screenshot(
|
||||
self,
|
||||
|
@ -242,17 +86,8 @@ class ScreenshotCog(commands.Cog):
|
|||
parsed = urlparse(url)
|
||||
await ctx.respond("Initialising...")
|
||||
|
||||
if not all(map(lambda x: x.exists() and x.is_file(), (self.chrome_bin, self.chromedriver_bin))):
|
||||
await ctx.edit(content="Chrome is not installed, downloading. This may take a minute.")
|
||||
await self.download_latest_chrome()
|
||||
await ctx.edit(content="Initialising...")
|
||||
elif not await self.is_up_to_date():
|
||||
await ctx.edit(content="Updating chrome. This may take a minute.")
|
||||
await self.download_latest_chrome()
|
||||
await ctx.edit(content="Initialising...")
|
||||
|
||||
start_init = time.time()
|
||||
service = await asyncio.to_thread(ChromeService, str(self.chromedriver_bin))
|
||||
service = await asyncio.to_thread(ChromeService)
|
||||
driver: webdriver.Chrome = await asyncio.to_thread(
|
||||
webdriver.Chrome,
|
||||
service=service,
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
import asyncio
|
||||
import functools
|
||||
import logging
|
||||
import tempfile
|
||||
import textwrap
|
||||
import typing
|
||||
from pathlib import Path
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import discord
|
||||
import yt_dlp
|
||||
from urllib.parse import urlparse
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
from discord.ext import commands
|
||||
|
||||
|
||||
COOKIES_TXT = Path.cwd() / "cookies.txt"
|
||||
|
||||
|
||||
|
|
|
@ -1,2 +1,6 @@
|
|||
[jimmy]
|
||||
token = "foo"
|
||||
token = "token"
|
||||
debug_guilds = [994710566612500550]
|
||||
|
||||
[logging]
|
||||
level = "DEBUG"
|
13
main.py
13
main.py
|
@ -1,14 +1,13 @@
|
|||
import datetime
|
||||
import traceback
|
||||
|
||||
import toml
|
||||
import discord
|
||||
import logging
|
||||
from pathlib import Path
|
||||
from rich.logging import RichHandler
|
||||
import traceback
|
||||
from logging import FileHandler
|
||||
from discord.ext import commands
|
||||
from pathlib import Path
|
||||
|
||||
import discord
|
||||
import toml
|
||||
from discord.ext import commands
|
||||
from rich.logging import RichHandler
|
||||
|
||||
log = logging.getLogger("jimmy")
|
||||
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
wheel>=0.42
|
||||
setuptools>=69
|
||||
yt-dlp @ https://github.com/yt-dlp/yt-dlp/archive/master.tar.gz
|
||||
py-cord==2.4.1
|
||||
# py-cord==2.4.1
|
||||
py-cord @ git+https://github.com/Pycord-Development/pycord.git
|
||||
httpx==0.26
|
||||
psycopg==3.1.16
|
||||
toml==0.10.2
|
||||
pillow==10.2
|
||||
selenium==4.16
|
||||
rich==13.7
|
||||
dnspython==2.4.2
|
||||
|
|
Loading…
Reference in a new issue