197 lines
5.2 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
# For showcasing the reading time of a user
# Should we show book covers or just the names?
module DiscourseRewind
2024-12-13 17:00:17 +01:00
class Rewind::Action::ReadingTime < Rewind::Action::BaseReport
FakeData = {
data: {
reading_time: 2_880_000,
book: "The Combined Cosmere works + Wheel of Time",
isbn: "978-0812511819",
series: true,
},
identifier: "reading-time",
}
def call
return FakeData if Rails.env.development?
2024-12-13 17:00:17 +01:00
reading_time = UserVisit.where(user_id: user.id).where(visited_at: date).sum(:time_read)
2025-01-13 17:00:32 +01:00
book = best_book_fit(reading_time)
return if book.nil?
{
data: {
reading_time: reading_time,
2025-01-13 17:00:32 +01:00
book: book[:title],
isbn: book[:isbn],
series: book[:series],
},
identifier: "reading-time",
}
end
2025-01-08 15:11:42 -06:00
def popular_books
{
2025-01-13 13:12:12 +01:00
"The Hunger Games" => {
reading_time: 19_740,
isbn: "978-0439023481",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"The Metamorphosis" => {
reading_time: 3120,
isbn: "978-0553213690",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"To Kill a Mockingbird" => {
reading_time: 22_800,
isbn: "978-0061120084",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"Pride and Prejudice" => {
reading_time: 25_200,
isbn: "978-1503290563",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"1984" => {
reading_time: 16_800,
isbn: "978-0451524935",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"The Lord of the Rings" => {
reading_time: 108_000,
isbn: "978-0544003415",
2025-01-14 15:19:16 -06:00
series: true,
2025-01-13 13:12:12 +01:00
},
"Harry Potter and the Sorcerer's Stone" => {
reading_time: 24_600,
isbn: "978-0590353427",
2025-01-14 15:19:16 -06:00
series: true,
2025-01-13 13:12:12 +01:00
},
"The Great Gatsby" => {
reading_time: 12_600,
isbn: "978-0743273565",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"The Little Prince" => {
reading_time: 5400,
isbn: "978-0156012195",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"Animal Farm" => {
reading_time: 7200,
isbn: "978-0451526342",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"The Catcher in the Rye" => {
reading_time: 18_000,
isbn: "978-0316769488",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"Jane Eyre" => {
reading_time: 34_200,
isbn: "978-0141441146",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"Fahrenheit 451" => {
reading_time: 15_000,
isbn: "978-1451673319",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"The Hobbit" => {
reading_time: 27_000,
isbn: "978-0547928227",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"The Da Vinci Code" => {
reading_time: 37_800,
isbn: "978-0307474278",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"Little Women" => {
reading_time: 30_000,
isbn: "978-0147514011",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"One Hundred Years of Solitude" => {
reading_time: 46_800,
isbn: "978-0060883287",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"And Then There Were None" => {
reading_time: 16_200,
isbn: "978-0062073488",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"The Alchemist" => {
reading_time: 10_800,
isbn: "978-0061122415",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
"The Hitchhiker's Guide to the Galaxy" => {
reading_time: 12_600,
isbn: "978-0345391803",
2025-01-14 15:19:16 -06:00
series: false,
2025-01-13 13:12:12 +01:00
},
2025-01-14 09:05:45 -06:00
"The Complete works of Shakespeare" => {
2025-01-14 11:17:55 -03:00
reading_time: 180_000,
isbn: "978-1853268953",
series: true,
2025-01-14 11:17:55 -03:00
},
2025-01-14 09:05:45 -06:00
"The Game of Thrones Series" => {
2025-01-14 11:17:55 -03:00
reading_time: 360_000,
isbn: "978-0007477159",
series: true,
2025-01-14 11:17:55 -03:00
},
"Malazan Book of the Fallen" => {
reading_time: 720_000,
isbn: "978-0765348821",
series: true,
2025-01-14 11:17:55 -03:00
},
"Terry Pratchetts Discworld series" => {
reading_time: 1_440_000,
isbn: "978-9123684458",
series: true,
2025-01-14 11:17:55 -03:00
},
"The Wandering Inn web series" => {
reading_time: 2_160_000,
2025-01-14 09:04:12 -06:00
isbn: "the-wandering-inn",
series: true,
2025-01-14 11:17:55 -03:00
},
2025-01-14 09:05:45 -06:00
"The Combined Cosmere works + Wheel of Time" => {
2025-01-14 11:17:55 -03:00
reading_time: 2_880_000,
isbn: "978-0812511819",
series: true,
2025-01-14 11:17:55 -03:00
},
2025-01-14 09:05:45 -06:00
"The Star Trek novels" => {
2025-01-14 11:17:55 -03:00
reading_time: 3_600_000,
isbn: "978-1852860691",
series: true,
2025-01-14 11:17:55 -03:00
},
2024-12-13 17:00:17 +01:00
}.symbolize_keys
end
def best_book_fit(reading_time)
reading_time_rest = reading_time
books = []
2025-01-07 23:26:17 +01:00
while reading_time_rest > 0
2025-01-08 15:11:42 -06:00
best_fit = popular_books.min_by { |_, v| (v[:reading_time] - reading_time_rest).abs }
break if best_fit.nil?
books << best_fit.first
reading_time_rest -= best_fit.last[:reading_time]
end
2025-01-07 23:26:17 +01:00
2025-01-13 17:00:32 +01:00
return if books.empty?
2025-01-13 13:12:12 +01:00
book_title =
books.group_by { |book| book }.transform_values(&:count).max_by { |_, count| count }.first
2025-01-08 15:11:42 -06:00
2025-01-14 15:17:10 -06:00
{ title: book_title, isbn: popular_books[book_title][:isbn], series: popular_books[book_title][:series] }
end
end
2025-01-13 13:12:12 +01:00
end