1st
This commit is contained in:
343
tennis.go
Normal file
343
tennis.go
Normal file
@@ -0,0 +1,343 @@
|
||||
package onexbet
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
webspider "gordenko.dev/dima/spider"
|
||||
|
||||
"gordenko.dev/dima/flashscore"
|
||||
)
|
||||
|
||||
var (
|
||||
// проверка на Contains
|
||||
bannedTennisChamps = []string{
|
||||
"Setka Cup",
|
||||
"Russia. Masters",
|
||||
"Russia. League Pro",
|
||||
"Daily Aqua Tour",
|
||||
"UTR Pro Tennis Series",
|
||||
"VS OPEN",
|
||||
"Daily Pro Tour",
|
||||
"Mountain Bay Open",
|
||||
"Russian River Cup",
|
||||
}
|
||||
|
||||
bannedTennisPrefixes = []string{}
|
||||
)
|
||||
|
||||
func TennisChampFilter(champName string) (_ bool) {
|
||||
for _, bannedChampName := range bannedHandballChamps {
|
||||
if strings.Contains(champName, bannedChampName) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for _, bannedPrefix := range bannedHandballPrefixes {
|
||||
if strings.HasPrefix(champName, bannedPrefix) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if flashscore.IsTennisDoublesChamp(champName) {
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("CHAMP NAME IS OK: %s\n", champName)
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
// Поля P и St - топ поля документа
|
||||
// Tennis match status
|
||||
// Подтверждено точно
|
||||
"St": 2,
|
||||
|
||||
// Tennis Match Stat
|
||||
// Счет по сетам
|
||||
"P": [
|
||||
{
|
||||
"A": 7,
|
||||
"CSPP": [],
|
||||
"H": 5,
|
||||
"T": 11,
|
||||
"TI": "000000000000000000000000"
|
||||
},
|
||||
{
|
||||
"A": 4,
|
||||
"CSPP": [],
|
||||
"H": 6,
|
||||
"T": 12,
|
||||
"TI": "000000000000000000000000"
|
||||
},
|
||||
{
|
||||
"A": 4,
|
||||
"CSPP": [],
|
||||
"H": 6,
|
||||
"T": 13,
|
||||
"TI": "000000000000000000000000"
|
||||
},
|
||||
{
|
||||
"A": 6,
|
||||
"CSPP": [],
|
||||
"H": 4,
|
||||
"T": 14,
|
||||
"TI": "000000000000000000000000"
|
||||
},
|
||||
{
|
||||
"A": 6,
|
||||
"CSPP": [],
|
||||
"H": 2,
|
||||
"T": 15,
|
||||
"TI": "000000000000000000000000"
|
||||
}
|
||||
],
|
||||
*/
|
||||
|
||||
type matchResult struct {
|
||||
Periods []periodResult `json:"P"`
|
||||
Status int `json:"St"`
|
||||
}
|
||||
|
||||
// Можно добавить поле T (код сета) для контроля.
|
||||
// Коды сетов: 1й - 11, 2й - 12, 3й - 13, 4й - 14, 5й - 15
|
||||
type periodResult struct {
|
||||
Code int `json:"T"`
|
||||
HomePoints int `json:"H"`
|
||||
AwayPoints int `json:"A"`
|
||||
}
|
||||
|
||||
// Для футбола и гандбола
|
||||
var periodCode2PeriodNumberMapping = map[int]int{
|
||||
1: 1,
|
||||
3: 2,
|
||||
}
|
||||
|
||||
var setCode2SetNumberMapping = map[int]int{
|
||||
11: 1,
|
||||
12: 2,
|
||||
13: 3,
|
||||
14: 4,
|
||||
15: 5,
|
||||
}
|
||||
|
||||
func GetTennisMatchResult(statsMatchID string) (result TeamMatchResult, err error) {
|
||||
url := fmt.Sprintf(matchStatsURLPattern, statsMatchID)
|
||||
|
||||
spider, err := webspider.NewSpider(nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
buf, err := spider.Get(url, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//fmt.Printf("%s\n", buf)
|
||||
|
||||
var tmp matchResult
|
||||
|
||||
err = json.Unmarshal(buf, &tmp)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
result.Status = tmp.Status
|
||||
result.ScoreByPeriods = make(map[int]PeriodScore)
|
||||
|
||||
for _, set := range tmp.Periods {
|
||||
setNumber := setCode2SetNumberMapping[set.Code]
|
||||
if setNumber == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
result.ScoreByPeriods[setNumber] = PeriodScore{
|
||||
HomePoints: set.HomePoints,
|
||||
AwayPoints: set.AwayPoints,
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
///////////
|
||||
|
||||
// Все структуры с маленькой буквы - это служебные структуры для парсинга
|
||||
|
||||
// служебная структура для парсинга данных live матча
|
||||
type tennisLiveMatchDataEnvelope struct {
|
||||
Error string
|
||||
ErrorCode int64
|
||||
Success bool // false, если матч закончен
|
||||
Value tennisLiveMatchData
|
||||
}
|
||||
|
||||
// поле BIG со списком matchID для других периодов встречается в JSON документах
|
||||
// других периодов. То есть если запросить данные для 2-го сета по специальному ID,
|
||||
// то в поле BIG будет список ID. Если же запросить документ для Regular Time, то
|
||||
// поля BIG не будет, а будет SG (с коэффициентами для других периодов)
|
||||
type tennisLiveMatchData struct {
|
||||
Markets []rawMarket `json:"GE"` // рынки
|
||||
// текущий счет, в том числе по геймам (только в Regular Time документе)
|
||||
Stats statAndScore `json:"SC"`
|
||||
Sets []tennisSet `json:"SG"`
|
||||
StatsMatchID string `json:"SGI"`
|
||||
}
|
||||
|
||||
type tennisSet struct {
|
||||
SetNumber int `json:"P"`
|
||||
Markets []rawMarket `json:"GE"`
|
||||
}
|
||||
|
||||
/*
|
||||
type tennisStatsAndScore struct {
|
||||
CurrentSetNumber int `json:"CP"`
|
||||
SetScore scoreStruct `json:"FS"` // счет по сетам
|
||||
GameScore []periodScore `json:"PS"`
|
||||
}
|
||||
*/
|
||||
|
||||
type statAndScore struct {
|
||||
Score scoreStruct `json:"FS"`
|
||||
ScoreByPeriods []periodScore `json:"PS"`
|
||||
CurrentPeriod int `json:"CP"`
|
||||
}
|
||||
|
||||
// public
|
||||
|
||||
func LoadTennisLiveMatchData(matchID string) (_ TeamLiveMatchData, isMatchFinished bool, err error) {
|
||||
url := fmt.Sprintf(liveMatchURLPattern, matchID)
|
||||
|
||||
spider, err := webspider.NewSpider(nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
buf, err := spider.Get(url, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
//fmt.Printf("buf: %s\n\n", buf)
|
||||
|
||||
var env tennisLiveMatchDataEnvelope
|
||||
|
||||
err = json.Unmarshal(buf, &env)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("json.Unmarshal liveMatchDataEnvelope: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !env.Success {
|
||||
isMatchFinished = true
|
||||
return
|
||||
}
|
||||
|
||||
data := TeamLiveMatchData{
|
||||
MatchID: matchID,
|
||||
ScoreByPeriods: make(map[int]Score),
|
||||
Periods: make(map[int]Period),
|
||||
}
|
||||
|
||||
// FULL TIME
|
||||
for _, market := range env.Value.Markets {
|
||||
switch market.MarketType {
|
||||
case tennisMarketWinner:
|
||||
|
||||
winner := &Winner2Way{}
|
||||
|
||||
for _, offers := range market.OffersList {
|
||||
if len(offers) > 0 {
|
||||
offer := offers[0]
|
||||
|
||||
if offer.IsBlocked {
|
||||
continue
|
||||
}
|
||||
|
||||
if offer.Side == 1 {
|
||||
// T=1
|
||||
winner.HasHome = true
|
||||
winner.Home = offer.Price
|
||||
} else if offer.Side == 3 {
|
||||
// T=3
|
||||
winner.HasAway = true
|
||||
winner.Away = offer.Price
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.Winner2Way = winner
|
||||
|
||||
case tennisMarketTotal:
|
||||
data.Total, err = getTotal(market)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("FT getTotal (tennis): %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
case tennisMarketHandicap:
|
||||
data.Handicap, err = getHandicap(market)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("FT getHandicap (tennis): %s", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BY SETS
|
||||
|
||||
for _, p := range env.Value.Sets {
|
||||
set := Period{
|
||||
PeriodNumber: p.SetNumber,
|
||||
}
|
||||
|
||||
for _, market := range p.Markets {
|
||||
switch market.MarketType {
|
||||
|
||||
case tennisMarketTotal:
|
||||
set.Total, err = getTotal(market)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("SET %d getTotal (tennis): %s", p.SetNumber, err)
|
||||
return
|
||||
}
|
||||
|
||||
case tennisMarketHandicap:
|
||||
set.Handicap, err = getHandicap(market)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("SET %d getHandicap (tennis): %s", p.SetNumber, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.Periods[p.SetNumber] = set
|
||||
}
|
||||
|
||||
// SCORE
|
||||
|
||||
stat := env.Value.Stats
|
||||
|
||||
if stat.CurrentPeriod == 0 {
|
||||
// ВАЖНО!
|
||||
// Если период не указан - поля нет в JSON, счета нет
|
||||
err = fmt.Errorf("Current score not found")
|
||||
return
|
||||
}
|
||||
|
||||
data.CurrentPeriod = stat.CurrentPeriod
|
||||
|
||||
data.Score.Home = stat.Score.HomeScore
|
||||
data.Score.Away = stat.Score.AwayScore
|
||||
|
||||
for _, p := range stat.ScoreByPeriods {
|
||||
data.ScoreByPeriods[p.Period] = Score{
|
||||
Home: p.Score.HomeScore,
|
||||
Away: p.Score.AwayScore,
|
||||
}
|
||||
}
|
||||
//fmt.Printf("%s\n\n", buf)
|
||||
|
||||
return data, false, nil
|
||||
}
|
||||
Reference in New Issue
Block a user