pcgamedb/crawler/steam.go

152 lines
3.6 KiB
Go
Raw Normal View History

2024-09-24 06:17:11 -04:00
package crawler
import (
"encoding/json"
"errors"
"fmt"
"net/url"
"regexp"
"strconv"
"strings"
"time"
2024-11-15 02:02:45 -05:00
2024-11-20 06:09:04 -05:00
"pcgamedb/cache"
"pcgamedb/config"
"pcgamedb/constant"
"pcgamedb/model"
"pcgamedb/utils"
2024-09-24 06:17:11 -04:00
)
func GetSteamAppDetail(id int) (*model.SteamAppDetail, error) {
baseURL, _ := url.Parse(constant.SteamAppDetailURL)
params := url.Values{}
params.Add("appids", strconv.Itoa(id))
// params.Add("l", "schinese")
baseURL.RawQuery = params.Encode()
resp, err := utils.Fetch(utils.FetchConfig{
Url: baseURL.String(),
Headers: map[string]string{
"User-Agent": "",
},
})
if err != nil {
return nil, err
}
var detail map[string]*model.SteamAppDetail
if err = json.Unmarshal(resp.Data, &detail); err != nil {
return nil, err
}
if _, ok := detail[strconv.Itoa(id)]; !ok {
return nil, fmt.Errorf("steam App not found: %d", id)
2024-09-24 06:17:11 -04:00
}
if detail[strconv.Itoa(id)] == nil {
return nil, fmt.Errorf("steam App not found: %d", id)
2024-09-24 06:17:11 -04:00
}
return detail[strconv.Itoa(id)], nil
}
func GetSteamAppDetailCache(id int) (*model.SteamAppDetail, error) {
if config.Config.RedisAvaliable {
key := fmt.Sprintf("steam_game:%d", id)
val, exist := cache.Get(key)
if exist {
var detail model.SteamAppDetail
if err := json.Unmarshal([]byte(val), &detail); err != nil {
return nil, err
}
return &detail, nil
} else {
data, err := GetSteamAppDetail(id)
if err != nil {
return nil, err
}
dataBytes, err := json.Marshal(data)
if err != nil {
return nil, err
}
_ = cache.Add(key, dataBytes)
return data, nil
}
} else {
return GetSteamAppDetail(id)
}
}
func GenerateSteamGameInfo(id int) (*model.GameInfo, error) {
item := &model.GameInfo{}
detail, err := GetSteamAppDetailCache(id)
if err != nil {
return nil, err
}
item.SteamID = id
item.Name = detail.Data.Name
item.Description = detail.Data.ShortDescription
item.Cover = fmt.Sprintf("https://shared.cloudflare.steamstatic.com/store_item_assets/steam/apps/%v/library_600x900_2x.jpg", id)
item.Developers = detail.Data.Developers
item.Publishers = detail.Data.Publishers
item.InfoUpdatedAt = time.Now()
var screenshots []string
2024-09-24 06:17:11 -04:00
for _, screenshot := range detail.Data.Screenshots {
screenshots = append(screenshots, screenshot.PathFull)
}
item.Screenshots = screenshots
return item, nil
}
func GetSteamIDByIGDBID(IGDBID int) (int, error) {
var err error
2024-11-26 10:14:15 -05:00
resp, err := igdbFetch(constant.IGDBWebsitesURL, fmt.Sprintf(`where game = %v; fields *; limit 500;`, IGDBID))
2024-09-24 06:17:11 -04:00
if err != nil {
return 0, err
}
var data []struct {
Game int `json:"game"`
Url string `json:"url"`
}
if err = json.Unmarshal(resp.Data, &data); err != nil {
return 0, err
}
if len(data) == 0 {
return 0, errors.New("not found")
2024-09-24 06:17:11 -04:00
}
for _, v := range data {
if strings.HasPrefix(v.Url, "https://store.steampowered.com/app/") {
regex := regexp.MustCompile(`https://store.steampowered.com/app/(\d+)/?`)
idStr := regex.FindStringSubmatch(v.Url)
if len(idStr) < 2 {
return 0, errors.New("failed parse")
2024-09-24 06:17:11 -04:00
}
steamID, err := strconv.Atoi(idStr[1])
if err != nil {
return 0, err
}
return steamID, nil
}
}
return 0, errors.New("not found")
2024-09-24 06:17:11 -04:00
}
func GetSteamIDByIGDBIDCache(IGDBID int) (int, error) {
if config.Config.RedisAvaliable {
key := fmt.Sprintf("steam_game:%d", IGDBID)
val, exist := cache.Get(key)
if exist {
id, err := strconv.Atoi(val)
if err != nil {
return 0, err
}
return id, nil
} else {
id, err := GetSteamIDByIGDBID(IGDBID)
if err != nil {
return 0, err
}
dataBytes := strconv.Itoa(id)
_ = cache.Add(key, dataBytes)
return id, nil
}
} else {
return GetSteamIDByIGDBID(IGDBID)
}
}