Skip to content

Commit 06ba3f7

Browse files
Add support to new boostable bosses page (#152)
Co-authored-by: Tobias Lindberg <tobias.ehlert@gmail.com>
1 parent a35bee2 commit 06ba3f7

File tree

5 files changed

+997
-0
lines changed

5 files changed

+997
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ Those are the current existing endpoints.
9797

9898
- GET `/ping`
9999
- GET `/health`
100+
- GET `/v3/boostablebosses`
100101
- GET `/v3/character/:name`
101102
- GET `/v3/creature/:race`
102103
- GET `/v3/creatures`
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"regexp"
6+
"strings"
7+
8+
"github.com/PuerkitoBio/goquery"
9+
)
10+
11+
// Child of BoostableBoss (used for list of boostable bosses and boosted boss section)
12+
type OverviewBoostableBoss struct {
13+
Name string `json:"name"`
14+
ImageURL string `json:"image_url"`
15+
Featured bool `json:"featured"`
16+
}
17+
18+
// Child of JSONData
19+
type BoostableBossesContainer struct {
20+
Boosted OverviewBoostableBoss `json:"boosted"`
21+
BoostableBosses []OverviewBoostableBoss `json:"boostable_boss_list"`
22+
}
23+
24+
//
25+
// The base includes two levels: BoostableBosses and Information
26+
type BoostableBossesOverviewResponse struct {
27+
BoostableBosses BoostableBossesContainer `json:"boostable_bosses"`
28+
Information Information `json:"information"`
29+
}
30+
31+
var (
32+
BoostedBossNameRegex = regexp.MustCompile(`<b>(.*)</b>`)
33+
BoostedBossImageRegex = regexp.MustCompile(`<img[^>]+\bsrc=["']([^"']+)["']`)
34+
BoostableBossInformationRegex = regexp.MustCompile(`<img src="(.*)" border.*div>(.*)<\/div>`)
35+
)
36+
37+
func TibiaBoostableBossesOverviewV3Impl(BoxContentHTML string) BoostableBossesOverviewResponse {
38+
var (
39+
BoostedBossName, BoostedBossImage string
40+
)
41+
42+
// Loading HTML data into ReaderHTML for goquery with NewReader
43+
ReaderHTML, err := goquery.NewDocumentFromReader(strings.NewReader(BoxContentHTML))
44+
if err != nil {
45+
log.Fatal(err)
46+
}
47+
48+
// Getting data from div.InnerTableContainer and then first p
49+
InnerTableContainerTMPB, err := ReaderHTML.Find(".InnerTableContainer p").First().Html()
50+
if err != nil {
51+
log.Fatal(err)
52+
}
53+
54+
// Regex to get data for name for boosted boss
55+
subma1b := BoostedBossNameRegex.FindAllStringSubmatch(InnerTableContainerTMPB, -1)
56+
57+
if len(subma1b) > 0 {
58+
// Settings vars for usage in JSONData
59+
BoostedBossName = subma1b[0][1]
60+
}
61+
62+
// Regex to get image of boosted boss
63+
subma2b := BoostedBossImageRegex.FindAllStringSubmatch(InnerTableContainerTMPB, -1)
64+
65+
if len(subma2b) > 0 {
66+
// Settings vars for usage in JSONData
67+
BoostedBossImage = subma2b[0][1]
68+
}
69+
70+
// Creating empty BoostableBossesData var
71+
var BoostableBossesData []OverviewBoostableBoss
72+
73+
// Running query over each div
74+
ReaderHTML.Find(".BoxContent div div").Each(func(index int, s *goquery.Selection) {
75+
76+
// Storing HTML into BoostableBossDivHTML
77+
BoostableBossDivHTML, err := s.Html()
78+
if err != nil {
79+
log.Fatal(err)
80+
}
81+
82+
// Regex to get data for name, race and img src param for creature
83+
subma1 := BoostableBossInformationRegex.FindAllStringSubmatch(BoostableBossDivHTML, -1)
84+
85+
// check if regex return length is over 0 and the match of name is over 1
86+
if len(subma1) > 0 && len(subma1[0][2]) > 1 {
87+
// Adding bool to indicate features in boostable_boss_list
88+
FeaturedRace := false
89+
if subma1[0][2] == BoostedBossName {
90+
FeaturedRace = true
91+
}
92+
93+
// Creating data block to return
94+
BoostableBossesData = append(BoostableBossesData, OverviewBoostableBoss{
95+
Name: TibiaDataSanitizeEscapedString(subma1[0][2]),
96+
ImageURL: subma1[0][1],
97+
Featured: FeaturedRace,
98+
})
99+
}
100+
})
101+
102+
// Build the data-blob
103+
return BoostableBossesOverviewResponse{
104+
BoostableBossesContainer{
105+
Boosted: OverviewBoostableBoss{
106+
Name: BoostedBossName,
107+
ImageURL: BoostedBossImage,
108+
Featured: true,
109+
},
110+
BoostableBosses: BoostableBossesData,
111+
},
112+
Information{
113+
APIVersion: TibiaDataAPIversion,
114+
Timestamp: TibiaDataDatetimeV3(""),
115+
},
116+
}
117+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package main
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestBoostableBossesOverview(t *testing.T) {
11+
data, err := os.ReadFile("../testdata/boostablebosses/boostablebosses.html")
12+
if err != nil {
13+
t.Errorf("File reading error: %s", err)
14+
return
15+
}
16+
17+
boostableBossesJson := TibiaBoostableBossesOverviewV3Impl(string(data))
18+
assert := assert.New(t)
19+
20+
assert.Equal("The Pale Worm", boostableBossesJson.BoostableBosses.Boosted.Name)
21+
assert.Equal("https://static.tibia.com/images/global/header/monsters/paleworm.gif", boostableBossesJson.BoostableBosses.Boosted.ImageURL)
22+
23+
assert.Equal(88, len(boostableBossesJson.BoostableBosses.BoostableBosses))
24+
25+
gnomevil := boostableBossesJson.BoostableBosses.BoostableBosses[18]
26+
assert.Equal("Gnomevil", gnomevil.Name)
27+
assert.Equal("https://static.tibia.com/images/library/gnomehorticulist.gif", gnomevil.ImageURL)
28+
assert.False(gnomevil.Featured)
29+
30+
paleworm := boostableBossesJson.BoostableBosses.BoostableBosses[72]
31+
assert.Equal("The Pale Worm", paleworm.Name)
32+
assert.Equal("https://static.tibia.com/images/library/paleworm.gif", paleworm.ImageURL)
33+
assert.True(paleworm.Featured)
34+
}

src/webserver.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ func runWebServer() {
8282
// TibiaData API version 3
8383
v3 := router.Group("/v3")
8484
{
85+
// Tibia characters
86+
v3.GET("/boostablebosses", tibiaBoostableBossesV3)
87+
8588
// Tibia characters
8689
v3.GET("/character/:name", tibiaCharactersCharacterV3)
8790

@@ -169,6 +172,29 @@ func runWebServer() {
169172
}
170173
}
171174

175+
// BoostableBosses godoc
176+
// @Summary List of boostable bosses
177+
// @Description Show all boostable bosses listed
178+
// @Tags boostable bosses
179+
// @Accept json
180+
// @Produce json
181+
// @Success 200 {object} BoostableBossesOverviewResponse
182+
// @Router /v3/boostablebosses [get]
183+
func tibiaBoostableBossesV3(c *gin.Context) {
184+
tibiadataRequest := TibiaDataRequestStruct{
185+
Method: resty.MethodGet,
186+
URL: "https://www.tibia.com/library/?subtopic=boostablebosses",
187+
}
188+
189+
tibiaDataRequestHandler(
190+
c,
191+
tibiadataRequest,
192+
func(BoxContentHTML string) (interface{}, int) {
193+
return TibiaBoostableBossesOverviewV3Impl(BoxContentHTML), http.StatusOK
194+
},
195+
"TibiaBoostableBossesV3")
196+
}
197+
172198
// Character godoc
173199
// @Summary Show one character
174200
// @Description Show all information about one character available

0 commit comments

Comments
 (0)