Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
  • Loading branch information
tsunagatteru committed Feb 15, 2023
0 parents commit 503b7c8
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 0 deletions.
37 changes: 37 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#+STARTUP: overview
#+TITLE: booru-bot
#+LANGUAGE: en
#+OPTIONS: num:nil

[[https://github.com/maubot/maubot][Maubot]] plugin to fetch random posts from Safebooru.
* Dependencies
** Pip
- maubot
- mautrix
- pymongo
- aiohttp
** MongoDB
* Installaion
- Clone repository
- Run build.sh
- Install mbp file via maubot web interface
- Enter MongoDB credentials in config section
* Usage
** !get
Fetches and sends x amount of pitures that matces specified tags
Examples:
- Fetch 3 random pictures
#+BEGIN_SRC
!g !3
#+END_SRC
- Fetch 1 picture that match two tags
#+BEGIN_SRC
!g tag_numer_one+tag_number_two
#+END_SRC
- Fetch 5 pictures that match last prompted tags
#+BEGIN_SRC
!g -!5
#+END_SRC

** !tags
Toggles sending tags of messages on/off
5 changes: 5 additions & 0 deletions base-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ip:
port:
user:
pass:
db:
1 change: 1 addition & 0 deletions boorubot/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .bot import BooruBot
77 changes: 77 additions & 0 deletions boorubot/bot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from maubot import Plugin, MessageEvent
from maubot.handlers import command
from mautrix.types import ImageInfo
from mautrix.errors import request
from .image import get_image
from .db import store_tags, get_tags, change_tags_listing, get_tags_listing
from mautrix.util.config import BaseProxyConfig, ConfigUpdateHelper
import mimetypes
from typing import Type
import pymongo


class Config(BaseProxyConfig):
def do_update(self, helper: ConfigUpdateHelper) -> None:
helper.copy("ip")
helper.copy("port")
helper.copy("user")
helper.copy("pass")
helper.copy("db")


class BooruBot(Plugin):
async def start(self) -> None:
self.config.load_and_update()

@command.new(name="tags", aliases=["t"])
async def respond2(self, evt: MessageEvent) -> None:
client = pymongo.MongoClient("mongodb://" + str(self.config["user"]) + ":" + str(self.config["pass"]) + "@" +
str(self.config["ip"]) + ":" + str(self.config["port"]))
target = client[str(self.config["db"])]["tags_listing"]
await change_tags_listing(evt.sender, target)
await evt.reply("Tags listing " + await get_tags_listing(evt.sender, target))

@command.new(name="get", aliases=["g"])
@command.argument("prompt", pass_raw=True, required=False)
async def respond(self, evt: MessageEvent, prompt: str) -> None:
arguments = prompt.split('!')
tags = arguments[0]
try:
times = (arguments[1])
except IndexError:
times = "1"
if times.isdigit():
times = int(times)
else:
times = 1
client = pymongo.MongoClient("mongodb://" + str(self.config["user"]) + ":" + str(self.config["pass"]) + "@" +
str(self.config["ip"]) + ":" + str(self.config["port"]))
target = client[str(self.config["db"])]["previous_tags"]
if tags == "-":
tags = await get_tags(evt.sender, target)
if tags == "-":
await evt.reply("No previous requests")
return None
target = client[str(self.config["db"])]["tags_listing"]
tags_listing = await get_tags_listing(evt.sender, target)
for i in range(times):
pic = await get_image(tags)
if pic.valid:
mime_type = mimetypes.guess_type(pic.name)[0]
uri = await self.client.upload_media(pic.image, mime_type=mime_type, filename=pic.name)
try:
await self.client.send_image(evt.room_id, url=uri, file_name=pic.name,
info=ImageInfo(mimetype=mime_type))
if tags_listing == "enabled":
await evt.respond(pic.tags)
except request.MLimitExceeded:
await evt.reply("Limit exceeded")
else:
await evt.reply("No results")
return None
target = client[str(self.config["db"])]["previous_tags"]
await store_tags(evt.sender, tags, target)

@classmethod
def get_config_class(cls) -> Type[BaseProxyConfig]:
return Config
37 changes: 37 additions & 0 deletions boorubot/db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
async def store_tags(sender, tags, target):
query = {"name": str(sender)}
db_entry = target.find_one(query)
if db_entry is None:
target.insert_one({"name": str(sender), "tags": tags})
else:
target.update_one(query, {"$set": {"tags": tags}})


async def get_tags(sender, target):
query = {"name": str(sender)}
db_entry = target.find_one(query)
if db_entry is None:
return "-"
else:
return db_entry.get('tags')


async def change_tags_listing(sender, target):
query = {"name": str(sender)}
db_entry = target.find_one(query)
if db_entry is None:
target.insert_one({"name": str(sender), "tags_listing": "enabled"})
else:
if db_entry.get('tags_listing') == "enabled":
target.update_one(query, {"$set": {"tags_listing": "disabled"}})
else:
target.update_one(query, {"$set": {"tags_listing": "enabled"}})


async def get_tags_listing(sender, target):
query = {"name": str(sender)}
db_entry = target.find_one(query)
if db_entry is None:
return "disabled"
else:
return db_entry.get('tags_listing')
43 changes: 43 additions & 0 deletions boorubot/image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import aiohttp
from xml.etree import ElementTree
import random
import math


async def make_request(session, url):
async with session.get(url) as response:
return await response.read()


class Result:
def __init__(self, image, name, valid):
self.image = image
self.name = name
self.valid = valid


async def get_image(tags):
async with aiohttp.ClientSession() as session:
url = ("https://safebooru.org/index.php?page=dapi&s=post&q=index&tags="+tags)
post_front = await make_request(session, url + "&limit=0")
out = Result("", "", True)
tree = ElementTree.fromstring(post_front)
post_count = int(tree.get('count'))
if post_count == 0:
out.valid = False
return out
post_number = random.randrange(post_count)
page_number = math.floor(post_number/100)
url += "&pid=" + str(page_number)
url += "."
if post_number < 10:
url += "0"
url += str(post_number % 100)
page_front = await make_request(session, url)
tree = ElementTree.fromstring(page_front)
image_url = tree.find('post').get('file_url')
image_tags = tree.find('post').get('tags')
out.image = await make_request(session, image_url)
out.name = image_url.replace('https://', '')
out.tags = image_tags
return out
3 changes: 3 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh
rm booru_bot.mbp
zip -r booru_bot.mbp boorubot/*.py maubot.yaml base-config.yaml
10 changes: 10 additions & 0 deletions maubot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
maubot: 0.3.1
id: ru.tsuanagatte.booru_bot
version: 1.0.0
license: Custom
modules:
- boorubot
main_class: BooruBot
config: true
extra_files:
- base-config.yaml

0 comments on commit 503b7c8

Please sign in to comment.