package tpdb import ( "context" "encoding/json" "fmt" "net/url" "git.leaktechnologies.dev/stu/Goondex/internal/model" ) // Scraper implements the scraper.Scraper interface for TPDB type Scraper struct { client *Client } // NewScraper creates a new TPDB scraper func NewScraper(baseURL, apiKey string) *Scraper { return &Scraper{ client: NewClient(baseURL, apiKey), } } // Name returns the scraper's unique identifier func (s *Scraper) Name() string { return "tpdb" } // SearchPerformers searches for performers by query string func (s *Scraper) SearchPerformers(ctx context.Context, query string) ([]model.Performer, error) { params := url.Values{} params.Set("q", query) body, err := s.client.get(ctx, "/performers", params) if err != nil { return nil, fmt.Errorf("failed to search performers: %w", err) } var apiResp APIResponse if err := json.Unmarshal(body, &apiResp); err != nil { return nil, fmt.Errorf("failed to parse response: %w", err) } var tpdbPerformers []PerformerResponse if err := json.Unmarshal(apiResp.Data, &tpdbPerformers); err != nil { return nil, fmt.Errorf("failed to parse performers: %w", err) } performers := make([]model.Performer, 0, len(tpdbPerformers)) for _, p := range tpdbPerformers { performers = append(performers, mapPerformer(p)) } return performers, nil } // SearchStudios searches for studios by query string func (s *Scraper) SearchStudios(ctx context.Context, query string) ([]model.Studio, error) { params := url.Values{} params.Set("q", query) body, err := s.client.get(ctx, "/sites", params) if err != nil { return nil, fmt.Errorf("failed to search studios: %w", err) } var apiResp APIResponse if err := json.Unmarshal(body, &apiResp); err != nil { return nil, fmt.Errorf("failed to parse response: %w", err) } var tpdbStudios []StudioResponse if err := json.Unmarshal(apiResp.Data, &tpdbStudios); err != nil { return nil, fmt.Errorf("failed to parse studios: %w", err) } studios := make([]model.Studio, 0, len(tpdbStudios)) for _, st := range tpdbStudios { studios = append(studios, mapStudio(st)) } return studios, nil } // SearchScenes searches for scenes by query string func (s *Scraper) SearchScenes(ctx context.Context, query string) ([]model.Scene, error) { params := url.Values{} params.Set("q", query) body, err := s.client.get(ctx, "/scenes", params) if err != nil { return nil, fmt.Errorf("failed to search scenes: %w", err) } var apiResp APIResponse if err := json.Unmarshal(body, &apiResp); err != nil { return nil, fmt.Errorf("failed to parse response: %w", err) } var tpdbScenes []SceneResponse if err := json.Unmarshal(apiResp.Data, &tpdbScenes); err != nil { return nil, fmt.Errorf("failed to parse scenes: %w", err) } scenes := make([]model.Scene, 0, len(tpdbScenes)) for _, sc := range tpdbScenes { scenes = append(scenes, mapScene(sc)) } return scenes, nil } // GetSceneByID retrieves a scene by its remote ID func (s *Scraper) GetSceneByID(ctx context.Context, remoteID string) (*model.Scene, error) { body, err := s.client.get(ctx, "/scenes/"+remoteID, nil) if err != nil { return nil, fmt.Errorf("failed to get scene: %w", err) } var apiResp APIResponse if err := json.Unmarshal(body, &apiResp); err != nil { return nil, fmt.Errorf("failed to parse response: %w", err) } var tpdbScene SceneResponse if err := json.Unmarshal(apiResp.Data, &tpdbScene); err != nil { return nil, fmt.Errorf("failed to parse scene: %w", err) } scene := mapScene(tpdbScene) return &scene, nil } // GetPerformerByID retrieves a performer by its remote ID func (s *Scraper) GetPerformerByID(ctx context.Context, remoteID string) (*model.Performer, error) { body, err := s.client.get(ctx, "/performers/"+remoteID, nil) if err != nil { return nil, fmt.Errorf("failed to get performer: %w", err) } var apiResp APIResponse if err := json.Unmarshal(body, &apiResp); err != nil { return nil, fmt.Errorf("failed to parse response: %w", err) } var tpdbPerformer PerformerResponse if err := json.Unmarshal(apiResp.Data, &tpdbPerformer); err != nil { return nil, fmt.Errorf("failed to parse performer: %w", err) } performer := mapPerformer(tpdbPerformer) return &performer, nil } // GetStudioByID retrieves a studio by its remote ID func (s *Scraper) GetStudioByID(ctx context.Context, remoteID string) (*model.Studio, error) { body, err := s.client.get(ctx, "/sites/"+remoteID, nil) if err != nil { return nil, fmt.Errorf("failed to get studio: %w", err) } var apiResp APIResponse if err := json.Unmarshal(body, &apiResp); err != nil { return nil, fmt.Errorf("failed to parse response: %w", err) } var tpdbStudio StudioResponse if err := json.Unmarshal(apiResp.Data, &tpdbStudio); err != nil { return nil, fmt.Errorf("failed to parse studio: %w", err) } studio := mapStudio(tpdbStudio) return &studio, nil }