def get_public_file_impl(self, request, fileId, name): try: if request.query.info: info = self.filesys_service.publicFileInfo(fileId) if name is not None: info['name'] = name return Response(200, {}, {"result": {'file': info}}) else: password = request.headers.get('X-YUE-PASSWORD', None) info, stream = self.filesys_service.loadPublicFile( fileId, password) go = files_generator_v2(stream) if name is None: name = info.name return send_generator(go, name, file_size=info.size, attachment=request.query.dl) except FileSysServiceException: return Response(401, {}, {"error": "invalid file id"}) except StorageNotFoundException: return Response(404, {}, {"error": "invalid file id"})
def get_song_by_reference(self, ref_id): try: song = self.audio_service.findSongByReferenceId( request.current_user, int(ref_id)) return Response(200, {}, {"result": song}) except AudioServiceException as e: return Response( 404, {}, {"error": "No Song for reference id %s" % (ref_id)})
def get_song(self, request): try: song = self.audio_service.findSongById(request.current_user, request.args.song_id) return Response(200, {}, {"result": song}) except AudioServiceException as e: return Response( 404, {}, {"error": "No Song for id %s" % (request.args.song_id)})
def set_default_queue(self, request): req = request.get_json() if 'query' not in req: return Response(400, {}, {"error": "invalid request: missing `query`"}) self.audio_service.setDefaultQuery(request.current_user, req['query']) return Response(200, {}, {"result": "OK"})
def root(self, request): host = request.headers['Host'] if host is not None: location = "https://%s/%s" % (host, request.args.path) headers = { "Location": location } response = Response(308, headers, None) else: response = Response(404, {}, None) return response
def remove_file(self, request): logging.info("received delete") self.filesys_service.remove(request.current_user, request.args.root, request.args.resPath) return Response(200, {}, {"result": "OK"})
def upload(self, request): """ mtime: on a successful upload, set the modified time to mtime, unix epoch time in seconds version: if greater than 1, validate version error codes: 409: file already exists and is a newer version """ stream = request.body request.raw_socket.setblocking(True) if request.query.crypt in (CryptMode.server, CryptMode.system): password = request.headers.get('X-YUE-PASSWORD', None) stream = self.filesys_service.encryptStream( request.current_user, password, stream, "r", request.query.crypt) data = self.filesys_service.saveFile( request.current_user, request.args.root, request.args.resPath, stream, mtime=request.query.mtime, version=request.query.version, permission=request.query.permission, encryption=request.query.crypt) obj = { "result": "OK", "file_info": data, } return Response(200, {}, obj)
def update_song(self, request): # for song in g.body: # self._correct_path(song) error = 200 try: n = self.audio_service.updateSongs(request.current_user, request.body) error = 200 if n == 1 else 400 except LibraryException as e: # logging.exception(e) return Response(400, {}, {"error": "%s" % e}) return Response(200, {}, {"result": "OK"})
def manifest(self, request): keys = { "manifest_version": 2, "version": "0.0.0", "name": "yueapp", } return Response(200, {}, keys)
def delete_user_note(self, note_id): """convenience function wrapping file delete""" resPath = self.filesys_service.fs.join(request.query.base, request.args.note_id) self.filesys_service.remove(request.current_user, request.query.root, resPath) return Response(200, {}, {"result": "OK"})
def list_users(self, request): """ list all users for a given domain """ user_info = self.user_service.listDomainUsers(request.args.domain) return Response(200, {}, {'result': user_info})
def get_user_notes(self, request): notes = self.filesys_service.getUserNotes(request.current_user, request.query.root, dir_path=request.query.base) # return note_id => note_info print(notes) payload = {note['file_name']: note for note in notes} return Response(200, {}, {"result": payload})
def is_token_valid(self, request): token = request.body["token"] is_valid, reason = self.user_service.verifyToken(token) res = {"token_is_valid": is_valid, "reason": reason} return Response(200, {}, res)
def set_song_art(self, request): self.audio_service.setSongAlbumArtPath(request.current_user, request.args.song_id, request.body['root'], request.body['path']) return Response(200, {}, {"result": "OK"})
def search_library_forest(self, request): """ return song information from the library """ forest = self.audio_service.search_forest( request.current_user, request.query.query, showBanished=request.query.showBanished) return Response(201, {}, {"result": forest})
def update_history(self, request): """ the json payload is a list of history records. {"timestamp": <epoch_time>, "song_id": <song_id>} epoch_time is the number of seconds since the UNIX epoch as an integer """ records = request.json if records is None or len(records) == 0: return Response(400, {}, {"error": "no data sent"}) count = self.audio_service.insertPlayHistory(request.current_user, records) obj = {"result": count, "records": len(records)} return Response(200, {}, obj)
def move_file(self, request): """ move or rename a file """ self.filesys_service.moveFile(request.current_user, request.args.root, request.body['src'], request.body['dst']) return Response(200, {}, {"result": "OK"})
def user_key(self): """ return the encrypted form of the current file encryption key. by default return the client key, """ key = self.filesys_service.getUserKey(request.current_user, request.query.mode) return Response(200, {}, {"result": {"key": key}})
def delete_song(self, request): try: success = self.audio_service.deleteSong(request.current_user, request.args.song_id) except AudioServiceException as e: success = False return Response(200 if success else 404, {}, {"result": "OK" if success else "ERROR"})
def get_history(self, request): """ get song history between a date range the start and end time can be an integer or ISO string. """ offset = request.query.page * request.query.page_size records = self.audio_service.getPlayHistory( request.current_user, request.query.start, request.query.end, offset=offset, limit=request.query.page_size) obj = { "result": records, "page": request.query.page, "page_size": request.query.page_size } return Response(200, {}, obj) """ get song history between a date range the start and end time can be an integer or ISO string. """ offset = request.query.page * request.query.page_size records = self.audio_service.getPlayHistory( request.current_user, request.query.start, request.query.end, offset=offset, limit=request.query.page_size) obj = { "result": records, "page": request.query.page, "page_size": request.query.page_size } return Response(200, {}, obj)
def doc(self, request): """ construct curl documentation for endpoints hostname: the hostname to use in examples if an empty string, the request url will be used """ doc = "".join(list(curldoc(self.app_endpoints, request.query.hostname))) return Response(200, {"Content-Type": "text/plain"}, doc.encode("utf-8"))
def set_user_key(self): """ set the 'client' encryption key only the client key can be set in this way. the system keys cannot be changed and the server key can be changed via change password api """ self.filesys_service.setUserClientKey(request.current_user, request.body) return Response(200, {}, {"result": "OK"})
def search(self, request): limit = request.query.limit offset = request.query.limit * request.query.page records = self.filesys_service.search(request.current_user, request.args.root, request.query.path, request.query.terms, limit, offset) return Response(200, {}, {"result": {'files': records}})
def create_user(self, request): """ TODO: return 404 if domain/role is not found TODO: return 400 is user exists """ user_id = user = self.user_service.createUser(request.body["email"], request.body["domain"], request.body["role"], request.body["password"]) return jsonify(id=user_id) return Response(200, {}, {'id': user_id})
def paginate_library(self, request): """ return song information from the library """ songs = self.audio_service.paginate( request.current_user, request.query.query, limit=request.query.limit, last_id=request.query.last_id, showBanished=request.query.showBanished) obj = { "result": songs, } return Response(200, {}, obj)
def create_queue(self, request): """ create a new queue using a query, return the new song list """ if request.query.query is None: request.query.query = self.audio_service.defaultQuery(request.current_user) songs = self.audio_service.search(request.current_user, request.query.query) # TODO: have role based limits on queue size songs = binshuffle(songs, lambda x: x['artist'])[:request.query.limit] song_ids = [song['id'] for song in songs] self.audio_service.setQueue(request.current_user, song_ids) return Response(200, {}, {"result": songs})
def speedtest_download(self, request): count = int_range(1, 2**8)(request.args.count) size = int_range(2, 2**16)(request.args.size) total_size = int_range(2, 2**20)(count * size) mimetype = "application/octect-stream" go = speedtest_gen(count, size) headers = { 'Content-Length': total_size, 'Content-Type': "application/octect-stream", } return Response(200, headers, go)
def increment_playcount(self, request): """ curl -u admin:admin --header "Content-Type: application/json" \ -X POST -d '["7065c940-3c6f-429f-bfd9-27cccc402447"]' \ http://localhost:4200/api/library/history/increment """ timestamp = timegm(time.localtime(time.time())) records = [{ 'song_id': sid, 'timestamp': timestamp } for sid in request.body] self.audio_service.updatePlayCount(request.current_user, records) return Response(200, {}, {"result": "OK"})
def get_index(self, request): """ return files owned by a user """ offset = request.query.limit * request.query.page files = self.filesys_service.listIndex(request.current_user, request.args.root, request.args.resPath, limit=request.query.limit, offset=offset) obj = { "result": files, "page": request.query.page, "page_size": request.query.limit, } return Response(200, {}, obj)
def doc_js(self, request): """ construct curl documentation for endpoints hostname: the hostname to use in examples if an empty string, the request url will be used """ api = OpenApi(self.app_endpoints) api.license("MIT", "https://mit-license.org/") api.contact(None, "*****@*****.**") api.version("0.0.0.0") api.title("YueApp") api.description("YueApp API Doc") api.servers([{"url": "https://%s" % request.query.hostname}]) return Response(200, {"Content-Type": "application/json"}, api.jsons().encode("utf-8"))