RafaM97 commited on
Commit
347d9a6
·
verified ·
1 Parent(s): 41242f7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +496 -304
app.py CHANGED
@@ -1,304 +1,496 @@
1
- import streamlit as st
2
- from datetime import datetime, timedelta
3
- import requests
4
- import base64
5
- from reportlab.lib.pagesizes import letter
6
- from reportlab.pdfgen import canvas
7
- from io import BytesIO
8
- from PIL import Image
9
- from reportlab.lib.pagesizes import letter
10
- from reportlab.pdfgen import canvas
11
- from reportlab.lib.units import inch
12
- from reportlab.platypus import SimpleDocTemplate, Paragraph
13
- from reportlab.lib.styles import getSampleStyleSheet
14
- from io import BytesIO
15
-
16
-
17
- from peft import PeftModel, PeftConfig
18
- from transformers import AutoModelForCausalLM
19
-
20
- config = PeftConfig.from_pretrained("RafaM97/Compass_Model")
21
- base_model = AutoModelForCausalLM.from_pretrained("unsloth/meta-llama-3.1-8b-bnb-4bit")
22
- model = PeftModel.from_pretrained(base_model, "RafaM97/Compass_Model")
23
-
24
- def create_pdf(content):
25
- buffer = BytesIO()
26
- doc = SimpleDocTemplate(buffer, pagesize=letter,
27
- rightMargin=72, leftMargin=72,
28
- topMargin=72, bottomMargin=18)
29
-
30
- styles = getSampleStyleSheet()
31
- style = styles["Normal"]
32
-
33
- story = []
34
-
35
- # Split content into paragraphs
36
- paragraphs = content.split('\n\n')
37
- for para in paragraphs:
38
- p = Paragraph(para, style)
39
- story.append(p)
40
-
41
- doc.build(story)
42
- buffer.seek(0)
43
- return buffer
44
-
45
- import streamlit as st
46
- from PIL import Image, ImageOps
47
- import io
48
-
49
- def remove_background(image):
50
- # Convert the logo to RGBA mode to handle transparency
51
- image = image.convert('RGBA')
52
-
53
- # Get the image data
54
- datas = image.getdata()
55
- new_data = []
56
-
57
- # Iterate through each pixel and check if it's dark enough to be background
58
- for item in datas:
59
- if item[0] < 50 and item[1] < 50 and item[2] < 50: # Dark pixels
60
- new_data.append((255, 255, 255, 0)) # Make it transparent
61
- else:
62
- new_data.append(item)
63
-
64
- # Update the image data
65
- image.putdata(new_data)
66
- return image
67
-
68
- def main():
69
- # Load the logo
70
- logo = Image.open("Compassai.png")
71
-
72
- # Remove background from logo
73
- logo = remove_background(logo)
74
-
75
-
76
-
77
- # Convert the image to bytes
78
- img_byte_arr = io.BytesIO()
79
- logo.save(img_byte_arr, format='PNG')
80
- img_byte_arr = img_byte_arr.getvalue()
81
-
82
- # Set page config with the logo as favicon
83
- st.set_page_config(
84
- page_title="Compass AI",
85
- page_icon=img_byte_arr,
86
- layout="centered" # Adjusted for center alignment
87
- )
88
-
89
- # Custom CSS to style the banner
90
- st.markdown("""
91
- <style>
92
- .banner-container {
93
- width: 100%; /* Make it span the entire width */
94
- display: flex;
95
- justify-content: center;
96
- align-items: center;
97
- padding: 5px 0;
98
- }
99
- .banner-container img {
100
- width: 100%; /* Banner stretches across the page */
101
- height: auto;
102
- }
103
- </style>
104
- """, unsafe_allow_html=True)
105
-
106
- # Display the banner at the top of the app
107
- st.markdown('<div class="banner-container">', unsafe_allow_html=True)
108
- st.image(logo, use_column_width=True)
109
- st.markdown('</div>', unsafe_allow_html=True)
110
-
111
- # Sidebar for navigation
112
- page = st.sidebar.selectbox("Choose a page", ["Home", "Campaign Creation", "Strategy", "Scheduling", "Analytics"])
113
-
114
- # Handle page selection
115
- if page == "Home":
116
- show_home()
117
- elif page == "Campaign Creation":
118
- show_campaign_creation()
119
- elif page == "Strategy":
120
- show_strategy()
121
- elif page == "Scheduling":
122
- show_scheduling()
123
- elif page == "Analytics":
124
- show_analytics()
125
-
126
-
127
-
128
-
129
- def show_home():
130
- st.markdown("""
131
- <style>
132
- .big-font {
133
- font-size:50px !important;
134
- font-weight: bold;
135
- color: #1E90FF;
136
- text-align: center;
137
- margin-bottom: 20px;
138
- }
139
- .sub-font {
140
- font-size:25px !important;
141
- color: #4682B4;
142
- text-align: center;
143
- margin-bottom: 30px;
144
- }
145
- .feature-font {
146
- font-size:30px !important;
147
- color: #4169E1;
148
- text-align: center;
149
- margin-bottom: 30px;
150
- }
151
- .feature-card {
152
- background-color: #F0F8FF;
153
- border-radius: 10px;
154
- padding: 20px;
155
- margin-bottom: 20px;
156
- border: 2px solid #1E90FF;
157
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
158
- }
159
- .feature-title {
160
- font-size: 24px !important;
161
- font-weight: bold;
162
- color: #1E90FF;
163
- margin-bottom: 10px;
164
- }
165
- .feature-list {
166
- color: #333;
167
- font-size: 16px !important;
168
- }
169
- </style>
170
- """, unsafe_allow_html=True)
171
-
172
- st.markdown('<p class="big-font">Welcome to AI Marketing Campaign Agent</p>', unsafe_allow_html=True)
173
- st.markdown('<p class="sub-font">Your intelligent assistant for creating, managing, and analyzing marketing campaigns</p>', unsafe_allow_html=True)
174
-
175
- st.markdown('<p class="feature-font">🚀 Key Features</p>', unsafe_allow_html=True)
176
-
177
- col1, col2 = st.columns(2)
178
-
179
- with col1:
180
- st.markdown('''
181
- <div class="feature-card">
182
- <p class="feature-title">Campaign Creation</p>
183
- <ul class="feature-list">
184
- <li>AI-powered content generation</li>
185
- <li>Customized for your brand</li>
186
- <li>Multiple content types</li>
187
- </ul>
188
- </div>
189
- ''', unsafe_allow_html=True)
190
-
191
- st.markdown('''
192
- <div class="feature-card">
193
- <p class="feature-title">Strategy Planning</p>
194
- <ul class="feature-list">
195
- <li>Comprehensive marketing strategies</li>
196
- <li>Day-by-day breakdown</li>
197
- <li>Tailored to your objectives</li>
198
- </ul>
199
- </div>
200
- ''', unsafe_allow_html=True)
201
-
202
- with col2:
203
- st.markdown('''
204
- <div class="feature-card">
205
- <p class="feature-title">Content Scheduling</p>
206
- <ul class="feature-list">
207
- <li>Multi-platform scheduling</li>
208
- <li>Optimize posting times</li>
209
- <li>Manage your content calendar</li>
210
- </ul>
211
- </div>
212
- ''', unsafe_allow_html=True)
213
-
214
- st.markdown('''
215
- <div class="feature-card">
216
- <p class="feature-title">Analytics (Coming Soon)</p>
217
- <ul class="feature-list">
218
- <li>Track campaign performance</li>
219
- <li>Gain actionable insights</li>
220
- <li>Improve your marketing ROI</li>
221
- </ul>
222
- </div>
223
- ''', unsafe_allow_html=True)
224
-
225
- st.markdown('<p class="sub-font">Get started by selecting a feature from the sidebar!</p>', unsafe_allow_html=True)
226
-
227
-
228
- def show_campaign_creation():
229
- st.header("Campaign Creation")
230
-
231
- # Brand Questionnaire
232
- st.subheader("Brand Questionnaire")
233
- brand_name = st.text_input("Brand Name")
234
- industry = st.selectbox("Industry", ["Technology", "Fashion", "Food & Beverage", "Other"])
235
- target_audience = st.text_area("Describe your target audience")
236
- campaign_objective = st.selectbox("Campaign Objective", ["Brand Awareness", "Lead Generation", "Sales", "Other"])
237
-
238
- # Content Generation
239
- st.subheader("Content Generation")
240
- content_type = st.selectbox("Content Type", ["Social Media Post", "Ad Copy", "Email"])
241
- content_prompt = st.text_area("Describe the content you want to generate")
242
-
243
- if st.button("Generate Content"):
244
- instruction = f"Create a single {content_type} for a {industry} company, focusing on {campaign_objective}"
245
- input_context = f"Brand: {brand_name}, Target Audience: {target_audience}, Objective: {campaign_objective}, Content Details: {content_prompt}"
246
-
247
- with st.spinner("Generating content..."):
248
- generated_content = generate_marketing_content(instruction, input_context)
249
-
250
- st.markdown(generated_content)
251
-
252
- # Download as PDF
253
- pdf = create_pdf(generated_content)
254
- st.download_button(
255
- label="Download Generated Content as PDF",
256
- data=pdf,
257
- file_name="generated_content.pdf",
258
- mime="application/pdf"
259
- )
260
-
261
- def show_strategy():
262
- st.header("Marketing Strategy")
263
-
264
- start_date = st.date_input("Campaign Start Date")
265
- duration = st.number_input("Campaign Duration (days)", min_value=1, value=30)
266
-
267
- if st.button("Generate Strategy"):
268
- instruction = f"Generate a day-by-day marketing strategy for {duration} days"
269
- input_context = f"Start Date: {start_date}, Duration: {duration} days"
270
-
271
- with st.spinner("Generating strategy..."):
272
- strategy = generate_marketing_content(instruction, input_context, is_strategy=True)
273
-
274
- st.subheader("Generated Marketing Strategy")
275
- st.markdown(strategy)
276
-
277
- # Download as PDF
278
- pdf = create_pdf(strategy)
279
- st.download_button(
280
- label="Download Marketing Strategy as PDF",
281
- data=pdf,
282
- file_name="marketing_strategy.pdf",
283
- mime="application/pdf"
284
- )
285
-
286
- def show_scheduling():
287
- st.header("Content Scheduling")
288
-
289
- platforms = st.multiselect("Select Platforms", ["Facebook", "Instagram", "Twitter"])
290
- post_content = st.text_area("Post Content")
291
- post_date = st.date_input("Post Date")
292
- post_time = st.time_input("Post Time")
293
-
294
- if st.button("Schedule Post"):
295
- scheduled_datetime = datetime.combine(post_date, post_time)
296
- for platform in platforms:
297
- st.success(f"Post scheduled for {platform} at {scheduled_datetime}")
298
-
299
- def show_analytics():
300
- st.header("Campaign Analytics")
301
- st.write("This feature is under development. It will show campaign performance metrics and insights.")
302
-
303
- if __name__ == "__main__":
304
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from datetime import datetime, timedelta
3
+ import requests
4
+ import json
5
+ import uuid
6
+ import os
7
+ from io import BytesIO
8
+ from PIL import Image
9
+ from reportlab.lib.pagesizes import letter
10
+ from reportlab.lib.units import inch
11
+ from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
12
+ from reportlab.lib.enums import TA_CENTER
13
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
14
+
15
+ # Groq API configuration
16
+ GROQ_API_KEY = st.secrets["API_KEY"]
17
+
18
+ GROQ_API_URL = "https://api.groq.com/openai/v1/chat/completions"
19
+ # Error handling decorator
20
+ def handle_errors(func):
21
+ def wrapper(*args, **kwargs):
22
+ try:
23
+ return func(*args, **kwargs)
24
+ except Exception as e:
25
+ st.error(f"An error occurred: {str(e)}")
26
+ return None
27
+ return wrapper
28
+
29
+ @handle_errors
30
+ def generate_marketing_content(instruction, input_context, is_strategy=False):
31
+ headers = {
32
+ "Authorization": f"Bearer {GROQ_API_KEY}",
33
+ "Content-Type": "application/json"
34
+ }
35
+
36
+ system_message = "You are a helpful AI assistant specializing in marketing and content creation."
37
+ if is_strategy:
38
+ system_message += " For strategy, provide a unique day-by-day breakdown tailored to the specific input."
39
+ else:
40
+ system_message += " For content, focus on creating a single cohesive piece without day-by-day breakdown."
41
+
42
+ system_message += " Avoid generating any external links or off-topic content."
43
+
44
+ data = {
45
+ "model": "llama3-8b-8192",
46
+ "messages": [
47
+ {"role": "system", "content": system_message},
48
+ {"role": "user", "content": f"Instruction: {instruction}\nInput: {input_context}\nPlease format your response in markdown, excluding any links."}
49
+ ],
50
+ "max_tokens": 1000,
51
+ "temperature": 0.7 # Adjust this value to increase randomness and uniqueness
52
+ }
53
+
54
+ response = requests.post(GROQ_API_URL, headers=headers, json=data)
55
+
56
+ if response.status_code == 200:
57
+ return response.json()['choices'][0]['message']['content']
58
+ else:
59
+ raise Exception(f"Unable to generate content. Status code: {response.status_code}")
60
+
61
+
62
+ def create_pdf(content):
63
+ buffer = BytesIO()
64
+ doc = SimpleDocTemplate(buffer, pagesize=letter,
65
+ rightMargin=inch, leftMargin=inch,
66
+ topMargin=inch, bottomMargin=inch)
67
+
68
+ styles = getSampleStyleSheet()
69
+
70
+ # Create custom styles
71
+ title_style = ParagraphStyle(
72
+ 'TitleStyle',
73
+ parent=styles['Heading1'],
74
+ fontSize=18,
75
+ alignment=TA_CENTER,
76
+ spaceAfter=12
77
+ )
78
+
79
+ heading_style = ParagraphStyle(
80
+ 'HeadingStyle',
81
+ parent=styles['Heading2'],
82
+ fontSize=14,
83
+ spaceBefore=12,
84
+ spaceAfter=6
85
+ )
86
+
87
+ normal_style = ParagraphStyle(
88
+ 'NormalStyle',
89
+ parent=styles['Normal'],
90
+ fontSize=11,
91
+ spaceBefore=6,
92
+ spaceAfter=6
93
+ )
94
+
95
+ story = []
96
+
97
+ # Split content into paragraphs
98
+ paragraphs = content.split('\n\n')
99
+
100
+ # Process paragraphs and apply appropriate styling
101
+ for i, para in enumerate(paragraphs):
102
+ if i == 0: # First paragraph as title
103
+ p = Paragraph(para, title_style)
104
+ elif para.startswith('#'): # Headings
105
+ level = para.count('#')
106
+ text = para.lstrip('#').strip()
107
+ if level == 2:
108
+ p = Paragraph(text, heading_style)
109
+ else:
110
+ p = Paragraph(text, normal_style)
111
+ else: # Normal paragraphs
112
+ p = Paragraph(para, normal_style)
113
+
114
+ story.append(p)
115
+ story.append(Spacer(1, 6)) # Add space between paragraphs
116
+
117
+ doc.build(story)
118
+ buffer.seek(0)
119
+ return buffer
120
+
121
+
122
+ import streamlit as st
123
+ from PIL import Image, ImageOps
124
+ import io
125
+
126
+ def remove_background(image):
127
+ # Convert the logo to RGBA mode to handle transparency
128
+ image = image.convert('RGBA')
129
+
130
+ # Get the image data
131
+ datas = image.getdata()
132
+ new_data = []
133
+
134
+ # Iterate through each pixel and check if it's dark enough to be background
135
+ for item in datas:
136
+ if item[0] < 50 and item[1] < 50 and item[2] < 50: # Dark pixels
137
+ new_data.append((255, 255, 255, 0)) # Make it transparent
138
+ else:
139
+ new_data.append(item)
140
+
141
+ # Update the image data
142
+ image.putdata(new_data)
143
+ return image
144
+
145
+ def main():
146
+ # Load the logo
147
+ logo = Image.open("Compassai.png")
148
+
149
+ # Remove background from logo
150
+ logo = remove_background(logo)
151
+
152
+
153
+
154
+ # Convert the image to bytes
155
+ img_byte_arr = io.BytesIO()
156
+ logo.save(img_byte_arr, format='PNG')
157
+ img_byte_arr = img_byte_arr.getvalue()
158
+
159
+ # Set page config with the logo as favicon
160
+ st.set_page_config(
161
+ page_title="Compass AI",
162
+ page_icon=img_byte_arr,
163
+ layout="centered" # Adjusted for center alignment
164
+ )
165
+
166
+ # Custom CSS to style the banner
167
+ st.markdown("""
168
+ <style>
169
+ .banner-container {
170
+ width: 100%; /* Make it span the entire width */
171
+ display: flex;
172
+ justify-content: center;
173
+ align-items: center;
174
+ padding: 10px 0;
175
+ }
176
+ .banner-container img {
177
+ width: 100%; /* Banner stretches across the page */
178
+ height: auto;
179
+ }
180
+ </style>
181
+ """, unsafe_allow_html=True)
182
+
183
+ # Display the banner at the top of the app
184
+ st.markdown('<div class="banner-container">', unsafe_allow_html=True)
185
+ st.image(logo, use_column_width=True)
186
+ st.markdown('</div>', unsafe_allow_html=True)
187
+
188
+ # Sidebar for navigation
189
+ page = st.sidebar.selectbox("Choose a page", ["Home", "Post Creation", "Marketing Strategy", "Scheduling", "Analytics"])
190
+
191
+ # Handle page selection
192
+ if page == "Home":
193
+ show_home()
194
+ elif page == "Post Creation":
195
+ show_post_creation()
196
+ elif page == "Marketing Strategy":
197
+ show_marketing_strategy()
198
+ elif page == "Scheduling":
199
+ show_scheduling()
200
+ elif page == "Analytics":
201
+ show_analytics()
202
+
203
+
204
+
205
+
206
+ def show_home():
207
+ st.markdown("""
208
+ <style>
209
+ .big-font {
210
+ font-size:50px !important;
211
+ font-weight: bold;
212
+ color: #1E90FF;
213
+ text-align: center;
214
+ margin-bottom: 20px;
215
+ }
216
+ .sub-font {
217
+ font-size:25px !important;
218
+ color: #4682B4;
219
+ text-align: center;
220
+ margin-bottom: 30px;
221
+ }
222
+ .feature-font {
223
+ font-size:30px !important;
224
+ color: #4169E1;
225
+ text-align: center;
226
+ margin-bottom: 30px;
227
+ }
228
+ .feature-card {
229
+ background-color: #F0F8FF;
230
+ border-radius: 10px;
231
+ padding: 20px;
232
+ margin-bottom: 20px;
233
+ border: 2px solid #1E90FF;
234
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
235
+ }
236
+ .feature-title {
237
+ font-size: 24px !important;
238
+ font-weight: bold;
239
+ color: #1E90FF;
240
+ margin-bottom: 10px;
241
+ }
242
+ .feature-list {
243
+ color: #333;
244
+ font-size: 16px !important;
245
+ }
246
+ </style>
247
+ """, unsafe_allow_html=True)
248
+
249
+ st.markdown('<p class="big-font">Welcome to AI Marketing Campaign Agent</p>', unsafe_allow_html=True)
250
+ st.markdown('<p class="sub-font">Your intelligent assistant for creating, managing, and analyzing marketing campaigns</p>', unsafe_allow_html=True)
251
+
252
+ st.markdown('<p class="feature-font">🚀 Key Features</p>', unsafe_allow_html=True)
253
+
254
+ col1, col2 = st.columns(2)
255
+
256
+ with col1:
257
+ st.markdown('''
258
+ <div class="feature-card">
259
+ <p class="feature-title">Campaign Creation</p>
260
+ <ul class="feature-list">
261
+ <li>AI-powered content generation</li>
262
+ <li>Customized for your brand</li>
263
+ <li>Multiple content types</li>
264
+ </ul>
265
+ </div>
266
+ ''', unsafe_allow_html=True)
267
+
268
+ st.markdown('''
269
+ <div class="feature-card">
270
+ <p class="feature-title">Strategy Planning</p>
271
+ <ul class="feature-list">
272
+ <li>Comprehensive marketing strategies</li>
273
+ <li>Day-by-day breakdown</li>
274
+ <li>Tailored to your objectives</li>
275
+ </ul>
276
+ </div>
277
+ ''', unsafe_allow_html=True)
278
+
279
+ with col2:
280
+ st.markdown('''
281
+ <div class="feature-card">
282
+ <p class="feature-title">Content Scheduling</p>
283
+ <ul class="feature-list">
284
+ <li>Multi-platform scheduling</li>
285
+ <li>Optimize posting times</li>
286
+ <li>Manage your content calendar</li>
287
+ </ul>
288
+ </div>
289
+ ''', unsafe_allow_html=True)
290
+
291
+ st.markdown('''
292
+ <div class="feature-card">
293
+ <p class="feature-title">Analytics (Coming Soon)</p>
294
+ <ul class="feature-list">
295
+ <li>Track campaign performance</li>
296
+ <li>Gain actionable insights</li>
297
+ <li>Improve your marketing ROI</li>
298
+ </ul>
299
+ </div>
300
+ ''', unsafe_allow_html=True)
301
+
302
+ st.markdown('<p class="sub-font">Get started by selecting a feature from the sidebar!</p>', unsafe_allow_html=True)
303
+
304
+
305
+ @handle_errors
306
+ def show_post_creation():
307
+ st.header("Post Creation")
308
+
309
+ content_type = st.selectbox("Content Type", ["Social Media Post", "Ad Copy", "Email"])
310
+ content_prompt = st.text_area("Describe the content you want to generate")
311
+
312
+ if st.button("Generate Content"):
313
+ if not content_prompt:
314
+ st.warning("Please provide a content description.")
315
+ else:
316
+ instruction = f"Create a single {content_type}"
317
+
318
+ with st.spinner("Generating content..."):
319
+ generated_content = generate_marketing_content(instruction, content_prompt)
320
+
321
+ st.markdown(generated_content)
322
+
323
+ # Download as PDF
324
+ pdf = create_pdf(generated_content)
325
+ st.download_button(
326
+ label="Download Generated Content as PDF",
327
+ data=pdf,file_name="generated_content.pdf",
328
+ mime="application/pdf"
329
+ )
330
+
331
+ @handle_errors
332
+ def show_marketing_strategy():
333
+ st.header("Marketing Strategy")
334
+
335
+ # Brand Questionnaire
336
+ st.subheader("Brand Questionnaire")
337
+ brand_name = st.text_input("Brand Name")
338
+ industry = st.selectbox("Industry", ["Technology", "Fashion", "Food & Beverage", "Other"])
339
+ target_audience = st.text_area("Describe your target audience")
340
+ campaign_objective = st.selectbox("Campaign Objective", ["Brand Awareness", "Lead Generation", "Sales", "Other"])
341
+
342
+ start_date = st.date_input("Campaign Start Date")
343
+ duration = st.number_input("Campaign Duration (days)", min_value=1, value=30)
344
+
345
+ if st.button("Generate Strategy"):
346
+ if not all([brand_name, industry, target_audience, campaign_objective]):
347
+ st.warning("Please fill in all the fields in the Brand Questionnaire.")
348
+ else:
349
+ instruction = f"Generate a unique day-by-day marketing strategy for {duration} days"
350
+ input_context = f"Brand: {brand_name}, Industry: {industry}, Target Audience: {target_audience}, Objective: {campaign_objective}, Start Date: {start_date}, Duration: {duration} days"
351
+
352
+ with st.spinner("Generating strategy..."):
353
+ strategy = generate_marketing_content(instruction, input_context, is_strategy=True)
354
+
355
+ st.subheader("Generated Marketing Strategy")
356
+ st.markdown(strategy)
357
+
358
+ # Download as PDF
359
+ pdf = create_pdf(strategy)
360
+ st.download_button(
361
+ label="Download Marketing Strategy as PDF",
362
+ data=pdf,
363
+ file_name="marketing_strategy.pdf",
364
+ mime="application/pdf"
365
+ )
366
+ import streamlit as st
367
+ import requests
368
+ import json
369
+ from datetime import datetime, timedelta
370
+ from PIL import Image
371
+ import io
372
+ import os
373
+ import uuid
374
+ ACCESS_TOKEN = st.secrets["META_ACCESS_TOKEN"]
375
+ PAGE_ID = st.secrets["META_PAGE_ID"]
376
+
377
+ HEADERS = {
378
+ "Authorization": f"Bearer {ACCESS_TOKEN}",
379
+ "Content-Type": "application/json"
380
+ }
381
+
382
+ def post_to_facebook(message, image_url=None, scheduled_time=None):
383
+ url = f"https://graph.facebook.com/v20.0/{PAGE_ID}/feed"
384
+ data = {
385
+ "message": message,
386
+ "published": False if scheduled_time else True,
387
+ }
388
+ if image_url:
389
+ data["link"] = image_url
390
+ if scheduled_time:
391
+ data["scheduled_publish_time"] = int(scheduled_time.timestamp())
392
+
393
+ response = requests.post(url, headers=HEADERS, json=data)
394
+ return response.json()
395
+
396
+
397
+
398
+ def save_scheduled_post(platform, content, image_path, scheduled_time):
399
+ # Create a unique ID for the scheduled post
400
+ post_id = str(uuid.uuid4())
401
+
402
+ # Save post details to a JSON file
403
+ scheduled_posts = load_scheduled_posts()
404
+ scheduled_posts[post_id] = {
405
+ "platform": platform,
406
+ "content": content,
407
+ "image_path": image_path,
408
+ "scheduled_time": scheduled_time.isoformat()
409
+ }
410
+
411
+ with open("scheduled_posts.json", "w") as f:
412
+ json.dump(scheduled_posts, f)
413
+
414
+ def load_scheduled_posts():
415
+ if os.path.exists("scheduled_posts.json"):
416
+ with open("scheduled_posts.json", "r") as f:
417
+ return json.load(f)
418
+ return {}
419
+
420
+
421
+
422
+
423
+ def show_scheduling():
424
+ st.header("Content Scheduling")
425
+
426
+ platforms = ["Facebook"] # Remove Instagram option
427
+
428
+ post_content = st.text_area("Post Content", key="schedule_post_content")
429
+
430
+ uploaded_image = st.file_uploader("Upload Image", type=["png", "jpg", "jpeg"], key="schedule_image_upload")
431
+
432
+ post_date = st.date_input("Post Date", key="schedule_post_date")
433
+ post_time = st.time_input("Post Time", key="schedule_post_time")
434
+
435
+ if post_content or uploaded_image:
436
+ st.subheader("Preview")
437
+
438
+ col1, col2 = st.columns(2)
439
+
440
+ with col1:
441
+ if post_content:
442
+ st.text_area("Content Preview", post_content, height=150, disabled=True, key="schedule_content_preview")
443
+
444
+ with col2:
445
+ if uploaded_image:
446
+ image = Image.open(uploaded_image)
447
+ st.image(image, caption="Uploaded Image", use_column_width=True)
448
+
449
+ if st.button("Schedule Post", key="schedule_post_button"):
450
+ if not post_content and not uploaded_image:
451
+ st.warning("Please add content or upload an image.")
452
+ else:
453
+ scheduled_datetime = datetime.combine(post_date, post_time)
454
+
455
+ # Save image temporarily if uploaded
456
+ image_path = None
457
+ if uploaded_image:
458
+ image_path = f"temp_image_{uuid.uuid4()}.jpg"
459
+ Image.open(uploaded_image).save(image_path)
460
+
461
+ response = post_to_facebook(post_content, image_path, scheduled_datetime)
462
+ if "id" in response:
463
+ st.success(f"Post scheduled for Facebook at {scheduled_datetime}")
464
+ # Save scheduled post
465
+ save_scheduled_post("Facebook", post_content, image_path, scheduled_datetime)
466
+ else:
467
+ st.error(f"Error scheduling Facebook post: {response.get('error', {}).get('message', 'Unknown error')}")
468
+
469
+ # Display scheduled post details
470
+ st.subheader("Scheduled Post Details")
471
+ st.write(f"Date and Time: {scheduled_datetime}")
472
+ st.write("Platform: Facebook")
473
+ if post_content:
474
+ st.write("Content:")
475
+ st.text_area("Scheduled Content", post_content, height=150, disabled=True, key="scheduled_content_display")
476
+ if uploaded_image:
477
+ st.write("Image:")
478
+ st.image(image, caption="Scheduled Image", use_column_width=True)
479
+
480
+ # Display scheduled posts
481
+ st.subheader("Scheduled Posts")
482
+ scheduled_posts = load_scheduled_posts()
483
+ for post_id, post_data in scheduled_posts.items():
484
+ st.write(f"Platform: {post_data['platform']}")
485
+ st.write(f"Scheduled Time: {post_data['scheduled_time']}")
486
+ st.text_area(f"Content for post {post_id}", post_data['content'], height=100, disabled=True, key=f"scheduled_post_{post_id}")
487
+ if post_data['image_path']:
488
+ st.image(post_data['image_path'], caption="Scheduled Image", width=200)
489
+ st.write("---")
490
+
491
+ def show_analytics():
492
+ st.header("Campaign Analytics")
493
+ st.write("This feature is under development. It will show campaign performance metrics and insights.")
494
+
495
+ if __name__ == "__main__":
496
+ main()