84 lines
2.5 KiB
Go
84 lines
2.5 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
func (app *UIApp) handleRecommendations(writer http.ResponseWriter, request *http.Request) {
|
|
writer.Header().Set("Cache-Control", "no-store")
|
|
if request.Method != http.MethodPost {
|
|
writeJSON(writer, http.StatusMethodNotAllowed, map[string]string{"error": "method not allowed"})
|
|
return
|
|
}
|
|
var query hongguoRecommendationQuery
|
|
decoder := json.NewDecoder(http.MaxBytesReader(writer, request.Body, 32768))
|
|
if decoder.Decode(&query) != nil || decoder.Decode(new(any)) != io.EOF || query.validate() != nil {
|
|
writeJSON(writer, http.StatusBadRequest, map[string]string{"error": "推荐分类或分页参数无效,请重新获取"})
|
|
return
|
|
}
|
|
if !requireSource(writer, request.Context(), sourceHongguo) {
|
|
return
|
|
}
|
|
ctx, cancel := context.WithTimeout(request.Context(), 45*time.Second)
|
|
defer cancel()
|
|
result, err := app.downloader.fetchHongguoRecommendations(ctx, query)
|
|
if request.Context().Err() != nil {
|
|
return
|
|
}
|
|
if err != nil {
|
|
fmt.Printf("红果分类推荐读取失败: %v\n", publicError(err))
|
|
writeJSON(writer, http.StatusBadGateway, map[string]string{"error": "推荐暂不可用,已保留当前内容,可重试或重新获取"})
|
|
return
|
|
}
|
|
result.Dramas = app.mergeRecommendedDramas(result.Dramas)
|
|
app.mu.Lock()
|
|
result.Saved = app.librarySaved && !app.libraryDirty
|
|
app.mu.Unlock()
|
|
writeJSON(writer, http.StatusOK, result)
|
|
}
|
|
|
|
func (app *UIApp) mergeRecommendedDramas(items []Drama) []Drama {
|
|
dramas := append([]Drama{}, items...)
|
|
if len(dramas) == 0 {
|
|
return dramas
|
|
}
|
|
positions := make(map[string]int, len(dramas))
|
|
for index, drama := range dramas {
|
|
positions[drama.ID] = index
|
|
}
|
|
app.mu.Lock()
|
|
app.normalizeDramaCovers(dramas)
|
|
newDramas := app.newSortMetadataDramasLocked(dramas)
|
|
app.dramas = mergeSourceDramas(app.dramas, dramas, nil, sourceHongguo)
|
|
app.enqueueSortMetadataLocked(newDramas, false)
|
|
app.loadedAt = time.Now()
|
|
if app.librarySources == nil {
|
|
app.librarySources = map[string]librarySourceState{}
|
|
}
|
|
state := app.librarySources[sourceHongguo]
|
|
state.Count = 0
|
|
for _, drama := range app.dramas {
|
|
if dramaProvider(drama) == sourceHongguo {
|
|
state.Count++
|
|
}
|
|
if index, found := positions[drama.ID]; found {
|
|
dramas[index] = drama
|
|
}
|
|
}
|
|
state.UpdatedAt = app.loadedAt
|
|
if state.Status == "" {
|
|
state.Status = "ready"
|
|
}
|
|
app.librarySources[sourceHongguo] = state
|
|
app.libraryDirty = true
|
|
app.libraryRevision++
|
|
app.mu.Unlock()
|
|
app.persistLibrary()
|
|
return dramas
|
|
}
|