Skip to content

Commit

Permalink
feat: also import reviews from goodreads #132
Browse files Browse the repository at this point in the history
  • Loading branch information
bayang committed Sep 15, 2024
1 parent c9fe2d6 commit 4ff2cd1
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/main/kotlin/io/github/bayang/jelu/dao/ImportRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class ImportRepository {
this.importSource = entity.importSource!!
this.librarythingId = entity.librarythingId
this.owned = entity.owned
this.rating = entity.rating
this.review = entity.review
}
}

Expand Down
4 changes: 4 additions & 0 deletions src/main/kotlin/io/github/bayang/jelu/dao/ImportTable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ object ImportEntityTable : UUIDTable("import_entity") {
var userId: Column<UUID> = uuid(name = "userId")
var shouldFetchMetadata: Column<Boolean> = bool("should_fetch_metadata")
var owned: Column<Boolean?> = bool("owned").nullable()
var rating: Column<Int?> = integer(name = "rating").nullable()
var review: Column<String?> = varchar("review", 500000).nullable()
}

class ImportEntity(id: EntityID<UUID>) : UUIDEntity(id) {
Expand All @@ -53,6 +55,8 @@ class ImportEntity(id: EntityID<UUID>) : UUIDEntity(id) {
var userId by ImportEntityTable.userId
var shouldFetchMetadata by ImportEntityTable.shouldFetchMetadata
var owned by ImportEntityTable.owned
var rating by ImportEntityTable.rating
var review by ImportEntityTable.review
}

enum class ProcessingStatus {
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/io/github/bayang/jelu/dto/ImportDto.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class ImportDto {
var readCount: Int? = null
var owned: Boolean? = null
var importSource: ImportSource? = null
var review: String? = null
var rating: Int? = null
}
data class ImportConfigurationDto(
var shouldFetchMetadata: Boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import io.github.bayang.jelu.dao.ImportSource
import io.github.bayang.jelu.dao.MessageCategory
import io.github.bayang.jelu.dao.ProcessingStatus
import io.github.bayang.jelu.dao.ReadingEventType
import io.github.bayang.jelu.dao.Visibility
import io.github.bayang.jelu.dto.AuthorDto
import io.github.bayang.jelu.dto.BookCreateDto
import io.github.bayang.jelu.dto.BookDto
import io.github.bayang.jelu.dto.CreateReadingEventDto
import io.github.bayang.jelu.dto.CreateReviewDto
import io.github.bayang.jelu.dto.CreateUserBookDto
import io.github.bayang.jelu.dto.CreateUserMessageDto
import io.github.bayang.jelu.dto.ImportConfigurationDto
Expand All @@ -24,6 +26,7 @@ import io.github.bayang.jelu.dto.UserBookUpdateDto
import io.github.bayang.jelu.service.BookService
import io.github.bayang.jelu.service.ImportService
import io.github.bayang.jelu.service.ReadingEventService
import io.github.bayang.jelu.service.ReviewService
import io.github.bayang.jelu.service.UserMessageService
import io.github.bayang.jelu.service.UserService
import io.github.bayang.jelu.service.metadata.FetchMetadataService
Expand All @@ -40,6 +43,7 @@ import org.springframework.scheduling.annotation.Async
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.io.File
import java.time.Instant
import java.time.LocalDate
import java.time.OffsetDateTime
import java.time.ZoneId
Expand Down Expand Up @@ -78,6 +82,7 @@ class CsvImportService(
private val userService: UserService,
private val readingEventService: ReadingEventService,
private val userMessageService: UserMessageService,
private val reviewService: ReviewService,
) {

// maybe later : use coroutines ?
Expand Down Expand Up @@ -321,6 +326,29 @@ class CsvImportService(
userEntity,
)
}
val rating: Int = if (importEntity.rating != null) (importEntity.rating!! * 2) else 0
if (!importEntity.review.isNullOrEmpty() || rating > 0) {
val existing = reviewService.find(
userEntity.id.value,
savedUserBook.book.id!!,
null,
null,
null,
Pageable.ofSize(10),
)
if (existing.isEmpty) {
reviewService.save(
CreateReviewDto(
Instant.now(),
if (importEntity.review.isNullOrEmpty()) "" else importEntity.review!!,
rating.toDouble(),
Visibility.PUBLIC,
savedUserBook.book.id,
),
userEntity,
)
}
}
importService.updateStatus(importEntity.id.value, ProcessingStatus.IMPORTED)
return ProcessingStatus.IMPORTED
} catch (e: Exception) {
Expand Down Expand Up @@ -651,6 +679,8 @@ class CsvImportService(
if (ownedCopies != null && ownedCopies > 0) {
dto.owned = true
}
dto.review = cleanString(record.get(19))
dto.rating = parseNumber(record.get(7))
dto.importSource = ImportSource.GOODREADS
return dto
}
Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/liquibase.xml
Original file line number Diff line number Diff line change
Expand Up @@ -544,4 +544,10 @@
</column>
</createTable>
</changeSet>
<changeSet id="add_rating_review_columns" author="byng">
<sql>
ALTER TABLE import_entity ADD rating INTEGER;
ALTER TABLE import_entity ADD review varchar(500000);
</sql>
</changeSet>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,27 @@ class CsvImportServiceTest(
}
}

@Test
fun testParseRatingAndReview() {
val userId = user().id.value
val csv = File(this::class.java.getResource("/csv-import/goodreads_library_export_one_line_modified_review.csv").file)
csvImportService.parse(csv, userId, importConfigurationDto())
val nb = importService.countByprocessingStatusAndUser(ProcessingStatus.SAVED, userId)
Assertions.assertEquals(4, nb)
val dtos = importService.getByprocessingStatusAndUser(ProcessingStatus.SAVED, userId)
dtos.forEach {
if (it.title.equals("Dr Jekyll and Mr Hyde")) {
Assertions.assertEquals("9780141973821", it.isbn13)
Assertions.assertEquals("Robert Louis Stevenson", it.authors)
Assertions.assertEquals(5, it.rating)
Assertions.assertTrue(it.review?.equals("Despite knowing the twist, I still enjoyed the book greatly. Excellently written.")!!)
} else if (it.title.equals("Povídky I")) {
Assertions.assertEquals(3, it.rating)
Assertions.assertTrue(it.review?.contains("Josefine (die Sängerin, oder Das Volk der Mäuse), and First Sorrow (Erstes Leid).<br/><br/>It should come as no surprise, then, that I like Kafka's more narrative-driven works better. In this collection, that would be:<br/><br/>(longer ones)<br/>* In the Penal Colony (In der Strafkolonie)<br/>* The Metamorphosis (Die Verwandlung)<br/>* The Stoker (Der Heizer)<br/>(shorter ones)<br/>* Before the Law (Vor dem Gesetz, amazing!)<br/>* The Dream (Ein Traum)<br/>* The Bucket")!!)
}
}
}

@Test
fun testParseIsbnList() {
val userId = user().id.value
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Book Id,Title,Author,Author l-f,Additional Authors,ISBN,ISBN13,My Rating,Average Rating,Publisher,Binding,Number of Pages,Year Published,Original Publication Year,Date Read,Date Added,Bookshelves,Bookshelves with positions,Exclusive Shelf,My Review,Spoiler,Private Notes,Read Count,Owned Copies
19308181,Dr Jekyll and Mr Hyde,Robert Louis Stevenson,"Stevenson, Robert Louis",,"=""014197382X""","=""9780141973821""",5,3.81,Penguin English Library,Kindle Edition,117,2012,,2020/01/23,2020/01/22,"brain, classic, fantasy, horror, mind, psychology","brain (#3), classic (#4), fantasy (#13), horror (#3), mind (#7), psychology (#6)",read,"Despite knowing the twist, I still enjoyed the book greatly. Excellently written.",,,1,0
18114322,The Grapes of Wrath,John Steinbeck,"Steinbeck, John",,"=""067001690X""","=""9780670016907""",4,4.00,Viking,Hardcover,479,2014,1939,2023/04/17,2023/04/17,,,read,Incredible story of a family trying to survive during the Great Depression that is strangely relevant even today. Loved the characters (especially Má and Tom) and the colloquial language.,,,1,0
13560311,The Handmaid's Tale,Margaret Atwood,"Atwood, Margaret","Elena Balbusso, Anna Balbusso","=""""","=""""",5,4.13,Folio Society,Hardcover,336,2012,1985,2021/10/09,2019/05/15,"owned-physical, dystopia, feminism","owned-physical (#31), dystopia (#1), feminism (#5)",read,"The narrator's account of what has happened to her seems to be woven with great care from many different pieces of our own history. It's appalling how many of the things in the book remind me of the various events that took place in the past decade, especially in the US. <br/><br/>Thinking back on the ending, I especially like it because it avoids being both a clichéd happy-end and its polar opposite. It's both bleak and hopeful, but also quite sudden; a story suddenly cut off. This reinforces its ""found diary"" quality.",,,1,0
430803,Povídky I,Franz Kafka,"Kafka, Franz",,"=""8085844508""","=""9788085844504""",3,4.00,Nakladatelství Franze Kafky,Hardcover,352,1999,1999,2023/01/12,2022/02/03,,,read,"Not an easy read for someone who like me who is probably just a surface reader at best.<br/><br/>Although the surreal feeling of his writing is probably what I like the most about it, sometimes in can lean into incomprehensible stream-of-consciousness style that is almost impossible to follow. This is especially true about the whole first part (called Contemplation, or Betrachtung in German) and the four stories united under the theme of a starving artist: A Hunger Artist (Ein Hungerkünstler), A Little Woman (Eine kleine Frau), Josephine the Singer, or the Mouse Folk or Josefine (die Sängerin, oder Das Volk der Mäuse), and First Sorrow (Erstes Leid).<br/><br/>It should come as no surprise, then, that I like Kafka's more narrative-driven works better. In this collection, that would be:<br/><br/>(longer ones)<br/>* In the Penal Colony (In der Strafkolonie)<br/>* The Metamorphosis (Die Verwandlung)<br/>* The Stoker (Der Heizer)<br/>(shorter ones)<br/>* Before the Law (Vor dem Gesetz, amazing!)<br/>* The Dream (Ein Traum)<br/>* The Bucket Rider (Der Kübelreiter)",,,1,0
92625,The Ones Who Walk Away from Omelas,Ursula K. Le Guin,"Guin, Ursula K. Le",,"=""0886825016""","=""9780886825010""",5,4.37,"Creative Education, Inc.",Library Binding,32,1997,1973,,2022/12/30,,,read,Inredible short story that doesn't lose any of its impact even when knowing its rough content in advance.,,,1,0

0 comments on commit 4ff2cd1

Please sign in to comment.