Skip to content

Commit bba16cb

Browse files
committed
update event fields to new model for OpenAI service
1 parent 62b794e commit bba16cb

File tree

1 file changed

+36
-39
lines changed

1 file changed

+36
-39
lines changed

backend/services/openai_service.py

Lines changed: 36 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,13 @@ def generate_event_embedding(self, event) -> list[float]:
5555
"""
5656
# Define field names to include
5757
field_names = [
58-
"name",
58+
"title",
5959
"description",
6060
"location",
6161
"club_type",
62-
"club_handle",
63-
"date",
64-
"start_time",
62+
"ig_handle",
63+
"dtstart",
64+
"dtend",
6565
"food",
6666
"price",
6767
"registration",
@@ -77,7 +77,7 @@ def generate_event_embedding(self, event) -> list[float]:
7777
return self.generate_embedding(enhanced_text)
7878

7979
def extract_events_from_caption(
80-
self, caption_text: str, image_url: str | None = None
80+
self, caption_text: str, source_image_url: str | None = None
8181
) -> list[dict[str, str | bool | float | None]]:
8282
"""Extract event information from Instagram caption text and optional image"""
8383
# Get current date and day of week for context
@@ -95,31 +95,29 @@ def extract_events_from_caption(
9595
Return a JSON array of event objects. Each event should have the following structure (all fields must be present):
9696
[
9797
{{
98-
"name": string, // name of the event
99-
"date": string, // date in YYYY-MM-DD format if found, empty string if not
100-
"start_time": string, // start time in HH:MM format if found, empty string if not
101-
"end_time": string, // end time in HH:MM format if found, empty string if not
98+
"title": string, // name of the event
99+
"dtstart": string, // start date in YYYY-MM-DD HH:MM:SS±HH format if found, empty string if not
100+
"dtend": string, // end date in YYYY-MM-DD HH:MM:SS±HH format if found, empty string if not
102101
"location": string, // location of the event
103102
"price": number or null, // price in dollars (e.g., 15.00) if mentioned, null if free or not mentioned
104103
"food": string, // food information if mentioned, empty string if not
105104
"registration": boolean, // true if registration is required/mentioned, false otherwise
106-
"image_url": string, // URL of the event image if provided, empty string if not
105+
"source_image_url": string, // URL of the event image if provided, empty string if not
107106
"description": string // the caption text word-for-word, followed by any additional insights from the image not in the caption
108107
}}
109108
]
110109
111110
Guidelines:
112-
- PRIORITIZE CAPTION TEXT for extracting fields (date, time, location, price, food, registration, description, etc.).
113-
- EXCEPTION: For the event "name" field ONLY, prefer an explicit title found in the image (e.g., poster text) if the caption does not contain a clear, explicit event title. If both caption and image provide a name, prefer the image-derived title for the "name" field; otherwise use the caption.
111+
- PRIORITIZE CAPTION TEXT for extracting fields (dtstart, dtend, location, price, food, registration, description, etc.).
112+
- EXCEPTION: For the event "title" field ONLY, prefer an explicit title found in the image (e.g., poster text) if the caption does not contain a clear, explicit event title. If both caption and image provide a name, prefer the image-derived title for the "title" field; otherwise use the caption.
114113
- Return an array of events - if multiple events are mentioned, create separate objects for each
115-
- Title-case event names (e.g., "...talk" -> "...Talk", "COFFEE CRAWL" -> "Coffee Crawl")
114+
- Title-case event titles (e.g., "...talk" -> "...Talk", "COFFEE CRAWL" -> "Coffee Crawl")
116115
- If multiple dates are mentioned (e.g., "Friday and Saturday"), create separate events for each date
117116
- If recurring events are mentioned (e.g., "every Friday"), just create one event
118-
- For dates, use YYYY-MM-DD format. If year not found, assume 2025
119-
- For times, use HH:MM format (24-hour)
117+
- For dtstart and dtend, if year not found, assume 2025
120118
- When interpreting relative terms like "tonight", "tomorrow", "weekly", "every Friday", use the current date context above and the date the post was made. If an explicit date is found in the image, use that date
121119
- For weekly events, calculate the next occurrence based on the current date and day of week
122-
- For addresses: use the format "[Street Address], [City], [Province] [Postal Code]" when possible
120+
- For (off-campus) addresses: use the format "[Street Address], [City], [Province] [Postal Code]" when possible
123121
- For price: extract dollar amounts (e.g., "$15", "15 dollars", "cost: $20") as numbers, use null for free events or when not mentioned
124122
- For food: extract and list all specific food or beverage items mentioned, separated by commas (e.g., "Snacks, drinks", "Pizza, bubble tea"). Always capitalize the first item mentioned
125123
- If the exact food items are not mentioned, e.g., the literal word "food" would be returned, output "Yes!" (exactly) for the food field to indicate that food is present. Do not output the literal word "food" by itself.
@@ -129,7 +127,7 @@ def extract_events_from_caption(
129127
- Be consistent with the exact field names
130128
- Return ONLY the JSON array, no additional text
131129
- If no events are found, return an empty array []
132-
{f"- An image is provided at: {image_url}. If there are conflicts between caption and image information, ALWAYS prioritize the caption text over visual cues from the image." if image_url else ""}
130+
{f"- An image is provided at: {source_image_url}. If there are conflicts between caption and image information, ALWAYS prioritize the caption text over visual cues from the image." if source_image_url else ""}
133131
"""
134132

135133
try:
@@ -149,10 +147,10 @@ def extract_events_from_caption(
149147
]
150148

151149
# Add image to the message if provided
152-
if image_url:
153-
logger.debug(f"Including image analysis from: {image_url}")
150+
if source_image_url:
151+
logger.debug(f"Including image analysis from: {source_image_url}")
154152
messages[1]["content"].append(
155-
{"type": "image_url", "image_url": {"url": image_url}}
153+
{"type": "source_image_url", "source_image_url": {"url": source_image_url}}
156154
)
157155
model = "gpt-4o-mini" # Use vision-capable model
158156
else:
@@ -185,16 +183,16 @@ def extract_events_from_caption(
185183
for event_data in events_data:
186184
# Ensure all required fields are present
187185
required_fields = [
188-
"name",
189-
"date",
190-
"start_time",
191-
"end_time",
186+
"title",
187+
"description",
192188
"location",
193-
"price",
189+
"club_type",
190+
"ig_handle",
191+
"dtstart",
192+
"dtend",
194193
"food",
194+
"price",
195195
"registration",
196-
"image_url",
197-
"description",
198196
]
199197
for field in required_fields:
200198
if field not in event_data:
@@ -205,9 +203,9 @@ def extract_events_from_caption(
205203
else:
206204
event_data[field] = ""
207205

208-
# Set image_url if provided
209-
if image_url and not event_data.get("image_url"):
210-
event_data["image_url"] = image_url
206+
# Set source_image_url if provided
207+
if source_image_url and not event_data.get("source_image_url"):
208+
event_data["source_image_url"] = source_image_url
211209

212210
processed_events.append(event_data)
213211

@@ -217,14 +215,14 @@ def extract_events_from_caption(
217215
logger.exception("Error parsing JSON response")
218216
logger.error(f"Response text: {response_text}")
219217
# Return default structure if JSON parsing fails
220-
return [_get_default_event_structure(image_url)]
218+
return [_get_default_event_structure(source_image_url)]
221219

222220
except Exception:
223221
logger.exception("Error parsing caption")
224222
logger.error(f"Caption text: {caption_text}")
225223
logger.error(f"Traceback: {traceback.format_exc()}")
226224
# Return default structure if API call fails
227-
return [_get_default_event_structure(image_url)]
225+
return [_get_default_event_structure(source_image_url)]
228226

229227
def generate_recommended_filters(self, events_data: list[dict]) -> list[str]:
230228
"""Generate recommended filter keywords from upcoming events data using GPT"""
@@ -235,7 +233,7 @@ def generate_recommended_filters(self, events_data: list[dict]) -> list[str]:
235233
# Prepare event summaries for the prompt
236234
event_summaries = []
237235
for event in events_data[:200]: # Limit to 200 events to avoid token limits
238-
summary = f"- {event.get('name', 'Unnamed')} at {event.get('location', 'TBD')} on {event.get('date', 'TBD')}"
236+
summary = f"- {event.get('title', 'Unnamed')} at {event.get('location', 'TBD')}"
239237
if event.get("food"):
240238
summary += f" (food: {event.get('food')})"
241239
if event.get("club_type"):
@@ -314,19 +312,18 @@ def generate_recommended_filters(self, events_data: list[dict]) -> list[str]:
314312

315313

316314
def _get_default_event_structure(
317-
image_url: str | None = None,
315+
source_image_url: str | None = None,
318316
) -> dict[str, str | bool | float | None]:
319317
"""Helper function to create default event structure"""
320318
return {
321-
"name": "",
322-
"date": "",
323-
"start_time": "",
324-
"end_time": "",
319+
"title": "",
320+
"dtstart": "",
321+
"dtend": "",
325322
"location": "",
326323
"price": None,
327324
"food": "",
328325
"registration": False,
329-
"image_url": image_url if image_url else "",
326+
"source_image_url": source_image_url if source_image_url else "",
330327
"description": "",
331328
}
332329

0 commit comments

Comments
 (0)