Add Dockerfile
Update blacklist Clean up e621 code
17
Bot/Dockerfile
Normal file
|
@ -0,0 +1,17 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
FROM alpine:3.18.2
|
||||
|
||||
EXPOSE 8000
|
||||
|
||||
RUN mkdir /app && mkdir /app/data
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./lynxie /app
|
||||
|
||||
RUN apk update && \
|
||||
apk --no-cache add python3 py3-pip && \
|
||||
pip install --no-cache-dir -r requirements.txt \
|
||||
|
||||
RUN python3 database.py
|
||||
|
||||
CMD ["python3", "main.py"]
|
|
@ -1,21 +1,27 @@
|
|||
cub
|
||||
young
|
||||
younger_penetrated
|
||||
teen
|
||||
teenager
|
||||
diaper
|
||||
pregnant
|
||||
loli
|
||||
|
||||
incest
|
||||
father_and_son
|
||||
father_and_daughter
|
||||
mother_and_son
|
||||
mother_and_daughter
|
||||
parent_and_child
|
||||
father_and_child
|
||||
mother_and_child
|
||||
brother_and_sister
|
||||
sister_and_sister
|
||||
brother_and_brother
|
||||
age-difference
|
||||
|
||||
bestiality
|
||||
feral_and_anthro
|
||||
human_on_feral
|
||||
feral_on_human
|
||||
anthro_on_feral
|
||||
feral_on_anthro
|
||||
|
||||
gore
|
||||
blood
|
||||
|
@ -30,3 +36,4 @@ watersports
|
|||
urine
|
||||
snuff
|
||||
eating_feces
|
||||
shota
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 934 B After Width: | Height: | Size: 934 B |
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
@ -9,7 +9,6 @@ from lynxie.config import E621_API_KEY, E621_USERNAME, E621_BLACKLIST
|
|||
from lynxie.utils import error_message
|
||||
|
||||
|
||||
_E621_API_URL = "https://e621.net/"
|
||||
_E621_AUTH = f"{E621_USERNAME}:{E621_API_KEY}".encode("utf-8")
|
||||
_E621_API_HEADERS = {
|
||||
"Accept": "application/json",
|
||||
|
@ -25,8 +24,7 @@ class E621(commands.Cog):
|
|||
|
||||
@commands.command()
|
||||
async def porb(self, ctx, *tags):
|
||||
# Base url for the request
|
||||
url = _E621_API_URL + "posts.json/?limit=1&tags=order:random+rating:e+"
|
||||
url = "https://e621.net/posts.json/?limit=1&tags=order:random+rating:e+"
|
||||
caught_tags = []
|
||||
|
||||
for tag in tags:
|
||||
|
@ -41,7 +39,8 @@ class E621(commands.Cog):
|
|||
if caught_tags:
|
||||
error = (
|
||||
"An error occurred while fetching the image! "
|
||||
f"{', '.join(caught_tags)} is a blacklisted tag!"
|
||||
f"{', '.join(['`'+tag+'`' for tag in caught_tags])} "
|
||||
f"is a blacklisted tag!"
|
||||
)
|
||||
await ctx.reply(embed=error_message(error))
|
||||
return
|
||||
|
@ -49,6 +48,13 @@ class E621(commands.Cog):
|
|||
request = requests.get(url, headers=_E621_API_HEADERS)
|
||||
response = json.loads(request.text)
|
||||
|
||||
if request.status_code == 503:
|
||||
error = (
|
||||
"The bot is currently rate limited! "
|
||||
"Wait a while before trying again."
|
||||
)
|
||||
await ctx.reply(embed=error_message(error))
|
||||
return
|
||||
if request.status_code != 200:
|
||||
error = (
|
||||
"An error occurred while fetching the image! "
|
||||
|
@ -58,44 +64,51 @@ class E621(commands.Cog):
|
|||
return
|
||||
|
||||
if not response["posts"]:
|
||||
error = "No results found for the given tags! " f"(Tags: {', '.join(tags)})"
|
||||
tags_to_display = range(min(len(tags), 20))
|
||||
error = (
|
||||
"No results found for the given tags! "
|
||||
f"(Tags: {', '.join(['`'+tags[i]+'`' for i in tags_to_display])})"
|
||||
)
|
||||
await ctx.reply(embed=error_message(error))
|
||||
return
|
||||
|
||||
post = response["posts"][0]
|
||||
general_tags = post["tags"]["general"]
|
||||
|
||||
embed = discord.Embed(
|
||||
title="E621",
|
||||
description=response["posts"][0]["description"]
|
||||
or "No description provided.",
|
||||
description=post["description"] or "No description provided.",
|
||||
colour=discord.Colour.orange(),
|
||||
)
|
||||
|
||||
embed.add_field(
|
||||
name="Score",
|
||||
value=f"^ {response['posts'][0]['score']['up']} | "
|
||||
f"v {response['posts'][0]['score']['down']}",
|
||||
value=f"⬆️ {post['score']['up']} | ⬇️ {post['score']['down']}",
|
||||
)
|
||||
embed.add_field(
|
||||
name="Favorites",
|
||||
value=response["posts"][0]["fav_count"],
|
||||
value=post["fav_count"],
|
||||
)
|
||||
embed.add_field(
|
||||
name="Comments",
|
||||
value=post["comment_count"],
|
||||
)
|
||||
|
||||
embed.add_field(
|
||||
name="Source",
|
||||
value=", ".join(response["posts"][0]["sources"]) or "No source provided.",
|
||||
name="Source(s)",
|
||||
value=", ".join(post["sources"]) or "No source provided.",
|
||||
inline=False,
|
||||
)
|
||||
embed.add_field(
|
||||
name="Tags",
|
||||
value=", ".join(response["posts"][0]["tags"]["general"])
|
||||
or "No tags provided.",
|
||||
value=(
|
||||
", ".join(["`"+general_tags[i]+"`" for i in range(min(len(general_tags), 20))])
|
||||
or "No tags provided."
|
||||
),
|
||||
inline=False,
|
||||
)
|
||||
|
||||
embed.set_footer(
|
||||
text=f"ID: {response['posts'][0]['id']} | "
|
||||
f"Created: {response['posts'][0]['created_at']}"
|
||||
)
|
||||
|
||||
embed.set_image(url=response["posts"][0]["file"]["url"])
|
||||
embed.set_footer(text=f"ID: {post['id']} | Created: {post['created_at']}")
|
||||
embed.set_image(url=post["file"]["url"])
|
||||
|
||||
await ctx.reply(embed=embed)
|
|
@ -16,9 +16,10 @@ class Img(commands.Cog):
|
|||
self.bot = bot
|
||||
|
||||
@staticmethod
|
||||
async def get_image_attachments(ctx):
|
||||
async def get_image_attachments(ctx) -> discord.Attachment or None:
|
||||
if ctx.message.attachments:
|
||||
return ctx.message.attachments[0]
|
||||
|
||||
if ctx.message.reference:
|
||||
if ctx.message.reference.resolved.attachments:
|
||||
return ctx.message.reference.resolved.attachments[0]
|
||||
|
@ -27,15 +28,17 @@ class Img(commands.Cog):
|
|||
and ctx.message.reference.resolved.embeds[0].image
|
||||
):
|
||||
return ctx.message.reference.resolved.embeds[0].image
|
||||
elif ctx.message.embeds and ctx.message.embeds[0].image:
|
||||
|
||||
if ctx.message.embeds and ctx.message.embeds[0].image:
|
||||
return ctx.message.embeds[0].image
|
||||
else:
|
||||
channel = ctx.guild.get_channel(ctx.channel.id)
|
||||
async for message in channel.history(limit=10):
|
||||
if message.attachments:
|
||||
return message.attachments[0]
|
||||
if message.embeds and message.embeds[0].image:
|
||||
return message.embeds[0].image
|
||||
|
||||
channel = ctx.guild.get_channel(ctx.channel.id)
|
||||
async for message in channel.history(limit=10):
|
||||
if message.attachments:
|
||||
return message.attachments[0]
|
||||
|
||||
if message.embeds and message.embeds[0].image:
|
||||
return message.embeds[0].image
|
||||
|
||||
return None
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
import re
|
||||
import requests
|
||||
import dotenv
|
||||
from discord import Object
|
||||
|
@ -14,8 +15,9 @@ DISCORD_TOKEN = (
|
|||
DISCORD_GUILD_ID = Object(id=1040757387033849976)
|
||||
LYNXIE_PREFIX = "?"
|
||||
|
||||
DATA_PATH = os.path.join("lynxie", "data")
|
||||
ASSETS_PATH = os.path.join("lynxie", "assets")
|
||||
DATA_PATH = os.path.join("/app", "data")
|
||||
ASSETS_PATH = os.path.join("/app", "assets")
|
||||
|
||||
|
||||
DATABASE_URI = "sqlite:///" + os.path.join(DATA_PATH, "lynxie.db")
|
||||
|
||||
|
@ -74,3 +76,12 @@ with open(os.path.join(ASSETS_PATH, "e621_blacklist.txt"), "r") as file:
|
|||
for line in file.readlines():
|
||||
if word := line.strip():
|
||||
E621_BLACKLIST.add(word)
|
||||
|
||||
|
||||
BAD_WORDS = []
|
||||
_bad_words_request = requests.get(
|
||||
"https://raw.githubusercontent.com/mogade/badwords/master/en.txt"
|
||||
)
|
||||
for word in _bad_words_request.text.split("\n"):
|
||||
if word := word.strip():
|
||||
BAD_WORDS.append(re.compile(word, re.IGNORECASE))
|
|
@ -1,3 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
# vim: set fileencoding=utf-8 :
|
||||
|
||||
import asyncio
|
||||
|
||||
import discord
|
||||
|
@ -43,7 +46,11 @@ async def on_command(ctx):
|
|||
|
||||
@lynxie.event
|
||||
async def on_command_error(ctx, error):
|
||||
if isinstance(error, commands.CommandNotFound):
|
||||
return
|
||||
|
||||
print(error)
|
||||
|
||||
error = "An internal error occurred while processing your command, oopsie..."
|
||||
await ctx.reply(embed=error_message(error), delete_after=5)
|
||||
|
13
Bot/requirements.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
python
|
||||
discord
|
||||
black
|
||||
sqlalchemy
|
||||
python-dotenv
|
||||
discord-py
|
||||
requests
|
||||
beautifulsoup4
|
||||
selenium
|
||||
webdriver-manager
|
||||
flask
|
||||
yt-dlp
|
||||
pillow
|
13
docker-compose.yml
Normal file
|
@ -0,0 +1,13 @@
|
|||
version: "3.9"
|
||||
|
||||
services:
|
||||
bot:
|
||||
build: Bot
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./Bot/data:/app/data
|
||||
environment:
|
||||
DISCORD_TOKEN: ${DISCORD_TOKEN}
|
||||
DISCORD_GUILD_ID: ${DISCORD_GUILD_ID}
|
||||
E621_USERNAME: ${E621_USERNAME}
|
||||
E621_API_KEY: ${E621_API_KEY}
|
2
lynxie/data/.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
*
|
||||
!.gitignore
|