Skip to content

Commit 0194410

Browse files
authored
fixed hltb (#2039)
1 parent 99309bb commit 0194410

4 files changed

Lines changed: 40 additions & 80 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ require (
9292
github.com/andybalholm/cascadia v1.3.1 // indirect
9393
github.com/bytedance/sonic v1.9.2 // indirect
9494
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
95+
github.com/forbiddencoding/howlongtobeat v0.0.0-20260210184841-a1f74e4d3b15 // indirect
9596
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
9697
github.com/goccy/go-json v0.10.2 // indirect
9798
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLg
191191
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
192192
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
193193
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
194+
github.com/forbiddencoding/howlongtobeat v0.0.0-20260210184841-a1f74e4d3b15 h1:9AaH1Iw7ve/3Kstc6+0yM7Lt6LG+R8nFYkqt8JdZuZc=
195+
github.com/forbiddencoding/howlongtobeat v0.0.0-20260210184841-a1f74e4d3b15/go.mod h1:dmFGl5FxpTS4ZUSYhP5kdkY9G0WBEK4lrbVHjNXkG4U=
194196
github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk=
195197
github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY=
196198
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=

stdcommands/howlongtobeat/howlongtobeat.go

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,12 @@ type hltb struct {
2424
CompletionistTimeHours string
2525
GameURL string
2626
ImageURL string
27-
JaroWinklerSimilarity float64
28-
}
29-
30-
type hltbRequest struct {
31-
SearchType string `json:"searchType"`
32-
SearchTerms []string `json:"searchTerms"`
27+
Similarity float64
3328
}
3429

3530
var (
36-
hltbScheme = "https"
37-
hltbHost = "howlongtobeat.com"
38-
hltbHostPath = "api/search"
31+
hltbScheme = "https"
32+
hltbHost = "howlongtobeat.com"
3933
)
4034

4135
// Command var needs a comment for lint :)
@@ -76,7 +70,6 @@ var Command = &commands.YAGCommand{
7670
return "No results", nil
7771
}
7872

79-
games = parseGameData(gameName, games)
8073
if compactView {
8174
compactData := fmt.Sprintf("%s: %s | %s | %s | <%s>",
8275
normaliseTitle(games[0].GameTitle),
@@ -88,16 +81,16 @@ var Command = &commands.YAGCommand{
8881
return compactData, nil
8982
}
9083

91-
hltbEmbed := embedCreator(games, 0, paginatedView)
84+
hltbEmbed := embedCreator(games[0], paginatedView)
9285

9386
if paginatedView {
9487
return paginatedmessages.NewPaginatedResponse(
9588
data.GuildData.GS.ID, data.ChannelID, 1, len(games), func(p *paginatedmessages.PaginatedMessage, page int) (*discordgo.MessageEmbed, error) {
9689
i := page - 1
9790
sort.SliceStable(games, func(i, j int) bool {
98-
return games[i].JaroWinklerSimilarity > games[j].JaroWinklerSimilarity
91+
return games[i].Similarity > games[j].Similarity
9992
})
100-
paginatedEmbed := embedCreator(games, i, paginatedView)
93+
paginatedEmbed := embedCreator(games[i], paginatedView)
10194
return paginatedEmbed, nil
10295
}), nil
10396
}
@@ -106,32 +99,32 @@ var Command = &commands.YAGCommand{
10699
},
107100
}
108101

109-
func embedCreator(games []hltb, i int, paginated bool) *discordgo.MessageEmbed {
102+
func embedCreator(game hltb, paginated bool) *discordgo.MessageEmbed {
110103
embed := &discordgo.MessageEmbed{
111104
Author: &discordgo.MessageEmbedAuthor{
112-
Name: normaliseTitle(games[i].GameTitle),
113-
URL: games[i].GameURL,
105+
Name: normaliseTitle(game.GameTitle),
106+
URL: game.GameURL,
114107
},
115108

116109
Color: int(rand.Int63n(16777215)),
117110
Thumbnail: &discordgo.MessageEmbedThumbnail{
118-
URL: games[i].ImageURL,
111+
URL: game.ImageURL,
119112
},
120113
}
121-
if games[i].MainStoryTime > 0 {
114+
if game.MainStoryTime > 0 {
122115
embed.Fields = append(embed.Fields,
123-
&discordgo.MessageEmbedField{Name: "Main Story", Value: games[i].MainStoryTimeHours})
116+
&discordgo.MessageEmbedField{Name: "Main Story", Value: game.MainStoryTimeHours})
124117
}
125-
if games[i].MainExtraTime > 0 {
118+
if game.MainExtraTime > 0 {
126119
embed.Fields = append(embed.Fields,
127-
&discordgo.MessageEmbedField{Name: "Main + Extra", Value: games[i].MainStoryExtraTimeHours})
120+
&discordgo.MessageEmbedField{Name: "Main + Extra", Value: game.MainStoryExtraTimeHours})
128121
}
129-
if games[i].CompletionistTime > 0 {
122+
if game.CompletionistTime > 0 {
130123
embed.Fields = append(embed.Fields,
131-
&discordgo.MessageEmbedField{Name: "Completionist", Value: games[i].CompletionistTimeHours})
124+
&discordgo.MessageEmbedField{Name: "Completionist", Value: game.CompletionistTimeHours})
132125
}
133126
if paginated {
134-
embed.Description = fmt.Sprintf("Term similarity: %.1f%%", games[i].JaroWinklerSimilarity*100)
127+
embed.Description = fmt.Sprintf("Term similarity: %.1f%%", game.Similarity*100)
135128
}
136129

137130
return embed

stdcommands/howlongtobeat/queryfunctions.go

Lines changed: 20 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,43 @@
11
package howlongtobeat
22

33
import (
4-
"encoding/json"
4+
"context"
55
"fmt"
6-
"io/ioutil"
7-
"net/http"
8-
"net/url"
9-
"strings"
10-
"time"
116

12-
"github.com/botlabs-gg/yagpdb/v2/commands"
13-
"github.com/botlabs-gg/yagpdb/v2/lib/jarowinkler"
7+
"github.com/forbiddencoding/howlongtobeat"
148
)
159

1610
func getGameData(searchTitle string) ([]hltb, error) {
17-
reqData := &hltbRequest{
18-
SearchType: "games",
19-
SearchTerms: []string{searchTitle},
20-
}
21-
u := &url.URL{
22-
Scheme: hltbScheme,
23-
Host: hltbHost,
24-
Path: hltbHostPath,
25-
}
26-
27-
urlStr := u.String()
28-
body, err := json.Marshal(reqData)
29-
if err != nil {
30-
return nil, commands.NewPublicError("Failed Parsing Query")
31-
}
32-
client := &http.Client{}
33-
r, _ := http.NewRequest("POST", urlStr, strings.NewReader(string(body)))
34-
r.Header.Add("Content-Type", "application/json")
35-
r.Header.Add("Accept", "*/*")
36-
r.Header.Add("User-Agent", "YAGPDB.xyz (https://github.com/botlabs-gg/yagpdb)")
37-
r.Header.Add("origin", "https://howlongtobeat.com")
38-
r.Header.Add("referer", "https://howlongtobeat.com/")
39-
40-
resp, err := client.Do(r)
11+
hltb, err := howlongtobeat.New()
4112
if err != nil {
4213
return nil, err
4314
}
44-
45-
if resp.StatusCode != 200 {
46-
return nil, commands.NewPublicError("Unable to fetch data from howlongtobeat.com")
47-
}
48-
r.Body.Close()
49-
50-
bytes, err := ioutil.ReadAll(resp.Body)
15+
searchResults, err := hltb.SearchSimple(context.TODO(), searchTitle, howlongtobeat.SearchModifierNone)
5116
if err != nil {
5217
return nil, err
5318
}
5419

55-
var hltbData struct {
56-
Games []hltb `json:"data"`
57-
}
58-
err = json.Unmarshal(bytes, &hltbData)
59-
if err != nil {
60-
return nil, commands.NewPublicError("Error parsing response from howlongtobeat.com")
61-
}
62-
63-
return hltbData.Games, nil
20+
return parseGameData(searchResults), nil
6421
}
6522

66-
func parseGameData(gameName string, games []hltb) []hltb {
23+
func parseGameData(games []*howlongtobeat.SearchGameSimple) []hltb {
6724
var parsedGames []hltb
6825
var parsingGame hltb
6926
for _, game := range games {
70-
parsingGame = game
71-
parsingGame.MainStoryTimeHours = fmt.Sprintf("%.2f Hours ", (time.Second * time.Duration(game.MainStoryTime)).Hours())
72-
parsingGame.MainStoryExtraTimeHours = fmt.Sprintf("%.2f Hours ", (time.Second * time.Duration(game.MainExtraTime)).Hours())
73-
parsingGame.CompletionistTimeHours = fmt.Sprintf("%.2f Hours ", (time.Second * time.Duration(game.CompletionistTime)).Hours())
74-
parsingGame.JaroWinklerSimilarity = jarowinkler.Similarity([]rune(gameName), []rune(game.GameTitle))
75-
parsingGame.GameURL = fmt.Sprintf("%s://%s/game/%d", hltbScheme, hltbHost, games[0].GameID)
76-
parsingGame.ImageURL = fmt.Sprintf("%s://%s/games/%s", hltbScheme, hltbHost, games[0].ImagePath)
27+
parsingGame = hltb{
28+
GameTitle: game.GameName,
29+
GameID: int64(game.GameID),
30+
ImagePath: game.GameImage,
31+
MainStoryTime: int64(game.CompMain),
32+
MainStoryTimeHours: fmt.Sprintf("%.2f Hours ", game.CompMain),
33+
MainExtraTime: int64(game.CompPlus),
34+
MainStoryExtraTimeHours: fmt.Sprintf("%.2f Hours ", game.CompPlus),
35+
CompletionistTime: int64(game.CompAll),
36+
CompletionistTimeHours: fmt.Sprintf("%.2f Hours ", game.CompAll),
37+
Similarity: game.Similarity,
38+
GameURL: fmt.Sprintf("%s://%s/game/%d", hltbScheme, hltbHost, game.GameID),
39+
ImageURL: fmt.Sprintf("%s://%s/games/%s", hltbScheme, hltbHost, game.GameImage),
40+
}
7741
parsedGames = append(parsedGames, parsingGame)
7842
}
7943
return parsedGames

0 commit comments

Comments
 (0)