Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from transformers import pipeline
|
3 |
+
import pandas as pd
|
4 |
+
from typing import List, Dict
|
5 |
+
import json
|
6 |
+
import plotly.express as px
|
7 |
+
from datetime import datetime
|
8 |
+
|
9 |
+
# Initialize sentiment analysis pipeline
|
10 |
+
@st.cache_resource
|
11 |
+
def load_model():
|
12 |
+
return pipeline("sentiment-analysis")
|
13 |
+
|
14 |
+
class GraicieAnalyzer:
|
15 |
+
def __init__(self):
|
16 |
+
"""Initialize the analyzer"""
|
17 |
+
self.sentiment_pipeline = load_model()
|
18 |
+
|
19 |
+
def analyze_post(self, post_text: str) -> Dict:
|
20 |
+
"""Analyze a single post and return all metrics"""
|
21 |
+
# Get base sentiment
|
22 |
+
sentiment_result = self.sentiment_pipeline(post_text)[0]
|
23 |
+
|
24 |
+
# Determine style based on post characteristics
|
25 |
+
style = self._determine_style(post_text)
|
26 |
+
|
27 |
+
# Determine tone based on content
|
28 |
+
tones = self._determine_tone(post_text, sentiment_result)
|
29 |
+
|
30 |
+
# Calculate rating
|
31 |
+
rating = self._calculate_rating(post_text)
|
32 |
+
|
33 |
+
return {
|
34 |
+
"post": post_text,
|
35 |
+
"style": style,
|
36 |
+
"tones": tones,
|
37 |
+
"rating": rating,
|
38 |
+
"sentiment": sentiment_result["label"],
|
39 |
+
"confidence": f"{sentiment_result['score']:.2%}"
|
40 |
+
}
|
41 |
+
|
42 |
+
def _determine_style(self, text: str) -> str:
|
43 |
+
"""Determine post style based on characteristics"""
|
44 |
+
text_lower = text.lower()
|
45 |
+
|
46 |
+
if "!" in text or "?" in text or "π±" in text or "π€―" in text:
|
47 |
+
return "Hooking"
|
48 |
+
elif len(text.split()) <= 10:
|
49 |
+
return "Short & Sweet"
|
50 |
+
elif text.count('π') > 0 or text.count('π') > 0:
|
51 |
+
return "Audience-focused"
|
52 |
+
elif text.count('π') > 0 or "i feel" in text_lower or "just" in text_lower:
|
53 |
+
return "Authentic"
|
54 |
+
elif text.count('πΈ') > 0 or text.count('π') > 0:
|
55 |
+
return "Visually appealing"
|
56 |
+
elif "?" in text or "what do you think" in text_lower:
|
57 |
+
return "Controversial"
|
58 |
+
else:
|
59 |
+
return "Storytelling"
|
60 |
+
|
61 |
+
def _determine_tone(self, text: str, sentiment: Dict) -> List[str]:
|
62 |
+
"""Determine post tone"""
|
63 |
+
tones = []
|
64 |
+
text_lower = text.lower()
|
65 |
+
|
66 |
+
if sentiment["label"] == "POSITIVE":
|
67 |
+
tones.append("Optimistic")
|
68 |
+
else:
|
69 |
+
tones.append("Pessimistic")
|
70 |
+
|
71 |
+
if "?" in text:
|
72 |
+
tones.append("Curious")
|
73 |
+
if "!" in text:
|
74 |
+
tones.append("Assertive")
|
75 |
+
if any(word in text_lower for word in ["learn", "guide", "how to", "tips"]):
|
76 |
+
tones.append("Informative")
|
77 |
+
if any(emoji in text for emoji in ["π", "π", "π€£"]):
|
78 |
+
tones.append("Entertaining")
|
79 |
+
|
80 |
+
return tones
|
81 |
+
|
82 |
+
def _calculate_rating(self, text: str) -> int:
|
83 |
+
"""Calculate content rating"""
|
84 |
+
text_lower = text.lower()
|
85 |
+
# Simple rating system based on content markers
|
86 |
+
rating = 1 # Start with family-friendly
|
87 |
+
|
88 |
+
sensitive_words = ["damn", "hell", "stupid", "idiot"]
|
89 |
+
very_sensitive_words = ["fuck", "shit", "ass"]
|
90 |
+
adult_themes = ["drunk", "sex", "nsfw", "18+"]
|
91 |
+
|
92 |
+
if any(word in text_lower for word in sensitive_words):
|
93 |
+
rating = max(rating, 2)
|
94 |
+
if any(word in text_lower for word in very_sensitive_words):
|
95 |
+
rating = max(rating, 4)
|
96 |
+
if any(word in text_lower for word in adult_themes):
|
97 |
+
rating = max(rating, 5)
|
98 |
+
|
99 |
+
return rating
|
100 |
+
|
101 |
+
def main():
|
102 |
+
# Set page config
|
103 |
+
st.set_page_config(
|
104 |
+
page_title="Project Graicie - Social Media Content Analyzer",
|
105 |
+
page_icon="π±",
|
106 |
+
layout="wide"
|
107 |
+
)
|
108 |
+
|
109 |
+
# Title and description
|
110 |
+
st.title("π€ Project Graicie")
|
111 |
+
st.markdown("""
|
112 |
+
### AI-Powered Social Media Content Analysis
|
113 |
+
Analyze your social media content to understand its style, tone, and appropriateness.
|
114 |
+
Get insights to improve your social media presence!
|
115 |
+
""")
|
116 |
+
|
117 |
+
# Initialize analyzer
|
118 |
+
analyzer = GraicieAnalyzer()
|
119 |
+
|
120 |
+
# Create columns for better layout
|
121 |
+
col1, col2 = st.columns([2, 1])
|
122 |
+
|
123 |
+
with col1:
|
124 |
+
# Input area
|
125 |
+
st.subheader("π Content Analysis")
|
126 |
+
post_text = st.text_area(
|
127 |
+
"Enter your social media post here:",
|
128 |
+
height=150,
|
129 |
+
placeholder="Type or paste your post content here..."
|
130 |
+
)
|
131 |
+
|
132 |
+
if st.button("π Analyze Content", use_container_width=True):
|
133 |
+
if post_text:
|
134 |
+
with st.spinner("Analyzing your content..."):
|
135 |
+
# Get analysis
|
136 |
+
result = analyzer.analyze_post(post_text)
|
137 |
+
|
138 |
+
# Display results in an organized way
|
139 |
+
st.success("Analysis Complete!")
|
140 |
+
|
141 |
+
# Create three columns for results
|
142 |
+
res_col1, res_col2, res_col3 = st.columns(3)
|
143 |
+
|
144 |
+
with res_col1:
|
145 |
+
st.metric("Style", result["style"])
|
146 |
+
|
147 |
+
with res_col2:
|
148 |
+
st.metric("Sentiment", f"{result['sentiment']} ({result['confidence']})")
|
149 |
+
|
150 |
+
with res_col3:
|
151 |
+
st.metric("Content Rating", f"{result['rating']}/5")
|
152 |
+
|
153 |
+
# Show tones
|
154 |
+
st.subheader("π Detected Tones")
|
155 |
+
tone_html = " ".join([f'<span style="background-color: #e6f3ff; padding: 5px 10px; margin: 5px; border-radius: 15px;">{tone}</span>' for tone in result["tones"]])
|
156 |
+
st.markdown(f"<div style='margin-top: 10px;'>{tone_html}</div>", unsafe_allow_html=True)
|
157 |
+
|
158 |
+
else:
|
159 |
+
st.warning("Please enter some content to analyze!")
|
160 |
+
|
161 |
+
with col2:
|
162 |
+
# Tips and information
|
163 |
+
st.subheader("π‘ Tips")
|
164 |
+
st.info("""
|
165 |
+
**For better results:**
|
166 |
+
- Write naturally
|
167 |
+
- Include relevant emojis
|
168 |
+
- Add hashtags if relevant
|
169 |
+
- Keep your audience in mind
|
170 |
+
""")
|
171 |
+
|
172 |
+
# Rating guide
|
173 |
+
st.subheader("π Rating Guide")
|
174 |
+
st.markdown("""
|
175 |
+
1οΈβ£ Family-friendly
|
176 |
+
2οΈβ£ Minor concerns
|
177 |
+
3οΈβ£ Teen-appropriate
|
178 |
+
4οΈβ£ Mature content
|
179 |
+
5οΈβ£ Adult/Sensitive content
|
180 |
+
""")
|
181 |
+
|
182 |
+
if __name__ == "__main__":
|
183 |
+
main()
|