Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -24,6 +24,9 @@ from wordpress_xmlrpc import Client
|
|
24 |
from wordpress_xmlrpc.compat import xmlrpc_client
|
25 |
from wordpress_xmlrpc.methods import media
|
26 |
|
|
|
|
|
|
|
27 |
|
28 |
|
29 |
# Try to get API_URL from environment variables, if not found set to a default value
|
@@ -478,7 +481,7 @@ def generate_audio(genre, energy_level, tempo, description, duration):
|
|
478 |
# First, verify user is logged in and has permissions
|
479 |
if st.session_state.get("jwt_token") is None:
|
480 |
st.error("You must be logged in to generate audio.")
|
481 |
-
return
|
482 |
|
483 |
auth_headers = get_auth_headers()
|
484 |
|
@@ -487,7 +490,7 @@ def generate_audio(genre, energy_level, tempo, description, duration):
|
|
487 |
subscription_response = requests.get(subscription_url, headers=auth_headers)
|
488 |
if subscription_response.status_code != 200:
|
489 |
st.error("Failed to retrieve your subscription status.")
|
490 |
-
return
|
491 |
|
492 |
subscription_data = subscription_response.json()
|
493 |
|
@@ -528,7 +531,7 @@ def generate_audio(genre, energy_level, tempo, description, duration):
|
|
528 |
"Consider upgrading to premium for reliable, fast access.\n\n"
|
529 |
"π [Upgrade Now](https://songlabai.com/subscribe/)"
|
530 |
)
|
531 |
-
return
|
532 |
|
533 |
# Clear warmup messages
|
534 |
for placeholder in [status_placeholder, progress_placeholder, subscription_placeholder, stage_placeholder]:
|
@@ -545,11 +548,21 @@ def generate_audio(genre, energy_level, tempo, description, duration):
|
|
545 |
|
546 |
if response and response.status_code == 200:
|
547 |
st.success("β¨ Music generated successfully!")
|
548 |
-
load_and_play_generated_audio
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
549 |
|
550 |
# Update generation count
|
551 |
update_generation_url = "https://songlabai.com/wp-json/custom-api/v1/update-generation-count"
|
552 |
requests.post(update_generation_url, headers=auth_headers)
|
|
|
|
|
553 |
else:
|
554 |
st.error(
|
555 |
"β Failed to generate audio.\n\n"
|
@@ -557,8 +570,10 @@ def generate_audio(genre, energy_level, tempo, description, duration):
|
|
557 |
"π‘ **Tip:** Premium users experience fewer failures and faster generation times.\n\n"
|
558 |
"π [Upgrade Now](https://songlabai.com/subscribe/)"
|
559 |
)
|
|
|
560 |
except Exception as e:
|
561 |
st.error(f"An unexpected error occurred: {str(e)}")
|
|
|
562 |
|
563 |
def download_audio():
|
564 |
if st_state.audio_pydub is None:
|
@@ -576,6 +591,57 @@ def download_audio():
|
|
576 |
mime="audio/wav",
|
577 |
on_click=update_download_count
|
578 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
579 |
|
580 |
def update_download_count():
|
581 |
auth_headers = get_auth_headers()
|
@@ -586,8 +652,8 @@ def update_download_count():
|
|
586 |
return
|
587 |
|
588 |
|
589 |
-
def load_and_play_generated_audio(response):
|
590 |
-
import soundfile as sf
|
591 |
from io import BytesIO
|
592 |
|
593 |
response_eval = json.loads(response.content)
|
@@ -596,13 +662,11 @@ def load_and_play_generated_audio(response):
|
|
596 |
|
597 |
# Check if the audio is stereo or mono
|
598 |
if isinstance(generated_audio[0], list): # Stereo
|
599 |
-
# Transpose the list to get channels in columns
|
600 |
audio_array = np.array(generated_audio).T
|
601 |
else: # Mono
|
602 |
audio_array = np.array(generated_audio)
|
603 |
|
604 |
# Convert the float32 audio data to int16
|
605 |
-
# Assuming the audio data is in range [-1.0, 1.0], scale accordingly
|
606 |
max_val = np.max(np.abs(audio_array))
|
607 |
if max_val > 0:
|
608 |
audio_array = audio_array / max_val # Normalize to [-1.0, 1.0]
|
@@ -611,7 +675,7 @@ def load_and_play_generated_audio(response):
|
|
611 |
# Write the audio data to a BytesIO buffer using soundfile
|
612 |
audio_buffer = BytesIO()
|
613 |
sf.write(audio_buffer, int_audio, sample_rate, format='WAV', subtype='PCM_16')
|
614 |
-
audio_buffer.seek(0)
|
615 |
|
616 |
# Read the audio data into an AudioSegment
|
617 |
audio_segment = AudioSegment.from_file(audio_buffer, format="wav")
|
@@ -626,6 +690,27 @@ def load_and_play_generated_audio(response):
|
|
626 |
# Save the audio to WordPress and get perm_link and product_code
|
627 |
perm_link, product_code = save_to_wordpress(audio_array, sample_rate)
|
628 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
629 |
# Define col_btn and col_text
|
630 |
col_btn, col_text = st.columns([2, 4])
|
631 |
|
@@ -639,7 +724,6 @@ def load_and_play_generated_audio(response):
|
|
639 |
)
|
640 |
st.write(f"To download use the following product code: {product_code}")
|
641 |
|
642 |
-
|
643 |
if st.button("Generate Audio", key="generate_audio_button"):
|
644 |
if genre and energy_level and description and tempo:
|
645 |
if st.session_state.get("jwt_token") is None:
|
|
|
24 |
from wordpress_xmlrpc.compat import xmlrpc_client
|
25 |
from wordpress_xmlrpc.methods import media
|
26 |
|
27 |
+
import smtplib
|
28 |
+
from email.mime.text import MIMEText
|
29 |
+
from email.mime.multipart import MIMEMultipart
|
30 |
|
31 |
|
32 |
# Try to get API_URL from environment variables, if not found set to a default value
|
|
|
481 |
# First, verify user is logged in and has permissions
|
482 |
if st.session_state.get("jwt_token") is None:
|
483 |
st.error("You must be logged in to generate audio.")
|
484 |
+
return None
|
485 |
|
486 |
auth_headers = get_auth_headers()
|
487 |
|
|
|
490 |
subscription_response = requests.get(subscription_url, headers=auth_headers)
|
491 |
if subscription_response.status_code != 200:
|
492 |
st.error("Failed to retrieve your subscription status.")
|
493 |
+
return None
|
494 |
|
495 |
subscription_data = subscription_response.json()
|
496 |
|
|
|
531 |
"Consider upgrading to premium for reliable, fast access.\n\n"
|
532 |
"π [Upgrade Now](https://songlabai.com/subscribe/)"
|
533 |
)
|
534 |
+
return None
|
535 |
|
536 |
# Clear warmup messages
|
537 |
for placeholder in [status_placeholder, progress_placeholder, subscription_placeholder, stage_placeholder]:
|
|
|
548 |
|
549 |
if response and response.status_code == 200:
|
550 |
st.success("β¨ Music generated successfully!")
|
551 |
+
# Pass all parameters to load_and_play_generated_audio
|
552 |
+
load_and_play_generated_audio(
|
553 |
+
response=response,
|
554 |
+
genre=genre,
|
555 |
+
energy_level=energy_level,
|
556 |
+
tempo=tempo,
|
557 |
+
description=description,
|
558 |
+
duration=duration
|
559 |
+
)
|
560 |
|
561 |
# Update generation count
|
562 |
update_generation_url = "https://songlabai.com/wp-json/custom-api/v1/update-generation-count"
|
563 |
requests.post(update_generation_url, headers=auth_headers)
|
564 |
+
|
565 |
+
return response # Return the response for email notification
|
566 |
else:
|
567 |
st.error(
|
568 |
"β Failed to generate audio.\n\n"
|
|
|
570 |
"π‘ **Tip:** Premium users experience fewer failures and faster generation times.\n\n"
|
571 |
"π [Upgrade Now](https://songlabai.com/subscribe/)"
|
572 |
)
|
573 |
+
return None
|
574 |
except Exception as e:
|
575 |
st.error(f"An unexpected error occurred: {str(e)}")
|
576 |
+
return None
|
577 |
|
578 |
def download_audio():
|
579 |
if st_state.audio_pydub is None:
|
|
|
591 |
mime="audio/wav",
|
592 |
on_click=update_download_count
|
593 |
)
|
594 |
+
|
595 |
+
def notify_admin_of_generation(user_id, genre, energy_level, tempo, description, duration, perm_link, product_code):
|
596 |
+
"""
|
597 |
+
Send a notification email to [email protected] when a song is generated
|
598 |
+
"""
|
599 |
+
sender_email = "[email protected]" # Your email
|
600 |
+
sender_password = os.getenv("EMAIL_PASSWORD") # Store this in your environment variables
|
601 |
+
|
602 |
+
# Create the email
|
603 |
+
msg = MIMEMultipart()
|
604 |
+
msg["From"] = sender_email
|
605 |
+
msg["To"] = sender_email # Sending to yourself
|
606 |
+
msg["Subject"] = f"New Song Generated - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
|
607 |
+
|
608 |
+
# Create the email body with generation details
|
609 |
+
body = f"""
|
610 |
+
New Song Generation Details:
|
611 |
+
|
612 |
+
Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
|
613 |
+
User ID: {user_id}
|
614 |
+
|
615 |
+
Song Parameters:
|
616 |
+
- Genre: {genre}
|
617 |
+
- Energy Level: {energy_level}
|
618 |
+
- Tempo: {tempo}
|
619 |
+
- Duration: {duration} seconds
|
620 |
+
- Description: {description}
|
621 |
+
|
622 |
+
Links:
|
623 |
+
- Permanent Link: {perm_link}
|
624 |
+
- Product Code: {product_code}
|
625 |
+
|
626 |
+
--
|
627 |
+
Automated notification from SongLab AI
|
628 |
+
"""
|
629 |
+
|
630 |
+
msg.attach(MIMEText(body, "plain"))
|
631 |
+
|
632 |
+
try:
|
633 |
+
# Connect to your email server (update these settings based on your email provider)
|
634 |
+
server = smtplib.SMTP("smtp.gmail.com", 587) # Update with your SMTP server
|
635 |
+
server.starttls()
|
636 |
+
server.login(sender_email, sender_password)
|
637 |
+
|
638 |
+
# Send the email
|
639 |
+
server.send_message(msg)
|
640 |
+
server.quit()
|
641 |
+
|
642 |
+
print("β Admin notification email sent successfully")
|
643 |
+
except Exception as e:
|
644 |
+
print(f"Γ Failed to send admin notification email: {str(e)}")
|
645 |
|
646 |
def update_download_count():
|
647 |
auth_headers = get_auth_headers()
|
|
|
652 |
return
|
653 |
|
654 |
|
655 |
+
def load_and_play_generated_audio(response, genre=None, energy_level=None, tempo=None, description=None, duration=None):
|
656 |
+
import soundfile as sf
|
657 |
from io import BytesIO
|
658 |
|
659 |
response_eval = json.loads(response.content)
|
|
|
662 |
|
663 |
# Check if the audio is stereo or mono
|
664 |
if isinstance(generated_audio[0], list): # Stereo
|
|
|
665 |
audio_array = np.array(generated_audio).T
|
666 |
else: # Mono
|
667 |
audio_array = np.array(generated_audio)
|
668 |
|
669 |
# Convert the float32 audio data to int16
|
|
|
670 |
max_val = np.max(np.abs(audio_array))
|
671 |
if max_val > 0:
|
672 |
audio_array = audio_array / max_val # Normalize to [-1.0, 1.0]
|
|
|
675 |
# Write the audio data to a BytesIO buffer using soundfile
|
676 |
audio_buffer = BytesIO()
|
677 |
sf.write(audio_buffer, int_audio, sample_rate, format='WAV', subtype='PCM_16')
|
678 |
+
audio_buffer.seek(0)
|
679 |
|
680 |
# Read the audio data into an AudioSegment
|
681 |
audio_segment = AudioSegment.from_file(audio_buffer, format="wav")
|
|
|
690 |
# Save the audio to WordPress and get perm_link and product_code
|
691 |
perm_link, product_code = save_to_wordpress(audio_array, sample_rate)
|
692 |
|
693 |
+
# Get user ID from JWT token
|
694 |
+
user_id = None
|
695 |
+
if st.session_state.get("jwt_token"):
|
696 |
+
try:
|
697 |
+
decoded = jwt.decode(st.session_state["jwt_token"], options={"verify_signature": False})
|
698 |
+
user_id = decoded.get('user_id', 'Unknown')
|
699 |
+
except:
|
700 |
+
user_id = 'Unknown'
|
701 |
+
|
702 |
+
# Send email notification using the separate function
|
703 |
+
notify_admin_of_generation(
|
704 |
+
user_id=user_id,
|
705 |
+
genre=genre,
|
706 |
+
energy_level=energy_level,
|
707 |
+
tempo=tempo,
|
708 |
+
description=description,
|
709 |
+
duration=duration,
|
710 |
+
perm_link=perm_link,
|
711 |
+
product_code=product_code
|
712 |
+
)
|
713 |
+
|
714 |
# Define col_btn and col_text
|
715 |
col_btn, col_text = st.columns([2, 4])
|
716 |
|
|
|
724 |
)
|
725 |
st.write(f"To download use the following product code: {product_code}")
|
726 |
|
|
|
727 |
if st.button("Generate Audio", key="generate_audio_button"):
|
728 |
if genre and energy_level and description and tempo:
|
729 |
if st.session_state.get("jwt_token") is None:
|