Repositories refactoring and merge

This commit is contained in:
Arty Bishop committed 2021-05-16 19:13:10 +01:00
1 parent 1a59b5e3e1
commit 0110de8104
28 files changed
+309 -577

No files matched your search

@@ -10,13 +10,13 @@ interface LocalDataSource {
fun getSatItems(): Flow<List<SatItem>>
fun getSatTransmitters(catNum: Int): Flow<List<SatTrans>>
suspend fun getSelectedSatellites(): List<Satellite>
suspend fun updateEntries(entries: List<SatEntry>)
suspend fun updateEntriesSelection(catNums: List<Int>, isSelected: Boolean)
fun getTransmittersForSat(catNum: Int): Flow<List<SatTrans>>
suspend fun updateTransmitters(satelliteTrans: List<SatTrans>)
}
@@ -1,35 +0,0 @@
package com.rtbishop.look4sat.data
import com.rtbishop.look4sat.domain.predict4kotlin.QthConverter
import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition
class LocationRepo(
private val locationSource: LocationSource,
private val qthConverter: QthConverter
) {
fun getStationPosition(): StationPosition {
return locationSource.loadStationPosition()
}
fun getMagDeclination(): Float {
return locationSource.getMagDeclination(getStationPosition())
}
fun positionToQTH(lat: Double, lon: Double): String? {
return qthConverter.positionToQTH(lat, lon)
}
fun updatePositionFromGPS(): Boolean {
val stationPosition = locationSource.getLastKnownLocation() ?: return false
locationSource.saveStationPosition(stationPosition)
return true
}
fun updatePositionFromQTH(qthString: String): Boolean {
val position = qthConverter.qthToPosition(qthString) ?: return false
val stationPosition = StationPosition(position.latitude, position.longitude, 0.0)
locationSource.saveStationPosition(stationPosition)
return true
}
}
@@ -1,14 +0,0 @@
package com.rtbishop.look4sat.data
import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition
interface LocationSource {
fun getLastKnownLocation(): StationPosition?
fun getMagDeclination(position: StationPosition): Float
fun loadStationPosition(): StationPosition
fun saveStationPosition(position: StationPosition)
}
@@ -0,0 +1,71 @@
/*
* Look4Sat. Amateur radio satellite tracker and pass predictor.
* Copyright (C) 2019-2021 Arty Bishop (bishop.arty@gmail.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.rtbishop.look4sat.data
import com.rtbishop.look4sat.domain.predict4kotlin.SatPass
import com.rtbishop.look4sat.domain.predict4kotlin.Satellite
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.withContext
import java.util.*
class PassesRepo(
private val preferenceSource: PreferenceSource,
private val defaultDispatcher: CoroutineDispatcher
) {
private val _passes = MutableSharedFlow<List<SatPass>>(replay = 1)
private var selectedSatellites = emptyList<Satellite>()
val passes: SharedFlow<List<SatPass>> = _passes
suspend fun triggerCalculation(satellites: List<Satellite>, refDate: Date = Date()) {
if (satellites.isEmpty()) {
_passes.emit(emptyList())
} else {
val oldCatNums = selectedSatellites.map { it.tle.catnum }
val newCatNums = satellites.map { it.tle.catnum }
if (oldCatNums != newCatNums) forceCalculation(satellites, refDate)
}
}
suspend fun forceCalculation(satellites: List<Satellite>, refDate: Date = Date()) {
if (satellites.isEmpty()) {
_passes.emit(emptyList())
} else {
withContext(defaultDispatcher) {
val allPasses = mutableListOf<SatPass>()
selectedSatellites = satellites
satellites.forEach { satellite -> allPasses.addAll(getPasses(satellite, refDate)) }
_passes.emit(filterPasses(allPasses, refDate))
}
}
}
private fun getPasses(satellite: Satellite, refDate: Date): List<SatPass> {
val predictor = satellite.getPredictor(preferenceSource.loadStationPosition())
return predictor.getPasses(refDate, preferenceSource.getHoursAhead(), true)
}
private fun filterPasses(passes: List<SatPass>, refDate: Date): List<SatPass> {
val timeFuture = Date(refDate.time + (preferenceSource.getHoursAhead() * 3600 * 1000))
return passes.filter { it.losDate.after(refDate) }
.filter { it.aosDate.before(timeFuture) }
.filter { it.maxElevation > preferenceSource.getMinElevation() }
.sortedBy { it.aosDate }
}
}
@@ -0,0 +1,38 @@
package com.rtbishop.look4sat.data
import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition
interface PreferenceSource {
fun positionToQTH(lat: Double, lon: Double): String?
fun loadStationPosition(): StationPosition
fun saveStationPosition(position: StationPosition)
fun updatePositionFromGPS(): Boolean
fun updatePositionFromQTH(qthString: String): Boolean
fun getMagDeclination(): Float
fun getHoursAhead(): Int
fun getMinElevation(): Double
fun shouldUseTextLabels(): Boolean
fun shouldUseUTC(): Boolean
fun shouldUseCompass(): Boolean
fun isFirstLaunch(): Boolean
fun setFirstLaunchDone()
fun saveModesSelection(modes: List<String>)
fun loadModesSelection(): List<String>
fun getRotatorServer(): Pair<String, Int>?
}
@@ -22,24 +22,23 @@ class SatelliteRepo(
return localSource.getSatItems()
}
fun getTransmittersForSat(catNum: Int): Flow<List<SatTrans>> {
return localSource.getTransmittersForSat(catNum)
fun getSatTransmitters(catNum: Int): Flow<List<SatTrans>> {
return localSource.getSatTransmitters(catNum)
}
suspend fun getSelectedSatellites(): List<Satellite> {
return localSource.getSelectedSatellites()
}
suspend fun importDataFromStream(stream: InputStream) = withContext(ioDispatcher) {
val importedEntries = Satellite.importElements(stream).map { tle -> SatEntry(tle) }
localSource.updateEntries(importedEntries)
suspend fun updateEntriesFromFile(stream: InputStream) = withContext(ioDispatcher) {
localSource.updateEntries(importSatEntries(stream))
}
suspend fun importDataFromWeb(sources: List<String>) {
suspend fun updateEntriesFromWeb(sources: List<String>) {
coroutineScope {
launch(ioDispatcher) {
val importedEntries = mutableListOf<SatEntry>()
val streams = mutableListOf<InputStream>()
val entries = mutableListOf<SatEntry>()
sources.forEach { source ->
remoteSource.fetchDataStream(source)?.let { stream ->
if (source.contains(".zip", true)) {
@@ -50,11 +49,8 @@ class SatelliteRepo(
}
}
}
streams.forEach { stream ->
val entries = Satellite.importElements(stream).map { tle -> SatEntry(tle) }
importedEntries.addAll(entries)
}
localSource.updateEntries(importedEntries)
streams.forEach { stream -> entries.addAll(importSatEntries(stream)) }
localSource.updateEntries(entries)
}
launch(ioDispatcher) {
val transmitters = remoteSource.fetchTransmitters().filter { it.isAlive }
@@ -66,4 +62,8 @@ class SatelliteRepo(
suspend fun updateEntriesSelection(catNums: List<Int>, isSelected: Boolean) {
localSource.updateEntriesSelection(catNums, isSelected)
}
private fun importSatEntries(stream: InputStream): List<SatEntry> {
return Satellite.importElements(stream).map { tle -> SatEntry(tle) }
}
}
@@ -4,9 +4,9 @@ import com.rtbishop.look4sat.data.SatelliteRepo
import com.rtbishop.look4sat.domain.model.SatTrans
import kotlinx.coroutines.flow.Flow
class GetTransmittersForSat(private val satelliteRepo: SatelliteRepo) {
class GetSatTransmitters(private val satelliteRepo: SatelliteRepo) {
operator fun invoke(catNum: Int): Flow<List<SatTrans>> {
return satelliteRepo.getTransmittersForSat(catNum)
return satelliteRepo.getSatTransmitters(catNum)
}
}
@@ -1,10 +0,0 @@
package com.rtbishop.look4sat.interactors
import com.rtbishop.look4sat.data.SatelliteRepo
class ImportDataFromWeb(private val satelliteRepo: SatelliteRepo) {
suspend operator fun invoke(sources: List<String>) {
satelliteRepo.importDataFromWeb(sources)
}
}
@@ -3,9 +3,9 @@ package com.rtbishop.look4sat.interactors
import com.rtbishop.look4sat.data.SatelliteRepo
import java.io.InputStream
class ImportDataFromStream(private val satelliteRepo: SatelliteRepo) {
class UpdateEntriesFromFile(private val satelliteRepo: SatelliteRepo) {
suspend operator fun invoke(stream: InputStream) {
satelliteRepo.importDataFromStream(stream)
satelliteRepo.updateEntriesFromFile(stream)
}
}
@@ -0,0 +1,17 @@
package com.rtbishop.look4sat.interactors
import com.rtbishop.look4sat.data.SatelliteRepo
class UpdateEntriesFromWeb(private val satelliteRepo: SatelliteRepo) {
private val defaultSources = listOf(
"https://celestrak.com/NORAD/elements/active.txt",
"https://amsat.org/tle/current/nasabare.txt",
"https://www.prismnet.com/~mmccants/tles/classfd.zip",
"https://www.prismnet.com/~mmccants/tles/inttles.zip"
)
suspend operator fun invoke(sources: List<String> = defaultSources) {
satelliteRepo.updateEntriesFromWeb(sources)
}
}