Skip to content

Commit 9cd9821

Browse files
committed
emojis in filters and announcement banner
1 parent af270a0 commit 9cd9821

File tree

8 files changed

+1095
-663
lines changed

8 files changed

+1095
-663
lines changed

backend/scraping/generate_static_data.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,18 +164,22 @@ def main():
164164
f.write("\n")
165165
f.write("];\n\n")
166166

167-
# Write recommended filters
167+
# Write recommended filters (now 3D array format)
168168
if recommended_filters:
169-
f.write("export const RECOMMENDED_FILTERS: string[] = [\n")
170-
for i, filter_keyword in enumerate(recommended_filters):
171-
escaped = filter_keyword.replace('"', '\\"')
172-
f.write(f' "{escaped}"')
173-
if i < len(recommended_filters) - 1:
174-
f.write(",")
175-
f.write("\n")
169+
f.write("export const RECOMMENDED_FILTERS: [string, string, string][] = [\n")
170+
for i, filter_item in enumerate(recommended_filters):
171+
if len(filter_item) == 3:
172+
category, emoji_string, filter_name = filter_item
173+
category_escaped = category.replace('"', '\\"')
174+
emoji_escaped = emoji_string.replace('"', '\\"')
175+
filter_escaped = filter_name.replace('"', '\\"')
176+
f.write(f' ["{category_escaped}", "{emoji_escaped}", "{filter_escaped}"]')
177+
if i < len(recommended_filters) - 1:
178+
f.write(",")
179+
f.write("\n")
176180
f.write("];\n")
177181
else:
178-
f.write("export const RECOMMENDED_FILTERS: string[] = [];\n")
182+
f.write("export const RECOMMENDED_FILTERS: [string, string, string][] = [];\n")
179183

180184
logger.info(
181185
"Successfully updated staticData.ts with events and recommended filters"

backend/services/openai_service.py

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from dotenv import load_dotenv
1717
from openai import OpenAI
1818

19+
from shared.constants.emojis import EMOJI_CATEGORIES
20+
1921
logger = logging.getLogger(__name__)
2022

2123

@@ -224,8 +226,11 @@ def extract_events_from_caption(
224226
# Return default structure if API call fails
225227
return [_get_default_event_structure(source_image_url)]
226228

227-
def generate_recommended_filters(self, events_data: list[dict]) -> list[str]:
228-
"""Generate recommended filter keywords from upcoming events data using GPT"""
229+
def generate_recommended_filters(self, events_data: list[dict]) -> list[list[str]]:
230+
"""Generate recommended filter keywords with emojis from upcoming events data using GPT
231+
232+
Returns a list of 3-element arrays: [category, emoji_string, filter_name]
233+
"""
229234
if not events_data:
230235
logger.warning("No events data provided for filter generation")
231236
return []
@@ -240,21 +245,44 @@ def generate_recommended_filters(self, events_data: list[dict]) -> list[str]:
240245
summary += f" [type: {event.get('club_type')}]"
241246
event_summaries.append(summary)
242247

248+
# Get the categorized emoji list for the prompt
249+
emoji_categories = EMOJI_CATEGORIES
250+
emoji_list_str = ""
251+
for category, emojis in emoji_categories.items():
252+
emoji_list_str += f"\n{category}:\n"
253+
emoji_list_str += ", ".join(emojis) + "\n"
254+
243255
prompt = f"""
244-
Analyze the following list of {len(event_summaries)} upcoming student events and generate 20-25 search filter keywords.
256+
Analyze the following list of {len(event_summaries)} upcoming student events and generate 20-25 search filter keywords with matching emojis.
245257
246258
Events:
247259
{chr(10).join(event_summaries)}
248260
261+
Available emojis organized by category (select the most fitting one for each filter):
262+
{emoji_list_str}
263+
249264
Generate filter keywords that:
250265
1. Capture the most common themes students care about (networking, meeting people, large events, food, professional development, etc.)
251266
2. Are SHORT (1-3 words max) and SPECIFIC
252267
3. Reflect actual patterns in the event data above
253268
4. Focus on: event types, activities, professional topics, food/drinks, social aspects, clubs/organizations
254269
5. Are diverse enough to cover different student interests
255270
256-
Return ONLY a JSON array of 20-25 keyword strings, like:
257-
["networking", "free food", "career fair", "live music", "workshop", ...]
271+
For each filter, select the MOST FITTING emoji from the available list above.
272+
273+
Return ONLY a JSON array of arrays, where each inner array has exactly 3 elements:
274+
- Index 0: The category name (exactly as it appears in the categories above)
275+
- Index 1: The emoji name (exactly as it appears in the available list above)
276+
- Index 2: The filter name (string)
277+
278+
Example format:
279+
[
280+
["Smileys", "Grinning%20Face", "networking"],
281+
["Food%20and%20Drink", "Pizza", "free food"],
282+
["Objects", "Graduation%20Cap", "career fair"],
283+
["Objects", "Musical%20Note", "live music"],
284+
["Objects", "Books", "workshop"]
285+
]
258286
259287
NO explanations, NO additional text, JUST the JSON array.
260288
"""
@@ -269,12 +297,12 @@ def generate_recommended_filters(self, events_data: list[dict]) -> list[str]:
269297
messages=[
270298
{
271299
"role": "system",
272-
"content": "You are a helpful assistant that generates search keywords. Always return valid JSON arrays.",
300+
"content": "You are a helpful assistant that generates search keywords with emojis. Always return valid JSON arrays with the exact structure requested.",
273301
},
274302
{"role": "user", "content": prompt},
275303
],
276304
temperature=0.3,
277-
max_tokens=300,
305+
max_tokens=15000,
278306
)
279307

280308
response_text = response.choices[0].message.content.strip()
@@ -292,14 +320,24 @@ def generate_recommended_filters(self, events_data: list[dict]) -> list[str]:
292320
return []
293321

294322
# Clean and validate filters
295-
cleaned_filters = [
296-
str(f).strip()
297-
for f in filters
298-
if f and isinstance(f, str) and len(str(f).strip()) > 0
299-
]
300-
301-
logger.info(f"Generated {len(cleaned_filters)} recommended filters")
302-
return list(set(cleaned_filters))[:25]
323+
cleaned_filters = []
324+
for filter_item in filters:
325+
if (isinstance(filter_item, list) and
326+
len(filter_item) == 3 and
327+
isinstance(filter_item[0], str) and
328+
isinstance(filter_item[1], str) and
329+
isinstance(filter_item[2], str) and
330+
filter_item[0].strip() and
331+
filter_item[1].strip() and
332+
filter_item[2].strip()):
333+
cleaned_filters.append([
334+
filter_item[0].strip(), # category
335+
filter_item[1].strip(), # emoji_string
336+
filter_item[2].strip() # filter_name
337+
])
338+
339+
logger.info(f"Generated {len(cleaned_filters)} recommended filters with emojis")
340+
return cleaned_filters[:15]
303341

304342
except json.JSONDecodeError:
305343
logger.exception("Error parsing JSON response for filters")

0 commit comments

Comments
 (0)