Skip to content

Commit

Permalink
Improve Fever adapters reliability (fixes #229 and should also fix #228)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shinokuni committed Dec 1, 2024
1 parent 383aea0 commit 35d3b31
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 168 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package com.readrops.api.services.fever.adapters

import com.readrops.api.utils.exceptions.ParseException
import com.readrops.api.utils.extensions.skipField
import com.readrops.api.utils.extensions.toBoolean
import com.squareup.moshi.FromJson
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonReader.Token
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.ToJson

Expand All @@ -21,21 +19,17 @@ class FeverAPIAdapter : JsonAdapter<Boolean>() {
override fun fromJson(reader: JsonReader): Boolean = with(reader) {
return try {
beginObject()
skipField()

var authenticated = 0
if (nextName() == "auth") {
authenticated = nextInt()
} else {
skipValue()
}

while (peek() == Token.NAME) {
skipField()
var authenticated = false
while (hasNext()) {
when (nextName()) {
"auth" -> authenticated = nextInt().toBoolean()
else -> skipValue()
}
}

endObject()
authenticated.toBoolean()
authenticated
} catch (e: Exception) {
throw ParseException(e.message)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.readrops.api.services.fever.adapters

import android.annotation.SuppressLint
import com.readrops.api.utils.exceptions.ParseException
import com.readrops.api.utils.extensions.skipField
import com.squareup.moshi.FromJson
import com.squareup.moshi.JsonReader
import com.squareup.moshi.ToJson
Expand All @@ -19,55 +18,61 @@ class FeverFaviconsAdapter {
@ToJson
fun toJson(favicons: List<Favicon>) = ""

@OptIn(ExperimentalEncodingApi::class)
@SuppressLint("CheckResult")
@FromJson
fun fromJson(reader: JsonReader): List<Favicon> = with(reader) {
return try {
val favicons = arrayListOf<Favicon>()

beginObject()

repeat(3) {
skipField()
}

nextName() // beginning of favicon array
beginArray()

while (hasNext()) {
beginObject()
when (nextName()) {
"favicons" -> {
beginArray()

var id = 0
var data: ByteArray? = null
while (hasNext()) {
beginObject()
parseFavicon(reader)?.let { favicons += it }

while (hasNext()) {
when (selectName(NAMES)) {
0 -> id = nextInt()
1 -> data = Base64.decode(nextString().substringAfter("base64,"))
else -> skipValue()
}
}
endObject()
}

if (id > 0 && data != null) {
favicons += Favicon(
id = id,
data = data,
)
endArray()
}
else -> skipValue()
}

endObject()
}

endArray()
endObject()

favicons
} catch (e: Exception) {
throw ParseException(e.message)
}
}

@OptIn(ExperimentalEncodingApi::class)
private fun parseFavicon(reader: JsonReader): Favicon? = with(reader) {
var id = 0
var data: ByteArray? = null

while (hasNext()) {
when (selectName(NAMES)) {
0 -> id = nextInt()
1 -> data = Base64.decode(nextString().substringAfter("base64,"))
else -> skipValue()
}
}

if (id > 0 && data != null) {
return Favicon(
id = id,
data = data,
)
} else {
null
}
}

companion object {
val NAMES: JsonReader.Options = JsonReader.Options.of("id", "data")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import com.readrops.api.utils.exceptions.ParseException
import com.readrops.api.utils.extensions.nextNonEmptyString
import com.readrops.api.utils.extensions.nextNullableString
import com.readrops.api.utils.extensions.skipField
import com.readrops.db.entities.Feed
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonReader
Expand All @@ -30,63 +29,34 @@ class FeverFeedsAdapter : JsonAdapter<FeverFeeds>() {
val feedsGroups = mutableMapOf<Int, List<Int>>()

beginObject()

while (nextName() != "feeds") {
skipValue()
}

// feeds array
beginArray()
while (hasNext()) {
beginObject()

val feed = Feed()
while (hasNext()) {
with(feed) {
when (selectName(NAMES)) {
0 -> remoteId = nextInt().toString()
1 -> favicons[nextInt()] = remoteId!!
2 -> name = nextNonEmptyString()
3 -> url = nextNonEmptyString()
4 -> siteUrl = nextNullableString()
else -> skipValue()
when (nextName()) {
"feeds" -> {
beginArray()
while (hasNext()) {
beginObject()
feeds += parseFeed(reader, favicons)

endObject()
}
}
}

feeds += feed
endObject()
}
endArray()
}
"feeds_groups" -> {
beginArray()
while (hasNext()) {
beginObject()

endArray()
val (folderId, feedsIds) = parseFeedsGroups(reader)
folderId?.let { feedsGroups[it] = feedsIds }

while (nextName() != "feeds_groups") {
skipValue()
}
endObject()
}

// feeds_groups array
beginArray()
while (hasNext()) {
beginObject()

var folderId: Int? = null
val feedsIds = mutableListOf<Int>()
while (hasNext()) {
when (selectName(JsonReader.Options.of("group_id", "feed_ids"))) {
0 -> folderId = nextInt()
1 -> feedsIds += nextNonEmptyString().split(",").map { it.toInt() }
else -> skipValue()
endArray()
}
else -> skipValue()
}

folderId?.let { feedsGroups[it] = feedsIds }
endObject()
}

endArray()

while (peek() != JsonReader.Token.END_OBJECT) {
skipField()
}

endObject()
Expand All @@ -101,6 +71,39 @@ class FeverFeedsAdapter : JsonAdapter<FeverFeeds>() {
}
}

private fun parseFeed(reader: JsonReader, favicons: MutableMap<Int, String>): Feed = with(reader) {
val feed = Feed()
while (hasNext()) {
with(feed) {
when (selectName(NAMES)) {
0 -> remoteId = nextInt().toString()
1 -> favicons[nextInt()] = remoteId!!
2 -> name = nextNonEmptyString()
3 -> url = nextNonEmptyString()
4 -> siteUrl = nextNullableString()
else -> skipValue()
}
}
}

return feed
}

private fun parseFeedsGroups(reader: JsonReader): Pair<Int?, List<Int>> = with(reader) {
var folderId: Int? = null
val feedsIds = mutableListOf<Int>()

while (hasNext()) {
when (selectName(JsonReader.Options.of("group_id", "feed_ids"))) {
0 -> folderId = nextInt()
1 -> feedsIds += nextNonEmptyString().split(",").map { it.toInt() }
else -> skipValue()
}
}

folderId to feedsIds
}

companion object {
val NAMES: JsonReader.Options =
JsonReader.Options.of("id", "favicon_id", "title", "url", "site_url")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package com.readrops.api.services.fever.adapters
import android.annotation.SuppressLint
import com.readrops.api.utils.exceptions.ParseException
import com.readrops.api.utils.extensions.nextNonEmptyString
import com.readrops.api.utils.extensions.skipField
import com.readrops.api.utils.extensions.skipToEnd
import com.readrops.db.entities.Folder
import com.squareup.moshi.FromJson
import com.squareup.moshi.JsonReader
Expand All @@ -22,35 +20,35 @@ class FeverFoldersAdapter {
val folders = arrayListOf<Folder>()

beginObject()

repeat(3) {
skipField()
}

nextName() // beginning of folders array
beginArray()

while (hasNext()) {
beginObject()

val folder = Folder()
while (hasNext()) {
with(folder) {
when (selectName(NAMES)) {
0 -> remoteId = nextInt().toString()
1 -> name = nextNonEmptyString()
when (nextName()) {
"groups" -> {
beginArray()

while (hasNext()) {
beginObject()

val folder = Folder()
while (hasNext()) {
with(folder) {
when (selectName(NAMES)) {
0 -> remoteId = nextInt().toString()
1 -> name = nextNonEmptyString()
}
}
}

folders += folder
endObject()
}

endArray()
}
else -> skipValue()
}

folders += folder
endObject()
}

endArray()
skipToEnd()
endObject()

folders
} catch (e: Exception) {
throw ParseException(e.message)
Expand Down
Loading

0 comments on commit 35d3b31

Please sign in to comment.