首先送出"G"跳到文章的最後一頁,之後的功能也預計會從新的推文往舊的解析,但換頁這部分我還在思考,不會在今天的內容。
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
PttClient.getInstance().send("G")
delay(100L)
Log.d(mTag, "current page:\n${PttClient.getInstance().getScreen()}")
val rows = PttClient.getInstance().getScreen().split("\n")
//TODO parsing.
}
在開始解析前先來看一下Ptt的看板設定:
其中i和a的開啟與否會影響推文時顯示的格式:
以上四行的設定分別是i關a關、i關a開、i開a關、i開a開。其中紅色覆蓋的是ID、綠色覆蓋的是IP。
因為我是在Ptt2做測試,因此最後面有多了一個"推",目前Ptt是沒有這個字了。
對我們分析影響比較大的是IP的設定,需設計成IP顯示與否都能正確解析的Pattern。
目前測試起來應該能符合的Pattern如下:"(?<like>[推]|[→]|[噓])*[ ](?<id>.*)[:][ ](?<content>.*)[ ](?<ip>((.*\.){3}.*|[ ]))(?<date>../.. ..:..)"
若ip無開放的話會去抓空格,開放的話也能將ip抓出來。
data class Comment(
val like: String,
val id: String,
val content: String,
val ip: String,
val time: String
) {
override fun equals(other: Any?): Boolean {
if (other is Comment) {
return (other.hashCode() == hashCode()) ||
(like == other.like && id == other.id && content == other.content
&& ip == other.ip && time == other.time)
}
return super.equals(other)
}
override fun hashCode(): Int {
return super.hashCode()
}
}
目前是先將上面抓出的項目都儲存起來,IP還在思考要不要存,因為應該是不會顯示。
另外有override equals方法,這是為了未來在更新推文時要比對用。
承一開始的程式碼,當中的//TODO parsing.
val commentPattern =
Pattern.compile("(?<like>[推]|[→]|[噓])*[ ](?<id>.*)[:][ ](?<content>.*)[ ](?<ip>((.*\.){3}.*|[ ]))(?<date>../.. ..:..)")
rows.forEach {
val matcher = commentPattern.matcher(it)
if (matcher.find()) {
val like = matcher.group("like")!!.trim()
val id = matcher.group("id")!!.trim()
val content = matcher.group("content")!!.trim()
val ip = matcher.group("ip")!!.trim()
val date = matcher.group("date")!!.trim()
val comment = Comment(
like,
id,
content,
ip,
date
)
Log.d(mTag, "comment:$comment")
}
}