Liss, Alex (NYC-HUG) commited on
Commit
bb4fc9d
·
1 Parent(s): ef3bbde

preparing to execute sprint 1 feature work log

Browse files
data/april_11_multimedia_data_collect/nfl_team_logos.csv ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ team_name,logo_url,local_path
2
+ "Arizona Cardinals News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/ARI,"team_logos/arizona_cardinals_news,_scores,_stats,_schedule.png"
3
+ "Atlanta Falcons News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/ATL,"team_logos/atlanta_falcons_news,_scores,_stats,_schedule.png"
4
+ "Carolina Panthers News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/CAR,"team_logos/carolina_panthers_news,_scores,_stats,_schedule.png"
5
+ "Chicago Bears News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/CHI,"team_logos/chicago_bears_news,_scores,_stats,_schedule.png"
6
+ "Dallas Cowboys News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/DAL,"team_logos/dallas_cowboys_news,_scores,_stats,_schedule.png"
7
+ "Detroit Lions News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/DET,"team_logos/detroit_lions_news,_scores,_stats,_schedule.png"
8
+ "Green Bay Packers News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/GB,"team_logos/green_bay_packers_news,_scores,_stats,_schedule.png"
9
+ "Los Angeles Rams News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/LA,"team_logos/los_angeles_rams_news,_scores,_stats,_schedule.png"
10
+ "Minnesota Vikings News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/MIN,"team_logos/minnesota_vikings_news,_scores,_stats,_schedule.png"
11
+ "New Orleans Saints News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/NO,"team_logos/new_orleans_saints_news,_scores,_stats,_schedule.png"
12
+ "New York Giants News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/NYG,"team_logos/new_york_giants_news,_scores,_stats,_schedule.png"
13
+ "Philadelphia Eagles News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/PHI,"team_logos/philadelphia_eagles_news,_scores,_stats,_schedule.png"
14
+ "San Francisco 49ers News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/SF,"team_logos/san_francisco_49ers_news,_scores,_stats,_schedule.png"
15
+ "Seattle Seahawks News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/SEA,"team_logos/seattle_seahawks_news,_scores,_stats,_schedule.png"
16
+ "Tampa Bay Buccaneers News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/TB,"team_logos/tampa_bay_buccaneers_news,_scores,_stats,_schedule.png"
17
+ "Washington Commanders News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/WAS,"team_logos/washington_commanders_news,_scores,_stats,_schedule.png"
18
+ "Baltimore Ravens News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/BAL,"team_logos/baltimore_ravens_news,_scores,_stats,_schedule.png"
19
+ "Buffalo Bills News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/BUF,"team_logos/buffalo_bills_news,_scores,_stats,_schedule.png"
20
+ "Cincinnati Bengals News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/CIN,"team_logos/cincinnati_bengals_news,_scores,_stats,_schedule.png"
21
+ "Cleveland Browns News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/CLE,"team_logos/cleveland_browns_news,_scores,_stats,_schedule.png"
22
+ "Denver Broncos News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/DEN,"team_logos/denver_broncos_news,_scores,_stats,_schedule.png"
23
+ "Jacksonville Jaguars News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/JAX,"team_logos/jacksonville_jaguars_news,_scores,_stats,_schedule.png"
24
+ "Kansas City Chiefs News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/KC,"team_logos/kansas_city_chiefs_news,_scores,_stats,_schedule.png"
25
+ "Las Vegas Raiders News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/LV,"team_logos/las_vegas_raiders_news,_scores,_stats,_schedule.png"
26
+ "Los Angeles Chargers News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/LAC,"team_logos/los_angeles_chargers_news,_scores,_stats,_schedule.png"
27
+ "Miami Dolphins News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/MIA,"team_logos/miami_dolphins_news,_scores,_stats,_schedule.png"
28
+ "New England Patriots News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/NE,"team_logos/new_england_patriots_news,_scores,_stats,_schedule.png"
29
+ "New York Jets News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/NYJ,"team_logos/new_york_jets_news,_scores,_stats,_schedule.png"
30
+ "Pittsburgh Steelers News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/PIT,"team_logos/pittsburgh_steelers_news,_scores,_stats,_schedule.png"
31
+ "Tennessee Titans News, Scores, Stats, Schedule",https://static.www.nfl.com/t_headshot_desktop/league/api/clubs/logos/TEN,"team_logos/tennessee_titans_news,_scores,_stats,_schedule.png"
32
+ Arizona Cardinals,https://a.espncdn.com/i/teamlogos/nfl/500/ari.png,team_logos/arizona_cardinals.png
33
+ Atlanta Falcons,https://a.espncdn.com/i/teamlogos/nfl/500/atl.png,team_logos/atlanta_falcons.png
34
+ Baltimore Ravens,https://a.espncdn.com/i/teamlogos/nfl/500/bal.png,team_logos/baltimore_ravens.png
35
+ Buffalo Bills,https://a.espncdn.com/i/teamlogos/nfl/500/buf.png,team_logos/buffalo_bills.png
36
+ Carolina Panthers,https://a.espncdn.com/i/teamlogos/nfl/500/car.png,team_logos/carolina_panthers.png
37
+ Chicago Bears,https://a.espncdn.com/i/teamlogos/nfl/500/chi.png,team_logos/chicago_bears.png
38
+ Cincinnati Bengals,https://a.espncdn.com/i/teamlogos/nfl/500/cin.png,team_logos/cincinnati_bengals.png
39
+ Cleveland Browns,https://a.espncdn.com/i/teamlogos/nfl/500/cle.png,team_logos/cleveland_browns.png
40
+ Dallas Cowboys,https://a.espncdn.com/i/teamlogos/nfl/500/dal.png,team_logos/dallas_cowboys.png
41
+ Denver Broncos,https://a.espncdn.com/i/teamlogos/nfl/500/den.png,team_logos/denver_broncos.png
42
+ Detroit Lions,https://a.espncdn.com/i/teamlogos/nfl/500/det.png,team_logos/detroit_lions.png
43
+ Green Bay Packers,https://a.espncdn.com/i/teamlogos/nfl/500/gb.png,team_logos/green_bay_packers.png
44
+ Houston Texans,https://a.espncdn.com/i/teamlogos/nfl/500/hou.png,team_logos/houston_texans.png
45
+ Indianapolis Colts,https://a.espncdn.com/i/teamlogos/nfl/500/ind.png,team_logos/indianapolis_colts.png
46
+ Jacksonville Jaguars,https://a.espncdn.com/i/teamlogos/nfl/500/jax.png,team_logos/jacksonville_jaguars.png
47
+ Kansas City Chiefs,https://a.espncdn.com/i/teamlogos/nfl/500/kc.png,team_logos/kansas_city_chiefs.png
48
+ Las Vegas Raiders,https://a.espncdn.com/i/teamlogos/nfl/500/lv.png,team_logos/las_vegas_raiders.png
49
+ Los Angeles Chargers,https://a.espncdn.com/i/teamlogos/nfl/500/lac.png,team_logos/los_angeles_chargers.png
50
+ Los Angeles Rams,https://a.espncdn.com/i/teamlogos/nfl/500/lar.png,team_logos/los_angeles_rams.png
51
+ Miami Dolphins,https://a.espncdn.com/i/teamlogos/nfl/500/mia.png,team_logos/miami_dolphins.png
52
+ Minnesota Vikings,https://a.espncdn.com/i/teamlogos/nfl/500/min.png,team_logos/minnesota_vikings.png
53
+ New England Patriots,https://a.espncdn.com/i/teamlogos/nfl/500/ne.png,team_logos/new_england_patriots.png
54
+ New Orleans Saints,https://a.espncdn.com/i/teamlogos/nfl/500/no.png,team_logos/new_orleans_saints.png
55
+ New York Giants,https://a.espncdn.com/i/teamlogos/nfl/500/nyg.png,team_logos/new_york_giants.png
56
+ New York Jets,https://a.espncdn.com/i/teamlogos/nfl/500/nyj.png,team_logos/new_york_jets.png
57
+ Philadelphia Eagles,https://a.espncdn.com/i/teamlogos/nfl/500/phi.png,team_logos/philadelphia_eagles.png
58
+ Pittsburgh Steelers,https://a.espncdn.com/i/teamlogos/nfl/500/pit.png,team_logos/pittsburgh_steelers.png
59
+ San Francisco 49ers,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png,team_logos/san_francisco_49ers.png
60
+ Seattle Seahawks,https://a.espncdn.com/i/teamlogos/nfl/500/sea.png,team_logos/seattle_seahawks.png
61
+ Tampa Bay Buccaneers,https://a.espncdn.com/i/teamlogos/nfl/500/tb.png,team_logos/tampa_bay_buccaneers.png
62
+ Tennessee Titans,https://a.espncdn.com/i/teamlogos/nfl/500/ten.png,team_logos/tennessee_titans.png
63
+ Washington Commanders,https://a.espncdn.com/i/teamlogos/nfl/500/wsh.png,team_logos/washington_commanders.png
data/april_11_multimedia_data_collect/nfl_team_logos_revised.csv ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ team_name,logo_url,local_path
2
+ Arizona Cardinals,https://a.espncdn.com/i/teamlogos/nfl/500/ari.png,team_logos/arizona_cardinals.png
3
+ Atlanta Falcons,https://a.espncdn.com/i/teamlogos/nfl/500/atl.png,team_logos/atlanta_falcons.png
4
+ Baltimore Ravens,https://a.espncdn.com/i/teamlogos/nfl/500/bal.png,team_logos/baltimore_ravens.png
5
+ Buffalo Bills,https://a.espncdn.com/i/teamlogos/nfl/500/buf.png,team_logos/buffalo_bills.png
6
+ Carolina Panthers,https://a.espncdn.com/i/teamlogos/nfl/500/car.png,team_logos/carolina_panthers.png
7
+ Chicago Bears,https://a.espncdn.com/i/teamlogos/nfl/500/chi.png,team_logos/chicago_bears.png
8
+ Cincinnati Bengals,https://a.espncdn.com/i/teamlogos/nfl/500/cin.png,team_logos/cincinnati_bengals.png
9
+ Cleveland Browns,https://a.espncdn.com/i/teamlogos/nfl/500/cle.png,team_logos/cleveland_browns.png
10
+ Dallas Cowboys,https://a.espncdn.com/i/teamlogos/nfl/500/dal.png,team_logos/dallas_cowboys.png
11
+ Denver Broncos,https://a.espncdn.com/i/teamlogos/nfl/500/den.png,team_logos/denver_broncos.png
12
+ Detroit Lions,https://a.espncdn.com/i/teamlogos/nfl/500/det.png,team_logos/detroit_lions.png
13
+ Green Bay Packers,https://a.espncdn.com/i/teamlogos/nfl/500/gb.png,team_logos/green_bay_packers.png
14
+ Houston Texans,https://a.espncdn.com/i/teamlogos/nfl/500/hou.png,team_logos/houston_texans.png
15
+ Indianapolis Colts,https://a.espncdn.com/i/teamlogos/nfl/500/ind.png,team_logos/indianapolis_colts.png
16
+ Jacksonville Jaguars,https://a.espncdn.com/i/teamlogos/nfl/500/jax.png,team_logos/jacksonville_jaguars.png
17
+ Kansas City Chiefs,https://a.espncdn.com/i/teamlogos/nfl/500/kc.png,team_logos/kansas_city_chiefs.png
18
+ Las Vegas Raiders,https://a.espncdn.com/i/teamlogos/nfl/500/lv.png,team_logos/las_vegas_raiders.png
19
+ Los Angeles Chargers,https://a.espncdn.com/i/teamlogos/nfl/500/lac.png,team_logos/los_angeles_chargers.png
20
+ Los Angeles Rams,https://a.espncdn.com/i/teamlogos/nfl/500/lar.png,team_logos/los_angeles_rams.png
21
+ Miami Dolphins,https://a.espncdn.com/i/teamlogos/nfl/500/mia.png,team_logos/miami_dolphins.png
22
+ Minnesota Vikings,https://a.espncdn.com/i/teamlogos/nfl/500/min.png,team_logos/minnesota_vikings.png
23
+ New England Patriots,https://a.espncdn.com/i/teamlogos/nfl/500/ne.png,team_logos/new_england_patriots.png
24
+ New Orleans Saints,https://a.espncdn.com/i/teamlogos/nfl/500/no.png,team_logos/new_orleans_saints.png
25
+ New York Giants,https://a.espncdn.com/i/teamlogos/nfl/500/nyg.png,team_logos/new_york_giants.png
26
+ New York Jets,https://a.espncdn.com/i/teamlogos/nfl/500/nyj.png,team_logos/new_york_jets.png
27
+ Philadelphia Eagles,https://a.espncdn.com/i/teamlogos/nfl/500/phi.png,team_logos/philadelphia_eagles.png
28
+ Pittsburgh Steelers,https://a.espncdn.com/i/teamlogos/nfl/500/pit.png,team_logos/pittsburgh_steelers.png
29
+ San Francisco 49ers,https://a.espncdn.com/i/teamlogos/nfl/500/sf.png,team_logos/san_francisco_49ers.png
30
+ Seattle Seahawks,https://a.espncdn.com/i/teamlogos/nfl/500/sea.png,team_logos/seattle_seahawks.png
31
+ Tampa Bay Buccaneers,https://a.espncdn.com/i/teamlogos/nfl/500/tb.png,team_logos/tampa_bay_buccaneers.png
32
+ Tennessee Titans,https://a.espncdn.com/i/teamlogos/nfl/500/ten.png,team_logos/tennessee_titans.png
33
+ Washington Commanders,https://a.espncdn.com/i/teamlogos/nfl/500/wsh.png,team_logos/washington_commanders.png
data/april_11_multimedia_data_collect/team_logos.py ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ from bs4 import BeautifulSoup
3
+ import csv
4
+ import os
5
+ import time
6
+ import re
7
+ import json
8
+ import logging
9
+
10
+ # Set up logging
11
+ logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
12
+ logger = logging.getLogger(__name__)
13
+
14
+ # Constants
15
+ NFL_TEAMS_URL = "https://www.nfl.com/teams/"
16
+ OUTPUT_DIR = "team_logos"
17
+ CSV_OUTPUT = "nfl_team_logos.csv"
18
+ EXPECTED_TEAM_COUNT = 32
19
+
20
+ def ensure_output_dir(dir_path):
21
+ """Ensure output directory exists"""
22
+ if not os.path.exists(dir_path):
23
+ os.makedirs(dir_path)
24
+ logger.info(f"Created directory: {dir_path}")
25
+
26
+ def download_image(url, file_path):
27
+ """Download image from URL and save to file_path"""
28
+ try:
29
+ headers = {
30
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
31
+ }
32
+ response = requests.get(url, headers=headers, stream=True)
33
+ response.raise_for_status()
34
+
35
+ with open(file_path, 'wb') as f:
36
+ for chunk in response.iter_content(chunk_size=8192):
37
+ f.write(chunk)
38
+
39
+ return True
40
+ except Exception as e:
41
+ logger.error(f"Failed to download image from {url}: {e}")
42
+ return False
43
+
44
+ def get_team_logo_urls():
45
+ """
46
+ Get team logo URLs directly from team pages.
47
+ Returns a dictionary mapping team names to their logo URLs.
48
+ """
49
+ logger.info(f"Fetching team information from {NFL_TEAMS_URL}")
50
+
51
+ headers = {
52
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
53
+ }
54
+
55
+ try:
56
+ response = requests.get(NFL_TEAMS_URL, headers=headers)
57
+ response.raise_for_status()
58
+ except Exception as e:
59
+ logger.error(f"Failed to fetch NFL teams page: {e}")
60
+ return {}
61
+
62
+ soup = BeautifulSoup(response.text, 'html.parser')
63
+
64
+ # Find all team links
65
+ team_links = []
66
+ for a_tag in soup.find_all('a', href=True):
67
+ if '/teams/' in a_tag['href'] and a_tag['href'].count('/') >= 3:
68
+ # This looks like a team-specific link
69
+ team_links.append(a_tag['href'])
70
+
71
+ # Get unique team URLs
72
+ team_urls = {}
73
+ for link in team_links:
74
+ # Extract team slug (e.g., 'cardinals', '49ers')
75
+ match = re.search(r'/teams/([a-z0-9-]+)/?$', link)
76
+ if match:
77
+ team_slug = match.group(1)
78
+ if team_slug not in team_urls:
79
+ full_url = f"https://www.nfl.com{link}" if not link.startswith('http') else link
80
+ team_urls[team_slug] = full_url
81
+
82
+ logger.info(f"Found {len(team_urls)} unique team URLs")
83
+
84
+ # Visit each team page to get the official logo
85
+ team_logos = {}
86
+ for slug, url in team_urls.items():
87
+ try:
88
+ logger.info(f"Visiting team page: {url}")
89
+ team_response = requests.get(url, headers=headers)
90
+ team_response.raise_for_status()
91
+
92
+ team_soup = BeautifulSoup(team_response.text, 'html.parser')
93
+
94
+ # Get team name from title
95
+ title_tag = team_soup.find('title')
96
+ if title_tag:
97
+ title_text = title_tag.text
98
+ team_name = title_text.split('|')[0].strip()
99
+ if not team_name:
100
+ team_name = slug.replace('-', ' ').title() # Fallback to slug
101
+ else:
102
+ team_name = slug.replace('-', ' ').title() # Fallback to slug
103
+
104
+ # Look for team logo in various places
105
+ logo_url = None
106
+
107
+ # Method 1: Look for logo in meta tags (most reliable)
108
+ og_image = team_soup.find('meta', property='og:image')
109
+ if og_image and og_image.get('content'):
110
+ logo_url = og_image.get('content')
111
+
112
+ # Method 2: Look for team logos in certain image tags or SVGs
113
+ if not logo_url:
114
+ team_header = team_soup.find('div', class_=lambda c: c and ('team-header' in c or 'logo' in c))
115
+ if team_header:
116
+ img = team_header.find('img')
117
+ if img and img.get('src'):
118
+ logo_url = img.get('src')
119
+
120
+ # Method 3: JavaScript data
121
+ if not logo_url:
122
+ scripts = team_soup.find_all('script')
123
+ for script in scripts:
124
+ if script.string and ('logo' in script.string.lower() or 'image' in script.string.lower()):
125
+ # Try to extract JSON data with logo information
126
+ json_matches = re.findall(r'({.*?"logo".*?})', script.string)
127
+ for match in json_matches:
128
+ try:
129
+ data = json.loads(match)
130
+ if 'logo' in data and isinstance(data['logo'], str):
131
+ logo_url = data['logo']
132
+ break
133
+ except:
134
+ continue
135
+
136
+ # Method 4: Fallback to a known pattern based on team abbreviation
137
+ if not logo_url and len(slug) > 2:
138
+ # Some teams have standardized logo URLs with abbreviations
139
+ team_abbr = slug[:2].upper() # Get first 2 chars as abbreviation
140
+ logo_url = f"https://static.www.nfl.com/t_headshot_desktop/f_auto/league/api/clubs/logos/{team_abbr}"
141
+
142
+ # If we found a logo, add it to our dictionary
143
+ if logo_url:
144
+ # If necessary, make the URL absolute
145
+ if not logo_url.startswith('http'):
146
+ logo_url = f"https://www.nfl.com{logo_url}" if logo_url.startswith('/') else f"https://www.nfl.com/{logo_url}"
147
+
148
+ team_logos[team_name] = logo_url
149
+ logger.info(f"Found logo for {team_name}: {logo_url}")
150
+ else:
151
+ logger.warning(f"Could not find logo URL for {team_name}")
152
+
153
+ # Be polite with rate limiting
154
+ time.sleep(1)
155
+
156
+ except Exception as e:
157
+ logger.error(f"Error processing team page {url}: {e}")
158
+
159
+ logger.info(f"Found logos for {len(team_logos)} teams")
160
+ return team_logos
161
+
162
+ def download_team_logos():
163
+ """Download NFL team logos and save to CSV"""
164
+ logger.info("Starting NFL team logo download")
165
+
166
+ # Ensure output directory exists
167
+ ensure_output_dir(OUTPUT_DIR)
168
+
169
+ # Get team logo URLs from team pages
170
+ team_logos = get_team_logo_urls()
171
+
172
+ # Use a backup approach for any missing teams
173
+ if len(team_logos) < EXPECTED_TEAM_COUNT:
174
+ logger.warning(f"Only found {len(team_logos)} team logos from web scraping. Using ESPN API as backup.")
175
+ # We'll use ESPN's API to get team data including logos
176
+ try:
177
+ espn_url = "https://site.api.espn.com/apis/site/v2/sports/football/nfl/teams"
178
+ response = requests.get(espn_url)
179
+ response.raise_for_status()
180
+
181
+ espn_data = response.json()
182
+ if 'sports' in espn_data and len(espn_data['sports']) > 0:
183
+ if 'leagues' in espn_data['sports'][0] and len(espn_data['sports'][0]['leagues']) > 0:
184
+ if 'teams' in espn_data['sports'][0]['leagues'][0]:
185
+ for team_data in espn_data['sports'][0]['leagues'][0]['teams']:
186
+ team = team_data.get('team', {})
187
+ team_name = team.get('displayName')
188
+ if team_name and team_name not in team_logos:
189
+ logo_url = team.get('logos', [{}])[0].get('href')
190
+ if logo_url:
191
+ team_logos[team_name] = logo_url
192
+ logger.info(f"Added {team_name} logo from ESPN API: {logo_url}")
193
+ except Exception as e:
194
+ logger.error(f"Error fetching from ESPN API: {e}")
195
+
196
+ # If we still don't have enough teams, use a manually defined dictionary
197
+ if len(team_logos) < EXPECTED_TEAM_COUNT:
198
+ logger.warning(f"Still only have {len(team_logos)} teams. Adding manual definitions for missing teams.")
199
+
200
+ # Standard team names that should be present
201
+ standard_teams = [
202
+ "Arizona Cardinals", "Atlanta Falcons", "Baltimore Ravens", "Buffalo Bills",
203
+ "Carolina Panthers", "Chicago Bears", "Cincinnati Bengals", "Cleveland Browns",
204
+ "Dallas Cowboys", "Denver Broncos", "Detroit Lions", "Green Bay Packers",
205
+ "Houston Texans", "Indianapolis Colts", "Jacksonville Jaguars", "Kansas City Chiefs",
206
+ "Las Vegas Raiders", "Los Angeles Chargers", "Los Angeles Rams", "Miami Dolphins",
207
+ "Minnesota Vikings", "New England Patriots", "New Orleans Saints", "New York Giants",
208
+ "New York Jets", "Philadelphia Eagles", "Pittsburgh Steelers", "San Francisco 49ers",
209
+ "Seattle Seahawks", "Tampa Bay Buccaneers", "Tennessee Titans", "Washington Commanders"
210
+ ]
211
+
212
+ # Manual dictionary of team logos (use correct ones from NFL's CDN)
213
+ manual_logos = {
214
+ "Arizona Cardinals": "https://static.www.nfl.com/image/private/f_auto/league/u9fltoslqdsyao8cpm0k",
215
+ "Atlanta Falcons": "https://static.www.nfl.com/image/private/f_auto/league/d8m7hzwsyzgg0smz7ifyj",
216
+ "Baltimore Ravens": "https://static.www.nfl.com/image/private/f_auto/league/ucsdijmddsqcj1i9tddd",
217
+ "Buffalo Bills": "https://static.www.nfl.com/image/private/f_auto/league/giphcy6ie9mxbnldntsf",
218
+ "Carolina Panthers": "https://static.www.nfl.com/image/private/f_auto/league/ervfzgrqdpnc7lh5gqwq",
219
+ "Chicago Bears": "https://static.www.nfl.com/image/private/f_auto/league/ra0poq2ivwyahbaq86d2",
220
+ "Cincinnati Bengals": "https://static.www.nfl.com/image/private/f_auto/league/bpx88i8nw4nnabuq0oob",
221
+ "Cleveland Browns": "https://static.www.nfl.com/image/private/f_auto/league/omlzo6n7dpxzbpwrqaak",
222
+ "Dallas Cowboys": "https://static.www.nfl.com/image/private/f_auto/league/dxibuyxbk0b9ua5ih9hn",
223
+ "Denver Broncos": "https://static.www.nfl.com/image/private/f_auto/league/t0p7m5cjdjy18rnzzqbx",
224
+ "Detroit Lions": "https://static.www.nfl.com/image/private/f_auto/league/dhfidtn8jrumakbawoxz",
225
+ "Green Bay Packers": "https://static.www.nfl.com/image/private/f_auto/league/q1l7xmkuuyrpdmnutkzf",
226
+ "Houston Texans": "https://static.www.nfl.com/image/private/f_auto/league/bpx88i8nw4nnabuq0oob",
227
+ "Indianapolis Colts": "https://static.www.nfl.com/image/private/f_auto/league/ketwqeuschqzjsllbid5",
228
+ "Jacksonville Jaguars": "https://static.www.nfl.com/image/private/f_auto/league/bwl1nuab0n2bhi8nxiar",
229
+ "Kansas City Chiefs": "https://static.www.nfl.com/image/private/f_auto/league/ujshjqvmnxce8m4obmvs",
230
+ "Las Vegas Raiders": "https://static.www.nfl.com/image/private/f_auto/league/gzcojbzcyjgubgyb6xf2",
231
+ "Los Angeles Chargers": "https://static.www.nfl.com/image/private/f_auto/league/dhfidtn8jrumakbawoxz",
232
+ "Los Angeles Rams": "https://static.www.nfl.com/image/private/f_auto/league/rjxoqpjirhjvvitffvwh",
233
+ "Miami Dolphins": "https://static.www.nfl.com/image/private/f_auto/league/lits6p8ycthy9to70bnt",
234
+ "Minnesota Vikings": "https://static.www.nfl.com/image/private/f_auto/league/teguylrnqqmfcwxvcmmz",
235
+ "New England Patriots": "https://static.www.nfl.com/image/private/f_auto/league/moyfxx3dq5pio4aiftnc",
236
+ "New Orleans Saints": "https://static.www.nfl.com/image/private/f_auto/league/grhjkahghuebpwzo6kxn",
237
+ "New York Giants": "https://static.www.nfl.com/image/private/f_auto/league/t6mhdmgizi6qhndh8b9p",
238
+ "New York Jets": "https://static.www.nfl.com/image/private/f_auto/league/ekijosiae96gektbo1lj",
239
+ "Philadelphia Eagles": "https://static.www.nfl.com/image/private/f_auto/league/puhrqgj71gobgmwb5g3p",
240
+ "Pittsburgh Steelers": "https://static.www.nfl.com/image/private/f_auto/league/xujik9a3j8hl6jjumu25",
241
+ "San Francisco 49ers": "https://static.www.nfl.com/image/private/f_auto/league/dxibuyxbk0b9ua5ih9hn",
242
+ "Seattle Seahawks": "https://static.www.nfl.com/image/private/f_auto/league/gcytzwpjdzbpwnwxincg",
243
+ "Tampa Bay Buccaneers": "https://static.www.nfl.com/image/private/f_auto/league/v8uqiualryypwqgvwcih",
244
+ "Tennessee Titans": "https://static.www.nfl.com/image/private/f_auto/league/pln44vuzugjgipyidsre",
245
+ "Washington Commanders": "https://static.www.nfl.com/image/private/f_auto/league/xymxwrxtyj9fhaegfwof"
246
+ }
247
+
248
+ # Fill in any missing teams with manual data
249
+ for team_name in standard_teams:
250
+ if team_name not in team_logos and team_name in manual_logos:
251
+ team_logos[team_name] = manual_logos[team_name]
252
+ logger.info(f"Added {team_name} logo from manual dictionary")
253
+
254
+ # Process and download team logos
255
+ results = []
256
+ for team_name, logo_url in team_logos.items():
257
+ # Create safe filename
258
+ safe_name = team_name.replace(' ', '_').lower()
259
+ file_extension = '.png' # Default to PNG
260
+ filename = f"{safe_name}{file_extension}"
261
+ local_path = os.path.join(OUTPUT_DIR, filename)
262
+
263
+ # Download the logo
264
+ logger.info(f"Downloading logo for {team_name} from {logo_url}")
265
+ download_success = download_image(logo_url, local_path)
266
+
267
+ if download_success:
268
+ results.append({
269
+ 'team_name': team_name,
270
+ 'logo_url': logo_url,
271
+ 'local_path': local_path
272
+ })
273
+ logger.info(f"Successfully downloaded logo for {team_name}")
274
+ else:
275
+ logger.error(f"Failed to download logo for {team_name}")
276
+
277
+ # Add a small delay
278
+ time.sleep(0.5)
279
+
280
+ # Save to CSV
281
+ with open(CSV_OUTPUT, 'w', newline='', encoding='utf-8') as f:
282
+ fieldnames = ['team_name', 'logo_url', 'local_path']
283
+ writer = csv.DictWriter(f, fieldnames=fieldnames)
284
+ writer.writeheader()
285
+ writer.writerows(results)
286
+
287
+ logger.info(f"Successfully saved {len(results)} team logos out of {len(team_logos)} teams.")
288
+ logger.info(f"CSV data saved to '{CSV_OUTPUT}'")
289
+
290
+ if len(results) < EXPECTED_TEAM_COUNT:
291
+ logger.warning(f"Only downloaded {len(results)} team logos, expected {EXPECTED_TEAM_COUNT}.")
292
+ else:
293
+ logger.info(f"SUCCESS! Downloaded all {EXPECTED_TEAM_COUNT} NFL team logos!")
294
+
295
+ return results
296
+
297
+ if __name__ == "__main__":
298
+ download_team_logos()
docs/requirements.md ADDED
@@ -0,0 +1,447 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # IFX Companion – Product & Technical Requirements (WIP)
2
+
3
+ ## 1. App at a Glance
4
+
5
+ **Name:** IFX Companion
6
+
7
+ **Summary:**
8
+ An AI-powered sports fan assistant that creates immersive, multimodal, and personalized experiences around NFL teams, players, games, rules, and fan communities. The app delivers conversational responses enhanced with visuals and session memory.
9
+
10
+ **Primary Users:**
11
+ - **Novice Fans:** Curious about the sport
12
+ - **Intermediate Fans:** Seeking updates and highlights
13
+ - **Super Fans:** Wanting in-depth stats, analysis, and community connection
14
+
15
+ **Key Value Proposition:**
16
+ IFX Companion makes fans feel seen, informed, and connected — through natural language, visual storytelling, and personalized interactions tailored to their fandom level.
17
+
18
+ ## 2. Experience Principles
19
+
20
+ ### Natural Language Question and Answers
21
+ Give the user a search interface to immediately find the focus of their intention, improving on existing league and teams apps (NFL, SF 49ers) that don't provide similar functionality.
22
+
23
+ ### Dynamic UI Outputs Tailored to User's Query
24
+ Dynamic layout and content of AI responses, based on the user's query (player / game / team) give the user an engaging and contextually relevant experience.
25
+
26
+ ### Personalization Based on User Profile
27
+ Pre-created fan profiles allow the user to select archetypes (casual fan, consistent fan, superfan) and experience different content and recommendations.
28
+
29
+ ### Connection with Communities of Like-Minded Fans
30
+ Recommendations for how to engage and participate with real-world fan communities allows the fan to join a bigger movement.
31
+
32
+ ## 3. Feature Overview
33
+
34
+ ### 0. Persona Selection
35
+ - **Description:**
36
+ User chooses a predefined persona that represents their level of engagement (novice, intermediate, super fan). This sets a `persona_id` and initializes a memory object in Zep.
37
+ - **Inputs:**
38
+ Button click (Gradio)
39
+ - **Outputs:**
40
+ Persona object passed into session memory for use in future context
41
+ - **Priority:**
42
+ **High**
43
+
44
+ **Persona Memory Structure (Zep)**
45
+ ```json
46
+ {
47
+ "persona_id": "superfan",
48
+ "name": "The Strategist",
49
+ "fan_level": "advanced",
50
+ "favorite_team": "49ers",
51
+ "preferred_channels": ["YouTube", "Twitter"]
52
+ }
53
+ ```
54
+
55
+ ### 1. Team Search
56
+ - **Description:** Natural language queries about team history, season recaps, outlooks, and trending stories.
57
+ - **Data Source:** Preloaded Neo4j graph database (no external SERP/API)
58
+ - **Display:** Dynamic Gradio widget layout with text + media (image, video preview)
59
+ - **Examples:**
60
+ - "Tell me about the 49ers"
61
+ - "How did they do in the offseason?"
62
+ - "Are they going to be good this year?"
63
+ - **Priority:** High
64
+
65
+ ### 2. Player Search
66
+ - **Description:** Player-specific queries, from basic info to advanced game-by-game stat breakdowns.
67
+ - **Data Source:** Preloaded Neo4j
68
+ - **Display:** Profile image + stat preview components
69
+ - **Examples:**
70
+ - "Who is the starting QB?"
71
+ - "What was Deebo Samuel's best game?"
72
+ - "How accurate is Brock Purdy's deep ball?"
73
+ - **Priority:** High
74
+
75
+ ### 3. Game Search
76
+ - **Description:** Game-level summaries and key moments/highlights.
77
+ - **Data Source:** Preloaded Neo4j
78
+ - **Display:** Recap text block + embedded image or video preview
79
+ - **Examples:**
80
+ - "How did the 49ers do vs Dolphins?"
81
+ - "What was the key play in the Seahawks loss?"
82
+ - **Priority:** High
83
+
84
+ ### 4. Fan Community Search
85
+ - **Description:** Allows users to find fan communities in a given location.
86
+ - **Data Source:** Neo4j (chapter name, location, contact info)
87
+ - **Input:** Location (e.g. city/state)
88
+ - **Output:** Community info cards
89
+ - **Examples:**
90
+ - "Are there any 49ers fan groups in Iowa?"
91
+ - **Priority:** Medium
92
+
93
+ ### 5. Rule Search (Deferred)
94
+ - **Description:** Future use of RAG or LLMs to answer football rules queries.
95
+ - **Status:** Deferred from MVP
96
+
97
+ ## 4. Technical Stack & Constraints
98
+
99
+ ### Frontend:
100
+ - Gradio (Python)
101
+ - Responsive, widget-based layout for chat and dynamic components
102
+ - Designed to be portable to other frameworks after POC
103
+
104
+ ### Backend:
105
+ - Modular microservices using MCP (Model Context Protocol)
106
+ - Each feature (team, player, game, fan) is its own callable service module
107
+ - Stateless with Zep memory injected as needed
108
+
109
+ ### Memory:
110
+ - Zep memory management using persona_id
111
+ - Memory updates per session stored but without historical user data in MVP
112
+
113
+ ### Database:
114
+ - Neo4j for all structured data:
115
+ - Teams
116
+ - Players
117
+ - Games
118
+ - Fan communities
119
+
120
+ ### Hosting:
121
+ - Hugging Face Spaces (initial deployment)
122
+
123
+ ### Constraints:
124
+ - No social logins or dynamic user accounts (MVP only)
125
+ - All personalization is based on preselected personas
126
+ - AI must not hallucinate or create false summaries — must stick to data in graph or defined assets
127
+
128
+ ## 5. App Architecture & Workflow
129
+
130
+ ```mermaid
131
+ flowchart TD
132
+ A[Select Persona] --> B[Load Zep Persona Memory]
133
+ B --> C[User Query (Text Input)]
134
+ C --> D[Classify Intent (Team/Player/Game/Fan)]
135
+ D --> E[Call MCP Service]
136
+ E --> F[Retrieve from Neo4j]
137
+ F --> G[Render Output in Gradio]
138
+ G --> H[Update Zep Memory]
139
+ ```
140
+
141
+ ## 6. Deployment & Testing
142
+
143
+ ### Deployment:
144
+ - Code managed via GitHub
145
+ - Hugging Face Spaces deployment using standard YAML metadata
146
+ - All assets and dependencies pinned in requirements.txt
147
+
148
+ ### Testing Strategy:
149
+
150
+ | Layer | Tool / Approach | Goal |
151
+ |-------|----------------|------|
152
+ | Service Layer | pytest unit tests | Validate correct behavior of each MCP service (team_service, player_service, etc.) |
153
+ | Graph Queries | Neo4j test container or schema mocks | Ensure Cypher queries return structured data as expected |
154
+ | Gradio UI | Manual session testing per persona | Simulate key user journeys across personas |
155
+ | Memory System | Mocked Zep client in pytest | Ensure persona selection creates correct memory structure |
156
+ | Integration | Persona-based E2E tests (manual) | Confirm chat-to-output loop works as designed for each use case |
157
+
158
+ ## 7. Design System (49ers Themed)
159
+
160
+ ### Color Palette:
161
+ - Primary Red: #AA0000
162
+ - Gold Accent: #B3995D
163
+ - Shadow Black: #111111
164
+ - Cool Gray: #E6E6E6
165
+ - White: #FFFFFF
166
+
167
+ ### Typography:
168
+ - Headlines: "Impact," sans-serif (or similar bold typeface)
169
+ - Body: "Open Sans," sans-serif
170
+
171
+ ### Sample CSS (for embedding in Gradio app):
172
+
173
+ ```css
174
+ body {
175
+ font-family: 'Open Sans', sans-serif;
176
+ background-color: #111111;
177
+ color: #E6E6E6;
178
+ }
179
+
180
+ h1, h2 {
181
+ font-family: 'Impact', sans-serif;
182
+ color: #AA0000;
183
+ }
184
+
185
+ button {
186
+ background-color: #B3995D;
187
+ color: #111111;
188
+ border-radius: 8px;
189
+ padding: 8px 16px;
190
+ border: none;
191
+ }
192
+ ```
193
+
194
+ ## 8. Component Library – Gradio Components for Reuse
195
+
196
+ | Component Name | Description | Gradio Element(s) |
197
+ |----------------|-------------|-------------------|
198
+ | Persona Selector | Three fan-type buttons (novice/intermediate/super fan). | gr.Row, gr.Button |
199
+ | Chat Window | Textbox for user query + LLM response. | gr.Textbox, gr.Markdown |
200
+ | Team Summary Card | Team logo, summary, record, etc. | gr.Image, gr.Markdown, gr.Row |
201
+ | Player Stat Card | Player image, name, key stats. | gr.Column, gr.Image, gr.Text |
202
+ | Game Recap Card | Score, highlight clip, key play. | gr.Row, gr.Image or gr.Video |
203
+ | Fan Group Finder | Location input + search results. | gr.Textbox, gr.Dataframe or gr.Accordion |
204
+
205
+ All components:
206
+ - Must be responsive
207
+ - Use the 49ers-themed CSS above
208
+ - Allow easy import from a components/ folder in the codebase
209
+
210
+ ## 9. Open Items / Next Steps
211
+
212
+ | Topic | Action |
213
+ |-------|--------|
214
+ | Personas | Finalize attributes for each of the 3 fan levels |
215
+ | Graph Schema | Reupload graph schema including links to media |
216
+ | Data Ingestion | Download team logo files + download game recaps |
217
+ | Component Dev | Build/test each Gradio component independently |
218
+ | Deployment | Set up GitHub+HF Spaces config for clean deployment cycle |
219
+ | CSS | Embed or reference the custom stylesheet for theme |
220
+
221
+ ## 10. Detailed Work Plan
222
+
223
+ Based on a review of the existing codebase and requirements, here's a structured implementation plan:
224
+
225
+ ### Phase 1: Foundation (April 14 - 25)
226
+
227
+ | Task | Description | Dependencies |
228
+ |------|-------------|--------------|
229
+ | **1.1 Complete data ingestion of team thumbnail images** | Download and integrate team logo files into the database | None |
230
+ | **1.1 data extracted on 4.13 ✅** |
231
+ | **1.2 Build and test gradio components locally** | Create components using CSV files instead of Neo4j, including multimedia integration | 1.1 |
232
+ | **1.3 Develop memory system and UI integration with Zep** | Implement persona-based memory system with Zep | None |
233
+
234
+ **Demo 1 Milestone:** April 22
235
+
236
+ ### Phase 2: Core Integration (April 28 - May 9)
237
+
238
+ | Task | Description | Dependencies |
239
+ |------|-------------|--------------|
240
+ | **2.1 Rebuild graph with full asset integration** | Develop and test low-latency approach for media assets | 1.1 |
241
+ | **2.2 Refactor ALL OF THE SERVICES** | Update services using updated graph and gradio UI integration | 1.2, 2.1 |
242
+
243
+ **Demo 2 Milestone:** May 6
244
+
245
+ ### Phase 3: Enhancement & Refinement (May 12 - May 23)
246
+
247
+ | Task | Description | Dependencies |
248
+ |------|-------------|--------------|
249
+ | **3.1 Cloud deployment to Hugging Face spaces** | Set up and configure deployment environment | 2.1, 2.2 |
250
+ | **3.2 Testing the tuning through FreePlay.AI** | Validate AI responses and performance | 3.1 |
251
+ | **3.3 Fine tuning responses between personality types and fan skill levels** | Customize responses based on persona | 1.3, 3.1 |
252
+ | **3.4 Refining precision of game recap search** | Improve search accuracy and relevance | 2.1, 2.2 |
253
+
254
+ **Demo 3 Milestone:** May 20
255
+
256
+ ### Phase 4: Final Launch (May 26 - 29)
257
+
258
+ | Task | Description | Dependencies |
259
+ |------|-------------|--------------|
260
+ | **4.1 Final testing and adjustments** | Address any remaining issues | 3.1, 3.2, 3.3, 3.4 |
261
+ | **4.2 Documentation and handoff** | Complete all documentation | 4.1 |
262
+
263
+ **FINAL GO LIVE:** May 29
264
+
265
+ ## Implementation Details
266
+
267
+ ### Technical Implementation Notes
268
+
269
+ 1. **Gradio Migration**
270
+ - Update existing `gradio_app.py` to support all required components
271
+ - Refactor `gradio_utils.py` to handle persona-based memory
272
+
273
+ 2. **Neo4j Schema Enhancements**
274
+ - Add media links to Player nodes (images, videos)
275
+ - Ensure Game nodes have highlight video links
276
+ - Add team-level properties for team info/history
277
+ - Reupload graph schema including links to media
278
+
279
+ 3. **Persona System**
280
+ - Create `persona.py` module with persona definitions and selection logic
281
+ - Enhance Zep integration to store persona context
282
+ - Develop memory system and UI integration with Zep (Phase 1)
283
+
284
+ 4. **MCP Services**
285
+ - Create `services/` directory with modules for each domain:
286
+ - `team_service.py`
287
+ - `player_service.py`
288
+ - `game_service.py`
289
+ - `community_service.py`
290
+ - Implement service registry and routing in `service_router.py`
291
+ - Refactor all services using updated graph and gradio UI integration (Phase 2)
292
+
293
+ 5. **UI Components**
294
+ - Create `components/` directory with reusable components:
295
+ - `persona_selector.py`
296
+ - `team_card.py`
297
+ - `player_card.py`
298
+ - `game_recap.py`
299
+ - `community_finder.py`
300
+ - Build and test gradio components locally using CSV files (Phase 1)
301
+
302
+ 6. **CSS Implementation**
303
+ - Create `static/styles.css` with 49ers theming
304
+ - Integrate with Gradio using custom CSS parameter
305
+
306
+ 7. **Data Integration**
307
+ - Complete data ingestion of team thumbnail images (Phase 1)
308
+ - Download game recaps (Phase 1)
309
+ - Rebuild graph with full asset integration (Phase 2)
310
+
311
+ 8. **Deployment & Testing**
312
+ - Cloud deployment to Hugging Face spaces (Phase 3)
313
+ - Testing the tuning through FreePlay.AI (Phase 3)
314
+ - Fine tuning responses between personality types and fan skill levels (Phase 3)
315
+ - Refining precision of game recap search (Phase 3)
316
+ - Final testing and adjustments (Phase 4)
317
+ - FINAL GO LIVE on May 29
318
+
319
+ ### Feature Gap Analysis
320
+
321
+ | Feature | Current Status | Work Needed |
322
+ |---------|---------------|-------------|
323
+ | Basic Chat | Implemented | Enhance with persona awareness |
324
+ | Neo4j Integration | Implemented | Add media fields to schema |
325
+ | Zep Memory | Basic implementation | Add persona structure |
326
+ | Gradio UI | Basic implementation | Add themed components |
327
+ | Persona Selection | Not implemented | Create from scratch |
328
+ | Media Components | Not implemented | Create from scratch |
329
+ | Service Architecture | Not implemented | Refactor into MCP services |
330
+ | Intent Classification | Basic implementation | Enhance with persona context |
331
+
332
+ ### Resource Requirements
333
+
334
+ 1. **Development Environment**
335
+ - Python 3.9+
336
+ - Neo4j database (access to update schema)
337
+ - OpenAI API key
338
+ - Zep account for memory management
339
+
340
+ 2. **Assets Needed**
341
+ - 49ers team imagery
342
+ - Player headshots
343
+ - Game highlight clips/thumbnails
344
+ - Custom CSS for theming
345
+
346
+ 3. **External Services**
347
+ - Hugging Face Spaces for deployment
348
+ - (Optional) Content hosting for media assets
349
+
350
+ ### Risk Management
351
+
352
+ | Risk | Mitigation Strategy |
353
+ |------|---------------------|
354
+ | Neo4j data completeness | Conduct audit of required fields before implementation |
355
+ | Media asset availability | Create fallback text-only components if media is unavailable |
356
+ | Persona complexity | Start with simplified personas, then enhance |
357
+ | Deployment constraints | Test with Hugging Face resource limits early |
358
+ | Memory persistence | Implement simple local fallback if Zep has issues |
359
+
360
+ ## 11. Feature Work Log
361
+
362
+ ### Step 1.2: Team Search Feature Implementation
363
+
364
+ #### Objective
365
+ Implement the Team Search feature (Feature 1 from Feature Overview) with focus on game recap display functionality.
366
+
367
+ #### Prerequisites
368
+ - Access to `schedule_with_result_april_11.csv`
369
+ - Access to `nfl_team_logos_revised.csv`
370
+ - Reference to `game recap layout example.png`
371
+ - Gradio app instance
372
+ - Neo4j database instance
373
+
374
+ #### Implementation Steps
375
+
376
+ 1. **CSS Integration**
377
+ - Add required CSS styles to the Gradio app
378
+ - Ensure styles support responsive layout
379
+ - Implement 49ers theme colors from Design System section
380
+
381
+ 2. **Data Requirements Enhancement**
382
+ - Review existing game score & result data
383
+ - Identify home team name and logo source
384
+ - Identify away team name and logo source
385
+ - Document data structure requirements
386
+
387
+ 3. **CSV File Update**
388
+ - Open `schedule_with_result_april_11.csv`
389
+ - Add columns for home team logo
390
+ - Add columns for away team logo
391
+ - Merge data from `nfl_team_logos_revised.csv`
392
+ - Validate data integrity
393
+ - Save as new version
394
+
395
+ 4. **Static Gradio Component Development**
396
+ - Create new component file
397
+ - Implement layout matching `game recap layout example.png`:
398
+ - Top row: away team elements
399
+ - Bottom row: home team elements
400
+ - Score display with winning team highlight
401
+ - Video preview box
402
+ - Use static assets for 49ers first game
403
+ - Implement responsive design
404
+
405
+ 5. **Component Testing**
406
+ - Add component as first element in Gradio app
407
+ - Test CSV data integration
408
+ - Verify static display
409
+ - Document any display issues
410
+
411
+ 6. **Function-Calling Implementation**
412
+ - Prepare Neo4j merge operations
413
+ - Update graph with new game data
414
+ - Preserve existing nodes
415
+ - Add new attributes
416
+ - Test data integrity
417
+
418
+ 7. **LangChain Integration**
419
+ - Adapt graph search function
420
+ - Implement game-specific search
421
+ - Test attribute retrieval
422
+ - Verify data flow to Gradio component
423
+
424
+ 8. **Final Deployment**
425
+ - Deploy to Gradio
426
+ - Perform final UI checks
427
+ - Verify data accuracy
428
+ - Document any issues
429
+
430
+ #### Failure Conditions
431
+ - Halt process if any step fails after 3 attempts
432
+ - Document failure point and reason
433
+ - Consult with user for guidance
434
+ - Do not proceed without resolution
435
+
436
+ #### Success Criteria
437
+ - Component displays correctly in Gradio
438
+ - Data flows accurately from CSV to display
439
+ - Graph integration works without data loss
440
+ - LangChain search returns correct game data
441
+ - UI matches design specifications
442
+
443
+ #### Notes
444
+ - Maintain existing Neo4j node structure
445
+ - Preserve all current functionality
446
+ - Document all changes for future reference
447
+ - Test thoroughly before proceeding to next phase
requirements.txt CHANGED
@@ -6,7 +6,6 @@ langchain-neo4j>=0.1.1
6
  openai>=1.2.0
7
  neo4j>=5.14.0
8
  python-dotenv>=1.0.0
9
- uuid>=1.30
10
  zep-cloud>=0.1.0
11
  asyncio>=3.4.3
12
  pandas>=2.0.0
 
6
  openai>=1.2.0
7
  neo4j>=5.14.0
8
  python-dotenv>=1.0.0
 
9
  zep-cloud>=0.1.0
10
  asyncio>=3.4.3
11
  pandas>=2.0.0