from flask import Blueprint, render_template, request, redirect, url_for, flash from app.routes.asset import GetOriginalAssetInfo, AddAudioAssetToAudioMigrationQueue from app.models.asset import Asset from app.models.user import User from app.services import economy from app.util import auth, websiteFeatures, turnstile, transactions from app.extensions import db, redis_controller from app.enums.TransactionType import TransactionType AudioMigratorRoute = Blueprint('assetmigrator', __name__, template_folder='pages') @AudioMigratorRoute.route('/audiomigrator', methods=['GET']) @auth.authenticated_required def audiomigrator(): return render_template('audiomigrator/index.html') @AudioMigratorRoute.route('/audiomigrator', methods=['POST']) @auth.authenticated_required def audiomigrator_post(): AuthenticatedUser : User = auth.GetCurrentUser() if not websiteFeatures.GetWebsiteFeature("AudioMigrator"): flash("Audio migration is temporarily disabled", "error") return redirect("/audiomigrator") CFTurnstileResponse = request.form.get( key="cf-turnstile-response", default=None, type=str) if CFTurnstileResponse is None: flash("Invalid captcha", "error") return redirect("/audiomigrator") if not turnstile.VerifyToken(CFTurnstileResponse): flash("Invalid captcha", "error") return redirect("/audiomigrator") PlaceId = request.form.get( key = "placeid", default = None, type = int ) if PlaceId is None: flash("Invalid place ID", "error") return redirect("/audiomigrator") RequestedAudioIds = request.form.get( key = "audio-ids", default = None, type = str ) if RequestedAudioIds is None: flash("Invalid audio IDs", "error") return redirect("/audiomigrator") RequestedAudioIds = RequestedAudioIds.split("\n") for i in range(len(RequestedAudioIds)): RequestedAudioIds[i] = RequestedAudioIds[i].strip() if RequestedAudioIds[i].isdigit(): RequestedAudioIds[i] = int(RequestedAudioIds[i]) else: RequestedAudioIds.remove(RequestedAudioIds[i]) if len(RequestedAudioIds) > 100: flash("You can only migrate 100 audios at a time", "error") return redirect("/audiomigrator") if len(RequestedAudioIds) < 1: flash("You must migrate at least 1 audio", "error") return redirect("/audiomigrator") if PlaceId < 1: flash("Invalid place ID", "error") return redirect("/audiomigrator") RobuxBalance, _ = economy.GetUserBalance(AuthenticatedUser) RequiredAmountRobux = 0 AudioIdsToMigrate : list[int] = [] for RequestedAudio in RequestedAudioIds: if Asset.query.filter_by(id = RequestedAudio ).first(): continue if redis_controller.lrange("migrate_audio_assets_queue", 0, -1).count(str(RequestedAudio)) > 0: continue if RequestedAudio in AudioIdsToMigrate: continue AudioIdsToMigrate.append(RequestedAudio) RequiredAmountRobux += 5 if len(AudioIdsToMigrate) == 0: flash(f"Queued 0 / {len(RequestedAudioIds)} audios to be migrated", "success") return redirect("/audiomigrator") if RobuxBalance < RequiredAmountRobux: flash(f"You don't have enough robux to migrate these audios, Required R${RequiredAmountRobux}", "error") return redirect("/audiomigrator") try: economy.DecrementTargetBalance( AuthenticatedUser, Amount = RequiredAmountRobux, CurrencyType = 0 ) except economy.InsufficientFundsException: flash(f"You don't have enough robux to migrate these audios, Required R${RequiredAmountRobux}", "error") return redirect("/audiomigrator") except Exception as e: flash(f"An error occured while deducting robux", "error") return redirect("/audiomigrator") transactions.CreateTransaction( Reciever = User.query.filter_by(id = 1).first(), Sender = AuthenticatedUser, CurrencyAmount = RequiredAmountRobux, CurrencyType = 0, TransactionType = TransactionType.Purchase, CustomText = f"Audio migration" ) for AudioId in AudioIdsToMigrate: AddAudioAssetToAudioMigrationQueue(AudioId, bypassQueueLimit = True ,placeId=PlaceId) flash(f"Queued {len(AudioIdsToMigrate)} / {len(RequestedAudioIds)} audios to be migrated", "success") return redirect("/audiomigrator")