From 77cd712f10694d49eef4855c085185e5039f289a Mon Sep 17 00:00:00 2001 From: "Troll (Hermes Agent)" Date: Mon, 10 Aug 2026 23:25:29 +0000 Subject: [PATCH] Add per-request MusicGPT poll button --- app.py | 41 +++++++++++++++++++++++++++++++++--- templates/admin/request.html | 3 +++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/app.py b/app.py index 80b8320..0dbe65e 100644 --- a/app.py +++ b/app.py @@ -325,15 +325,14 @@ def musicgpt_webhook(): update_fields['musicgpt_error'] = data.get('reason') or 'Flagged by MusicGPT' if new_status in ('COMPLETED', 'FINISHED'): # Webhooks often fire before audio URLs are ready. Store whatever the - # webhook gives us, then rely on the dashboard manual refresh to - # download files once the API reports them fully available. + # webhook gives us (album cover, cost), then attempt download in case + # the webhook is the rare complete one. if data.get('album_cover_path'): update_fields['album_cover_url'] = data.get('album_cover_path') try: update_fields['musicgpt_cost'] = float(data.get('conversion_cost') or 0) except (ValueError, TypeError): pass - # Still attempt download in case the webhook is the rare complete one. download_musicgpt_outputs(req, data, version=version) row = db.execute('SELECT * FROM requests WHERE id = ?', (req['id'],)).fetchone() req = dict(row) @@ -421,6 +420,42 @@ def admin_musicgpt_refresh(): return redirect(url_for('admin_dashboard')) +@app.route('/admin/musicgpt/poll/', methods=['POST']) +def admin_musicgpt_poll_request(rid): + """Poll a single MusicGPT task from the admin request page and download files if ready.""" + redir = require_admin() + if redir: + return redir + req = get_request_by_id(rid) + if not req: + flash('Request not found.', 'error') + return redirect(url_for('admin_dashboard')) + task_id = req.get('musicgpt_task_id') + if not task_id: + flash('No MusicGPT task for this request.', 'error') + return redirect(url_for('admin_request', rid=rid)) + result = musicgpt_poll_status(task_id) + conversion = result.get('conversion') or {} + status = (conversion.get('status') or result.get('status') or '').upper() + if status in ('COMPLETED', 'FINISHED'): + download_musicgpt_outputs(req, conversion) + req = get_request_by_id(rid) + fields = {'musicgpt_status': 'COMPLETED'} + if req and req.get('song_a_path') and req.get('song_b_path'): + fields['status'] = 'songs_uploaded' + update_request(rid, **fields) + flash('MusicGPT task completed and files downloaded.', 'success') + elif status in ('FAILED', 'ERROR'): + update_request(rid, musicgpt_status='FAILED', musicgpt_error=(conversion.get('status_msg') if isinstance(conversion, dict) else None) or 'Polling reported failure') + flash('MusicGPT task failed.', 'error') + elif status: + update_request(rid, musicgpt_status=status) + flash(f'MusicGPT status: {status}', 'info') + else: + flash('Could not determine MusicGPT status.', 'warning') + return redirect(url_for('admin_request', rid=rid)) + + @app.route('/thanks/') def thanks(rid): """Confirmation page shown after a customer submits a request.""" diff --git a/templates/admin/request.html b/templates/admin/request.html index 2c12a64..e6168fe 100644 --- a/templates/admin/request.html +++ b/templates/admin/request.html @@ -385,6 +385,9 @@ {% if in_progress %} {% endif %} + {% if req.musicgpt_task_id and req.musicgpt_status not in ('IN_QUEUE', 'IN_PROGRESS') %} + + {% endif %}