# Copyright (c) 2018, George Tokmaji # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. from ..helpers import * import string, magic def _add_upload(entry : Upload, session : DBSession): return { "voting" : { "sum" : 0, "count" : 0, "votes" : None }, "id" : entry.id, "title" : entry.title, "author" : { "id" : entry.author.id if entry.author is not None else "0" * 24, "username" : entry.author.name if entry.author is not None else "N/A" }, "tags" : entry.tags, "files" : [{ "metadata" : { "hashes" : { "sha1" : file.hash } }, "aliases" : None, "deleted" : False, "id" : file.id, "filename" : file.name, "content-type" : file.content_type, "length" : file.length, "chunkSize" : BLOCKSIZE, "uploadData" : file.date.isoformat() } for file in session.query(File).filter_by(upload=entry) ], "dependencies" : [], #TODO "deleted" : False, "description" : entry.description, "pic" : None, #TODO "slug" : entry.slug, "createdAt" : entry.created_at.isoformat(), "updatedAt" : entry.updated_at.isoformat(), "__v" : entry._v, "comments" : [{ "voting" : { "sum" : 0, "count" : 0, "votes" : None }, "deleted" : False, "id" : comment.id, "body" : comment.body, "author" : { "id" : comment.author.id, "username" : comment.author.name }, "upload" : comment.upload.id, "createdAt" : comment.created_at.isoformat(), "updatedAt" : comment.updated_at.isoformat() } for comment in session.query(Comment).filter_by(upload=entry) ] } @route("/api/uploads") def get_uploads(): ret = { "pagination" : { "total" : 0, "limit" : 50, "page" : 1, "pages" : 1 }, "uploads" : [] } session = DBSession() for entry in session.query(Upload).order_by(Upload.updated_at.desc()): ret["uploads"].append(_add_upload(entry, session)) ret["pagination"]["total"] = ret["pagination"]["limit"] = len(ret["uploads"]) return ret @route("/api/uploads/") def get_upload(id): session = DBSession() entry = session.query(Upload).get(id) if entry is not None: return _add_upload(entry, session) else: raise HTTPResponse(status=404) @route("/api/uploads", method="POST") @auth_basic def post_upload(): try: session = DBSession() if len(session.query(Upload).filter_by(title=requests.forms.title).all()): raise HTTPResponse("An entry with the specified title already exists", 410) entry = Upload( title=request.forms.title, author=session.query(User).filter_by(username=request.forms.username), description=request.forms.description, slug="".join(i for i in requests.forms.title.lower() if i in string.ascii_letters), tags=request.forms.tags.split(";") if "tags" in request.forms else [] ) session.add(entry) try: os.mkdir(os.path.join(os.getcwd(), "media")) except FileExistsError: pass for file in request.files.values(): f = File( name=file.filename, upload=entry ) path = os.path.join(os.getcwd(), "media", f["id"]) file.save(path) with open(path, "rb") as fobj: f.hash = calculateHashForFile(fobj).hexdigest() f.length = fobj.tell() f.content_type = magic.from_file(path, mime=True) session.add(f) except KeyError as e: session.rollback() raise HTTPResponse(f"Missing form value: {e.args[0]}", 400) session.commit() return HTTPResponse(status=201) @route("/api/uploads//comments", method="POST") @auth_basic def post_comments(id): session = DBSession() try: session.query(Upload).filter_by(id=id).one() except db.orm.exc.NoResultFound: raise HTTPResponse("Invalid upload id", 404) try: session.add(Comment( body=request.forms.body, author=session.query(User).filter_by(username=request.forms.username).one() )) except KeyError as e: raise HTTPResponse(f"Missing form value: {e.args[0]}", 400) session.commit() return HTTPResponse(status=201) @route("/api/uploads//comments/", method="DELETE") @auth_basic def delete_comments(id, comment_id): session = DBSession() try: comment = session.query(Comment).filter_by(id=comment_id, author=session.query(User).filter_by(username).one(), upload=session.query(Upload).filter_by(id=id).one()).one() except db.orm.exc.NoResultFound: raise HTTPResponse("Requested comment not found", 404) session.delete(comment) session.commit() return HTTPResponse(status=204)