def add_post_comment(post_id, username, text): try: timestamp = datetime.utcnow().isoformat() post_data = PostModel.add_comment(post_id=post_id, username=username, text=text, timestamp=timestamp) post_username = post_data['username'] post_title = post_data['title'] UserModel.add_notification_message( post_username, f'commented on your post {post_title}', user_ref=username, post_ref=post_id) return make_response( jsonify({ 'status': 'success', 'message': 'Comment successfully added to post.', 'data': post_data }), 200) except OperationFailure as e: return make_response( jsonify({ 'status': 'fail', 'message': f'DB Operation Error: {str(e)}', }), 400) except ConnectionFailure as e: return make_response( jsonify({ 'status': 'fail', 'message': f'DB Connection Error: {str(e)}', }), 500)
def like_post(post_id, username): try: post_data = PostModel.like_post( post_id=post_id, username=username, ) post_username = post_data['username'] post_title = post_data['title'] UserModel.add_notification_message(post_username, f'liked your post {post_title}', user_ref=username, post_ref=post_id) return make_response( jsonify({ 'status': 'success', 'message': 'Post successfully liked.', 'data': post_data }), 200) except OperationFailure as e: return make_response( jsonify({ 'status': 'fail', 'message': f'DB Operation Error: {str(e)}', }), 400) except ConnectionFailure as e: return make_response( jsonify({ 'status': 'fail', 'message': f'DB Connection Error: {str(e)}', }), 500)
def follow(username, other_username): try: user_app_data = UserModel.follow(username, other_username)[0] UserModel.add_notification_message(other_username, f'followed you!', user_ref=username) data = { 'username': user_app_data['_id'], 'email': user_app_data['email'], 'followers': user_app_data['followers'], 'followings': user_app_data['followings'], 'posts': user_app_data['posts'], } return make_response( jsonify({ 'status': 'success', 'message': f'Successfully followed {other_username}.', 'data': data }), 200) except Auth0Error as e: return make_response( jsonify({ 'status': 'fail', 'message': f'Auth0 Error: {str(e)}', }), 400) except OperationFailure as e: return make_response( jsonify({ 'status': 'fail', 'message': f'DB Operation Error: {str(e)}', }), 400) except ConnectionFailure as e: return make_response( jsonify({ 'status': 'fail', 'message': f'DB Connection Error: {str(e)}', }), 500)
def create_user_post(username, title, audio_file, description=None, image_file=None): try: post_id = uuid.uuid4().hex timestamp = datetime.utcnow().isoformat() file_name, file_ext = os.path.splitext(audio_file.filename) # todo: multithread or multiprocess the audio conversion cos it's blocking and uses high cpu audio = AudioSegment.from_file(audio_file, format=file_ext.lstrip('.')) if len(audio ) > 12 * 60 * 1000: # len(audio) is audio duration in ms return make_response( jsonify({ 'status': 'fail', 'message': f'Audio duration is longer than 12 minutes, actual duration = {len(audio)/1000/60}min.' }), 400) # export in memory, not stored to disk audio_buffer = io.BytesIO() # normalize audio amplitude (volume) to -20 dBFS (smaller is quieter) # src: https://github.com/jiaaro/pydub/issues/90#issuecomment-75551606 target_dBFS = -20 change_in_dBFS = target_dBFS - audio.dBFS normalized_audio = audio.apply_gain(change_in_dBFS) normalized_audio.export(audio_buffer, format='mp3') audio_link = upload(audio_buffer, uuid.uuid4().hex + '.mp3') audio_buffer.close() image_link = None if image_file is not None: file_name, file_ext = os.path.splitext(image_file.filename) image_buffer = io.BytesIO() process_image(image_file, image_buffer) image_link = upload(image_buffer, uuid.uuid4().hex + file_ext) image_buffer.close() post_data = PostModel.add_user_post(username=username, post_id=post_id, title=title, timestamp=timestamp, audio_link=audio_link, description=description, image_link=image_link) user_data = UserModel.get_user(username) for follower_username in user_data['followers']: UserModel.add_notification_message( follower_username, f'made a new post!', user_ref=username, post_ref=post_id, ) return make_response( jsonify({ 'status': 'success', 'message': 'Post successfully created.', 'data': post_data }), 201) except CouldntDecodeError as e: return make_response( jsonify({ 'status': 'fail', 'message': f'PyDub failed to decode: {str(e)}', }), 400) except CouldntEncodeError as e: return make_response( jsonify({ 'status': 'fail', 'message': f'PyDub failed to encode: {str(e)}', }), 500) except UnidentifiedImageError as e: return make_response( jsonify({ 'status': 'fail', 'message': f'PIL failed to read image: {str(e)}', }), 400) except OperationFailure as e: return make_response( jsonify({ 'status': 'fail', 'message': f'DB Operation Error: {str(e)}', }), 400) except ConnectionFailure as e: return make_response( jsonify({ 'status': 'fail', 'message': f'DB Connection Error: {str(e)}', }), 500) except ClientError as e: return make_response( jsonify({ 'status': 'fail', 'message': f'S3 Connection Error: {str(e)}', }), 500)