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 Namespace, Resource, fields
from flask_restx import reqparse 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 from api.clientGetter import getClientSafely
import logging import logging
import random import random
@ -8,7 +10,43 @@ import random
# Exported namespace # Exported namespace
api = Namespace('resource', description='Interact with the raw underlying files. This namespace does NOT speak json, just raw files') 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('/exact/<string:file_name>')
@api.route('/<string:file_name>', doc={
"description" : "Alias for /exact/{query}"
})
@api.doc(description="Interact with exact raw files.") @api.doc(description="Interact with exact raw files.")
class getExactFile(Resource): class getExactFile(Resource):
@api.doc('get') @api.doc('get')
@ -24,6 +62,34 @@ class getExactFile(Resource):
else: else:
abort(400, "Requested file '" + file_name + "' not found") 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.route('/random')
@api.doc(description="Returns a random meme") @api.doc(description="Returns a random meme")
class getRandomFile(Resource): class getRandomFile(Resource):

View File

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

View File

@ -1,13 +1,14 @@
import logging import logging
import os import os
from minio.commonconfig import Tags
from minio import Minio from minio import Minio
from minio.commonconfig import Tags from minio.commonconfig import Tags
from minio.error import S3Error from minio.error import S3Error
from datetime import datetime from datetime import datetime
from functools import lru_cache
S3_URL = "" S3_URL = ""
S3_UN = "" S3_UN = ""
@ -108,6 +109,7 @@ class Client:
return self.allMemes return self.allMemes
@lru_cache(maxsize=32)
def getMeme(self, memeName: str): def getMeme(self, memeName: str):
""" """
Return a meme with the exact given name, or raise an exception 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") raise Exception("Requested meme '" + memeName + "' not found")
return None 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): def getTagsOnMeme(self, memeName: str):
""" """
Returns the S3 Tags object for a given meme Returns the S3 Tags object for a given meme