def get(self): magnet = request.args.get('magnet', None) if not magnet: return JU.make_response("parameter '?magnet=' required", 400) Hash = seedr.add_magnet(magnet, username=get_jwt_identity()) if not Hash: return JU.make_response("invalid magnet", 400) return make_response({"hash": Hash}, 200)
def post(self, *args, **kwargs): from_path, to_path, iscut = JU.extract_keys(request.get_json(), "from", "to", "iscut") if None in [from_path, to_path]: return JU.make_response("paths missing", 400) if not os.path.exists(from_path): return JU.make_response( "path: '{}' doesn't exists".format(from_path), 400) if not os.path.exists(to_path): return JU.make_response( "path: '{}' doesn't exists".format(to_path), 400) # construct full absolute path to_path = os.path.join(to_path, os.path.basename(from_path)) try: if iscut: shutil.move(from_path, to_path) else: shutil.copy(from_path, to_path) except Exception as e: return JU.make_response("Error occured: {}".format(str(e)), 500) return JU.make_response("file copied", 200)
def post(self, *args, **kwargs): hls_element = JU.extract_keys(request.get_json(), "hls_element") file_path = hls_element.get('path') + "/" + hls_element.get( 'info').get('key') + ".m3u8" if not file_path: return JU.make_response("invalid data", 400) username = get_jwt_identity() user = User.find_by_username(username) if not user: return JU.make_response(f"user '{username}' doesn't exists", 404) if os.path.exists(file_path): output_file = os.path.join( os.path.dirname(os.path.dirname(file_path)), os.path.splitext(os.path.basename(file_path))[0] + ".mp4") output_file = hls.convert_to_mp4(file_path, output_file) new_mp4_child = { 'name': os.path.basename(os.path.splitext(file_path)[0]) + ".mp4", 'type': 'file', 'path': output_file, 'ext': ".mp4", 'size': os.stat(output_file).st_size } return new_mp4_child, 200 else: return JU.make_response(f"file '{file_path}' doesn't exists", 404)
def get(self): username = request.args.get('username', None) if not username: return JU.make_response(f"parameter '?username='******'{username}' exists", 200) return JU.make_response(f"username '{username}' doesn't exists", 404)
def post(self, *args, **kwargs): # create public url from file path file_path = JU.extract_keys(request.get_json(), "file_path") if not file_path: return JU.make_response("invalid data", 400) username = get_jwt_identity() user = User.find_by_username(username) if not user: return JU.make_response(f"user '{username}' doesn't exists", 404) if os.path.exists(file_path): record = PublicURLS.find_by_file_path(file_path=file_path) if record: return record.as_dict() created_at = int(time.time()) file_path_hash = hashlib.sha1( str(file_path).encode()).hexdigest()[:10] expire_after = int( current_app.config.get('PUBLIC_URL_EXPIRES').total_seconds()) record = PublicURLS(file_path=file_path, public_url_hash=file_path_hash, username=username, created_at=created_at, expire_after=expire_after) record.save_to_db() return record.as_dict() else: return JU.make_response(f"file '{file_path}' doesn't exists", 404)
def post(self, *args, **kwargs): file_path = JU.extract_keys(request.get_json(), "file_path") if not file_path: return JU.make_response("invalid data", 400) username = get_jwt_identity() user = User.find_by_username(username) if not user: return JU.make_response(f"user '{username}' doesn't exists", 404) if os.path.exists(file_path): output_file = parse_name(os.path.basename(file_path))['key'] output_file_dirname = os.path.basename( os.path.splitext(file_path)[0]) output_file = os.path.join(os.path.dirname(file_path), output_file_dirname, output_file + ".m3u8") output_file = hls.convert_to_hls(file_path, output_file) new_hls_child = { 'name': os.path.basename(os.path.splitext(file_path)[0]), 'info': parse_name(os.path.basename(file_path)), 'type': 'hls', 'path': os.path.splitext(file_path)[0], 'ext': ".m3u8", 'size': os.stat(file_path).st_size } return new_hls_child, 200 else: return JU.make_response(f"file '{file_path}' doesn't exists", 404)
def get(self): email = request.args.get('email', None) if not email: return JU.make_response(f"parameter '?email=' required", 400) if User.find_by_email(email): return JU.make_response(f"email '{email}' exists", 200) return JU.make_response(f"email '{email}' doesn't exists", 404)
def post(self): if os.environ.get('DISABLE_SIGNUP', "false").lower() == "true": return JU.make_response("signup is disabled by admin", 403) name, username, email, password = JU.extract_keys( request.get_json(), "name", "username", "email", "password") if JU.null_values(name, username, email, password): return JU.make_response("invalid data", 400) if User.find_by_username(username): return JU.make_response(f"user '{username}' already exists", 409) if User.find_by_email(email): return JU.make_response(f"email '{username}' already used", 409) new_user = User(name=name, username=username, email=email, password=User.hashify(password)) try: new_user.save_to_db() access_token = create_access_token(identity=username, fresh=True) refresh_token = create_refresh_token(identity=username) return make_response( { "message": f"user {username} created", "access_token": access_token, "refresh_token": refresh_token }, 200) except Exception as e: print(e) return JU.make_response("something went wrong", 500)
def get(self): Hash = request.args.get('hash', None) if not Hash: return JU.make_response("parameter '?hash=' required", 400) status = seedr.remove_torrent(Hash, username=get_jwt_identity()) if not status: return JU.make_response(f"torrent '{Hash}' not found", 404) return JU.make_response(f"torrent '{Hash}' removed", 200)
def get(self, access_token, bs64_file_path, filename): file_path = base64.b64decode(bs64_file_path).decode() file_path = os.path.join(file_path, filename) if not os.path.exists(file_path): return JU.make_response(f"invalid path: {file_path}", 400) if request.args.get('download', None): return JU.make_response(f"hls needs to be converted to mp4 first", 200) return send_file(file_path, mimetype='application/octet-stream', attachment_filename=os.path.basename(filename))
def get(self, public_url_hash, filename): query = PublicURLS.find_by_public_url_hash(public_url_hash=public_url_hash) if not query: return JU.make_response(f"url not found", 404) if not query.is_valid: return JU.make_response(f"url expired", 410) file_path = os.path.join(query.file_path, filename) if not os.path.exists(file_path): return JU.make_response(f"invalid path: {file_path}", 400) if request.args.get('download', None): return JU.make_response(f"hls needs to be converted to mp4 first", 200) return send_file(file_path, mimetype='application/octet-stream', attachment_filename=os.path.basename(filename))
def get(self): Hash = request.args.get('hash', None) if not Hash: return JU.make_response("parameter '?hash=' required", 400) torrent = Torrent.find_by_hash_and_username( Hash, username=get_jwt_identity()) if not torrent: return JU.make_response("torrent not found", 404) structure = fs.json_tree(torrent.download_path) if not structure: return JU.make_response("download path error", 404) return make_response(structure, 200)
def post(self, *args, **kwargs): path, newname = JU.extract_keys(request.get_json(), "path", "newname") if None in [path, newname]: return JU.make_response("data missing", 400) if not os.path.exists(path): return JU.make_response("paths doesn't exists", 400) try: os.rename(path, os.path.join(os.path.dirname(path), newname)) except Exception as e: return JU.make_response("Error occured: {}".format(e), 500) return JU.make_response("file rename successfull", 200)
def send_file(self, path, download=False): if not os.path.exists(path): return JU.make_response("invalid path", 400) elif os.path.isdir(path): return JU.make_response("downloading directories not allowed", 400) elif os.path.exists(path): if download: # send raw file that can be downloaded directly return send_file(path, mimetype='application/octet-stream', attachment_filename=os.path.basename(path), as_attachment=True) # stream file over byte range header range_header = request.headers.get('Range', None) byte1, byte2 = 0, None if range_header: match = re.search(r'(\d+)-(\d*)', range_header) groups = match.groups() if groups[0]: byte1 = int(groups[0]) if groups[1]: byte2 = int(groups[1]) try: mimetype = mimetypes.guess_type(path)[0] if mimetype is None: mimetype = 'text/plain' elif mimetype.startswith('video'): mimetype = 'video/mp4' except: return self.send_file(path, download=True) chunk, start, length, file_size = self.get_chunk( path, byte1, byte2) resp = Response(chunk, 206, mimetype=mimetype, content_type=mimetype, direct_passthrough=True) resp.headers.add( 'Content-Range', 'bytes {0}-{1}/{2}'.format(start, start + length - 1, file_size)) return resp
def post(self, *args, **kwargs): item = JU.extract_keys(request.get_json(), "item") if not item: return JU.make_response("invalid data", 400) if "magnet" in item.keys(): return {"magnet": item.get("magnet")} magnet = ts.get_magnet(item) return {"magnet": magnet}
def get(self): Hash = request.args.get('hash', None) if not Hash: return make_response( {"torrents": seedr.list_torrents(username=get_jwt_identity())}, 200) status = seedr.torrent_status(Hash) if not status: return JU.make_response(f"torrent '{Hash}' not found", 404) return make_response(status, 200)
def post(self): hashes = JU.extract_keys(request.get_json(), "hashes") if JU.null_values(hashes): return JU.make_response("invalid data", 400) removed = [] for Hash in hashes: status = seedr.remove_torrent(Hash) if not status: continue removed.append(Hash) return make_response({"removed": removed}, 200)
def post(self): magnets = JU.extract_keys(request.get_json(), "magnets") if JU.null_values(magnets): return JU.make_response("invalid data", 400) hashes = [] for magnet in magnets: Hash = seedr.add_magnet(magnet) if not Hash: continue hashes.append(Hash) return make_response({"hashes": hashes}, 200)
def get(self): query = request.args.get('query', None) if not query: return JU.make_response("parameter '?query=' required", 400) try: torrents = ts.search(query, max_results=20) except Exception as e: torrents = [] return make_response(json.dumps(torrents), 200)
def post(self): username = get_jwt_identity() password, refresh_token = JU.extract_keys(request.get_json(), "password", "refresh_token") if JU.null_values(username, password, refresh_token): return JU.make_response("invalid data", 400) access_jti = get_raw_jwt()['jti'] refresh_jti = get_jti(refresh_token) user = User.find_by_username(username) if not user: return JU.make_response(f"user '{username}' doesn't exists", 404) if not User.verify(user.password, password): return JU.make_response(f"wrong password", 401) user.delete_from_db() RevokedToken(jti=access_jti).add() RevokedToken(jti=refresh_jti).add() return JU.make_response(f"user '{username}' deleted", 200)
def delete(self, *args, **kwargs): path = JU.extract_keys(request.get_json(), "path") if not path: return JU.make_response("paths missing", 400) if not os.path.exists(path): return JU.make_response("paths doesn't exists", 400) try: PublicURLS.find_by_file_path(file_path=path).delete_from_db() except: pass try: if os.path.isfile(path): os.remove(path) else: shutil.rmtree(path) except Exception as e: return JU.make_response("Error occured: {}".format(str(e)), 500) return JU.make_response("file deleted", 200)
def post(self): access_jti = get_raw_jwt()['jti'] refresh_token = JU.extract_keys(request.get_json(), "refresh_token") if not refresh_token: return JU.make_response("refresh token is required", 400) try: refresh_jti = get_jti(refresh_token) RevokedToken(jti=access_jti).add() RevokedToken(jti=refresh_jti).add() return {'message': 'logged out successfully'} except Exception as e: print(e) return {'message': 'something went wrong'}, 500
def get(self, public_url_hash): access_token = request.args.get('token', None) if not access_token: query = PublicURLS.find_by_public_url_hash( public_url_hash=public_url_hash) if not query: return JU.make_response(f"url not found", 404) if not query.is_valid: return JU.make_response(f"url expired", 410) return self.send_file(query.file_path, request.args.get('download', None)) else: access_token = decode_token(access_token) if time.time() > access_token.get('exp'): JU.make_response("token expired", 401) try: path = base64.b64decode(public_url_hash).decode('utf-8') except: return JU.make_response("invalid path", 400) return self.send_file(path)
def post(self): username, password = JU.extract_keys(request.get_json(), "username", "password") if JU.null_values(username, password): return JU.make_response("invalid data", 400) user = User.find_by_username(username) if not user: return JU.make_response(f"username '{username}' doesn't exist", 404) if not User.verify(user.password, password): return JU.make_response(f"wrong password", 401) access_token = create_access_token(identity=username, fresh=True) refresh_token = create_refresh_token(identity=username) return make_response( { "message": f"logged in as {username}", "access_token": access_token, "refresh_token": refresh_token }, 200)
def get(self): username = get_jwt_identity() user = User.find_by_username(username) if not user: return JU.make_response(f"user '{username}' doesn't exists", 404) return user.JSON
def post(self): hashes = JU.extract_keys(request.get_json(), "hashes") if JU.null_values(hashes): return JU.make_response("invalid data", 400) return make_response({"torrents": seedr.list_torrents(hashes)}, 200)
def send_file(self, path, download=False): if not os.path.exists(path): return JU.make_response("invalid path", 400) elif os.path.isdir(path): # archive directory and send zip file current_app.logger.info(f"archiving dir: {path} to send") os.makedirs("/downloads/tmp", exist_ok=True) fname = os.path.join("/downloads/tmp/", os.path.basename(path)) + ".zip" for i in glob.glob("/downloads/tmp/*.zip"): current_app.logger.info(f"deleting older archive: {i}") os.remove(i) if not os.path.exists(fname): shutil.make_archive(fname.rstrip(".zip"), 'zip', path) if os.path.exists(path): return send_file(fname, mimetype='application/octet-stream', attachment_filename=os.path.basename(fname), as_attachment=True) else: return JU.make_response("Unable to archive directory", 400) elif os.path.exists(path): if download: # send raw file that can be downloaded directly return send_file(path, mimetype='application/octet-stream', attachment_filename=os.path.basename(path), as_attachment=True) # stream file over byte range header range_header = request.headers.get('Range', None) byte1, byte2 = 0, None if range_header: match = re.search(r'(\d+)-(\d*)', range_header) groups = match.groups() if groups[0]: byte1 = int(groups[0]) if groups[1]: byte2 = int(groups[1]) try: mimetype = mimetypes.guess_type(path)[0] if mimetype is None: mimetype = 'text/plain' elif mimetype.startswith('video'): mimetype = 'video/mp4' except: return self.send_file(path, download=True) chunk, start, length, file_size = self.get_chunk( path, byte1, byte2) resp = Response(chunk, 206, mimetype=mimetype, content_type=mimetype, direct_passthrough=True) resp.headers.add( 'Content-Range', 'bytes {0}-{1}/{2}'.format(start, start + length - 1, file_size)) return resp