Skip to content

Commit

Permalink
Apply suggested fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
KotlinGeekDev committed Jan 2, 2025
1 parent 991265f commit 5d501d6
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 88 deletions.
22 changes: 14 additions & 8 deletions app/src/main/java/com/nononsenseapps/feeder/model/FeedParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ class FeedParser(override val di: DI) : DIAware {
when (parsedProfile) {
is Nip21Enum.Pubkey -> return Nip19Profile(parsedProfile.publicKey)
is Nip21Enum.Profile -> return Nip19Profile(parsedProfile.profile.publicKey(), parsedProfile.profile.relays())
else -> throw Throwable(message = "Could not find the user's info: $nostrUri")
else -> throw NostrUriParserException(message = "Could not find the user's info: $nostrUri")
}
}
}
Expand All @@ -264,7 +264,7 @@ class FeedParser(override val di: DI) : DIAware {
it.size < 4
}.orEmpty()
.ifEmpty { getUserPublishRelays(publicKey) }
println("Relays from Nip19 -> ${relayList.joinToString(separator = ", ")}")
logDebug(LOG_TAG, "Relays from Nip19 -> ${relayList.joinToString(separator = ", ")}")
relayList
.ifEmpty { defaultFetchRelays }
.forEach { relayUrl ->
Expand All @@ -276,7 +276,7 @@ class FeedParser(override val di: DI) : DIAware {
publicKey = publicKey,
timeout = Duration.ofSeconds(5L),
)
println(profileInfo.asPrettyJson())
logDebug(LOG_TAG, profileInfo.asPrettyJson())

// Check if all relays in relaylist can be connected to
AuthorNostrData(
Expand Down Expand Up @@ -329,15 +329,15 @@ class FeedParser(override val di: DI) : DIAware {
Filter()
.author(author)
.kind(Kind.fromEnum(KindEnum.LongFormTextNote))
logDebug(LOG_TAG, "Relay List size: -> ${relays.size}")
logDebug(LOG_TAG, "Relay List size: ${relays.size}")

nostrClient.removeAllRelays()
val relaysToUse =
relays.take(2).plus(defaultArticleFetchRelays.random())
.ifEmpty { defaultFetchRelays }
relaysToUse.forEach { relay -> nostrClient.addReadRelay(relay) }
nostrClient.connect()
logDebug(LOG_TAG, "-------------------FETCHING ARTICLES----------------------")
logDebug(LOG_TAG, "FETCHING ARTICLES")
val articleEventSet =
nostrClient.fetchEventsFrom(
urls = relaysToUse,
Expand Down Expand Up @@ -448,7 +448,7 @@ private fun List<Event>.mapToFeed(
authorName: String,
imageUrl: String,
): ParsedFeed {
val description = "Nostr articles by $authorName"
val description = "Nostr: $authorName"
val author =
ParsedAuthor(
name = authorName,
Expand Down Expand Up @@ -511,14 +511,14 @@ fun Event.asArticle(
val articleSummary = tags().find(TagKind.Summary)?.content()
val articleContent = content()
val parsedMarkdown = markDownParser.buildMarkdownTreeFromString(articleContent)
val htmlFromContent = HtmlGenerator(articleContent, parsedMarkdown, CommonMarkFlavourDescriptor()).generateHtml()
val htmlContent = HtmlGenerator(articleContent, parsedMarkdown, CommonMarkFlavourDescriptor()).generateHtml()

return ParsedArticle(
id = articleId,
url = articleUri,
external_url = externalLink,
title = articleTitle,
content_html = htmlFromContent,
content_html = htmlContent,
content_text = articleContent,
summary = articleSummary,
image = if (articleImage != null) MediaImage(url = articleImage.toString()) else null,
Expand Down Expand Up @@ -733,6 +733,12 @@ class AuthorNostrData(
val relayList: List<String>,
)

sealed class NostrException(message: String) : Exception(message)

class NostrUriParserException(override val message: String) : NostrException(message)

class NostrMetadataException(override val message: String) : NostrException(message)

@Parcelize
sealed class FeedParserError : Parcelable {
abstract val url: String
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.nononsenseapps.feeder.model

import android.util.Log
import com.nononsenseapps.feeder.FeederApplication
import com.nononsenseapps.feeder.R
import com.nononsenseapps.feeder.archmodel.Repository
import com.nononsenseapps.feeder.background.runOnceFullTextSync
import com.nononsenseapps.feeder.blob.blobFile
Expand Down Expand Up @@ -50,6 +52,7 @@ class RssLocalSync(override val di: DI) : DIAware {
private val feedParser: FeedParser by instance()
private val okHttpClient: OkHttpClient by instance()
private val filePathProvider: FilePathProvider by instance()
private val application: FeederApplication by instance()

suspend fun syncFeeds(
feedId: Long = ID_UNSET,
Expand Down Expand Up @@ -249,10 +252,12 @@ class RssLocalSync(override val di: DI) : DIAware {
Either.catching(
onCatch = { t -> FetchError(url = url.toString(), throwable = t) },
) {
feedParser.getProfileMetadata(url)
.getOrNull()!!
feedParser.getProfileMetadata(url).getOrNull() ?: throw NostrMetadataException("Could not find metadata for $url")
}.flatMap { profile ->
feedParser.findNostrFeed(profile)
.map {
it.copy(description = application.applicationContext.getString(R.string.nostr_feed_description, profile.name))
}
}
} else {
Either.catching(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ import com.nononsenseapps.feeder.archmodel.themeOptionsFromString
import com.nononsenseapps.feeder.db.room.Feed
import com.nononsenseapps.feeder.db.room.FeedDao
import com.nononsenseapps.feeder.model.OPMLParserHandler
import com.nononsenseapps.feeder.util.isAdaptedUrlFromNostrUri
import com.nononsenseapps.feeder.util.logDebug
import kotlinx.coroutines.flow.first
import org.kodein.di.DI
import org.kodein.di.DIAware
Expand All @@ -27,22 +25,11 @@ open class OPMLImporter(override val di: DI) : OPMLParserHandler, DIAware {

override suspend fun saveFeed(feed: Feed) {
val existing = feedDao.loadFeedWithUrl(feed.url)
val existingNostrFeeds = feedDao.getAllFeeds().filter { it.url.isAdaptedUrlFromNostrUri() }
// Don't want to remove existing feed on OPML imports
if (existing != null) {
feedDao.updateFeed(feed.copy(id = existing.id))
} else {
if (feed.url.isAdaptedUrlFromNostrUri()) {
val potentialNostrFeed = existingNostrFeeds.find { it.title == feed.title }
if (potentialNostrFeed != null) {
logDebug(LOG_TAG, "Nostr feed with title <${feed.title}> already exists. Updating feed.")
feedDao.updateFeed(feed.copy(id = potentialNostrFeed.id))
} else {
feedDao.insertFeed(feed)
}
} else {
feedDao.insertFeed(feed)
}
feedDao.insertFeed(feed)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.nononsenseapps.feeder.db.room.Feed
import com.nononsenseapps.feeder.model.OPMLParserHandler
import com.nononsenseapps.feeder.util.Either
import com.nononsenseapps.feeder.util.flatMap
import com.nononsenseapps.feeder.util.getOrCreateFromUri
import com.nononsenseapps.feeder.util.isNostrUri
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.withContext
Expand Down Expand Up @@ -249,7 +250,7 @@ class OpmlPullParser(private val opmlToDb: OPMLParserHandler) {
)
try {
val parsedUrlOrUri = parser.getAttributeValue(null, ATTR_XMLURL)
val feedUrl = URL(if (parsedUrlOrUri.isNostrUri()) "https://njump.me/$parsedUrlOrUri" else parsedUrlOrUri)
val feedUrl = URL(parsedUrlOrUri.getOrCreateFromUri())
val feed =
Feed(
// Ensure not both are empty string: title will get replaced on sync
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/nononsenseapps/feeder/ui/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ const val ARG_FEED_FULL_TEXT_BY_DEFAULT = "feed_full_text_by_default"
const val ARG_FEED_OPEN_ARTICLES_WITH = "feed_open_articles_with"
const val ARG_URL = "url"
const val ARG_ONLY_NEW = "only_new"

const val NOSTR_URI_PREFIX = "nostr:"
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.nononsenseapps.feeder.background.runOnceRssSync
import com.nononsenseapps.feeder.base.DIAwareViewModel
import com.nononsenseapps.feeder.db.room.Feed
import com.nononsenseapps.feeder.ui.compose.utils.mutableSavedStateOf
import com.nononsenseapps.feeder.util.getOrCreateFromUri
import com.nononsenseapps.feeder.util.isNostrUri
import com.nononsenseapps.feeder.util.sloppyLinkToStrictURLOrNull
import kotlinx.coroutines.launch
Expand All @@ -31,12 +32,10 @@ class CreateFeedScreenViewModel(
// These three are updated as a result of url/uri updating
override var isNotValidUrl by mutableStateOf(false)
override var isOkToSave: Boolean by mutableStateOf(false)
override var isNostrUri: Boolean by mutableStateOf(false)

override var feedUrl: String by mutableSavedStateOf(state, "") { value ->
isNotValidUrl = !isValidUrl(value)
isNostrUri = value.isNostrUri()
isOkToSave = isValidUrl(value) || isNostrUri
isNotValidUrl = !isValidUrlOrUri(value)
isOkToSave = isValidUrlOrUri(value)
}
override var feedTitle: String by mutableSavedStateOf(state, "")
override var feedTag: String by mutableSavedStateOf(state, "")
Expand Down Expand Up @@ -84,11 +83,11 @@ class CreateFeedScreenViewModel(
val feedId =
repository.saveFeed(
Feed(
url = URL(if (isNostrUri) "https://njump.me/$feedUrl" else feedUrl),
url = URL(feedUrl.getOrCreateFromUri()),
title = feedTitle,
customTitle = feedTitle,
tag = feedTag,
fullTextByDefault = if (isNostrUri) false else fullTextByDefault,
fullTextByDefault = if (feedUrl.isNostrUri()) false else fullTextByDefault,
notify = notify,
skipDuplicates = skipDuplicates,
openArticlesWith = articleOpener,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import com.nononsenseapps.feeder.ui.compose.utils.LocalWindowSizeMetrics
import com.nononsenseapps.feeder.ui.compose.utils.ScreenType
import com.nononsenseapps.feeder.ui.compose.utils.getScreenType
import com.nononsenseapps.feeder.ui.compose.utils.rememberApiPermissionState
import com.nononsenseapps.feeder.util.isNostrUri

@Composable
fun CreateFeedScreen(
Expand Down Expand Up @@ -351,9 +352,9 @@ fun ColumnScope.LeftContent(
value = viewState.feedUrl,
onValueChange = { viewState.feedUrl = it.trim() },
label = {
Text(stringResource(id = R.string.url))
Text(stringResource(id = R.string.url_or_uri))
},
isError = !viewState.isNostrUri && viewState.isNotValidUrl,
isError = viewState.isNotValidUrl,
keyboardOptions =
KeyboardOptions(
capitalization = KeyboardCapitalization.None,
Expand All @@ -376,10 +377,10 @@ fun ColumnScope.LeftContent(
focusManager.moveFocus(FocusDirection.Down)
},
)
AnimatedVisibility(visible = !viewState.isNostrUri && viewState.isNotValidUrl) {
AnimatedVisibility(visible = viewState.isNotValidUrl) {
Text(
textAlign = TextAlign.Center,
text = stringResource(R.string.invalid_url),
text = stringResource(R.string.invalid_url_or_uri),
style = MaterialTheme.typography.labelMedium.copy(color = MaterialTheme.colorScheme.error),
)
}
Expand Down Expand Up @@ -488,8 +489,8 @@ fun ColumnScope.RightContent(
) {
SwitchSetting(
title = stringResource(id = R.string.fetch_full_articles_by_default),
checked = if (viewState.isNostrUri) false else viewState.fullTextByDefault,
enabled = !viewState.isNostrUri,
checked = viewState.fullTextByDefault,
enabled = !viewState.feedUrl.isNostrUri(),
icon = null,
modifier =
Modifier
Expand Down Expand Up @@ -571,7 +572,6 @@ interface EditFeedScreenState {
var articleOpener: String
var alternateId: Boolean
val isOkToSave: Boolean
val isNostrUri: Boolean
val isNotValidUrl: Boolean
val isOpenItemWithBrowser: Boolean
val isOpenItemWithCustomTab: Boolean
Expand All @@ -586,7 +586,6 @@ fun EditFeedScreenState(): EditFeedScreenState = ScreenState()

private class ScreenState(
override val isOkToSave: Boolean = false,
override val isNostrUri: Boolean = false,
override val isNotValidUrl: Boolean = false,
override val isOpenItemWithBrowser: Boolean = false,
override val isOpenItemWithCustomTab: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.nononsenseapps.feeder.background.runOnceRssSync
import com.nononsenseapps.feeder.base.DIAwareViewModel
import com.nononsenseapps.feeder.db.room.Feed
import com.nononsenseapps.feeder.ui.compose.utils.mutableSavedStateOf
import com.nononsenseapps.feeder.util.getOrCreateFromUri
import com.nononsenseapps.feeder.util.isNostrUri
import kotlinx.coroutines.launch
import org.kodein.di.DI
Expand All @@ -34,12 +35,10 @@ class EditFeedScreenViewModel(
// These two are updated as a result of url updating
override var isNotValidUrl by mutableStateOf(false)
override var isOkToSave: Boolean by mutableStateOf(false)
override var isNostrUri: Boolean by mutableStateOf(false)

override var feedUrl: String by mutableSavedStateOf(state, "") { value ->
isNotValidUrl = !isValidUrl(value)
isNostrUri = value.isNostrUri()
isOkToSave = isValidUrl(value) || isNostrUri
isNotValidUrl = !isValidUrlOrUri(value)
isOkToSave = isValidUrlOrUri(value)
}
override var feedTitle: String by mutableSavedStateOf(state, "")
override var feedTag: String by mutableSavedStateOf(state, "")
Expand Down Expand Up @@ -126,11 +125,11 @@ class EditFeedScreenViewModel(

val updatedFeed =
feed.copy(
url = URL(if (isNostrUri) "https://njump.me/$feedUrl" else feedUrl),
url = URL(feedUrl.getOrCreateFromUri()),
title = feedTitle,
customTitle = feedTitle,
tag = feedTag,
fullTextByDefault = if (isNostrUri) false else fullTextByDefault,
fullTextByDefault = if (feedUrl.isNostrUri()) false else fullTextByDefault,
notify = notify,
skipDuplicates = skipDuplicates,
openArticlesWith = articleOpener,
Expand All @@ -156,10 +155,14 @@ class EditFeedScreenViewModel(
}
}

internal fun isValidUrl(value: String): Boolean {
internal fun isValidUrlOrUri(value: String): Boolean {
return try {
URL(value)
true
if (value.isNostrUri()) {
true
} else {
URL(value)
true
}
} catch (e: Exception) {
false
}
Expand Down
Loading

0 comments on commit 5d501d6

Please sign in to comment.