From 9ad81399cbcc0c40d3963fbf231f1e26b61b8ca0 Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Fri, 4 Nov 2022 22:34:26 -0400 Subject: [PATCH 1/9] complete functionality to save file locally --- src/memes.py | 23 +++++++++++++++++++++++ src/on_message.py | 11 ++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/memes.py b/src/memes.py index af5241e..d1297d0 100644 --- a/src/memes.py +++ b/src/memes.py @@ -3,6 +3,7 @@ import os, random, io from datetime import datetime from fuzzywuzzy import fuzz, process from minio import Minio +from minio.commonconfig import Tags from minio.error import S3Error from catbox import Uploader @@ -258,3 +259,25 @@ async def memeDump(command, message, client): else: await message.channel.send(file=ready_meme) return "Enjoy your memes :)" + +# get an uploaded meme and save it +async def uploadMeme(command, message, client): + #TODO check for memes sent using links + if len(message.attachments) <= 0: + return "You didn't attach anything! Please attach a file to upload" + + tags = Tags.new_object_tags() + tags["uploader"] = message.author.name + print(tags) + + all_memes = getCurrentMemeList() + file_names = [] + + for file in message.attachments: + if file.filename in all_memes: + return "File with name " + file.filename + " already exists!" + #TODO check for file hash + await file.save("/tmp/" + file.filename) + + + return "not implemented dickhead" diff --git a/src/on_message.py b/src/on_message.py index d583247..91ba84f 100644 --- a/src/on_message.py +++ b/src/on_message.py @@ -1,7 +1,7 @@ #!/usr/bin/python3 import requests import os, random, sys -from memes import parseMeme, memeCount, memeDump, allMemes +from memes import parseMeme, memeCount, memeDump, allMemes, uploadMeme import discord async def showHelp(very, useless, arguments): @@ -28,6 +28,10 @@ calldict = { "!memedump" : memeDump, "!allmemes" : allMemes, "!help" : showHelp, + "!up" : uploadMeme, + "!upload" : uploadMeme, + "!uploadmeme": uploadMeme, + #"!memeblame" : memeBlame # plex #"!plexleaderboard" : getTopUsers, } @@ -36,11 +40,12 @@ calldict = { # parse the message async def parse_message(client, message): command = message.content.split() + cmd_input = command[0].lower() # if i know this command - if command[0] in calldict.keys(): + if cmd_input in calldict.keys(): print(f'{client.user} was passed a command I know! ({message.content})') - result = await calldict[command[0]](command, message, client) + result = await calldict[cmd_input](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) From 6dcf4b43b8b2fecbbf93980c97c87f7b05d779b1 Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Fri, 4 Nov 2022 22:49:16 -0400 Subject: [PATCH 2/9] complete basic uploading --- src/memes.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/memes.py b/src/memes.py index d1297d0..e8c9c23 100644 --- a/src/memes.py +++ b/src/memes.py @@ -82,12 +82,12 @@ def getClient(): # Helper methods # Methods to break up the calldict methods -def getCurrentMemeList(): +def getCurrentMemeList(force=False): global last_checked_all_memes global all_memes now = datetime.now() # if no update in the past 5 mins - if (now - last_checked_all_memes).seconds > 300: + if (now - last_checked_all_memes).seconds > 300 or force: print("Enough time has elapsed, refreshing meme cache...") last_checked_all_memes = now all_memes.clear() @@ -266,18 +266,30 @@ async def uploadMeme(command, message, client): if len(message.attachments) <= 0: return "You didn't attach anything! Please attach a file to upload" - tags = Tags.new_object_tags() - tags["uploader"] = message.author.name - print(tags) + uploader_tags = Tags.new_object_tags() + uploader_tags["uploader"] = message.author.name + print(uploader_tags) all_memes = getCurrentMemeList() + client = getClient() file_names = [] for file in message.attachments: if file.filename in all_memes: - return "File with name " + file.filename + " already exists!" + return "File with name '" + file.filename + "' already exists!" #TODO check for file hash + await file.save("/tmp/" + file.filename) + #upload the file to S3 + client.fput_object(bucket_name=S3_BUCKET, + object_name=file.filename, + file_path="/tmp/" + file.filename, + tags=uploader_tags, + content_type=None) - return "not implemented dickhead" + os.remove("/tmp/" + file.filename) + + getCurrentMemeList(force=True) + + return "Thanks got your memes!" From 9292869520b95ec8e3d9adee78ba8212ca9250b9 Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Thu, 1 Dec 2022 18:05:58 -0500 Subject: [PATCH 3/9] Save progress --- Dockerfile | 9 +++++++++ docker-compose.yml | 10 ++++++++++ src/.env | 8 ++++---- src/memes.py | 23 +++++++++++++++++------ 4 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..71f5805 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,9 @@ +FROM python + +WORKDIR /usr/src/app + +COPY ./src ./ + +RUN pip install -r requirements.txt + +CMD "python" "./main.py" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..26b59ad --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,10 @@ +version: '3' + bot: + image: bot + environment: + - DISCORD_TOKEN=token + - S3_URL=url + - S3_UN=UN + - S3_PW=PW + - S3_TLS=TLS + - S3_BUCKET=BUCKET diff --git a/src/.env b/src/.env index 11e554d..4ac624c 100644 --- a/src/.env +++ b/src/.env @@ -1,7 +1,7 @@ -DISCORD_TOKEN= -S3_URL= -S3_UN= -S3_PW= +DISCORD_TOKEN=NjY0MzA5MDEyNDgwNzg2NDMz.XhVL-g.y71awGdbVN88SI7CqYxiSY-fu7s +S3_URL=192.168.1.104:9000 +S3_UN=DISCORDBOTMEMES +S3_PW=PtWPsXYuQMlhGDF83arfiFD9DP7PdeGH2FrzejnD S3_TLS=False S3_BUCKET=memes TAUTULLI_URL= diff --git a/src/memes.py b/src/memes.py index e8c9c23..0984055 100644 --- a/src/memes.py +++ b/src/memes.py @@ -6,6 +6,7 @@ from minio import Minio from minio.commonconfig import Tags from minio.error import S3Error from catbox import Uploader +from hashlib import md5 # memes we have most recently gotten class RecentMemeQueue: @@ -27,6 +28,7 @@ recentMemes = RecentMemeQueue() # list of all current memes' names all_memes = [] +memes_to_md5 = dict() last_checked_all_memes = datetime.strptime("2000-01-01 01:01:01", "%Y-%m-%d %H:%M:%S") S3_URL = "" @@ -85,6 +87,7 @@ def getClient(): def getCurrentMemeList(force=False): global last_checked_all_memes global all_memes + global memes_to_md5 now = datetime.now() # if no update in the past 5 mins if (now - last_checked_all_memes).seconds > 300 or force: @@ -96,6 +99,9 @@ def getCurrentMemeList(force=False): if not obj.is_dir: #print(f'{obj.object_name}') all_memes.append(obj.object_name) + if obj.object_name == 'combat_shotgun_my_beloved1.png': + print("Found! " + obj.etag) + memes_to_md5[obj.etag] = obj.object_name print(f"Got {len(all_memes)} memes") return all_memes @@ -262,6 +268,7 @@ async def memeDump(command, message, client): # get an uploaded meme and save it async def uploadMeme(command, message, client): + global memes_to_md5 #TODO check for memes sent using links if len(message.attachments) <= 0: return "You didn't attach anything! Please attach a file to upload" @@ -277,16 +284,20 @@ async def uploadMeme(command, message, client): for file in message.attachments: if file.filename in all_memes: return "File with name '" + file.filename + "' already exists!" - #TODO check for file hash await file.save("/tmp/" + file.filename) #upload the file to S3 - client.fput_object(bucket_name=S3_BUCKET, - object_name=file.filename, - file_path="/tmp/" + file.filename, - tags=uploader_tags, - content_type=None) + file_hash = md5(open("/tmp/" + file.filename, 'rb').read()) + print("Uploaded file has md5 hash of " + file_hash.hexdigest()) + if file_hash not in memes_to_md5: + client.fput_object(bucket_name=S3_BUCKET, + object_name=file.filename, + file_path="/tmp/" + file.filename, + tags=uploader_tags, + content_type=None) + else: + return "Found that meme already! (aka " + memes_to_md5[file_hash] + ")" os.remove("/tmp/" + file.filename) From 8f98230e87c49f48c1b7045438ded1834590435b Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Fri, 16 Dec 2022 17:10:41 -0500 Subject: [PATCH 4/9] Add drone --- .drone.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .drone.yml diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..0b3abd5 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,18 @@ +kind: pipeline +name: default + +steps: + - name: docker + image: thegeeklab/drone-docker + privileged: true + settings: + username: + from_secret: dockerhub_username + password: + from_secret: dockerhub_password + repo: + from_secret: dockerhub_repo + tags: latest + when: + branch: + - master From 6777aea80ccaaf7f801e1d3a27d01ec107c0acee Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Sat, 17 Dec 2022 19:08:27 -0500 Subject: [PATCH 5/9] Pull in new drone file --- .drone.yml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/.drone.yml b/.drone.yml index 0b3abd5..8e4eab8 100644 --- a/.drone.yml +++ b/.drone.yml @@ -3,8 +3,7 @@ name: default steps: - name: docker - image: thegeeklab/drone-docker - privileged: true + image: plugins/docker settings: username: from_secret: dockerhub_username @@ -15,4 +14,15 @@ steps: tags: latest when: branch: - - master + - main + - name: notify + image: clortox/drone-ntfy + settings: + URL: https://ntfy.clortox.com + USERNAME: drone + PASSWORD: + from_secret: ntfy_password + TOPIC: drone-builds + MESSAGE: Discord Bot build finished! + CLICK: https://drone.clortox.com/tyler/Memerr + TITLE: Memerr build From 3871840d2fe96173f34865c850b1498feb3a7653 Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Sat, 17 Dec 2022 21:01:25 -0500 Subject: [PATCH 6/9] Remove env file --- src/.env | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 src/.env diff --git a/src/.env b/src/.env deleted file mode 100644 index 4ac624c..0000000 --- a/src/.env +++ /dev/null @@ -1,8 +0,0 @@ -DISCORD_TOKEN=NjY0MzA5MDEyNDgwNzg2NDMz.XhVL-g.y71awGdbVN88SI7CqYxiSY-fu7s -S3_URL=192.168.1.104:9000 -S3_UN=DISCORDBOTMEMES -S3_PW=PtWPsXYuQMlhGDF83arfiFD9DP7PdeGH2FrzejnD -S3_TLS=False -S3_BUCKET=memes -TAUTULLI_URL= -TAUTULLI_APIKEY= From ddcace0abbaed580a28934b251d409ab52508b2c Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Sat, 17 Dec 2022 21:03:24 -0500 Subject: [PATCH 7/9] Ignore environment script --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 577d148..5d4ace9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ src/.env venv +apply_environment.sh From bb9b21c8f59d931f0a5f1385c265942f44c29095 Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Sat, 17 Dec 2022 21:49:01 -0500 Subject: [PATCH 8/9] Add hash checking of files --- src/memes.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/memes.py b/src/memes.py index 0984055..1ec86ec 100644 --- a/src/memes.py +++ b/src/memes.py @@ -93,14 +93,15 @@ def getCurrentMemeList(force=False): if (now - last_checked_all_memes).seconds > 300 or force: print("Enough time has elapsed, refreshing meme cache...") last_checked_all_memes = now + all_memes.clear() + memes_to_md5.clear() + myClient = getClient() for obj in myClient.list_objects(S3_BUCKET): if not obj.is_dir: #print(f'{obj.object_name}') all_memes.append(obj.object_name) - if obj.object_name == 'combat_shotgun_my_beloved1.png': - print("Found! " + obj.etag) memes_to_md5[obj.etag] = obj.object_name print(f"Got {len(all_memes)} memes") return all_memes @@ -275,7 +276,6 @@ async def uploadMeme(command, message, client): uploader_tags = Tags.new_object_tags() uploader_tags["uploader"] = message.author.name - print(uploader_tags) all_memes = getCurrentMemeList() client = getClient() @@ -287,20 +287,24 @@ async def uploadMeme(command, message, client): await file.save("/tmp/" + file.filename) - #upload the file to S3 - file_hash = md5(open("/tmp/" + file.filename, 'rb').read()) - print("Uploaded file has md5 hash of " + file_hash.hexdigest()) - if file_hash not in memes_to_md5: - client.fput_object(bucket_name=S3_BUCKET, - object_name=file.filename, - file_path="/tmp/" + file.filename, - tags=uploader_tags, - content_type=None) - else: - return "Found that meme already! (aka " + memes_to_md5[file_hash] + ")" + result = client.fput_object(bucket_name=S3_BUCKET, + object_name=file.filename, + file_path="/tmp/" + file.filename, + tags=uploader_tags, + content_type=None) + + if result.etag in memes_to_md5: + print("Already have that meme, etag is (" + result.etag + ")") + + client.remove_object(bucket_name=S3_BUCKET, + object_name=file.filename) + return "That meme is already in the cache (it's called " + memes_to_md5[result.etag] + ")" os.remove("/tmp/" + file.filename) getCurrentMemeList(force=True) return "Thanks got your memes!" + + + From 4bbcdc00015908c4a0ea555358948c0758c7ddb6 Mon Sep 17 00:00:00 2001 From: Tyler Perkins Date: Sat, 17 Dec 2022 21:54:20 -0500 Subject: [PATCH 9/9] Update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 517768b..6cbe7a4 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Features - [X] Fuzzy search for memes - [X] Get a random meme - [X] Get a set of memes -- [ ] Upload memes to bucket +- [X] Upload memes to bucket - [ ] Check status of Plex instance Enviroment vars