mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-04 11:37:22 +00:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbe3e50f86 | ||
|
|
38b29e3015 | ||
|
|
1a3a05c8b6 | ||
|
|
1e33a10fb4 | ||
|
|
6546e32360 |
No files matched your search
@@ -112,6 +112,17 @@ transition to OMM/CSV automatically.
|
||||
- `build-logic/convention/` contains all shared Gradle configuration — edit there, not in individual modules.
|
||||
- ProGuard is enabled for release builds — don't add reflection-based libs or any other dependencies without asking.
|
||||
|
||||
## Release Notes Must Be Bilingual (BA7OPF fork convention)
|
||||
|
||||
Every GitHub release body carries **two sections — English first, then Chinese** (`## <tag>` each),
|
||||
listing only that release's changes, in the same order with the same claims and the same numbers.
|
||||
Both sections end with the verification line (which unit tests ran, APK signature / ABI check).
|
||||
A single-language body is a defect: fix it before the release counts as done.
|
||||
|
||||
中文规则:每次 release 的说明必须**中英双语,先英文后中文**,两段一一对应(同一顺序、同一结论、
|
||||
同一数字,不做自由意译),只列本版改动;两段末尾都写验证情况(跑了哪些单测、签名/ABI 校验)。
|
||||
只写一种语言视为缺陷,需补齐后再算发布完成。
|
||||
|
||||
## Copilot Working Mode: Code-Only
|
||||
|
||||
- Default to code changes only. Provide explanations in chat only.
|
||||
|
||||
@@ -51,7 +51,15 @@ class SelectionRepo(
|
||||
null // null = no filtering
|
||||
} else {
|
||||
val ids = resolveTypeIds(types)
|
||||
if (ids.isEmpty()) emptySet() else ids.toHashSet()
|
||||
when {
|
||||
ids.isNotEmpty() -> ids.toHashSet()
|
||||
// "All" is the CelesTrak active group, i.e. the whole catalogue: an empty
|
||||
// persisted list must mean "no filtering" (show every satellite), not an
|
||||
// empty list. Its list can be empty simply because CelesTrak answered 403
|
||||
// to a repeated download inside the 2-hour update window.
|
||||
Sources.allSourceType in types -> null
|
||||
else -> emptySet()
|
||||
}
|
||||
}
|
||||
currentItems.map { items ->
|
||||
if (catnumSet == null) items else items.filter { it.catnum in catnumSet }
|
||||
|
||||
+21
@@ -23,6 +23,7 @@ import com.rtbishop.look4sat.core.domain.predict.OrbitalObject
|
||||
import com.rtbishop.look4sat.core.domain.repository.ISelectionRepo
|
||||
import com.rtbishop.look4sat.core.domain.repository.ISettingsRepo
|
||||
import com.rtbishop.look4sat.core.domain.source.ILocalSource
|
||||
import com.rtbishop.look4sat.core.domain.source.Sources
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -241,6 +242,26 @@ class SelectionRepoSearchTest {
|
||||
assertEquals(sampleItems.map { it.catnum }.toSet(), results.map { it.catnum }.toSet())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `All with empty persisted ids falls back to no filtering`() = runTest {
|
||||
// CelesTrak answers 403 to a repeated download inside its 2-hour update window,
|
||||
// so the persisted "All" id list can be empty. Selecting All then means "all
|
||||
// satellites" (no filtering) instead of blanking the list.
|
||||
val repo = createRepo(sampleItems)
|
||||
repo.setTypes(listOf(Sources.allSourceType))
|
||||
val results = repo.getEntriesFlow().first()
|
||||
assertEquals(sampleItems.map { it.catnum }.toSet(), results.map { it.catnum }.toSet())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `other source type with empty persisted ids still shows empty`() = runTest {
|
||||
// Only "All" falls back to no filtering; a regular source without persisted ids
|
||||
// keeps the previous behaviour (empty list).
|
||||
val repo = createRepo(sampleItems)
|
||||
repo.setTypes(listOf("Amateur"))
|
||||
assertTrue(repo.getEntriesFlow().first().isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getTypesList excludes only the Other placeholder`() = runTest {
|
||||
val repo = createRepo(sampleItems)
|
||||
|
||||
@@ -18,41 +18,32 @@
|
||||
package com.rtbishop.look4sat.core.domain.source
|
||||
|
||||
object Sources {
|
||||
// Default TLE sources, aligned with upstream's "most specific to most generic" order:
|
||||
// the first source that knows a satellite gets to name it, with the full catalogue
|
||||
// (CelesTrak active) as the fallback. Upstream dropped the old CelesTrak category
|
||||
// groups (amateur/cubesat/weather/...) — a single `active` group covers them and keeps
|
||||
// the request count (and CelesTrak's 2-hourly "already downloaded" 403s) down.
|
||||
// The three BA7OPF additions keep their own spots: Kaggle LAPAN-A2 first and the two
|
||||
// AutoTLE mirrors next to R4UAB (Chinese amateur catalogues, freshest for CN sats).
|
||||
val satelliteDataUrls = mapOf(
|
||||
"LAPAN-A2" to "https://www.kaggle.com/api/v1/datasets/download/muazamnugroho/lapan-a2-satellite-two-line-element-tle-dataset/LAPAN-A2_TLE_latest.txt",
|
||||
"ARISS" to "https://live.ariss.org/iss.txt",
|
||||
"R4UAB" to "https://r4uab.ru/satonline.txt",
|
||||
"BI4PYM AutoTLE (GitHub)" to "https://raw.githubusercontent.com/BI4PYM/AutoTLE/refs/heads/master/AutoTLE.txt",
|
||||
"BI4PYM AutoTLE (Mirror)" to "https://autotle.bi4pym.cn/AutoTLE.txt",
|
||||
"Classified" to "https://www.mmccants.org/tles/classfd.zip",
|
||||
"Amsat" to "https://amsat.org/tle/current/nasabare.txt",
|
||||
"All" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=active&FORMAT=csv",
|
||||
"SatNOGS" to "https://db.satnogs.org/api/tle/?format=3le",
|
||||
"Amateur" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=amateur&FORMAT=csv",
|
||||
"Brightest" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=visual&FORMAT=csv",
|
||||
"Cubesat" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=cubesat&FORMAT=csv",
|
||||
"Education" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=education&FORMAT=csv",
|
||||
"Engineer" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=engineering&FORMAT=csv",
|
||||
"Geostationary" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=geo&FORMAT=csv",
|
||||
"Globalstar" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=globalstar&FORMAT=csv",
|
||||
"GNSS" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=gnss&FORMAT=csv",
|
||||
"Intelsat" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=intelsat&FORMAT=csv",
|
||||
"Iridium" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=iridium-NEXT&FORMAT=csv",
|
||||
"Military" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=military&FORMAT=csv",
|
||||
"New" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=last-30-days&FORMAT=csv",
|
||||
"OneWeb" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=oneweb&FORMAT=csv",
|
||||
"Orbcomm" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=orbcomm&FORMAT=csv",
|
||||
"Resource" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=resource&FORMAT=csv",
|
||||
"CelesTrak SatNOGS" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=satnogs&FORMAT=csv",
|
||||
"Science" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=science&FORMAT=csv",
|
||||
"Spire" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=spire&FORMAT=csv",
|
||||
"Starlink" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=starlink&FORMAT=csv",
|
||||
"Swarm" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=swarm&FORMAT=csv",
|
||||
"Weather" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=weather&FORMAT=csv",
|
||||
"X-Comm" to "https://celestrak.org/NORAD/elements/gp.php?GROUP=x-comm&FORMAT=csv",
|
||||
"Amsat" to "https://amsat.org/tle/current/nasabare.txt",
|
||||
"Classified" to "https://www.mmccants.org/tles/classfd.zip",
|
||||
"McCants" to "https://www.mmccants.org/tles/inttles.zip",
|
||||
"ARISS" to "https://live.ariss.org/iss.txt",
|
||||
"Other" to "" // key for sats filter
|
||||
)
|
||||
// Transceiver sources. Both publish the same SatNOGS-uuid records (measured 2026-10-04:
|
||||
// 2760 shared uuids), and the sync keeps the FIRST source's copy for a shared uuid
|
||||
// (distinctBy { uuid }). SatNOGS is kept first on purpose: its copies carry the
|
||||
// up-to-date descriptions (e.g. AO-91 "no CTCSS any longer") and it is the only source
|
||||
// with the newest satellites' transmitters (T-18 objects etc.), while R4UAB mainly adds
|
||||
// long-dead entries plus a handful of live extras. Upstream lists R4UAB first; this fork
|
||||
// intentionally differs.
|
||||
val transceiversDataUrls = mapOf(
|
||||
"SatNOGS" to "https://db.satnogs.org/api/transmitters/?format=json&status=active",
|
||||
"R4UAB" to "https://r4uab.ru/transmitters.json"
|
||||
@@ -78,4 +69,12 @@ object Sources {
|
||||
* per-type IDs, and are mutually exclusive with the regular TLE-source
|
||||
* types in the picker. */
|
||||
val virtualTypeNames = listOf("AMSAT Live FM", "AMSAT Live Linear", "Live SSTV")
|
||||
|
||||
/** Key of the CelesTrak "active" group source in [satelliteDataUrls] — the whole
|
||||
* catalogue. Selecting it means "all satellites", so when its persisted id list
|
||||
* is empty the picker must fall back to no filtering instead of showing an empty
|
||||
* list. The list can legitimately be empty: CelesTrak answers 403 ("GP data has
|
||||
* not updated since your last successful download", groups update every 2 hours)
|
||||
* when a group is re-requested, and the sync then persists nothing for that type. */
|
||||
val allSourceType = "All"
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
[versions]
|
||||
#noinspection UnusedVersionCatalogEntry
|
||||
appVersionCode = "560"
|
||||
appVersionCode = "563"
|
||||
#noinspection UnusedVersionCatalogEntry
|
||||
appVersionName = "4.4.8-ba7opf.6"
|
||||
appVersionName = "4.4.8-ba7opf.8"
|
||||
#noinspection UnusedVersionCatalogEntry
|
||||
compileSdk = "37"
|
||||
#noinspection UnusedVersionCatalogEntry
|
||||
|
||||
Reference in new issue
Block a user