From 85fc5cac21a78aa42cc80447bdea479f5f57de41 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Sat, 16 Mar 2024 09:48:08 +0530 Subject: [PATCH] fix: adjust for new API changes --- CHANGELOG.md | 4 ++++ .../claw/api/converters/SearchConverter.kt | 22 +----------------- .../kotlin/dev/msfjarvis/claw/api/ApiTest.kt | 2 +- .../dev/msfjarvis/claw/api/SearchApiTest.kt | 5 ++-- api/src/test/resources/hottest.json | 2 +- api/src/test/resources/msfjarvis.json | 2 +- .../test/resources/post_details_tdfoqh.json | 2 +- .../claw/common/comments/CommentEntry.kt | 19 +++++++-------- .../claw/common/posts/LobstersCard.kt | 11 ++++----- .../claw/database/SavedPostSerializer.kt | 15 ++++-------- .../claw/database/local/SavedPost.sq | 1 - .../core/src/main/sqldelight/migrations/5.sqm | 2 +- .../core/src/main/sqldelight/migrations/6.sqm | 23 +++++++++++++++++++ .../claw/database/SavedPostSerializerTest.kt | 3 +-- .../core/src/test/resources/saved_post.json | 2 +- .../database/local/SavedPostQueriesTest.kt | 1 - .../dev/msfjarvis/claw/model/Comment.kt | 4 ++-- .../dev/msfjarvis/claw/model/LobstersPost.kt | 8 ++----- .../claw/model/LobstersPostDetails.kt | 14 +++-------- .../kotlin/dev/msfjarvis/claw/model/UIPost.kt | 13 +++-------- 20 files changed, 65 insertions(+), 90 deletions(-) create mode 100644 database/core/src/main/sqldelight/migrations/6.sqm diff --git a/CHANGELOG.md b/CHANGELOG.md index 042424f1..0adab1f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/api/src/main/kotlin/dev/msfjarvis/claw/api/converters/SearchConverter.kt b/api/src/main/kotlin/dev/msfjarvis/claw/api/converters/SearchConverter.kt index 2a606254..000bf235 100644 --- a/api/src/main/kotlin/dev/msfjarvis/claw/api/converters/SearchConverter.kt +++ b/api/src/main/kotlin/dev/msfjarvis/claw/api/converters/SearchConverter.kt @@ -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> { 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> { 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, diff --git a/api/src/test/kotlin/dev/msfjarvis/claw/api/ApiTest.kt b/api/src/test/kotlin/dev/msfjarvis/claw/api/ApiTest.kt index ca653a41..0a360973 100644 --- a/api/src/test/kotlin/dev/msfjarvis/claw/api/ApiTest.kt +++ b/api/src/test/kotlin/dev/msfjarvis/claw/api/ApiTest.kt @@ -33,7 +33,7 @@ class ApiTest { val posts = api.getHottestPosts(1) assertIs>>(posts) val commentsOnlyPosts = posts.value.asSequence().filter { it.url.isEmpty() }.toSet() - assertThat(commentsOnlyPosts).hasSize(2) + assertThat(commentsOnlyPosts).hasSize(1) } @Test diff --git a/api/src/test/kotlin/dev/msfjarvis/claw/api/SearchApiTest.kt b/api/src/test/kotlin/dev/msfjarvis/claw/api/SearchApiTest.kt index 5b5dc8af..73382c96 100644 --- a/api/src/test/kotlin/dev/msfjarvis/claw/api/SearchApiTest.kt +++ b/api/src/test/kotlin/dev/msfjarvis/claw/api/SearchApiTest.kt @@ -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 = "", ), diff --git a/api/src/test/resources/hottest.json b/api/src/test/resources/hottest.json index 4e3f86a6..78cdb38a 100644 --- a/api/src/test/resources/hottest.json +++ b/api/src/test/resources/hottest.json @@ -1 +1 @@ -[{"short_id":"q1hh1g","short_id_url":"https://lobste.rs/s/q1hh1g","created_at":"2020-09-21T08:04:24.000-05:00","title":"Simple Anomaly Detection Using Plain SQL","url":"https://hakibenita.com/sql-anomaly-detection","score":33,"flags":0,"comment_count":5,"description":"","comments_url":"https://lobste.rs/s/q1hh1g/simple_anomaly_detection_using_plain_sql","submitter_user":{"username":"Haki","created_at":"2019-01-04T01:25:42.000-06:00","is_admin":false,"about":"https://hakibenita.com","is_moderator":false,"karma":278,"avatar_url":"/avatars/Haki-100.png","invited_by_user":"pstef"},"tags":["databases"]},{"short_id":"gnd8bc","short_id_url":"https://lobste.rs/s/gnd8bc","created_at":"2020-09-21T11:56:04.000-05:00","title":"scalar: A small chat protocol, inspired by Gemini","url":"https://sr.ht/~icefox/scalar/","score":18,"flags":0,"comment_count":4,"description":"","comments_url":"https://lobste.rs/s/gnd8bc/scalar_small_chat_protocol_inspired_by","submitter_user":{"username":"icefox","created_at":"2018-08-26T20:59:16.000-05:00","is_admin":false,"about":"","is_moderator":false,"karma":2818,"avatar_url":"/avatars/icefox-100.png","invited_by_user":"shanemhansen"},"tags":["networking","release","show"]},{"short_id":"bssphv","short_id_url":"https://lobste.rs/s/bssphv","created_at":"2020-09-21T14:21:46.000-05:00","title":"My Least Favorite Rust Type","url":"https://ridiculousfish.com/blog/posts/least-favorite-rust-type.html","score":23,"flags":0,"comment_count":1,"description":"","comments_url":"https://lobste.rs/s/bssphv/my_least_favorite_rust_type","submitter_user":{"username":"liftM","created_at":"2017-11-18T04:29:06.000-06:00","is_admin":false,"about":"I work on programming languages and build systems.","is_moderator":false,"karma":161,"avatar_url":"/avatars/liftM-100.png","invited_by_user":"alok","github_username":"liftM","twitter_username":"liftm2"},"tags":["rust"]},{"short_id":"d8wxhi","short_id_url":"https://lobste.rs/s/d8wxhi","created_at":"2020-09-20T20:34:16.000-05:00","title":"On the use of a life","url":"http://www.daemonology.net/blog/2020-09-20-On-the-use-of-a-life.html","score":103,"flags":5,"comment_count":12,"description":"","comments_url":"https://lobste.rs/s/d8wxhi/on_use_life","submitter_user":{"username":"amontalenti","created_at":"2014-02-11T09:12:37.000-06:00","is_admin":false,"about":"Founder of [Parse.ly](http://parse.ly). Python, Clojure, JavaScript, \u0026 C. UNIX lover. Web hacker. Blogging at [amontalenti.com](https://amontalenti.com), tweeting at [@amontalenti](http://twitter.com/amontalenti).","is_moderator":false,"karma":930,"avatar_url":"/avatars/amontalenti-100.png","invited_by_user":"conroy"},"tags":["crypto","freebsd","person"]},{"short_id":"gxgoel","short_id_url":"https://lobste.rs/s/gxgoel","created_at":"2020-09-21T13:22:08.000-05:00","title":"Plan 9 rides again; WSL file access","url":"https://nelsonslog.wordpress.com/2019/02/16/plan-9-rides-again-wsl-file-access/","score":13,"flags":0,"comment_count":1,"description":"","comments_url":"https://lobste.rs/s/gxgoel/plan_9_rides_again_wsl_file_access","submitter_user":{"username":"awreece","created_at":"2016-01-15T00:04:45.000-06:00","is_admin":false,"about":"My hobbies are systems performance, computer security, and weird bugs. http://codearcana.com/","is_moderator":false,"karma":286,"avatar_url":"/avatars/awreece-100.png","invited_by_user":"peter"},"tags":["linux","osdev","windows"]},{"short_id":"hvr16d","short_id_url":"https://lobste.rs/s/hvr16d","created_at":"2020-09-21T05:17:04.000-05:00","title":"What are you doing this week?","url":"","score":16,"flags":0,"comment_count":20,"description":"\u003cp\u003eWhat are you doing this week? Feel free to share!\u003c/p\u003e\n\u003cp\u003eKeep in mind it’s OK to do nothing at all, too.\u003c/p\u003e\n","comments_url":"https://lobste.rs/s/hvr16d/what_are_you_doing_this_week","submitter_user":{"username":"caius","created_at":"2014-05-13T06:58:30.000-05:00","is_admin":false,"about":"Compulsive Geek, Ale Connoisseur, Head of Engineering at [SafeguardingMonitor](https://safeguardingmonitor.co.uk), Occasionally Responsible Adult.","is_moderator":false,"karma":5077,"avatar_url":"/avatars/caius-100.png","invited_by_user":"lauris","github_username":"caius","twitter_username":"Caius"},"tags":["ask","programming"]},{"short_id":"jgcvev","short_id_url":"https://lobste.rs/s/jgcvev","created_at":"2020-09-20T15:25:25.000-05:00","title":"Why Not Rust?","url":"https://matklad.github.io//2020/09/20/why-not-rust.html","score":60,"flags":0,"comment_count":25,"description":"","comments_url":"https://lobste.rs/s/jgcvev/why_not_rust","submitter_user":{"username":"notriddle","created_at":"2018-08-30T09:08:52.000-05:00","is_admin":false,"about":"https://notriddle.com/","is_moderator":false,"karma":2864,"avatar_url":"/avatars/notriddle-100.png","invited_by_user":"zimbatm","github_username":"notriddle"},"tags":["rust"]},{"short_id":"xhrskw","short_id_url":"https://lobste.rs/s/xhrskw","created_at":"2020-09-21T05:42:07.000-05:00","title":"Is it possible to hide all \"What are you doing this XXX\" threads?","url":"","score":33,"flags":0,"comment_count":21,"description":"\u003cp\u003eI’m annoyed by all these “What are you doing this XXX” threads.\nIs it possible to automatically hide them?\u003c/p\u003e\n\u003cp\u003eThey are usually tagged with “ask” and “programming”.\nSo hiding all “ask” and “programming” threads in my settings\nprobably would do the trick,\nbut then I’d also miss the interesting questions…\u003c/p\u003e\n","comments_url":"https://lobste.rs/s/xhrskw/is_it_possible_hide_all_what_are_you_doing","submitter_user":{"username":"hwj","created_at":"2019-05-30T00:12:36.000-05:00","is_admin":false,"about":"computer science student","is_moderator":false,"karma":763,"avatar_url":"/avatars/hwj-100.png","invited_by_user":"nickpsecurity"},"tags":["meta"]},{"short_id":"xuvwrb","short_id_url":"https://lobste.rs/s/xuvwrb","created_at":"2020-09-21T10:22:37.000-05:00","title":"The unrealized potential of federation","url":"https://drewdevault.com/2020/09/20/The-potential-of-federation.html","score":7,"flags":1,"comment_count":1,"description":"","comments_url":"https://lobste.rs/s/xuvwrb/unrealized_potential_federation","submitter_user":{"username":"zge","created_at":"2017-11-19T11:49:35.000-06:00","is_admin":false,"about":"CS student and hobby developer.","is_moderator":false,"karma":9038,"avatar_url":"/avatars/zge-100.png","invited_by_user":"josuah","github_username":"phikal"},"tags":["networking"]},{"short_id":"9t1ves","short_id_url":"https://lobste.rs/s/9t1ves","created_at":"2020-09-21T06:53:28.000-05:00","title":"Creating a Home IPv6 Network","url":"https://blog.hansenpartnership.com/creating-a-home-ipv6-network/","score":14,"flags":0,"comment_count":1,"description":"","comments_url":"https://lobste.rs/s/9t1ves/creating_home_ipv6_network","submitter_user":{"username":"freddyb","created_at":"2017-02-02T09:12:16.000-06:00","is_admin":false,"about":"Security. Mostly in Browsers, but not exclusively.","is_moderator":false,"karma":3873,"avatar_url":"/avatars/freddyb-100.png","invited_by_user":"stas","keybase_signatures":[{"kb_username":"freddyb","sig_hash":"550e2f5b27d4b5d558c02dfb2b23a628e90635183c93f993eeea4e16b20c51150f"}]},"tags":["linux","networking"]},{"short_id":"8m7ydc","short_id_url":"https://lobste.rs/s/8m7ydc","created_at":"2020-09-21T11:18:06.000-05:00","title":"dstask: Single binary terminal-based TODO manager with git-based sync + markdown notes per task","url":"https://github.com/naggie/dstask","score":5,"flags":0,"comment_count":4,"description":"\u003cp\u003eShowcasing on behalf of the author\u003c/p\u003e\n","comments_url":"https://lobste.rs/s/8m7ydc/dstask_single_binary_terminal_based_todo","submitter_user":{"username":"JordiGH","created_at":"2014-11-24T16:21:05.000-06:00","is_admin":false,"about":"Jordi Gutiérrez Hermoso. \r\n\r\nGNU Octave dev, Mercurial enthusiast.\r\n\r\nCoder, mathematician, hacker-errant.\r\n\r\nYou may contact me at jordigh@octave.org","is_moderator":false,"karma":6718,"avatar_url":"/avatars/JordiGH-100.png","invited_by_user":"technomancy"},"tags":["go","show"]},{"short_id":"lzaycw","short_id_url":"https://lobste.rs/s/lzaycw","created_at":"2020-09-21T13:01:05.000-05:00","title":"Maybe don’t write off Scala just yet","url":"https://levelup.gitconnected.com/maybe-dont-write-off-scala-just-yet-f0c128a570f0","score":5,"flags":0,"comment_count":1,"description":"","comments_url":"https://lobste.rs/s/lzaycw/maybe_don_t_write_off_scala_just_yet","submitter_user":{"username":"asteroid","created_at":"2020-01-29T13:58:14.000-06:00","is_admin":false,"about":"Writer. Editor. Computer geek. Chocoholic. Baseball fan. Not always in that order.","is_moderator":false,"karma":333,"avatar_url":"/avatars/asteroid-100.png","invited_by_user":"petdance","twitter_username":"estherschindler"},"tags":["scala"]},{"short_id":"uqiz1y","short_id_url":"https://lobste.rs/s/uqiz1y","created_at":"2020-09-21T16:37:37.000-05:00","title":"Croquet Project Demo (2003)","url":"https://www.youtube.com/watch?v=cXGLOiZUZ2U","score":3,"flags":0,"comment_count":0,"description":"","comments_url":"https://lobste.rs/s/uqiz1y/croquet_project_demo_2003","submitter_user":{"username":"sevan","created_at":"2013-06-02T17:42:02.000-05:00","is_admin":false,"about":"","is_moderator":false,"karma":6732,"avatar_url":"/avatars/sevan-100.png","invited_by_user":"jturner","github_username":"sevan"},"tags":["graphics","video"]},{"short_id":"9tdnvp","short_id_url":"https://lobste.rs/s/9tdnvp","created_at":"2020-09-20T12:40:46.000-05:00","title":"uMatrix development has ended","url":"https://www.ghacks.net/2020/09/20/umatrix-development-has-ended/","score":38,"flags":1,"comment_count":13,"description":"","comments_url":"https://lobste.rs/s/9tdnvp/umatrix_development_has_ended","submitter_user":{"username":"skrzyp","created_at":"2016-05-21T16:41:57.000-05:00","is_admin":false,"about":"````\r\n````","is_moderator":false,"karma":867,"avatar_url":"/avatars/skrzyp-100.png","invited_by_user":"mulander"},"tags":["browsers","privacy","web"]},{"short_id":"mi4tlk","short_id_url":"https://lobste.rs/s/mi4tlk","created_at":"2020-09-21T08:28:38.000-05:00","title":"Deep Learning in Clojure with Fewer Parentheses than Keras and Python","url":"https://dragan.rocks/articles/20/Deep-Diamond-Deep-Learning-in-Clojure-Fewer-Parentheses-Python-Keras","score":4,"flags":0,"comment_count":0,"description":"","comments_url":"https://lobste.rs/s/mi4tlk/deep_learning_clojure_with_fewer","submitter_user":{"username":"dragandj","created_at":"2016-05-12T13:12:22.000-05:00","is_admin":false,"about":"","is_moderator":false,"karma":154,"avatar_url":"/avatars/dragandj-100.png","invited_by_user":"mindcrime"},"tags":["ai","clojure","java","python"]},{"short_id":"ztsooj","short_id_url":"https://lobste.rs/s/ztsooj","created_at":"2020-09-21T06:39:34.000-05:00","title":"14nm and 7nm are NOT what you think it is","url":"https://www.youtube.com/watch?v=1kQUXpZpLXI","score":7,"flags":0,"comment_count":2,"description":"","comments_url":"https://lobste.rs/s/ztsooj/14nm_7nm_are_not_what_you_think_it_is","submitter_user":{"username":"asymptotically","created_at":"2019-08-11T09:22:13.000-05:00","is_admin":false,"about":"","is_moderator":false,"karma":558,"avatar_url":"/avatars/asymptotically-100.png","invited_by_user":"gerikson"},"tags":["hardware","video"]},{"short_id":"wgfc92","short_id_url":"https://lobste.rs/s/wgfc92","created_at":"2020-09-21T13:43:50.000-05:00","title":"EDN parser and generator for TS/JS working with plain data and stream support","url":"https://github.com/jorinvo/edn-data","score":1,"flags":0,"comment_count":0,"description":"","comments_url":"https://lobste.rs/s/wgfc92/edn_parser_generator_for_ts_js_working","submitter_user":{"username":"jorin","created_at":"2020-07-06T11:34:49.000-05:00","is_admin":false,"about":"✨ decentralize all the things ✨ #clojure is just data 🖤 \r\n🌱 plant trees 🌳\r\n→ experimenting with feedback systems 🤖\r\nFind me at https://mas.to/@jorin","is_moderator":false,"karma":52,"avatar_url":"/avatars/jorin-100.png","invited_by_user":"jussi","github_username":"jorinvo","twitter_username":"jorinvo"},"tags":["clojure","javascript","nodejs","release"]},{"short_id":"bhttyk","short_id_url":"https://lobste.rs/s/bhttyk","created_at":"2020-09-20T11:28:13.000-05:00","title":"organice (Org mode for mobile devices and the browser) renders clickable links automatically","url":"https://200ok.ch/posts/2020-09-20_organice_renders_clickable_links_automatically.html","score":20,"flags":0,"comment_count":7,"description":"","comments_url":"https://lobste.rs/s/bhttyk/organice_org_mode_for_mobile_devices","submitter_user":{"username":"munen","created_at":"2019-09-23T02:27:28.000-05:00","is_admin":false,"about":"CEO 200ok.ch, Lecturer at ZHAW. Ordained Zen Buddhist monk and caretaker of the Lambda Zen Temple (http://zen-temple.net).","is_moderator":false,"karma":296,"avatar_url":"/avatars/munen-100.png","invited_by_user":"bandali","github_username":"munen"},"tags":["emacs"]},{"short_id":"lfslfx","short_id_url":"https://lobste.rs/s/lfslfx","created_at":"2020-09-21T04:28:22.000-05:00","title":"Demystifying AWS VPC","url":"https://scorpil.com/post/aws-vpc/","score":8,"flags":0,"comment_count":0,"description":"\u003cp\u003eThis is posted on behalf of \u003ca href=\"https://lobste.rs/u/scorpil\" rel=\"ugc\"\u003e@scorpil\u003c/a\u003e, who can’t post their own stuff yet. I found it relevant to this community (but as I’m their inviter I might be biased)\u003c/p\u003e\n","comments_url":"https://lobste.rs/s/lfslfx/demystifying_aws_vpc","submitter_user":{"username":"gerikson","created_at":"2017-01-13T03:16:10.000-06:00","is_admin":false,"about":"Swede, father and husband. \r\n\r\nhttp://gerikson.com/blog/\r\n\r\n### Invitation policy\r\n\r\nNote that this is my personal policy. If I don't extend an invite, it doesn't mean no-one else will. Be polite, be open, and be patient.\r\n\r\nFirst step, please reach out to the community in [chat](https://lobste.rs/chat) and let us know why you want to be a part of the community. \r\n\r\nI will typically request some form of proof that your username is associated with a public profile on a social network (and yes, I count GitHub as a social network). If you do not wish to share such information in the general chat, I will not consider extending an invite. \r\n\r\nI will probably not extend an invite if your online behavior exhibits sexism, misogyny, racism or homophobia. \r\n\r\nI will politely ignore unsolicitated requests for invites via Twitter DM or email.","is_moderator":false,"karma":7097,"avatar_url":"/avatars/gerikson-100.png","invited_by_user":"varjag","github_username":"gustafe","twitter_username":"gerikson"},"tags":["distributed","networking"]},{"short_id":"ote3wb","short_id_url":"https://lobste.rs/s/ote3wb","created_at":"2020-09-21T03:17:38.000-05:00","title":"D Tetris running on Webassembly","url":"http://dpldocs.info/this-week-in-d/Blog.Posted_2020_08_10.html","score":8,"flags":0,"comment_count":1,"description":"","comments_url":"https://lobste.rs/s/ote3wb/d_tetris_running_on_webassembly","submitter_user":{"username":"speps","created_at":"2017-09-06T02:15:19.000-05:00","is_admin":false,"about":"Senior Software Engineer at Rare Ltd (Microsoft Studios UK). All opinions are my own and do not reflect my employer's.","is_moderator":false,"karma":233,"avatar_url":"/avatars/speps-100.png","invited_by_user":"mikejsavage"},"tags":["d","wasm"]},{"short_id":"vkm0ad","short_id_url":"https://lobste.rs/s/vkm0ad","created_at":"2020-09-21T07:59:49.000-05:00","title":"k2k20 hackathon report: Klemens Nanni on network land decluttering","url":"http://undeadly.org/cgi?action=article;sid=20200921110059","score":5,"flags":0,"comment_count":0,"description":"","comments_url":"https://lobste.rs/s/vkm0ad/k2k20_hackathon_report_klemens_nanni_on","submitter_user":{"username":"calvin","created_at":"2014-07-01T06:47:13.000-05:00","is_admin":false,"about":"Soon we will all have special names... names designed to make the cathode ray tube resonate.","is_moderator":false,"karma":66870,"avatar_url":"/avatars/calvin-100.png","invited_by_user":"nbyouri","github_username":"NattyNarwhal"},"tags":["openbsd"]},{"short_id":"liy030","short_id_url":"https://lobste.rs/s/liy030","created_at":"2020-09-21T14:21:28.000-05:00","title":"Local memoized recursive functions","url":"https://quanttype.net/posts/2020-09-20-local-memoized-recursive-functions.html","score":2,"flags":0,"comment_count":0,"description":"","comments_url":"https://lobste.rs/s/liy030/local_memoized_recursive_functions","submitter_user":{"username":"jussi","created_at":"2016-06-07T11:38:09.000-05:00","is_admin":false,"about":"Programmer at Metosin\r\n\r\nClojure/Python/Javascript/Rust/Ruby/DuckDuckGo.\r\n\r\n","is_moderator":false,"karma":407,"avatar_url":"/avatars/jussi-100.png","invited_by_user":"flyingfisch","github_username":"jrasanen","twitter_username":"jussiras"},"tags":["clojure","programming"]},{"short_id":"lcb5us","short_id_url":"https://lobste.rs/s/lcb5us","created_at":"2020-09-21T08:56:55.000-05:00","title":"Analyzing Python Code with Python","url":"https://rotemtam.com/2020/08/13/python-ast/","score":4,"flags":0,"comment_count":0,"description":"","comments_url":"https://lobste.rs/s/lcb5us/analyzing_python_code_with_python","submitter_user":{"username":"learnbyexample","created_at":"2020-06-15T09:51:10.000-05:00","is_admin":false,"about":"Sundeep Agarwal is a freelance trainer, [author](https://learnbyexample.github.io/books/) and mentor. You can find his works, primarily focused on Linux command line, text processing, scripting languages and curated lists, at [https://github.com/learnbyexample](https://github.com/learnbyexample).","is_moderator":false,"karma":347,"avatar_url":"/avatars/learnbyexample-100.png","invited_by_user":"ngoldbaum"},"tags":["python","testing"]},{"short_id":"rmlqmn","short_id_url":"https://lobste.rs/s/rmlqmn","created_at":"2020-09-21T13:19:01.000-05:00","title":"Data art posters about music (streaming) data for Sony Music","url":"https://www.visualcinnamon.com/2020/06/sony-music-data-art","score":2,"flags":1,"comment_count":0,"description":"","comments_url":"https://lobste.rs/s/rmlqmn/data_art_posters_about_music_streaming","submitter_user":{"username":"danburzo","created_at":"2018-10-02T10:53:45.000-05:00","is_admin":false,"about":"Building things for the web. Learning in public. Co-founder of [Moqups](https://moqups.com). Find me [on Mastodon](https://mastodon.social/@danburzo).","is_moderator":false,"karma":1159,"avatar_url":"/avatars/danburzo-100.png","invited_by_user":"migurski","github_username":"danburzo","twitter_username":"danburzo"},"tags":["design","visualization"]},{"short_id":"zqyydb","short_id_url":"https://lobste.rs/s/zqyydb","created_at":"2020-09-21T07:11:14.000-05:00","title":"k2k20 hackathon report: Bob Beck on LibreSSL progress","url":"https://undeadly.org/cgi?action=article;sid=20200921105847","score":4,"flags":0,"comment_count":0,"description":"","comments_url":"https://lobste.rs/s/zqyydb/k2k20_hackathon_report_bob_beck_on","submitter_user":{"username":"Vigdis","created_at":"2017-02-27T21:08:14.000-06:00","is_admin":false,"about":"Alleycat for the fun, sys/net admin for a living and OpenBSD contributions for the pleasure. (Not so) French dude in Montreal\r\n\r\nhttps://chown.me","is_moderator":false,"karma":76,"avatar_url":"/avatars/Vigdis-100.png","invited_by_user":"sevan"},"tags":["openbsd"]}] \ No newline at end of file +[{"short_id":"lfg3lj","short_id_url":"https://lobste.rs/s/lfg3lj","created_at":"2024-03-15T16:06:08.000-05:00","title":"Zig, Rust, and other languages","url":"https://notes.eatonphil.com/2024-03-15-zig-rust-and-other-languages.html","score":22,"flags":0,"comment_count":14,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/lfg3lj/zig_rust_other_languages","submitter_user":"eatonphil","user_is_author":true,"tags":["rust","zig"]},{"short_id":"46dgy1","short_id_url":"https://lobste.rs/s/46dgy1","created_at":"2024-03-15T10:51:28.000-05:00","title":"npm install everything, and the complete and utter chaos that follows","url":"https://boehs.org/node/npm-everything","score":27,"flags":0,"comment_count":16,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/46dgy1/npm_install_everything_complete_utter","submitter_user":"calvin","user_is_author":false,"tags":["nodejs"]},{"short_id":"ngdrbc","short_id_url":"https://lobste.rs/s/ngdrbc","created_at":"2024-03-15T08:26:50.000-05:00","title":"The Montreal Problem: Why Programming Languages Need a Style Czar","url":"https://earthly.dev/blog/language-style-czar/","score":18,"flags":0,"comment_count":16,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/ngdrbc/montreal_problem_why_programming","submitter_user":"adamgordonbell","user_is_author":true,"tags":["plt"]},{"short_id":"gwsilq","short_id_url":"https://lobste.rs/s/gwsilq","created_at":"2024-03-15T05:53:31.000-05:00","title":"IAM Is The Worst","url":"https://matduggan.com/iam-is-the-worst/","score":48,"flags":0,"comment_count":13,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/gwsilq/iam_is_worst","submitter_user":"maduggan","user_is_author":true,"tags":["devops","rant"]},{"short_id":"spozr1","short_id_url":"https://lobste.rs/s/spozr1","created_at":"2024-03-15T14:01:49.000-05:00","title":"µON - a compact and simple binary object notation","url":"https://github.com/vshymanskyy/muon/","score":15,"flags":0,"comment_count":1,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/spozr1/on_compact_simple_binary_object_notation","submitter_user":"Wryl","user_is_author":false,"tags":["programming"]},{"short_id":"pbqail","short_id_url":"https://lobste.rs/s/pbqail","created_at":"2024-03-15T14:10:46.000-05:00","title":"Bringing Verse Transactional Memory Semantics to C++","url":"https://www.unrealengine.com/en-US/tech-blog/bringing-verse-transactional-memory-semantics-to-c","score":10,"flags":0,"comment_count":2,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/pbqail/bringing_verse_transactional_memory","submitter_user":"mikejsavage","user_is_author":false,"tags":["c++","compilers"]},{"short_id":"j7c4rw","short_id_url":"https://lobste.rs/s/j7c4rw","created_at":"2024-03-15T21:45:03.000-05:00","title":"Nix is a better Docker image builder than Docker's image builder","url":"https://xeiaso.net/talks/2024/nix-docker-build/","score":5,"flags":0,"comment_count":0,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/j7c4rw/nix_is_better_docker_image_builder_than","submitter_user":"jfb","user_is_author":false,"tags":["devops","nix"]},{"short_id":"kpi2xx","short_id_url":"https://lobste.rs/s/kpi2xx","created_at":"2024-03-14T23:44:47.000-05:00","title":"What’s the most interesting automation you have created?","url":"","score":28,"flags":1,"comment_count":31,"description":"\u003cp\u003eWould love to hear about the most interesting automation you have created either at work or personal automation.\u003c/p\u003e\n\u003cp\u003eAlso what language did you use?\u003c/p\u003e\n","description_plain":"Would love to hear about the most interesting automation you have created either at work or personal automation.\r\n\r\nAlso what language did you use?","comments_url":"https://lobste.rs/s/kpi2xx/what_s_most_interesting_automation_you","submitter_user":"mraza007","user_is_author":true,"tags":["ask","programming"]},{"short_id":"mlek1h","short_id_url":"https://lobste.rs/s/mlek1h","created_at":"2024-03-15T06:26:22.000-05:00","title":"Onboarding roulette: deleting our employee accounts daily","url":"https://graphite.dev/blog/onboarding-roulette","score":15,"flags":0,"comment_count":5,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/mlek1h/onboarding_roulette_deleting_our","submitter_user":"knl","user_is_author":false,"tags":["practices"]},{"short_id":"dlpl1r","short_id_url":"https://lobste.rs/s/dlpl1r","created_at":"2024-03-14T13:20:28.000-05:00","title":"Today we launched Flox 1.0","url":"https://tinkering.xyz/releasing-flox/","score":43,"flags":1,"comment_count":9,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/dlpl1r/today_we_launched_flox_1_0","submitter_user":"zmitchell","user_is_author":true,"tags":["devops","nix","release"]},{"short_id":"qd7sq1","short_id_url":"https://lobste.rs/s/qd7sq1","created_at":"2024-03-15T05:06:26.000-05:00","title":"GG, a GUI for Jujutsu","url":"https://github.com/gulbanana/gg","score":22,"flags":0,"comment_count":3,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/qd7sq1/gg_gui_for_jujutsu","submitter_user":"eterps","user_is_author":false,"tags":["vcs"]},{"short_id":"6brpob","short_id_url":"https://lobste.rs/s/6brpob","created_at":"2024-03-15T14:51:42.000-05:00","title":"The t-digest: Efficient estimates of quantiles","url":"https://www.sciencedirect.com/science/article/pii/S2665963820300403","score":4,"flags":0,"comment_count":3,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/6brpob/t_digest_efficient_estimates_quantiles","submitter_user":"itamarst","user_is_author":false,"tags":["compsci"]},{"short_id":"dgmp4p","short_id_url":"https://lobste.rs/s/dgmp4p","created_at":"2024-03-15T19:24:22.000-05:00","title":"Making a Compiler to Prove tmux Is Turing Complete","url":"https://willhbr.net/2024/03/15/making-a-compiler-to-prove-tmux-is-turing-complete/","score":4,"flags":0,"comment_count":0,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/dgmp4p/making_compiler_prove_tmux_is_turing","submitter_user":"algernon","user_is_author":false,"tags":["programming"]},{"short_id":"bdl64p","short_id_url":"https://lobste.rs/s/bdl64p","created_at":"2024-03-15T02:11:09.000-05:00","title":"Diffing patches for visual programming language MaxMSP","url":"https://github.com/Ableton/maxdevtools/tree/main/maxdiff","score":11,"flags":0,"comment_count":3,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/bdl64p/diffing_patches_for_visual_programming","submitter_user":"thev","user_is_author":true,"tags":["programming","vcs"]},{"short_id":"t9shpe","short_id_url":"https://lobste.rs/s/t9shpe","created_at":"2024-03-15T10:21:07.000-05:00","title":"How to approach a reduce problem","url":"https://thoughtbot.com/blog/how-to-approach-a-reduce-problem","score":8,"flags":0,"comment_count":2,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/t9shpe/how_approach_reduce_problem","submitter_user":"MatheusRich","user_is_author":false,"tags":["ruby"]},{"short_id":"3h6mpx","short_id_url":"https://lobste.rs/s/3h6mpx","created_at":"2024-03-15T13:09:43.000-05:00","title":"Experiences with Thread Programming in Microsoft Windows","url":"https://www.johndcook.com/blog/2024/03/15/experiences-with-thread-programming-in-microsoft-windows/","score":6,"flags":0,"comment_count":0,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/3h6mpx/experiences_with_thread_programming","submitter_user":"hwayne","user_is_author":false,"tags":["performance","windows"]},{"short_id":"qr7lbq","short_id_url":"https://lobste.rs/s/qr7lbq","created_at":"2024-03-14T18:09:50.000-05:00","title":"Oh no, I started a Magit-like plugin for the Lem editor","url":"https://lisp-journey.gitlab.io/blog/oh-no-i-started-a-magit-like-plugin-for-the-lem-editor/","score":24,"flags":0,"comment_count":1,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/qr7lbq/oh_no_i_started_magit_like_plugin_for_lem","submitter_user":"vindarel","user_is_author":true,"tags":["emacs","lisp","vcs"]},{"short_id":"dpkose","short_id_url":"https://lobste.rs/s/dpkose","created_at":"2024-03-15T01:07:17.000-05:00","title":"Compressing Chess Moves for Fun and Profit","url":"https://mbuffett.com/posts/compressing-chess-moves/","score":10,"flags":0,"comment_count":8,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/dpkose/compressing_chess_moves_for_fun_profit","submitter_user":"calvin","user_is_author":false,"tags":["programming"]},{"short_id":"hhfs13","short_id_url":"https://lobste.rs/s/hhfs13","created_at":"2024-03-14T22:41:23.000-05:00","title":"Bellroy Technology Team: 2023 in Review","url":"https://exploring-better-ways.bellroy.com/bellroy-technology-team-2023-in-review.html","score":11,"flags":0,"comment_count":1,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/hhfs13/bellroy_technology_team_2023_review","submitter_user":"michaelwebb76","user_is_author":true,"tags":["haskell","nix","practices","scaling","web"]},{"short_id":"mkaigy","short_id_url":"https://lobste.rs/s/mkaigy","created_at":"2024-03-14T13:22:51.000-05:00","title":"SoloVer is a simple and expressive versioning specification","url":"https://beza1e1.tuxen.de/SoloVer","score":18,"flags":0,"comment_count":29,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/mkaigy/solover_is_simple_expressive_versioning","submitter_user":"qznc","user_is_author":true,"tags":["api","practices"]},{"short_id":"mqq4v9","short_id_url":"https://lobste.rs/s/mqq4v9","created_at":"2024-03-15T10:30:23.000-05:00","title":"Haiku Activity \u0026 Contract Report, February 2024","url":"https://www.haiku-os.org/blog/waddlesplash/2024-03-14_haiku_activity_contract_report_february_2024","score":6,"flags":0,"comment_count":0,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/mqq4v9/haiku_activity_contract_report_february","submitter_user":"rjzak","user_is_author":false,"tags":["osdev"]},{"short_id":"w4xnbg","short_id_url":"https://lobste.rs/s/w4xnbg","created_at":"2024-03-14T23:49:33.000-05:00","title":"Optimizing Matrix Multiplication with Zig","url":"https://svaniksharma.github.io/posts/2023-05-07-optimizing-matrix-multiplication-with-zig/","score":20,"flags":0,"comment_count":3,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/w4xnbg/optimizing_matrix_multiplication_with","submitter_user":"benjaminmaccini","user_is_author":false,"tags":["zig"]},{"short_id":"yx1vis","short_id_url":"https://lobste.rs/s/yx1vis","created_at":"2024-03-15T16:55:37.000-05:00","title":"Tokamak: A web framework for Zig","url":"https://tomsik.cz/posts/tokamak/","score":2,"flags":0,"comment_count":0,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/yx1vis/tokamak_web_framework_for_zig","submitter_user":"friendlysock","user_is_author":false,"tags":["web","zig"]},{"short_id":"bumvly","short_id_url":"https://lobste.rs/s/bumvly","created_at":"2024-03-15T03:56:28.000-05:00","title":"How to write your own custom terraform provider","url":"https://medium.com/@ledevedeccorentin/how-to-write-your-own-custom-terraform-provider-f1c27fa5d75e","score":4,"flags":0,"comment_count":1,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/bumvly/how_write_your_own_custom_terraform","submitter_user":"Strygwyr","user_is_author":true,"tags":["devops","go"]},{"short_id":"fmilri","short_id_url":"https://lobste.rs/s/fmilri","created_at":"2024-03-14T16:47:24.000-05:00","title":"Дія (Ukrainian government app) source code released under EUPL","url":"https://github.com/diia-open-source/","score":26,"flags":1,"comment_count":2,"description":"","description_plain":"","comments_url":"https://lobste.rs/s/fmilri/ukrainian_government_app_source_code","submitter_user":"two","user_is_author":false,"tags":["law","release"]}] \ No newline at end of file diff --git a/api/src/test/resources/msfjarvis.json b/api/src/test/resources/msfjarvis.json index c60ffb3d..c0ff986e 100644 --- a/api/src/test/resources/msfjarvis.json +++ b/api/src/test/resources/msfjarvis.json @@ -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"} \ No newline at end of file +{"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"} \ No newline at end of file diff --git a/api/src/test/resources/post_details_tdfoqh.json b/api/src/test/resources/post_details_tdfoqh.json index 5c11a1ea..8529d57f 100644 --- a/api/src/test/resources/post_details_tdfoqh.json +++ b/api/src/test/resources/post_details_tdfoqh.json @@ -1 +1 @@ -{"short_id":"tdfoqh","short_id_url":"https://lobste.rs/s/tdfoqh","created_at":"2022-07-22T12:06:59.000-05:00","title":"Ranking comments by sum of replies' scores","url":"","score":18,"flags":0,"comment_count":10,"description":"\u003cp\u003eThere are often cases where comments with a poor score (say, 1 point), invite high-quality replies that receive many upvotes.\u003c/p\u003e\n\u003cp\u003eThese threads are not shown at the top of the story’s comments page because their “root comment” has a low score.\u003c/p\u003e\n\u003cp\u003eAn example, as of 2022-07-22 17:00 UTC, is \u003ca href=\"https://lobste.rs/s/ekvqcf/random_wallpaper_with_just_bash_systemd#c_vop9bt\" rel=\"ugc\"\u003ehttps://lobste.rs/s/ekvqcf/random_wallpaper_with_just_bash_systemd#c_vop9bt\u003c/a\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ethe root comment has 1 point,\u003c/li\u003e\n\u003cli\u003ethe first reply has 12 points,\u003c/li\u003e\n\u003cli\u003eand, in total, 18 points have been accumulated by all the replies with score \u0026gt; 1 point.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eBecause the root comment has only 1 point, it remains at the bottom of the page, bringing down with itself also the good comment with 12 points and all the other upvoted comments.\u003c/p\u003e\n\u003cp\u003eCould an alternative ranking system be put in place, where the threads and subthreads are not sorted by the score of their root comment, but by the \u003cem\u003esum of all the scores of their children\u003c/em\u003e?\u003c/p\u003e\n\u003cp\u003e(Maybe taking into account only children with \u003ccode\u003e\u0026gt;1\u003c/code\u003e point, to avoid giving importance to superficial back-and-forth discussions.)\u003c/p\u003e\n","description_plain":"There are often cases where comments with a poor score (say, 1 point), invite high-quality replies that receive many upvotes.\r\n\r\nThese threads are not shown at the top of the story's comments page because their \"root comment\" has a low score.\r\n\r\nAn example, as of 2022-07-22 17:00 UTC, is \u003chttps://lobste.rs/s/ekvqcf/random_wallpaper_with_just_bash_systemd#c_vop9bt\u003e:\r\n* the root comment has 1 point,\r\n* the first reply has 12 points,\r\n* and, in total, 18 points have been accumulated by all the replies with score \u003e 1 point.\r\n\r\nBecause the root comment has only 1 point, it remains at the bottom of the page, bringing down with itself also the good comment with 12 points and all the other upvoted comments.\r\n\r\nCould an alternative ranking system be put in place, where the threads and subthreads are not sorted by the score of their root comment, but by the _sum of all the scores of their children_?\r\n\r\n(Maybe taking into account only children with `\u003e1` point, to avoid giving importance to superficial back-and-forth discussions.)","comments_url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores","submitter_user":{"username":"gioele","created_at":"2018-04-25T11:31:25.000-05:00","is_admin":false,"about":"https://gioele.io","is_moderator":false,"karma":737,"avatar_url":"/avatars/gioele-100.png","invited_by_user":"pushcx"},"tags":["meta"],"comments":[{"short_id":"ncdsfc","short_id_url":"https://lobste.rs/c/ncdsfc","created_at":"2022-07-22T14:04:36.000-05:00","updated_at":"2022-07-22T14:04:36.000-05:00","is_deleted":false,"is_moderated":false,"score":17,"flags":0,"parent_comment":null,"comment":"\u003cblockquote\u003e\n\u003cp\u003eto avoid giving importance to superficial back-and-forth discussions\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eMaybe take the max, instead of the sum? That way it’s still comparing the score of individual comments. A highly-upvoted child would rank higher than a less-upvoted toplevel comment, but long threads wouldn’t get any bonus.\u003c/p\u003e\n","comment_plain":"\u003e to avoid giving importance to superficial back-and-forth discussions\r\n\r\nMaybe take the max, instead of the sum? That way it's still comparing the score of individual comments. A highly-upvoted child would rank higher than a less-upvoted toplevel comment, but long threads wouldn't get any bonus.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_ncdsfc","indent_level":null,"commenting_user":{"username":"dpercy","created_at":"2019-09-06T11:52:32.000-05:00","is_admin":false,"about":"","is_moderator":false,"karma":459,"avatar_url":"/avatars/dpercy-100.png","invited_by_user":"glowe","github_username":"dpercy"}},{"short_id":"m3wyu5","short_id_url":"https://lobste.rs/c/m3wyu5","created_at":"2022-07-23T01:04:43.000-05:00","updated_at":"2022-07-23T01:04:43.000-05:00","is_deleted":false,"is_moderated":false,"score":8,"flags":0,"parent_comment":null,"comment":"\u003cp\u003eFor better or worse, the deeper you go into threads the less likely it is that the discussion is still about the original submission. Your proposal, or the max variant presented elsewhere, I fear would unduly reward flamebait and off-topic discussion.\u003c/p\u003e\n","comment_plain":"For better or worse, the deeper you go into threads the less likely it is that the discussion is still about the original submission. Your proposal, or the max variant presented elsewhere, I fear would unduly reward flamebait and off-topic discussion.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_m3wyu5","indent_level":null,"commenting_user":{"username":"friendlysock","created_at":"2014-02-20T00:43:41.000-06:00","is_admin":false,"about":"*Literally* full of ants.\r\n\r\nFriendly engineer and human being.\r\n\r\nStrong opinions held weakly, sometimes weekly.\r\n\r\n\u003e Gentrification is the process by which nebulous threats are pacified and alchemised into money. \r\n","is_moderator":false,"karma":40606,"avatar_url":"/avatars/friendlysock-100.png","invited_by_user":"MasonJar"}},{"short_id":"pcvbcd","short_id_url":"https://lobste.rs/c/pcvbcd","created_at":"2022-07-23T09:52:52.000-05:00","updated_at":"2022-07-23T10:09:15.000-05:00","is_deleted":false,"is_moderated":false,"score":2,"flags":0,"parent_comment":"m3wyu5","comment":"\u003cblockquote\u003e\n\u003cp\u003eYour proposal, or the max variant presented elsewhere, I fear would unduly reward flamebait and off-topic discussion.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eSuch off-topic discussions that stray away from the main topic do exist, are a nuisance, and, surely, they should not be rewarded with more attention. However, such sub-threads exists as a long string of short comments with no or very few upvotes. (I wonder if the data confirms this or it is just my impression.)\u003c/p\u003e\n\u003cp\u003eFor this reason I believe that a) not counting in comments with score==1 or b) \u003ca href=\"https://lobste.rs/u/dpercy\" rel=\"ugc\"\u003e@dpercy\u003c/a\u003e’s max variant would avoid rewarding such discussions.\u003c/p\u003e\n","comment_plain":"\u003e Your proposal, or the max variant presented elsewhere, I fear would unduly reward flamebait and off-topic discussion.\r\n\r\nSuch off-topic discussions that stray away from the main topic do exist, are a nuisance, and, surely, they should not be rewarded with more attention. However, such sub-threads exists as a long string of short comments with no or very few upvotes. (I wonder if the data confirms this or it is just my impression.)\r\n\r\nFor this reason I believe that a) not counting in comments with score==1 or b) @dpercy's max variant would avoid rewarding such discussions.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_pcvbcd","indent_level":null,"commenting_user":{"username":"gioele","created_at":"2018-04-25T11:31:25.000-05:00","is_admin":false,"about":"https://gioele.io","is_moderator":false,"karma":737,"avatar_url":"/avatars/gioele-100.png","invited_by_user":"pushcx"}},{"short_id":"9vyyu5","short_id_url":"https://lobste.rs/c/9vyyu5","created_at":"2022-07-22T13:39:20.000-05:00","updated_at":"2022-07-22T13:39:20.000-05:00","is_deleted":false,"is_moderated":false,"score":5,"flags":0,"parent_comment":null,"comment":"\u003cp\u003eJust like to point out that the assumption here is that upvotes is a metric of quality. On lobste.rs as in any other social context, upvotes/support is a measure of popularity.\u003c/p\u003e\n\u003cp\u003eThere are many instances where the two are correlated, and some important instances where they are not.\u003c/p\u003e\n","comment_plain":"Just like to point out that the assumption here is that upvotes is a metric of quality. On lobste.rs as in any other social context, upvotes/support is a measure of popularity.\r\n\r\nThere are many instances where the two are correlated, and some important instances where they are not.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_9vyyu5","indent_level":null,"commenting_user":{"username":"kghose","created_at":"2014-09-03T12:48:11.000-05:00","is_admin":false,"about":"Electrical Engineer, Software writer, fascinated by mathematics, visualizations and the human brain, currently a novice bioinformatician. [Long form articles and coding diary](http://kaushikghose.wordpress.com)\r\n","is_moderator":false,"karma":3988,"avatar_url":"/avatars/kghose-100.png","invited_by_user":"hdevalence"}},{"short_id":"owddle","short_id_url":"https://lobste.rs/c/owddle","created_at":"2022-07-22T13:57:19.000-05:00","updated_at":"2022-07-22T13:57:19.000-05:00","is_deleted":false,"is_moderated":false,"score":7,"flags":0,"parent_comment":"9vyyu5","comment":"\u003cblockquote\u003e\n\u003cp\u003eJust like to point out that the assumption here is that upvotes is a metric of quality. On lobste.rs as in any other social context, upvotes/support is a measure of popularity.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eI fully agree: upvotes are a metric of popularity and not of quality. But this proposal does not assume that.\u003c/p\u003e\n\u003cp\u003eRegardless of what upvotes represent, currently threads are sorted in descending order of (upvotes, time). All that this proposal suggests, is to change that to (sum(upvotes of root-and-children), time).\u003c/p\u003e\n\u003cp\u003eThe only assumption here is: if ranking a thread by upvotes of its root comment is considered good (and at the moment it is), then ranking by the sum of the upvotes of the whole thread is better.\u003c/p\u003e\n","comment_plain":"\u003e Just like to point out that the assumption here is that upvotes is a metric of quality. On lobste.rs as in any other social context, upvotes/support is a measure of popularity.\r\n\r\nI fully agree: upvotes are a metric of popularity and not of quality. But this proposal does not assume that.\r\n\r\nRegardless of what upvotes represent, currently threads are sorted in descending order of (upvotes, time). All that this proposal suggests, is to change that to (sum(upvotes of root-and-children), time).\r\n\r\nThe only assumption here is: if ranking a thread by upvotes of its root comment is considered good (and at the moment it is), then ranking by the sum of the upvotes of the whole thread is better.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_owddle","indent_level":null,"commenting_user":{"username":"gioele","created_at":"2018-04-25T11:31:25.000-05:00","is_admin":false,"about":"https://gioele.io","is_moderator":false,"karma":737,"avatar_url":"/avatars/gioele-100.png","invited_by_user":"pushcx"}},{"short_id":"lqqn3a","short_id_url":"https://lobste.rs/c/lqqn3a","created_at":"2022-07-22T14:28:14.000-05:00","updated_at":"2022-07-22T14:28:27.000-05:00","is_deleted":false,"is_moderated":false,"score":2,"flags":0,"parent_comment":"owddle","comment":"\u003cp\u003eTangential to your effort here, on a personal note, if I find a discussion interesting I read all the posts regardless of ranking. On the discussions I find worthwhile I find that post quality is unrelated to upvotes.\u003c/p\u003e\n\u003cp\u003eOn some discussions I find the top voted comment has devolved into a long tail of niche discussion, often acrimonious, which is not as useful as later posts.\u003c/p\u003e\n\u003cp\u003eWorst to pick out of the noise are replies to replies which are great but buried in not so great comments.\u003c/p\u003e\n","comment_plain":"Tangential to your effort here, on a personal note, if I find a discussion interesting I read all the posts regardless of ranking. On the discussions I find worthwhile I find that post quality is unrelated to upvotes.\r\n\r\nOn some discussions I find the top voted comment has devolved into a long tail of niche discussion, often acrimonious, which is not as useful as later posts.\r\n\r\nWorst to pick out of the noise are replies to replies which are great but buried in not so great comments.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_lqqn3a","indent_level":null,"commenting_user":{"username":"kghose","created_at":"2014-09-03T12:48:11.000-05:00","is_admin":false,"about":"Electrical Engineer, Software writer, fascinated by mathematics, visualizations and the human brain, currently a novice bioinformatician. [Long form articles and coding diary](http://kaushikghose.wordpress.com)\r\n","is_moderator":false,"karma":3988,"avatar_url":"/avatars/kghose-100.png","invited_by_user":"hdevalence"}},{"short_id":"7b0jgw","short_id_url":"https://lobste.rs/c/7b0jgw","created_at":"2022-07-23T11:25:10.000-05:00","updated_at":"2022-07-23T11:26:03.000-05:00","is_deleted":false,"is_moderated":false,"score":4,"flags":0,"parent_comment":null,"comment":"\u003cp\u003eRanking by max or sum upvotes optimizes for photogenic smackdowns of bad opinions.\u003c/p\u003e\n\u003cp\u003eMaybe disaggregate “agreement upvotes” and “contribution upvotes”?\u003c/p\u003e\n","comment_plain":"Ranking by max or sum upvotes optimizes for photogenic smackdowns of bad opinions.\r\n\r\nMaybe disaggregate \"agreement upvotes\" and \"contribution upvotes\"?","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_7b0jgw","indent_level":null,"commenting_user":{"username":"FeepingCreature","created_at":"2021-02-24T01:40:27.000-06:00","is_admin":false,"about":"","is_moderator":false,"karma":1172,"avatar_url":"/avatars/FeepingCreature-100.png","invited_by_user":"rsaarelm"}},{"short_id":"ei3nck","short_id_url":"https://lobste.rs/c/ei3nck","created_at":"2022-07-23T10:43:21.000-05:00","updated_at":"2022-07-23T10:48:49.000-05:00","is_deleted":false,"is_moderated":false,"score":2,"flags":0,"parent_comment":null,"comment":"\u003cp\u003eI feel kind of honored to be taken as an example, so please let me share my personal thoughts (TL;DR below):\u003c/p\u003e\n\u003cp\u003eIt is impossible to find \u003cem\u003ethe\u003c/em\u003e definite ranking system, but let me elaborate by using 3 extremes to see where the current and proposed systems fail:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cem\u003ehighly controversial root comment\u003c/em\u003e with score 0 (100 upvotes, 100 downvotes), logically controversial responses with median 0,\u003c/li\u003e\n\u003cli\u003e\n\u003cem\u003eroot comment preaching to the choir\u003c/em\u003e with logically high score and usually high-score responses,\u003c/li\u003e\n\u003cli\u003e\n\u003cem\u003elow-score root comment with high-score responses\u003c/em\u003e (like the presented case)\u003c/li\u003e\n\u003cli\u003e\n\u003cem\u003eOC high-value root comment\u003c/em\u003e with high score and high-value responses\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eIt all depends on personal preference though, but I personally would like more controversial topics to be on top and less controversial ones to be secondary. The reason for that is that you otherwise might end up with echo-chambers, given users are encouraged to preach to the choir for a high karma score. As a tangent, I would prefer two karmas for each user: A “paragon-karma” and “renegade-karma” whose sum would be an “influence” score (in the end up- or downvotes both reflect a certain influence) and whose difference would be a “non-controversiality-score” (a low difference reflects controversiality, a high score the opposite). All in all, maybe we should move away complete from the miriad of downvote-options on lobsters and simply have an “agree” and “disagree”. If something is spam, you can report it, if something is incorrect, you can write a response rectifying it (which would then be subject to a vote of agreement and disagreement, depending on how well you state your case).\u003c/p\u003e\n\u003cp\u003eThe proposal to add replies into the weight would not change the ranking of controversial topics (1), but even moreso weigh comments preaching to the choir (2) because everyone replying would aim to also get some karma. It would solve the presented case (3) though. Case (4) would also be favoured.\u003c/p\u003e\n\u003cp\u003eThe proposal by \u003ca href=\"https://lobste.rs/u/dpercy\" rel=\"ugc\"\u003e@dpercy\u003c/a\u003e to the take the max would not change (1)’s ranking, probably not affect (2) but help (3) as well. (4) is also positively affected.\u003c/p\u003e\n\u003cp\u003eTL;DR, here’s my proposal so more highly-controversial topics (those that are interesting) are more favoured: Consider root comment and replies as equals and only take \u003cem\u003einfluence\u003c/em\u003e (sum of up- and downvotes) as a score.\u003c/p\u003e\n\u003cp\u003eThis benefits (1), which in the current form end up at the bottom, which makes zero sense. It also benefits (2) and (4), which is a forced compromise, given the score does not really show how “original” a comment is (this is why Reddit probably introduced awards to allow users to weigh very good posts). By taking all replies into account, it also, of course, benefits (3), which makes sense to push up.\u003c/p\u003e\n\u003cp\u003eReplies with no votes increase the influence of the thread by 1, indeed, but isn’t the purpose of the score to show what the hivemind thinks? By scoring them as zero (which was proposed here), you effectively value an elaborated response lower than a simple upvote of the original comment. Instead, why not simply “fold” long subthreads so they don’t take up too much space?\u003c/p\u003e\n\u003cp\u003eAs another tangent: By weighing root and children, this might encourage people to respond to “deep” threads instead of writing a new post.\u003c/p\u003e\n\u003cp\u003eLet’s see what \u003ca href=\"https://lobste.rs/u/pushcx\" rel=\"ugc\"\u003e@pushcx\u003c/a\u003e decides in the end. :)\u003c/p\u003e\n","comment_plain":"I feel kind of honored to be taken as an example, so please let me share my personal thoughts (TL;DR below):\r\n\r\nIt is impossible to find _the_ definite ranking system, but let me elaborate by using 3 extremes to see where the current and proposed systems fail:\r\n\r\n1. *highly controversial root comment* with score 0 (100 upvotes, 100 downvotes), logically controversial responses with median 0,\r\n2. *root comment preaching to the choir* with logically high score and usually high-score responses,\r\n3. *low-score root comment with high-score responses* (like the presented case)\r\n4. *OC high-value root comment* with high score and high-value responses\r\n\r\nIt all depends on personal preference though, but I personally would like more controversial topics to be on top and less controversial ones to be secondary. The reason for that is that you otherwise might end up with echo-chambers, given users are encouraged to preach to the choir for a high karma score. As a tangent, I would prefer two karmas for each user: A \"paragon-karma\" and \"renegade-karma\" whose sum would be an \"influence\" score (in the end up- or downvotes both reflect a certain influence) and whose difference would be a \"non-controversiality-score\" (a low difference reflects controversiality, a high score the opposite). All in all, maybe we should move away complete from the miriad of downvote-options on lobsters and simply have an \"agree\" and \"disagree\". If something is spam, you can report it, if something is incorrect, you can write a response rectifying it (which would then be subject to a vote of agreement and disagreement, depending on how well you state your case).\r\n\r\nThe proposal to add replies into the weight would not change the ranking of controversial topics (1), but even moreso weigh comments preaching to the choir (2) because everyone replying would aim to also get some karma. It would solve the presented case (3) though. Case (4) would also be favoured.\r\n\r\nThe proposal by @dpercy to the take the max would not change (1)'s ranking, probably not affect (2) but help (3) as well. (4) is also positively affected.\r\n\r\nTL;DR, here's my proposal so more highly-controversial topics (those that are interesting) are more favoured: Consider root comment and replies as equals and only take *influence* (sum of up- and downvotes) as a score.\r\n\r\nThis benefits (1), which in the current form end up at the bottom, which makes zero sense. It also benefits (2) and (4), which is a forced compromise, given the score does not really show how \"original\" a comment is (this is why Reddit probably introduced awards to allow users to weigh very good posts). By taking all replies into account, it also, of course, benefits (3), which makes sense to push up.\r\n\r\nReplies with no votes increase the influence of the thread by 1, indeed, but isn't the purpose of the score to show what the hivemind thinks? By scoring them as zero (which was proposed here), you effectively value an elaborated response lower than a simple upvote of the original comment. Instead, why not simply \"fold\" long subthreads so they don't take up too much space?\r\n\r\nAs another tangent: By weighing root and children, this might encourage people to respond to \"deep\" threads instead of writing a new post.\r\n\r\nLet's see what @pushcx decides in the end. :)","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_ei3nck","indent_level":null,"commenting_user":{"username":"FRIGN","created_at":"2015-02-19T10:11:05.000-06:00","is_admin":false,"about":"dev@frign.de\r\n\r\nsuckless developer, UNIX enthusiast\r\n\r\n|| https://frign.de ||\r\n\r\n(https://2f30.org https://suckless.org)","is_moderator":false,"karma":3732,"avatar_url":"/avatars/FRIGN-100.png","invited_by_user":"sin"}},{"short_id":"4l8mzk","short_id_url":"https://lobste.rs/c/4l8mzk","created_at":"2022-07-22T12:30:20.000-05:00","updated_at":"2022-07-22T12:30:20.000-05:00","is_deleted":false,"is_moderated":false,"score":2,"flags":0,"parent_comment":null,"comment":"\u003cp\u003eI really like this idea but have no idea what its implementation would represent in terms of additional load to the server.\u003c/p\u003e\n","comment_plain":"I really like this idea but have no idea what its implementation would represent in terms of additional load to the server.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_4l8mzk","indent_level":null,"commenting_user":{"username":"feoh","created_at":"2016-01-11T11:27:16.000-06:00","is_admin":false,"about":"Automation Junkie, Geek, Freemason. I wave my freak flag high :)","is_moderator":false,"karma":8264,"avatar_url":"/avatars/feoh-100.png","invited_by_user":"derekprior","github_username":"feoh","twitter_username":"feoh","keybase_signatures":[{"kb_username":"feoh","sig_hash":"b3a82d7fb3adf54a619afefce9f2543ab857626b34915bfb52b19eca48604c750f"}]}},{"short_id":"qy0l9k","short_id_url":"https://lobste.rs/c/qy0l9k","created_at":"2022-07-22T16:12:09.000-05:00","updated_at":"2022-07-22T16:12:09.000-05:00","is_deleted":false,"is_moderated":false,"score":5,"flags":0,"parent_comment":"4l8mzk","comment":"\u003cp\u003eI’ve moved most of the \u003ca href=\"https://github.com/lobsters/lobsters/blob/cf52ab9f3f0b3ac805effc2e718f15922cb67332/app/models/comment.rb#L340\" rel=\"ugc\"\u003evote\u003c/a\u003e into the db, but \u003ca href=\"https://github.com/lobsters/lobsters/blob/cf52ab9f3f0b3ac805effc2e718f15922cb67332/app/models/comment.rb#L219\" rel=\"ugc\"\u003enot all\u003c/a\u003e. If \u003ccode\u003ecalculated_confidence\u003c/code\u003e finished its move into the db almost any algorithm would be faster than the current implementation.\u003c/p\u003e\n","comment_plain":"I've moved most of the [vote](https://github.com/lobsters/lobsters/blob/cf52ab9f3f0b3ac805effc2e718f15922cb67332/app/models/comment.rb#L340) into the db, but [not all](https://github.com/lobsters/lobsters/blob/cf52ab9f3f0b3ac805effc2e718f15922cb67332/app/models/comment.rb#L219). If `calculated_confidence` finished its move into the db almost any algorithm would be faster than the current implementation.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_qy0l9k","indent_level":null,"commenting_user":{"username":"pushcx","created_at":"2012-08-14T20:25:08.000-05:00","is_admin":true,"about":"Hi, I'm [Peter Bhat Harkins](https://malaprop.org), a programmer and entrepreneur from Chicago. From June 2014 to winter of 2015 I typically posted a dozen stories per day to [help](https://lobste.rs/s/9pm09z/what_is_on_topic_what_is_not/comments/nie0yn#c_nie0yn) the site reach a critical mass of regular visitors. In October 2017 I became the site administrator after the site creator @jcs stepped down.\r\n\r\n * Please don’t message me for an invitation if we're complete strangers; check \u003ca href=\"https://lobste.rs/u\"\u003ethe user list\u003c/a\u003e for someone you know or ask [in chat](https://lobste.rs/chat).\r\n * Submit a [`meta`](https://lobste.rs/t/meta) post for feature requests (including new tags) to let the community discuss. Bug reports and \"is this a bug?\" should go to [the issue tracker](https://github.com/lobsters/lobsters/issues).\r\n * [Message me](https://lobste.rs/messages?to=pushcx) for administrative and moderator things. I don't see everything and I gotta sleep sometime.\r\n * E-mail my first name @malaprop.org regarding site security or if you can't log in to message me. If I've posted or commented about something here or in the chat room, I'd almost certainly love to talk more about it.\r\n","is_moderator":true,"avatar_url":"/avatars/pushcx-100.png","invited_by_user":"jcs","github_username":"pushcx","twitter_username":"pushcx","keybase_signatures":[{"kb_username":"pushcx","sig_hash":"de6fb28b501c211e88fabddeacc834c6b922d738efd6b4108ce871879d039e510f"}]}}]} \ No newline at end of file +{"short_id":"tdfoqh","short_id_url":"https://lobste.rs/s/tdfoqh","created_at":"2022-07-22T12:06:59.000-05:00","title":"Ranking comments by sum of replies' scores","url":"","score":18,"flags":0,"comment_count":10,"description":"\u003cp\u003eThere are often cases where comments with a poor score (say, 1 point), invite high-quality replies that receive many upvotes.\u003c/p\u003e\n\u003cp\u003eThese threads are not shown at the top of the story’s comments page because their “root comment” has a low score.\u003c/p\u003e\n\u003cp\u003eAn example, as of 2022-07-22 17:00 UTC, is \u003ca href=\"https://lobste.rs/s/ekvqcf/random_wallpaper_with_just_bash_systemd#c_vop9bt\" rel=\"ugc\"\u003ehttps://lobste.rs/s/ekvqcf/random_wallpaper_with_just_bash_systemd#c_vop9bt\u003c/a\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ethe root comment has 1 point,\u003c/li\u003e\n\u003cli\u003ethe first reply has 12 points,\u003c/li\u003e\n\u003cli\u003eand, in total, 18 points have been accumulated by all the replies with score \u0026gt; 1 point.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eBecause the root comment has only 1 point, it remains at the bottom of the page, bringing down with itself also the good comment with 12 points and all the other upvoted comments.\u003c/p\u003e\n\u003cp\u003eCould an alternative ranking system be put in place, where the threads and subthreads are not sorted by the score of their root comment, but by the \u003cem\u003esum of all the scores of their children\u003c/em\u003e?\u003c/p\u003e\n\u003cp\u003e(Maybe taking into account only children with \u003ccode\u003e\u0026gt;1\u003c/code\u003e point, to avoid giving importance to superficial back-and-forth discussions.)\u003c/p\u003e\n","description_plain":"There are often cases where comments with a poor score (say, 1 point), invite high-quality replies that receive many upvotes.\r\n\r\nThese threads are not shown at the top of the story's comments page because their \"root comment\" has a low score.\r\n\r\nAn example, as of 2022-07-22 17:00 UTC, is \u003chttps://lobste.rs/s/ekvqcf/random_wallpaper_with_just_bash_systemd#c_vop9bt\u003e:\r\n* the root comment has 1 point,\r\n* the first reply has 12 points,\r\n* and, in total, 18 points have been accumulated by all the replies with score \u003e 1 point.\r\n\r\nBecause the root comment has only 1 point, it remains at the bottom of the page, bringing down with itself also the good comment with 12 points and all the other upvoted comments.\r\n\r\nCould an alternative ranking system be put in place, where the threads and subthreads are not sorted by the score of their root comment, but by the _sum of all the scores of their children_?\r\n\r\n(Maybe taking into account only children with `\u003e1` point, to avoid giving importance to superficial back-and-forth discussions.)","comments_url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores","submitter_user":"gioele","user_is_author":true,"tags":["meta"],"comments":[{"short_id":"ncdsfc","short_id_url":"https://lobste.rs/c/ncdsfc","created_at":"2022-07-22T14:04:36.000-05:00","updated_at":"2022-07-22T14:04:36.000-05:00","is_deleted":false,"is_moderated":false,"score":17,"flags":0,"parent_comment":null,"comment":"\u003cblockquote\u003e\n\u003cp\u003eto avoid giving importance to superficial back-and-forth discussions\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eMaybe take the max, instead of the sum? That way it’s still comparing the score of individual comments. A highly-upvoted child would rank higher than a less-upvoted toplevel comment, but long threads wouldn’t get any bonus.\u003c/p\u003e\n","comment_plain":"\u003e to avoid giving importance to superficial back-and-forth discussions\r\n\r\nMaybe take the max, instead of the sum? That way it's still comparing the score of individual comments. A highly-upvoted child would rank higher than a less-upvoted toplevel comment, but long threads wouldn't get any bonus.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_ncdsfc","depth":0,"commenting_user":"dpercy"},{"short_id":"m3wyu5","short_id_url":"https://lobste.rs/c/m3wyu5","created_at":"2022-07-23T01:04:43.000-05:00","updated_at":"2022-07-23T01:04:43.000-05:00","is_deleted":false,"is_moderated":false,"score":8,"flags":0,"parent_comment":null,"comment":"\u003cp\u003eFor better or worse, the deeper you go into threads the less likely it is that the discussion is still about the original submission. Your proposal, or the max variant presented elsewhere, I fear would unduly reward flamebait and off-topic discussion.\u003c/p\u003e\n","comment_plain":"For better or worse, the deeper you go into threads the less likely it is that the discussion is still about the original submission. Your proposal, or the max variant presented elsewhere, I fear would unduly reward flamebait and off-topic discussion.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_m3wyu5","depth":0,"commenting_user":"friendlysock"},{"short_id":"pcvbcd","short_id_url":"https://lobste.rs/c/pcvbcd","created_at":"2022-07-23T09:52:52.000-05:00","updated_at":"2022-07-23T10:09:15.000-05:00","is_deleted":false,"is_moderated":false,"score":2,"flags":0,"parent_comment":"m3wyu5","comment":"\u003cblockquote\u003e\n\u003cp\u003eYour proposal, or the max variant presented elsewhere, I fear would unduly reward flamebait and off-topic discussion.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eSuch off-topic discussions that stray away from the main topic do exist, are a nuisance, and, surely, they should not be rewarded with more attention. However, such sub-threads exists as a long string of short comments with no or very few upvotes. (I wonder if the data confirms this or it is just my impression.)\u003c/p\u003e\n\u003cp\u003eFor this reason I believe that a) not counting in comments with score==1 or b) \u003ca href=\"https://lobste.rs/u/dpercy\" rel=\"ugc\"\u003e@dpercy\u003c/a\u003e’s max variant would avoid rewarding such discussions.\u003c/p\u003e\n","comment_plain":"\u003e Your proposal, or the max variant presented elsewhere, I fear would unduly reward flamebait and off-topic discussion.\r\n\r\nSuch off-topic discussions that stray away from the main topic do exist, are a nuisance, and, surely, they should not be rewarded with more attention. However, such sub-threads exists as a long string of short comments with no or very few upvotes. (I wonder if the data confirms this or it is just my impression.)\r\n\r\nFor this reason I believe that a) not counting in comments with score==1 or b) @dpercy's max variant would avoid rewarding such discussions.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_pcvbcd","depth":1,"commenting_user":"gioele"},{"short_id":"9vyyu5","short_id_url":"https://lobste.rs/c/9vyyu5","created_at":"2022-07-22T13:39:20.000-05:00","updated_at":"2022-07-22T13:39:20.000-05:00","is_deleted":false,"is_moderated":false,"score":5,"flags":0,"parent_comment":null,"comment":"\u003cp\u003eJust like to point out that the assumption here is that upvotes is a metric of quality. On lobste.rs as in any other social context, upvotes/support is a measure of popularity.\u003c/p\u003e\n\u003cp\u003eThere are many instances where the two are correlated, and some important instances where they are not.\u003c/p\u003e\n","comment_plain":"Just like to point out that the assumption here is that upvotes is a metric of quality. On lobste.rs as in any other social context, upvotes/support is a measure of popularity.\r\n\r\nThere are many instances where the two are correlated, and some important instances where they are not.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_9vyyu5","depth":0,"commenting_user":"kghose"},{"short_id":"owddle","short_id_url":"https://lobste.rs/c/owddle","created_at":"2022-07-22T13:57:19.000-05:00","updated_at":"2022-07-22T13:57:19.000-05:00","is_deleted":false,"is_moderated":false,"score":7,"flags":0,"parent_comment":"9vyyu5","comment":"\u003cblockquote\u003e\n\u003cp\u003eJust like to point out that the assumption here is that upvotes is a metric of quality. On lobste.rs as in any other social context, upvotes/support is a measure of popularity.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eI fully agree: upvotes are a metric of popularity and not of quality. But this proposal does not assume that.\u003c/p\u003e\n\u003cp\u003eRegardless of what upvotes represent, currently threads are sorted in descending order of (upvotes, time). All that this proposal suggests, is to change that to (sum(upvotes of root-and-children), time).\u003c/p\u003e\n\u003cp\u003eThe only assumption here is: if ranking a thread by upvotes of its root comment is considered good (and at the moment it is), then ranking by the sum of the upvotes of the whole thread is better.\u003c/p\u003e\n","comment_plain":"\u003e Just like to point out that the assumption here is that upvotes is a metric of quality. On lobste.rs as in any other social context, upvotes/support is a measure of popularity.\r\n\r\nI fully agree: upvotes are a metric of popularity and not of quality. But this proposal does not assume that.\r\n\r\nRegardless of what upvotes represent, currently threads are sorted in descending order of (upvotes, time). All that this proposal suggests, is to change that to (sum(upvotes of root-and-children), time).\r\n\r\nThe only assumption here is: if ranking a thread by upvotes of its root comment is considered good (and at the moment it is), then ranking by the sum of the upvotes of the whole thread is better.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_owddle","depth":1,"commenting_user":"gioele"},{"short_id":"lqqn3a","short_id_url":"https://lobste.rs/c/lqqn3a","created_at":"2022-07-22T14:28:14.000-05:00","updated_at":"2022-07-22T14:28:27.000-05:00","is_deleted":false,"is_moderated":false,"score":2,"flags":0,"parent_comment":"owddle","comment":"\u003cp\u003eTangential to your effort here, on a personal note, if I find a discussion interesting I read all the posts regardless of ranking. On the discussions I find worthwhile I find that post quality is unrelated to upvotes.\u003c/p\u003e\n\u003cp\u003eOn some discussions I find the top voted comment has devolved into a long tail of niche discussion, often acrimonious, which is not as useful as later posts.\u003c/p\u003e\n\u003cp\u003eWorst to pick out of the noise are replies to replies which are great but buried in not so great comments.\u003c/p\u003e\n","comment_plain":"Tangential to your effort here, on a personal note, if I find a discussion interesting I read all the posts regardless of ranking. On the discussions I find worthwhile I find that post quality is unrelated to upvotes.\r\n\r\nOn some discussions I find the top voted comment has devolved into a long tail of niche discussion, often acrimonious, which is not as useful as later posts.\r\n\r\nWorst to pick out of the noise are replies to replies which are great but buried in not so great comments.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_lqqn3a","depth":2,"commenting_user":"kghose"},{"short_id":"7b0jgw","short_id_url":"https://lobste.rs/c/7b0jgw","created_at":"2022-07-23T11:25:10.000-05:00","updated_at":"2022-07-23T11:26:03.000-05:00","is_deleted":false,"is_moderated":false,"score":4,"flags":0,"parent_comment":null,"comment":"\u003cp\u003eRanking by max or sum upvotes optimizes for photogenic smackdowns of bad opinions.\u003c/p\u003e\n\u003cp\u003eMaybe disaggregate “agreement upvotes” and “contribution upvotes”?\u003c/p\u003e\n","comment_plain":"Ranking by max or sum upvotes optimizes for photogenic smackdowns of bad opinions.\r\n\r\nMaybe disaggregate \"agreement upvotes\" and \"contribution upvotes\"?","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_7b0jgw","depth":0,"commenting_user":"FeepingCreature"},{"short_id":"ei3nck","short_id_url":"https://lobste.rs/c/ei3nck","created_at":"2022-07-23T10:43:21.000-05:00","updated_at":"2022-07-23T10:48:49.000-05:00","is_deleted":false,"is_moderated":false,"score":2,"flags":0,"parent_comment":null,"comment":"\u003cp\u003eI feel kind of honored to be taken as an example, so please let me share my personal thoughts (TL;DR below):\u003c/p\u003e\n\u003cp\u003eIt is impossible to find \u003cem\u003ethe\u003c/em\u003e definite ranking system, but let me elaborate by using 3 extremes to see where the current and proposed systems fail:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cem\u003ehighly controversial root comment\u003c/em\u003e with score 0 (100 upvotes, 100 downvotes), logically controversial responses with median 0,\u003c/li\u003e\n\u003cli\u003e\n\u003cem\u003eroot comment preaching to the choir\u003c/em\u003e with logically high score and usually high-score responses,\u003c/li\u003e\n\u003cli\u003e\n\u003cem\u003elow-score root comment with high-score responses\u003c/em\u003e (like the presented case)\u003c/li\u003e\n\u003cli\u003e\n\u003cem\u003eOC high-value root comment\u003c/em\u003e with high score and high-value responses\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eIt all depends on personal preference though, but I personally would like more controversial topics to be on top and less controversial ones to be secondary. The reason for that is that you otherwise might end up with echo-chambers, given users are encouraged to preach to the choir for a high karma score. As a tangent, I would prefer two karmas for each user: A “paragon-karma” and “renegade-karma” whose sum would be an “influence” score (in the end up- or downvotes both reflect a certain influence) and whose difference would be a “non-controversiality-score” (a low difference reflects controversiality, a high score the opposite). All in all, maybe we should move away complete from the miriad of downvote-options on lobsters and simply have an “agree” and “disagree”. If something is spam, you can report it, if something is incorrect, you can write a response rectifying it (which would then be subject to a vote of agreement and disagreement, depending on how well you state your case).\u003c/p\u003e\n\u003cp\u003eThe proposal to add replies into the weight would not change the ranking of controversial topics (1), but even moreso weigh comments preaching to the choir (2) because everyone replying would aim to also get some karma. It would solve the presented case (3) though. Case (4) would also be favoured.\u003c/p\u003e\n\u003cp\u003eThe proposal by \u003ca href=\"https://lobste.rs/u/dpercy\" rel=\"ugc\"\u003e@dpercy\u003c/a\u003e to the take the max would not change (1)’s ranking, probably not affect (2) but help (3) as well. (4) is also positively affected.\u003c/p\u003e\n\u003cp\u003eTL;DR, here’s my proposal so more highly-controversial topics (those that are interesting) are more favoured: Consider root comment and replies as equals and only take \u003cem\u003einfluence\u003c/em\u003e (sum of up- and downvotes) as a score.\u003c/p\u003e\n\u003cp\u003eThis benefits (1), which in the current form end up at the bottom, which makes zero sense. It also benefits (2) and (4), which is a forced compromise, given the score does not really show how “original” a comment is (this is why Reddit probably introduced awards to allow users to weigh very good posts). By taking all replies into account, it also, of course, benefits (3), which makes sense to push up.\u003c/p\u003e\n\u003cp\u003eReplies with no votes increase the influence of the thread by 1, indeed, but isn’t the purpose of the score to show what the hivemind thinks? By scoring them as zero (which was proposed here), you effectively value an elaborated response lower than a simple upvote of the original comment. Instead, why not simply “fold” long subthreads so they don’t take up too much space?\u003c/p\u003e\n\u003cp\u003eAs another tangent: By weighing root and children, this might encourage people to respond to “deep” threads instead of writing a new post.\u003c/p\u003e\n\u003cp\u003eLet’s see what \u003ca href=\"https://lobste.rs/u/pushcx\" rel=\"ugc\"\u003e@pushcx\u003c/a\u003e decides in the end. :)\u003c/p\u003e\n","comment_plain":"I feel kind of honored to be taken as an example, so please let me share my personal thoughts (TL;DR below):\r\n\r\nIt is impossible to find _the_ definite ranking system, but let me elaborate by using 3 extremes to see where the current and proposed systems fail:\r\n\r\n1. *highly controversial root comment* with score 0 (100 upvotes, 100 downvotes), logically controversial responses with median 0,\r\n2. *root comment preaching to the choir* with logically high score and usually high-score responses,\r\n3. *low-score root comment with high-score responses* (like the presented case)\r\n4. *OC high-value root comment* with high score and high-value responses\r\n\r\nIt all depends on personal preference though, but I personally would like more controversial topics to be on top and less controversial ones to be secondary. The reason for that is that you otherwise might end up with echo-chambers, given users are encouraged to preach to the choir for a high karma score. As a tangent, I would prefer two karmas for each user: A \"paragon-karma\" and \"renegade-karma\" whose sum would be an \"influence\" score (in the end up- or downvotes both reflect a certain influence) and whose difference would be a \"non-controversiality-score\" (a low difference reflects controversiality, a high score the opposite). All in all, maybe we should move away complete from the miriad of downvote-options on lobsters and simply have an \"agree\" and \"disagree\". If something is spam, you can report it, if something is incorrect, you can write a response rectifying it (which would then be subject to a vote of agreement and disagreement, depending on how well you state your case).\r\n\r\nThe proposal to add replies into the weight would not change the ranking of controversial topics (1), but even moreso weigh comments preaching to the choir (2) because everyone replying would aim to also get some karma. It would solve the presented case (3) though. Case (4) would also be favoured.\r\n\r\nThe proposal by @dpercy to the take the max would not change (1)'s ranking, probably not affect (2) but help (3) as well. (4) is also positively affected.\r\n\r\nTL;DR, here's my proposal so more highly-controversial topics (those that are interesting) are more favoured: Consider root comment and replies as equals and only take *influence* (sum of up- and downvotes) as a score.\r\n\r\nThis benefits (1), which in the current form end up at the bottom, which makes zero sense. It also benefits (2) and (4), which is a forced compromise, given the score does not really show how \"original\" a comment is (this is why Reddit probably introduced awards to allow users to weigh very good posts). By taking all replies into account, it also, of course, benefits (3), which makes sense to push up.\r\n\r\nReplies with no votes increase the influence of the thread by 1, indeed, but isn't the purpose of the score to show what the hivemind thinks? By scoring them as zero (which was proposed here), you effectively value an elaborated response lower than a simple upvote of the original comment. Instead, why not simply \"fold\" long subthreads so they don't take up too much space?\r\n\r\nAs another tangent: By weighing root and children, this might encourage people to respond to \"deep\" threads instead of writing a new post.\r\n\r\nLet's see what @pushcx decides in the end. :)","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_ei3nck","depth":0,"commenting_user":"FRIGN"},{"short_id":"4l8mzk","short_id_url":"https://lobste.rs/c/4l8mzk","created_at":"2022-07-22T12:30:20.000-05:00","updated_at":"2022-07-22T12:30:20.000-05:00","is_deleted":false,"is_moderated":false,"score":2,"flags":0,"parent_comment":null,"comment":"\u003cp\u003eI really like this idea but have no idea what its implementation would represent in terms of additional load to the server.\u003c/p\u003e\n","comment_plain":"I really like this idea but have no idea what its implementation would represent in terms of additional load to the server.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_4l8mzk","depth":0,"commenting_user":"feoh"},{"short_id":"qy0l9k","short_id_url":"https://lobste.rs/c/qy0l9k","created_at":"2022-07-22T16:12:09.000-05:00","updated_at":"2022-07-22T16:12:09.000-05:00","is_deleted":false,"is_moderated":false,"score":5,"flags":0,"parent_comment":"4l8mzk","comment":"\u003cp\u003eI’ve moved most of the \u003ca href=\"https://github.com/lobsters/lobsters/blob/cf52ab9f3f0b3ac805effc2e718f15922cb67332/app/models/comment.rb#L340\" rel=\"ugc\"\u003evote\u003c/a\u003e into the db, but \u003ca href=\"https://github.com/lobsters/lobsters/blob/cf52ab9f3f0b3ac805effc2e718f15922cb67332/app/models/comment.rb#L219\" rel=\"ugc\"\u003enot all\u003c/a\u003e. If \u003ccode\u003ecalculated_confidence\u003c/code\u003e finished its move into the db almost any algorithm would be faster than the current implementation.\u003c/p\u003e\n","comment_plain":"I've moved most of the [vote](https://github.com/lobsters/lobsters/blob/cf52ab9f3f0b3ac805effc2e718f15922cb67332/app/models/comment.rb#L340) into the db, but [not all](https://github.com/lobsters/lobsters/blob/cf52ab9f3f0b3ac805effc2e718f15922cb67332/app/models/comment.rb#L219). If `calculated_confidence` finished its move into the db almost any algorithm would be faster than the current implementation.","url":"https://lobste.rs/s/tdfoqh/ranking_comments_by_sum_replies_scores#c_qy0l9k","depth":1,"commenting_user":"pushcx"}]} \ No newline at end of file diff --git a/common/src/main/kotlin/dev/msfjarvis/claw/common/comments/CommentEntry.kt b/common/src/main/kotlin/dev/msfjarvis/claw/common/comments/CommentEntry.kt index 32b65f27..1562436c 100644 --- a/common/src/main/kotlin/dev/msfjarvis/claw/common/comments/CommentEntry.kt +++ b/common/src/main/kotlin/dev/msfjarvis/claw/common/comments/CommentEntry.kt @@ -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( diff --git a/common/src/main/kotlin/dev/msfjarvis/claw/common/posts/LobstersCard.kt b/common/src/main/kotlin/dev/msfjarvis/claw/common/posts/LobstersCard.kt index 8333dfd8..2c72d479 100644 --- a/common/src/main/kotlin/dev/msfjarvis/claw/common/posts/LobstersCard.kt +++ b/common/src/main/kotlin/dev/msfjarvis/claw/common/posts/LobstersCard.kt @@ -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(), ) } diff --git a/database/core/src/main/kotlin/dev/msfjarvis/claw/database/SavedPostSerializer.kt b/database/core/src/main/kotlin/dev/msfjarvis/claw/database/SavedPostSerializer.kt index 99195e05..5f5d5557 100644 --- a/database/core/src/main/kotlin/dev/msfjarvis/claw/database/SavedPostSerializer.kt +++ b/database/core/src/main/kotlin/dev/msfjarvis/claw/database/SavedPostSerializer.kt @@ -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 { element("commentCount", isOptional = true) element("commentsUrl") element("submitterName") - element("submitterAvatarUrl") element>("tags") element("description") } @@ -46,7 +45,6 @@ object SavedPostSerializer : KSerializer { var commentCount: Int? = null var commentsUrl = "" var submitterName = "" - var submitterAvatarUrl = "" var tags = emptyList() var description = "" while (true) { @@ -58,9 +56,8 @@ object SavedPostSerializer : KSerializer { 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 { commentCount = commentCount, commentsUrl = commentsUrl, submitterName = submitterName, - submitterAvatarUrl = submitterAvatarUrl, tags = tags, description = description, ) @@ -89,9 +85,8 @@ object SavedPostSerializer : KSerializer { 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) } } } diff --git a/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/SavedPost.sq b/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/SavedPost.sq index 0165f5fb..84dec796 100644 --- a/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/SavedPost.sq +++ b/database/core/src/main/sqldelight/dev/msfjarvis/claw/database/local/SavedPost.sq @@ -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 NOT NULL, description TEXT NOT NULL DEFAULT "" ); diff --git a/database/core/src/main/sqldelight/migrations/5.sqm b/database/core/src/main/sqldelight/migrations/5.sqm index 6263faaf..09756fa5 100644 --- a/database/core/src/main/sqldelight/migrations/5.sqm +++ b/database/core/src/main/sqldelight/migrations/5.sqm @@ -1,3 +1,3 @@ -CREATE TABLE ReadPosts( +CREATE TABLE IF NOT EXISTS ReadPosts( id TEXT NOT NULL PRIMARY KEY ); diff --git a/database/core/src/main/sqldelight/migrations/6.sqm b/database/core/src/main/sqldelight/migrations/6.sqm new file mode 100644 index 00000000..ac41af66 --- /dev/null +++ b/database/core/src/main/sqldelight/migrations/6.sqm @@ -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 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; diff --git a/database/core/src/test/kotlin/dev/msfjarvis/claw/database/SavedPostSerializerTest.kt b/database/core/src/test/kotlin/dev/msfjarvis/claw/database/SavedPostSerializerTest.kt index d7dd081b..eacba645 100644 --- a/database/core/src/test/kotlin/dev/msfjarvis/claw/database/SavedPostSerializerTest.kt +++ b/database/core/src/test/kotlin/dev/msfjarvis/claw/database/SavedPostSerializerTest.kt @@ -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 = "

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?

\n", diff --git a/database/core/src/test/resources/saved_post.json b/database/core/src/test/resources/saved_post.json index be0a5e7a..469985f6 100644 --- a/database/core/src/test/resources/saved_post.json +++ b/database/core/src/test/resources/saved_post.json @@ -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":"

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?

\n"} \ No newline at end of file +{"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":"

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?

\n"} \ No newline at end of file diff --git a/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/SavedPostQueriesTest.kt b/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/SavedPostQueriesTest.kt index aa36466f..c2b22b25 100644 --- a/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/SavedPostQueriesTest.kt +++ b/database/impl/src/test/kotlin/dev/msfjarvis/claw/database/local/SavedPostQueriesTest.kt @@ -122,7 +122,6 @@ class SavedPostQueriesTest { commentCount = 0, commentsUrl = "test_comments_url", submitterName = "test_user_$i", - submitterAvatarUrl = "test_avatar_url", tags = listOf(), description = "", ) diff --git a/model/src/main/kotlin/dev/msfjarvis/claw/model/Comment.kt b/model/src/main/kotlin/dev/msfjarvis/claw/model/Comment.kt index d4469bca..3300b311 100644 --- a/model/src/main/kotlin/dev/msfjarvis/claw/model/Comment.kt +++ b/model/src/main/kotlin/dev/msfjarvis/claw/model/Comment.kt @@ -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, ) diff --git a/model/src/main/kotlin/dev/msfjarvis/claw/model/LobstersPost.kt b/model/src/main/kotlin/dev/msfjarvis/claw/model/LobstersPost.kt index ee0a3b92..2eed02a7 100644 --- a/model/src/main/kotlin/dev/msfjarvis/claw/model/LobstersPost.kt +++ b/model/src/main/kotlin/dev/msfjarvis/claw/model/LobstersPost.kt @@ -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, ) diff --git a/model/src/main/kotlin/dev/msfjarvis/claw/model/LobstersPostDetails.kt b/model/src/main/kotlin/dev/msfjarvis/claw/model/LobstersPostDetails.kt index b5c369de..b00aad5d 100644 --- a/model/src/main/kotlin/dev/msfjarvis/claw/model/LobstersPostDetails.kt +++ b/model/src/main/kotlin/dev/msfjarvis/claw/model/LobstersPostDetails.kt @@ -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, val comments: List, ) diff --git a/model/src/main/kotlin/dev/msfjarvis/claw/model/UIPost.kt b/model/src/main/kotlin/dev/msfjarvis/claw/model/UIPost.kt index 63d74d3a..a5ca91e2 100644 --- a/model/src/main/kotlin/dev/msfjarvis/claw/model/UIPost.kt +++ b/model/src/main/kotlin/dev/msfjarvis/claw/model/UIPost.kt @@ -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, val comments: List = 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"), ],