|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "log" |
| 5 | + "regexp" |
| 6 | + "strings" |
| 7 | + |
| 8 | + "github.com/PuerkitoBio/goquery" |
| 9 | + "github.com/gin-gonic/gin" |
| 10 | +) |
| 11 | + |
| 12 | +// TibiaGuildsGuildV3 func |
| 13 | +func TibiaGuildsGuildV3(c *gin.Context) { |
| 14 | + |
| 15 | + // getting params from URL |
| 16 | + guild := c.Param("guild") |
| 17 | + |
| 18 | + // Child of Guild |
| 19 | + type Guildhall struct { |
| 20 | + Name string `json:"name"` |
| 21 | + World string `json:"world"` // Maybe duplicate info? Guild can only be on one world.. |
| 22 | + /* |
| 23 | + Town string `json:"town"` // We can collect that from cached info? |
| 24 | + Status string `json:"status"` // rented (but maybe also auctioned) |
| 25 | + Owner string `json:"owner"` // We can collect that from cached info? |
| 26 | + HouseID int `json:"houseid"` // We can collect that from cached info? |
| 27 | + */ |
| 28 | + PaidUntil string `json:"paid_until"` // Paid until date |
| 29 | + } |
| 30 | + |
| 31 | + // Child of Guild |
| 32 | + type Members struct { |
| 33 | + Name string `json:"name"` |
| 34 | + Title string `json:"title"` |
| 35 | + Rank string `json:"rank"` |
| 36 | + Vocation string `json:"vocation"` |
| 37 | + Level int `json:"level"` |
| 38 | + Joined string `json:"joined"` |
| 39 | + Status string `json:"status"` |
| 40 | + } |
| 41 | + // Child of Guild |
| 42 | + type Invited struct { |
| 43 | + Name string `json:"name"` |
| 44 | + Date string `json:"date"` |
| 45 | + } |
| 46 | + |
| 47 | + // Child of Guilds |
| 48 | + type Guild struct { |
| 49 | + Name string `json:"name"` |
| 50 | + World string `json:"world"` |
| 51 | + LogoURL string `json:"logo_url"` |
| 52 | + Description string `json:"description"` |
| 53 | + Guildhalls []Guildhall `json:"guildhalls"` |
| 54 | + Active bool `json:"active"` |
| 55 | + Founded string `json:"founded"` |
| 56 | + Applications bool `json:"open_applications"` |
| 57 | + Homepage string `json:"homepage"` |
| 58 | + InWar bool `json:"in_war"` |
| 59 | + DisbandedDate string `json:"disband_date"` |
| 60 | + DisbandedCondition string `json:"disband_condition"` |
| 61 | + PlayersOnline int `json:"players_online"` |
| 62 | + PlayersOffline int `json:"players_offline"` |
| 63 | + MembersTotal int `json:"members_total"` |
| 64 | + MembersInvited int `json:"members_invited"` |
| 65 | + Members []Members `json:"members"` |
| 66 | + Invited []Invited `json:"invites"` |
| 67 | + } |
| 68 | + |
| 69 | + // Child of JSONData |
| 70 | + type Guilds struct { |
| 71 | + Guild Guild `json:"guild"` |
| 72 | + } |
| 73 | + |
| 74 | + // |
| 75 | + // The base includes two levels: Guild and Information |
| 76 | + type JSONData struct { |
| 77 | + Guilds Guilds `json:"guilds"` |
| 78 | + Information Information `json:"information"` |
| 79 | + } |
| 80 | + |
| 81 | + // Creating empty vars |
| 82 | + var MembersData []Members |
| 83 | + var InvitedData []Invited |
| 84 | + var GuildGuildhallData []Guildhall |
| 85 | + var MembersRank, MembersTitle, MembersStatus, GuildDescription, GuildDisbandedDate, GuildDisbandedCondition, GuildHomepage, GuildWorld, GuildLogoURL, GuildFounded string |
| 86 | + var GuildActive, GuildApplications, GuildInWar bool |
| 87 | + var MembersCountOnline, MembersCountOffline, MembersCountInvited int |
| 88 | + |
| 89 | + // Getting data with TibiadataHTMLDataCollectorV3 |
| 90 | + BoxContentHTML := TibiadataHTMLDataCollectorV3("https://www.tibia.com/community/?subtopic=guilds&page=view&GuildName=" + TibiadataQueryEscapeStringV3(guild)) |
| 91 | + |
| 92 | + // Loading HTML data into ReaderHTML for goquery with NewReader |
| 93 | + ReaderHTML, err := goquery.NewDocumentFromReader(strings.NewReader(BoxContentHTML)) |
| 94 | + if err != nil { |
| 95 | + log.Fatal(err) |
| 96 | + } |
| 97 | + |
| 98 | + // Getting data from div.InnerTableContainer and then first p |
| 99 | + InnerTableContainerTMPA, err := ReaderHTML.Find(".BoxContent table").Html() |
| 100 | + if err != nil { |
| 101 | + log.Fatal(err) |
| 102 | + } |
| 103 | + regex1b := regexp.MustCompile(`.*img src="(.*)" width=.*`) |
| 104 | + subma1b := regex1b.FindAllStringSubmatch(InnerTableContainerTMPA, -1) |
| 105 | + GuildLogoURL = subma1b[0][1] |
| 106 | + |
| 107 | + // Getting data from div.InnerTableContainer and then first p |
| 108 | + InnerTableContainerTMPB, err := ReaderHTML.Find("#GuildInformationContainer").Html() |
| 109 | + if err != nil { |
| 110 | + log.Fatal(err) |
| 111 | + } |
| 112 | + |
| 113 | + var GuildDescriptionFinished bool |
| 114 | + for _, line := range strings.Split(strings.TrimSuffix(InnerTableContainerTMPB, "\n"), "\n") { |
| 115 | + |
| 116 | + // Guild information |
| 117 | + if !GuildDescriptionFinished { |
| 118 | + // First line is the description.. |
| 119 | + GuildDescription += strings.ReplaceAll(line+"\n", "<br/><br/>\n", "") |
| 120 | + |
| 121 | + // Abort loop and continue wiht next section |
| 122 | + if strings.Contains(line, "<br/><br/>") { |
| 123 | + GuildDescription = TibiadataUnescapeStringV3(GuildDescription) |
| 124 | + GuildDescriptionFinished = true |
| 125 | + } |
| 126 | + |
| 127 | + } else if GuildDescriptionFinished { |
| 128 | + // The rest of the Guild information |
| 129 | + |
| 130 | + if strings.Contains(line, "The guild was founded on") { |
| 131 | + // Regex to get GuildWorld and GuildFounded |
| 132 | + regex1b := regexp.MustCompile(`The guild was founded on (.*) on (.*).<br/>`) |
| 133 | + subma1b := regex1b.FindAllStringSubmatch(line, -1) |
| 134 | + GuildWorld = subma1b[0][1] |
| 135 | + GuildFounded = TibiadataDateV3(subma1b[0][2]) |
| 136 | + } |
| 137 | + |
| 138 | + // If to get GuildActive |
| 139 | + if strings.Contains(line, "It is currently active") { |
| 140 | + GuildActive = true |
| 141 | + } |
| 142 | + |
| 143 | + // If open for applications |
| 144 | + if strings.Contains(line, "Guild is opened for applications.") { |
| 145 | + GuildApplications = true |
| 146 | + } else if strings.Contains(line, "Guild is closed for applications during war.") { |
| 147 | + GuildInWar = true |
| 148 | + } |
| 149 | + |
| 150 | + if strings.Contains(line, "The official homepage is") { |
| 151 | + regex1c := regexp.MustCompile(`<a href="(.*)" target=.*>`) |
| 152 | + subma1c := regex1c.FindAllStringSubmatch(line, -1) |
| 153 | + GuildHomepage = subma1c[0][1] |
| 154 | + } |
| 155 | + |
| 156 | + // If guildhall |
| 157 | + if strings.Contains(line, "Their home on "+GuildWorld) { |
| 158 | + // Regex to get GuildWorld and GuildFounded |
| 159 | + regex1b := regexp.MustCompile(`Their home on ` + GuildWorld + ` is (.*). The rent is paid until (.*).<br/>`) |
| 160 | + subma1b := regex1b.FindAllStringSubmatch(line, -1) |
| 161 | + |
| 162 | + GuildGuildhallData = append(GuildGuildhallData, Guildhall{ |
| 163 | + Name: TibiadataUnescapeStringV3(subma1b[0][1]), |
| 164 | + World: GuildWorld, |
| 165 | + PaidUntil: TibiadataDateV3(subma1b[0][2]), |
| 166 | + }) |
| 167 | + } |
| 168 | + |
| 169 | + // If disbanded |
| 170 | + if strings.Contains(line, "<b>It will be disbanded on ") { |
| 171 | + regex1c := regexp.MustCompile(`<b>It will be disbanded on (.*.[0-9]+.[0-9]+) (.*)\.<\/b>.*`) |
| 172 | + subma1c := regex1c.FindAllStringSubmatch(line, -1) |
| 173 | + if len(subma1c) > 0 { |
| 174 | + GuildDisbandedDate = subma1c[0][1] |
| 175 | + GuildDisbandedCondition = subma1c[0][2] |
| 176 | + } |
| 177 | + } |
| 178 | + } |
| 179 | + } |
| 180 | + |
| 181 | + // Running query over each div |
| 182 | + ReaderHTML.Find(".TableContentContainer .TableContent tbody tr").Each(func(index int, s *goquery.Selection) { |
| 183 | + |
| 184 | + // Storing HTML into GuildsDivHTML |
| 185 | + GuildsDivHTML, err := s.Html() |
| 186 | + if err != nil { |
| 187 | + log.Fatal(err) |
| 188 | + } |
| 189 | + |
| 190 | + // Removing linebreaks from HTML |
| 191 | + GuildsDivHTML = TibiadataHTMLRemoveLinebreaksV3(GuildsDivHTML) |
| 192 | + |
| 193 | + // Regex to get data for record values |
| 194 | + regex1 := regexp.MustCompile(`<td>(.*)<\/td><td><a.*">(.*)<\/a>(.*)<\/td><td>(.*)<\/td><td>([0-9]+)<\/td><td>(.*)<\/td><td class.*class.*">(.*)<\/span><\/td>`) |
| 195 | + subma1 := regex1.FindAllStringSubmatch(GuildsDivHTML, -1) |
| 196 | + |
| 197 | + if len(subma1) > 0 { |
| 198 | + // Rank name |
| 199 | + if len(subma1[0][1]) > 2 { |
| 200 | + MembersRank = subma1[0][1] |
| 201 | + } |
| 202 | + |
| 203 | + // Title |
| 204 | + MembersTitle = strings.ReplaceAll(strings.ReplaceAll(subma1[0][3], " (", ""), ")", "") |
| 205 | + |
| 206 | + // Status |
| 207 | + if strings.Contains(subma1[0][7], "online") { |
| 208 | + MembersStatus = "online" |
| 209 | + MembersCountOnline++ |
| 210 | + } else { |
| 211 | + MembersStatus = "offline" |
| 212 | + MembersCountOffline++ |
| 213 | + } |
| 214 | + |
| 215 | + MembersData = append(MembersData, Members{ |
| 216 | + Name: TibiadataUnescapeStringV3(subma1[0][2]), |
| 217 | + Title: MembersTitle, |
| 218 | + Rank: MembersRank, |
| 219 | + Vocation: subma1[0][4], |
| 220 | + Level: TibiadataStringToIntegerV3(subma1[0][5]), |
| 221 | + Joined: TibiadataDateV3(subma1[0][6]), |
| 222 | + Status: MembersStatus, |
| 223 | + }) |
| 224 | + |
| 225 | + } else { |
| 226 | + |
| 227 | + // Regex to get data for record values |
| 228 | + regex2 := regexp.MustCompile(`<td><a.*">(.*)<\/a><\/td><td>(.*)<\/td>`) |
| 229 | + subma2 := regex2.FindAllStringSubmatch(GuildsDivHTML, -1) |
| 230 | + |
| 231 | + if len(subma2) > 0 { |
| 232 | + MembersCountInvited++ |
| 233 | + InvitedData = append(InvitedData, Invited{ |
| 234 | + Name: subma2[0][1], |
| 235 | + Date: subma2[0][2], |
| 236 | + }) |
| 237 | + } |
| 238 | + } |
| 239 | + }) |
| 240 | + |
| 241 | + // |
| 242 | + // Build the data-blob |
| 243 | + jsonData := JSONData{ |
| 244 | + Guilds{ |
| 245 | + Guild{ |
| 246 | + Name: guild, |
| 247 | + World: GuildWorld, |
| 248 | + LogoURL: GuildLogoURL, |
| 249 | + Description: GuildDescription, |
| 250 | + Guildhalls: GuildGuildhallData, |
| 251 | + Active: GuildActive, |
| 252 | + Founded: GuildFounded, |
| 253 | + Applications: GuildApplications, |
| 254 | + Homepage: GuildHomepage, |
| 255 | + InWar: GuildInWar, |
| 256 | + DisbandedDate: GuildDisbandedDate, |
| 257 | + DisbandedCondition: GuildDisbandedCondition, |
| 258 | + |
| 259 | + PlayersOnline: MembersCountOnline, |
| 260 | + PlayersOffline: MembersCountOffline, |
| 261 | + MembersTotal: (MembersCountOnline + MembersCountOffline), |
| 262 | + MembersInvited: MembersCountInvited, |
| 263 | + Members: MembersData, |
| 264 | + Invited: InvitedData, |
| 265 | + }, |
| 266 | + }, |
| 267 | + Information{ |
| 268 | + APIVersion: TibiadataAPIversion, |
| 269 | + Timestamp: TibiadataDatetimeV3(""), |
| 270 | + }, |
| 271 | + } |
| 272 | + |
| 273 | + // return jsonData |
| 274 | + TibiaDataAPIHandleSuccessResponse(c, "TibiaGuildsGuildV3", jsonData) |
| 275 | +} |
0 commit comments