add admin page to manage private data
This commit is contained in:
123
webpages/adminpages/helloween_image.py
Normal file
123
webpages/adminpages/helloween_image.py
Normal file
@@ -0,0 +1,123 @@
|
||||
import streamlit as st
|
||||
from PIL import Image
|
||||
from google import genai
|
||||
import json
|
||||
from io import BytesIO
|
||||
from .email_helloween_image import send_email_with_attachment
|
||||
|
||||
|
||||
def camera_photo():
|
||||
st.markdown("<h1 style='text-align: center; color: #451002;'>🎃 Halloween Photo Booth 📸</h1>", unsafe_allow_html=True)
|
||||
st.markdown("<h5 style='text-align: center;'> Capture your Halloween spirit with a festive photo! 👻 </h3>", unsafe_allow_html=True)
|
||||
|
||||
if 'image_response' not in st.session_state:
|
||||
st.session_state.image_response = None
|
||||
|
||||
enable_camera = st.checkbox("Enable Camera")
|
||||
if enable_camera:
|
||||
st.info("📎Note: No photos are stored. The image is processed in-memory and deleted after refresh app.")
|
||||
picture = st.camera_input("Take a Halloween-themed photo! 🎃👻🕸️")
|
||||
|
||||
if picture is not None:
|
||||
image = Image.open(picture)
|
||||
|
||||
keep_dressing_style = st.checkbox("Keep original dressing style", value=False)
|
||||
keep_body_pose = st.checkbox("Keep original body pose", value=False)
|
||||
|
||||
theme = st.selectbox(
|
||||
"Select or Input a Halloween theme for your photo:",
|
||||
[ "🎃 Classic Halloween",
|
||||
"👻 Haunted House",
|
||||
"⚗️ Science Experiment Gone Wrong",
|
||||
"🎥 Horror Film Inspired",
|
||||
"🕯️ Gothic",
|
||||
"🧙♂️ Harry Potter",
|
||||
"⚰️ Graveyard",
|
||||
"🔮 Cult Horror Theme"
|
||||
],
|
||||
index=0,
|
||||
key="theme_selector"
|
||||
)
|
||||
|
||||
if st.button("AI Editing"):
|
||||
edit_prompt = f"""
|
||||
Retain original facial features (eyes, nose, mouth etc.) of any persons in the photo. The goal is to achieve a realistic, edited look, not an AI-generated or overly smoothed/perfected appearance. Avoid any artificial alterations to these features.
|
||||
Keep the original dressing style: {str(keep_dressing_style)}
|
||||
Keep the original body pose: {str(keep_body_pose)}
|
||||
Theme: {theme}
|
||||
If a person is already in costume, enhance the costume and add more Halloween elements and background to the scene.
|
||||
If multiple persons are present, ensure all are included in the Halloween theme.
|
||||
- Overall Style: The final image should be photorealistic.
|
||||
Ensure the final image is vibrant, festive, and captures the Halloween spirit!
|
||||
"""
|
||||
with st.spinner("Editing image..."):
|
||||
text_response, image_response = edit_image_with_ai(image, edit_prompt)
|
||||
if text_response:
|
||||
st.info(text_response)
|
||||
if image_response:
|
||||
st.session_state.image_response = image_response
|
||||
# Rerun to display the generated image and send options
|
||||
st.rerun()
|
||||
|
||||
if st.session_state.image_response:
|
||||
st.image(st.session_state.image_response)
|
||||
# Convert PIL image to bytes for download
|
||||
img_byte_arr = BytesIO()
|
||||
st.session_state.image_response.save(img_byte_arr, format="JPEG")
|
||||
st.download_button(
|
||||
label="Download Edited Image",
|
||||
data=img_byte_arr.getvalue(),
|
||||
file_name="edited_image.jpeg",
|
||||
mime="image/jpeg"
|
||||
)
|
||||
send_image(st.session_state.image_response)
|
||||
|
||||
def send_image(image_response):
|
||||
st.divider()
|
||||
to_email = st.text_input("Enter your email to receive the photo:", key="email_input")
|
||||
if st.button("Send Email"):
|
||||
with st.spinner("Sending email..."):
|
||||
if to_email and image_response:
|
||||
with open('app_config.json') as config_file:
|
||||
config = json.load(config_file)
|
||||
sender_email = config["send_email"]["sender_email"]
|
||||
password = config["send_email"]["password"]
|
||||
subject = "Your Spooktacular Halloween Photo! 🎃👻"
|
||||
send_email_with_attachment(sender_email, password, to_email, subject, image_response)
|
||||
st.success("Email sent successfully!")
|
||||
else:
|
||||
st.error("Please enter a valid email address and ensure the image is generated.")
|
||||
|
||||
|
||||
|
||||
|
||||
def edit_image_with_ai(image, description):
|
||||
with open('app_config.json') as config_file:
|
||||
config = json.load(config_file)
|
||||
api_key = config["nano-banana"]["api_key"]
|
||||
|
||||
client = genai.Client(api_key=api_key)
|
||||
|
||||
prompt = description
|
||||
|
||||
response = client.models.generate_content(
|
||||
model="gemini-2.5-flash-image-preview",
|
||||
contents=[prompt, image],
|
||||
)
|
||||
|
||||
text_response = None
|
||||
image_response = None
|
||||
|
||||
# AttributeError: 'NoneType' object has no attribute 'parts'
|
||||
if response.candidates and len(response.candidates) <= 0:
|
||||
st.error("No response from AI model. Please try again.")
|
||||
return text_response, image_response
|
||||
|
||||
for part in response.candidates[0].content.parts:
|
||||
if part.text is not None:
|
||||
text_response = part.text
|
||||
|
||||
if part.inline_data is not None:
|
||||
image_response = Image.open(BytesIO(part.inline_data.data))
|
||||
|
||||
return text_response, image_response
|
||||
Reference in New Issue
Block a user