Spaces:
Runtime error
Runtime error
| import json | |
| from datetime import datetime | |
| import re | |
| class ProfileDataProvider: | |
| """Tillhandahåller riktig profildata för sommarpratare""" | |
| def __init__(self, data_file, image_matcher): | |
| self.data_file = data_file | |
| self.image_matcher = image_matcher | |
| self.episodes = [] | |
| self._load_data() | |
| def _load_data(self): | |
| """Ladda episoddata""" | |
| try: | |
| with open(self.data_file, 'r', encoding='utf-8') as f: | |
| self.episodes = json.load(f) | |
| except Exception as e: | |
| print(f"Fel vid laddning av profildata: {e}") | |
| self.episodes = [] | |
| def get_profile_data(self, name, year=None): | |
| """Hämta komplett profildata för en person""" | |
| # Hitta alla episoder för denna person | |
| matching_episodes = [] | |
| for episode in self.episodes: | |
| episode_title = episode.get('episode_title', '') | |
| if self._names_match(name, episode_title): | |
| matching_episodes.append(episode) | |
| if not matching_episodes: | |
| return None | |
| # Välj rätt episod baserat på år om angivet | |
| selected_episode = self._select_best_episode(matching_episodes, year) | |
| # Hämta matchande bilder | |
| images = [] | |
| if self.image_matcher: | |
| images = self.image_matcher.find_images_for_episode(selected_episode) | |
| # Bygg profildata | |
| profile = { | |
| 'name': name, | |
| 'year': year, | |
| 'episodes': matching_episodes, | |
| 'selected_episode': selected_episode, | |
| 'images': images, | |
| 'stats': self._calculate_person_stats(matching_episodes), | |
| 'biography': self._generate_biography(name, matching_episodes), | |
| 'career_span': self._get_career_span(matching_episodes) | |
| } | |
| return profile | |
| def _select_best_episode(self, episodes, target_year): | |
| """Välj bästa episod baserat på år""" | |
| if not episodes: | |
| return None | |
| if not target_year: | |
| # Returnera senaste episoden | |
| return max(episodes, key=lambda ep: ep.get('episode_date', '')) | |
| # Hitta episod närmast målåret | |
| target_year = int(target_year) | |
| best_episode = episodes[0] | |
| min_diff = float('inf') | |
| for episode in episodes: | |
| date_str = episode.get('episode_date', '') | |
| if date_str: | |
| try: | |
| ep_year = int(date_str.split('-')[0]) | |
| diff = abs(ep_year - target_year) | |
| if diff < min_diff: | |
| min_diff = diff | |
| best_episode = episode | |
| except: | |
| continue | |
| return best_episode | |
| def _names_match(self, name1, name2): | |
| """Kontrollera om två namn matchar""" | |
| if not name1 or not name2: | |
| return False | |
| # Normalisera namn | |
| norm1 = self._normalize_name(name1) | |
| norm2 = self._normalize_name(name2) | |
| # Exakt matchning | |
| if norm1 == norm2: | |
| return True | |
| # Kontrollera om det ena namnet innehåller det andra | |
| if norm1 in norm2 or norm2 in norm1: | |
| return True | |
| # Kontrollera för- och efternamn | |
| parts1 = norm1.split() | |
| parts2 = norm2.split() | |
| if len(parts1) >= 2 and len(parts2) >= 2: | |
| # Jämför förnamn och efternamn | |
| if parts1[0] == parts2[0] and parts1[-1] == parts2[-1]: | |
| return True | |
| return False | |
| def _normalize_name(self, name): | |
| """Normalisera namn för jämförelse""" | |
| # Ta bort extra tecken och gör lowercase | |
| normalized = re.sub(r'[^\w\s]', '', name.lower()) | |
| # Ta bort extra whitespace | |
| normalized = re.sub(r'\s+', ' ', normalized).strip() | |
| return normalized | |
| def _calculate_person_stats(self, episodes): | |
| """Beräkna statistik för en person""" | |
| if not episodes: | |
| return {'episodes': 0, 'songs': 0, 'years_active': 0} | |
| total_songs = sum(len(ep.get('songs', [])) for ep in episodes) | |
| # Beräkna aktiva år | |
| years = [] | |
| for episode in episodes: | |
| date_str = episode.get('episode_date', '') | |
| if date_str: | |
| try: | |
| year = int(date_str.split('-')[0]) | |
| years.append(year) | |
| except: | |
| continue | |
| years_active = max(years) - min(years) + 1 if years else 0 | |
| return { | |
| 'episodes': len(episodes), | |
| 'songs': total_songs, | |
| 'years_active': years_active, | |
| 'first_year': min(years) if years else None, | |
| 'last_year': max(years) if years else None | |
| } | |
| def _generate_biography(self, name, episodes): | |
| """Generera en kort biografi baserat på episoddata""" | |
| if not episodes: | |
| return f"{name} är en svensk kulturpersonlighet som har delat sina berättelser i Sommar i P1." | |
| stats = self._calculate_person_stats(episodes) | |
| bio_parts = [f"{name} har varit sommarpratare i Sveriges Radio"] | |
| if stats['episodes'] > 1: | |
| bio_parts.append(f"vid {stats['episodes']} tillfällen") | |
| if stats['first_year'] and stats['last_year']: | |
| if stats['first_year'] == stats['last_year']: | |
| bio_parts.append(f"år {stats['first_year']}") | |
| else: | |
| bio_parts.append(f"mellan {stats['first_year']} och {stats['last_year']}") | |
| bio = " ".join(bio_parts) + "." | |
| # Lägg till information om musikval | |
| if stats['songs'] > 0: | |
| bio += f" Genom {stats['songs']} låtar har {name.split()[0]} delat sin musiksmak och sina minnen med svenska lyssnare." | |
| # Lägg till reflektion om betydelse | |
| if stats['episodes'] > 2: | |
| bio += f" Som återkommande sommarpratare har {name.split()[0]} blivit en viktig röst i programmet och format många svenska sommrar." | |
| return bio | |
| def _get_career_span(self, episodes): | |
| """Få karriärspann för personen""" | |
| if not episodes: | |
| return None | |
| years = [] | |
| for episode in episodes: | |
| date_str = episode.get('episode_date', '') | |
| if date_str: | |
| try: | |
| year = int(date_str.split('-')[0]) | |
| years.append(year) | |
| except: | |
| continue | |
| if not years: | |
| return None | |
| return { | |
| 'start': min(years), | |
| 'end': max(years), | |
| 'span': max(years) - min(years) + 1 | |
| } | |
| def get_all_profiles_summary(self): | |
| """Få sammanfattning av alla profiler""" | |
| people = {} | |
| for episode in self.episodes: | |
| name = episode.get('episode_title', '').strip() | |
| if name: | |
| if name not in people: | |
| people[name] = [] | |
| people[name].append(episode) | |
| summary = { | |
| 'total_people': len(people), | |
| 'multiple_episodes': sum(1 for eps in people.values() if len(eps) > 1), | |
| 'most_episodes': max((len(eps) for eps in people.values()), default=0), | |
| 'people_by_decade': self._group_by_decade(people) | |
| } | |
| return summary | |
| def _group_by_decade(self, people): | |
| """Gruppera personer efter årtionde""" | |
| decades = {} | |
| for name, episodes in people.items(): | |
| for episode in episodes: | |
| date_str = episode.get('episode_date', '') | |
| if date_str: | |
| try: | |
| year = int(date_str.split('-')[0]) | |
| decade = f"{year//10*10}s" | |
| if decade not in decades: | |
| decades[decade] = set() | |
| decades[decade].add(name) | |
| except: | |
| continue | |
| # Konvertera sets till counts | |
| return {decade: len(names) for decade, names in decades.items()} | |
| def create_profile_provider(): | |
| """Skapa och returnera en ProfileDataProvider instans""" | |
| data_file = '/Users/isakskogstad/Desktop/p1_sommar_space/hf_sommar_space/data.json' | |
| try: | |
| from image_matcher import SommarImageMatcher | |
| image_matcher = SommarImageMatcher('images', data_file) | |
| except: | |
| image_matcher = None | |
| return ProfileDataProvider(data_file, image_matcher) | |
| if __name__ == "__main__": | |
| # Test funktionaliteten | |
| provider = create_profile_provider() | |
| # Testa med en känd sommarpratare | |
| profile = provider.get_profile_data("Jonas Gardell", "1992") | |
| if profile: | |
| print(f"Profil för {profile['name']}:") | |
| print(f"Episoder: {profile['stats']['episodes']}") | |
| print(f"Låtar: {profile['stats']['songs']}") | |
| print(f"Biografi: {profile['biography']}") | |
| else: | |
| print("Ingen profil hittad") | |
| # Visa sammanfattning | |
| summary = provider.get_all_profiles_summary() | |
| print(f"\nSammanfattning:") | |
| print(f"Totalt antal personer: {summary['total_people']}") | |
| print(f"Personer med flera episoder: {summary['multiple_episodes']}") | |
| print(f"Mest episoder: {summary['most_episodes']}") |