fix: adjust for new API changes
This commit is contained in:
parent
86a40d2e84
commit
85fc5cac21
|
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
* Adapt to changes in lobste.rs API
|
||||
|
||||
## [1.41.0] - 2024-03-07
|
||||
|
||||
### Fixed
|
||||
|
|
|
@ -8,7 +8,6 @@ package dev.msfjarvis.claw.api.converters
|
|||
|
||||
import dev.msfjarvis.claw.api.LobstersApi
|
||||
import dev.msfjarvis.claw.model.LobstersPost
|
||||
import dev.msfjarvis.claw.model.User
|
||||
import java.lang.reflect.Type
|
||||
import okhttp3.ResponseBody
|
||||
import org.jsoup.Jsoup
|
||||
|
@ -32,8 +31,7 @@ object SearchConverter : Converter<ResponseBody, List<LobstersPost>> {
|
|||
val url = titleElement.attr("href")
|
||||
val tags = elem.select("span.tags > a").map(Element::text)
|
||||
val (commentCount, commentsUrl) = getCommentsData(elem.select("span.comments_label"))
|
||||
val submitter =
|
||||
getSubmitter(elem.select("div.byline").first() ?: error("No byline element found"))
|
||||
val submitter = elem.select("div.byline > a.u-author").text()
|
||||
return LobstersPost(
|
||||
shortId = shortId,
|
||||
title = title,
|
||||
|
@ -55,24 +53,6 @@ object SearchConverter : Converter<ResponseBody, List<LobstersPost>> {
|
|||
return (countString.toIntOrNull() ?: 0) to commentsUrl
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a bare-bones [User] object given a byline [elem]. We only need this to be usable for
|
||||
* displaying in a list.
|
||||
*/
|
||||
private fun getSubmitter(elem: Element): User {
|
||||
val userElement = elem.select("a.u-author")
|
||||
val avatarElement = elem.select("img.avatar")
|
||||
val username = userElement.text()
|
||||
val avatarUrl = avatarElement.attr("src")
|
||||
return User(
|
||||
username = username,
|
||||
about = "",
|
||||
invitedBy = null,
|
||||
avatarUrl = avatarUrl,
|
||||
createdAt = "",
|
||||
)
|
||||
}
|
||||
|
||||
object Factory : Converter.Factory() {
|
||||
override fun responseBodyConverter(
|
||||
type: Type,
|
||||
|
|
|
@ -33,7 +33,7 @@ class ApiTest {
|
|||
val posts = api.getHottestPosts(1)
|
||||
assertIs<Success<List<LobstersPost>>>(posts)
|
||||
val commentsOnlyPosts = posts.value.asSequence().filter { it.url.isEmpty() }.toSet()
|
||||
assertThat(commentsOnlyPosts).hasSize(2)
|
||||
assertThat(commentsOnlyPosts).hasSize(1)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -10,7 +10,6 @@ import com.google.common.truth.Truth.assertThat
|
|||
import com.slack.eithernet.ApiResult
|
||||
import com.slack.eithernet.test.newEitherNetController
|
||||
import dev.msfjarvis.claw.model.LobstersPost
|
||||
import dev.msfjarvis.claw.model.User
|
||||
import dev.msfjarvis.claw.util.TestUtils.assertIs
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Test
|
||||
|
@ -38,7 +37,7 @@ class SearchApiTest {
|
|||
createdAt = "",
|
||||
commentCount = 3,
|
||||
commentsUrl = "https://lobste.rs/s/gjlsdg/chatgpt_visits_emacs_doctor",
|
||||
submitter = User("xenodium", "", null, "/avatars/xenodium-16.png", ""),
|
||||
submitter = "xenodium",
|
||||
tags = listOf("ai", "emacs"),
|
||||
description = "",
|
||||
),
|
||||
|
@ -50,7 +49,7 @@ class SearchApiTest {
|
|||
createdAt = "",
|
||||
commentCount = 0,
|
||||
commentsUrl = "https://lobste.rs/s/astcqf/implementing_question_answering_system",
|
||||
submitter = User("asteroid", "", null, "/avatars/asteroid-16.png", ""),
|
||||
submitter = "asteroid",
|
||||
tags = listOf("ai"),
|
||||
description = "",
|
||||
),
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
{"username":"msfjarvis","created_at":"2020-04-24T11:41:56.000-05:00","is_admin":false,"about":"Android and Kotlin developer\r\n","is_moderator":false,"karma":574,"avatar_url":"/avatars/msfjarvis-100.png","invited_by_user":"Amolith","github_username":"msfjarvis","twitter_username":"msfjarvis"}
|
||||
{"username":"msfjarvis","created_at":"2020-04-24T11:41:56.000-05:00","is_admin":false,"about":"Android and Kotlin developer, currently working for [Dyte](https://dyte.io/)","is_moderator":false,"karma":1343,"avatar_url":"/avatars/msfjarvis-100.png","invited_by_user":"Amolith","github_username":"msfjarvis"}
|
File diff suppressed because one or more lines are too long
|
@ -90,13 +90,11 @@ internal fun CommentsHeader(
|
|||
Spacer(Modifier.height(4.dp))
|
||||
}
|
||||
Submitter(
|
||||
text = AnnotatedString("Submitted by ${post.submitter.username}"),
|
||||
avatarUrl = "https://lobste.rs/${post.submitter.avatarUrl}",
|
||||
contentDescription = "User avatar for ${post.submitter.username}",
|
||||
text = AnnotatedString("Submitted by ${post.submitter}"),
|
||||
avatarUrl = "https://lobste.rs/avatars/${post.submitter}-100.png",
|
||||
contentDescription = "User avatar for ${post.submitter}",
|
||||
modifier =
|
||||
Modifier.clickable {
|
||||
uriHandler.openUri("https://lobste.rs/u/${post.submitter.username}")
|
||||
},
|
||||
Modifier.clickable { uriHandler.openUri("https://lobste.rs/u/${post.submitter}") },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -156,16 +154,15 @@ internal fun CommentEntry(
|
|||
Submitter(
|
||||
text =
|
||||
buildCommenterString(
|
||||
commenterName = comment.user.username,
|
||||
commenterName = comment.user,
|
||||
score = comment.score,
|
||||
isUnread = commentNode.isUnread,
|
||||
createdAt = comment.createdAt,
|
||||
updatedAt = comment.updatedAt,
|
||||
),
|
||||
avatarUrl = "https://lobste.rs/${comment.user.avatarUrl}",
|
||||
contentDescription = "User avatar for ${comment.user.username}",
|
||||
modifier =
|
||||
Modifier.clickable { uriHandler.openUri("https://lobste.rs/u/${comment.user.username}") },
|
||||
avatarUrl = "https://lobste.rs/avatars/${comment.user}-100.png",
|
||||
contentDescription = "User avatar for ${comment.user}",
|
||||
modifier = Modifier.clickable { uriHandler.openUri("https://lobste.rs/u/${comment.user}") },
|
||||
)
|
||||
if (commentNode.isExpanded) {
|
||||
ThemedRichText(
|
||||
|
|
|
@ -53,7 +53,6 @@ import dev.msfjarvis.claw.common.ui.NetworkImage
|
|||
import dev.msfjarvis.claw.common.ui.preview.ThemePreviews
|
||||
import dev.msfjarvis.claw.model.LinkMetadata
|
||||
import dev.msfjarvis.claw.model.UIPost
|
||||
import dev.msfjarvis.claw.model.User
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
|
@ -122,9 +121,9 @@ fun PostDetails(post: UIPost, isRead: Boolean, modifier: Modifier = Modifier) {
|
|||
TagRow(tags = post.tags.toImmutableList())
|
||||
Spacer(Modifier.height(4.dp))
|
||||
Submitter(
|
||||
text = AnnotatedString("Submitted by ${post.submitter.username}"),
|
||||
avatarUrl = "https://lobste.rs/${post.submitter.avatarUrl}",
|
||||
contentDescription = "User avatar for ${post.submitter.username}",
|
||||
text = AnnotatedString("Submitted by ${post.submitter}"),
|
||||
avatarUrl = "https://lobste.rs/avatars/${post.submitter}-100.png",
|
||||
contentDescription = "User avatar for ${post.submitter}",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -249,7 +248,7 @@ private fun LobstersCardPreview() {
|
|||
createdAt = "2020-09-21T08:04:24.000-05:00",
|
||||
commentCount = 1,
|
||||
commentsUrl = "https://lobste.rs/s/q1hh1g/simple_anomaly_detection_using_plain_sql",
|
||||
submitter = User("Haki", "", "", "/avatars/Haki-100.png", ""),
|
||||
submitter = "Haki",
|
||||
tags = listOf("databases", "apis"),
|
||||
description = "",
|
||||
isSaved = true,
|
||||
|
@ -275,7 +274,7 @@ private fun LobstersCardPreview() {
|
|||
commentsUrl = "https://lobste.rs/s/q1hh1g/simple_anomaly_detection_using_plain_sql",
|
||||
tags = listOf("databases", "apis"),
|
||||
description = "",
|
||||
submitter = User("Haki", "", "", "", ""),
|
||||
submitter = "Haki",
|
||||
comments = emptyList(),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2023 Harsh Shandilya.
|
||||
* Copyright © 2023-2024 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
|
@ -32,7 +32,6 @@ object SavedPostSerializer : KSerializer<SavedPost> {
|
|||
element<Int?>("commentCount", isOptional = true)
|
||||
element<String>("commentsUrl")
|
||||
element<String>("submitterName")
|
||||
element<String>("submitterAvatarUrl")
|
||||
element<List<String>>("tags")
|
||||
element<String>("description")
|
||||
}
|
||||
|
@ -46,7 +45,6 @@ object SavedPostSerializer : KSerializer<SavedPost> {
|
|||
var commentCount: Int? = null
|
||||
var commentsUrl = ""
|
||||
var submitterName = ""
|
||||
var submitterAvatarUrl = ""
|
||||
var tags = emptyList<String>()
|
||||
var description = ""
|
||||
while (true) {
|
||||
|
@ -58,9 +56,8 @@ object SavedPostSerializer : KSerializer<SavedPost> {
|
|||
4 -> commentCount = decodeNullableSerializableElement(descriptor, 4, Int.serializer())
|
||||
5 -> commentsUrl = decodeStringElement(descriptor, 5)
|
||||
6 -> submitterName = decodeStringElement(descriptor, 6)
|
||||
7 -> submitterAvatarUrl = decodeStringElement(descriptor, 7)
|
||||
8 -> tags = decodeSerializableElement(descriptor, 8, delegateSerializer)
|
||||
9 -> description = decodeStringElement(descriptor, 9)
|
||||
7 -> tags = decodeSerializableElement(descriptor, 7, delegateSerializer)
|
||||
8 -> description = decodeStringElement(descriptor, 8)
|
||||
CompositeDecoder.DECODE_DONE -> break
|
||||
else -> error("Unexpected index: $index")
|
||||
}
|
||||
|
@ -73,7 +70,6 @@ object SavedPostSerializer : KSerializer<SavedPost> {
|
|||
commentCount = commentCount,
|
||||
commentsUrl = commentsUrl,
|
||||
submitterName = submitterName,
|
||||
submitterAvatarUrl = submitterAvatarUrl,
|
||||
tags = tags,
|
||||
description = description,
|
||||
)
|
||||
|
@ -89,9 +85,8 @@ object SavedPostSerializer : KSerializer<SavedPost> {
|
|||
encodeNullableSerializableElement(descriptor, 4, Int.serializer(), value.commentCount)
|
||||
encodeStringElement(descriptor, 5, value.commentsUrl)
|
||||
encodeStringElement(descriptor, 6, value.submitterName)
|
||||
encodeStringElement(descriptor, 7, value.submitterAvatarUrl)
|
||||
encodeSerializableElement(descriptor, 8, delegateSerializer, value.tags)
|
||||
encodeStringElement(descriptor, 9, value.description)
|
||||
encodeSerializableElement(descriptor, 7, delegateSerializer, value.tags)
|
||||
encodeStringElement(descriptor, 8, value.description)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ CREATE TABLE IF NOT EXISTS SavedPost(
|
|||
commentCount INTEGER AS Int,
|
||||
commentsUrl TEXT NOT NULL,
|
||||
submitterName TEXT NOT NULL,
|
||||
submitterAvatarUrl TEXT NOT NULL,
|
||||
tags TEXT AS List<String> NOT NULL,
|
||||
description TEXT NOT NULL DEFAULT ""
|
||||
);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
CREATE TABLE ReadPosts(
|
||||
CREATE TABLE IF NOT EXISTS ReadPosts(
|
||||
id TEXT NOT NULL PRIMARY KEY
|
||||
);
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
import kotlin.Int;
|
||||
import kotlin.String;
|
||||
import kotlin.collections.List;
|
||||
|
||||
ALTER TABLE SavedPost RENAME TO SavedPost_Old;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS SavedPost(
|
||||
shortId TEXT NOT NULL PRIMARY KEY,
|
||||
title TEXT NOT NULL,
|
||||
url TEXT NOT NULL,
|
||||
createdAt TEXT NOT NULL,
|
||||
commentCount INTEGER AS Int,
|
||||
commentsUrl TEXT NOT NULL,
|
||||
submitterName TEXT NOT NULL,
|
||||
tags TEXT AS List<String> NOT NULL,
|
||||
description TEXT NOT NULL DEFAULT ""
|
||||
);
|
||||
|
||||
INSERT INTO SavedPost(shortId, title, url, createdAt, commentCount, commentsUrl, submitterName, tags, description)
|
||||
SELECT shortId, title, url, createdAt, commentCount, commentsUrl, submitterName, tags, description
|
||||
FROM SavedPost_Old;
|
||||
|
||||
DROP TABLE SavedPost_Old;
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2023 Harsh Shandilya.
|
||||
* Copyright © 2023-2024 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
|
@ -52,7 +52,6 @@ class SavedPostSerializerTest {
|
|||
commentCount = 13,
|
||||
commentsUrl = "https://lobste.rs/s/nbigsf/fun_format_friday_you_now_have_super",
|
||||
submitterName = "LenFalken",
|
||||
submitterAvatarUrl = "/avatars/LenFalken-100.png",
|
||||
tags = listOf("ask", "programming"),
|
||||
description =
|
||||
"<p>You suddenly have in your possession a super computer. What comes next? What projects are suddenly possible for you? What performance tests can you now explore?</p>\n",
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"short_id":"nbigsf","title":"Fun Format Friday: You now have a super computer. What next?","url":"","created_at":"2023-05-04T23:43:50.000-05:00","comment_count":13,"comments_url":"https://lobste.rs/s/nbigsf/fun_format_friday_you_now_have_super","submitter_name":"LenFalken","submitter_avatar_url":"/avatars/LenFalken-100.png","tags":["ask","programming"],"description":"<p>You suddenly have in your possession a super computer. What comes next? What projects are suddenly possible for you? What performance tests can you now explore?</p>\n"}
|
||||
{"short_id":"nbigsf","title":"Fun Format Friday: You now have a super computer. What next?","url":"","created_at":"2023-05-04T23:43:50.000-05:00","comment_count":13,"comments_url":"https://lobste.rs/s/nbigsf/fun_format_friday_you_now_have_super","submitter_name":"LenFalken","tags":["ask","programming"],"description":"<p>You suddenly have in your possession a super computer. What comes next? What projects are suddenly possible for you? What performance tests can you now explore?</p>\n"}
|
|
@ -122,7 +122,6 @@ class SavedPostQueriesTest {
|
|||
commentCount = 0,
|
||||
commentsUrl = "test_comments_url",
|
||||
submitterName = "test_user_$i",
|
||||
submitterAvatarUrl = "test_avatar_url",
|
||||
tags = listOf(),
|
||||
description = "",
|
||||
)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2021-2023 Harsh Shandilya.
|
||||
* Copyright © 2021-2024 Harsh Shandilya.
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
* https://opensource.org/licenses/MIT.
|
||||
|
@ -24,5 +24,5 @@ class Comment(
|
|||
@Serializable(with = JavaInstantSerializer::class) val createdAt: TemporalAccessor,
|
||||
@Serializable(with = JavaInstantSerializer::class) val updatedAt: TemporalAccessor,
|
||||
val parentComment: String?,
|
||||
@SerialName("commenting_user") val user: User,
|
||||
@SerialName("commenting_user") val user: String,
|
||||
)
|
||||
|
|
|
@ -18,11 +18,7 @@ import kotlinx.serialization.Serializable
|
|||
@Poko
|
||||
@KonvertTo(
|
||||
value = UIPost::class,
|
||||
mappings =
|
||||
[
|
||||
Mapping(target = "submitterName", expression = "it.submitter.username"),
|
||||
Mapping(target = "submitterAvatarUrl", expression = "it.submitter.avatarUrl"),
|
||||
],
|
||||
mappings = [Mapping(target = "submitterName", expression = "it.submitter.username")],
|
||||
)
|
||||
class LobstersPost(
|
||||
val shortId: String,
|
||||
|
@ -32,6 +28,6 @@ class LobstersPost(
|
|||
val description: String,
|
||||
val commentCount: Int,
|
||||
val commentsUrl: String,
|
||||
@SerialName("submitter_user") val submitter: User,
|
||||
@SerialName("submitter_user") val submitter: String,
|
||||
val tags: List<String>,
|
||||
)
|
||||
|
|
|
@ -19,19 +19,11 @@ import kotlinx.serialization.Serializable
|
|||
@Poko
|
||||
@KonvertTo(
|
||||
value = UIPost::class,
|
||||
mappings =
|
||||
[
|
||||
Mapping(target = "submitterName", expression = "it.submitter.username"),
|
||||
Mapping(target = "submitterAvatarUrl", expression = "it.submitter.avatarUrl"),
|
||||
],
|
||||
mappings = [Mapping(target = "submitterName", expression = "it.submitter")],
|
||||
)
|
||||
@KonvertTo(
|
||||
value = SavedPost::class,
|
||||
mappings =
|
||||
[
|
||||
Mapping(target = "submitterName", expression = "it.submitter.username"),
|
||||
Mapping(target = "submitterAvatarUrl", expression = "it.submitter.avatarUrl"),
|
||||
],
|
||||
mappings = [Mapping(target = "submitterName", expression = "it.submitter")],
|
||||
)
|
||||
class LobstersPostDetails(
|
||||
val shortId: String,
|
||||
|
@ -41,7 +33,7 @@ class LobstersPostDetails(
|
|||
val description: String,
|
||||
val commentCount: Int,
|
||||
val commentsUrl: String,
|
||||
@SerialName("submitter_user") val submitter: User,
|
||||
@SerialName("submitter_user") val submitter: String,
|
||||
val tags: List<String>,
|
||||
val comments: List<Comment>,
|
||||
)
|
||||
|
|
|
@ -14,11 +14,7 @@ import kotlinx.serialization.SerialName
|
|||
|
||||
@KonvertTo(
|
||||
value = SavedPost::class,
|
||||
mappings =
|
||||
[
|
||||
Mapping(target = "submitterName", expression = "it.submitter.username"),
|
||||
Mapping(target = "submitterAvatarUrl", expression = "it.submitter.avatarUrl"),
|
||||
],
|
||||
mappings = [Mapping(target = "submitterName", expression = "it.submitter")],
|
||||
)
|
||||
data class UIPost(
|
||||
val shortId: String,
|
||||
|
@ -28,7 +24,7 @@ data class UIPost(
|
|||
val description: String,
|
||||
val commentCount: Int,
|
||||
val commentsUrl: String,
|
||||
@SerialName("submitter_user") val submitter: User,
|
||||
@SerialName("submitter_user") val submitter: String,
|
||||
val tags: List<String>,
|
||||
val comments: List<Comment> = emptyList(),
|
||||
val isSaved: Boolean = false,
|
||||
|
@ -38,10 +34,7 @@ data class UIPost(
|
|||
value = SavedPost::class,
|
||||
mappings =
|
||||
[
|
||||
Mapping(
|
||||
target = "submitter",
|
||||
expression = "User(it.submitterName, \"\", null, it.submitterAvatarUrl, \"\")",
|
||||
),
|
||||
Mapping(target = "submitter", expression = "it.submitterName"),
|
||||
Mapping(target = "commentCount", expression = "it.commentCount ?: 0"),
|
||||
Mapping(target = "isSaved", expression = "true"),
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue