2019-04-22 02:59:20 +00:00

1481 lines
51 KiB
Go

package search
import (
"context"
"net/http"
"net/url"
"strconv"
"time"
"go-common/app/interface/main/app-interface/conf"
arcdao "go-common/app/interface/main/app-interface/dao/archive"
bangumidao "go-common/app/interface/main/app-interface/dao/bangumi"
livedao "go-common/app/interface/main/app-interface/dao/live"
"go-common/app/interface/main/app-interface/model"
bangumimdl "go-common/app/interface/main/app-interface/model/bangumi"
livemdl "go-common/app/interface/main/app-interface/model/live"
"go-common/app/interface/main/app-interface/model/search"
"go-common/app/service/main/archive/api"
locmdl "go-common/app/service/main/location/model"
locrpc "go-common/app/service/main/location/rpc/client"
seasongrpc "go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
"go-common/library/ecode"
"go-common/library/log"
httpx "go-common/library/net/http/blademaster"
"go-common/library/net/metadata"
"go-common/library/sync/errgroup"
"github.com/pkg/errors"
)
const (
_main = "/main/search"
_suggest = "/main/suggest"
_hot = "/main/hotword"
_defaultWords = "/widget/getSearchDefaultWords"
_rcmd = "/query/recommend"
_rcmdNoResult = "/search/recommend"
_suggest3 = "/main/suggest/new"
_pre = "/search/frontpage"
)
const (
_oldAndroid = 514000
_oldIOS = 6090
_searchCodeLimitAndroid = 5250001
_searchCodeLimitIPhone = 6680
)
// Dao is search dao
type Dao struct {
c *conf.Config
arcDao *arcdao.Dao
liveDao *livedao.Dao
bangumiDao *bangumidao.Dao
client *httpx.Client
client2 *httpx.Client
main string
suggest string
hot string
defaultWords string
rcmd string
rcmdNoResult string
suggest3 string
pre string
// rpc
locRPC *locrpc.Service
}
// New initial search dao
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
arcDao: arcdao.New(c),
liveDao: livedao.New(c),
bangumiDao: bangumidao.New(c),
client: httpx.NewClient(c.HTTPSearch),
client2: httpx.NewClient(c.HTTPClient),
main: c.Host.Search + _main,
suggest: c.Host.Search + _suggest,
hot: c.Host.Search + _hot,
defaultWords: c.Host.WWW + _defaultWords,
rcmd: c.Host.Search + _rcmd,
rcmdNoResult: c.Host.Search + _rcmdNoResult,
suggest3: c.Host.Search + _suggest3,
pre: c.Host.Search + _pre,
locRPC: locrpc.New(c.LocationRPC),
}
return
}
// Search app all search .
func (d *Dao) Search(c context.Context, mid, zoneid int64, mobiApp, device, platform, buvid, keyword, duration, order, filtered, fromSource, recommend, parent string, plat int8, seasonNum, movieNum, upUserNum, uvLimit, userNum, userVideoLimit, biliUserNum, biliUserVideoLimit, rid, highlight, build, pn, ps, isQuery int, old bool, now time.Time, newPGC, flow bool) (res *search.Search, code int, err error) {
var (
req *http.Request
ip = metadata.String(c, metadata.RemoteIP)
ipInfo *locmdl.Info
)
if ipInfo, err = d.locRPC.Info(c, &locmdl.ArgIP{IP: ip}); err != nil {
log.Warn("%v", err)
err = nil
}
res = &search.Search{}
params := url.Values{}
params.Set("build", strconv.Itoa(build))
params.Set("keyword", keyword)
params.Set("main_ver", "v3")
params.Set("highlight", strconv.Itoa(highlight))
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("tids", strconv.Itoa(rid))
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
if newPGC {
params.Set("media_bangumi_num", strconv.Itoa(seasonNum))
} else {
params.Set("bangumi_num", strconv.Itoa(seasonNum))
params.Set("smerge", "1")
}
if (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) {
params.Set("is_new_user", "1")
} else {
if old {
params.Set("upuser_num", strconv.Itoa(upUserNum))
params.Set("uv_limit", strconv.Itoa(uvLimit))
} else {
params.Set("bili_user_num", strconv.Itoa(biliUserNum))
params.Set("bili_user_vl", strconv.Itoa(biliUserVideoLimit))
}
params.Set("user_num", strconv.Itoa(userNum))
params.Set("user_video_limit", strconv.Itoa(userVideoLimit))
params.Set("query_rec_need", recommend)
}
params.Set("platform", platform)
params.Set("duration", duration)
params.Set("order", order)
params.Set("search_type", "all")
params.Set("from_source", fromSource)
if filtered == "1" {
params.Set("filtered", filtered)
}
if model.IsOverseas(plat) {
params.Set("use_area", "1")
params.Set("zone_id", strconv.FormatInt(zoneid, 10))
} else if newPGC {
params.Set("media_ft_num", strconv.Itoa(movieNum))
params.Set("is_new_pgc", "1")
} else {
params.Set("movie_num", strconv.Itoa(movieNum))
}
if flow {
params.Set("flow_need", "1")
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.ComicAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.ComicIOS) || model.IsIPhoneB(plat) {
params.Set("is_comic", "1")
}
if (model.IsAndroid(plat) && build > search.SearchLiveAllAndroid) || (model.IsIPhone(plat) && build > search.SearchLiveAllIOS) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
params.Set("new_live", "1")
}
if (model.IsAndroid(plat) && build > search.SearchTwitterAndroid) || (model.IsIPhone(plat) && build > search.SearchTwitterIOS) || model.IsIPhoneB(plat) {
params.Set("is_twitter", "1")
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.PGCHighLightAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.PGCHighLightIOS) {
params.Set("app_highlight", "media_bangumi,media_ft")
}
if (model.IsAndroid(plat) && build >= search.SearchConvergeAndroid) || (model.IsIPhone(plat) && build >= search.SearchConvergeIOS) || model.IsIPhoneB(plat) {
params.Set("card_num", "1")
}
params.Set("is_parents", parent)
if (model.IsAndroid(plat) && build > search.SearchStarAndroid) || (model.IsIPhone(plat) && build > search.SearchStarIOS) || model.IsIPhoneB(plat) {
params.Set("is_star", "1")
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.PGCALLAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.PGCALLIOS) || model.IsIPhoneB(plat) {
params.Set("is_pgc_all", "1")
}
if (model.IsAndroid(plat) && build > search.SearchTicketAndroid) || (model.IsIPhone(plat) && build > search.SearchTicketIOS) || model.IsIPhoneB(plat) {
params.Set("is_ticket", "1")
}
if (model.IsAndroid(plat) && build > search.SearchProductAndroid) || (model.IsIPhone(plat) && build > search.SearchProductIOS) || model.IsIPhoneB(plat) {
params.Set("is_product", "1")
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SearchArticleAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SearchArticleIOS) || model.IsIPhoneB(plat) {
params.Set("is_article", "1")
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.ChannelAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.ChannelIOS) {
params.Set("is_tag", "1")
}
params.Set("is_org_query", strconv.Itoa(isQuery))
if ipInfo != nil {
params.Set("user_city", ipInfo.City)
}
// new request
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
if err = d.client.Do(c, req, res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
} else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
}
for _, flow := range res.FlowResult {
flow.Change()
}
code = res.Code
return
}
// Season search season data.
func (d *Dao) Season(c context.Context, mid, zoneID int64, keyword, mobiApp, device, platform, buvid, filtered string, plat int8, build, pn, ps int, now time.Time) (st *search.TypeSearch, err error) {
var (
req *http.Request
ip = metadata.String(c, metadata.RemoteIP)
)
params := url.Values{}
params.Set("main_ver", "v3")
params.Set("platform", platform)
params.Set("build", strconv.Itoa(build))
params.Set("keyword", keyword)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("func", "search")
params.Set("smerge", "1")
params.Set("search_type", "bangumi")
params.Set("source_type", "0")
if filtered == "1" {
params.Set("filtered", filtered)
}
if model.IsOverseas(plat) {
params.Set("use_area", "1")
params.Set("zone_id", strconv.FormatInt(zoneID, 10))
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
// new request
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Pages int `json:"numPages"`
List []*search.Bangumi `json:"result"`
}
// do
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
} else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
return
}
items := make([]*search.Item, 0, len(res.List))
for _, v := range res.List {
si := &search.Item{}
if (model.IsAndroid(plat) && build <= _oldAndroid) || (model.IsIPhone(plat) && build <= _oldIOS) {
si.FromSeason(v, model.GotoBangumi)
} else {
si.FromSeason(v, model.GotoBangumiWeb)
}
items = append(items, si)
}
st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
return
}
// Upper search upper data.
func (d *Dao) Upper(c context.Context, mid int64, keyword, mobiApp, device, platform, buvid, filtered, order string, biliUserVL, highlight, build, userType, orderSort, pn, ps int, old bool, now time.Time) (st *search.TypeSearch, err error) {
var (
req *http.Request
plat = model.Plat(mobiApp, device)
avids []int64
avm map[int64]*api.Arc
roomIDs []int64
lm map[int64]*livemdl.RoomInfo
ip = metadata.String(c, metadata.RemoteIP)
)
params := url.Values{}
params.Set("main_ver", "v3")
params.Set("keyword", keyword)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("highlight", strconv.Itoa(highlight))
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("func", "search")
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("smerge", "1")
params.Set("platform", platform)
params.Set("build", strconv.Itoa(build))
if old {
params.Set("search_type", "upuser")
} else {
params.Set("search_type", "bili_user")
params.Set("bili_user_vl", strconv.Itoa(biliUserVL))
params.Set("user_type", strconv.Itoa(userType))
params.Set("order_sort", strconv.Itoa(orderSort))
}
params.Set("order", order)
params.Set("source_type", "0")
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
if filtered == "1" {
params.Set("filtered", filtered)
}
// new request
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Pages int `json:"numPages"`
List []*search.User `json:"result"`
}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
} else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
return
}
items := make([]*search.Item, 0, len(res.List))
for _, v := range res.List {
for _, vr := range v.Res {
avids = append(avids, vr.Aid)
}
roomIDs = append(roomIDs, v.RoomID)
}
g, ctx := errgroup.WithContext(c)
if len(avids) != 0 {
g.Go(func() (err error) {
if avm, err = d.arcDao.Archives2(ctx, avids); err != nil {
log.Error("Upper %+v", err)
err = nil
}
return
})
}
if len(roomIDs) > 0 {
g.Go(func() (err error) {
if lm, err = d.liveDao.LiveByRIDs(ctx, roomIDs); err != nil {
log.Error("Upper %+v", err)
err = nil
}
return
})
}
if err = g.Wait(); err != nil {
log.Error("%+v", err)
return
}
for _, v := range res.List {
si := &search.Item{}
si.FromUpUser(v, avm, lm[v.RoomID])
items = append(items, si)
}
st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
return
}
// MovieByType search movie data from api .
func (d *Dao) MovieByType(c context.Context, mid, zoneid int64, keyword, mobiApp, device, platform, buvid, filtered string, plat int8, build, pn, ps int, now time.Time) (st *search.TypeSearch, err error) {
var (
req *http.Request
avids []int64
avm map[int64]*api.Arc
ip = metadata.String(c, metadata.RemoteIP)
)
params := url.Values{}
params.Set("keyword", keyword)
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("platform", platform)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("build", strconv.Itoa(build))
params.Set("main_ver", "v3")
params.Set("search_type", "pgc")
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("order", "totalrank")
if filtered == "1" {
params.Set("filtered", filtered)
}
if model.IsOverseas(plat) {
params.Set("use_area", "1")
params.Set("zone_id", strconv.FormatInt(zoneid, 10))
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
// new request
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Pages int `json:"numPages"`
List []*search.Movie `json:"result"`
}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
} else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
return
}
items := make([]*search.Item, 0, len(res.List))
for _, v := range res.List {
if v.Type == "movie" {
avids = append(avids, v.Aid)
}
}
if len(avids) != 0 {
if avm, err = d.arcDao.Archives2(c, avids); err != nil {
log.Error("RecommendNoResult %+v", err)
err = nil
}
}
for _, v := range res.List {
si := &search.Item{}
si.FromMovie(v, avm)
items = append(items, si)
}
st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
return
}
// LiveByType search by diff type
func (d *Dao) LiveByType(c context.Context, mid, zoneid int64, keyword, mobiApp, device, platform, buvid, filtered, order, sType string, plat int8, build, pn, ps int, now time.Time) (st *search.TypeSearch, err error) {
var (
req *http.Request
ip = metadata.String(c, metadata.RemoteIP)
// roomIDs []int64
// lm map[int64]*livemdl.RoomInfo
)
params := url.Values{}
params.Set("keyword", keyword)
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("platform", platform)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("build", strconv.Itoa(build))
params.Set("main_ver", "v3")
params.Set("search_type", sType)
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("order", order)
if filtered == "1" {
params.Set("filtered", filtered)
}
if model.IsOverseas(plat) {
params.Set("use_area", "1")
params.Set("zone_id", strconv.FormatInt(zoneid, 10))
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
// new request
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Pages int `json:"numPages"`
List []*search.Live `json:"result"`
}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
} else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
return
}
// for _, v := range res.List {
// roomIDs = append(roomIDs, v.RoomID)
// }
// if len(roomIDs) > 0 {
// if lm, err = d.liveDao.LiveByRIDs(c, roomIDs, ip); err != nil {
// log.Error("LiveByType %+v", err)
// err = nil
// }
// }
items := make([]*search.Item, 0, len(res.List))
for _, v := range res.List {
si := &search.Item{}
si.FromLive(v, nil)
items = append(items, si)
}
st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
return
}
// Live search for live
func (d *Dao) Live(c context.Context, mid int64, keyword, mobiApp, platform, buvid, device, order, sType string, build, pn, ps int) (st *search.TypeSearch, err error) {
var (
req *http.Request
plat = model.Plat(mobiApp, device)
roomIDs []int64
lm map[int64]*livemdl.RoomInfo
ip = metadata.String(c, metadata.RemoteIP)
)
params := url.Values{}
params.Set("keyword", keyword)
params.Set("mobi_app", mobiApp)
params.Set("platform", platform)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("build", strconv.Itoa(build))
params.Set("main_ver", "v3")
params.Set("search_type", sType)
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("device", device)
params.Set("order", order)
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
// new request
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Pages int `json:"numPages"`
List []*search.Live `json:"result"`
}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
} else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
return
}
if !model.IsAndroid(plat) || (model.IsAndroid(plat) && build > search.LiveBroadcastTypeAndroid) {
for _, v := range res.List {
roomIDs = append(roomIDs, v.RoomID)
}
if len(roomIDs) > 0 {
if lm, err = d.liveDao.LiveByRIDs(c, roomIDs); err != nil {
log.Error("Live %+v", err)
err = nil
}
}
}
items := make([]*search.Item, 0, len(res.List))
for _, v := range res.List {
si := &search.Item{}
si.FromLive2(v, lm[v.RoomID])
items = append(items, si)
}
st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
return
}
// LiveAll search for live version > 5.28
func (d *Dao) LiveAll(c context.Context, mid int64, keyword, mobiApp, platform, buvid, device, order, sType string, build, pn, ps int) (st *search.TypeSearchLiveAll, err error) {
var (
req *http.Request
plat = model.Plat(mobiApp, device)
roomIDs []int64
lm map[int64]*livemdl.RoomInfo
ip = metadata.String(c, metadata.RemoteIP)
)
params := url.Values{}
params.Set("keyword", keyword)
params.Set("mobi_app", mobiApp)
params.Set("platform", platform)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("build", strconv.Itoa(build))
params.Set("main_ver", "v3")
params.Set("search_type", sType)
params.Set("page", strconv.Itoa(pn))
params.Set("live_room_num", strconv.Itoa(ps))
params.Set("device", device)
params.Set("order", order)
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
// new request
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Pages int `json:"numPages"`
PageInfo *struct {
Master *search.Live `json:"live_master"`
Room *search.Live `json:"live_room"`
} `json:"pageinfo"`
List *struct {
Master []*search.Live `json:"live_master"`
Room []*search.Live `json:"live_room"`
} `json:"result"`
}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || model.IsIPad(plat) || model.IsIPhoneB(plat) {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
} else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
return
}
st = &search.TypeSearchLiveAll{
TrackID: res.SeID,
Pages: res.Pages,
Master: &search.TypeSearch{},
Room: &search.TypeSearch{},
}
if res.PageInfo != nil {
if res.PageInfo.Master != nil {
st.Master.Pages = res.PageInfo.Master.Pages
st.Master.Total = res.PageInfo.Master.Total
}
if res.PageInfo.Room != nil {
st.Room.Pages = res.PageInfo.Room.Pages
st.Room.Total = res.PageInfo.Room.Total
}
}
if res.List != nil {
if !model.IsAndroid(plat) || (model.IsAndroid(plat) && build > search.LiveBroadcastTypeAndroid) {
for _, v := range res.List.Master {
roomIDs = append(roomIDs, v.RoomID)
}
for _, v := range res.List.Room {
roomIDs = append(roomIDs, v.RoomID)
}
if len(roomIDs) > 0 {
if lm, err = d.liveDao.LiveByRIDs(c, roomIDs); err != nil {
log.Error("LiveAll %+v", err)
err = nil
}
}
}
st.Master.Items = make([]*search.Item, 0, len(res.List.Master))
for _, v := range res.List.Master {
si := &search.Item{}
si.FromLiveMaster(v, lm[v.RoomID])
st.Master.Items = append(st.Master.Items, si)
}
st.Room.Items = make([]*search.Item, 0, len(res.List.Room))
for _, v := range res.List.Room {
si := &search.Item{}
si.FromLive2(v, lm[v.RoomID])
st.Room.Items = append(st.Room.Items, si)
}
}
return
}
// ArticleByType search article.
func (d *Dao) ArticleByType(c context.Context, mid, zoneid int64, keyword, mobiApp, device, platform, buvid, filtered, order, sType string, plat int8, categoryID, build, highlight, pn, ps int, now time.Time) (st *search.TypeSearch, err error) {
var (
req *http.Request
ip = metadata.String(c, metadata.RemoteIP)
)
params := url.Values{}
params.Set("keyword", keyword)
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("platform", platform)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("build", strconv.Itoa(build))
params.Set("main_ver", "v3")
params.Set("highlight", strconv.Itoa(highlight))
params.Set("search_type", sType)
params.Set("category_id", strconv.Itoa(categoryID))
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("order", order)
if filtered == "1" {
params.Set("filtered", filtered)
}
if model.IsOverseas(plat) {
params.Set("use_area", "1")
params.Set("zone_id", strconv.FormatInt(zoneid, 10))
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Pages int `json:"numPages"`
List []*search.Article `json:"result"`
}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
return
}
items := make([]*search.Item, 0, len(res.List))
for _, v := range res.List {
si := &search.Item{}
si.FromArticle(v, nil)
items = append(items, si)
}
st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
return
}
// HotSearch is hot words search data.
func (d *Dao) HotSearch(c context.Context, buvid string, mid int64, build, limit int, mobiApp, device, platform string, now time.Time) (res *search.Hot, err error) {
ip := metadata.String(c, metadata.RemoteIP)
params := url.Values{}
params.Set("main_ver", "v3")
params.Set("actionKey", "appkey")
params.Set("limit", strconv.Itoa(limit))
params.Set("build", strconv.Itoa(build))
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("platform", platform)
params.Set("userid", strconv.FormatInt(mid, 10))
req, err := d.client.NewRequest("GET", d.hot, ip, params)
if err != nil {
return
}
req.Header.Set("Buvid", buvid)
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
err = errors.Wrap(ecode.Int(res.Code), d.hot+"?"+params.Encode())
}
return
}
// Suggest suggest data.
func (d *Dao) Suggest(c context.Context, mid int64, buvid, term string, build int, mobiApp, device string, now time.Time) (res *search.Suggest, err error) {
plat := model.Plat(mobiApp, device)
ip := metadata.String(c, metadata.RemoteIP)
params := url.Values{}
params.Set("main_ver", "v4")
params.Set("func", "suggest")
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("buvid", buvid)
params.Set("build", strconv.Itoa(build))
params.Set("mobi_app", mobiApp)
params.Set("bangumi_acc_num", "3")
params.Set("special_acc_num", "3")
params.Set("topic_acc_num", "3")
params.Set("upuser_acc_num", "1")
params.Set("tag_num", "10")
params.Set("special_num", "10")
params.Set("bangumi_num", "10")
params.Set("upuser_num", "3")
params.Set("suggest_type", "accurate")
params.Set("term", term)
res = &search.Suggest{}
if err = d.client.Get(c, d.suggest, ip, params, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
err = errors.Wrap(ecode.Int(res.Code), d.suggest+"?"+params.Encode())
} else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.suggest+"?"+params.Encode())
}
return
}
if res.ResultBs == nil {
return
}
switch v := res.ResultBs.(type) {
case []interface{}:
return
case map[string]interface{}:
if acc, ok := v["accurate"]; ok {
if accm, ok := acc.(map[string]interface{}); ok && accm != nil {
res.Result.Accurate.UpUser = accm["upuser"]
res.Result.Accurate.Bangumi = accm["bangumi"]
}
}
if tag, ok := v["tag"]; ok {
if tags, ok := tag.([]interface{}); ok {
for _, t := range tags {
if tm, ok := t.(map[string]interface{}); ok && tm != nil {
if v, ok := tm["value"]; ok {
if vs, ok := v.(string); ok {
res.Result.Tag = append(res.Result.Tag, &struct {
Value string `json:"value,omitempty"`
}{vs})
}
}
}
}
}
}
}
return
}
// Suggest2 suggest data.
func (d *Dao) Suggest2(c context.Context, mid int64, platform, buvid, term string, build int, mobiApp string, now time.Time) (res *search.Suggest2, err error) {
ip := metadata.String(c, metadata.RemoteIP)
params := url.Values{}
params.Set("main_ver", "v4")
params.Set("suggest_type", "accurate")
params.Set("platform", platform)
params.Set("mobi_app", mobiApp)
params.Set("clientip", ip)
params.Set("build", strconv.Itoa(build))
if mid != 0 {
params.Set("userid", strconv.FormatInt(mid, 10))
}
params.Set("term", term)
params.Set("sug_num", "10")
params.Set("buvid", buvid)
res = &search.Suggest2{}
if err = d.client.Get(c, d.suggest, ip, params, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
err = errors.Wrap(ecode.Int(res.Code), d.suggest+"?"+params.Encode())
}
return
}
// Suggest3 suggest data.
func (d *Dao) Suggest3(c context.Context, mid int64, platform, buvid, term, device string, build, highlight int, mobiApp string, now time.Time) (res *search.Suggest3, err error) {
var (
req *http.Request
plat = model.Plat(mobiApp, device)
ip = metadata.String(c, metadata.RemoteIP)
)
params := url.Values{}
params.Set("suggest_type", "accurate")
params.Set("platform", platform)
params.Set("mobi_app", mobiApp)
params.Set("clientip", ip)
params.Set("highlight", strconv.Itoa(highlight))
params.Set("build", strconv.Itoa(build))
if mid != 0 {
params.Set("userid", strconv.FormatInt(mid, 10))
}
params.Set("term", term)
params.Set("sug_num", "10")
params.Set("buvid", buvid)
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SugDetailAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SugDetailIOS) {
params.Set("is_detail_info", "1")
}
if req, err = d.client.NewRequest("GET", d.suggest3, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
res = &search.Suggest3{}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
err = errors.Wrap(ecode.Int(res.Code), d.suggest3+"?"+params.Encode())
return
}
for _, flow := range res.Result {
flow.SugChange()
}
return
}
// Season2 search new season data.
func (d *Dao) Season2(c context.Context, mid int64, keyword, mobiApp, device, platform, buvid string, highlight, build, pn, ps int) (st *search.TypeSearch, err error) {
var (
req *http.Request
plat = model.Plat(mobiApp, device)
ip = metadata.String(c, metadata.RemoteIP)
seasonIDs []int64
bangumis map[string]*bangumimdl.Card
)
params := url.Values{}
params.Set("main_ver", "v3")
params.Set("platform", platform)
params.Set("build", strconv.Itoa(build))
params.Set("keyword", keyword)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("search_type", "media_bangumi")
params.Set("order", "totalrank")
params.Set("highlight", strconv.Itoa(highlight))
params.Set("app_highlight", "media_bangumi")
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.PGCALLAndroid) || (model.IsIPhone(plat) && build >= d.c.SearchBuildLimit.PGCALLIOS) || model.IsIPhoneB(plat) {
params.Set("is_pgc_all", "1")
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Total int `json:"numResults"`
Pages int `json:"numPages"`
List []*search.Media `json:"result"`
}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
} else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
return
}
for _, v := range res.List {
seasonIDs = append(seasonIDs, v.SeasonID)
}
if len(seasonIDs) > 0 {
if bangumis, err = d.bangumiDao.Card(c, mid, seasonIDs); err != nil {
log.Error("Season2 %+v", err)
err = nil
}
}
items := make([]*search.Item, 0, len(res.List))
for _, v := range res.List {
si := &search.Item{}
si.FromMedia(v, "", model.GotoBangumi, bangumis)
items = append(items, si)
}
st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Total: res.Total, Items: items}
return
}
// MovieByType2 search new movie data from api .
func (d *Dao) MovieByType2(c context.Context, mid int64, keyword, mobiApp, device, platform, buvid string, highlight, build, pn, ps int) (st *search.TypeSearch, err error) {
var (
req *http.Request
plat = model.Plat(mobiApp, device)
ip = metadata.String(c, metadata.RemoteIP)
seasonIDs []int64
bangumis map[string]*bangumimdl.Card
)
params := url.Values{}
params.Set("keyword", keyword)
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("platform", platform)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("build", strconv.Itoa(build))
params.Set("main_ver", "v3")
params.Set("search_type", "media_ft")
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("order", "totalrank")
params.Set("highlight", strconv.Itoa(highlight))
params.Set("app_highlight", "media_ft")
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.PGCALLAndroid) || (model.IsIPhone(plat) && build >= d.c.SearchBuildLimit.PGCALLIOS) || model.IsIPhoneB(plat) {
params.Set("is_pgc_all", "1")
}
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Total int `json:"numResults"`
Pages int `json:"numPages"`
List []*search.Media `json:"result"`
}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
} else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
return
}
for _, v := range res.List {
seasonIDs = append(seasonIDs, v.SeasonID)
}
if len(seasonIDs) > 0 {
if bangumis, err = d.bangumiDao.Card(c, mid, seasonIDs); err != nil {
log.Error("MovieByType2 %+v", err)
err = nil
}
}
items := make([]*search.Item, 0, len(res.List))
for _, v := range res.List {
si := &search.Item{}
si.FromMedia(v, "", model.GotoMovie, bangumis)
items = append(items, si)
}
st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Total: res.Total, Items: items}
return
}
// User search user data.
func (d *Dao) User(c context.Context, mid int64, keyword, mobiApp, device, platform, buvid, filtered, order, fromSource string, highlight, build, userType, orderSort, pn, ps int, now time.Time) (user []*search.User, err error) {
var (
req *http.Request
plat = model.Plat(mobiApp, device)
ip = metadata.String(c, metadata.RemoteIP)
)
params := url.Values{}
params.Set("platform", platform)
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("build", strconv.Itoa(build))
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("keyword", keyword)
params.Set("highlight", strconv.Itoa(highlight))
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("main_ver", "v3")
params.Set("func", "search")
params.Set("smerge", "1")
params.Set("source_type", "0")
params.Set("search_type", "bili_user")
params.Set("user_type", strconv.Itoa(userType))
params.Set("order", order)
params.Set("order_sort", strconv.Itoa(orderSort))
params.Set("from_source", fromSource)
if filtered == "1" {
params.Set("filtered", filtered)
}
// new request
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Pages int `json:"numPages"`
List []*search.User `json:"result"`
}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) || model.IsIPhoneB(plat) {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
} else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
return
}
user = res.List
return
}
// Recommend is recommend search data.
func (d *Dao) Recommend(c context.Context, mid int64, build, from, show int, buvid, platform, mobiApp, device string) (res *search.RecommendResult, err error) {
ip := metadata.String(c, metadata.RemoteIP)
params := url.Values{}
params.Set("main_ver", "v3")
params.Set("platform", platform)
params.Set("mobi_app", mobiApp)
params.Set("clientip", ip)
params.Set("device", device)
params.Set("build", strconv.Itoa(build))
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("search_type", "guess")
params.Set("req_source", strconv.Itoa(from))
params.Set("show_area", strconv.Itoa(show))
req, err := d.client.NewRequest("GET", d.rcmd, ip, params)
if err != nil {
return
}
req.Header.Set("Buvid", buvid)
var rcmdRes struct {
Code int `json:"code,omitempty"`
SeID string `json:"seid,omitempty"`
Tips string `json:"recommend_tips,omitempty"`
NumResult int `json:"numResult,omitempty"`
Resutl []struct {
ID int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
} `json:"result,omitempty"`
}
if err = d.client.Do(c, req, &rcmdRes); err != nil {
return
}
if rcmdRes.Code != ecode.OK.Code() {
if rcmdRes.Code != model.ForbidCode {
err = errors.Wrap(ecode.Int(rcmdRes.Code), d.rcmd+"?"+params.Encode())
}
return
}
res = &search.RecommendResult{TrackID: rcmdRes.SeID, Title: rcmdRes.Tips, Pages: rcmdRes.NumResult}
for _, v := range rcmdRes.Resutl {
item := &search.Item{}
item.ID = v.ID
item.Param = strconv.Itoa(int(v.ID))
item.Title = v.Name
item.Type = v.Type
res.Items = append(res.Items, item)
}
return
}
// DefaultWords is default words search data.
func (d *Dao) DefaultWords(c context.Context, mid int64, build, from int, buvid, platform, mobiApp, device string) (res *search.DefaultWords, err error) {
ip := metadata.String(c, metadata.RemoteIP)
params := url.Values{}
params.Set("main_ver", "v3")
params.Set("platform", platform)
params.Set("mobi_app", mobiApp)
params.Set("clientip", ip)
params.Set("device", device)
params.Set("build", strconv.Itoa(build))
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("search_type", "default")
params.Set("req_source", strconv.Itoa(from))
req, err := d.client.NewRequest("GET", d.rcmd, ip, params)
if err != nil {
return
}
req.Header.Set("Buvid", buvid)
var rcmdRes struct {
Code int `json:"code,omitempty"`
SeID string `json:"seid,omitempty"`
Tips string `json:"recommend_tips,omitempty"`
NumResult int `json:"numResult,omitempty"`
ShowFront int `json:"show_front,omitempty"`
Resutl []struct {
ID int64 `json:"id,omitempty"`
Name string `json:"name,omitempty"`
ShowName string `json:"show_name,omitempty"`
Type string `json:"type,omitempty"`
} `json:"result,omitempty"`
}
if err = d.client.Do(c, req, &rcmdRes); err != nil {
return
}
if rcmdRes.Code != ecode.OK.Code() {
if rcmdRes.Code != model.ForbidCode {
err = errors.Wrap(ecode.Int(rcmdRes.Code), d.rcmd+"?"+params.Encode())
}
return
}
if len(rcmdRes.Resutl) == 0 {
err = ecode.NothingFound
return
}
res = &search.DefaultWords{}
for _, v := range rcmdRes.Resutl {
res.Trackid = rcmdRes.SeID
res.Param = strconv.Itoa(int(v.ID))
res.Show = v.ShowName
res.Word = v.Name
res.ShowFront = rcmdRes.ShowFront
}
return
}
// RecommendNoResult is no result recommend search data.
func (d *Dao) RecommendNoResult(c context.Context, platform, mobiApp, device, buvid, keyword string, build, pn, ps int, mid int64) (res *search.NoResultRcndResult, err error) {
ip := metadata.String(c, metadata.RemoteIP)
params := url.Values{}
params.Set("main_ver", "v3")
params.Set("platform", platform)
params.Set("mobi_app", mobiApp)
params.Set("clientip", ip)
params.Set("device", device)
params.Set("build", strconv.Itoa(build))
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("search_type", "video")
params.Set("keyword", keyword)
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
req, err := d.client.NewRequest("GET", d.rcmdNoResult, ip, params)
if err != nil {
return
}
req.Header.Set("Buvid", buvid)
var (
resTmp *search.NoResultRcmd
avids []int64
avm map[int64]*api.Arc
cooperation bool
)
if err = d.client.Do(c, req, &resTmp); err != nil {
return
}
if resTmp.Code != ecode.OK.Code() {
if resTmp.Code != model.ForbidCode {
err = errors.Wrap(ecode.Int(resTmp.Code), d.rcmdNoResult+"?"+params.Encode())
}
return
}
res = &search.NoResultRcndResult{TrackID: resTmp.Trackid, Title: resTmp.RecommendTips, Pages: resTmp.NumResults}
for _, v := range resTmp.Result {
avids = append(avids, v.ID)
}
if len(avids) != 0 {
if avm, err = d.arcDao.Archives2(c, avids); err != nil {
log.Error("RecommendNoResult %+v", err)
err = nil
}
}
items := make([]*search.Item, 0, len(resTmp.Result))
for _, v := range resTmp.Result {
ri := &search.Item{}
ri.FromVideo(v, avm[v.ID], cooperation)
items = append(items, ri)
}
res.Items = items
return
}
// Channel for search channel
func (d *Dao) Channel(c context.Context, mid int64, keyword, mobiApp, platform, buvid, device, order, sType string, build, pn, ps, highlight int) (st *search.TypeSearch, err error) {
var (
req *http.Request
plat = model.Plat(mobiApp, device)
ip = metadata.String(c, metadata.RemoteIP)
)
params := url.Values{}
params.Set("keyword", keyword)
params.Set("mobi_app", mobiApp)
params.Set("platform", platform)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("build", strconv.Itoa(build))
params.Set("main_ver", "v3")
params.Set("search_type", sType)
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("device", device)
params.Set("order", order)
params.Set("highlight", strconv.Itoa(highlight))
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
// new request
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Pages int `json:"numPages"`
List []*search.Channel `json:"result"`
}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
}
return
}
items := make([]*search.Item, 0, len(res.List))
for _, v := range res.List {
si := &search.Item{}
avm := make(map[int64]*api.Arc)
bangumis := make(map[int32]*seasongrpc.CardInfoProto)
lm := make(map[int64]*livemdl.RoomInfo)
si.FromChannel(v, avm, bangumis, lm, nil)
items = append(items, si)
}
st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
return
}
// RecommendPre search at pre-page
func (d *Dao) RecommendPre(c context.Context, platform, mobiApp, device, buvid string, build, ps int, mid int64) (res *search.RecommendPreResult, err error) {
ip := metadata.String(c, metadata.RemoteIP)
params := url.Values{}
params.Set("main_ver", "v3")
params.Set("platform", platform)
params.Set("mobi_app", mobiApp)
params.Set("clientip", ip)
params.Set("device", device)
params.Set("build", strconv.Itoa(build))
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("search_type", "discover_page")
params.Set("pagesize", strconv.Itoa(ps))
req, err := d.client.NewRequest("GET", d.pre, ip, params)
if err != nil {
return
}
req.Header.Set("Buvid", buvid)
var (
resTmp *search.RecommendPre
avids []int64
avm map[int64]*api.Arc
seasonIDs []int32
bangumis map[int32]*seasongrpc.CardInfoProto
)
if err = d.client.Do(c, req, &resTmp); err != nil {
return
}
if resTmp.Code != ecode.OK.Code() {
if resTmp.Code != model.ForbidCode {
err = errors.Wrap(ecode.Int(resTmp.Code), d.pre+"?"+params.Encode())
}
return
}
for _, v := range resTmp.Result {
for _, vv := range v.List {
if vv.Type == "video" {
avids = append(avids, vv.ID)
} else if vv.Type == "pgc" {
seasonIDs = append(seasonIDs, int32(vv.ID))
}
}
}
g, ctx := errgroup.WithContext(c)
if len(avids) != 0 {
g.Go(func() (err error) {
if avm, err = d.arcDao.Archives2(ctx, avids); err != nil {
log.Error("RecommendPre avids(%v) error(%v)", avids, err)
err = nil
}
return
})
}
if len(seasonIDs) > 0 {
g.Go(func() (err error) {
if bangumis, err = d.bangumiDao.Cards(c, seasonIDs); err != nil {
log.Error("RecommendPre seasonIDs(%v) error(%v)", seasonIDs, err)
err = nil
}
return
})
}
if err = g.Wait(); err != nil {
log.Error("%+v", err)
return
}
res = &search.RecommendPreResult{TrackID: resTmp.Trackid, Total: resTmp.NumResult}
items := make([]*search.Item, 0, len(resTmp.Result))
for _, v := range resTmp.Result {
rs := &search.Item{Title: v.Query}
for _, vv := range v.List {
if vv.Type == "video" {
if a, ok := avm[vv.ID]; ok {
r := &search.Item{}
r.FromRcmdPre(vv.ID, a, nil)
rs.Item = append(rs.Item, r)
}
} else if vv.Type == "pgc" {
if b, ok := bangumis[int32(vv.ID)]; ok {
r := &search.Item{}
r.FromRcmdPre(vv.ID, nil, b)
rs.Item = append(rs.Item, r)
}
}
}
items = append(items, rs)
}
res.Items = items
return
}
// Video search new archive data.
func (d *Dao) Video(c context.Context, mid int64, keyword, mobiApp, device, platform, buvid string, highlight, build, pn, ps int) (st *search.TypeSearch, err error) {
var (
req *http.Request
ip = metadata.String(c, metadata.RemoteIP)
plat = model.Plat(mobiApp, device)
avids []int64
avm map[int64]*api.Arc
cooperation bool
)
params := url.Values{}
params.Set("main_ver", "v3")
params.Set("platform", platform)
params.Set("build", strconv.Itoa(build))
params.Set("keyword", keyword)
params.Set("userid", strconv.FormatInt(mid, 10))
params.Set("mobi_app", mobiApp)
params.Set("device", device)
params.Set("page", strconv.Itoa(pn))
params.Set("pagesize", strconv.Itoa(ps))
params.Set("search_type", "video")
params.Set("order", "totalrank")
params.Set("highlight", strconv.Itoa(highlight))
if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
params.Set("is_special_guide", "1")
}
if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
return
}
req.Header.Set("Buvid", buvid)
var res struct {
Code int `json:"code"`
SeID string `json:"seid"`
Total int `json:"numResults"`
Pages int `json:"numPages"`
List []*search.Video `json:"result"`
}
if err = d.client.Do(c, req, &res); err != nil {
return
}
if res.Code != ecode.OK.Code() {
err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
return
}
for _, v := range res.List {
avids = append(avids, v.ID)
}
if len(avids) > 0 {
if avm, err = d.arcDao.Archives2(c, avids); err != nil {
log.Error("Upper %+v", err)
err = nil
}
}
items := make([]*search.Item, 0, len(res.List))
for _, v := range res.List {
si := &search.Item{}
si.FromVideo(v, avm[v.ID], cooperation)
items = append(items, si)
}
st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Total: res.Total, Items: items}
return
}