/
aggregate.go
81 lines (69 loc) · 1.83 KB
/
aggregate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package indexer
import (
"errors"
"io"
"net/http"
"github.com/cardigann/cardigann/logger"
"github.com/cardigann/cardigann/torznab"
"golang.org/x/sync/errgroup"
)
type Aggregate []torznab.Indexer
func (ag Aggregate) Search(query torznab.Query) ([]torznab.ResultItem, error) {
g := errgroup.Group{}
allResults := make([][]torznab.ResultItem, len(ag))
maxLength := 0
// fetch all results
for idx, indexer := range ag {
indexerID := indexer.Info().ID
idx, indexer := idx, indexer
g.Go(func() error {
result, err := indexer.Search(query)
if err != nil {
logger.Logger.Warnf("Indexer %q failed: %s", indexerID, err)
return nil
}
allResults[idx] = result
if l := len(result); l > maxLength {
maxLength = l
}
return nil
})
}
if err := g.Wait(); err != nil {
logger.Logger.Warn(err)
return nil, err
}
results := []torznab.ResultItem{}
// interleave search results to preserve ordering
for i := 0; i <= maxLength; i++ {
for _, r := range allResults {
if len(r) > i {
results = append(results, r[i])
}
}
}
if query.Limit > 0 && len(results) > query.Limit {
results = results[:query.Limit]
}
return results, nil
}
func (ag Aggregate) Info() torznab.Info {
return torznab.Info{
ID: "aggregate",
Title: "Aggregated Indexer",
Language: "en-US",
Link: "",
}
}
func (ag Aggregate) Capabilities() torznab.Capabilities {
return torznab.Capabilities{
SearchModes: []torznab.SearchMode{
{Key: "movie-search", Available: true, SupportedParams: []string{"q", "imdbid"}},
{Key: "tv-search", Available: true, SupportedParams: []string{"q", "season", "ep"}},
{Key: "search", Available: true, SupportedParams: []string{"q"}},
},
}
}
func (ag Aggregate) Download(u string) (io.ReadCloser, http.Header, error) {
return nil, http.Header{}, errors.New("Not implemented")
}