Add uploading functionality #13

Merged
tyler merged 1 commits from Upload-memes into master 2023-02-24 22:41:09 +00:00
3 changed files with 93 additions and 3 deletions

View File

@ -1,6 +1,8 @@
from flask_restx import Namespace, Resource, fields
from flask_restx import reqparse
from flask import make_response, abort
from flask import make_response, abort, request
from minio.commonconfig import Tags
from werkzeug.datastructures import FileStorage
from api.clientGetter import getClientSafely
import logging
import random
@ -8,7 +10,43 @@ import random
# Exported namespace
api = Namespace('resource', description='Interact with the raw underlying files. This namespace does NOT speak json, just raw files')
uploadFields = {'name' : fields.String(title='Name',
description='File name of your meme',
required=True,
example='Funny.mp4'),
'uploader' : fields.String(title='Uploader',
description='Name of the user who uploaded the meme',
required=True),
'nsfw': fields.Boolean(title='NSFW',
description='Is this NSFW/Spoilable?',
default=False),
'file': fields.String(title='File',
description='File as Base64'),
}
uploadForm = api.parser()
uploadForm.add_argument('file',
location='files',
type=FileStorage,
required=True)
uploadForm.add_argument('name',
location='headers',
type=str,
required=True)
uploadForm.add_argument('uploader',
location='headers',
type=str,
required=True)
uploadForm.add_argument('nsfw',
location='headers',
type=bool,
required=True)
@api.route('/exact/<string:file_name>')
@api.route('/<string:file_name>', doc={
"description" : "Alias for /exact/{query}"
})
@api.doc(description="Interact with exact raw files.")
class getExactFile(Resource):
@api.doc('get')
@ -24,6 +62,34 @@ class getExactFile(Resource):
else:
abort(400, "Requested file '" + file_name + "' not found")
@api.route('/')
class addFile(Resource):
@api.response(200, 'Sucess')
@api.response(500, 'S3 Error')
@api.response(400, 'Bad request')
@api.expect(uploadForm)
def post(self):
client = getClientSafely()
if client is None:
abort(500, "S3 failed to start")
args = uploadForm.parse_args()
file = args['file']
fileName = args['name']
uploader = args['uploader']
nsfw = args['nsfw']
tags = Tags.new_object_tags()
tags["uploader"] = uploader
tags["nsfw"] = str(nsfw)
if client.addMeme(fileContents=file,
name=fileName,
tags=tags):
return {"message" : "sucess"}
@api.route('/random')
@api.doc(description="Returns a random meme")
class getRandomFile(Resource):

View File

@ -40,6 +40,9 @@ class exactSearch(Resource):
'query' : 'Search query to attempt to compare against'
},description="Find a meme thats close using levenshtein distance")
class textualClose(Resource):
@api.doc('fuzzy search')
@api.response(200, 'Sucess')
@api.response(500, 'S3 Error')
def get(self, query):
client = getClientSafely()
if client is None:

View File

@ -1,13 +1,14 @@
import logging
import os
from minio.commonconfig import Tags
from minio import Minio
from minio.commonconfig import Tags
from minio.error import S3Error
from datetime import datetime
from functools import lru_cache
S3_URL = ""
S3_UN = ""
@ -108,6 +109,7 @@ class Client:
return self.allMemes
@lru_cache(maxsize=32)
def getMeme(self, memeName: str):
"""
Return a meme with the exact given name, or raise an exception
@ -125,6 +127,25 @@ class Client:
raise Exception("Requested meme '" + memeName + "' not found")
return None
def addMeme(self, fileContents, name: str, tags: Tags = Tags.new_object_tags()):
result = self.client.put_object(bucket_name=S3_BUCKET,
object_name=name,
data=fileContents,
length=-1,
tags=tags,
part_size=10*1024*1024)
if result.etag in self.memesToMd5:
logger.info('Uploaded meme named ' + name + ' already exists')
client.remove_object(bucket_name=S3_BUCKET,
object_name=name)
return False
else:
self.allMemes.add(name)
self.memesToMd5[name] = result.etag
self.memesToTags[name] = tags
return True
@lru_cache(maxsize=32)
def getTagsOnMeme(self, memeName: str):
"""
Returns the S3 Tags object for a given meme