This commit is contained in:
+57
-5
@@ -248,7 +248,8 @@ func (a *App) runDownload(recordID int64, url, start, end, quality, outputPath s
|
||||
|
||||
func (a *App) searchMedia(c *gin.Context) {
|
||||
var req struct {
|
||||
Query string `json:"query"`
|
||||
Query string `json:"query"`
|
||||
Platforms []string `json:"platforms"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
@@ -265,8 +266,9 @@ func (a *App) searchMedia(c *gin.Context) {
|
||||
queryVariants = []string{req.Query}
|
||||
}
|
||||
|
||||
enabledPlatforms := normalizePlatforms(req.Platforms)
|
||||
a.Hub.Broadcast("progress", gin.H{"type": "search", "status": "searching Google Video, Envato, and Artgrid", "progress": 35})
|
||||
results, err := a.SearchService.SearchMedia(queryVariants)
|
||||
results, err := a.SearchService.SearchMedia(queryVariants, enabledPlatforms)
|
||||
if err != nil {
|
||||
a.Hub.Broadcast("progress", gin.H{"type": "search", "status": "search failed", "progress": 100, "message": err.Error()})
|
||||
c.JSON(http.StatusBadGateway, gin.H{"error": err.Error()})
|
||||
@@ -285,9 +287,12 @@ func (a *App) searchMedia(c *gin.Context) {
|
||||
rankQuery = strings.Join(queryVariants[:min(len(queryVariants), 3)], " ")
|
||||
}
|
||||
scored := rankSearchResults(rankQuery, results)
|
||||
shortlist := scored[:min(len(scored), 10)]
|
||||
a.Hub.Broadcast("progress", gin.H{"type": "search", "status": "analyzing shortlisted thumbnails with Gemini Vision", "progress": 75})
|
||||
recommended, err := a.GeminiService.Recommend(req.Query, shortlist)
|
||||
a.Hub.Broadcast("progress", gin.H{"type": "search", "status": "analyzing all candidate visuals with Gemini Vision", "progress": 75})
|
||||
recommended := evaluateAllCandidatesWithGemini(a.GeminiService, req.Query, scored)
|
||||
err = nil
|
||||
if len(recommended) == 0 {
|
||||
err = fmt.Errorf("gemini vision returned no recommended items across all candidate batches")
|
||||
}
|
||||
if err != nil {
|
||||
fallback := make([]services.AIRecommendation, 0, min(20, len(scored)))
|
||||
for _, result := range scored[:min(20, len(scored))] {
|
||||
@@ -345,6 +350,53 @@ func min(a, b int) int {
|
||||
return b
|
||||
}
|
||||
|
||||
func normalizePlatforms(platforms []string) map[string]bool {
|
||||
if len(platforms) == 0 {
|
||||
return map[string]bool{
|
||||
"envato": true,
|
||||
"artgrid": true,
|
||||
"google video": true,
|
||||
}
|
||||
}
|
||||
normalized := map[string]bool{}
|
||||
for _, item := range platforms {
|
||||
switch strings.ToLower(strings.TrimSpace(item)) {
|
||||
case "envato":
|
||||
normalized["envato"] = true
|
||||
case "artgrid":
|
||||
normalized["artgrid"] = true
|
||||
case "google video", "google_video", "google":
|
||||
normalized["google video"] = true
|
||||
}
|
||||
}
|
||||
return normalized
|
||||
}
|
||||
|
||||
func evaluateAllCandidatesWithGemini(service *services.GeminiService, query string, ranked []services.SearchResult) []services.AIRecommendation {
|
||||
const chunkSize = 8
|
||||
merged := make([]services.AIRecommendation, 0, len(ranked))
|
||||
seen := map[string]bool{}
|
||||
for start := 0; start < len(ranked); start += chunkSize {
|
||||
end := start + chunkSize
|
||||
if end > len(ranked) {
|
||||
end = len(ranked)
|
||||
}
|
||||
batch := ranked[start:end]
|
||||
recommended, err := service.Recommend(query, batch)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
for _, item := range recommended {
|
||||
if item.Link == "" || seen[item.Link] {
|
||||
continue
|
||||
}
|
||||
seen[item.Link] = true
|
||||
merged = append(merged, item)
|
||||
}
|
||||
}
|
||||
return merged
|
||||
}
|
||||
|
||||
func rankSearchResults(query string, results []services.SearchResult) []services.SearchResult {
|
||||
queryTerms := strings.Fields(strings.ToLower(query))
|
||||
positiveTerms := []string{
|
||||
|
||||
Reference in New Issue
Block a user