mirror of
https://github.com/nexy7574/LCC-bot.git
synced 2024-09-19 01:53:39 +01:00
add whois
This commit is contained in:
parent
0ca7e76c7d
commit
61fb6cb382
9 changed files with 177 additions and 261 deletions
|
@ -20,9 +20,9 @@ import discord
|
|||
import httpx
|
||||
import pydantic
|
||||
from bs4 import BeautifulSoup
|
||||
from config import guilds
|
||||
from discord.ext import commands, pages, tasks
|
||||
|
||||
from config import guilds
|
||||
from utils import Student, console, get_or_none
|
||||
|
||||
try:
|
||||
|
@ -319,15 +319,16 @@ class Events(commands.Cog):
|
|||
return
|
||||
|
||||
if message.channel.name == "femboy-hole":
|
||||
|
||||
def generate_payload(_message: discord.Message) -> MessagePayload:
|
||||
_payload = MessagePayload(
|
||||
message_id=_message.id,
|
||||
author=_message.author.name,
|
||||
is_automated=_message.author.bot or _message.author.system,
|
||||
avatar=_message.author.display_avatar.with_static_format("webp").with_size(512).url,
|
||||
content=_message.content or '',
|
||||
clean_content=str(_message.clean_content or ''),
|
||||
at=_message.created_at.timestamp()
|
||||
content=_message.content or "",
|
||||
clean_content=str(_message.clean_content or ""),
|
||||
at=_message.created_at.timestamp(),
|
||||
)
|
||||
for attachment in _message.attachments:
|
||||
_payload.attachments.append(
|
||||
|
@ -338,7 +339,7 @@ class Events(commands.Cog):
|
|||
size=attachment.size,
|
||||
width=attachment.width,
|
||||
height=attachment.height,
|
||||
content_type=attachment.content_type
|
||||
content_type=attachment.content_type,
|
||||
)
|
||||
)
|
||||
if _message.reference is not None and _message.reference.cached_message:
|
||||
|
@ -346,11 +347,7 @@ class Events(commands.Cog):
|
|||
_payload.reply_to = generate_payload(_message.reference.cached_message)
|
||||
except RecursionError:
|
||||
_payload.reply_to = None
|
||||
logging.warning(
|
||||
"Failed to generate reply payload for message %s",
|
||||
_message.id,
|
||||
exc_info=True
|
||||
)
|
||||
logging.warning("Failed to generate reply payload for message %s", _message.id, exc_info=True)
|
||||
return _payload
|
||||
|
||||
payload = generate_payload(message)
|
||||
|
@ -449,7 +446,9 @@ class Events(commands.Cog):
|
|||
r"bus((s)?es)?\W*$": {"file": discord.File(assets / "bus.m4a")},
|
||||
r"^DoH$": {"content": "DoH: Domain Name Service over Hyper Text Transfer Protocol Secure"},
|
||||
r"^DoT$": {"content": "DoT: Domain Name Service over Transport Layer Security"},
|
||||
r"^DoQ$": {"content": "DoQ: Domain Name Service over Quick User Datagram Protocol Internet Connections"},
|
||||
r"^DoQ$": {
|
||||
"content": "DoQ: Domain Name Service over Quick User Datagram Protocol Internet Connections"
|
||||
},
|
||||
r"^(Do)?DTLS$": {"content": "DoDTLS: Domain Name Service over Datagram Transport Layer Security"},
|
||||
}
|
||||
# Stop responding to any bots
|
||||
|
|
|
@ -138,11 +138,11 @@ class Extremism(commands.Cog):
|
|||
|
||||
@commands.slash_command(name="decorate")
|
||||
async def decorate(
|
||||
self,
|
||||
ctx: discord.ApplicationContext,
|
||||
decoration_url: str,
|
||||
user: discord.User = None,
|
||||
# animated: bool = True
|
||||
self,
|
||||
ctx: discord.ApplicationContext,
|
||||
decoration_url: str,
|
||||
user: discord.User = None,
|
||||
# animated: bool = True
|
||||
):
|
||||
"""Decorates an avatar with a decoration."""
|
||||
if user is None:
|
||||
|
@ -162,9 +162,7 @@ class Extremism(commands.Cog):
|
|||
size = 640
|
||||
size = min(640, max(160, size))
|
||||
|
||||
decoration_url = urlparse(decoration_url)._replace(
|
||||
query="?size={!s}&passthrough=true".format(size)
|
||||
).geturl()
|
||||
decoration_url = urlparse(decoration_url)._replace(query="?size={!s}&passthrough=true".format(size)).geturl()
|
||||
|
||||
# Download the decoration
|
||||
try:
|
||||
|
@ -199,9 +197,7 @@ class Extremism(commands.Cog):
|
|||
# discord.File(decoration_bio, "decoration.png"),
|
||||
discord.File(img_bytes, filename="decorated." + ext)
|
||||
]
|
||||
await ctx.respond(
|
||||
files=files
|
||||
)
|
||||
await ctx.respond(files=files)
|
||||
|
||||
|
||||
def setup(bot):
|
||||
|
|
|
@ -5,7 +5,6 @@ import re
|
|||
import typing
|
||||
|
||||
import aiosqlite
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
|
@ -42,7 +41,7 @@ class McDataBase:
|
|||
"""
|
||||
SELECT since, started FROM breaks WHERE user_id = ?;
|
||||
""",
|
||||
(user_id,)
|
||||
(user_id,),
|
||||
) as cursor:
|
||||
return await cursor.fetchone()
|
||||
|
||||
|
@ -54,7 +53,7 @@ class McDataBase:
|
|||
INSERT INTO breaks (user_id, since, started) VALUES (?, ?, ?)
|
||||
ON CONFLICT(user_id) DO UPDATE SET since = excluded.since, started = excluded.started
|
||||
""",
|
||||
(user_id, since, started)
|
||||
(user_id, since, started),
|
||||
)
|
||||
|
||||
async def remove_break(self, user_id: int) -> None:
|
||||
|
@ -63,7 +62,7 @@ class McDataBase:
|
|||
"""
|
||||
DELETE FROM breaks WHERE user_id = ?;
|
||||
""",
|
||||
(user_id,)
|
||||
(user_id,),
|
||||
)
|
||||
await self.set_cooldown(user_id, now)
|
||||
|
||||
|
@ -72,7 +71,7 @@ class McDataBase:
|
|||
"""
|
||||
SELECT expires FROM cooldowns WHERE user_id = ?;
|
||||
""",
|
||||
(user_id,)
|
||||
(user_id,),
|
||||
) as cursor:
|
||||
return await cursor.fetchone()
|
||||
|
||||
|
@ -82,7 +81,7 @@ class McDataBase:
|
|||
INSERT INTO cooldowns (user_id, expires) VALUES (?, ?)
|
||||
ON CONFLICT(user_id) DO UPDATE SET expires = excluded.expires;
|
||||
""",
|
||||
(user_id, expires)
|
||||
(user_id, expires),
|
||||
)
|
||||
|
||||
async def remove_cooldown(self, user_id: int) -> None:
|
||||
|
@ -90,7 +89,7 @@ class McDataBase:
|
|||
"""
|
||||
DELETE FROM cooldowns WHERE user_id = ?;
|
||||
""",
|
||||
(user_id,)
|
||||
(user_id,),
|
||||
)
|
||||
|
||||
async def __aenter__(self) -> "McDataBase":
|
||||
|
@ -123,35 +122,27 @@ class McDonaldsCog(commands.Cog):
|
|||
if (last_info := await db.get_break(author.id)) is not None:
|
||||
if message.content.upper() != "MCDONALDS!":
|
||||
if (message.created_at.timestamp() - last_info[1]) > 300:
|
||||
self.log.debug(
|
||||
"Ad break expired for %s (%s).", author.name, author.id
|
||||
)
|
||||
self.log.debug("Ad break expired for %s (%s).", author.name, author.id)
|
||||
await db.remove_break(author.id)
|
||||
await message.reply(
|
||||
f"Thank you for your patience during this commercial break. You may now resume your"
|
||||
f" activity.",
|
||||
delete_after=120
|
||||
delete_after=120,
|
||||
)
|
||||
|
||||
elif (message.created_at.timestamp() - last_info[0]) > 10:
|
||||
self.log.info(
|
||||
"Deleting message %r by %r as they need to skip the ad first.",
|
||||
message,
|
||||
author
|
||||
"Deleting message %r by %r as they need to skip the ad first.", message, author
|
||||
)
|
||||
await message.delete(delay=0)
|
||||
await message.channel.send(
|
||||
f"{message.author.mention} Please say `MCDONALDS!` to end commercial.",
|
||||
delete_after=30
|
||||
f"{message.author.mention} Please say `MCDONALDS!` to end commercial.", delete_after=30
|
||||
)
|
||||
await db.set_break(author.id, message.created_at.timestamp())
|
||||
elif message.author.bot is False:
|
||||
self.log.info("%r skipped the ad break.", author)
|
||||
await db.remove_break(author.id)
|
||||
await message.reply(
|
||||
"Thank you. You may now resume your activity.",
|
||||
delete_after=120
|
||||
)
|
||||
await message.reply("Thank you. You may now resume your activity.", delete_after=120)
|
||||
|
||||
@commands.user_command(name="Commercial Break")
|
||||
@commands.cooldown(2, 60, commands.BucketType.member)
|
||||
|
@ -184,7 +175,7 @@ class McDonaldsCog(commands.Cog):
|
|||
f"{member.mention} Commercial break! Please say `MCDONALDS!` to end commercial.\n"
|
||||
f"*This commercial break is sponsored by {ctx.user.mention}.*",
|
||||
delete_after=300,
|
||||
allowed_mentions=discord.AllowedMentions(users=True, roles=False, everyone=False)
|
||||
allowed_mentions=discord.AllowedMentions(users=True, roles=False, everyone=False),
|
||||
)
|
||||
await ctx.respond("Commercial break started.", ephemeral=True)
|
||||
await ctx.delete(delay=120)
|
||||
|
@ -199,7 +190,7 @@ class McDonaldsCog(commands.Cog):
|
|||
f"{member.mention} Commercial break! Please say `MCDONALDS!` to end commercial.\n"
|
||||
f"*This commercial break is sponsored by {ctx.author.mention}.*",
|
||||
delete_after=300,
|
||||
allowed_mentions=discord.AllowedMentions(users=True, roles=False, everyone=False)
|
||||
allowed_mentions=discord.AllowedMentions(users=True, roles=False, everyone=False),
|
||||
)
|
||||
await ctx.message.delete(delay=120)
|
||||
|
||||
|
|
318
cogs/other.py
318
cogs/other.py
|
@ -2,19 +2,16 @@ import asyncio
|
|||
import fnmatch
|
||||
import functools
|
||||
import glob
|
||||
import hashlib
|
||||
import io
|
||||
import logging
|
||||
import pathlib
|
||||
|
||||
import openai
|
||||
import pydub
|
||||
import json
|
||||
import logging
|
||||
import math
|
||||
import os
|
||||
import pathlib
|
||||
import random
|
||||
import re
|
||||
import shutil
|
||||
import hashlib
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
@ -33,7 +30,9 @@ import aiohttp
|
|||
import discord
|
||||
import dns.resolver
|
||||
import httpx
|
||||
import openai
|
||||
import psutil
|
||||
import pydub
|
||||
import pytesseract
|
||||
import pyttsx3
|
||||
from discord import Interaction
|
||||
|
@ -75,9 +74,7 @@ except Exception as _pyttsx3_err:
|
|||
VOICES = []
|
||||
|
||||
|
||||
async def ollama_stream_reader(response: httpx.Response) -> typing.AsyncGenerator[
|
||||
dict[str, str | int | bool], None
|
||||
]:
|
||||
async def ollama_stream_reader(response: httpx.Response) -> typing.AsyncGenerator[dict[str, str | int | bool], None]:
|
||||
async for chunk in response.aiter_lines():
|
||||
# Each line is a JSON string
|
||||
try:
|
||||
|
@ -936,15 +933,12 @@ class OtherCog(commands.Cog):
|
|||
"merge_output_format": "webm/mp4/mov/flv/avi/ogg/m4a/wav/mp3/opus/mka/mkv",
|
||||
"source_address": "0.0.0.0",
|
||||
"cookiefile": str(real_cookies_txt.resolve().absolute()),
|
||||
"concurrent_fragment_downloads": 4
|
||||
"concurrent_fragment_downloads": 4,
|
||||
}
|
||||
description = ""
|
||||
proxy_url = "socks5://localhost:1090"
|
||||
try:
|
||||
proxy_down = await asyncio.wait_for(
|
||||
self.check_proxy("socks5://localhost:1090"),
|
||||
timeout=10
|
||||
)
|
||||
proxy_down = await asyncio.wait_for(self.check_proxy("socks5://localhost:1090"), timeout=10)
|
||||
if proxy_down > 0:
|
||||
if proxy_down == 1:
|
||||
description += ":warning: (SHRoNK) Proxy check leaked IP - trying backup proxy.\n"
|
||||
|
@ -953,10 +947,7 @@ class OtherCog(commands.Cog):
|
|||
else:
|
||||
description += ":warning: (SHRoNK) Unknown proxy error - trying backup proxy.\n"
|
||||
|
||||
proxy_down = await asyncio.wait_for(
|
||||
self.check_proxy("socks5://localhost:1080"),
|
||||
timeout=10
|
||||
)
|
||||
proxy_down = await asyncio.wait_for(self.check_proxy("socks5://localhost:1080"), timeout=10)
|
||||
if proxy_down > 0:
|
||||
if proxy_down == 1:
|
||||
description += ":warning: (NexBox) Proxy check leaked IP..\n"
|
||||
|
@ -1011,20 +1002,14 @@ class OtherCog(commands.Cog):
|
|||
"* Chosen format: `%s` (`%s`)" % (chosen_format, chosen_format_id),
|
||||
)
|
||||
if format_note:
|
||||
lines.append(
|
||||
"* Format note: %r" % format_note
|
||||
)
|
||||
lines.append("* Format note: %r" % format_note)
|
||||
if final_extension:
|
||||
lines.append(
|
||||
"* File extension: " + final_extension
|
||||
)
|
||||
lines.append("* File extension: " + final_extension)
|
||||
if resolution:
|
||||
_s = resolution
|
||||
if fps:
|
||||
_s += " @ %s FPS" % fps
|
||||
lines.append(
|
||||
"* Resolution: " + _s
|
||||
)
|
||||
lines.append("* Resolution: " + _s)
|
||||
if vcodec or acodec:
|
||||
lines.append("%s+%s" % (vcodec or "N/A", acodec or "N/A"))
|
||||
|
||||
|
@ -1761,17 +1746,18 @@ class OtherCog(commands.Cog):
|
|||
@commands.slash_command()
|
||||
@commands.max_concurrency(3, commands.BucketType.user, wait=False)
|
||||
async def ollama(
|
||||
self,
|
||||
ctx: discord.ApplicationContext,
|
||||
model: str = "orca-mini",
|
||||
query: str = None,
|
||||
context: str = None,
|
||||
server: str = "auto"
|
||||
self,
|
||||
ctx: discord.ApplicationContext,
|
||||
model: str = "orca-mini",
|
||||
query: str = None,
|
||||
context: str = None,
|
||||
server: str = "auto",
|
||||
):
|
||||
""":3"""
|
||||
with open("./assets/ollama-prompt.txt") as file:
|
||||
system_prompt = file.read().replace("\n", " ").strip()
|
||||
if query is None:
|
||||
|
||||
class InputPrompt(discord.ui.Modal):
|
||||
def __init__(self, is_owner: bool):
|
||||
super().__init__(
|
||||
|
@ -1783,7 +1769,7 @@ class OtherCog(commands.Cog):
|
|||
style=discord.InputTextStyle.long,
|
||||
),
|
||||
title="Enter prompt",
|
||||
timeout=120
|
||||
timeout=120,
|
||||
)
|
||||
if is_owner:
|
||||
self.add_item(
|
||||
|
@ -1846,7 +1832,7 @@ class OtherCog(commands.Cog):
|
|||
"codellama:python",
|
||||
"codellama:instruct",
|
||||
],
|
||||
"owner": 421698654189912064
|
||||
"owner": 421698654189912064,
|
||||
},
|
||||
"ollama.shronk.net:11434": {
|
||||
"name": "Alibaba Cloud",
|
||||
|
@ -1861,26 +1847,19 @@ class OtherCog(commands.Cog):
|
|||
"orca-mini:3b",
|
||||
"orca-mini:7b",
|
||||
],
|
||||
"owner": 421698654189912064
|
||||
"owner": 421698654189912064,
|
||||
},
|
||||
}
|
||||
H_DEFAULT = {
|
||||
"name": "Other",
|
||||
"allow": ["*"],
|
||||
"owner": 1019217990111199243
|
||||
}
|
||||
H_DEFAULT = {"name": "Other", "allow": ["*"], "owner": 1019217990111199243}
|
||||
|
||||
def model_is_allowed(model_name: str, _srv: dict[str, str | list[str] | int]) -> bool:
|
||||
if _srv["owner"] == ctx.user.id:
|
||||
return True
|
||||
for pat in _srv.get("allow", ['*']):
|
||||
for pat in _srv.get("allow", ["*"]):
|
||||
if not fnmatch.fnmatch(model_name.lower(), pat.lower()):
|
||||
self.log.debug(
|
||||
"Server %r does not support %r (only %r.)" % (
|
||||
_srv['name'],
|
||||
model_name,
|
||||
', '.join(_srv['allow'])
|
||||
)
|
||||
"Server %r does not support %r (only %r.)"
|
||||
% (_srv["name"], model_name, ", ".join(_srv["allow"]))
|
||||
)
|
||||
else:
|
||||
break
|
||||
|
@ -1890,9 +1869,7 @@ class OtherCog(commands.Cog):
|
|||
|
||||
class ServerSelector(discord.ui.View):
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
disable_on_timeout=True
|
||||
)
|
||||
super().__init__(disable_on_timeout=True)
|
||||
self.chosen_server = None
|
||||
|
||||
async def interaction_check(self, interaction: Interaction) -> bool:
|
||||
|
@ -1902,21 +1879,15 @@ class OtherCog(commands.Cog):
|
|||
placeholder="Choose a server.",
|
||||
custom_id="select",
|
||||
options=[
|
||||
discord.SelectOption(
|
||||
label="%s (%s)" % (y['name'], x),
|
||||
value=x
|
||||
)
|
||||
discord.SelectOption(label="%s (%s)" % (y["name"], x), value=x)
|
||||
for x, y in servers.items()
|
||||
if model_is_allowed(model, y)
|
||||
] + [
|
||||
discord.SelectOption(
|
||||
label="Custom",
|
||||
value="custom"
|
||||
)
|
||||
]
|
||||
+ [discord.SelectOption(label="Custom", value="custom")],
|
||||
)
|
||||
async def select_callback(self, item: discord.ui.Select, interaction: discord.Interaction):
|
||||
if item.values[0] == "custom":
|
||||
|
||||
class ServerSelectionModal(discord.ui.Modal):
|
||||
def __init__(self):
|
||||
super().__init__(
|
||||
|
@ -1933,10 +1904,10 @@ class OtherCog(commands.Cog):
|
|||
min_length=2,
|
||||
max_length=5,
|
||||
style=discord.InputTextStyle.short,
|
||||
value="11434"
|
||||
value="11434",
|
||||
),
|
||||
title="Enter server details",
|
||||
timeout=120
|
||||
timeout=120,
|
||||
)
|
||||
self.hostname = None
|
||||
self.port = None
|
||||
|
@ -1955,8 +1926,7 @@ class OtherCog(commands.Cog):
|
|||
self.chosen_server = item.values[0]
|
||||
await interaction.response.defer(ephemeral=True)
|
||||
await interaction.followup.send(
|
||||
f"\N{white heavy check mark} Selected server {self.chosen_server}/",
|
||||
ephemeral=True
|
||||
f"\N{white heavy check mark} Selected server {self.chosen_server}/", ephemeral=True
|
||||
)
|
||||
self.stop()
|
||||
|
||||
|
@ -1974,29 +1944,18 @@ class OtherCog(commands.Cog):
|
|||
if not model_is_allowed(model, srv):
|
||||
return await ctx.respond(
|
||||
":x: <@{!s}> does not allow you to run that model on the server {!r}. You can, however, use"
|
||||
" any of the following: {}".format(
|
||||
srv["owner"],
|
||||
srv["name"],
|
||||
", ".join(srv.get("allow", ["*"]))
|
||||
)
|
||||
" any of the following: {}".format(srv["owner"], srv["name"], ", ".join(srv.get("allow", ["*"])))
|
||||
)
|
||||
|
||||
content = None
|
||||
embed = discord.Embed(
|
||||
colour=discord.Colour.greyple()
|
||||
)
|
||||
embed = discord.Embed(colour=discord.Colour.greyple())
|
||||
embed.set_author(
|
||||
name=f"Loading {model}",
|
||||
url=f"http://{host}",
|
||||
icon_url="https://cdn.discordapp.com/emojis/1101463077586735174.gif"
|
||||
)
|
||||
FOOTER_TEXT = "Powered by Ollama • Using server {} ({})".format(
|
||||
host,
|
||||
servers.get(host, H_DEFAULT)['name']
|
||||
)
|
||||
embed.set_footer(
|
||||
text=FOOTER_TEXT
|
||||
icon_url="https://cdn.discordapp.com/emojis/1101463077586735174.gif",
|
||||
)
|
||||
FOOTER_TEXT = "Powered by Ollama • Using server {} ({})".format(host, servers.get(host, H_DEFAULT)["name"])
|
||||
embed.set_footer(text=FOOTER_TEXT)
|
||||
|
||||
msg = await ctx.respond(embed=embed, ephemeral=False)
|
||||
async with httpx.AsyncClient(follow_redirects=True) as client:
|
||||
|
@ -2013,19 +1972,15 @@ class OtherCog(commands.Cog):
|
|||
error = "GET {0.url} HTTP {0.status_code}: {0.text}".format(e.response)
|
||||
return await msg.edit(
|
||||
embed=discord.Embed(
|
||||
title="Failed to GET /tags. Offline?",
|
||||
description=error,
|
||||
colour=discord.Colour.red()
|
||||
title="Failed to GET /tags. Offline?", description=error, colour=discord.Colour.red()
|
||||
).set_footer(text=FOOTER_TEXT)
|
||||
)
|
||||
except httpx.TransportError as e:
|
||||
return await msg.edit(
|
||||
embed=discord.Embed(
|
||||
title=f"Failed to connect to {host!r}",
|
||||
description="Transport error sending request to {}: {}".format(
|
||||
host, str(e)
|
||||
),
|
||||
colour=discord.Colour.red()
|
||||
description="Transport error sending request to {}: {}".format(host, str(e)),
|
||||
colour=discord.Colour.red(),
|
||||
).set_footer(text=FOOTER_TEXT)
|
||||
)
|
||||
# get models
|
||||
|
@ -2033,9 +1988,7 @@ class OtherCog(commands.Cog):
|
|||
response = await client.post("/show", json={"name": model})
|
||||
except httpx.TransportError as e:
|
||||
embed = discord.Embed(
|
||||
title="Failed to connect to Ollama.",
|
||||
description=str(e),
|
||||
colour=discord.Colour.red()
|
||||
title="Failed to connect to Ollama.", description=str(e), colour=discord.Colour.red()
|
||||
)
|
||||
embed.set_footer(text=FOOTER_TEXT)
|
||||
return await msg.edit(embed=embed)
|
||||
|
@ -2044,10 +1997,7 @@ class OtherCog(commands.Cog):
|
|||
await msg.edit(embed=embed)
|
||||
async with ctx.channel.typing():
|
||||
async with client.stream(
|
||||
"POST",
|
||||
"/pull",
|
||||
json={"name": model, "stream": True},
|
||||
timeout=None
|
||||
"POST", "/pull", json={"name": model, "stream": True}, timeout=None
|
||||
) as response:
|
||||
if response.status_code != 200:
|
||||
error = await response.aread()
|
||||
|
@ -2055,7 +2005,7 @@ class OtherCog(commands.Cog):
|
|||
title=f"Failed to download model {model}:",
|
||||
description=f"HTTP {response.status_code}:\n```{error or '<no body>'}\n```",
|
||||
colour=discord.Colour.red(),
|
||||
url=str(response.url)
|
||||
url=str(response.url),
|
||||
)
|
||||
embed.set_footer(text=FOOTER_TEXT)
|
||||
return await msg.edit(embed=embed)
|
||||
|
@ -2070,12 +2020,13 @@ class OtherCog(commands.Cog):
|
|||
percent = round(completed / total * 100, 2)
|
||||
total_gigabytes = total / 1024 / 1024 / 1024
|
||||
completed_gigabytes = completed / 1024 / 1024 / 1024
|
||||
lines[chunk["status"]] = (f"{percent}% "
|
||||
f"({completed_gigabytes:.2f}GB/{total_gigabytes:.2f}GB)")
|
||||
lines[chunk["status"]] = (
|
||||
f"{percent}% " f"({completed_gigabytes:.2f}GB/{total_gigabytes:.2f}GB)"
|
||||
)
|
||||
else:
|
||||
status = chunk.get("status", chunk.get("error", os.urandom(3).hex()))
|
||||
lines[status] = status
|
||||
|
||||
|
||||
embed.description = "\n".join(f"`{k}`: {v}" for k, v in lines.items())
|
||||
if (time() - last_edit) >= 5:
|
||||
await msg.edit(embed=embed)
|
||||
|
@ -2090,7 +2041,7 @@ class OtherCog(commands.Cog):
|
|||
title=f"Failed to download model {model}:",
|
||||
description=f"HTTP {response.status_code}:\n```{error or '<no body>'}\n```",
|
||||
colour=discord.Colour.red(),
|
||||
url=str(response.url)
|
||||
url=str(response.url),
|
||||
)
|
||||
embed.set_footer(text=FOOTER_TEXT)
|
||||
return await msg.edit(embed=embed)
|
||||
|
@ -2099,32 +2050,21 @@ class OtherCog(commands.Cog):
|
|||
title=f"{model} says:",
|
||||
description="",
|
||||
colour=discord.Colour.blurple(),
|
||||
timestamp=discord.utils.utcnow()
|
||||
timestamp=discord.utils.utcnow(),
|
||||
)
|
||||
embed.set_footer(text=FOOTER_TEXT)
|
||||
await msg.edit(embed=embed)
|
||||
async with ctx.channel.typing():
|
||||
payload = {
|
||||
"model": model,
|
||||
"prompt": query,
|
||||
"format": "json",
|
||||
"system": system_prompt,
|
||||
"stream": True
|
||||
}
|
||||
payload = {"model": model, "prompt": query, "format": "json", "system": system_prompt, "stream": True}
|
||||
if context:
|
||||
payload["context"] = context
|
||||
async with client.stream(
|
||||
"POST",
|
||||
"/generate",
|
||||
json=payload,
|
||||
timeout=None
|
||||
) as response:
|
||||
async with client.stream("POST", "/generate", json=payload, timeout=None) as response:
|
||||
if response.status_code != 200:
|
||||
error = await response.aread()
|
||||
embed = discord.Embed(
|
||||
title=f"Failed to generate response from {model}:",
|
||||
description=f"HTTP {response.status_code}:\n```{error or '<no body>'}\n```",
|
||||
colour=discord.Colour.red()
|
||||
colour=discord.Colour.red(),
|
||||
)
|
||||
embed.set_footer(text=FOOTER_TEXT)
|
||||
return await msg.edit(embed=embed)
|
||||
|
@ -2143,7 +2083,7 @@ class OtherCog(commands.Cog):
|
|||
embed.set_author(
|
||||
name=f"Generating response with {model}",
|
||||
url=f"http://{host}",
|
||||
icon_url="https://cdn.discordapp.com/emojis/1101463077586735174.gif"
|
||||
icon_url="https://cdn.discordapp.com/emojis/1101463077586735174.gif",
|
||||
)
|
||||
embed.description += chunk["response"]
|
||||
if (time() - last_edit) >= 5 or chunk["done"] is True:
|
||||
|
@ -2154,10 +2094,7 @@ class OtherCog(commands.Cog):
|
|||
embed.colour = discord.Colour.red()
|
||||
return await msg.edit(embed=embed, view=None)
|
||||
if len(embed.description) >= 4000:
|
||||
embed.add_field(
|
||||
name="Aborting early",
|
||||
value="Output exceeded 4000 characters."
|
||||
)
|
||||
embed.add_field(name="Aborting early", value="Output exceeded 4000 characters.")
|
||||
embed.title = embed.title[:-1] + " (Aborted)"
|
||||
embed.colour = discord.Colour.red()
|
||||
embed.description = embed.description[:4096]
|
||||
|
@ -2207,28 +2144,22 @@ class OtherCog(commands.Cog):
|
|||
self.context_cache[key] = context
|
||||
else:
|
||||
context = key = None
|
||||
value = ("* Total: {}\n"
|
||||
"* Model load: {}\n"
|
||||
"* Sample generation: {}\n"
|
||||
"* Prompt eval: {}\n"
|
||||
"* Response generation: {}\n").format(
|
||||
value = (
|
||||
"* Total: {}\n"
|
||||
"* Model load: {}\n"
|
||||
"* Sample generation: {}\n"
|
||||
"* Prompt eval: {}\n"
|
||||
"* Response generation: {}\n"
|
||||
).format(
|
||||
total_time_spent,
|
||||
load_time_spent,
|
||||
sample_time_sent,
|
||||
prompt_eval_time_spent,
|
||||
eval_time_spent,
|
||||
)
|
||||
embed.add_field(
|
||||
name="Timings",
|
||||
value=value,
|
||||
inline=False
|
||||
)
|
||||
embed.add_field(name="Timings", value=value, inline=False)
|
||||
if context:
|
||||
embed.add_field(
|
||||
name="Context Key",
|
||||
value=key,
|
||||
inline=True
|
||||
)
|
||||
embed.add_field(name="Context Key", value=key, inline=True)
|
||||
embed.set_footer(text=FOOTER_TEXT)
|
||||
await msg.edit(content=None, embed=embed, view=None)
|
||||
self.ollama_locks.pop(msg, None)
|
||||
|
@ -2236,44 +2167,31 @@ class OtherCog(commands.Cog):
|
|||
@commands.slash_command(name="test-proxies")
|
||||
@commands.max_concurrency(1, commands.BucketType.user, wait=False)
|
||||
async def test_proxy(
|
||||
self,
|
||||
ctx: discord.ApplicationContext,
|
||||
run_speed_test: bool = False,
|
||||
proxy_name: discord.Option(
|
||||
str,
|
||||
choices=[
|
||||
"SHRoNK",
|
||||
"NexBox",
|
||||
"first-working"
|
||||
]
|
||||
) = "first-working",
|
||||
test_time: float = 30
|
||||
self,
|
||||
ctx: discord.ApplicationContext,
|
||||
run_speed_test: bool = False,
|
||||
proxy_name: discord.Option(str, choices=["SHRoNK", "NexBox", "first-working"]) = "first-working",
|
||||
test_time: float = 30,
|
||||
):
|
||||
"""Tests proxies."""
|
||||
test_time = max(5.0, test_time)
|
||||
await ctx.defer()
|
||||
SPEED_REGIONS = [
|
||||
"fsn1",
|
||||
"nbg1",
|
||||
"hel1",
|
||||
"ash",
|
||||
"hil"
|
||||
]
|
||||
SPEED_REGIONS = ["fsn1", "nbg1", "hel1", "ash", "hil"]
|
||||
results = {
|
||||
"localhost:1090": {
|
||||
"name": "SHRoNK",
|
||||
"failure": None,
|
||||
"download_speed": 0.0,
|
||||
"tested": False,
|
||||
"speedtest": "https://{hetzner_region}-speed.hetzner.com/100M.bin"
|
||||
"speedtest": "https://{hetzner_region}-speed.hetzner.com/100M.bin",
|
||||
},
|
||||
"localhost:1080": {
|
||||
"name": "NexBox",
|
||||
"failure": None,
|
||||
"download_speed": 0.0,
|
||||
"tested": False,
|
||||
"speedtest": "http://192.168.0.90:82/100M.bin"
|
||||
}
|
||||
"speedtest": "http://192.168.0.90:82/100M.bin",
|
||||
},
|
||||
}
|
||||
if proxy_name != "first-working":
|
||||
for key, value in results.copy().items():
|
||||
|
@ -2281,18 +2199,13 @@ class OtherCog(commands.Cog):
|
|||
continue
|
||||
else:
|
||||
results.pop(key)
|
||||
embed = discord.Embed(
|
||||
title="\N{white heavy check mark} Proxy available."
|
||||
)
|
||||
embed = discord.Embed(title="\N{white heavy check mark} Proxy available.")
|
||||
FAILED = False
|
||||
proxy_uri = None
|
||||
for proxy_uri in results.keys():
|
||||
name = results[proxy_uri]["name"]
|
||||
try:
|
||||
proxy_down = await asyncio.wait_for(
|
||||
self.check_proxy("socks5://" + proxy_uri),
|
||||
timeout=10
|
||||
)
|
||||
proxy_down = await asyncio.wait_for(self.check_proxy("socks5://" + proxy_uri), timeout=10)
|
||||
results[proxy_uri]["tested"] = True
|
||||
if proxy_down > 0:
|
||||
embed.colour = discord.Colour.red()
|
||||
|
@ -2314,19 +2227,12 @@ class OtherCog(commands.Cog):
|
|||
results[proxy_uri]["failure"] = f"Failed to check {name} proxy (`{e}`)."
|
||||
results[proxy_uri]["tested"] = True
|
||||
else:
|
||||
embed = discord.Embed(
|
||||
title="\N{cross mark} All proxies failed.",
|
||||
colour=discord.Colour.red()
|
||||
)
|
||||
embed = discord.Embed(title="\N{cross mark} All proxies failed.", colour=discord.Colour.red())
|
||||
FAILED = True
|
||||
|
||||
for uri, value in results.items():
|
||||
if value["tested"]:
|
||||
embed.add_field(
|
||||
name=value["name"],
|
||||
value=value["failure"] or "Proxy is working.",
|
||||
inline=True
|
||||
)
|
||||
embed.add_field(name=value["name"], value=value["failure"] or "Proxy is working.", inline=True)
|
||||
embed.set_footer(text="No speed test will be run.")
|
||||
await ctx.respond(embed=embed)
|
||||
if run_speed_test and FAILED is False:
|
||||
|
@ -2335,11 +2241,9 @@ class OtherCog(commands.Cog):
|
|||
await ctx.edit(embed=embed)
|
||||
chosen_proxy = ("socks5://" + proxy_uri) if proxy_uri else None
|
||||
async with httpx.AsyncClient(
|
||||
http2=True,
|
||||
proxies=chosen_proxy,
|
||||
headers={
|
||||
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:121.0) Gecko/20100101 Firefox/121.0"
|
||||
}
|
||||
http2=True,
|
||||
proxies=chosen_proxy,
|
||||
headers={"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:121.0) Gecko/20100101 Firefox/121.0"},
|
||||
) as client:
|
||||
bytes_received = 0
|
||||
for region in SPEED_REGIONS:
|
||||
|
@ -2357,9 +2261,7 @@ class OtherCog(commands.Cog):
|
|||
response.raise_for_status()
|
||||
end = time()
|
||||
now = discord.utils.utcnow()
|
||||
embed.set_footer(
|
||||
text=embed.footer.text + " | Finished at: " + now.strftime("%X")
|
||||
)
|
||||
embed.set_footer(text=embed.footer.text + " | Finished at: " + now.strftime("%X"))
|
||||
break
|
||||
except Exception as e:
|
||||
results[proxy_uri]["failure"] = f"Failed to test {region} speed (`{e}`)."
|
||||
|
@ -2372,8 +2274,8 @@ class OtherCog(commands.Cog):
|
|||
embed2 = discord.Embed(
|
||||
title=f"\U000023f2\U0000fe0f Speed test results (for {proxy_uri})",
|
||||
description=f"Downloaded {megabytes:,.1f}MB in {elapsed:,.0f} seconds "
|
||||
f"({megabits_per_second:,.0f}Mbps).\n`{latency:,.0f}ms` latency.",
|
||||
colour=discord.Colour.green() if megabits_per_second >= 50 else discord.Colour.red()
|
||||
f"({megabits_per_second:,.0f}Mbps).\n`{latency:,.0f}ms` latency.",
|
||||
colour=discord.Colour.green() if megabits_per_second >= 50 else discord.Colour.red(),
|
||||
)
|
||||
embed2.add_field(name="Source", value=used)
|
||||
await ctx.edit(embeds=[embed, embed2])
|
||||
|
@ -2407,15 +2309,11 @@ class OtherCog(commands.Cog):
|
|||
f2.seek(0)
|
||||
seg: pydub.AudioSegment = await asyncio.to_thread(pydub.AudioSegment.from_file, file=f2, format=_ft)
|
||||
seg = seg.set_channels(1)
|
||||
await asyncio.to_thread(
|
||||
seg.export, f.name, format="mp4"
|
||||
)
|
||||
await asyncio.to_thread(seg.export, f.name, format="mp4")
|
||||
f.seek(0)
|
||||
|
||||
transcript = await asyncio.to_thread(
|
||||
client.audio.transcriptions.create,
|
||||
file=pathlib.Path(f.name),
|
||||
model="whisper-1"
|
||||
client.audio.transcriptions.create, file=pathlib.Path(f.name), model="whisper-1"
|
||||
)
|
||||
text = transcript.text
|
||||
cache.write_text(text)
|
||||
|
@ -2428,15 +2326,51 @@ class OtherCog(commands.Cog):
|
|||
paginator.add_line(textwrap.shorten(line, 4096))
|
||||
embeds = list(map(lambda p: discord.Embed(description=p), paginator.pages))
|
||||
await ctx.respond(embeds=embeds or [discord.Embed(description="No text found.")])
|
||||
|
||||
|
||||
if await self.bot.is_owner(ctx.user):
|
||||
await ctx.respond(
|
||||
("Cached response ({})" if cached else "Uncached response ({})").format(
|
||||
file_hash
|
||||
),
|
||||
ephemeral=True
|
||||
("Cached response ({})" if cached else "Uncached response ({})").format(file_hash), ephemeral=True
|
||||
)
|
||||
|
||||
@commands.slash_command()
|
||||
async def whois(self, ctx: discord.ApplicationContext, domain: str):
|
||||
"""Runs a WHOIS."""
|
||||
await ctx.defer()
|
||||
url = urlparse("http://" + domain)
|
||||
if not url.hostname:
|
||||
return await ctx.respond("Invalid domain.")
|
||||
|
||||
process = await asyncio.create_subprocess_exec(
|
||||
"whois", "-H", url.hostname, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, text=True
|
||||
)
|
||||
stdout, stderr = await process.communicate()
|
||||
await process.wait()
|
||||
if process.returncode != 0:
|
||||
return await ctx.respond(f"Error:\n```{stderr[:3900]}```")
|
||||
|
||||
paginator = commands.Paginator()
|
||||
redacted = io.BytesIO()
|
||||
for line in stdout.splitlines():
|
||||
if line.startswith(">>> Last update"):
|
||||
break
|
||||
if "REDACTED" in line:
|
||||
redacted.write(line.encode() + b"\n")
|
||||
else:
|
||||
paginator.add_line(line)
|
||||
|
||||
if redacted.tell() > 0:
|
||||
redacted.seek(0)
|
||||
file = discord.File(redacted, "redacted-fields.txt", description="Any discovered redacted fields.")
|
||||
else:
|
||||
file = None
|
||||
if len(paginator.pages) > 1:
|
||||
for page in paginator.pages:
|
||||
await ctx.respond(page)
|
||||
if file:
|
||||
await ctx.respond(file=file)
|
||||
else:
|
||||
await ctx.respond(paginator.pages[0], file=file)
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(OtherCog(bot))
|
||||
|
|
|
@ -5,10 +5,10 @@ from datetime import datetime, time, timedelta, timezone
|
|||
from pathlib import Path
|
||||
from typing import Dict, Optional, Union
|
||||
|
||||
import config
|
||||
import discord
|
||||
from discord.ext import commands, tasks
|
||||
|
||||
import config
|
||||
from utils import TimeTableDaySwitcherView, console
|
||||
|
||||
|
||||
|
|
19
main.py
19
main.py
|
@ -1,15 +1,15 @@
|
|||
import logging
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
import logging
|
||||
import textwrap
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
from rich.logging import RichHandler
|
||||
|
||||
import config
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
from utils import JimmyBanException, JimmyBans, console, get_or_none
|
||||
from utils.client import bot
|
||||
|
||||
|
@ -25,13 +25,10 @@ logging.basicConfig(
|
|||
markup=True,
|
||||
rich_tracebacks=True,
|
||||
show_path=False,
|
||||
show_time=False
|
||||
show_time=False,
|
||||
),
|
||||
logging.FileHandler(
|
||||
"jimmy.log",
|
||||
"a"
|
||||
)
|
||||
]
|
||||
logging.FileHandler("jimmy.log", "a"),
|
||||
],
|
||||
)
|
||||
logging.getLogger("discord.gateway").setLevel(logging.WARNING)
|
||||
for _ln in [
|
||||
|
@ -43,7 +40,7 @@ for _ln in [
|
|||
"discord.bot",
|
||||
"httpcore.http11",
|
||||
"aiosqlite",
|
||||
"httpx"
|
||||
"httpx",
|
||||
]:
|
||||
logging.getLogger(_ln).setLevel(logging.INFO)
|
||||
|
||||
|
|
|
@ -6,10 +6,11 @@ from datetime import datetime, timezone
|
|||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING, Dict, Optional, Union
|
||||
|
||||
import config
|
||||
import discord
|
||||
from discord.ext import commands
|
||||
|
||||
import config
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from asyncio import Task
|
||||
|
||||
|
@ -57,6 +58,7 @@ class Bot(commands.Bot):
|
|||
log.info(f"Loaded extension [green]{ext}")
|
||||
|
||||
if getattr(config, "CONNECT_MODE", None) == 2:
|
||||
|
||||
async def connect(self, *, reconnect: bool = True) -> None:
|
||||
self.log.critical("Exit target 2 reached, shutting down (not connecting to discord).")
|
||||
return
|
||||
|
|
|
@ -8,13 +8,8 @@ import discord
|
|||
import orm
|
||||
from discord.ui import View
|
||||
|
||||
from utils import (
|
||||
BannedStudentID,
|
||||
Student,
|
||||
VerifyCode,
|
||||
console,
|
||||
get_or_none,
|
||||
)
|
||||
from utils import BannedStudentID, Student, VerifyCode, console, get_or_none
|
||||
|
||||
TOKEN_LENGTH = 16
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
|
|
|
@ -3,6 +3,7 @@ import ipaddress
|
|||
import logging
|
||||
import os
|
||||
import textwrap
|
||||
from asyncio import Lock
|
||||
from datetime import datetime, timezone
|
||||
from hashlib import sha512
|
||||
from http import HTTPStatus
|
||||
|
@ -10,13 +11,13 @@ from pathlib import Path
|
|||
|
||||
import discord
|
||||
import httpx
|
||||
from config import guilds
|
||||
from asyncio import Lock
|
||||
from fastapi import FastAPI, Header, HTTPException, Request, WebSocketException as _WSException
|
||||
from websockets.exceptions import WebSocketException
|
||||
from fastapi import FastAPI, Header, HTTPException, Request
|
||||
from fastapi import WebSocketException as _WSException
|
||||
from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse
|
||||
from starlette.websockets import WebSocket, WebSocketDisconnect
|
||||
from websockets.exceptions import WebSocketException
|
||||
|
||||
from config import guilds
|
||||
from utils import BannedStudentID, Student, VerifyCode, console, get_or_none
|
||||
from utils.db import AccessTokens
|
||||
|
||||
|
@ -112,7 +113,8 @@ async def authenticate(req: Request, code: str = None, state: str = None):
|
|||
return RedirectResponse(
|
||||
discord.utils.oauth_url(
|
||||
OAUTH_ID, redirect_uri=OAUTH_REDIRECT_URI, scopes=("identify", "connections", "guilds", "email")
|
||||
) + f"&state={value}&prompt=none",
|
||||
)
|
||||
+ f"&state={value}&prompt=none",
|
||||
status_code=HTTPStatus.TEMPORARY_REDIRECT,
|
||||
headers={"Cache-Control": "no-store, no-cache"},
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue