Phase 3: Integrate Google Takeout context into InsightGenerator
- Updated InsightGenerator struct with calendar, location, and search DAOs - Implemented hybrid context gathering methods: * gather_calendar_context(): ±7 days with semantic ranking * gather_location_context(): ±30 min with GPS proximity check * gather_search_context(): ±30 days semantic search - Added haversine_distance() utility for GPS calculations - Updated generate_insight_for_photo_with_model() to use multi-source context - Combined all context sources (SMS + Calendar + Location + Search) with equal weight - Initialized new DAOs in AppState (both default and test implementations) - All contexts are optional (graceful degradation if data missing) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
30
src/state.rs
30
src/state.rs
@@ -1,6 +1,8 @@
|
||||
use crate::ai::{InsightGenerator, OllamaClient, SmsApiClient};
|
||||
use crate::database::{
|
||||
DailySummaryDao, ExifDao, InsightDao, SqliteDailySummaryDao, SqliteExifDao, SqliteInsightDao,
|
||||
CalendarEventDao, DailySummaryDao, ExifDao, InsightDao, LocationHistoryDao, SearchHistoryDao,
|
||||
SqliteCalendarEventDao, SqliteDailySummaryDao, SqliteExifDao, SqliteInsightDao,
|
||||
SqliteLocationHistoryDao, SqliteSearchHistoryDao,
|
||||
};
|
||||
use crate::video::actors::{PlaylistGenerator, StreamActor, VideoPlaylistManager};
|
||||
use actix::{Actor, Addr};
|
||||
@@ -96,16 +98,27 @@ impl Default for AppState {
|
||||
let daily_summary_dao: Arc<Mutex<Box<dyn DailySummaryDao>>> =
|
||||
Arc::new(Mutex::new(Box::new(SqliteDailySummaryDao::new())));
|
||||
|
||||
// Initialize Google Takeout DAOs
|
||||
let calendar_dao: Arc<Mutex<Box<dyn CalendarEventDao>>> =
|
||||
Arc::new(Mutex::new(Box::new(SqliteCalendarEventDao::new())));
|
||||
let location_dao: Arc<Mutex<Box<dyn LocationHistoryDao>>> =
|
||||
Arc::new(Mutex::new(Box::new(SqliteLocationHistoryDao::new())));
|
||||
let search_dao: Arc<Mutex<Box<dyn SearchHistoryDao>>> =
|
||||
Arc::new(Mutex::new(Box::new(SqliteSearchHistoryDao::new())));
|
||||
|
||||
// Load base path
|
||||
let base_path = env::var("BASE_PATH").expect("BASE_PATH was not set in the env");
|
||||
|
||||
// Initialize InsightGenerator
|
||||
// Initialize InsightGenerator with all data sources
|
||||
let insight_generator = InsightGenerator::new(
|
||||
ollama.clone(),
|
||||
sms_client.clone(),
|
||||
insight_dao.clone(),
|
||||
exif_dao.clone(),
|
||||
daily_summary_dao.clone(),
|
||||
calendar_dao.clone(),
|
||||
location_dao.clone(),
|
||||
search_dao.clone(),
|
||||
base_path.clone(),
|
||||
);
|
||||
|
||||
@@ -155,7 +168,15 @@ impl AppState {
|
||||
let daily_summary_dao: Arc<Mutex<Box<dyn DailySummaryDao>>> =
|
||||
Arc::new(Mutex::new(Box::new(SqliteDailySummaryDao::new())));
|
||||
|
||||
// Initialize test InsightGenerator
|
||||
// Initialize test Google Takeout DAOs
|
||||
let calendar_dao: Arc<Mutex<Box<dyn CalendarEventDao>>> =
|
||||
Arc::new(Mutex::new(Box::new(SqliteCalendarEventDao::new())));
|
||||
let location_dao: Arc<Mutex<Box<dyn LocationHistoryDao>>> =
|
||||
Arc::new(Mutex::new(Box::new(SqliteLocationHistoryDao::new())));
|
||||
let search_dao: Arc<Mutex<Box<dyn SearchHistoryDao>>> =
|
||||
Arc::new(Mutex::new(Box::new(SqliteSearchHistoryDao::new())));
|
||||
|
||||
// Initialize test InsightGenerator with all data sources
|
||||
let base_path_str = base_path.to_string_lossy().to_string();
|
||||
let insight_generator = InsightGenerator::new(
|
||||
ollama.clone(),
|
||||
@@ -163,6 +184,9 @@ impl AppState {
|
||||
insight_dao.clone(),
|
||||
exif_dao.clone(),
|
||||
daily_summary_dao.clone(),
|
||||
calendar_dao.clone(),
|
||||
location_dao.clone(),
|
||||
search_dao.clone(),
|
||||
base_path_str.clone(),
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user