mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Added the ability to fully customize data sources via import
This commit is contained in:
1 parent
24eebdef74
commit
2f4e3f5802
12 files changed
+190
-213
No files matched your search
@@ -23,7 +23,6 @@ import com.rtbishop.look4sat.core.domain.repository.IDatabaseRepo
|
||||
import com.rtbishop.look4sat.core.domain.repository.ISettingsRepo
|
||||
import com.rtbishop.look4sat.core.domain.source.ILocalSource
|
||||
import com.rtbishop.look4sat.core.domain.source.IRemoteSource
|
||||
import com.rtbishop.look4sat.core.domain.source.Sources
|
||||
import com.rtbishop.look4sat.core.domain.utility.DataParser
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.async
|
||||
@@ -40,7 +39,6 @@ class DatabaseRepo(
|
||||
private val settingsRepo: ISettingsRepo
|
||||
) : IDatabaseRepo {
|
||||
|
||||
private val customSourceType = "Other"
|
||||
|
||||
override suspend fun updateTLEFromFile(uri: String): Int = withContext(dispatcher) {
|
||||
var importedCount = 0
|
||||
@@ -65,18 +63,13 @@ class DatabaseRepo(
|
||||
}
|
||||
|
||||
override suspend fun updateFromRemote() = withContext(dispatcher) {
|
||||
val dataSourcesSettings = settingsRepo.dataSourcesSettings.value
|
||||
val tleUrls = buildMap {
|
||||
putAll(Sources.satelliteDataUrls)
|
||||
if (dataSourcesSettings.useCustomTLE) put(customSourceType, dataSourcesSettings.tleUrl)
|
||||
}.filterValues { it.isNotBlank() }
|
||||
val radioUrls = buildMap {
|
||||
putAll(Sources.transceiversDataUrls)
|
||||
if (dataSourcesSettings.useCustomTransceivers) put(customSourceType, dataSourcesSettings.transceiversUrl)
|
||||
}.filterValues { it.isNotBlank() }
|
||||
val settings = settingsRepo.dataSourcesSettings.value
|
||||
fun normalizeUrl(url: String) = if (url.startsWith("http")) url else "https://$url"
|
||||
val tleUrls = settings.satelliteUrls.filter { it.isNotBlank() }.map(::normalizeUrl)
|
||||
val radioUrls = settings.transceiversUrls.filter { it.isNotBlank() }.map(::normalizeUrl)
|
||||
// launch all network requests concurrently
|
||||
val tleJobs = tleUrls.values.map { url -> async { url to remoteSource.getNetworkStream(url) } }
|
||||
val radioJobs = radioUrls.values.map { url -> async { url to remoteSource.getNetworkStream(url) } }
|
||||
val tleJobs = tleUrls.map { url -> async { url to remoteSource.getNetworkStream(url) } }
|
||||
val radioJobs = radioUrls.map { url -> async { url to remoteSource.getNetworkStream(url) } }
|
||||
// parse fetched data concurrently
|
||||
val importedEntries = tleJobs.awaitAll().flatMap { (url, stream) ->
|
||||
stream?.let { parseSatelliteStream(url, unwrapIfZipped(url, it)) }.orEmpty()
|
||||
|
||||
+12
-12
@@ -31,6 +31,7 @@ import com.rtbishop.look4sat.core.domain.model.RCSettings
|
||||
import com.rtbishop.look4sat.core.domain.model.RadioControlSettings
|
||||
import com.rtbishop.look4sat.core.domain.predict.GeoPos
|
||||
import com.rtbishop.look4sat.core.domain.repository.ISettingsRepo
|
||||
import com.rtbishop.look4sat.core.domain.source.Sources
|
||||
import com.rtbishop.look4sat.core.domain.utility.positionToQth
|
||||
import com.rtbishop.look4sat.core.domain.utility.qthToPosition
|
||||
import com.rtbishop.look4sat.core.domain.utility.round
|
||||
@@ -89,11 +90,10 @@ class SettingsRepo(
|
||||
private val keyHighElevation = "highElevation"
|
||||
private val keyRadarCompassOffset = "radarCompassOffset"
|
||||
private val keyRadarCompassOffsetElev = "radarCompassOffsetElev"
|
||||
private val keyUseCustomTle = "useCustomTle"
|
||||
private val keyUseCustomTransceivers = "useCustomTransceivers"
|
||||
private val keyTleUrl = "tleUrl"
|
||||
private val keyTransceiversUrl = "transceiversUrl"
|
||||
private val keySatelliteUrls = "satelliteUrls"
|
||||
private val keyTransceiversUrls = "transceiversUrls"
|
||||
private val separatorComma = ","
|
||||
private val separatorUrl = "\n"
|
||||
|
||||
//region # Satellites selection settings
|
||||
private val _satelliteSelection = MutableStateFlow(getSelectedIds())
|
||||
@@ -365,19 +365,19 @@ class SettingsRepo(
|
||||
|
||||
override fun updateDataSourcesSettings(settings: DataSourcesSettings) {
|
||||
preferences.edit {
|
||||
putBoolean(keyUseCustomTle, settings.useCustomTLE)
|
||||
putBoolean(keyUseCustomTransceivers, settings.useCustomTransceivers)
|
||||
putString(keyTleUrl, settings.tleUrl)
|
||||
putString(keyTransceiversUrl, settings.transceiversUrl)
|
||||
putString(keySatelliteUrls, settings.satelliteUrls.joinToString(separatorUrl))
|
||||
putString(keyTransceiversUrls, settings.transceiversUrls.joinToString(separatorUrl))
|
||||
}
|
||||
_dataSourcesSettings.value = settings
|
||||
}
|
||||
|
||||
private fun getDataSourcesSettings(): DataSourcesSettings = DataSourcesSettings(
|
||||
useCustomTLE = preferences.getBoolean(keyUseCustomTle, false),
|
||||
useCustomTransceivers = preferences.getBoolean(keyUseCustomTransceivers, false),
|
||||
tleUrl = preferences.getString(keyTleUrl, "https://example.com/tle.txt") ?: "",
|
||||
transceiversUrl = preferences.getString(keyTransceiversUrl, "https://example.com/radio.json") ?: ""
|
||||
satelliteUrls = preferences.getString(keySatelliteUrls, null)
|
||||
?.split(separatorUrl)?.filter { it.isNotBlank() }
|
||||
?: Sources.satelliteDataUrls,
|
||||
transceiversUrls = preferences.getString(keyTransceiversUrls, null)
|
||||
?.split(separatorUrl)?.filter { it.isNotBlank() }
|
||||
?: Sources.transceiversDataUrls
|
||||
)
|
||||
//endregion
|
||||
|
||||
|
||||
+4
-8
@@ -90,10 +90,8 @@ class DatabaseRepoTest {
|
||||
}
|
||||
val settingsRepo = FakeSettingsRepo(
|
||||
dataSources = DataSourcesSettings(
|
||||
useCustomTLE = true,
|
||||
useCustomTransceivers = false,
|
||||
tleUrl = customCsvUrl,
|
||||
transceiversUrl = ""
|
||||
satelliteUrls = listOf(customCsvUrl),
|
||||
transceiversUrls = emptyList()
|
||||
)
|
||||
)
|
||||
val repository = DatabaseRepo(dispatcher, dataParser, localSource, remoteSource, settingsRepo)
|
||||
@@ -221,9 +219,7 @@ private class FakeSettingsRepo(dataSources: DataSourcesSettings = defaultDataSou
|
||||
|
||||
private fun defaultDataSourcesSettings(): DataSourcesSettings {
|
||||
return DataSourcesSettings(
|
||||
useCustomTLE = false,
|
||||
useCustomTransceivers = false,
|
||||
tleUrl = "",
|
||||
transceiversUrl = ""
|
||||
satelliteUrls = emptyList(),
|
||||
transceiversUrls = emptyList()
|
||||
)
|
||||
}
|
||||
+1
-1
@@ -135,7 +135,7 @@ class SelectionRepoTest {
|
||||
)
|
||||
|
||||
override val dataSourcesSettings: StateFlow<DataSourcesSettings> = MutableStateFlow(
|
||||
DataSourcesSettings(false, false, "", "")
|
||||
DataSourcesSettings(emptyList(), emptyList())
|
||||
)
|
||||
|
||||
override val radioControlSettings: StateFlow<RadioControlSettings> = MutableStateFlow(
|
||||
|
||||
@@ -67,10 +67,8 @@ data class OtherSettings(
|
||||
)
|
||||
|
||||
data class DataSourcesSettings(
|
||||
val useCustomTLE: Boolean,
|
||||
val useCustomTransceivers: Boolean,
|
||||
val tleUrl: String,
|
||||
val transceiversUrl: String
|
||||
val satelliteUrls: List<String>,
|
||||
val transceiversUrls: List<String>
|
||||
)
|
||||
|
||||
data class RadioControlSettings(
|
||||
|
||||
@@ -18,18 +18,17 @@
|
||||
package com.rtbishop.look4sat.core.domain.source
|
||||
|
||||
object Sources {
|
||||
val satelliteDataUrls = mapOf(
|
||||
"CelesTrak" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=active&FORMAT=csv",
|
||||
"AMSAT" to "https://amsat.org/tle/current/nasabare.txt",
|
||||
"McCants Classified" to "https://www.mmccants.org/tles/classfd.zip",
|
||||
"McCants Integrated" to "https://www.mmccants.org/tles/inttles.zip",
|
||||
"R4UAB" to "https://r4uab.ru/satonline.txt",
|
||||
"SatNOGS" to "https://db.satnogs.org/api/tle/?format=3le",
|
||||
"ARISS" to "https://live.ariss.org/iss.txt",
|
||||
"Other" to "" // key for sats filter
|
||||
val satelliteDataUrls = listOf(
|
||||
"celestrak.org/NORAD/elements/gp.php?GROUP=active&FORMAT=csv",
|
||||
"db.satnogs.org/api/tle/?format=3le",
|
||||
"amsat.org/tle/current/nasabare.txt",
|
||||
"mmccants.org/tles/classfd.zip",
|
||||
"r4uab.ru/satonline.txt",
|
||||
"live.ariss.org/iss.txt"
|
||||
)
|
||||
val transceiversDataUrls = mapOf(
|
||||
"SatNOGS" to "https://db.satnogs.org/api/transmitters/?format=json&status=active"
|
||||
val transceiversDataUrls = listOf(
|
||||
"db.satnogs.org/api/transmitters/?format=json&status=active",
|
||||
"r4uab.ru/transmitters.json"
|
||||
)
|
||||
val satelliteModes = listOf(
|
||||
"4FSK", "64-QAM", "AFSK", "AFSK TUBiX10", "AHRPT", "AM", "APT", "ASK", "BPSK",
|
||||
|
||||
+7
-2
@@ -239,8 +239,13 @@ fun CardButton(onClick: () -> Unit, text: String, modifier: Modifier = Modifier)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun IconCard(action: () -> Unit, resId: Int, modifier: Modifier = Modifier, enabled: Boolean = true) {
|
||||
ElevatedCard(modifier = Modifier.size(48.dp), enabled = enabled, onClick = action) {
|
||||
fun IconCard(
|
||||
action: () -> Unit, resId: Int, modifier: Modifier = Modifier,
|
||||
enabled: Boolean = true, containerColor: Color = Color.Unspecified
|
||||
) {
|
||||
val colors = if (containerColor == Color.Unspecified) CardDefaults.elevatedCardColors()
|
||||
else CardDefaults.elevatedCardColors(containerColor = containerColor)
|
||||
ElevatedCard(modifier = Modifier.size(48.dp), enabled = enabled, onClick = action, colors = colors) {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
Icon(painter = painterResource(resId), contentDescription = null, modifier = modifier)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M440,520L200,520L200,440L440,440L440,200L520,200L520,440L760,440L760,520L520,520L520,760L440,760L440,520Z" />
|
||||
</vector>
|
||||
@@ -172,10 +172,7 @@
|
||||
<string name="prefs_data_import_satellites_error">No satellites imported. Select a valid TLE/3LE (.txt) or OMM (.csv) file.</string>
|
||||
<string name="prefs_data_import_transceivers_error">No transceivers imported. Select a valid SatNOGS (.json) file.</string>
|
||||
|
||||
<string name="prefs_data_sources_title">Custom sources</string>
|
||||
<string name="prefs_data_sources_tle_switch">TLE URL</string>
|
||||
<string name="prefs_data_sources_transceivers_switch">Transceivers URL</string>
|
||||
<string name="prefs_data_sources_url_title" translatable="false">URL (HTTPS)</string>
|
||||
<string name="prefs_data_sources_title">Data sources</string>
|
||||
|
||||
<string name="prefs_data_output_title">Data output</string>
|
||||
<string name="prefs_net_output">Network</string>
|
||||
|
||||
Reference in new issue
Block a user