velra-ai / frontend /shared.py
tarujain8's picture
Update frontend/shared.py
ccc3370 verified
Raw
History Blame Contribute Delete
10.4 kB
import re
import requests
API_URL = "/analyze"
MAX_FILES = 5
def parse_score_value(raw_score):
match = re.search(r"\d+(?:\.\d+)?", str(raw_score))
return float(match.group()) if match else None
def clean_text(value, fallback="Not available yet."):
text = str(value).strip() if value is not None else ""
return text if text else fallback
def clean_list(value):
if isinstance(value, list):
return [str(item).strip() for item in value if str(item).strip()]
if value is None:
return []
text = str(value).strip()
return [text] if text else []
def count_files(uploaded_files):
return len(uploaded_files) if uploaded_files else 0
def normalize_files(uploaded_files):
if not uploaded_files:
return []
return list(uploaded_files[:MAX_FILES])
def interest_to_percent(value):
text = str(value or "").lower()
mapping = {
"very high": 92,
"high": 82,
"medium": 58,
"mixed": 46,
"low": 28,
"very low": 14,
}
for key, score in mapping.items():
if key in text:
return score
return 50
def get_emotional_signal(score_value):
if score_value is None:
return "AI signal", "The emotional pattern is still forming."
if score_value >= 80:
return "Deep resonance", "The connection reads warm, mutual, and emotionally available."
if score_value >= 60:
return "Promising energy", "There is meaningful interest here, but clarity still matters."
if score_value >= 40:
return "Mixed signals", "The attraction may be real, but the emotional consistency is uneven."
return "Guarded connection", "Protect your energy and look for stronger reciprocity before investing more."
def analyze_payload(chat, feelings, uploaded_files, user_perspective="", emotional_goal="", conversation_consistency=""):
selected_files = normalize_files(uploaded_files)
files = [("files", (file.name, file, file.type)) for file in selected_files]
response = requests.post(
API_URL,
data={
"chat": chat,
"feelings": feelings,
"user_perspective": user_perspective,
"emotional_goal": emotional_goal,
"conversation_consistency": conversation_consistency
},
files=files,
timeout=180,
)
response.raise_for_status()
return response.json()
def detect_perspective_payload(chat, feelings, uploaded_files):
selected_files = normalize_files(uploaded_files)
files = [("files", (file.name, file, file.type)) for file in selected_files]
url = API_URL.replace("/analyze", "/detect_perspective")
response = requests.post(
url,
data={"chat": chat, "feelings": feelings},
files=files,
timeout=180,
)
response.raise_for_status()
return response.json()
def build_people_cards(analysis, feelings):
analyst = analysis.get("analyst", {})
psychology = analysis.get("psychology", {})
interest_level = clean_text(analyst.get("interest_level"), "Unclear")
emotional_tone = clean_text(analyst.get("emotional_tone"), "Unreadable")
partner_intent = clean_text(psychology.get("partner_intent"), "Unclear intent")
user_intent = clean_text(psychology.get("user_intent"), "Clarifying feelings")
feelings_text = f"{feelings} {user_intent}".lower()
partner_text = f"{interest_level} {emotional_tone} {partner_intent}".lower()
if any(word in feelings_text for word in ["break up", "breakup", "leave", "dont love", "don't love", "end it", "distance"]):
you = {
"label": "You",
"emoji": "\U0001F494",
"title": "Ready to step back",
"description": "Your side reads emotionally detached and focused on ending this respectfully.",
"percent": 90,
"meter_label": "Clarity",
}
elif any(word in feelings_text for word in ["confused", "unsure", "mixed", "idk"]):
you = {
"label": "You",
"emoji": "\U0001FAE7",
"title": "Still sorting feelings",
"description": "You sound uncertain and are looking for emotional clarity before acting.",
"percent": 58,
"meter_label": "Certainty",
}
else:
you = {
"label": "You",
"emoji": "\U0001FA77",
"title": clean_text(user_intent, "Emotionally engaged"),
"description": "Your side still sounds invested in understanding what this connection means.",
"percent": 72,
"meter_label": "Investment",
}
if any(word in partner_text for word in ["cold", "dry", "avoidant", "disinterest", "ignoring", "distance", "very low", "low"]):
partner = {
"label": "Them",
"emoji": "\U0001F9CA",
"title": "Emotionally cold",
"description": "Their side reads short, guarded, and low-effort rather than warm or reassuring.",
"percent": 24,
"meter_label": "Warmth",
}
elif any(word in partner_text for word in ["mixed", "unclear"]):
partner = {
"label": "Them",
"emoji": "\U0001F90D",
"title": "Mixed energy",
"description": "They are giving some signal, but not enough consistency to feel fully safe or clear.",
"percent": 48,
"meter_label": "Warmth",
}
else:
partner = {
"label": "Them",
"emoji": "\U0001F60D",
"title": clean_text(interest_level, "Interested"),
"description": "Their tone and effort look more emotionally open and invested.",
"percent": interest_to_percent(interest_level),
"meter_label": "Warmth",
}
return [you, partner]
def build_story_cards(analysis):
analyst = analysis.get("analyst", {})
psychology = analysis.get("psychology", {})
strategy = analysis.get("strategy", {})
cards = [
{
"emoji": "\U0001F50E",
"title": "Truth",
"body": clean_text(strategy.get("truth")),
"tone": "pink",
},
{
"emoji": "\u26A0\uFE0F",
"title": "Risk",
"body": clean_text(strategy.get("warning")),
"tone": "amber",
},
{
"emoji": "\U0001F9ED",
"title": "Best next move",
"body": clean_text(strategy.get("action_advice")),
"tone": "violet",
},
{
"emoji": "\U0001FAE0",
"title": "Hidden meaning",
"body": clean_text(analyst.get("hidden_meaning")),
"tone": "rose",
},
{
"emoji": "\U0001F9E0",
"title": "Psych dynamic",
"body": clean_text(psychology.get("psychological_dynamic")),
"tone": "indigo",
},
]
if strategy.get("detachment_path"):
cards.append({
"emoji": "\U0001F6E1\uFE0F",
"title": "Healthy Detachment",
"body": clean_text(strategy.get("detachment_path")),
"tone": "slate",
})
if strategy.get("reconnection_path"):
cards.append({
"emoji": "\U0001F504",
"title": "Reconnection Path",
"body": clean_text(strategy.get("reconnection_path")),
"tone": "rose",
})
for reply in clean_list(strategy.get("suggested_replies"))[:3]:
cards.append(
{
"emoji": "\U0001F4AC",
"title": "Suggested reply",
"body": reply,
"tone": "slate",
}
)
return cards
def build_key_insight_cards(analysis):
analyst = analysis.get("analyst", {})
strategy = analysis.get("strategy", {})
return [
{
"emoji": "\u26A0\uFE0F",
"title": "Risk",
"body": clean_text(strategy.get("warning")),
"tone": "amber",
},
{
"emoji": "\U0001FAE0",
"title": "Hidden meaning",
"body": clean_text(analyst.get("hidden_meaning")),
"tone": "rose",
},
{
"emoji": "\U0001F9ED",
"title": "Best next step",
"body": clean_text(strategy.get("action_advice")),
"tone": "violet",
},
]
def default_swipe_profiles():
return [
{
"name": "Aarav",
"age": 26,
"bio": "Warm texter, quick replies, values direct communication and emotional consistency.",
"compatibility": 72,
"emotional_availability": "Open but cautious",
"red_flags": "Can pull back if conversations become unclear.",
"communication_style": "Clear, affectionate, reassurance-seeking",
"theme": "rose",
"emoji": "\U0001F60A",
},
{
"name": "Maya",
"age": 24,
"bio": "Playful energy, strong chemistry, but can be inconsistent when overwhelmed.",
"compatibility": 64,
"emotional_availability": "Mixed signals",
"red_flags": "Hot-cold rhythm and unclear follow-through.",
"communication_style": "Flirty, reactive, emotionally uneven",
"theme": "violet",
"emoji": "\U0001F970",
},
{
"name": "Rehan",
"age": 28,
"bio": "Slow-burn type, thoughtful in person, not always expressive over text.",
"compatibility": 58,
"emotional_availability": "Steady but reserved",
"red_flags": "Can feel distant if you need frequent reassurance.",
"communication_style": "Measured, calm, low-drama",
"theme": "amber",
"emoji": "\U0001F60C",
},
{
"name": "Kiara",
"age": 25,
"bio": "High chemistry, sharp intuition, but protects herself with emotional distance.",
"compatibility": 49,
"emotional_availability": "Guarded",
"red_flags": "Avoids clarity when things get serious.",
"communication_style": "Stylish, witty, emotionally hard to read",
"theme": "indigo",
"emoji": "\U0001F9CA",
},
]