Single-paste Hermes response with title extraction and copy buttons
This commit is contained in:
parent
665a7e5655
commit
30732c0b64
3 changed files with 46 additions and 19 deletions
1
app.py
1
app.py
|
|
@ -196,6 +196,7 @@ def admin_request(rid):
|
||||||
|
|
||||||
if action == 'save_prompt':
|
if action == 'save_prompt':
|
||||||
update_request(rid,
|
update_request(rid,
|
||||||
|
suno_title=request.form.get('suno_title', '').strip(),
|
||||||
suno_style=request.form.get('suno_style', '').strip(),
|
suno_style=request.form.get('suno_style', '').strip(),
|
||||||
suno_lyrics=request.form.get('suno_lyrics', '').strip(),
|
suno_lyrics=request.form.get('suno_lyrics', '').strip(),
|
||||||
status='prompt_ready'
|
status='prompt_ready'
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ CREATE TABLE IF NOT EXISTS requests (
|
||||||
style_genre TEXT,
|
style_genre TEXT,
|
||||||
extra_requests TEXT,
|
extra_requests TEXT,
|
||||||
status TEXT DEFAULT 'pending',
|
status TEXT DEFAULT 'pending',
|
||||||
|
suno_title TEXT,
|
||||||
suno_style TEXT,
|
suno_style TEXT,
|
||||||
suno_lyrics TEXT,
|
suno_lyrics TEXT,
|
||||||
song_a_path TEXT,
|
song_a_path TEXT,
|
||||||
|
|
|
||||||
|
|
@ -53,25 +53,31 @@ pre{background:#111827;padding:.8rem;border-radius:.5rem;overflow:auto;white-spa
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h2>1. Generate Suno Prompt</h2>
|
<h2>1. Generate Suno Prompt</h2>
|
||||||
<button type="button" onclick="copyPromptForHermes()">Copy customer info for Hermes</button>
|
<button type="button" onclick="copyPromptForHermes()">Copy customer info for Hermes</button>
|
||||||
<p class="copy-hint">Paste the Style block and Lyrics block from Hermes into the boxes below, then click Apply.</p>
|
<p class="copy-hint">Paste Hermes response into the box below. It will auto-extract Title, Style, and Lyrics.</p>
|
||||||
|
|
||||||
<label for="pasted_style">Paste Style block here</label>
|
<label for="hermes_response">Paste Hermes response here</label>
|
||||||
<textarea id="pasted_style" rows="6" placeholder="Everything under 'Style:'"></textarea>
|
<textarea id="hermes_response" rows="14" placeholder="Title: ...\nStyle: ...\nLyrics: ..."></textarea>
|
||||||
|
|
||||||
<label for="pasted_lyrics">Paste Lyrics block here</label>
|
|
||||||
<textarea id="pasted_lyrics" rows="10" placeholder="Everything under 'Lyrics:'"></textarea>
|
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button type="button" class="secondary" onclick="applyPastedBlocks()">Apply to fields</button>
|
<button type="button" class="secondary" onclick="extractHermesResponse()">Extract Title / Style / Lyrics</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="POST">
|
<form method="POST">
|
||||||
<input type="hidden" name="action" value="save_prompt">
|
<input type="hidden" name="action" value="save_prompt">
|
||||||
|
|
||||||
|
<label for="suno_title">Suggested Title</label>
|
||||||
|
<input type="text" id="suno_title" name="suno_title" value="{{ req.suno_title or '' }}" readonly>
|
||||||
|
|
||||||
<label for="suno_style">Suno Style</label>
|
<label for="suno_style">Suno Style</label>
|
||||||
<textarea id="suno_style" name="suno_style">{{ req.suno_style or '' }}</textarea>
|
<textarea id="suno_style" name="suno_style">{{ req.suno_style or '' }}</textarea>
|
||||||
|
|
||||||
<label for="suno_lyrics">Suno Lyrics (with metatags)</label>
|
<label for="suno_lyrics">Suno Lyrics (with metatags)</label>
|
||||||
<textarea id="suno_lyrics" name="suno_lyrics" rows="12">{{ req.suno_lyrics or '' }}</textarea>
|
<textarea id="suno_lyrics" name="suno_lyrics" rows="12">{{ req.suno_lyrics or '' }}</textarea>
|
||||||
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
|
<button type="button" class="secondary" onclick="copyToClipboard('suno_title', 'Title')">Copy Title</button>
|
||||||
|
<button type="button" class="secondary" onclick="copyToClipboard('suno_style', 'Style')">Copy Style</button>
|
||||||
|
<button type="button" class="secondary" onclick="copyToClipboard('suno_lyrics', 'Lyrics')">Copy Lyrics</button>
|
||||||
<button type="submit">Save Prompt</button>
|
<button type="submit">Save Prompt</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
@ -127,24 +133,43 @@ function copyPromptForHermes() {
|
||||||
style_genre: {{ req.style_genre | tojson }},
|
style_genre: {{ req.style_genre | tojson }},
|
||||||
extra_requests: {{ req.extra_requests | tojson }}
|
extra_requests: {{ req.extra_requests | tojson }}
|
||||||
};
|
};
|
||||||
const text = `Please write a Suno Custom Mode prompt for this customer.\n\nCustomer data:\nName: ${data.name}\nHobbies: ${data.hobbies || '-'}\nNotable facts: ${data.notable_facts || '-'}\nStyle / genre: ${data.style_genre || '-'}\nExtra requests: ${data.extra_requests || '-'}\n\nReply with exactly this format (no JSON):\n\nStyle:\n[the style description here]\n\nLyrics:\n[the lyrics here, with metatags]`;
|
const text = `Please write a Suno Custom Mode prompt for this customer. Suggest a song title too.\n\nCustomer data:\nName: ${data.name}\nHobbies: ${data.hobbies || '-'}\nNotable facts: ${data.notable_facts || '-'}\nStyle / genre: ${data.style_genre || '-'}\nExtra requests: ${data.extra_requests || '-'}\n\nReply with exactly this format:\n\nTitle: [suggested title]\n\nStyle:\n[the style description here]\n\nLyrics:\n[the lyrics here, with metatags]`;
|
||||||
navigator.clipboard.writeText(text).then(() => alert("Copied! Paste Hermes response into the Style and Lyrics boxes, then click Apply."));
|
navigator.clipboard.writeText(text).then(() => alert("Copied! Paste Hermes response into the box above and click Extract."));
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyPastedBlocks() {
|
function extractHermesResponse() {
|
||||||
const styleBlock = document.getElementById('pasted_style').value.trim();
|
const raw = document.getElementById('hermes_response').value;
|
||||||
const lyricsBlock = document.getElementById('pasted_lyrics').value.trim();
|
if (!raw.trim()) {
|
||||||
if (!styleBlock && !lyricsBlock) {
|
alert("Paste Hermes response first.");
|
||||||
alert("Paste Style and/or Lyrics first.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (styleBlock) {
|
|
||||||
document.getElementById('suno_style').value = styleBlock;
|
const titleMatch = raw.match(/^[\s]*Title:\s*([\s\S]*?)(?=\n\s*Style:|\n\s*Lyrics:|$)/im);
|
||||||
|
const styleMatch = raw.match(/^[\s]*Style:\s*([\s\S]*?)(?=\n\s*Lyrics:|$)/im);
|
||||||
|
const lyricsMatch = raw.match(/^[\s]*Lyrics:\s*([\s\S]*?)$/im);
|
||||||
|
|
||||||
|
if (titleMatch) {
|
||||||
|
document.getElementById('suno_title').value = titleMatch[1].trim();
|
||||||
}
|
}
|
||||||
if (lyricsBlock) {
|
if (styleMatch) {
|
||||||
document.getElementById('suno_lyrics').value = lyricsBlock;
|
document.getElementById('suno_style').value = styleMatch[1].trim();
|
||||||
}
|
}
|
||||||
alert("Style and lyrics applied.");
|
if (lyricsMatch) {
|
||||||
|
document.getElementById('suno_lyrics').value = lyricsMatch[1].trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!styleMatch && !lyricsMatch) {
|
||||||
|
alert("Could not find Style or Lyrics sections. Make sure the response uses the exact format.");
|
||||||
|
} else {
|
||||||
|
alert("Title, Style, and Lyrics extracted. Use Copy buttons to paste into Suno.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyToClipboard(elementId, label) {
|
||||||
|
const el = document.getElementById(elementId);
|
||||||
|
el.select();
|
||||||
|
el.setSelectionRange(0, 99999);
|
||||||
|
navigator.clipboard.writeText(el.value).then(() => alert(label + " copied!"));
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Reference in a new issue