-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
60 changed files
with
963 additions
and
289 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
api/src/main/kotlin/nebulosa/api/data/entities/TLEEntity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package nebulosa.api.data.entities | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnore | ||
import io.objectbox.annotation.Entity | ||
import io.objectbox.annotation.Id | ||
import io.objectbox.annotation.Index | ||
|
||
@Entity | ||
data class TLEEntity( | ||
@Id(assignable = true) var id: Long = 0L, | ||
@JsonIgnore @Index var source: Long = 0L, | ||
var name: String = "", | ||
var tle: String = "", | ||
) { | ||
|
||
companion object { | ||
|
||
@JvmStatic | ||
fun from(source: TLESourceEntity, lines: List<String>): TLEEntity { | ||
val name = lines[0] | ||
val id = lines[1].substring(2..6).toLong() | ||
val tle = lines.joinToString("\n") | ||
return TLEEntity(id, source.id, name, tle) | ||
} | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
api/src/main/kotlin/nebulosa/api/data/entities/TLESourceEntity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package nebulosa.api.data.entities | ||
|
||
import io.objectbox.annotation.Entity | ||
import io.objectbox.annotation.Id | ||
import io.objectbox.annotation.Index | ||
|
||
@Entity | ||
data class TLESourceEntity( | ||
@Id var id: Long = 0L, | ||
@Index var url: String = "", | ||
var updatedAt: Long = 0, | ||
var enabled: Boolean = true, | ||
var deletable: Boolean = false, | ||
) |
43 changes: 43 additions & 0 deletions
43
api/src/main/kotlin/nebulosa/api/data/serializers/GuiderSerializer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package nebulosa.api.data.serializers | ||
|
||
import com.fasterxml.jackson.core.JsonGenerator | ||
import com.fasterxml.jackson.databind.SerializerProvider | ||
import com.fasterxml.jackson.databind.ser.std.StdSerializer | ||
import nebulosa.guiding.GuidePoint | ||
import nebulosa.guiding.Guider | ||
import org.springframework.beans.factory.annotation.Qualifier | ||
import org.springframework.stereotype.Component | ||
|
||
@Component | ||
@Qualifier("serializer") | ||
class GuiderSerializer : StdSerializer<Guider>(Guider::class.java) { | ||
|
||
override fun serialize( | ||
guider: Guider, | ||
gen: JsonGenerator, | ||
provider: SerializerProvider, | ||
) { | ||
gen.writeStartObject() | ||
gen.writeFieldName("lockPosition") | ||
gen.writeGuidePoint(guider.lockPosition) | ||
gen.writeFieldName("primaryStar") | ||
gen.writeGuidePoint(guider.primaryStar) | ||
gen.writeNumberField("searchRegion", guider.searchRegion) | ||
gen.writeBooleanField("looping", guider.isLooping) | ||
gen.writeBooleanField("calibrating", guider.isCalibrating) | ||
gen.writeBooleanField("guiding", guider.isGuiding) | ||
gen.writeEndObject() | ||
} | ||
|
||
companion object { | ||
|
||
@JvmStatic | ||
private fun JsonGenerator.writeGuidePoint(point: GuidePoint) { | ||
writeStartObject() | ||
writeNumberField("x", point.x) | ||
writeNumberField("y", point.y) | ||
writeBooleanField("valid", point.valid) | ||
writeEndObject() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
123 changes: 123 additions & 0 deletions
123
api/src/main/kotlin/nebulosa/api/repositories/TLERepository.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package nebulosa.api.repositories | ||
|
||
import io.objectbox.BoxStore | ||
import io.objectbox.query.QueryBuilder.StringOrder.CASE_INSENSITIVE | ||
import jakarta.annotation.PostConstruct | ||
import nebulosa.api.data.entities.TLEEntity | ||
import nebulosa.api.data.entities.TLEEntity_ | ||
import nebulosa.api.data.entities.TLESourceEntity | ||
import nebulosa.log.loggerFor | ||
import okhttp3.OkHttpClient | ||
import okhttp3.Request | ||
import org.springframework.stereotype.Service | ||
import java.io.ByteArrayInputStream | ||
import java.io.InputStream | ||
import java.util.concurrent.CompletableFuture | ||
import java.util.concurrent.ExecutorService | ||
import java.util.function.Supplier | ||
|
||
@Service | ||
class TLERepository( | ||
boxStore: BoxStore, | ||
private val tleSourceRepository: TLESourceRepository, | ||
private val systemExecutorService: ExecutorService, | ||
private val okHttpClient: OkHttpClient, | ||
) : BoxRepository<TLEEntity>() { | ||
|
||
override val box = boxStore.boxFor(TLEEntity::class.java)!! | ||
|
||
fun sources() = tleSourceRepository.all() | ||
|
||
fun withSources(source: TLESourceEntity): List<TLEEntity> = box.query() | ||
.equal(TLEEntity_.source, source.id) | ||
.build() | ||
.find() | ||
|
||
fun withName(name: String): List<TLEEntity> = box.query() | ||
.let { if (name.isBlank()) it else it.contains(TLEEntity_.name, name, CASE_INSENSITIVE) } | ||
.order(TLEEntity_.name) | ||
.build() | ||
.find() | ||
|
||
fun deleteWithSource(source: TLESourceEntity) = box.query() | ||
.equal(TLEEntity_.source, source.id) | ||
.build() | ||
.remove() | ||
|
||
@PostConstruct | ||
fun updateIfOld() { | ||
val currentTime = System.currentTimeMillis() | ||
|
||
for (source in sources()) { | ||
if (source.enabled && currentTime - source.updatedAt >= TLE_UPDATE_INTERVAL) { | ||
deleteWithSource(source) | ||
|
||
CompletableFuture | ||
.supplyAsync(TLEUpdater(source), systemExecutorService) | ||
.whenComplete { entities, e -> | ||
e?.printStackTrace() | ||
|
||
if (!entities.isNullOrEmpty()) { | ||
saveAll(entities) | ||
|
||
source.updatedAt = System.currentTimeMillis() | ||
tleSourceRepository.save(source) | ||
|
||
LOG.info("updated {} satellites from {}", entities.size, source.url) | ||
} | ||
} | ||
} else if (!source.enabled) { | ||
deleteWithSource(source) | ||
} | ||
} | ||
} | ||
|
||
private inner class TLEUpdater(private val source: TLESourceEntity) : Supplier<List<TLEEntity>> { | ||
|
||
override fun get(): List<TLEEntity> { | ||
val request = Request.Builder() | ||
.get() | ||
.url(source.url) | ||
.build() | ||
|
||
return okHttpClient.newCall(request) | ||
.execute().use { | ||
if (it.isSuccessful) { | ||
source.parseTLEFile(it.body.byteStream()) | ||
} else { | ||
emptyList() | ||
} | ||
} | ||
} | ||
} | ||
|
||
companion object { | ||
|
||
const val TLE_UPDATE_INTERVAL = 1000L * 60 * 60 * 72 // 72 hours in ms | ||
|
||
@JvmStatic private val LOG = loggerFor<TLERepository>() | ||
|
||
@JvmStatic | ||
internal fun TLESourceEntity.parseTLEFile(data: ByteArray): List<TLEEntity> { | ||
return parseTLEFile(ByteArrayInputStream(data)) | ||
} | ||
|
||
@JvmStatic | ||
internal fun TLESourceEntity.parseTLEFile(data: InputStream): List<TLEEntity> { | ||
val entities = ArrayList<TLEEntity>(128) | ||
val lines = ArrayList<String>(3) | ||
|
||
for (line in data.bufferedReader().lines()) { | ||
lines.add(line) | ||
|
||
if (lines.size == 3) { | ||
val tle = TLEEntity.from(this, lines) | ||
lines.clear() | ||
entities.add(tle) | ||
} | ||
} | ||
|
||
return entities | ||
} | ||
} | ||
} |
Oops, something went wrong.