File size: 7,334 Bytes
70e7a93
517995a
14b368e
b0e4528
517995a
 
d2d5f1a
517995a
ebfbcbb
14b368e
15d4a5b
3c702d3
517995a
3c702d3
 
 
 
 
517995a
 
 
 
6bf7ce5
517995a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
708859f
ebfbcbb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
517995a
 
 
 
 
 
 
 
 
 
f855ccd
 
 
 
 
bef3485
517995a
bef3485
517995a
 
 
 
 
 
ebfbcbb
 
517995a
ebfbcbb
f855ccd
 
 
 
ebfbcbb
 
 
 
 
 
 
 
 
 
bef3485
 
ebfbcbb
 
 
 
bef3485
 
 
 
 
 
 
 
 
 
517995a
 
 
 
 
 
 
 
 
3c702d3
517995a
 
 
ef5c69d
517995a
3c702d3
 
 
 
517995a
 
 
 
 
ebfbcbb
517995a
 
 
 
 
 
bef3485
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import streamlit as st
import random
import os
import re
from groq import Groq
import base64

# Set your GROQ API Key
GROQ_API_KEY = os.getenv("GROQ_API_KEY", "your_groq_api_key_here")  # Replace with your actual key or set via environment
client = Groq(api_key=GROQ_API_KEY)

# Stickers for response - using more reliable CDN URLs
stickers = [
    "https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f60a.png",  # Smiling face
    "https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f31f.png",  # Glowing star
    "https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f338.png",  # Cherry blossom
    "https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/1f31c.png",  # Moon face
    "https://cdn.jsdelivr.net/gh/twitter/twemoji@14.0.2/assets/72x72/2728.png"   # Sparkles
]

# Streamlit UI setup
st.set_page_config(page_title="SkinSense AI", layout="centered")
st.markdown("<h1 style='text-align:center; color:#4CAF50;'>🌿 SkinSense AI – Skincare Buddy</h1>", unsafe_allow_html=True)

# Input form
name = st.text_input("Your Name")
gender = st.radio("Gender", ["Female", "Male", "Other"])
age = st.slider("Age", 12, 100, 25)
skin_concern = st.selectbox("Main Skin Concern", ["Acne", "Dryness", "Oiliness", "Pores", "Dullness", "Pigmentation", "Other"])
description = st.text_area("Describe Your Skin Problem", placeholder="e.g. Small white pimples under skin for 2 weeks...")
image = st.file_uploader("Or upload a picture of your skin", type=["jpg", "jpeg", "png"])
duration = st.selectbox("How long has this been a concern?", ["Less than 1 week", "1-2 weeks", "More than 2 weeks"])
sensitivity = st.radio("Is your skin sensitive?", ["Yes", "No", "Not Sure"])
routine = st.text_input("Do you follow a routine?", placeholder="e.g. Facewash, moisturizer, sunscreen")
submit = st.button("✨ Generate Skincare Advice")

# Core function
def skincare_advice(name, gender, age, skin_concern, description, duration, sensitivity, routine, image):
    if not name.strip():
        return "<span style='color:red;'>⚠ Please enter your name.</span>"

    sticker = random.choice(stickers)

    # Determine concern text
    if description.strip():
        concern_text = description.strip()
    elif image is not None:
        concern_text = "The user uploaded an image showing their skin issue. Please base your suggestions on typical visible skin concerns."
    else:
        concern_text = skin_concern

    # Prompt for the model
    prompt = f"""
    A user named {name} (Gender: {gender}, Age: {age}) is experiencing a skin issue: "{concern_text}".
    Duration: {duration}, Sensitive skin: {sensitivity}, Routine followed: {routine}.

    Write a response in sections using emojis and headings only for:
    🌟 Greeting
    🩺 Skin Issue Summary
    πŸ“Š Global Insight
    🧴 Daily Skincare Routine
    🌿 Natural Remedy
    πŸ’‘ Lifestyle Tips
    πŸ’¬ Motivational Quote

    Each section should start with a title (e.g., 🌿 Natural Remedy) on one line, then 2–4 lines of helpful content below it in plain text or bullet points.
    Do not use bold, underline, or any extra styling.
    """

    try:
        response = client.chat.completions.create(
            model="llama3-8b-8192",
            messages=[{"role": "user", "content": prompt}]
        )
        raw = response.choices[0].message.content
    except Exception as e:
        return f"<span style='color:red;'>❌ Error: {str(e)}</span>"

    # Clean the raw response first - remove any HTML tags that might be in the AI response
    import html
    raw = html.unescape(raw)  # Decode HTML entities
    raw = re.sub(r'<[^>]+>', '', raw)  # Remove any HTML tags
    
    # Format response using markdown and simple text formatting
    lines = raw.strip().split("\n")
    formatted_content = ""
    section_colors = {
        "🌟": "#E53935", "🩺": "#D81B60", "πŸ“Š": "#5E35B1",
        "🧴": "#F57C00", "🌿": "#43A047", "πŸ’‘": "#039BE5", "πŸ’¬": "#6D4C41"
    }

    for line in lines:
        stripped = line.strip()
        if not stripped:
            continue
        
        # Skip lines that look like HTML code or contain style attributes
        if '<' in stripped and ('style=' in stripped or '/>' in stripped or '</p>' in stripped):
            continue
            
        # Check if this line is a section header (starts with emoji and contains expected keywords)
        is_section_header = False
        for emoji in section_colors:
            if stripped.startswith(emoji):
                # Additional check to ensure it's actually a header and not content
                header_keywords = ["Greeting", "Skin Issue Summary", "Global Insight", "Daily Skincare Routine", 
                                 "Natural Remedy", "Lifestyle Tips", "Motivational Quote"]
                if any(keyword.lower() in stripped.lower() for keyword in header_keywords):
                    is_section_header = True
                    color = section_colors[emoji]
                    # Use HTML span for colored headers
                    formatted_content += f"<br><span style='color:{color}; font-weight:bold; font-size:18px;'>{stripped}</span><br>\n"
                    break
        
        # If not a section header, treat as regular content
        if not is_section_header:
            # Clean content and add as regular text
            clean_content = stripped.replace('<', '&lt;').replace('>', '&gt;')
            formatted_content += f"{clean_content}<br>\n"
    
    # Build the final response with proper HTML structure
    html_output = f"""
<div style='margin: 10px 0;'>
    {formatted_content}
</div>
"""

    # Embed uploaded image
    image_html = ""
    if image is not None:
        mime = image.type
        img_bytes = image.read()
        img_b64 = base64.b64encode(img_bytes).decode()
        image_html = f"<img src='data:{mime};base64,{img_b64}' style='max-width:100%; border-radius:12px; margin:15px 0;'>"

    # Final HTML layout with fallback for sticker
    final_html = f"""
<div style='font-family:Arial, sans-serif; color:#111; background:#fff; padding:20px;
            border-radius:12px; border:1px solid #ccc; box-shadow:0 2px 6px rgba(0,0,0,0.1);'>
    <div style='display:flex; align-items:center; justify-content:space-between; margin-bottom:20px;'>
        <h2 style='color:#000; margin:0;'>πŸ‘€ <b>{name}</b> | {gender}, {age} yrs</h2>
        <div style='width:70px; height:70px; border-radius:10px; background:linear-gradient(45deg, #ff6b6b, #4ecdc4); display:flex; align-items:center; justify-content:center; font-size:30px;'>
            <img src="{sticker}" style="width:60px; height:60px; border-radius:8px;" alt="✨" onerror="this.style.display='none'; this.nextSibling.style.display='block';">
            <span style="display:none; color:white;">✨</span>
        </div>
    </div>
    {image_html}
    {html_output}
</div>
"""

    return final_html

# Handle button press
if submit:
    with st.spinner("Generating advice..."):
        result = skincare_advice(name, gender, age, skin_concern, description, duration, sensitivity, routine, image)
        if result.startswith("<span style='color:red;'>"):
            st.markdown(result, unsafe_allow_html=True)
        else:
            st.markdown(result, unsafe_allow_html=True)