Coverage Summary for Class: ForumsKt (com.galarzaa.tibiakt.core.html)
| Class |
Class, %
|
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| ForumsKt |
100%
(1/1)
|
100%
(3/3)
|
69.6%
(39/56)
|
96.8%
(61/63)
|
90.9%
(439/483)
|
/*
* Copyright © 2025 Allan Galarza
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.galarzaa.tibiakt.core.html
import com.galarzaa.tibiakt.core.enums.StringEnum
import com.galarzaa.tibiakt.core.exceptions.ParsingException
import com.galarzaa.tibiakt.core.section.community.guild.model.GuildMembershipWithTitle
import com.galarzaa.tibiakt.core.section.forum.shared.builder.lastPost
import com.galarzaa.tibiakt.core.section.forum.shared.model.ForumAuthor
import com.galarzaa.tibiakt.core.section.forum.shared.model.LastPost
import com.galarzaa.tibiakt.core.text.findInteger
import com.galarzaa.tibiakt.core.text.parseInteger
import com.galarzaa.tibiakt.core.text.remove
import com.galarzaa.tibiakt.core.time.parseTibiaForumDateTime
import org.jsoup.nodes.Element
internal const val TRADED_TAG = "(traded)"
internal fun parseLastPostFromCell(cell: Element): LastPost? {
val postDate = cell.selectFirst("span.LastPostInfo") ?: return null
val permalink = cell.selectFirst("a")?.getLinkInformation() ?: return null
val authorTag = cell.selectFirst("font") ?: return null
val authorLink = authorTag.selectFirst("a")?.getLinkInformation()
var authorName = authorTag.cleanText().removePrefix("by ")
var isTraded = false
if (TRADED_TAG in authorName) {
authorName = authorName.remove(TRADED_TAG)
isTraded = true
}
return lastPost {
postId = permalink.queryParams["postid"]!!.first().toInt()
postedAt = parseTibiaForumDateTime(postDate.cleanText())
this.authorName = authorName
isDeleted = authorLink == null && !isTraded
this.isTraded = isTraded
}
}
private val titles =
listOf("Tutor", "Community Manager", "Customer Support", "Programmer", "Game Content Designer", "Tester")
private val charInfoRegex = Regex("""Inhabitant of (\w+)\nVocation: ([\w\s]+)\nLevel: (\d+)""")
private val authorPostsRegex = Regex("""Posts: (\d+)""")
private val titleRegex = Regex("""\(([\w\s]+)\)""")
internal fun parseAuthorTable(table: Element): ForumAuthor {
val charLink = table.selectFirst("a")?.getLinkInformation()
if (charLink == null) {
val name = table.cleanText()
val isTraded: Boolean = name.contains(TRADED_TAG)
return ForumAuthor.Unavailable(name.remove(TRADED_TAG).trim(), !isTraded, isTraded)
}
val charInfo = table.selectFirst("font.ff_infotext")
val positionInfo = table.selectFirst("font.ff_smallinfo")
var title: String? = null
var position: String? = null
var isRecentlyTraded = false
if (positionInfo != null && (charInfo == null || positionInfo.parent() != charInfo)) {
positionInfo.replaceBrs().wholeCleanText().split("\n").forEach {
if (it in titles) position = it
else if ("traded" in it) isRecentlyTraded = true
else title = it
}
}
var guildMembership: GuildMembershipWithTitle? = null
charInfo?.selectFirst("font.ff_smallinfo")?.let {
val guildLink = it.selectFirst("a")
val guildLinkInfo = guildLink?.getLinkInformation()!!
val guildName = guildLinkInfo.title
guildLink.remove()
var rank = it.cleanText()
val guildTitle = titleRegex.find(rank)?.groupValues?.get(1)?.also { g -> rank = rank.remove("($g)").trim() }
rank = rank.removeSuffix("of the").trim()
guildMembership = GuildMembershipWithTitle(guildName, rank, guildTitle)
}
charInfo?.replaceBrs()
if (charInfo?.cleanText()?.contains("Tournament - ") == true) {
return ForumAuthor.Tournament(charLink.title, charInfo.cleanText().findInteger())
}
val (_, world, vocation, level) = charInfoRegex.find(charInfo!!.wholeCleanText())?.groupValues
?: throw ParsingException("Could not find character info")
val (_, postsText) = authorPostsRegex.find(charInfo.wholeCleanText())!!.groupValues
return ForumAuthor.Character(
name = charLink.title,
level = level.toInt(),
world = world,
vocation = StringEnum.fromValue(vocation) ?: throw ParsingException("Unknown vocation: $vocation"),
position = position,
title = title,
guild = guildMembership,
postsCount = postsText.parseInteger(),
isRecentlyTraded = isRecentlyTraded
)
}