Merge remote-tracking branch 'origin/master'

# Conflicts:
#	.idea/dataSources.local.xml
#	.idea/misc.xml
This commit is contained in:
Nexus 2024-04-15 19:28:48 +01:00
commit 660b9fdb84
Signed by: nex
GPG key ID: 0FA334385D0B689F
3 changed files with 86 additions and 61 deletions

2
.idea/.gitignore vendored
View file

@ -1,3 +1,5 @@
# Default ignored files # Default ignored files
/shelf/ /shelf/
/workspace.xml /workspace.xml
# GitHub Copilot persisted chat sessions
/copilot/chatSessions

View file

@ -2,6 +2,8 @@
<module type="PYTHON_MODULE" version="4"> <module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.idea/copilot/chatSessions" />
<excludeFolder url="file://$MODULE_DIR$/.venv" />
<excludeFolder url="file://$MODULE_DIR$/venv" /> <excludeFolder url="file://$MODULE_DIR$/venv" />
</content> </content>
<orderEntry type="inheritedJdk" /> <orderEntry type="inheritedJdk" />

View file

@ -1,55 +1,42 @@
import asyncio import asyncio
import fnmatch
import functools
import glob import glob
import hashlib import hashlib
import io import io
import json import json
import logging import logging
import math
import os import os
import pathlib import pathlib
import random import random
import re import re
import shutil import shutil
import subprocess
import sys
import tempfile import tempfile
import textwrap import textwrap
import traceback
import typing import typing
from functools import partial from functools import partial
from io import BytesIO
from pathlib import Path from pathlib import Path
from time import sleep, time, time_ns from time import time
from typing import Dict, Literal, Optional, Tuple from typing import Dict, Literal, Tuple
from urllib.parse import urlparse from urllib.parse import urlparse
import aiofiles
import aiohttp import aiohttp
import config
import discord import discord
import dns.resolver
import httpx import httpx
import openai import openai
import psutil import psutil
import pydub import pydub
import pytesseract import pytesseract
import pyttsx3 import pyttsx3
from discord import Interaction
from discord.ext import commands
from dns import asyncresolver
from PIL import Image from PIL import Image
from rich import print from discord.ext import commands
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
import config from utils import Timer
from utils import Timer, console
try: try:
from config import proxy from config import proxy
@ -530,21 +517,8 @@ class OtherCog(commands.Cog):
else: else:
return await ctx.respond(result, view=GenerateNewView()) return await ctx.respond(result, view=GenerateNewView())
@commands.slash_command() async def _ocr_core(self, attachment: discord.Attachment) -> tuple[dict[str, float], str]:
@commands.cooldown(1, 30, commands.BucketType.user) timings: dict[str, float] = {}
@commands.max_concurrency(1, commands.BucketType.user)
async def ocr(
self,
ctx: discord.ApplicationContext,
attachment: discord.Option(
discord.SlashCommandOptionType.attachment,
description="Image to perform OCR on",
),
):
"""OCRs an image"""
await ctx.defer()
timings: Dict[str, float] = {}
attachment: discord.Attachment
with Timer() as _t: with Timer() as _t:
data = await attachment.read() data = await attachment.read()
file = io.BytesIO(data) file = io.BytesIO(data)
@ -558,45 +532,92 @@ class OtherCog(commands.Cog):
text = await self.bot.loop.run_in_executor(None, pytesseract.image_to_string, img) text = await self.bot.loop.run_in_executor(None, pytesseract.image_to_string, img)
timings["Perform OCR"] = _t.total timings["Perform OCR"] = _t.total
except pytesseract.TesseractError as e: except pytesseract.TesseractError as e:
return await ctx.respond(f"Failed to perform OCR: `{e}`") raise RuntimeError(f"Failed to perform OCR: `{e}`")
if len(text) > 4096: if len(text) >= 1744:
with Timer() as _t: with Timer() as _t:
try: try:
response = await self.http.put( file.seek(0)
"https://api.mystb.in/paste", response = await self.http.post(
json={ "https://paste.nexy7574.co.uk/upload",
"files": [{"filename": "ocr.txt", "content": text}], data={
"expiration": "1week",
"burn_after": "0",
"syntax_highlight": "none",
"privacy": "unlisted",
"content": text
}, },
files={
"file": (attachment.filename, file, attachment.content_type)
},
follow_redirects=False
) )
response.raise_for_status() if response.status_code not in range(200, 400):
except httpx.HTTPError: response.raise_for_status()
return await ctx.respond("OCR content too large to post.") except httpx.HTTPError as e:
raise RuntimeError(f"Failed to upload OCR content: `{e}`")
else: else:
data = response.json() text = "View on [paste.nexy7574.co.uk](%s)" % response.next_request.url
with Timer(timings, "Respond (URL)"): timings["Upload text to pastebin"] = _t.total
embed = discord.Embed( return timings, text
description="View on [mystb.in](%s)" % ("https://mystb.in/" + data["id"]),
colour=discord.Colour.dark_theme(), @commands.slash_command()
) @commands.cooldown(1, 30, commands.BucketType.user)
await ctx.respond(embed=embed) @commands.max_concurrency(1, commands.BucketType.user)
timings["Upload text to mystbin"] = _t.total async def ocr(
elif len(text) <= 1500: self,
with Timer() as _t: ctx: discord.ApplicationContext,
await ctx.respond(embed=discord.Embed(description=text)) attachment: discord.Option(
timings["Respond (Text)"] = _t.total discord.SlashCommandOptionType.attachment,
else: description="Image to perform OCR on",
with Timer() as _t: ),
out_file = io.BytesIO(text.encode("utf-8", "replace")) ):
await ctx.respond(file=discord.File(out_file, filename="ocr.txt")) """OCRs an image"""
timings["Respond (File)"] = _t.total await ctx.defer()
attachment: discord.Attachment
timings, text = await self._ocr_core(attachment)
embed = discord.Embed(
description=text,
colour=discord.Colour.blurple()
)
embed.set_image(url=attachment.url)
with Timer() as _t:
await ctx.respond(
embed=embed
)
timings["Respond (Text)"] = _t.total
if timings: if timings:
text = "Timings:\n" + "\n".join("{}: {:.2f}s".format(k.title(), v) for k, v in timings.items()) text = "Timings:\n" + "\n".join("{}: {:.2f}s".format(k.title(), v) for k, v in timings.items())
await ctx.edit( await ctx.edit(
content=text, content=text
) )
@commands.message_command(name="Run OCR")
async def message_ocr(self, ctx: discord.ApplicationContext, message: discord.Message):
await ctx.defer()
embeds = []
for attachment in message.attachments:
if attachment.content_type.startswith("image/"):
timings, text = await self._ocr_core(attachment)
embed = discord.Embed(
title="OCR for " + attachment.filename,
description=text,
colour=discord.Colour.blurple(),
url=message.jump_url
)
embed.set_image(url=attachment.url)
embeds.append(embed)
if len(embeds) == 25:
break
if not embeds:
return await ctx.respond(":x: No images found in message.", delete_after=30)
else:
return await ctx.respond(embeds=embeds)
@commands.message_command(name="Convert Image to GIF") @commands.message_command(name="Convert Image to GIF")
async def convert_image_to_gif(self, ctx: discord.ApplicationContext, message: discord.Message): async def convert_image_to_gif(self, ctx: discord.ApplicationContext, message: discord.Message):
await ctx.defer() await ctx.defer()