diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt index d673a12..e61a20d 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt @@ -9,6 +9,7 @@ import android.widget.ImageView.ScaleType import androidx.recyclerview.widget.RecyclerView import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.databinding.CardItemBinding +import bou.amine.apps.readerforselfossv2.android.sendSilentlyWithAcraWithName import bou.amine.apps.readerforselfossv2.android.utils.LinkOnTouchListener import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable @@ -110,7 +111,12 @@ class ItemCardAdapter( binding.title.setLinkTextColor(c.resources.getColor(R.color.colorAccent)) - binding.sourceTitleAndDate.text = itm.sourceAuthorAndDate() + binding.sourceTitleAndDate.text = try { + itm.sourceAuthorAndDate() + } catch (e: Exception) { + e.sendSilentlyWithAcraWithName("ItemCardAdapter parse date") + itm.sourceAuthorOnly() + } if (!appSettingsService.isFullHeightCardsEnabled()) { binding.itemImage.maxHeight = imageMaxHeight diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt index 4ac6983..2d27e84 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt @@ -7,6 +7,7 @@ import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.databinding.ListItemBinding +import bou.amine.apps.readerforselfossv2.android.sendSilentlyWithAcraWithName import bou.amine.apps.readerforselfossv2.android.utils.LinkOnTouchListener import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable import bou.amine.apps.readerforselfossv2.android.utils.openItemUrl @@ -63,7 +64,12 @@ class ItemListAdapter( binding.title.setLinkTextColor(c.resources.getColor(R.color.colorAccent)) - binding.sourceTitleAndDate.text = itm.sourceAuthorAndDate() + binding.sourceTitleAndDate.text = try { + itm.sourceAuthorAndDate() + } catch (e: Exception) { + e.sendSilentlyWithAcraWithName("ItemListAdapter parse date") + itm.sourceAuthorOnly() + } if (itm.getThumbnail(repository.baseUrl).isEmpty()) { if (itm.getIcon(repository.baseUrl).isEmpty()) { diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt index 3062466..4f052e6 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt @@ -102,7 +102,12 @@ class ArticleFragment : Fragment(), DIAware { contentText = item.content contentTitle = item.title.getHtmlDecoded() contentImage = item.getThumbnail(repository.baseUrl) - contentSource = item.sourceAuthorAndDate() + contentSource = try { + item.sourceAuthorAndDate() + } catch (e: Exception) { + e.sendSilentlyWithAcraWithName("Article Fragment parse date") + item.sourceAuthorOnly() + } allImages = item.getImages() fontSize = appSettingsService.getFontSize() diff --git a/androidApp/src/test/kotlin/DatesTest.kt b/androidApp/src/test/kotlin/DatesTest.kt index 7a28337..f525801 100644 --- a/androidApp/src/test/kotlin/DatesTest.kt +++ b/androidApp/src/test/kotlin/DatesTest.kt @@ -8,12 +8,12 @@ import kotlinx.datetime.toInstant import org.junit.Test class DatesTest { - private val newVersionDateVariant = "2022-12-24T17:00:08+00" - private val newVersionDate = "2013-04-07T13:43:00+01:00" - private val oldVersionDate = "2013-05-07 13:46:00" - private val oldVersionDateVariant = "2021-03-21 10:32:00.000000" + private val newVersionDateVariant = "2022-12-24T17:00:08+00" + private val newVersionDate = "2013-04-07T13:43:00+01:00" + private val newVersionDate2 = "2013-04-07T13:43:00-01:00" + private val oldVersionDate = "2013-05-07 13:46:00" + private val oldVersionDateVariant = "2021-03-21 10:32:00.000000" - private val bugVersionDate = "2023-12-19T10:30:53-05:00" @Test fun new_version_date_should_be_parsed() { @@ -24,6 +24,15 @@ class DatesTest { assertEquals(expected, date) } + @Test + fun new_version_date2_should_be_parsed() { + val date = DateUtils.parseDate(newVersionDate2) + val expected = + LocalDateTime(2013, 4, 7, 13, 43, 0, 0).toInstant(TimeZone.currentSystemDefault()) + .toEpochMilliseconds() + + assertEquals(expected, date) + } @Test fun old_version_date_should_be_parsed() { @@ -54,14 +63,4 @@ class DatesTest { assertEquals(expected, date) } - - @Test - fun bug_version_variant_date_should_be_parsed() { - val date = DateUtils.parseDate(bugVersionDate) - val expected = - LocalDateTime(1991, 3, 18, 3, 0, 0, 0).toInstant(TimeZone.currentSystemDefault()) - .toEpochMilliseconds() - - assertEquals(expected, date) - } } diff --git a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index bbb23c9..a428111 100644 --- a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -11,7 +11,7 @@ actual class DateUtils { private val oldVersionFormat = "\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}(.()\\d*)?".toRegex() // yyyy-MM-dd'T'HH:mm:ss[.SSS]XXX (RFC3339) - private val newVersionFormat = "\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\+\\d{2}(:\\d{2})?".toRegex() + private val newVersionFormat = "(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})[+-](\\d{2}(:\\d{2})?)?".toRegex() // We may need to consider moving the formatting to platform specific code, even if the tests are doubled // For now, we handle this in a hacky way, because kotlin only accepts iso formats @@ -21,13 +21,12 @@ actual class DateUtils { if (dateString.matches(oldVersionFormat)) { dateString.replace(" ", "T") } else if (dateString.matches(newVersionFormat)) { - dateString.split("+")[0] + newVersionFormat.find(dateString)?.groups?.get(1)?.value ?: throw Exception("Couldn't parse $dateString") } else { throw Exception("Unrecognized format for $dateString") } } catch (e: Exception) { - Napier.e("parseDate failed", e, tag = "DateUtils.parseDate") - "1991-03-18T03:00:00" + throw Exception("parseDate failed for $dateString", e) } return LocalDateTime.parse(isoDateString).toInstant(TimeZone.currentSystemDefault()).toEpochMilliseconds() diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt index 34fc7e9..de13183 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt @@ -146,6 +146,14 @@ class SelfossModel { return txt } + fun sourceAuthorOnly(): String { + var txt = this.sourcetitle.getHtmlDecoded() + if (!this.author.isNullOrBlank()) { + txt += " (by ${this.author}) " + } + return txt + } + fun toggleStar(): Item { this.starred = !this.starred return this