diff --git a/src/TibiaBoostableBossesOverview.go b/src/TibiaBoostableBossesOverview.go
index a5f7cd1b..748b4419 100644
--- a/src/TibiaBoostableBossesOverview.go
+++ b/src/TibiaBoostableBossesOverview.go
@@ -1,12 +1,11 @@
package main
import (
- "fmt"
+ "errors"
"net/http"
- "regexp"
"strings"
- "github.com/PuerkitoBio/goquery"
+ "github.com/TibiaData/tibiadata-api-go/src/validation"
)
// Child of BoostableBoss (used for list of boostable bosses and boosted boss section)
@@ -28,95 +27,126 @@ type BoostableBossesOverviewResponse struct {
Information Information `json:"information"`
}
-var (
- BoostedBossNameRegex = regexp.MustCompile(`(.*)`)
- BoostedBossImageRegex = regexp.MustCompile(`
]+\bsrc=["']([^"']+)["']`)
- BoostableBossInformationRegex = regexp.MustCompile(`
(.*)<\/div>`)
-)
+func TibiaBoostableBossesOverviewImpl(BoxContentHTML string) (BoostableBossesOverviewResponse, error) {
+ const (
+ bodyIndexer = `
`
-func TibiaBoostableBossesOverviewImpl(BoxContentHTML string) (*BoostableBossesOverviewResponse, error) {
- // Creating empty vars
- var (
- BoostedBossName, BoostedBossImage string
+ todayChecker = `Today's boosted boss: `
+ bossesChecker = ``
+
+ todayBossIndexer = `title="` + todayChecker
+ endTodayBossIndexer = `" src="`
+
+ todayBossImgIndexer = `https://static.tibia.com/images/global/header/monsters/`
+ endTodayBossImgIndexer = `" onClick="`
+
+ bossesImgIndexer = `https://static.tibia.com/images/library/`
+ endBossesImgIndexer = `"`
+
+ bossesNameIndexer = `border=0 />
`
+ endBossesNameIndexer = `
`
+ )
+
+ bodyIdx := strings.Index(
+ BoxContentHTML, bodyIndexer,
)
- // Loading HTML data into ReaderHTML for goquery with NewReader
- ReaderHTML, err := goquery.NewDocumentFromReader(strings.NewReader(BoxContentHTML))
- if err != nil {
- return nil, fmt.Errorf("[error] TibiaBoostableBossesOverviewImpl failed at goquery.NewDocumentFromReader, err: %s", err)
- }
- // Getting data from div.InnerTableContainer and then first p
- InnerTableContainerTMPB, err := ReaderHTML.Find(".InnerTableContainer p").First().Html()
- if err != nil {
- return nil, fmt.Errorf("[error] TibiaBoostableBossesOverviewImpl failed at ReaderHTML.Find, error: %s", err)
+ if bodyIdx == -1 {
+ return BoostableBossesOverviewResponse{}, errors.New("[error] body passd to TibiaBoostableBossesOverviewImpl is not valid")
}
- // Regex to get data for name for boosted boss
- subma1b := BoostedBossNameRegex.FindAllStringSubmatch(InnerTableContainerTMPB, -1)
+ endBodyIdx := strings.Index(
+ BoxContentHTML[bodyIdx:], endBodyIndexer,
+ ) + bodyIdx + len(endBodyIndexer)
- if len(subma1b) > 0 {
- // Settings vars for usage in JSONData
- BoostedBossName = subma1b[0][1]
+ if endBodyIdx == -1 {
+ return BoostableBossesOverviewResponse{}, errors.New("[error] body passd to TibiaBoostableBossesOverviewImpl is not valid")
}
- // Regex to get image of boosted boss
- subma2b := BoostedBossImageRegex.FindAllStringSubmatch(InnerTableContainerTMPB, -1)
+ data := BoxContentHTML[bodyIdx:endBodyIdx]
- if len(subma2b) > 0 {
- // Settings vars for usage in JSONData
- BoostedBossImage = subma2b[0][1]
- }
+ var (
+ started bool
- // Creating empty BoostableBossesData var
- var BoostableBossesData []OverviewBoostableBoss
+ boostedBossName string
+ boostedBossImg string
- var insideError error
+ bosses = make([]OverviewBoostableBoss, 0, validation.AmountOfBoostableBosses)
+ )
- // Running query over each div
- ReaderHTML.Find(".BoxContent div div").EachWithBreak(func(index int, s *goquery.Selection) bool {
+ split := strings.Split(data, "\n")
+ for _, cur := range split {
+ isTodaysLine := strings.Contains(cur, todayChecker) && !started
+ isBossesLine := strings.Contains(cur, bossesChecker)
- // Storing HTML into BoostableBossDivHTML
- BoostableBossDivHTML, err := s.Html()
- if err != nil {
- insideError = fmt.Errorf("[error] TibiaBoostableBossesOverviewImpl failed at BoostableBossDivHTML, err := s.Html(), err: %s", err)
- return false
+ if !isTodaysLine && !isBossesLine {
+ continue
}
- // Regex to get data for name, race and img src param for creature
- subma1 := BoostableBossInformationRegex.FindAllStringSubmatch(BoostableBossDivHTML, -1)
+ if isTodaysLine {
+ started = true
- // check if regex return length is over 0 and the match of name is over 1
- if len(subma1) > 0 && len(subma1[0][2]) > 1 {
- // Adding bool to indicate features in boostable_boss_list
- FeaturedRace := false
- if subma1[0][2] == BoostedBossName {
- FeaturedRace = true
- }
+ todayBossIdx := strings.Index(
+ cur, todayBossIndexer,
+ ) + len(todayBossIndexer)
+ endTodayBossIdx := strings.Index(
+ cur[todayBossIdx:], endTodayBossIndexer,
+ ) + todayBossIdx
- // Creating data block to return
- BoostableBossesData = append(BoostableBossesData, OverviewBoostableBoss{
- Name: TibiaDataSanitizeEscapedString(subma1[0][2]),
- ImageURL: subma1[0][1],
- Featured: FeaturedRace,
- })
+ boostedBossName = TibiaDataSanitizeEscapedString(
+ cur[todayBossIdx:endTodayBossIdx],
+ )
+
+ todayBossImgIdx := strings.Index(
+ cur[todayBossIdx:], todayBossImgIndexer,
+ ) + todayBossIdx
+ endTodayBossImgIdx := strings.Index(
+ cur[todayBossImgIdx:], endTodayBossImgIndexer,
+ ) + todayBossImgIdx
+
+ boostedBossImg = cur[todayBossImgIdx:endTodayBossImgIdx]
}
- return true
- })
+ if isBossesLine {
+ for idx := strings.Index(cur, bossesImgIndexer); idx != -1; idx = strings.Index(cur, bossesImgIndexer) {
+ imgIdx := strings.Index(
+ cur, bossesImgIndexer,
+ )
+ endImgIdx := strings.Index(
+ cur[imgIdx:], endBossesImgIndexer,
+ ) + imgIdx
+ img := cur[imgIdx:endImgIdx]
+
+ nameIdx := strings.Index(
+ cur, bossesNameIndexer,
+ ) + len(bossesNameIndexer)
+ endNameIdx := strings.Index(
+ cur[nameIdx:], endBossesNameIndexer,
+ ) + nameIdx
+ name := TibiaDataSanitizeEscapedString(cur[nameIdx:endNameIdx])
+
+ bosses = append(bosses, OverviewBoostableBoss{
+ Name: name,
+ ImageURL: img,
+ Featured: name == boostedBossName,
+ })
+
+ cur = cur[endNameIdx-1:]
+ }
- if insideError != nil {
- return nil, insideError
+ break
+ }
}
- // Build the data-blob
- return &BoostableBossesOverviewResponse{
+ return BoostableBossesOverviewResponse{
BoostableBossesContainer{
Boosted: OverviewBoostableBoss{
- Name: TibiaDataSanitizeEscapedString(BoostedBossName),
- ImageURL: BoostedBossImage,
+ Name: boostedBossName,
+ ImageURL: boostedBossImg,
Featured: true,
},
- BoostableBosses: BoostableBossesData,
+ BoostableBosses: bosses,
},
Information{
APIDetails: TibiaDataAPIDetails,
diff --git a/src/TibiaBoostableBossesOverview_test.go b/src/TibiaBoostableBossesOverview_test.go
index 71a7a2cf..45cc7e53 100644
--- a/src/TibiaBoostableBossesOverview_test.go
+++ b/src/TibiaBoostableBossesOverview_test.go
@@ -22,24 +22,85 @@ func TestBoostableBossesOverview(t *testing.T) {
boostableBossesJson, _ := TibiaBoostableBossesOverviewImpl(string(data))
assert := assert.New(t)
+ boosted := boostableBossesJson.BoostableBosses.Boosted
+ bosses := boostableBossesJson.BoostableBosses.BoostableBosses
- assert.Equal("Goshnar's Malice", boostableBossesJson.BoostableBosses.Boosted.Name)
- assert.Equal("https://static.tibia.com/images/global/header/monsters/goshnarsmalice.gif", boostableBossesJson.BoostableBosses.Boosted.ImageURL)
+ assert.Equal(91, len(bosses))
+ assert.Equal("Sharpclaw", boosted.Name)
+ assert.Equal(
+ "https://static.tibia.com/images/global/header/monsters/sharpclaw.gif",
+ boosted.ImageURL,
+ )
- assert.Equal(89, len(boostableBossesJson.BoostableBosses.BoostableBosses))
+ for _, tc := range []struct {
+ idx int
+ name string
+ featured bool
+ imageURL string
+ }{
+ {
+ idx: 19,
+ name: "Gnomevil",
+ featured: false,
+ imageURL: "https://static.tibia.com/images/library/gnomehorticulist.gif",
+ },
+ {
+ idx: 24,
+ name: "Goshnar's Malice",
+ featured: false,
+ imageURL: "https://static.tibia.com/images/library/goshnarsmalice.gif",
+ },
+ {
+ idx: 52,
+ name: "Sharpclaw",
+ featured: true,
+ imageURL: "https://static.tibia.com/images/library/sharpclaw.gif",
+ },
+ {
+ idx: 75,
+ name: "The Pale Worm",
+ featured: false,
+ imageURL: "https://static.tibia.com/images/library/paleworm.gif",
+ },
+ } {
+ boss := bosses[tc.idx]
+ assert.Equal(
+ tc.name, boss.Name,
+ "Wrong name\nidx: %d (%s)\nwant: %s\ngot: %s",
+ tc.idx, tc.name, tc.name, boss.Name,
+ )
+ assert.Equal(
+ tc.featured, boss.Featured,
+ "Wrong featured status\nidx: %d (%s)\nwant: %v\ngot: %v",
+ tc.idx, tc.name, tc.featured, boss.Featured,
+ )
+ assert.Equal(
+ tc.imageURL, boss.ImageURL,
+ "Wrong image URL\nidx: %d (%s)\nwant: %s\ngot: %s",
+ tc.idx, tc.name, tc.imageURL, boss.ImageURL,
+ )
+ }
+}
- gnomevil := boostableBossesJson.BoostableBosses.BoostableBosses[18]
- assert.Equal("Gnomevil", gnomevil.Name)
- assert.Equal("https://static.tibia.com/images/library/gnomehorticulist.gif", gnomevil.ImageURL)
- assert.False(gnomevil.Featured)
+var bossSink BoostableBossesOverviewResponse
- goshnarsmalice := boostableBossesJson.BoostableBosses.BoostableBosses[23]
- assert.Equal("Goshnar's Malice", goshnarsmalice.Name)
- assert.Equal("https://static.tibia.com/images/library/goshnarsmalice.gif", goshnarsmalice.ImageURL)
- assert.True(goshnarsmalice.Featured)
+func BenchmarkTibiaBoostableBossesOverviewImpl(b *testing.B) {
+ file, err := static.TestFiles.Open("testdata/boostablebosses/boostablebosses.html")
+ if err != nil {
+ b.Fatalf("file opening error: %s", err)
+ }
+ defer file.Close()
- paleworm := boostableBossesJson.BoostableBosses.BoostableBosses[73]
- assert.Equal("The Pale Worm", paleworm.Name)
- assert.Equal("https://static.tibia.com/images/library/paleworm.gif", paleworm.ImageURL)
- assert.False(paleworm.Featured)
+ rawData, err := io.ReadAll(file)
+ if err != nil {
+ b.Fatalf("File reading error: %s", err)
+ }
+ data := string(rawData)
+
+ b.ReportAllocs()
+ b.ResetTimer()
+
+ for i := 0; i < b.N; i++ {
+ bossSink, _ = TibiaBoostableBossesOverviewImpl(data)
+ }
}
diff --git a/src/static/testdata/boostablebosses/boostablebosses.html b/src/static/testdata/boostablebosses/boostablebosses.html
index c06059a8..7dd8f9c8 100644
--- a/src/static/testdata/boostablebosses/boostablebosses.html
+++ b/src/static/testdata/boostablebosses/boostablebosses.html
@@ -1,4 +1,5 @@
+
@@ -39,13 +40,13 @@
-
+
-
+
-
-
-
+
+
+
+
+ var loginStatus=0; loginStatus='false'; var activeSubmenuItem='boostablebosses'; var JS_DIR_IMAGES=0; JS_DIR_IMAGES='https://static.tibia.com/images/'; var JS_DIR_ACCOUNT=0; JS_DIR_ACCOUNT='https://www.tibia.com/account/'; var JS_DIR_COMMUNITY=0; JS_DIR_COMMUNITY='https://www.tibia.com/community/'; var JS_DIR_WEBSITESERVICES=0; JS_DIR_WEBSITESERVICES='https://www.tibia.com/websiteservices/'; var JS_FACEBOOKAPPID = '497232093667125'; var JS_COOKIE_DOMAIN=0; JS_COOKIE_DOMAIN='.tibia.com'; var g_FormName=''; var g_FormField=''; var g_Deactivated=false; var JS_ANNIVERSARY_THEMEBOX_STEP_1=0; JS_ANNIVERSARY_THEMEBOX_STEP_1='1663660800'; var JS_ANNIVERSARY_THEMEBOX_STEP_2=0; JS_ANNIVERSARY_THEMEBOX_STEP_2='1663660800'; var JS_ANNIVERSARY_THEMEBOX_STEP_3=0; JS_ANNIVERSARY_THEMEBOX_STEP_3='1664215200';var FB_TryLogin = 0;var FB_ForceReload = 0;
-
-
+
+
+
@@ -109,7 +113,7 @@