Skip to content

Commit

Permalink
Add bookshelves
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Reumann committed Aug 7, 2021
1 parent dd5eb4b commit 5da834c
Show file tree
Hide file tree
Showing 16 changed files with 200 additions and 13 deletions.
20 changes: 20 additions & 0 deletions src/main/kotlin/googlebooksapi/BookshelfClient.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package googlebooksapi

import googlebooksapi.data.bookshelf.Bookshelf
import googlebooksapi.data.bookshelf.BookshelfItem
import googlebooksapi.data.volume.Volume
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.client.statement.*

class BookshelfClient : Client() {
suspend fun getAll(url: String): Bookshelf {
val response: HttpResponse = httpClient.get(url) {}
return response.receive()
}

suspend fun get(url: String): BookshelfItem {
val response: HttpResponse = httpClient.get(url) {}
return response.receive()
}
}
65 changes: 65 additions & 0 deletions src/main/kotlin/googlebooksapi/BookshelfHelper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package googlebooksapi

import googlebooksapi.data.bookshelf.Bookshelf
import googlebooksapi.data.bookshelf.BookshelfItem
import googlebooksapi.data.volume.Volume
import googlebooksapi.exceptions.HelperException
import googlebooksapi.options.FilterOption
import googlebooksapi.options.PrintTypeOption
import googlebooksapi.options.ProjectionOption
import googlebooksapi.options.SortOption
import io.ktor.client.features.*

class BookshelfHelper(apikey: String) {
private val urlBuilder: BookshelfURLBuilder
private var userID: String

init {
urlBuilder = BookshelfURLBuilder(apikey)
userID = StringUtils.EMPTY_STRING
}

fun userID(id: String) {
userID = id
}

suspend fun getAll(): Bookshelf {
val url = urlBuilder.getURL(userID)
val client = BookshelfClient()
val bookshelf: Bookshelf

try {
bookshelf = client.getAll(url)
} catch (redirectException: RedirectResponseException) {
throw HelperException(redirectException.message ?: "3xx received")
} catch (clientException: ClientRequestException) {
throw HelperException(clientException.message)
} catch (serverException: ServerResponseException) {
throw HelperException(serverException.message ?: "5xx received")
} finally {
client.close()
}

return bookshelf
}

suspend fun get(bookshelfID: String): BookshelfItem {
val url = urlBuilder.getURLByBookshelfID(userID, bookshelfID)
val client = BookshelfClient()
val item: BookshelfItem

try {
item = client.get(url)
} catch (redirectException: RedirectResponseException) {
throw HelperException(redirectException.message ?: "3xx received")
} catch (clientException: ClientRequestException) {
throw HelperException(clientException.message)
} catch (serverException: ServerResponseException) {
throw HelperException(serverException.message ?: "5xx received")
} finally {
client.close()
}

return item
}
}
23 changes: 23 additions & 0 deletions src/main/kotlin/googlebooksapi/BookshelfURLBuilder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package googlebooksapi

import googlebooksapi.exceptions.InvalidUserIdException
import java.lang.StringBuilder

class BookshelfURLBuilder(private var key: String = StringUtils.EMPTY_STRING) : URLBuilder() {
private val url: String

init {
url = baseURL + "/users"
}

fun getURL(userID: String): String {
if (userID.isEmpty()) {
throw InvalidUserIdException("UserID is empty")
}
return "$url/$userID/bookshelves?key=$key"
}

fun getURLByBookshelfID(userID: String, bookshelfID: String): String {
return "$url/$userID/bookshelves/$bookshelfID?key=$key"
}
}
2 changes: 0 additions & 2 deletions src/main/kotlin/googlebooksapi/Client.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,4 @@ abstract class Client {
fun close(){
httpClient.close()
}

abstract suspend fun get(url: String): Volume
}
2 changes: 1 addition & 1 deletion src/main/kotlin/googlebooksapi/VolumeClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import io.ktor.client.request.*
import io.ktor.client.statement.*

class VolumeClient : Client() {
override suspend fun get(url: String): Volume {
suspend fun get(url: String): Volume {
val response: HttpResponse = httpClient.get(url) {}
return response.receive()
}
Expand Down
4 changes: 4 additions & 0 deletions src/main/kotlin/googlebooksapi/VolumeHelper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ package googlebooksapi

import googlebooksapi.data.volume.Volume
import googlebooksapi.exceptions.HelperException
import googlebooksapi.options.FilterOption
import googlebooksapi.options.PrintTypeOption
import googlebooksapi.options.ProjectionOption
import googlebooksapi.options.SortOption
import io.ktor.client.features.*

class VolumeHelper(apikey: String) {
Expand Down
24 changes: 18 additions & 6 deletions src/main/kotlin/googlebooksapi/VolumeSearch.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,39 @@ class VolumeSearch(
) {
override fun toString(): String {
val sb = StringBuilder("?q=")

appendSearchText(sb)
appendFields(sb)
appendParameters(sb)

return sb.toString()
}

private fun appendSearchText(s: StringBuilder){
if (searchText.isNotEmpty()) {
sb.append(searchText)
s.append(searchText)

if (fields.isNotEmpty()) {
sb.append("+")
s.append("+")
}
}
}

private fun appendFields(s: StringBuilder){
val lastIndex = fields.size - 1
var idx = 0
fields.forEach { name, value ->
sb.append("${name}:${value}")
if (idx < lastIndex) sb.append("+")
s.append("${name}:${value}")
if (idx < lastIndex) s.append("+")
idx++
}
}

private fun appendParameters(s: StringBuilder) {
if (parameters.isNotEmpty()) {
parameters.forEach { name, value ->
sb.append("&${name}=${value}")
s.append("&${name}=${value}")
}
}
return sb.toString()
}
}
6 changes: 6 additions & 0 deletions src/main/kotlin/googlebooksapi/data/bookshelf/Bookshelf.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package googlebooksapi.data.bookshelf

data class Bookshelf(
val kind: String,
val bookshelfItems: List<BookshelfItem>
)
17 changes: 17 additions & 0 deletions src/main/kotlin/googlebooksapi/data/bookshelf/BookshelfItem.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package googlebooksapi.data.bookshelf

import java.net.URI
import java.time.Instant

data class BookshelfItem(
val kind: String,
val id: Int,
val selfLink: URI,
val title: String,
val description: String,
val access: String,
val updated: Instant,
val created: Instant,
val volumeCount: Int,
val volumesLastUpdated: Instant
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package googlebooksapi.exceptions

class InvalidUserIdException(message: String) : Exception(message) {
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package googlebooksapi
package googlebooksapi.options

enum class FilterOption(val string: String){
PARTIAL("partial"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package googlebooksapi
package googlebooksapi.options

enum class PrintTypeOption(val string: String) {
ALL("all"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package googlebooksapi
package googlebooksapi.options

enum class ProjectionOption(val string: String) {
FULL("full"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package googlebooksapi
package googlebooksapi.options

enum class SortOption(val string: String) {
RELEVANCE("relevance"),
Expand Down
37 changes: 37 additions & 0 deletions src/test/kotlin/googlebooksapi/BookshelfURLBuilderTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package googlebooksapi

import googlebooksapi.exceptions.InvalidUserIdException
import kotlin.test.Test
import kotlin.test.assertEquals

internal class BookshelfURLBuilderTest {
companion object {
val EMPTY_STRING: String = ""

val KEY: String = "xxxx"
val USERID: String = "11111"
val BOOKSHELFID: String = "3"
}

@Test(InvalidUserIdException::class)
fun testGetURLEmptyUserID() {
val urlBuilder = BookshelfURLBuilder(KEY)
urlBuilder.getURL(userID = EMPTY_STRING)
}

@Test
fun testGetURLValid() {
val urlBuilder = BookshelfURLBuilder(KEY)
val actual = urlBuilder.getURL(userID = USERID)
val expected = "https://www.googleapis.com/books/v1/users/$USERID/bookshelves?key=$KEY"
assertEquals(expected, actual)
}

@Test
fun testGetURLByBookshelfID(){
val urlBuilder = BookshelfURLBuilder(KEY)
val actual = urlBuilder.getURLByBookshelfID(USERID, BOOKSHELFID)
val expected = "https://www.googleapis.com/books/v1/users/$USERID/bookshelves/$BOOKSHELFID?key=$KEY"
assertEquals(expected, actual)
}
}
1 change: 1 addition & 0 deletions src/test/kotlin/googlebooksapi/VolumeURLBuilderTest.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package googlebooksapi

import googlebooksapi.options.PrintTypeOption
import kotlin.test.Test
import kotlin.test.assertEquals

Expand Down

0 comments on commit 5da834c

Please sign in to comment.