Create & Init Project...
This commit is contained in:
41
app/interface/main/tv/model/search/BUILD
Normal file
41
app/interface/main/tv/model/search/BUILD
Normal file
@ -0,0 +1,41 @@
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load(
|
||||
"@io_bazel_rules_go//go:def.bzl",
|
||||
"go_library",
|
||||
)
|
||||
|
||||
go_library(
|
||||
name = "go_default_library",
|
||||
srcs = [
|
||||
"client.go",
|
||||
"elastic.go",
|
||||
"result.go",
|
||||
"sug.go",
|
||||
"wild.go",
|
||||
],
|
||||
importpath = "go-common/app/interface/main/tv/model/search",
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//app/interface/main/tv/model:go_default_library",
|
||||
"//app/interface/main/tv/model/thirdp:go_default_library",
|
||||
"//app/service/main/archive/api:go_default_library",
|
||||
"//library/time:go_default_library",
|
||||
"//vendor/github.com/siddontang/go-mysql/mysql:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "package-srcs",
|
||||
srcs = glob(["**"]),
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:private"],
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "all-srcs",
|
||||
srcs = [":package-srcs"],
|
||||
tags = ["automanaged"],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
17
app/interface/main/tv/model/search/client.go
Normal file
17
app/interface/main/tv/model/search/client.go
Normal file
@ -0,0 +1,17 @@
|
||||
package search
|
||||
|
||||
//RespForClient def.
|
||||
type RespForClient struct {
|
||||
*ResultResponse
|
||||
SearchType string `json:"search_type"`
|
||||
PageInfo *pageinfo `json:"pageinfo"`
|
||||
ResultAll *AllForClient `json:"resultall"`
|
||||
PGC []*CommonResult `json:"pgc"`
|
||||
UGC []*CommonResult `json:"ugc"`
|
||||
}
|
||||
|
||||
//AllForClient def.
|
||||
type AllForClient struct {
|
||||
Pgc []*CommonResult `json:"tvpgc"`
|
||||
Ugc []*CommonResult `json:"tvugc"`
|
||||
}
|
266
app/interface/main/tv/model/search/elastic.go
Normal file
266
app/interface/main/tv/model/search/elastic.go
Normal file
@ -0,0 +1,266 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"go-common/app/interface/main/tv/model"
|
||||
"go-common/app/interface/main/tv/model/thirdp"
|
||||
"go-common/library/time"
|
||||
|
||||
"github.com/siddontang/go-mysql/mysql"
|
||||
)
|
||||
|
||||
const (
|
||||
_pgcType = 1
|
||||
_ugcType = 2
|
||||
_hotestOrder = 2
|
||||
// AllLabel is the string that means all data
|
||||
AllLabel = "-1" // it means all for index
|
||||
)
|
||||
|
||||
// EsPage def.
|
||||
type EsPage struct {
|
||||
Num int `json:"num"`
|
||||
Size int `json:"size"`
|
||||
Total int `json:"total"`
|
||||
PageNum int `json:"page_num"`
|
||||
}
|
||||
|
||||
// GetPageNb def.
|
||||
func (v *EsPage) GetPageNb() {
|
||||
if v.Total%v.Size == 0 {
|
||||
v.PageNum = v.Total / v.Size
|
||||
} else {
|
||||
v.PageNum = v.Total/v.Size + 1
|
||||
}
|
||||
}
|
||||
|
||||
// EsPgcResult def.
|
||||
type EsPgcResult struct {
|
||||
Page *EsPage `json:"page"`
|
||||
Result []*PgcEsMdl `json:"result"`
|
||||
}
|
||||
|
||||
// EsUgcResult def.
|
||||
type EsUgcResult struct {
|
||||
Page *EsPage `json:"page"`
|
||||
Result []*UgcEsMdl `json:"result"`
|
||||
}
|
||||
|
||||
// UgcEsMdl def.
|
||||
type UgcEsMdl struct {
|
||||
AID int64 `json:"aid"`
|
||||
TypeID int32 `json:"typeid"`
|
||||
}
|
||||
|
||||
// PgcEsMdl def.
|
||||
type PgcEsMdl struct {
|
||||
SeasonID int64 `json:"season_id"`
|
||||
}
|
||||
|
||||
// EsCard def.
|
||||
type EsCard struct {
|
||||
model.Card
|
||||
DataType int `json:"data_type"` // 1=pgc, 2=ugc
|
||||
}
|
||||
|
||||
// EsPager def.
|
||||
type EsPager struct {
|
||||
Title string `json:"title"`
|
||||
Page *EsPage `json:"page"`
|
||||
Result []*EsCard `json:"result"`
|
||||
}
|
||||
|
||||
// FromPgc def.
|
||||
func (v *EsCard) FromPgc(card *model.Card) {
|
||||
v.Card = *card
|
||||
v.DataType = _pgcType
|
||||
}
|
||||
|
||||
// FromUgc def.
|
||||
func (v *EsCard) FromUgc(card *model.Card) {
|
||||
v.Card = *card
|
||||
v.DataType = _ugcType
|
||||
}
|
||||
|
||||
// ReqEsPn is part of the es request for page related cfg
|
||||
type ReqEsPn struct {
|
||||
Ps int `form:"ps" default:"50"`
|
||||
Pn int `form:"pn" default:"1"`
|
||||
Order int `form:"order" validate:"required"`
|
||||
Sort int `form:"sort" default:"0"`
|
||||
}
|
||||
|
||||
// ReqPgcIdx is bm request for pgc index
|
||||
type ReqPgcIdx struct {
|
||||
SeasonType int `form:"category" validate:"required,max=5"`
|
||||
ProducerID int `form:"producer_id"`
|
||||
Year string `form:"year"`
|
||||
StyleID int `form:"style_id"`
|
||||
PubDate string `form:"pub_date"`
|
||||
SeasonMonth int `form:"season_month" validate:"max=10"`
|
||||
SeasonStatus []int `form:"season_status,split"`
|
||||
Copyright []int `form:"copyright,split"`
|
||||
IsFinish string `form:"is_finish"`
|
||||
Area []int `form:"area,split"`
|
||||
SeasonVersion int `form:"season_version"`
|
||||
ReqEsPn
|
||||
}
|
||||
|
||||
// IsDefault def.
|
||||
func (v *ReqPgcIdx) IsDefault() bool {
|
||||
return v.Order == _hotestOrder && v.ProducerID <= 0 &&
|
||||
v.IsAllStr(v.Year) && v.StyleID <= 0 && v.IsAllStr(v.PubDate) && v.SeasonMonth <= 0 &&
|
||||
v.IsAll(v.SeasonStatus) && v.IsAll(v.Copyright) && v.IsAllStr(v.IsFinish) && v.IsAll(v.Area) &&
|
||||
v.SeasonVersion <= 0
|
||||
}
|
||||
|
||||
// IsDefault def.
|
||||
func (v *ReqUgcIdx) IsDefault() bool {
|
||||
return v.Order == _hotestOrder && v.SecondTID <= 0 && (v.PubTime == "" || v.PubTime == AllLabel)
|
||||
}
|
||||
|
||||
// Title def.
|
||||
func (v *ReqPgcIdx) Title() string {
|
||||
return thirdp.PgcCat(v.SeasonType)
|
||||
}
|
||||
|
||||
// PgcOrder treats the order to get the responding field
|
||||
func (v *ReqPgcIdx) PgcOrder() (field string) {
|
||||
switch v.Order {
|
||||
case 0: // update time
|
||||
return "latest_time"
|
||||
case 1:
|
||||
return "dm_count"
|
||||
case 2:
|
||||
return "play_count"
|
||||
case 3: // follow
|
||||
return "fav_count"
|
||||
case 4:
|
||||
return "score"
|
||||
case 5: // for others
|
||||
return "pub_time"
|
||||
case 6: // for movie
|
||||
return "release_date"
|
||||
default:
|
||||
return "play_count"
|
||||
}
|
||||
}
|
||||
|
||||
// IdxSort treats the sort
|
||||
func IdxSort(sortV int) (sort string) {
|
||||
switch sortV {
|
||||
case 0:
|
||||
return "desc"
|
||||
case 1:
|
||||
return "asc"
|
||||
default:
|
||||
return "desc"
|
||||
}
|
||||
}
|
||||
|
||||
// ReqUgcIdx is bm request for ugc index
|
||||
type ReqUgcIdx struct {
|
||||
ParentTID int32 `form:"category" validate:"required"`
|
||||
SecondTID int32 `form:"typeid"`
|
||||
PubTime string `form:"pubtime"`
|
||||
ReqEsPn
|
||||
}
|
||||
|
||||
// TimeStr picks json str from request and returns the time range struct in String format
|
||||
func (v *ReqUgcIdx) TimeStr() (res *UgcTime, err error) {
|
||||
var pubTimeV = &UgcTimeV{}
|
||||
if err = json.Unmarshal([]byte(v.PubTime), &pubTimeV); err != nil {
|
||||
return
|
||||
}
|
||||
res = &UgcTime{
|
||||
STime: pubTimeV.STime.Time().Format(mysql.TimeFormat),
|
||||
ETime: pubTimeV.ETime.Time().Format(mysql.TimeFormat),
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// UgcTimeV def. INT64 for http
|
||||
type UgcTimeV struct {
|
||||
STime time.Time `json:"stime"`
|
||||
ETime time.Time `json:"etime"`
|
||||
}
|
||||
|
||||
// UgcTime def. STRING for ES
|
||||
type UgcTime struct {
|
||||
STime string `json:"stime"`
|
||||
ETime string `json:"etime"`
|
||||
}
|
||||
|
||||
// SrvUgcIdx is the request treated by service for DAO, like type_id field and pub_time
|
||||
type SrvUgcIdx struct {
|
||||
TIDs []int32
|
||||
PubTime *UgcTime
|
||||
ReqEsPn
|
||||
}
|
||||
|
||||
// UgcOrder treats the order to get the responding field
|
||||
func (v *SrvUgcIdx) UgcOrder() (field string) {
|
||||
switch v.Order {
|
||||
case 1: // update time
|
||||
return "pubtime"
|
||||
case 2:
|
||||
return "click"
|
||||
default:
|
||||
return "click"
|
||||
}
|
||||
}
|
||||
|
||||
// ReqIdxInterv is used for index intervention treatment
|
||||
type ReqIdxInterv struct {
|
||||
EsIDs []int64
|
||||
Category int
|
||||
IsPGC bool
|
||||
Pn int
|
||||
}
|
||||
|
||||
// FromPGC def.
|
||||
func (v *ReqIdxInterv) FromPGC(sids []int64, req *ReqPgcIdx) {
|
||||
v.EsIDs = sids
|
||||
v.Category = req.SeasonType
|
||||
v.IsPGC = true
|
||||
v.Pn = req.Pn
|
||||
}
|
||||
|
||||
// FromUGC def.
|
||||
func (v *ReqIdxInterv) FromUGC(aids []int64, req *ReqUgcIdx) {
|
||||
v.EsIDs = aids
|
||||
v.Category = int(req.ParentTID)
|
||||
v.IsPGC = false
|
||||
v.Pn = req.Pn
|
||||
}
|
||||
|
||||
// IdxIntervSave def.
|
||||
type IdxIntervSave struct {
|
||||
Pgc map[int][]int64
|
||||
Ugc map[int][]int64
|
||||
}
|
||||
|
||||
// IsAll checks whether a slice of int means all data
|
||||
func (v *ReqPgcIdx) IsAll(params []int) (res bool) {
|
||||
if len(params) == 0 {
|
||||
return true
|
||||
}
|
||||
for _, v := range params {
|
||||
if v < 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsAllStr checks whether a string means all data
|
||||
func (v *ReqPgcIdx) IsAllStr(duration string) (res bool) {
|
||||
if duration == "" {
|
||||
return true
|
||||
}
|
||||
if duration == AllLabel {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
113
app/interface/main/tv/model/search/result.go
Normal file
113
app/interface/main/tv/model/search/result.go
Normal file
@ -0,0 +1,113 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"go-common/app/interface/main/tv/model"
|
||||
)
|
||||
|
||||
// ResultResponse def .
|
||||
type ResultResponse struct {
|
||||
Page int `json:"page"`
|
||||
Pagesize int `json:"pagesize"`
|
||||
NumResults int `json:"numResults"`
|
||||
NumPages int `json:"numPages"`
|
||||
Seid string `json:"seid"`
|
||||
}
|
||||
|
||||
type pageinfo struct {
|
||||
Tvpgc *Page `json:"tvpgc"`
|
||||
Tvugc *Page `json:"tvugc"`
|
||||
}
|
||||
|
||||
// Page struct .
|
||||
type Page struct {
|
||||
NumResult int `json:"numResults"`
|
||||
Total int `json:"total"`
|
||||
Pages int `json:"pages"`
|
||||
}
|
||||
|
||||
// RespAll def .
|
||||
type RespAll struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
*ResultResponse
|
||||
PageInfo *pageinfo `json:"pageinfo"`
|
||||
Result *AllResult `json:"result"`
|
||||
}
|
||||
|
||||
// AllResult def .
|
||||
type AllResult struct {
|
||||
Pgc []*PgcResult `json:"tvpgc"`
|
||||
Ugc []*UgcResult `json:"tvugc"`
|
||||
}
|
||||
|
||||
// RespPgc def .
|
||||
type RespPgc struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
*ResultResponse
|
||||
Result []*PgcResult `json:"result"`
|
||||
}
|
||||
|
||||
// RespUgc def .
|
||||
type RespUgc struct {
|
||||
Code int `json:"code"`
|
||||
Msg string `json:"msg"`
|
||||
*ResultResponse
|
||||
Result []*UgcResult `json:"result"`
|
||||
}
|
||||
|
||||
// UgcResult def .
|
||||
type UgcResult struct {
|
||||
ID int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Cover string `json:"cover"`
|
||||
Description string `json:"description"`
|
||||
Pubtime int `json:"pubtime"`
|
||||
Category int `json:"category"`
|
||||
}
|
||||
|
||||
// PgcResult def .
|
||||
type PgcResult struct {
|
||||
*UgcResult
|
||||
CV string `json:"cv"`
|
||||
Staff string `json:"staff"`
|
||||
CornerMark *model.SnVipCorner `json:"cornermark"`
|
||||
}
|
||||
|
||||
// ToCommon transform pgc to common .
|
||||
func (p *PgcResult) ToCommon() (res *CommonResult) {
|
||||
return &CommonResult{
|
||||
PgcResult: p,
|
||||
Type: "pgc",
|
||||
}
|
||||
}
|
||||
|
||||
// ToCommon transform pgc to common .
|
||||
func (p *UgcResult) ToCommon() (res *CommonResult) {
|
||||
res = &CommonResult{}
|
||||
res.PgcResult = &PgcResult{
|
||||
UgcResult: p,
|
||||
}
|
||||
res.Type = "ugc"
|
||||
return
|
||||
}
|
||||
|
||||
// CommonResult is the common result for both pgc & ugc .
|
||||
type CommonResult struct {
|
||||
*PgcResult
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// ReqSearch def .
|
||||
type ReqSearch struct {
|
||||
SearchType string `form:"search_type" validate:"required"`
|
||||
Order string `form:"order"`
|
||||
Category int `form:"category"`
|
||||
Platform string `form:"platform" validate:"required"`
|
||||
Build string `form:"build" validate:"required"`
|
||||
MobiAPP string `form:"mobi_app"`
|
||||
Device string `form:"device"`
|
||||
Keyword string `form:"keyword" validate:"required"`
|
||||
Page int `form:"page" validate:"required,min=1"`
|
||||
Pagesize int `form:"pagesize"`
|
||||
}
|
55
app/interface/main/tv/model/search/sug.go
Normal file
55
app/interface/main/tv/model/search/sug.go
Normal file
@ -0,0 +1,55 @@
|
||||
package search
|
||||
|
||||
// SugResponse is the structure of search api response
|
||||
type SugResponse struct {
|
||||
Code int `json:"code"`
|
||||
Cost *Cost `json:"cost"`
|
||||
Result *Result `json:"result"`
|
||||
PageCaches *PageCaches `json:"page caches"`
|
||||
Sengine *Sengine `json:"sengine"`
|
||||
Stoken string `json:"stoken"`
|
||||
}
|
||||
|
||||
// Cost def.
|
||||
type Cost struct {
|
||||
About *About `json:"about"`
|
||||
}
|
||||
|
||||
// About def.
|
||||
type About struct {
|
||||
ParamsCheck string `json:"params_check"`
|
||||
Total string `json:"total"`
|
||||
MainHandler string `json:"main_handler"`
|
||||
}
|
||||
|
||||
// Result def.
|
||||
type Result struct {
|
||||
Tag []*STag `json:"tag"`
|
||||
}
|
||||
|
||||
// STag def.
|
||||
type STag struct {
|
||||
Value string `json:"value"`
|
||||
Ref int `json:"ref"`
|
||||
Name string `json:"name"`
|
||||
Spid int `json:"spid"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// PageCaches def.
|
||||
type PageCaches struct {
|
||||
SaveCache string `json:"save cache"`
|
||||
}
|
||||
|
||||
// Sengine def.
|
||||
type Sengine struct {
|
||||
Usage int `json:"usage"`
|
||||
}
|
||||
|
||||
// ReqSug def.
|
||||
type ReqSug struct {
|
||||
MobiApp string `form:"mobi_app"`
|
||||
Build string `form:"build"`
|
||||
Platform string `form:"platform"`
|
||||
Term string `form:"term" validate:"required"`
|
||||
}
|
647
app/interface/main/tv/model/search/wild.go
Normal file
647
app/interface/main/tv/model/search/wild.go
Normal file
@ -0,0 +1,647 @@
|
||||
package search
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
v1 "go-common/app/service/main/archive/api"
|
||||
xtime "go-common/library/time"
|
||||
)
|
||||
|
||||
// default .
|
||||
const (
|
||||
GotoBangumi = "bangumi"
|
||||
GotoAv = "av"
|
||||
GotoWeb = "web"
|
||||
GotoMovie = "movie"
|
||||
GotoBangumiWeb = "bangumi_web"
|
||||
GotoSp = "sp"
|
||||
GotoLive = "live"
|
||||
GotoGame = "game"
|
||||
GotoAuthor = "author"
|
||||
GotoClip = "clip"
|
||||
GotoAlbum = "album"
|
||||
GotoArticle = "article"
|
||||
GotoAudio = "audio"
|
||||
GotoSpecial = "special"
|
||||
GotoBanner = "banner"
|
||||
GotoSpecialS = "special_s"
|
||||
GotoConverge = "converge"
|
||||
GotoPGC = "pgc"
|
||||
GotoChannel = "channel"
|
||||
GotoEP = "ep"
|
||||
GotoTwitter = "twitter"
|
||||
|
||||
CoverIng = "即将上映"
|
||||
CoverPay = "付费观看"
|
||||
CoverFree = "免费观看"
|
||||
CoverVipFree = "付费观看"
|
||||
CoverVipOnly = "专享"
|
||||
CoverVipFirst = "抢先"
|
||||
)
|
||||
|
||||
// UserSearch user search request .
|
||||
type UserSearch struct {
|
||||
SearchType string `form:"search_type" validate:"required"`
|
||||
Order string `form:"order"`
|
||||
Category int `form:"category"`
|
||||
Platform string `form:"platform"`
|
||||
Build string `form:"build"`
|
||||
MobiAPP string `form:"mobi_app"`
|
||||
Device string `form:"device"`
|
||||
Keyword string `form:"keyword" validate:"required"`
|
||||
Page int `form:"page" validate:"required,min=1"`
|
||||
Pagesize int `form:"pagesize"`
|
||||
UserType int `form:"user_type"`
|
||||
Highlight int `form:"highlight"`
|
||||
OrderSort int `form:"order_sort"`
|
||||
FromSource string `form:"from_source"`
|
||||
Buvid string `form:"buvid"`
|
||||
Duration int `form:"duration"` // 视频时长
|
||||
// 传递参数,给到dao用
|
||||
SeasonNum int `form:"season_num"`
|
||||
MovieNum int `form:"movie_num"`
|
||||
RID int `form:"rid"`
|
||||
MID int64 `form:"mid"`
|
||||
}
|
||||
|
||||
// User struct res .
|
||||
type User struct {
|
||||
Type string `json:"type"`
|
||||
Mid int64 `json:"mid,omitempty"`
|
||||
Name string `json:"uname,omitempty"`
|
||||
Usign string `json:"usign,omitempty"`
|
||||
Fans int `json:"fans,omitempty"`
|
||||
Videos int `json:"videos,omitempty"`
|
||||
Pic string `json:"upic,omitempty"`
|
||||
VerifyInfo string `json:"verify_info"`
|
||||
Level int `json:"level,omitempty"`
|
||||
Gender int `json:"gender"`
|
||||
IsUpuser int `json:"is_upuser,omitempty"`
|
||||
IsLive int `json:"is_live,omitempty"`
|
||||
RoomID int64 `json:"room_id,omitempty"`
|
||||
Res []*struct {
|
||||
Aid int64 `json:"aid,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Pubdate int64 `json:"pubdate,omitempty"`
|
||||
ArcURL string `json:"arcurl,omitempty"`
|
||||
Pic string `json:"pic,omitempty"`
|
||||
Play interface{} `json:"play,omitempty"`
|
||||
Danmaku int `json:"dm,omitempty"`
|
||||
Coin int `json:"coin"`
|
||||
Fav int `json:"fav"`
|
||||
Desc string `json:"desc"`
|
||||
Duration string `json:"duration,omitempty"`
|
||||
} `json:"res,omitempty"`
|
||||
OfficialVerify *OfficialVerify `json:"official_verify,omitempty"`
|
||||
*ResultResponse
|
||||
}
|
||||
|
||||
// OfficialVerify struct .
|
||||
type OfficialVerify struct {
|
||||
Type int `json:"type"`
|
||||
Desc string `json:"desc,omitempty"`
|
||||
}
|
||||
|
||||
// Search all .
|
||||
type Search struct {
|
||||
Code int `json:"code,omitempty"`
|
||||
Trackid string `json:"seid,omitempty"`
|
||||
Page int `json:"page,omitempty"`
|
||||
PageSize int `json:"pagesize,omitempty"`
|
||||
Total int `json:"total,omitempty"`
|
||||
NumResults int `json:"numResults,omitempty"`
|
||||
NumPages int `json:"numPages,omitempty"`
|
||||
SuggestKeyword string `json:"suggest_keyword,omitempty"`
|
||||
Attribute int32 `json:"exp_bits,omitempty"`
|
||||
PageInfo struct {
|
||||
Bangumi *Page `json:"bangumi,omitempty"`
|
||||
UpUser *Page `json:"upuser,omitempty"`
|
||||
BiliUser *Page `json:"bili_user,omitempty"`
|
||||
User *Page `json:"user,omitempty"`
|
||||
Movie *Page `json:"movie,omitempty"`
|
||||
Film *Page `json:"pgc,omitempty"`
|
||||
MediaBangumi *Page `json:"media_bangumi,omitempty"`
|
||||
MediaFt *Page `json:"media_ft,omitempty"`
|
||||
} `json:"pageinfo,omitempty"`
|
||||
Result struct {
|
||||
Bangumi []*Bangumi `json:"bangumi,omitempty"`
|
||||
UpUser []*User `json:"upuser,omitempty"`
|
||||
BiliUser []*User `json:"bili_user,omitempty"`
|
||||
User []*User `json:"user,omitempty"`
|
||||
Movie []*Movie `json:"movie,omitempty"`
|
||||
Video []*Video `json:"video,omitempty"`
|
||||
MediaBangumi []*Media `json:"media_bangumi,omitempty"`
|
||||
MediaFt []*Media `json:"media_ft,omitempty"`
|
||||
} `json:"result,omitempty"`
|
||||
}
|
||||
|
||||
// Media struct .
|
||||
type Media struct {
|
||||
MediaID int64 `json:"media_id,omitempty"`
|
||||
SeasonID int64 `json:"season_id,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
OrgTitle string `json:"org_title,omitempty"`
|
||||
Styles string `json:"styles,omitempty"`
|
||||
Cover string `json:"cover,omitempty"`
|
||||
PlayState int `json:"play_state,omitempty"`
|
||||
MediaScore *struct {
|
||||
Score float64 `json:"score,omitempty"`
|
||||
UserCount int `json:"user_count,omitempty"`
|
||||
} `json:"media_score,omitempty"`
|
||||
MediaType int `json:"media_type,omitempty"`
|
||||
CV string `json:"cv,omitempty"`
|
||||
Staff string `json:"staff,omitempty"`
|
||||
Areas string `json:"areas,omitempty"`
|
||||
GotoURL string `json:"goto_url,omitempty"`
|
||||
Pubtime xtime.Time `json:"pubtime,omitempty"`
|
||||
HitColumns []string `json:"hit_columns,omitempty"`
|
||||
}
|
||||
|
||||
// Movie struct .
|
||||
type Movie struct {
|
||||
Title string `json:"title"`
|
||||
SpID string `json:"spid"`
|
||||
Type string `json:"type"`
|
||||
Aid int64 `json:"aid"`
|
||||
Desc string `json:"description"`
|
||||
Actors string `json:"actors"`
|
||||
Staff string `json:"staff"`
|
||||
Cover string `json:"cover"`
|
||||
Pic string `json:"pic"`
|
||||
ScreenDate string `json:"screenDate"`
|
||||
Area string `json:"area"`
|
||||
Status int `json:"status"`
|
||||
Length int `json:"length"`
|
||||
Pages int `json:"numPages"`
|
||||
}
|
||||
|
||||
// Video struct .
|
||||
type Video struct {
|
||||
ID int64 `json:"id"`
|
||||
Author string `json:"author"`
|
||||
Title string `json:"title"`
|
||||
Pic string `json:"pic"`
|
||||
Desc string `json:"description"`
|
||||
Play interface{} `json:"play"`
|
||||
Danmaku int `json:"video_review"`
|
||||
Duration string `json:"duration"`
|
||||
Pages int `json:"numPages"`
|
||||
ViewType string `json:"view_type"`
|
||||
RecTags []string `json:"rec_tags"`
|
||||
}
|
||||
|
||||
// ResultAll struct .
|
||||
type ResultAll struct {
|
||||
Trackid string `json:"trackid,omitempty"`
|
||||
Page int `json:"page,omitempty"`
|
||||
NavInfo []*NavInfo `json:"nav,omitempty"`
|
||||
Items ResultItems `json:"items,omitempty"`
|
||||
Item []*Item `json:"item,omitempty"` // 混排的数据(未用到)
|
||||
Attribute int32 `json:"attribute"` // 实验中开关
|
||||
}
|
||||
|
||||
// ResultItems struct .
|
||||
type ResultItems struct {
|
||||
Season2 []*Item `json:"season2,omitempty"`
|
||||
Season []*Item `json:"season,omitempty"` // 老数据字段(未用到)
|
||||
Upper []*Item `json:"upper,omitempty"`
|
||||
Movie2 []*Item `json:"movie2,omitempty"`
|
||||
Movie []*Item `json:"movie,omitempty"` // 老数据字段(未用到)
|
||||
Archive []*Item `json:"archive,omitempty"`
|
||||
}
|
||||
|
||||
// NavInfo struct .
|
||||
type NavInfo struct {
|
||||
Name string `json:"name"`
|
||||
Total int `json:"total"`
|
||||
Pages int `json:"pages"`
|
||||
Type int `json:"type"`
|
||||
Show int `json:"show_more,omitempty"`
|
||||
}
|
||||
|
||||
// Item struct .
|
||||
type Item struct {
|
||||
TrackID string `json:"trackid,omitempty"`
|
||||
LinkType string `json:"linktype,omitempty"`
|
||||
Position int `json:"position,omitempty"`
|
||||
SuggestKeyword string `json:"suggest_keyword,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Cover string `json:"cover,omitempty"`
|
||||
URI string `json:"uri,omitempty"`
|
||||
Param string `json:"param,omitempty"`
|
||||
Goto string `json:"goto,omitempty"`
|
||||
// av
|
||||
Play int `json:"play,omitempty"`
|
||||
Danmaku int `json:"danmaku,omitempty"`
|
||||
Author string `json:"author,omitempty"`
|
||||
ViewType string `json:"view_type,omitempty"`
|
||||
PTime xtime.Time `json:"ptime,omitempty"`
|
||||
RecTags []string `json:"rec_tags,omitempty"`
|
||||
// media bangumi and mdeia ft
|
||||
Prompt string `json:"prompt,omitempty"`
|
||||
Episodes []*Item `json:"episodes,omitempty"`
|
||||
Label string `json:"label,omitempty"`
|
||||
// bangumi season
|
||||
Finish int8 `json:"finish,omitempty"`
|
||||
Started int8 `json:"started,omitempty"`
|
||||
Index string `json:"index,omitempty"`
|
||||
NewestCat string `json:"newest_cat,omitempty"`
|
||||
NewestSeason string `json:"newest_season,omitempty"`
|
||||
CatDesc string `json:"cat_desc,omitempty"`
|
||||
TotalCount int `json:"total_count,omitempty"`
|
||||
MediaType int `json:"media_type,omitempty"`
|
||||
PlayState int `json:"play_state,omitempty"`
|
||||
Style string `json:"style,omitempty"`
|
||||
CV string `json:"cv,omitempty"`
|
||||
Rating float64 `json:"rating,omitempty"`
|
||||
Vote int `json:"vote,omitempty"`
|
||||
RatingCount int `json:"rating_count,omitempty"`
|
||||
BadgeType int `json:"badge_type,omitempty"`
|
||||
// upper
|
||||
Sign string `json:"sign,omitempty"`
|
||||
Fans int `json:"fans,omitempty"`
|
||||
Level int `json:"level,omitempty"`
|
||||
Desc string `json:"desc,omitempty"`
|
||||
OfficialVerify *OfficialVerify `json:"official_verify,omitempty"`
|
||||
AvItems []*Item `json:"av_items,omitempty"`
|
||||
Item []*Item `json:"item,omitempty"`
|
||||
CTime int64 `json:"ctime,omitempty"`
|
||||
IsUp bool `json:"is_up,omitempty"`
|
||||
LiveURI string `json:"live_uri,omitempty"`
|
||||
// movie
|
||||
ScreenDate string `json:"screen_date,omitempty"`
|
||||
Area string `json:"area,omitempty"`
|
||||
CoverMark string `json:"cover_mark,omitempty"`
|
||||
// user
|
||||
Face string `json:"face,omitempty"`
|
||||
// arc and sp
|
||||
Arcs int `json:"archives,omitempty"`
|
||||
// arc and movie
|
||||
Duration string `json:"duration,omitempty"`
|
||||
DurationInt int64 `json:"duration_int,omitempty"`
|
||||
Actors string `json:"actors,omitempty"`
|
||||
Staff string `json:"staff,omitempty"`
|
||||
Length int `json:"length,omitempty"`
|
||||
Status int `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Bangumi struct .
|
||||
type Bangumi struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
SeasonID int `json:"season_id,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Cover string `json:"cover,omitempty"`
|
||||
Evaluate string `json:"evaluate,omitempty"`
|
||||
NewestEpID int `json:"newest_ep_id,omitempty"`
|
||||
NewestEpIndex string `json:"newest_ep_index,omitempty"`
|
||||
IsFinish int `json:"is_finish,omitempty"`
|
||||
IsStarted int `json:"is_started,omitempty"`
|
||||
NewestCat string `json:"newest_cat,omitempty"`
|
||||
NewestSeason string `json:"newest_season,omitempty"`
|
||||
TotalCount int `json:"total_count,omitempty"`
|
||||
Pages int `json:"numPages,omitempty"`
|
||||
CatList *struct {
|
||||
TV int `json:"tv"`
|
||||
Movie int `json:"movie"`
|
||||
Ova int `json:"ova"`
|
||||
} `json:"catlist,omitempty"`
|
||||
}
|
||||
|
||||
// TypeSearch struct .
|
||||
type TypeSearch struct {
|
||||
TrackID string `json:"trackid"`
|
||||
Pages int `json:"pages"`
|
||||
Total int `json:"total"`
|
||||
Items []*Item `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
// Card for bangumi .
|
||||
type Card struct {
|
||||
SeasonID int64 `json:"season_id"`
|
||||
IsFollow int `json:"is_follow"`
|
||||
IsSelection int `json:"is_selection"`
|
||||
Badge string `json:"badge"`
|
||||
BadgeType int `json:"badge_type"`
|
||||
Episodes []*Episode `json:"episodes"`
|
||||
}
|
||||
|
||||
// Episode for bangumi card .
|
||||
type Episode struct {
|
||||
ID int64 `json:"id"`
|
||||
Badge string `json:"badge"`
|
||||
BadgeType int `json:"badge_type"`
|
||||
Status int `json:"status"`
|
||||
Cover string `json:"cover"`
|
||||
Index string `json:"index"`
|
||||
IndexTitle string `json:"index_title"`
|
||||
}
|
||||
|
||||
// StatusMark cover status mark .
|
||||
func StatusMark(status int) string {
|
||||
if status == 0 {
|
||||
return CoverIng
|
||||
} else if status == 1 {
|
||||
return CoverPay
|
||||
} else if status == 2 {
|
||||
return CoverFree
|
||||
} else if status == 3 {
|
||||
return CoverVipFree
|
||||
} else if status == 4 {
|
||||
return CoverVipOnly
|
||||
} else if status == 5 {
|
||||
return CoverVipFirst
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// FillURI deal app schema .
|
||||
func FillURI(gt, param string, f func(uri string) string) (uri string) {
|
||||
switch gt {
|
||||
case GotoAv, "":
|
||||
uri = "bilibili://video/" + param
|
||||
case GotoLive:
|
||||
uri = "bilibili://live/" + param
|
||||
case GotoBangumi:
|
||||
uri = "bilibili://bangumi/season/" + param
|
||||
case GotoBangumiWeb:
|
||||
uri = "http://bangumi.bilibili.com/anime/" + param
|
||||
case GotoGame:
|
||||
uri = "bilibili://game_center/detail?id=" + param + "&sourceType=adPut"
|
||||
case GotoSp:
|
||||
uri = "bilibili://splist/" + param
|
||||
case GotoAuthor:
|
||||
uri = "bilibili://author/" + param
|
||||
case GotoClip:
|
||||
uri = "bilibili://clip/" + param
|
||||
case GotoAlbum:
|
||||
uri = "bilibili://album/" + param
|
||||
case GotoArticle:
|
||||
uri = "bilibili://article/" + param
|
||||
case GotoWeb:
|
||||
uri = param
|
||||
case GotoPGC:
|
||||
uri = "https://www.bilibili.com/bangumi/play/ss" + param
|
||||
case GotoChannel:
|
||||
uri = "bilibili://pegasus/channel/" + param + "/"
|
||||
case GotoEP:
|
||||
uri = "https://www.bilibili.com/bangumi/play/ep" + param
|
||||
case GotoTwitter:
|
||||
uri = "bilibili://pictureshow/detail/" + param
|
||||
}
|
||||
if f != nil {
|
||||
uri = f(uri)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// search const
|
||||
var getHightLight = regexp.MustCompile(`<em.*?em>`)
|
||||
|
||||
var (
|
||||
// AvHandler .
|
||||
AvHandler = func(a *v1.Arc) func(uri string) string {
|
||||
return func(uri string) string {
|
||||
if a == nil {
|
||||
return uri
|
||||
}
|
||||
if a.Dimension.Height != 0 || a.Dimension.Width != 0 {
|
||||
return fmt.Sprintf("%s?player_width=%d&player_height=%d&player_rotate=%d", uri, a.Dimension.Width, a.Dimension.Height, a.Dimension.Rotate)
|
||||
}
|
||||
return uri
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// FromSeason .
|
||||
func (i *Item) FromSeason(b *Bangumi, bangumi string) {
|
||||
i.Title = b.Title
|
||||
i.Cover = b.Cover
|
||||
i.Goto = GotoBangumi
|
||||
i.Param = strconv.Itoa(int(b.SeasonID))
|
||||
i.URI = FillURI(bangumi, i.Param, nil)
|
||||
i.Finish = int8(b.IsFinish)
|
||||
i.Started = int8(b.IsStarted)
|
||||
i.Index = b.NewestEpIndex
|
||||
i.NewestCat = b.NewestCat
|
||||
i.NewestSeason = b.NewestSeason
|
||||
i.TotalCount = b.TotalCount
|
||||
var buf bytes.Buffer
|
||||
if b.CatList.TV != 0 {
|
||||
buf.WriteString(`TV(`)
|
||||
buf.WriteString(strconv.Itoa(b.CatList.TV))
|
||||
buf.WriteString(`) `)
|
||||
}
|
||||
if b.CatList.Movie != 0 {
|
||||
buf.WriteString(`剧场版(`)
|
||||
buf.WriteString(strconv.Itoa(b.CatList.Movie))
|
||||
buf.WriteString(`) `)
|
||||
}
|
||||
if b.CatList.Ova != 0 {
|
||||
buf.WriteString(`OVA/OAD/SP(`)
|
||||
buf.WriteString(strconv.Itoa(b.CatList.Ova))
|
||||
buf.WriteString(`)`)
|
||||
}
|
||||
i.CatDesc = buf.String()
|
||||
}
|
||||
|
||||
// FromUpUser form func .
|
||||
func (i *Item) FromUpUser(u *User, as map[int64]*v1.Arc) {
|
||||
i.Title = u.Name
|
||||
i.Cover = u.Pic
|
||||
i.Goto = GotoAuthor
|
||||
i.OfficialVerify = u.OfficialVerify
|
||||
i.Param = strconv.Itoa(int(u.Mid))
|
||||
i.URI = FillURI(i.Goto, i.Param, nil)
|
||||
i.Sign = u.Usign
|
||||
i.Fans = u.Fans
|
||||
i.Level = u.Level
|
||||
i.Arcs = u.Videos
|
||||
i.AvItems = make([]*Item, 0, len(u.Res))
|
||||
for _, v := range u.Res {
|
||||
vi := &Item{}
|
||||
vi.Title = v.Title
|
||||
vi.Cover = v.Pic
|
||||
vi.Goto = GotoAv
|
||||
vi.Param = strconv.Itoa(int(v.Aid))
|
||||
a, ok := as[v.Aid]
|
||||
if ok {
|
||||
vi.Play = int(a.Stat.View)
|
||||
vi.Danmaku = int(a.Stat.Danmaku)
|
||||
} else {
|
||||
switch play := v.Play.(type) {
|
||||
case float64:
|
||||
vi.Play = int(play)
|
||||
case string:
|
||||
vi.Play, _ = strconv.Atoi(play)
|
||||
}
|
||||
vi.Danmaku = v.Danmaku
|
||||
}
|
||||
vi.CTime = v.Pubdate
|
||||
vi.Duration = v.Duration
|
||||
i.AvItems = append(i.AvItems, vi)
|
||||
}
|
||||
}
|
||||
|
||||
// FromUser form func .
|
||||
func (i *Item) FromUser(u *User, as map[int64]*v1.Arc) {
|
||||
i.Title = u.Name
|
||||
i.Cover = u.Pic
|
||||
i.Goto = GotoAuthor
|
||||
i.OfficialVerify = u.OfficialVerify
|
||||
i.Param = strconv.Itoa(int(u.Mid))
|
||||
i.URI = FillURI(i.Goto, i.Param, nil)
|
||||
i.Sign = u.Usign
|
||||
i.Fans = u.Fans
|
||||
i.Level = u.Level
|
||||
i.Arcs = u.Videos
|
||||
i.AvItems = make([]*Item, 0, len(u.Res))
|
||||
if u.IsUpuser == 1 {
|
||||
for _, v := range u.Res {
|
||||
vi := &Item{}
|
||||
vi.Title = v.Title
|
||||
vi.Cover = v.Pic
|
||||
vi.Goto = GotoAv
|
||||
vi.Param = strconv.Itoa(int(v.Aid))
|
||||
a, ok := as[v.Aid]
|
||||
if ok {
|
||||
vi.Play = int(a.Stat.View)
|
||||
vi.Danmaku = int(a.Stat.Danmaku)
|
||||
} else {
|
||||
switch play := v.Play.(type) {
|
||||
case float64:
|
||||
vi.Play = int(play)
|
||||
case string:
|
||||
vi.Play, _ = strconv.Atoi(play)
|
||||
}
|
||||
vi.Danmaku = v.Danmaku
|
||||
}
|
||||
vi.CTime = v.Pubdate
|
||||
vi.Duration = v.Duration
|
||||
i.AvItems = append(i.AvItems, vi)
|
||||
}
|
||||
i.IsUp = true
|
||||
}
|
||||
}
|
||||
|
||||
// FromMovie form func .
|
||||
func (i *Item) FromMovie(m *Movie, as map[int64]*v1.Arc) {
|
||||
i.Title = m.Title
|
||||
i.Desc = m.Desc
|
||||
if m.Type == "movie" {
|
||||
i.Cover = m.Cover
|
||||
i.Param = strconv.Itoa(int(m.Aid))
|
||||
i.Goto = GotoAv
|
||||
i.URI = FillURI(i.Goto, i.Param, AvHandler(as[m.Aid]))
|
||||
i.CoverMark = StatusMark(m.Status)
|
||||
} else if m.Type == "special" {
|
||||
i.Param = m.SpID
|
||||
i.Goto = GotoSp
|
||||
i.URI = FillURI(i.Goto, i.Param, nil)
|
||||
i.Cover = m.Pic
|
||||
}
|
||||
i.Staff = m.Staff
|
||||
i.Actors = m.Actors
|
||||
i.Area = m.Area
|
||||
i.Length = m.Length
|
||||
i.Status = m.Status
|
||||
i.ScreenDate = m.ScreenDate
|
||||
}
|
||||
|
||||
// FromVideo form func .
|
||||
func (i *Item) FromVideo(v *Video, a *v1.Arc) {
|
||||
i.Title = v.Title
|
||||
i.Cover = v.Pic
|
||||
i.Author = v.Author
|
||||
i.Param = strconv.Itoa(int(v.ID))
|
||||
i.Goto = GotoAv
|
||||
if a != nil {
|
||||
i.Face = a.Author.Face
|
||||
i.URI = FillURI(i.Goto, i.Param, AvHandler(a))
|
||||
i.Play = int(a.Stat.View)
|
||||
i.Danmaku = int(a.Stat.Danmaku)
|
||||
} else {
|
||||
i.URI = FillURI(i.Goto, i.Param, nil)
|
||||
switch play := v.Play.(type) {
|
||||
case float64:
|
||||
i.Play = int(play)
|
||||
case string:
|
||||
i.Play, _ = strconv.Atoi(play)
|
||||
}
|
||||
i.Danmaku = v.Danmaku
|
||||
}
|
||||
i.Desc = v.Desc
|
||||
i.Duration = v.Duration
|
||||
i.ViewType = v.ViewType
|
||||
i.RecTags = v.RecTags
|
||||
}
|
||||
|
||||
// FromMedia form func .
|
||||
func (i *Item) FromMedia(m *Media, prompt string, gt string, bangumis map[string]*Card) {
|
||||
i.Title = m.Title
|
||||
if i.Title == "" {
|
||||
i.Title = m.OrgTitle
|
||||
}
|
||||
i.Cover = m.Cover
|
||||
i.Goto = gt
|
||||
i.Param = strconv.Itoa(int(m.SeasonID))
|
||||
i.URI = m.GotoURL
|
||||
i.MediaType = m.MediaType
|
||||
i.PlayState = m.PlayState
|
||||
i.Style = m.Styles
|
||||
i.CV = m.CV
|
||||
i.Staff = m.Staff
|
||||
if m.MediaScore != nil {
|
||||
i.Rating = m.MediaScore.Score
|
||||
i.Vote = m.MediaScore.UserCount
|
||||
}
|
||||
i.PTime = m.Pubtime
|
||||
areas := strings.Split(m.Areas, "、")
|
||||
if len(areas) != 0 {
|
||||
i.Area = areas[0]
|
||||
}
|
||||
i.Prompt = prompt
|
||||
var hit string
|
||||
for _, v := range m.HitColumns {
|
||||
if v == "cv" {
|
||||
hit = v
|
||||
break
|
||||
} else if v == "staff" {
|
||||
hit = v
|
||||
}
|
||||
}
|
||||
if hit == "cv" {
|
||||
for _, v := range getHightLight.FindAllStringSubmatch(m.CV, -1) {
|
||||
if gt == GotoBangumi {
|
||||
i.Label = fmt.Sprintf("声优: %v...", v[0])
|
||||
break
|
||||
} else if gt == GotoMovie {
|
||||
i.Label = fmt.Sprintf("演员: %v...", v[0])
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if hit == "staff" {
|
||||
for _, v := range getHightLight.FindAllStringSubmatch(m.Staff, -1) {
|
||||
i.Label = fmt.Sprintf("制作人员: %v...", v[0])
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// get from PGC API .
|
||||
ssID := strconv.Itoa(int(m.SeasonID))
|
||||
if bgm, ok := bangumis[ssID]; ok {
|
||||
for _, v := range bgm.Episodes {
|
||||
tmp := &Item{
|
||||
Param: strconv.Itoa(int(v.ID)),
|
||||
Index: v.Index,
|
||||
BadgeType: v.BadgeType,
|
||||
}
|
||||
tmp.URI = FillURI(GotoEP, tmp.Param, nil)
|
||||
i.Episodes = append(i.Episodes, tmp)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user