Update venv
This commit is contained in:
parent
9c14774edc
commit
995eacbb30
11
README.md
11
README.md
@ -3,15 +3,16 @@ Memerr
|
||||
|
||||
A discord bot to manage you and your friend's meme collection
|
||||
|
||||
You can get this on [Docker](https://hub.docker.com/r/clortox/memerr)
|
||||
|
||||
Features
|
||||
----
|
||||
|
||||
- [ ] Run in a docker container
|
||||
- [ ] Query for memes by name
|
||||
- [ ] Fuzzy search for memes
|
||||
- [ ] Get a random meme
|
||||
- [ ] Get a set of memes
|
||||
- [X] Run in a docker container
|
||||
- [X] Query for memes by name
|
||||
- [X] Fuzzy search for memes
|
||||
- [X] Get a random meme
|
||||
- [X] Get a set of memes
|
||||
- [ ] Upload memes to bucket
|
||||
- [ ] Check status of Plex instance
|
||||
|
||||
|
@ -1,13 +1,17 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ ! -d "./venv" ]; then
|
||||
mkdir ./venv 2> /dev/null
|
||||
|
||||
python -m venv ./venv
|
||||
fi
|
||||
|
||||
cp ./src/* ./venv/
|
||||
cp ./src/.env ./venv/.env 2> /dev/null
|
||||
|
||||
cd ./venv
|
||||
pip install -r requirements.txt --user
|
||||
touch .env
|
||||
echo "evn $(cat .env | xargs) python ./main.py" >> run.sh
|
||||
chmod +x run.sh
|
||||
|
||||
env $(cat .env | xargs) python ./main.py
|
||||
|
@ -24,6 +24,8 @@ client = discord.Client()
|
||||
async def on_message(message):
|
||||
if message.author == client.user:
|
||||
return
|
||||
if len(message.content) == 0: # if its empty, like an uploaded image, ignore it
|
||||
return
|
||||
return await parse_message(client, message)
|
||||
|
||||
# messege delete handler
|
||||
|
126
src/memes.py
126
src/memes.py
@ -7,8 +7,22 @@ from minio.error import S3Error
|
||||
from catbox import Uploader
|
||||
|
||||
# memes we have most recently gotten
|
||||
last_memes = []
|
||||
last_memes_max = 20
|
||||
class RecentMemeQueue:
|
||||
#last_memes = []
|
||||
#last_memes_max = 20
|
||||
def __init__(self):
|
||||
self.last_memes = []
|
||||
self.last_memes_max = 20
|
||||
def insertMeme(self, meme):
|
||||
self.last_memes.insert(0, meme)
|
||||
if len(self.last_memes) > self.last_memes_max:
|
||||
self.last_memes.pop()
|
||||
def inQueue(self, meme) -> bool:
|
||||
return meme in self.last_memes
|
||||
def getList(self):
|
||||
return self.last_memes
|
||||
|
||||
recentMemes = RecentMemeQueue()
|
||||
|
||||
# list of all current memes' names
|
||||
all_memes = []
|
||||
@ -72,14 +86,16 @@ def getCurrentMemeList():
|
||||
global all_memes
|
||||
now = datetime.now()
|
||||
# if no update in the past 5 mins
|
||||
if (last_checked_all_memes - now).seconds / 60 > 5:
|
||||
if (now - last_checked_all_memes).seconds > 300:
|
||||
print("Enough time has elapsed, refreshing meme cache...")
|
||||
last_checked_all_memes = now
|
||||
all_memes.clear()
|
||||
myClient = getClient()
|
||||
for obj in myClient.list_objects(S3_BUCKET):
|
||||
if not obj.is_dir:
|
||||
print(f'{obj.object_name}')
|
||||
#print(f'{obj.object_name}')
|
||||
all_memes.append(obj.object_name)
|
||||
print(f"Got {len(all_memes)} memes")
|
||||
return all_memes
|
||||
|
||||
# given a file, we will return:
|
||||
@ -87,7 +103,6 @@ def getCurrentMemeList():
|
||||
# A catbox.moe link if its larger than 8mb
|
||||
def getDiscordReadyObjectFromS3(file_name):
|
||||
size = 0
|
||||
out_file_path = "/tmp/" + file_name
|
||||
#get the file
|
||||
client = getClient()
|
||||
stream = ""
|
||||
@ -101,12 +116,58 @@ def getDiscordReadyObjectFromS3(file_name):
|
||||
|
||||
# check the object size
|
||||
if size >= 8000000: # to big, use catbox
|
||||
print(f"{file_name} was to big, uploading to catbox...")
|
||||
catbox_uploader = Uploader(token='')
|
||||
url = catbox_uploader.upload(file_raw=stream)
|
||||
extension = file_name.split('.')[-1]
|
||||
if len(extension) == 0:
|
||||
extension = None
|
||||
url = catbox_uploader.upload(file_raw=stream, file_type=extension)
|
||||
return url["file"]
|
||||
else: #small enough, use discord
|
||||
print(f"{file_name} was small enough to send using discord")
|
||||
return discord.File(fp=io.BytesIO(stream), filename=file_name)
|
||||
|
||||
# get a meme whos name closest matches the provided query
|
||||
def getCloseMemeToQuery(query, returnAllClose = False):
|
||||
global all_memes
|
||||
all_memes = getCurrentMemeList()
|
||||
top_meme = ''
|
||||
top_memes = []
|
||||
top_score = 0
|
||||
|
||||
for meme in all_memes:
|
||||
current_score = fuzz.partial_ratio(query, meme)
|
||||
if current_score > top_score:
|
||||
top_meme = meme
|
||||
top_score = current_score
|
||||
if current_score == 100:
|
||||
top_memes.append(meme)
|
||||
top_meme = meme
|
||||
|
||||
print("Top memes we found:")
|
||||
if len(top_memes) > 0:
|
||||
print(top_memes)
|
||||
if top_meme != '':
|
||||
print(top_meme)
|
||||
|
||||
# if there was one or more perfect matches, get them
|
||||
if top_score == 100:
|
||||
top_meme = random.choice(top_memes)
|
||||
if not all(elem in recentMemes.getList() for elem in top_memes):
|
||||
while top_meme in recentMemes.getList():
|
||||
top_meme = random.choice(top_memes)
|
||||
recentMemes.insertMeme(top_meme)
|
||||
|
||||
if returnAllClose and len(top_memes) > 1:
|
||||
print("Returning all found memes...")
|
||||
for meme in top_memes:
|
||||
recentMemes.insertMeme(meme)
|
||||
return top_memes, 1 if len(top_memes) <= 1 else len(top_memes)
|
||||
else:
|
||||
print(f"Returning {top_meme}...")
|
||||
recentMemes.insertMeme(top_meme)
|
||||
return top_meme, 1 if len(top_memes) <= 1 else len(top_memes)
|
||||
|
||||
# get the name of the user who uploaded the file
|
||||
# their tag is always under the 'uploader' tag
|
||||
def getMemeUploader(file_name):
|
||||
@ -118,6 +179,17 @@ def getMemeUploader(file_name):
|
||||
return uploader
|
||||
return "Unkown"
|
||||
|
||||
# gets a random meme
|
||||
# this will ensure that the meme is not in the last_memes list
|
||||
def getRandomMeme():
|
||||
all_memes = getCurrentMemeList()
|
||||
choice = random.choice(all_memes)
|
||||
while recentMemes.inQueue(choice):
|
||||
choice = random.choice(all_memes)
|
||||
recentMemes.insertMeme(choice)
|
||||
return choice
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Calldict methods
|
||||
|
||||
@ -133,24 +205,56 @@ async def parseMeme(command, message, client):
|
||||
if len(command) > 1: # if there is a query
|
||||
query_string = ' '.join(command[1:]) #get QUERY_STRING
|
||||
|
||||
all_memes = getCurrentMemeList()
|
||||
#first, check if the exact meme exists
|
||||
all_memes = getCurrentMemeList()
|
||||
if query_string in all_memes: # found the exact meme, return it
|
||||
return getDiscordReadyObjectFromS3(query_string)
|
||||
|
||||
#if we get here then we didnt find the meme, lets find the closest meme
|
||||
close_meme, total_close_memes = getCloseMemeToQuery(query_string)
|
||||
await message.channel.send(f"Found a close meme (from {total_close_memes} choices)")
|
||||
return getDiscordReadyObjectFromS3(close_meme)
|
||||
|
||||
else: #there is no query, get a random meme
|
||||
pass
|
||||
print(f'Getting a random meme...')
|
||||
meme = getRandomMeme()
|
||||
print(f'Got a random meme ({meme})')
|
||||
return getDiscordReadyObjectFromS3(meme)
|
||||
|
||||
# get all ememes that are similar to the given query
|
||||
async def allMemes(command, message, client):
|
||||
pass
|
||||
if len(command) > 1:
|
||||
query_string = ' '.join(command[1:])
|
||||
close_memes, total_close_memes = getCloseMemeToQuery(query_string,
|
||||
returnAllClose=True)
|
||||
if total_close_memes == 0:
|
||||
return "I found nothing similar to " + query_string
|
||||
elif total_close_memes == 1:
|
||||
return getDiscordReadyObjectFromS3(close_memes)
|
||||
else:
|
||||
for meme in close_memes:
|
||||
ready_meme = getDiscordReadyObjectFromS3(meme)
|
||||
if isinstance(ready_meme, str):
|
||||
await message.channel.send(ready_meme)
|
||||
else:
|
||||
await message.channel.send(file=ready_meme)
|
||||
return "Enjoy your memes :)"
|
||||
else:
|
||||
return "I need a query!"
|
||||
|
||||
# get total number of memes stored
|
||||
async def memeCount(command, message, client):
|
||||
pass
|
||||
all_memes = getCurrentMemeList()
|
||||
return "Currently we have " + str(len(all_memes)) + " memes"
|
||||
|
||||
# get a set of random memes
|
||||
async def memeDump(command, message, client):
|
||||
pass
|
||||
await message.channel.send("Getting your memes...")
|
||||
for i in range(0,5):
|
||||
meme = getRandomMeme()
|
||||
ready_meme = getDiscordReadyObjectFromS3(meme)
|
||||
if isinstance(ready_meme, str):
|
||||
await message.channel.send(ready_meme)
|
||||
else:
|
||||
await message.channel.send(file=ready_meme)
|
||||
return "Enjoy your memes :)"
|
||||
|
@ -4,6 +4,21 @@ import os, random, sys
|
||||
from memes import parseMeme, memeCount, memeDump, allMemes
|
||||
import discord
|
||||
|
||||
async def showHelp(very, useless, arguments):
|
||||
str = "```Usage:\n"
|
||||
str += "!meme [QUERY]\n"
|
||||
str += " Get a meme. Query for the exact name or search. Paramater is optional\n"
|
||||
str += "!memecount\n"
|
||||
str += " Print total number of memes in the store\n"
|
||||
str += "!memedump\n"
|
||||
str += " Get 5 random memes\n"
|
||||
str += "!allmemes QUERY\n"
|
||||
str += " Get all memes that are like the given query\n"
|
||||
str += "!help\n"
|
||||
str += " Print this message\n"
|
||||
str += "```"
|
||||
return str
|
||||
|
||||
# dictionary associating
|
||||
# a command to a function name
|
||||
calldict = {
|
||||
@ -12,10 +27,12 @@ calldict = {
|
||||
"!memecount" : memeCount,
|
||||
"!memedump" : memeDump,
|
||||
"!allmemes" : allMemes,
|
||||
"!help" : showHelp,
|
||||
# plex
|
||||
#"!plexleaderboard" : getTopUsers,
|
||||
}
|
||||
|
||||
|
||||
# parse the message
|
||||
async def parse_message(client, message):
|
||||
command = message.content.split()
|
||||
@ -25,8 +42,10 @@ async def parse_message(client, message):
|
||||
print(f'{client.user} was passed a command I know! ({message.content})')
|
||||
result = await calldict[command[0]](command, message, client)
|
||||
if isinstance(result, discord.File):
|
||||
print(f'{client.user} is replying with a file ({result.filename})')
|
||||
return await message.channel.send(file=result)
|
||||
else:
|
||||
print(f'{client.user} is replying with the string ({result})')
|
||||
return await message.channel.send(result)
|
||||
|
||||
pass
|
||||
|
Loading…
Reference in New Issue
Block a user