def reset_password(): """ Ask for a reset password link by email. --- tags: - Accounts responses: 200: description: fixme. """ email = request.args.get("email", None) if not email: abort(400) user = User.query.filter(User.email == email).first() if not user: abort(404) # generate a reset link prt = PasswordResetToken() prt.token = generate_random_token() prt.expires_at = None prt.user_id = user.id db.session.add(prt) db.session.commit() add_user_log(user.id, user.id, "user", "info", "Password reset token generated") # Send email token_link = f"https://{current_app.config['AP_DOMAIN']}/password-reset/{prt.token}" msg = Message(subject="Password reset", recipients=[user.email], sender=current_app.config["MAIL_DEFAULT_SENDER"]) _config = Config.query.first() if not _config: print("ERROR: cannot get instance Config from database") instance = {"name": None, "url": None} if _config: instance["name"] = _config.app_name instance["url"] = current_app.config["REEL2BITS_URL"] msg.body = render_template("email/password_reset.txt", token_link=token_link, user=user, instance=instance) msg.html = render_template("email/password_reset.html", token_link=token_link, user=user, instance=instance) err = None mail = current_app.extensions.get("mail") if not mail: err = "mail extension is none" else: try: mail.send(msg) except ConnectionRefusedError as e: # TODO: do something about that maybe print(f"Error sending mail: {e}") err = e except smtplib.SMTPRecipientsRefused as e: print(f"Error sending mail: {e}") err = e except smtplib.SMTPException as e: print(f"Error sending mail: {e}") err = e if err: add_log( "global", "ERROR", f"Error sending email for password reset user {user.id}: {err}" ) add_user_log(user.id, user.id, "user", "error", "An error occured while sending email") return jsonify({"status": "ok"}), 204
def account_delete(): """ Delete account --- tags: - Accounts responses: 200: description: Returns user username """ current_user = current_token.user if not current_user: abort(400) # store a few infos username = current_user.name user_id = current_user.id email = current_user.email # Revoke Oauth2 credentials for oa2_token in OAuth2Token.query.filter( OAuth2Token.user_id == current_user.id).all(): oa2_token.revoked = True # Drop password reset tokens for prt in PasswordResetToken.query.filter( PasswordResetToken.user_id == current_user.id).all(): db.session.delete(prt) # set all activities as deleted activities = Activity.query.filter( Activity.actor == current_user.actor[0].id) for activity in activities.all(): activity.meta_deleted = True # set actor as deleted and federate a Delete(Actor) current_user.actor[0].meta_deleted = True # Federate Delete(Actor) federate_delete_actor(current_user.actor[0]) # drop all relations follows = Follower.query.filter( or_(Follower.actor_id == current_user.actor[0].id, Follower.target_id == current_user.actor[0].id)) for follow_rel in follows.all(): db.session.delete(follow_rel) # delete User db.session.delete(current_user) db.session.commit() # crimes # send email that account have been deleted msg = Message(subject="Account successfully deleted", recipients=[email], sender=current_app.config["MAIL_DEFAULT_SENDER"]) msg.body = render_template("email/account_deleted.txt", username=username) msg.html = render_template("email/account_deleted.html", username=username) err = None mail = current_app.extensions.get("mail") if not mail: err = "mail extension is none" else: try: mail.send(msg) except ConnectionRefusedError as e: # TODO: do something about that maybe print(f"Error sending mail: {e}") err = e except smtplib.SMTPRecipientsRefused as e: print(f"Error sending mail: {e}") err = e except smtplib.SMTPException as e: print(f"Error sending mail: {e}") err = e if err: add_log( "global", "ERROR", f"Error sending email for account deletion of {username} ({user_id}): {err}" ) return jsonify({"username": username}), 200
def work_metadatas(sound_id, force=False): # force is unused for now sound = Sound.query.get(sound_id) if not sound: print("- Cant find sound ID %(id)s in database".format(id=sound_id)) return add_user_log( sound.id, sound.user.id, "sounds", "info", "Metadatas gathering started for: {0} -- {1}".format(sound.id, sound.title), ) _infos = sound.sound_infos.first() if not _infos: _infos = SoundInfo() _infos.sound_id = sound.id # Generate Basic infos fname = os.path.join(current_app.config["UPLOADED_SOUNDS_DEST"], sound.user.slug, sound.filename) basic_infos = None if not _infos.done_basic: basic_infos = get_basic_infos(fname) if type(basic_infos) != dict: # cannot process further print(f"- MIME: '{basic_infos}' is not supported") add_log("global", "ERROR", f"Unsupported audio format: {basic_infos}") return False if not _infos.done_basic or force: print("- WORKING BASIC on {0}, {1}".format(sound.id, sound.filename)) print("- Our file got basic infos: {0}".format(basic_infos)) _infos.duration = basic_infos["duration"] _infos.channels = basic_infos["channels"] _infos.rate = basic_infos["rate"] _infos.codec = basic_infos["codec"] _infos.format = basic_infos["format"] _infos.bitrate = basic_infos["bitrate"] _infos.bitrate_mode = basic_infos["bitrate_mode"] _infos.done_basic = True _infos.type = basic_infos["type"] _infos.type_human = basic_infos["type_human"] if not _infos.done_waveform or force: if sound.transcode_state == Sound.TRANSCODE_DONE: _f, _e = splitext(fname) fname_t = "{0}.mp3".format(_f) print("- WORKING ON TRANSCODED FOR WAVEFORM") else: fname_t = fname print("- GENERATING AUDIO DAT FILE") dat_file_name = generate_audio_dat_file(fname_t, _infos.duration) print("- WORKING WAVEFORM on {0}, {1}".format(sound.id, sound.filename)) waveform_infos = get_waveform(dat_file_name, _infos.duration) print("- Our file got waveform infos: {0}".format(waveform_infos)) _infos.waveform = waveform_infos if not waveform_infos: _infos.waveform_error = True add_user_log( sound.id, sound.user.id, "sounds", "info", "Got an error when generating waveform" " for: {0} -- {1}".format(sound.id, sound.title), ) # Delete the temporary dat file os.unlink(dat_file_name) _infos.done_waveform = True db.session.add(_infos) db.session.commit() add_user_log( sound.id, sound.user.id, "sounds", "info", "Metadatas gathering finished for: {0} -- {1}".format(sound.id, sound.title), ) return True
def upload_workflow(self, sound_id): print("UPLOAD WORKFLOW started") sound = Sound.query.get(sound_id) if not sound: print("- Cant find sound ID {id} in database".format(id=sound_id)) return # First, if the sound isn't local, we need to fetch it if sound.activity and not sound.activity.local: fetch_remote_track(sound_id) fetch_remote_artwork(sound_id) if not sound.filename.startswith("remote_"): print("UPLOAD WORKFLOW had errors") add_log("global", "ERROR", f"Error fetching remote track {sound.id}") return print("METADATAS started") metadatas = work_metadatas(sound_id) print("METADATAS finished") if not metadatas: # cannot process further sound.transcode_state = Sound.TRANSCODE_ERROR db.session.commit() print("UPLOAD WORKFLOW had errors") add_log("global", "ERROR", f"Error processing track {sound.id}") add_user_log(sound.id, sound.user_id, "sounds", "error", "An error occured while processing your track") return if metadatas: print("TRANSCODE started") work_transcode(sound_id) print("TRANSCODE finished") # The rest only applies if the track is local if not sound.remote_uri: # Federate if public if not sound.private: print("UPLOAD WORKFLOW federating sound") # Federate only if sound is public sound.activity_id = federate_new_sound(sound) db.session.commit() track_url = f"https://{current_app.config['AP_DOMAIN']}/{sound.user.name}/track/{sound.slug}" msg = Message( subject="Song processing finished", recipients=[sound.user.email], sender=current_app.config["MAIL_DEFAULT_SENDER"], ) _config = Config.query.first() if not _config: print("ERROR: cannot get instance Config from database") instance = {"name": None, "url": None} if _config: instance["name"] = _config.app_name instance["url"] = current_app.config["REEL2BITS_URL"] msg.body = render_template("email/song_processed.txt", sound=sound, track_url=track_url, instance=instance) msg.html = render_template("email/song_processed.html", sound=sound, track_url=track_url, instance=instance) err = None mail = current_app.extensions.get("mail") if not mail: err = "mail extension is none" else: try: mail.send(msg) except ConnectionRefusedError as e: # TODO: do something about that maybe print(f"Error sending mail: {e}") err = e except smtplib.SMTPRecipientsRefused as e: print(f"Error sending mail: {e}") err = e except smtplib.SMTPException as e: print(f"Error sending mail: {e}") err = e if err: add_log("global", "ERROR", f"Error sending email for track {sound.id}: {err}") add_user_log(sound.id, sound.user.id, "sounds", "error", "An error occured while sending email") print("UPLOAD WORKFLOW finished")
def upload_workflow(self, sound_id): print("UPLOAD WORKFLOW started") sound = Sound.query.get(sound_id) if not sound: print("- Cant find sound ID {id} in database".format(id=sound_id)) return print("METADATAS started") metadatas = work_metadatas(sound_id) print("METADATAS finished") if not metadatas: # cannot process further sound.transcode_state = Sound.TRANSCODE_ERROR db.session.commit() print("UPLOAD WORKFLOW had errors") add_log("global", "ERROR", f"Error processing track {sound.id}") add_user_log(sound.id, sound.user.id, "sounds", "error", "An error occured while processing your track") return if metadatas: print("TRANSCODE started") work_transcode(sound_id) print("TRANSCODE finished") # Federate if public if not sound.private: print("UPLOAD WORKFLOW federating sound") # Federate only if sound is public sound.activity_id = federate_new_sound(sound) db.session.commit() track_url = f"https://{current_app.config['AP_DOMAIN']}/{sound.user.name}/track/{sound.slug}" msg = Message( subject="Song processing finished", recipients=[sound.user.email], sender=current_app.config["MAIL_DEFAULT_SENDER"], ) msg.body = render_template("email/song_processed.txt", sound=sound, track_url=track_url) msg.html = render_template("email/song_processed.html", sound=sound, track_url=track_url) err = None mail = current_app.extensions.get("mail") if not mail: err = "mail extension is none" else: try: mail.send(msg) except ConnectionRefusedError as e: # TODO: do something about that maybe print(f"Error sending mail: {e}") err = e except smtplib.SMTPRecipientsRefused as e: print(f"Error sending mail: {e}") err = e except smtplib.SMTPException as e: print(f"Error sending mail: {e}") err = e if err: add_log("global", "ERROR", f"Error sending email for track {sound.id}: {err}") add_user_log(sound.id, sound.user.id, "sounds", "error", "An error occured while sending email") print("UPLOAD WORKFLOW finished")