dao.go 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480
  1. package search
  2. import (
  3. "context"
  4. "net/http"
  5. "net/url"
  6. "strconv"
  7. "time"
  8. "go-common/app/interface/main/app-interface/conf"
  9. arcdao "go-common/app/interface/main/app-interface/dao/archive"
  10. bangumidao "go-common/app/interface/main/app-interface/dao/bangumi"
  11. livedao "go-common/app/interface/main/app-interface/dao/live"
  12. "go-common/app/interface/main/app-interface/model"
  13. bangumimdl "go-common/app/interface/main/app-interface/model/bangumi"
  14. livemdl "go-common/app/interface/main/app-interface/model/live"
  15. "go-common/app/interface/main/app-interface/model/search"
  16. "go-common/app/service/main/archive/api"
  17. locmdl "go-common/app/service/main/location/model"
  18. locrpc "go-common/app/service/main/location/rpc/client"
  19. seasongrpc "go-common/app/service/openplatform/pgc-season/api/grpc/season/v1"
  20. "go-common/library/ecode"
  21. "go-common/library/log"
  22. httpx "go-common/library/net/http/blademaster"
  23. "go-common/library/net/metadata"
  24. "go-common/library/sync/errgroup"
  25. "github.com/pkg/errors"
  26. )
  27. const (
  28. _main = "/main/search"
  29. _suggest = "/main/suggest"
  30. _hot = "/main/hotword"
  31. _defaultWords = "/widget/getSearchDefaultWords"
  32. _rcmd = "/query/recommend"
  33. _rcmdNoResult = "/search/recommend"
  34. _suggest3 = "/main/suggest/new"
  35. _pre = "/search/frontpage"
  36. )
  37. const (
  38. _oldAndroid = 514000
  39. _oldIOS = 6090
  40. _searchCodeLimitAndroid = 5250001
  41. _searchCodeLimitIPhone = 6680
  42. )
  43. // Dao is search dao
  44. type Dao struct {
  45. c *conf.Config
  46. arcDao *arcdao.Dao
  47. liveDao *livedao.Dao
  48. bangumiDao *bangumidao.Dao
  49. client *httpx.Client
  50. client2 *httpx.Client
  51. main string
  52. suggest string
  53. hot string
  54. defaultWords string
  55. rcmd string
  56. rcmdNoResult string
  57. suggest3 string
  58. pre string
  59. // rpc
  60. locRPC *locrpc.Service
  61. }
  62. // New initial search dao
  63. func New(c *conf.Config) (d *Dao) {
  64. d = &Dao{
  65. c: c,
  66. arcDao: arcdao.New(c),
  67. liveDao: livedao.New(c),
  68. bangumiDao: bangumidao.New(c),
  69. client: httpx.NewClient(c.HTTPSearch),
  70. client2: httpx.NewClient(c.HTTPClient),
  71. main: c.Host.Search + _main,
  72. suggest: c.Host.Search + _suggest,
  73. hot: c.Host.Search + _hot,
  74. defaultWords: c.Host.WWW + _defaultWords,
  75. rcmd: c.Host.Search + _rcmd,
  76. rcmdNoResult: c.Host.Search + _rcmdNoResult,
  77. suggest3: c.Host.Search + _suggest3,
  78. pre: c.Host.Search + _pre,
  79. locRPC: locrpc.New(c.LocationRPC),
  80. }
  81. return
  82. }
  83. // Search app all search .
  84. 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) {
  85. var (
  86. req *http.Request
  87. ip = metadata.String(c, metadata.RemoteIP)
  88. ipInfo *locmdl.Info
  89. )
  90. if ipInfo, err = d.locRPC.Info(c, &locmdl.ArgIP{IP: ip}); err != nil {
  91. log.Warn("%v", err)
  92. err = nil
  93. }
  94. res = &search.Search{}
  95. params := url.Values{}
  96. params.Set("build", strconv.Itoa(build))
  97. params.Set("keyword", keyword)
  98. params.Set("main_ver", "v3")
  99. params.Set("highlight", strconv.Itoa(highlight))
  100. params.Set("mobi_app", mobiApp)
  101. params.Set("device", device)
  102. params.Set("userid", strconv.FormatInt(mid, 10))
  103. params.Set("tids", strconv.Itoa(rid))
  104. params.Set("page", strconv.Itoa(pn))
  105. params.Set("pagesize", strconv.Itoa(ps))
  106. if newPGC {
  107. params.Set("media_bangumi_num", strconv.Itoa(seasonNum))
  108. } else {
  109. params.Set("bangumi_num", strconv.Itoa(seasonNum))
  110. params.Set("smerge", "1")
  111. }
  112. if (plat == model.PlatIPad && build >= search.SearchNewIPad) || (plat == model.PlatIpadHD && build >= search.SearchNewIPadHD) {
  113. params.Set("is_new_user", "1")
  114. } else {
  115. if old {
  116. params.Set("upuser_num", strconv.Itoa(upUserNum))
  117. params.Set("uv_limit", strconv.Itoa(uvLimit))
  118. } else {
  119. params.Set("bili_user_num", strconv.Itoa(biliUserNum))
  120. params.Set("bili_user_vl", strconv.Itoa(biliUserVideoLimit))
  121. }
  122. params.Set("user_num", strconv.Itoa(userNum))
  123. params.Set("user_video_limit", strconv.Itoa(userVideoLimit))
  124. params.Set("query_rec_need", recommend)
  125. }
  126. params.Set("platform", platform)
  127. params.Set("duration", duration)
  128. params.Set("order", order)
  129. params.Set("search_type", "all")
  130. params.Set("from_source", fromSource)
  131. if filtered == "1" {
  132. params.Set("filtered", filtered)
  133. }
  134. if model.IsOverseas(plat) {
  135. params.Set("use_area", "1")
  136. params.Set("zone_id", strconv.FormatInt(zoneid, 10))
  137. } else if newPGC {
  138. params.Set("media_ft_num", strconv.Itoa(movieNum))
  139. params.Set("is_new_pgc", "1")
  140. } else {
  141. params.Set("movie_num", strconv.Itoa(movieNum))
  142. }
  143. if flow {
  144. params.Set("flow_need", "1")
  145. }
  146. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.ComicAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.ComicIOS) || model.IsIPhoneB(plat) {
  147. params.Set("is_comic", "1")
  148. }
  149. 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) {
  150. params.Set("new_live", "1")
  151. }
  152. if (model.IsAndroid(plat) && build > search.SearchTwitterAndroid) || (model.IsIPhone(plat) && build > search.SearchTwitterIOS) || model.IsIPhoneB(plat) {
  153. params.Set("is_twitter", "1")
  154. }
  155. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.PGCHighLightAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.PGCHighLightIOS) {
  156. params.Set("app_highlight", "media_bangumi,media_ft")
  157. }
  158. if (model.IsAndroid(plat) && build >= search.SearchConvergeAndroid) || (model.IsIPhone(plat) && build >= search.SearchConvergeIOS) || model.IsIPhoneB(plat) {
  159. params.Set("card_num", "1")
  160. }
  161. params.Set("is_parents", parent)
  162. if (model.IsAndroid(plat) && build > search.SearchStarAndroid) || (model.IsIPhone(plat) && build > search.SearchStarIOS) || model.IsIPhoneB(plat) {
  163. params.Set("is_star", "1")
  164. }
  165. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.PGCALLAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.PGCALLIOS) || model.IsIPhoneB(plat) {
  166. params.Set("is_pgc_all", "1")
  167. }
  168. if (model.IsAndroid(plat) && build > search.SearchTicketAndroid) || (model.IsIPhone(plat) && build > search.SearchTicketIOS) || model.IsIPhoneB(plat) {
  169. params.Set("is_ticket", "1")
  170. }
  171. if (model.IsAndroid(plat) && build > search.SearchProductAndroid) || (model.IsIPhone(plat) && build > search.SearchProductIOS) || model.IsIPhoneB(plat) {
  172. params.Set("is_product", "1")
  173. }
  174. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  175. params.Set("is_special_guide", "1")
  176. }
  177. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SearchArticleAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SearchArticleIOS) || model.IsIPhoneB(plat) {
  178. params.Set("is_article", "1")
  179. }
  180. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.ChannelAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.ChannelIOS) {
  181. params.Set("is_tag", "1")
  182. }
  183. params.Set("is_org_query", strconv.Itoa(isQuery))
  184. if ipInfo != nil {
  185. params.Set("user_city", ipInfo.City)
  186. }
  187. // new request
  188. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  189. return
  190. }
  191. req.Header.Set("Buvid", buvid)
  192. if err = d.client.Do(c, req, res); err != nil {
  193. return
  194. }
  195. if res.Code != ecode.OK.Code() {
  196. 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) {
  197. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  198. } else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  199. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  200. }
  201. }
  202. for _, flow := range res.FlowResult {
  203. flow.Change()
  204. }
  205. code = res.Code
  206. return
  207. }
  208. // Season search season data.
  209. 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) {
  210. var (
  211. req *http.Request
  212. ip = metadata.String(c, metadata.RemoteIP)
  213. )
  214. params := url.Values{}
  215. params.Set("main_ver", "v3")
  216. params.Set("platform", platform)
  217. params.Set("build", strconv.Itoa(build))
  218. params.Set("keyword", keyword)
  219. params.Set("userid", strconv.FormatInt(mid, 10))
  220. params.Set("mobi_app", mobiApp)
  221. params.Set("device", device)
  222. params.Set("page", strconv.Itoa(pn))
  223. params.Set("pagesize", strconv.Itoa(ps))
  224. params.Set("func", "search")
  225. params.Set("smerge", "1")
  226. params.Set("search_type", "bangumi")
  227. params.Set("source_type", "0")
  228. if filtered == "1" {
  229. params.Set("filtered", filtered)
  230. }
  231. if model.IsOverseas(plat) {
  232. params.Set("use_area", "1")
  233. params.Set("zone_id", strconv.FormatInt(zoneID, 10))
  234. }
  235. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  236. params.Set("is_special_guide", "1")
  237. }
  238. // new request
  239. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  240. return
  241. }
  242. req.Header.Set("Buvid", buvid)
  243. var res struct {
  244. Code int `json:"code"`
  245. SeID string `json:"seid"`
  246. Pages int `json:"numPages"`
  247. List []*search.Bangumi `json:"result"`
  248. }
  249. // do
  250. if err = d.client.Do(c, req, &res); err != nil {
  251. return
  252. }
  253. if res.Code != ecode.OK.Code() {
  254. 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) {
  255. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  256. } else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  257. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  258. }
  259. return
  260. }
  261. items := make([]*search.Item, 0, len(res.List))
  262. for _, v := range res.List {
  263. si := &search.Item{}
  264. if (model.IsAndroid(plat) && build <= _oldAndroid) || (model.IsIPhone(plat) && build <= _oldIOS) {
  265. si.FromSeason(v, model.GotoBangumi)
  266. } else {
  267. si.FromSeason(v, model.GotoBangumiWeb)
  268. }
  269. items = append(items, si)
  270. }
  271. st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
  272. return
  273. }
  274. // Upper search upper data.
  275. 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) {
  276. var (
  277. req *http.Request
  278. plat = model.Plat(mobiApp, device)
  279. avids []int64
  280. avm map[int64]*api.Arc
  281. roomIDs []int64
  282. lm map[int64]*livemdl.RoomInfo
  283. ip = metadata.String(c, metadata.RemoteIP)
  284. )
  285. params := url.Values{}
  286. params.Set("main_ver", "v3")
  287. params.Set("keyword", keyword)
  288. params.Set("userid", strconv.FormatInt(mid, 10))
  289. params.Set("highlight", strconv.Itoa(highlight))
  290. params.Set("mobi_app", mobiApp)
  291. params.Set("device", device)
  292. params.Set("func", "search")
  293. params.Set("page", strconv.Itoa(pn))
  294. params.Set("pagesize", strconv.Itoa(ps))
  295. params.Set("smerge", "1")
  296. params.Set("platform", platform)
  297. params.Set("build", strconv.Itoa(build))
  298. if old {
  299. params.Set("search_type", "upuser")
  300. } else {
  301. params.Set("search_type", "bili_user")
  302. params.Set("bili_user_vl", strconv.Itoa(biliUserVL))
  303. params.Set("user_type", strconv.Itoa(userType))
  304. params.Set("order_sort", strconv.Itoa(orderSort))
  305. }
  306. params.Set("order", order)
  307. params.Set("source_type", "0")
  308. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  309. params.Set("is_special_guide", "1")
  310. }
  311. if filtered == "1" {
  312. params.Set("filtered", filtered)
  313. }
  314. // new request
  315. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  316. return
  317. }
  318. req.Header.Set("Buvid", buvid)
  319. var res struct {
  320. Code int `json:"code"`
  321. SeID string `json:"seid"`
  322. Pages int `json:"numPages"`
  323. List []*search.User `json:"result"`
  324. }
  325. if err = d.client.Do(c, req, &res); err != nil {
  326. return
  327. }
  328. if res.Code != ecode.OK.Code() {
  329. 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) {
  330. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  331. } else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  332. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  333. }
  334. return
  335. }
  336. items := make([]*search.Item, 0, len(res.List))
  337. for _, v := range res.List {
  338. for _, vr := range v.Res {
  339. avids = append(avids, vr.Aid)
  340. }
  341. roomIDs = append(roomIDs, v.RoomID)
  342. }
  343. g, ctx := errgroup.WithContext(c)
  344. if len(avids) != 0 {
  345. g.Go(func() (err error) {
  346. if avm, err = d.arcDao.Archives2(ctx, avids); err != nil {
  347. log.Error("Upper %+v", err)
  348. err = nil
  349. }
  350. return
  351. })
  352. }
  353. if len(roomIDs) > 0 {
  354. g.Go(func() (err error) {
  355. if lm, err = d.liveDao.LiveByRIDs(ctx, roomIDs); err != nil {
  356. log.Error("Upper %+v", err)
  357. err = nil
  358. }
  359. return
  360. })
  361. }
  362. if err = g.Wait(); err != nil {
  363. log.Error("%+v", err)
  364. return
  365. }
  366. for _, v := range res.List {
  367. si := &search.Item{}
  368. si.FromUpUser(v, avm, lm[v.RoomID])
  369. items = append(items, si)
  370. }
  371. st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
  372. return
  373. }
  374. // MovieByType search movie data from api .
  375. 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) {
  376. var (
  377. req *http.Request
  378. avids []int64
  379. avm map[int64]*api.Arc
  380. ip = metadata.String(c, metadata.RemoteIP)
  381. )
  382. params := url.Values{}
  383. params.Set("keyword", keyword)
  384. params.Set("mobi_app", mobiApp)
  385. params.Set("device", device)
  386. params.Set("platform", platform)
  387. params.Set("userid", strconv.FormatInt(mid, 10))
  388. params.Set("build", strconv.Itoa(build))
  389. params.Set("main_ver", "v3")
  390. params.Set("search_type", "pgc")
  391. params.Set("page", strconv.Itoa(pn))
  392. params.Set("pagesize", strconv.Itoa(ps))
  393. params.Set("order", "totalrank")
  394. if filtered == "1" {
  395. params.Set("filtered", filtered)
  396. }
  397. if model.IsOverseas(plat) {
  398. params.Set("use_area", "1")
  399. params.Set("zone_id", strconv.FormatInt(zoneid, 10))
  400. }
  401. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  402. params.Set("is_special_guide", "1")
  403. }
  404. // new request
  405. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  406. return
  407. }
  408. req.Header.Set("Buvid", buvid)
  409. var res struct {
  410. Code int `json:"code"`
  411. SeID string `json:"seid"`
  412. Pages int `json:"numPages"`
  413. List []*search.Movie `json:"result"`
  414. }
  415. if err = d.client.Do(c, req, &res); err != nil {
  416. return
  417. }
  418. if res.Code != ecode.OK.Code() {
  419. 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) {
  420. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  421. } else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  422. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  423. }
  424. return
  425. }
  426. items := make([]*search.Item, 0, len(res.List))
  427. for _, v := range res.List {
  428. if v.Type == "movie" {
  429. avids = append(avids, v.Aid)
  430. }
  431. }
  432. if len(avids) != 0 {
  433. if avm, err = d.arcDao.Archives2(c, avids); err != nil {
  434. log.Error("RecommendNoResult %+v", err)
  435. err = nil
  436. }
  437. }
  438. for _, v := range res.List {
  439. si := &search.Item{}
  440. si.FromMovie(v, avm)
  441. items = append(items, si)
  442. }
  443. st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
  444. return
  445. }
  446. // LiveByType search by diff type
  447. 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) {
  448. var (
  449. req *http.Request
  450. ip = metadata.String(c, metadata.RemoteIP)
  451. // roomIDs []int64
  452. // lm map[int64]*livemdl.RoomInfo
  453. )
  454. params := url.Values{}
  455. params.Set("keyword", keyword)
  456. params.Set("mobi_app", mobiApp)
  457. params.Set("device", device)
  458. params.Set("platform", platform)
  459. params.Set("userid", strconv.FormatInt(mid, 10))
  460. params.Set("build", strconv.Itoa(build))
  461. params.Set("main_ver", "v3")
  462. params.Set("search_type", sType)
  463. params.Set("page", strconv.Itoa(pn))
  464. params.Set("pagesize", strconv.Itoa(ps))
  465. params.Set("order", order)
  466. if filtered == "1" {
  467. params.Set("filtered", filtered)
  468. }
  469. if model.IsOverseas(plat) {
  470. params.Set("use_area", "1")
  471. params.Set("zone_id", strconv.FormatInt(zoneid, 10))
  472. }
  473. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  474. params.Set("is_special_guide", "1")
  475. }
  476. // new request
  477. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  478. return
  479. }
  480. req.Header.Set("Buvid", buvid)
  481. var res struct {
  482. Code int `json:"code"`
  483. SeID string `json:"seid"`
  484. Pages int `json:"numPages"`
  485. List []*search.Live `json:"result"`
  486. }
  487. if err = d.client.Do(c, req, &res); err != nil {
  488. return
  489. }
  490. if res.Code != ecode.OK.Code() {
  491. 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) {
  492. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  493. } else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  494. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  495. }
  496. return
  497. }
  498. // for _, v := range res.List {
  499. // roomIDs = append(roomIDs, v.RoomID)
  500. // }
  501. // if len(roomIDs) > 0 {
  502. // if lm, err = d.liveDao.LiveByRIDs(c, roomIDs, ip); err != nil {
  503. // log.Error("LiveByType %+v", err)
  504. // err = nil
  505. // }
  506. // }
  507. items := make([]*search.Item, 0, len(res.List))
  508. for _, v := range res.List {
  509. si := &search.Item{}
  510. si.FromLive(v, nil)
  511. items = append(items, si)
  512. }
  513. st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
  514. return
  515. }
  516. // Live search for live
  517. 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) {
  518. var (
  519. req *http.Request
  520. plat = model.Plat(mobiApp, device)
  521. roomIDs []int64
  522. lm map[int64]*livemdl.RoomInfo
  523. ip = metadata.String(c, metadata.RemoteIP)
  524. )
  525. params := url.Values{}
  526. params.Set("keyword", keyword)
  527. params.Set("mobi_app", mobiApp)
  528. params.Set("platform", platform)
  529. params.Set("userid", strconv.FormatInt(mid, 10))
  530. params.Set("build", strconv.Itoa(build))
  531. params.Set("main_ver", "v3")
  532. params.Set("search_type", sType)
  533. params.Set("page", strconv.Itoa(pn))
  534. params.Set("pagesize", strconv.Itoa(ps))
  535. params.Set("device", device)
  536. params.Set("order", order)
  537. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  538. params.Set("is_special_guide", "1")
  539. }
  540. // new request
  541. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  542. return
  543. }
  544. req.Header.Set("Buvid", buvid)
  545. var res struct {
  546. Code int `json:"code"`
  547. SeID string `json:"seid"`
  548. Pages int `json:"numPages"`
  549. List []*search.Live `json:"result"`
  550. }
  551. if err = d.client.Do(c, req, &res); err != nil {
  552. return
  553. }
  554. if res.Code != ecode.OK.Code() {
  555. 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) {
  556. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  557. } else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  558. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  559. }
  560. return
  561. }
  562. if !model.IsAndroid(plat) || (model.IsAndroid(plat) && build > search.LiveBroadcastTypeAndroid) {
  563. for _, v := range res.List {
  564. roomIDs = append(roomIDs, v.RoomID)
  565. }
  566. if len(roomIDs) > 0 {
  567. if lm, err = d.liveDao.LiveByRIDs(c, roomIDs); err != nil {
  568. log.Error("Live %+v", err)
  569. err = nil
  570. }
  571. }
  572. }
  573. items := make([]*search.Item, 0, len(res.List))
  574. for _, v := range res.List {
  575. si := &search.Item{}
  576. si.FromLive2(v, lm[v.RoomID])
  577. items = append(items, si)
  578. }
  579. st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
  580. return
  581. }
  582. // LiveAll search for live version > 5.28
  583. 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) {
  584. var (
  585. req *http.Request
  586. plat = model.Plat(mobiApp, device)
  587. roomIDs []int64
  588. lm map[int64]*livemdl.RoomInfo
  589. ip = metadata.String(c, metadata.RemoteIP)
  590. )
  591. params := url.Values{}
  592. params.Set("keyword", keyword)
  593. params.Set("mobi_app", mobiApp)
  594. params.Set("platform", platform)
  595. params.Set("userid", strconv.FormatInt(mid, 10))
  596. params.Set("build", strconv.Itoa(build))
  597. params.Set("main_ver", "v3")
  598. params.Set("search_type", sType)
  599. params.Set("page", strconv.Itoa(pn))
  600. params.Set("live_room_num", strconv.Itoa(ps))
  601. params.Set("device", device)
  602. params.Set("order", order)
  603. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  604. params.Set("is_special_guide", "1")
  605. }
  606. // new request
  607. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  608. return
  609. }
  610. req.Header.Set("Buvid", buvid)
  611. var res struct {
  612. Code int `json:"code"`
  613. SeID string `json:"seid"`
  614. Pages int `json:"numPages"`
  615. PageInfo *struct {
  616. Master *search.Live `json:"live_master"`
  617. Room *search.Live `json:"live_room"`
  618. } `json:"pageinfo"`
  619. List *struct {
  620. Master []*search.Live `json:"live_master"`
  621. Room []*search.Live `json:"live_room"`
  622. } `json:"result"`
  623. }
  624. if err = d.client.Do(c, req, &res); err != nil {
  625. return
  626. }
  627. if res.Code != ecode.OK.Code() {
  628. if (model.IsAndroid(plat) && build > _searchCodeLimitAndroid) || (model.IsIPhone(plat) && build > _searchCodeLimitIPhone) || model.IsIPad(plat) || model.IsIPhoneB(plat) {
  629. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  630. } else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  631. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  632. }
  633. return
  634. }
  635. st = &search.TypeSearchLiveAll{
  636. TrackID: res.SeID,
  637. Pages: res.Pages,
  638. Master: &search.TypeSearch{},
  639. Room: &search.TypeSearch{},
  640. }
  641. if res.PageInfo != nil {
  642. if res.PageInfo.Master != nil {
  643. st.Master.Pages = res.PageInfo.Master.Pages
  644. st.Master.Total = res.PageInfo.Master.Total
  645. }
  646. if res.PageInfo.Room != nil {
  647. st.Room.Pages = res.PageInfo.Room.Pages
  648. st.Room.Total = res.PageInfo.Room.Total
  649. }
  650. }
  651. if res.List != nil {
  652. if !model.IsAndroid(plat) || (model.IsAndroid(plat) && build > search.LiveBroadcastTypeAndroid) {
  653. for _, v := range res.List.Master {
  654. roomIDs = append(roomIDs, v.RoomID)
  655. }
  656. for _, v := range res.List.Room {
  657. roomIDs = append(roomIDs, v.RoomID)
  658. }
  659. if len(roomIDs) > 0 {
  660. if lm, err = d.liveDao.LiveByRIDs(c, roomIDs); err != nil {
  661. log.Error("LiveAll %+v", err)
  662. err = nil
  663. }
  664. }
  665. }
  666. st.Master.Items = make([]*search.Item, 0, len(res.List.Master))
  667. for _, v := range res.List.Master {
  668. si := &search.Item{}
  669. si.FromLiveMaster(v, lm[v.RoomID])
  670. st.Master.Items = append(st.Master.Items, si)
  671. }
  672. st.Room.Items = make([]*search.Item, 0, len(res.List.Room))
  673. for _, v := range res.List.Room {
  674. si := &search.Item{}
  675. si.FromLive2(v, lm[v.RoomID])
  676. st.Room.Items = append(st.Room.Items, si)
  677. }
  678. }
  679. return
  680. }
  681. // ArticleByType search article.
  682. 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) {
  683. var (
  684. req *http.Request
  685. ip = metadata.String(c, metadata.RemoteIP)
  686. )
  687. params := url.Values{}
  688. params.Set("keyword", keyword)
  689. params.Set("mobi_app", mobiApp)
  690. params.Set("device", device)
  691. params.Set("platform", platform)
  692. params.Set("userid", strconv.FormatInt(mid, 10))
  693. params.Set("build", strconv.Itoa(build))
  694. params.Set("main_ver", "v3")
  695. params.Set("highlight", strconv.Itoa(highlight))
  696. params.Set("search_type", sType)
  697. params.Set("category_id", strconv.Itoa(categoryID))
  698. params.Set("page", strconv.Itoa(pn))
  699. params.Set("pagesize", strconv.Itoa(ps))
  700. params.Set("order", order)
  701. if filtered == "1" {
  702. params.Set("filtered", filtered)
  703. }
  704. if model.IsOverseas(plat) {
  705. params.Set("use_area", "1")
  706. params.Set("zone_id", strconv.FormatInt(zoneid, 10))
  707. }
  708. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  709. params.Set("is_special_guide", "1")
  710. }
  711. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  712. return
  713. }
  714. req.Header.Set("Buvid", buvid)
  715. var res struct {
  716. Code int `json:"code"`
  717. SeID string `json:"seid"`
  718. Pages int `json:"numPages"`
  719. List []*search.Article `json:"result"`
  720. }
  721. if err = d.client.Do(c, req, &res); err != nil {
  722. return
  723. }
  724. if res.Code != ecode.OK.Code() {
  725. if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  726. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  727. }
  728. return
  729. }
  730. items := make([]*search.Item, 0, len(res.List))
  731. for _, v := range res.List {
  732. si := &search.Item{}
  733. si.FromArticle(v, nil)
  734. items = append(items, si)
  735. }
  736. st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
  737. return
  738. }
  739. // HotSearch is hot words search data.
  740. 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) {
  741. ip := metadata.String(c, metadata.RemoteIP)
  742. params := url.Values{}
  743. params.Set("main_ver", "v3")
  744. params.Set("actionKey", "appkey")
  745. params.Set("limit", strconv.Itoa(limit))
  746. params.Set("build", strconv.Itoa(build))
  747. params.Set("mobi_app", mobiApp)
  748. params.Set("device", device)
  749. params.Set("platform", platform)
  750. params.Set("userid", strconv.FormatInt(mid, 10))
  751. req, err := d.client.NewRequest("GET", d.hot, ip, params)
  752. if err != nil {
  753. return
  754. }
  755. req.Header.Set("Buvid", buvid)
  756. if err = d.client.Do(c, req, &res); err != nil {
  757. return
  758. }
  759. if res.Code != ecode.OK.Code() {
  760. err = errors.Wrap(ecode.Int(res.Code), d.hot+"?"+params.Encode())
  761. }
  762. return
  763. }
  764. // Suggest suggest data.
  765. 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) {
  766. plat := model.Plat(mobiApp, device)
  767. ip := metadata.String(c, metadata.RemoteIP)
  768. params := url.Values{}
  769. params.Set("main_ver", "v4")
  770. params.Set("func", "suggest")
  771. params.Set("mobi_app", mobiApp)
  772. params.Set("device", device)
  773. params.Set("userid", strconv.FormatInt(mid, 10))
  774. params.Set("buvid", buvid)
  775. params.Set("build", strconv.Itoa(build))
  776. params.Set("mobi_app", mobiApp)
  777. params.Set("bangumi_acc_num", "3")
  778. params.Set("special_acc_num", "3")
  779. params.Set("topic_acc_num", "3")
  780. params.Set("upuser_acc_num", "1")
  781. params.Set("tag_num", "10")
  782. params.Set("special_num", "10")
  783. params.Set("bangumi_num", "10")
  784. params.Set("upuser_num", "3")
  785. params.Set("suggest_type", "accurate")
  786. params.Set("term", term)
  787. res = &search.Suggest{}
  788. if err = d.client.Get(c, d.suggest, ip, params, &res); err != nil {
  789. return
  790. }
  791. if res.Code != ecode.OK.Code() {
  792. 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) {
  793. err = errors.Wrap(ecode.Int(res.Code), d.suggest+"?"+params.Encode())
  794. } else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  795. err = errors.Wrap(ecode.Int(res.Code), d.suggest+"?"+params.Encode())
  796. }
  797. return
  798. }
  799. if res.ResultBs == nil {
  800. return
  801. }
  802. switch v := res.ResultBs.(type) {
  803. case []interface{}:
  804. return
  805. case map[string]interface{}:
  806. if acc, ok := v["accurate"]; ok {
  807. if accm, ok := acc.(map[string]interface{}); ok && accm != nil {
  808. res.Result.Accurate.UpUser = accm["upuser"]
  809. res.Result.Accurate.Bangumi = accm["bangumi"]
  810. }
  811. }
  812. if tag, ok := v["tag"]; ok {
  813. if tags, ok := tag.([]interface{}); ok {
  814. for _, t := range tags {
  815. if tm, ok := t.(map[string]interface{}); ok && tm != nil {
  816. if v, ok := tm["value"]; ok {
  817. if vs, ok := v.(string); ok {
  818. res.Result.Tag = append(res.Result.Tag, &struct {
  819. Value string `json:"value,omitempty"`
  820. }{vs})
  821. }
  822. }
  823. }
  824. }
  825. }
  826. }
  827. }
  828. return
  829. }
  830. // Suggest2 suggest data.
  831. 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) {
  832. ip := metadata.String(c, metadata.RemoteIP)
  833. params := url.Values{}
  834. params.Set("main_ver", "v4")
  835. params.Set("suggest_type", "accurate")
  836. params.Set("platform", platform)
  837. params.Set("mobi_app", mobiApp)
  838. params.Set("clientip", ip)
  839. params.Set("build", strconv.Itoa(build))
  840. if mid != 0 {
  841. params.Set("userid", strconv.FormatInt(mid, 10))
  842. }
  843. params.Set("term", term)
  844. params.Set("sug_num", "10")
  845. params.Set("buvid", buvid)
  846. res = &search.Suggest2{}
  847. if err = d.client.Get(c, d.suggest, ip, params, &res); err != nil {
  848. return
  849. }
  850. if res.Code != ecode.OK.Code() {
  851. err = errors.Wrap(ecode.Int(res.Code), d.suggest+"?"+params.Encode())
  852. }
  853. return
  854. }
  855. // Suggest3 suggest data.
  856. 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) {
  857. var (
  858. req *http.Request
  859. plat = model.Plat(mobiApp, device)
  860. ip = metadata.String(c, metadata.RemoteIP)
  861. )
  862. params := url.Values{}
  863. params.Set("suggest_type", "accurate")
  864. params.Set("platform", platform)
  865. params.Set("mobi_app", mobiApp)
  866. params.Set("clientip", ip)
  867. params.Set("highlight", strconv.Itoa(highlight))
  868. params.Set("build", strconv.Itoa(build))
  869. if mid != 0 {
  870. params.Set("userid", strconv.FormatInt(mid, 10))
  871. }
  872. params.Set("term", term)
  873. params.Set("sug_num", "10")
  874. params.Set("buvid", buvid)
  875. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SugDetailAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SugDetailIOS) {
  876. params.Set("is_detail_info", "1")
  877. }
  878. if req, err = d.client.NewRequest("GET", d.suggest3, ip, params); err != nil {
  879. return
  880. }
  881. req.Header.Set("Buvid", buvid)
  882. res = &search.Suggest3{}
  883. if err = d.client.Do(c, req, &res); err != nil {
  884. return
  885. }
  886. if res.Code != ecode.OK.Code() {
  887. err = errors.Wrap(ecode.Int(res.Code), d.suggest3+"?"+params.Encode())
  888. return
  889. }
  890. for _, flow := range res.Result {
  891. flow.SugChange()
  892. }
  893. return
  894. }
  895. // Season2 search new season data.
  896. 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) {
  897. var (
  898. req *http.Request
  899. plat = model.Plat(mobiApp, device)
  900. ip = metadata.String(c, metadata.RemoteIP)
  901. seasonIDs []int64
  902. bangumis map[string]*bangumimdl.Card
  903. )
  904. params := url.Values{}
  905. params.Set("main_ver", "v3")
  906. params.Set("platform", platform)
  907. params.Set("build", strconv.Itoa(build))
  908. params.Set("keyword", keyword)
  909. params.Set("userid", strconv.FormatInt(mid, 10))
  910. params.Set("mobi_app", mobiApp)
  911. params.Set("device", device)
  912. params.Set("page", strconv.Itoa(pn))
  913. params.Set("pagesize", strconv.Itoa(ps))
  914. params.Set("search_type", "media_bangumi")
  915. params.Set("order", "totalrank")
  916. params.Set("highlight", strconv.Itoa(highlight))
  917. params.Set("app_highlight", "media_bangumi")
  918. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.PGCALLAndroid) || (model.IsIPhone(plat) && build >= d.c.SearchBuildLimit.PGCALLIOS) || model.IsIPhoneB(plat) {
  919. params.Set("is_pgc_all", "1")
  920. }
  921. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  922. params.Set("is_special_guide", "1")
  923. }
  924. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  925. return
  926. }
  927. req.Header.Set("Buvid", buvid)
  928. var res struct {
  929. Code int `json:"code"`
  930. SeID string `json:"seid"`
  931. Total int `json:"numResults"`
  932. Pages int `json:"numPages"`
  933. List []*search.Media `json:"result"`
  934. }
  935. if err = d.client.Do(c, req, &res); err != nil {
  936. return
  937. }
  938. if res.Code != ecode.OK.Code() {
  939. 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) {
  940. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  941. } else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  942. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  943. }
  944. return
  945. }
  946. for _, v := range res.List {
  947. seasonIDs = append(seasonIDs, v.SeasonID)
  948. }
  949. if len(seasonIDs) > 0 {
  950. if bangumis, err = d.bangumiDao.Card(c, mid, seasonIDs); err != nil {
  951. log.Error("Season2 %+v", err)
  952. err = nil
  953. }
  954. }
  955. items := make([]*search.Item, 0, len(res.List))
  956. for _, v := range res.List {
  957. si := &search.Item{}
  958. si.FromMedia(v, "", model.GotoBangumi, bangumis)
  959. items = append(items, si)
  960. }
  961. st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Total: res.Total, Items: items}
  962. return
  963. }
  964. // MovieByType2 search new movie data from api .
  965. 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) {
  966. var (
  967. req *http.Request
  968. plat = model.Plat(mobiApp, device)
  969. ip = metadata.String(c, metadata.RemoteIP)
  970. seasonIDs []int64
  971. bangumis map[string]*bangumimdl.Card
  972. )
  973. params := url.Values{}
  974. params.Set("keyword", keyword)
  975. params.Set("mobi_app", mobiApp)
  976. params.Set("device", device)
  977. params.Set("platform", platform)
  978. params.Set("userid", strconv.FormatInt(mid, 10))
  979. params.Set("build", strconv.Itoa(build))
  980. params.Set("main_ver", "v3")
  981. params.Set("search_type", "media_ft")
  982. params.Set("page", strconv.Itoa(pn))
  983. params.Set("pagesize", strconv.Itoa(ps))
  984. params.Set("order", "totalrank")
  985. params.Set("highlight", strconv.Itoa(highlight))
  986. params.Set("app_highlight", "media_ft")
  987. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.PGCALLAndroid) || (model.IsIPhone(plat) && build >= d.c.SearchBuildLimit.PGCALLIOS) || model.IsIPhoneB(plat) {
  988. params.Set("is_pgc_all", "1")
  989. }
  990. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  991. params.Set("is_special_guide", "1")
  992. }
  993. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  994. return
  995. }
  996. req.Header.Set("Buvid", buvid)
  997. var res struct {
  998. Code int `json:"code"`
  999. SeID string `json:"seid"`
  1000. Total int `json:"numResults"`
  1001. Pages int `json:"numPages"`
  1002. List []*search.Media `json:"result"`
  1003. }
  1004. if err = d.client.Do(c, req, &res); err != nil {
  1005. return
  1006. }
  1007. if res.Code != ecode.OK.Code() {
  1008. 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) {
  1009. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  1010. } else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  1011. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  1012. }
  1013. return
  1014. }
  1015. for _, v := range res.List {
  1016. seasonIDs = append(seasonIDs, v.SeasonID)
  1017. }
  1018. if len(seasonIDs) > 0 {
  1019. if bangumis, err = d.bangumiDao.Card(c, mid, seasonIDs); err != nil {
  1020. log.Error("MovieByType2 %+v", err)
  1021. err = nil
  1022. }
  1023. }
  1024. items := make([]*search.Item, 0, len(res.List))
  1025. for _, v := range res.List {
  1026. si := &search.Item{}
  1027. si.FromMedia(v, "", model.GotoMovie, bangumis)
  1028. items = append(items, si)
  1029. }
  1030. st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Total: res.Total, Items: items}
  1031. return
  1032. }
  1033. // User search user data.
  1034. 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) {
  1035. var (
  1036. req *http.Request
  1037. plat = model.Plat(mobiApp, device)
  1038. ip = metadata.String(c, metadata.RemoteIP)
  1039. )
  1040. params := url.Values{}
  1041. params.Set("platform", platform)
  1042. params.Set("mobi_app", mobiApp)
  1043. params.Set("device", device)
  1044. params.Set("build", strconv.Itoa(build))
  1045. params.Set("userid", strconv.FormatInt(mid, 10))
  1046. params.Set("keyword", keyword)
  1047. params.Set("highlight", strconv.Itoa(highlight))
  1048. params.Set("page", strconv.Itoa(pn))
  1049. params.Set("pagesize", strconv.Itoa(ps))
  1050. params.Set("main_ver", "v3")
  1051. params.Set("func", "search")
  1052. params.Set("smerge", "1")
  1053. params.Set("source_type", "0")
  1054. params.Set("search_type", "bili_user")
  1055. params.Set("user_type", strconv.Itoa(userType))
  1056. params.Set("order", order)
  1057. params.Set("order_sort", strconv.Itoa(orderSort))
  1058. params.Set("from_source", fromSource)
  1059. if filtered == "1" {
  1060. params.Set("filtered", filtered)
  1061. }
  1062. // new request
  1063. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  1064. return
  1065. }
  1066. req.Header.Set("Buvid", buvid)
  1067. var res struct {
  1068. Code int `json:"code"`
  1069. SeID string `json:"seid"`
  1070. Pages int `json:"numPages"`
  1071. List []*search.User `json:"result"`
  1072. }
  1073. if err = d.client.Do(c, req, &res); err != nil {
  1074. return
  1075. }
  1076. if res.Code != ecode.OK.Code() {
  1077. 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) {
  1078. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  1079. } else if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  1080. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  1081. }
  1082. return
  1083. }
  1084. user = res.List
  1085. return
  1086. }
  1087. // Recommend is recommend search data.
  1088. func (d *Dao) Recommend(c context.Context, mid int64, build, from, show int, buvid, platform, mobiApp, device string) (res *search.RecommendResult, err error) {
  1089. ip := metadata.String(c, metadata.RemoteIP)
  1090. params := url.Values{}
  1091. params.Set("main_ver", "v3")
  1092. params.Set("platform", platform)
  1093. params.Set("mobi_app", mobiApp)
  1094. params.Set("clientip", ip)
  1095. params.Set("device", device)
  1096. params.Set("build", strconv.Itoa(build))
  1097. params.Set("userid", strconv.FormatInt(mid, 10))
  1098. params.Set("search_type", "guess")
  1099. params.Set("req_source", strconv.Itoa(from))
  1100. params.Set("show_area", strconv.Itoa(show))
  1101. req, err := d.client.NewRequest("GET", d.rcmd, ip, params)
  1102. if err != nil {
  1103. return
  1104. }
  1105. req.Header.Set("Buvid", buvid)
  1106. var rcmdRes struct {
  1107. Code int `json:"code,omitempty"`
  1108. SeID string `json:"seid,omitempty"`
  1109. Tips string `json:"recommend_tips,omitempty"`
  1110. NumResult int `json:"numResult,omitempty"`
  1111. Resutl []struct {
  1112. ID int64 `json:"id,omitempty"`
  1113. Name string `json:"name,omitempty"`
  1114. Type string `json:"type,omitempty"`
  1115. } `json:"result,omitempty"`
  1116. }
  1117. if err = d.client.Do(c, req, &rcmdRes); err != nil {
  1118. return
  1119. }
  1120. if rcmdRes.Code != ecode.OK.Code() {
  1121. if rcmdRes.Code != model.ForbidCode {
  1122. err = errors.Wrap(ecode.Int(rcmdRes.Code), d.rcmd+"?"+params.Encode())
  1123. }
  1124. return
  1125. }
  1126. res = &search.RecommendResult{TrackID: rcmdRes.SeID, Title: rcmdRes.Tips, Pages: rcmdRes.NumResult}
  1127. for _, v := range rcmdRes.Resutl {
  1128. item := &search.Item{}
  1129. item.ID = v.ID
  1130. item.Param = strconv.Itoa(int(v.ID))
  1131. item.Title = v.Name
  1132. item.Type = v.Type
  1133. res.Items = append(res.Items, item)
  1134. }
  1135. return
  1136. }
  1137. // DefaultWords is default words search data.
  1138. func (d *Dao) DefaultWords(c context.Context, mid int64, build, from int, buvid, platform, mobiApp, device string) (res *search.DefaultWords, err error) {
  1139. ip := metadata.String(c, metadata.RemoteIP)
  1140. params := url.Values{}
  1141. params.Set("main_ver", "v3")
  1142. params.Set("platform", platform)
  1143. params.Set("mobi_app", mobiApp)
  1144. params.Set("clientip", ip)
  1145. params.Set("device", device)
  1146. params.Set("build", strconv.Itoa(build))
  1147. params.Set("userid", strconv.FormatInt(mid, 10))
  1148. params.Set("search_type", "default")
  1149. params.Set("req_source", strconv.Itoa(from))
  1150. req, err := d.client.NewRequest("GET", d.rcmd, ip, params)
  1151. if err != nil {
  1152. return
  1153. }
  1154. req.Header.Set("Buvid", buvid)
  1155. var rcmdRes struct {
  1156. Code int `json:"code,omitempty"`
  1157. SeID string `json:"seid,omitempty"`
  1158. Tips string `json:"recommend_tips,omitempty"`
  1159. NumResult int `json:"numResult,omitempty"`
  1160. ShowFront int `json:"show_front,omitempty"`
  1161. Resutl []struct {
  1162. ID int64 `json:"id,omitempty"`
  1163. Name string `json:"name,omitempty"`
  1164. ShowName string `json:"show_name,omitempty"`
  1165. Type string `json:"type,omitempty"`
  1166. } `json:"result,omitempty"`
  1167. }
  1168. if err = d.client.Do(c, req, &rcmdRes); err != nil {
  1169. return
  1170. }
  1171. if rcmdRes.Code != ecode.OK.Code() {
  1172. if rcmdRes.Code != model.ForbidCode {
  1173. err = errors.Wrap(ecode.Int(rcmdRes.Code), d.rcmd+"?"+params.Encode())
  1174. }
  1175. return
  1176. }
  1177. if len(rcmdRes.Resutl) == 0 {
  1178. err = ecode.NothingFound
  1179. return
  1180. }
  1181. res = &search.DefaultWords{}
  1182. for _, v := range rcmdRes.Resutl {
  1183. res.Trackid = rcmdRes.SeID
  1184. res.Param = strconv.Itoa(int(v.ID))
  1185. res.Show = v.ShowName
  1186. res.Word = v.Name
  1187. res.ShowFront = rcmdRes.ShowFront
  1188. }
  1189. return
  1190. }
  1191. // RecommendNoResult is no result recommend search data.
  1192. func (d *Dao) RecommendNoResult(c context.Context, platform, mobiApp, device, buvid, keyword string, build, pn, ps int, mid int64) (res *search.NoResultRcndResult, err error) {
  1193. ip := metadata.String(c, metadata.RemoteIP)
  1194. params := url.Values{}
  1195. params.Set("main_ver", "v3")
  1196. params.Set("platform", platform)
  1197. params.Set("mobi_app", mobiApp)
  1198. params.Set("clientip", ip)
  1199. params.Set("device", device)
  1200. params.Set("build", strconv.Itoa(build))
  1201. params.Set("userid", strconv.FormatInt(mid, 10))
  1202. params.Set("search_type", "video")
  1203. params.Set("keyword", keyword)
  1204. params.Set("page", strconv.Itoa(pn))
  1205. params.Set("pagesize", strconv.Itoa(ps))
  1206. req, err := d.client.NewRequest("GET", d.rcmdNoResult, ip, params)
  1207. if err != nil {
  1208. return
  1209. }
  1210. req.Header.Set("Buvid", buvid)
  1211. var (
  1212. resTmp *search.NoResultRcmd
  1213. avids []int64
  1214. avm map[int64]*api.Arc
  1215. cooperation bool
  1216. )
  1217. if err = d.client.Do(c, req, &resTmp); err != nil {
  1218. return
  1219. }
  1220. if resTmp.Code != ecode.OK.Code() {
  1221. if resTmp.Code != model.ForbidCode {
  1222. err = errors.Wrap(ecode.Int(resTmp.Code), d.rcmdNoResult+"?"+params.Encode())
  1223. }
  1224. return
  1225. }
  1226. res = &search.NoResultRcndResult{TrackID: resTmp.Trackid, Title: resTmp.RecommendTips, Pages: resTmp.NumResults}
  1227. for _, v := range resTmp.Result {
  1228. avids = append(avids, v.ID)
  1229. }
  1230. if len(avids) != 0 {
  1231. if avm, err = d.arcDao.Archives2(c, avids); err != nil {
  1232. log.Error("RecommendNoResult %+v", err)
  1233. err = nil
  1234. }
  1235. }
  1236. items := make([]*search.Item, 0, len(resTmp.Result))
  1237. for _, v := range resTmp.Result {
  1238. ri := &search.Item{}
  1239. ri.FromVideo(v, avm[v.ID], cooperation)
  1240. items = append(items, ri)
  1241. }
  1242. res.Items = items
  1243. return
  1244. }
  1245. // Channel for search channel
  1246. 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) {
  1247. var (
  1248. req *http.Request
  1249. plat = model.Plat(mobiApp, device)
  1250. ip = metadata.String(c, metadata.RemoteIP)
  1251. )
  1252. params := url.Values{}
  1253. params.Set("keyword", keyword)
  1254. params.Set("mobi_app", mobiApp)
  1255. params.Set("platform", platform)
  1256. params.Set("userid", strconv.FormatInt(mid, 10))
  1257. params.Set("build", strconv.Itoa(build))
  1258. params.Set("main_ver", "v3")
  1259. params.Set("search_type", sType)
  1260. params.Set("page", strconv.Itoa(pn))
  1261. params.Set("pagesize", strconv.Itoa(ps))
  1262. params.Set("device", device)
  1263. params.Set("order", order)
  1264. params.Set("highlight", strconv.Itoa(highlight))
  1265. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  1266. params.Set("is_special_guide", "1")
  1267. }
  1268. // new request
  1269. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  1270. return
  1271. }
  1272. req.Header.Set("Buvid", buvid)
  1273. var res struct {
  1274. Code int `json:"code"`
  1275. SeID string `json:"seid"`
  1276. Pages int `json:"numPages"`
  1277. List []*search.Channel `json:"result"`
  1278. }
  1279. if err = d.client.Do(c, req, &res); err != nil {
  1280. return
  1281. }
  1282. if res.Code != ecode.OK.Code() {
  1283. if res.Code != model.ForbidCode && res.Code != model.NoResultCode {
  1284. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  1285. }
  1286. return
  1287. }
  1288. items := make([]*search.Item, 0, len(res.List))
  1289. for _, v := range res.List {
  1290. si := &search.Item{}
  1291. avm := make(map[int64]*api.Arc)
  1292. bangumis := make(map[int32]*seasongrpc.CardInfoProto)
  1293. lm := make(map[int64]*livemdl.RoomInfo)
  1294. si.FromChannel(v, avm, bangumis, lm, nil)
  1295. items = append(items, si)
  1296. }
  1297. st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Items: items}
  1298. return
  1299. }
  1300. // RecommendPre search at pre-page
  1301. func (d *Dao) RecommendPre(c context.Context, platform, mobiApp, device, buvid string, build, ps int, mid int64) (res *search.RecommendPreResult, err error) {
  1302. ip := metadata.String(c, metadata.RemoteIP)
  1303. params := url.Values{}
  1304. params.Set("main_ver", "v3")
  1305. params.Set("platform", platform)
  1306. params.Set("mobi_app", mobiApp)
  1307. params.Set("clientip", ip)
  1308. params.Set("device", device)
  1309. params.Set("build", strconv.Itoa(build))
  1310. params.Set("userid", strconv.FormatInt(mid, 10))
  1311. params.Set("search_type", "discover_page")
  1312. params.Set("pagesize", strconv.Itoa(ps))
  1313. req, err := d.client.NewRequest("GET", d.pre, ip, params)
  1314. if err != nil {
  1315. return
  1316. }
  1317. req.Header.Set("Buvid", buvid)
  1318. var (
  1319. resTmp *search.RecommendPre
  1320. avids []int64
  1321. avm map[int64]*api.Arc
  1322. seasonIDs []int32
  1323. bangumis map[int32]*seasongrpc.CardInfoProto
  1324. )
  1325. if err = d.client.Do(c, req, &resTmp); err != nil {
  1326. return
  1327. }
  1328. if resTmp.Code != ecode.OK.Code() {
  1329. if resTmp.Code != model.ForbidCode {
  1330. err = errors.Wrap(ecode.Int(resTmp.Code), d.pre+"?"+params.Encode())
  1331. }
  1332. return
  1333. }
  1334. for _, v := range resTmp.Result {
  1335. for _, vv := range v.List {
  1336. if vv.Type == "video" {
  1337. avids = append(avids, vv.ID)
  1338. } else if vv.Type == "pgc" {
  1339. seasonIDs = append(seasonIDs, int32(vv.ID))
  1340. }
  1341. }
  1342. }
  1343. g, ctx := errgroup.WithContext(c)
  1344. if len(avids) != 0 {
  1345. g.Go(func() (err error) {
  1346. if avm, err = d.arcDao.Archives2(ctx, avids); err != nil {
  1347. log.Error("RecommendPre avids(%v) error(%v)", avids, err)
  1348. err = nil
  1349. }
  1350. return
  1351. })
  1352. }
  1353. if len(seasonIDs) > 0 {
  1354. g.Go(func() (err error) {
  1355. if bangumis, err = d.bangumiDao.Cards(c, seasonIDs); err != nil {
  1356. log.Error("RecommendPre seasonIDs(%v) error(%v)", seasonIDs, err)
  1357. err = nil
  1358. }
  1359. return
  1360. })
  1361. }
  1362. if err = g.Wait(); err != nil {
  1363. log.Error("%+v", err)
  1364. return
  1365. }
  1366. res = &search.RecommendPreResult{TrackID: resTmp.Trackid, Total: resTmp.NumResult}
  1367. items := make([]*search.Item, 0, len(resTmp.Result))
  1368. for _, v := range resTmp.Result {
  1369. rs := &search.Item{Title: v.Query}
  1370. for _, vv := range v.List {
  1371. if vv.Type == "video" {
  1372. if a, ok := avm[vv.ID]; ok {
  1373. r := &search.Item{}
  1374. r.FromRcmdPre(vv.ID, a, nil)
  1375. rs.Item = append(rs.Item, r)
  1376. }
  1377. } else if vv.Type == "pgc" {
  1378. if b, ok := bangumis[int32(vv.ID)]; ok {
  1379. r := &search.Item{}
  1380. r.FromRcmdPre(vv.ID, nil, b)
  1381. rs.Item = append(rs.Item, r)
  1382. }
  1383. }
  1384. }
  1385. items = append(items, rs)
  1386. }
  1387. res.Items = items
  1388. return
  1389. }
  1390. // Video search new archive data.
  1391. 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) {
  1392. var (
  1393. req *http.Request
  1394. ip = metadata.String(c, metadata.RemoteIP)
  1395. plat = model.Plat(mobiApp, device)
  1396. avids []int64
  1397. avm map[int64]*api.Arc
  1398. cooperation bool
  1399. )
  1400. params := url.Values{}
  1401. params.Set("main_ver", "v3")
  1402. params.Set("platform", platform)
  1403. params.Set("build", strconv.Itoa(build))
  1404. params.Set("keyword", keyword)
  1405. params.Set("userid", strconv.FormatInt(mid, 10))
  1406. params.Set("mobi_app", mobiApp)
  1407. params.Set("device", device)
  1408. params.Set("page", strconv.Itoa(pn))
  1409. params.Set("pagesize", strconv.Itoa(ps))
  1410. params.Set("search_type", "video")
  1411. params.Set("order", "totalrank")
  1412. params.Set("highlight", strconv.Itoa(highlight))
  1413. if (model.IsAndroid(plat) && build > d.c.SearchBuildLimit.SpecialerGuideAndroid) || (model.IsIPhone(plat) && build > d.c.SearchBuildLimit.SpecialerGuideIOS) {
  1414. params.Set("is_special_guide", "1")
  1415. }
  1416. if req, err = d.client.NewRequest("GET", d.main, ip, params); err != nil {
  1417. return
  1418. }
  1419. req.Header.Set("Buvid", buvid)
  1420. var res struct {
  1421. Code int `json:"code"`
  1422. SeID string `json:"seid"`
  1423. Total int `json:"numResults"`
  1424. Pages int `json:"numPages"`
  1425. List []*search.Video `json:"result"`
  1426. }
  1427. if err = d.client.Do(c, req, &res); err != nil {
  1428. return
  1429. }
  1430. if res.Code != ecode.OK.Code() {
  1431. err = errors.Wrap(ecode.Int(res.Code), d.main+"?"+params.Encode())
  1432. return
  1433. }
  1434. for _, v := range res.List {
  1435. avids = append(avids, v.ID)
  1436. }
  1437. if len(avids) > 0 {
  1438. if avm, err = d.arcDao.Archives2(c, avids); err != nil {
  1439. log.Error("Upper %+v", err)
  1440. err = nil
  1441. }
  1442. }
  1443. items := make([]*search.Item, 0, len(res.List))
  1444. for _, v := range res.List {
  1445. si := &search.Item{}
  1446. si.FromVideo(v, avm[v.ID], cooperation)
  1447. items = append(items, si)
  1448. }
  1449. st = &search.TypeSearch{TrackID: res.SeID, Pages: res.Pages, Total: res.Total, Items: items}
  1450. return
  1451. }