starbash 0.3.4__tar.gz → 0.3.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. {starbash-0.3.4 → starbash-0.3.6}/PKG-INFO +36 -38
  2. {starbash-0.3.4 → starbash-0.3.6}/README.md +33 -35
  3. {starbash-0.3.4 → starbash-0.3.6}/pyproject.toml +6 -3
  4. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/app.py +48 -5
  5. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/commands/repo.py +19 -4
  6. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/database.py +86 -10
  7. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/doit.py +10 -10
  8. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/exception.py +1 -1
  9. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/os.py +1 -1
  10. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/publish/github_service.py +4 -0
  11. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/tool/base.py +17 -1
  12. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/tool/graxpert.py +2 -1
  13. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/tool/rcastro.py +11 -2
  14. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/tool/siril.py +8 -3
  15. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/tool/starnet.py +62 -3
  16. starbash-0.3.6/src/starbash/ui/qt/launcher.py +32 -0
  17. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/pages/repositories.py +2 -2
  18. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/pages/wizard.py +47 -37
  19. {starbash-0.3.4 → starbash-0.3.6}/LICENSE +0 -0
  20. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/__init__.py +0 -0
  21. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/aliases.py +0 -0
  22. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/analytics.py +0 -0
  23. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/assets/__init__.py +0 -0
  24. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/assets/check.png +0 -0
  25. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/assets/favicon.ico +0 -0
  26. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/assets/icon.png +0 -0
  27. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/assets/icon.svg +0 -0
  28. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/assets/starbash.desktop.in +0 -0
  29. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/check_version.py +0 -0
  30. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/commands/__init__.py +0 -0
  31. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/commands/gui.py +0 -0
  32. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/commands/info.py +0 -0
  33. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/commands/process.py +0 -0
  34. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/commands/publish.py +0 -0
  35. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/commands/select.py +0 -0
  36. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/commands/user.py +0 -0
  37. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/defaults/__init__.py +0 -0
  38. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/defaults/starbash.toml +0 -0
  39. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/doit_types.py +0 -0
  40. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/dwarf3.py +0 -0
  41. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/events.py +0 -0
  42. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/filtering.py +0 -0
  43. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/fits.py +0 -0
  44. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/interaction.py +0 -0
  45. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/linux.py +0 -0
  46. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/main.py +0 -0
  47. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/parameters.py +0 -0
  48. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/paths.py +0 -0
  49. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/preferences.py +0 -0
  50. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/processed_target.py +0 -0
  51. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/processing.py +0 -0
  52. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/processing_like.py +0 -0
  53. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/publish/__init__.py +0 -0
  54. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/publish/credentials.py +0 -0
  55. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/publish/github.py +0 -0
  56. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/publish/github_publish.py +0 -0
  57. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/recipes/README.md +0 -0
  58. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/recipes/__init__.py +0 -0
  59. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/recipes/crop.py +0 -0
  60. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/recipes/osc.py +0 -0
  61. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/recipes/report_registration.py +0 -0
  62. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/report.py +0 -0
  63. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/rich.py +0 -0
  64. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/run_state.py +0 -0
  65. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/safety.py +0 -0
  66. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/score.py +0 -0
  67. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/selection.py +0 -0
  68. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/sim_siril/__init__.py +0 -0
  69. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/sim_siril/connection.py +0 -0
  70. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/sim_siril/enums.py +0 -0
  71. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/sim_siril/utility.py +0 -0
  72. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/siril/import_registration.py +0 -0
  73. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/stage_utils.py +0 -0
  74. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/stages.py +0 -0
  75. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/__init__.py +0 -0
  76. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/repo/master.toml +0 -0
  77. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/repo/processed.toml +0 -0
  78. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/report/Gemfile +0 -0
  79. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/report/README.md.jinja +0 -0
  80. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/report/__init__.py +0 -0
  81. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/report/_config.yml +0 -0
  82. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/report/default.html +0 -0
  83. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/report/index.md.jinja +0 -0
  84. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/report/target.md.jinja +0 -0
  85. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/target/master.toml +0 -0
  86. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/target/processed/about.toml +0 -0
  87. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/target/processed/main.toml +0 -0
  88. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/target/processed/sessions.toml +0 -0
  89. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/templates/userconfig.toml +0 -0
  90. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/toml.py +0 -0
  91. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/tool/__init__.py +0 -0
  92. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/tool/context.py +0 -0
  93. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/tool/python.py +0 -0
  94. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/__init__.py +0 -0
  95. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/cli.py +0 -0
  96. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/cli_events.py +0 -0
  97. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/__init__.py +0 -0
  98. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/app.py +0 -0
  99. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/bridge.py +0 -0
  100. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/desktop.py +0 -0
  101. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/interaction.py +0 -0
  102. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/jobs.py +0 -0
  103. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/main_window.py +0 -0
  104. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/models.py +0 -0
  105. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/pages/__init__.py +0 -0
  106. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/pages/base.py +0 -0
  107. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/pages/dashboard.py +0 -0
  108. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/pages/masters.py +0 -0
  109. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/pages/processing.py +0 -0
  110. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/pages/publish.py +0 -0
  111. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/pages/sessions.py +0 -0
  112. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/pages/settings.py +0 -0
  113. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/pages/targets.py +0 -0
  114. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/services.py +0 -0
  115. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/theme.py +0 -0
  116. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/widgets/__init__.py +0 -0
  117. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/widgets/busy_indicator.py +0 -0
  118. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/widgets/file_links.py +0 -0
  119. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/widgets/github_login.py +0 -0
  120. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/widgets/hover_preview.py +0 -0
  121. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/widgets/image_viewer.py +0 -0
  122. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/widgets/log_view.py +0 -0
  123. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/widgets/master_picker.py +0 -0
  124. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/widgets/selection_panel.py +0 -0
  125. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/widgets/stat_card.py +0 -0
  126. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/widgets/tool_warning.py +0 -0
  127. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/ui/qt/workers.py +0 -0
  128. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/url.py +0 -0
  129. {starbash-0.3.4 → starbash-0.3.6}/src/starbash/windows.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: starbash
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: A tool for automating/standardizing/sharing astrophotography workflows.
5
5
  License-File: LICENSE
6
6
  Author: Kevin Hester
@@ -12,10 +12,10 @@ Classifier: Programming Language :: Python :: 3.13
12
12
  Classifier: Programming Language :: Python :: 3.14
13
13
  Requires-Dist: astropy (>=7.1.1)
14
14
  Requires-Dist: doit (>=0.36.0)
15
- Requires-Dist: graxpert[cpuonly] (>=3.2.0a2,<4.0.0)
15
+ Requires-Dist: graxpert[cpuonly] (>=3.2.0a3,<4.0.0)
16
16
  Requires-Dist: jinja2 (>=3.1,<4.0)
17
17
  Requires-Dist: keyring (>=25.6)
18
- Requires-Dist: numpy (==2.2.6)
18
+ Requires-Dist: numpy (>=2.2.6)
19
19
  Requires-Dist: platformdirs (>=4.5.0,<5.0.0)
20
20
  Requires-Dist: pygal (>=3.0,<4.0)
21
21
  Requires-Dist: pyqt6 (>=6.10.1,<7.0.0)
@@ -113,6 +113,7 @@ We have a CLI interface also...
113
113
 
114
114
  ## Features coming soon
115
115
 
116
+ * Fixed SHO/HOO auto post processing pipeline for dual narrowband OSC filters. Currently everything after pallete recomposition looks bad for those workflows (prior stage outputs are all good though)
116
117
  * Recipe 'writers guide' documentation. Currently iterating based on usage reports 😄
117
118
  * Support for mono-camera workflows (this alpha only includes osc recipes).
118
119
  * The target report can be used to auto-generate a human-friendly 'postable/shareable' report about that image.
@@ -152,7 +153,37 @@ Completion will take effect once you restart the terminal
152
153
 
153
154
  ```
154
155
 
155
- ## Use
156
+ ## Supported telescope software
157
+
158
+ * N.I.N.A. - tested, seems fairly okay.
159
+ * Asiair - tested, seems fairly okay.
160
+ * Seestar - tested, seems fairly okay.
161
+ * Dwarf3 - tested but young and possibly buggy, please report bugs if you find them.
162
+ * Ekos/Kstars - not tested; please try it and file a GitHub issue if you see any problems.
163
+
164
+ ## Supported tools (now)
165
+ Starbash is a tool agnostic workflow manager. But it wouldn't be possible without the folling great tools.
166
+
167
+ * [Siril](https://siril.org/)
168
+ * [Graxpert](https://graxpert.com/) - for background and noise elimination
169
+ * [blur exterminator / noise exterminator](https://www.rc-astro.com/stand-alone-rc-astro-tools/)
170
+ * [starnet](https://starnetastro.com/cli-tools/) - for star removal
171
+ * [Python](https://www.python.org/) (you can add Python code to recipes if necessary)
172
+
173
+ ## Desktop GUI
174
+
175
+ Prefer clicking to typing? Starbash ships a desktop app that
176
+ covers the same ground as the CLI — browse sessions and preview frames, edit the
177
+ selection, run the pipeline and watch every stage live, tweak per-target stage
178
+ exclusions, manage repositories, and build the report site.
179
+
180
+ ```bash
181
+ sb
182
+ ```
183
+
184
+ ## CLI
185
+
186
+ ** Warning: The following instructions are written wrt to the CLI. The newer GUI can do all the same things - but easier/prettier. So most users should use the GUI first **
156
187
 
157
188
  ### Initial setup
158
189
 
@@ -229,22 +260,6 @@ sb publish github # Publish to github
229
260
  See the [GitHub publishing guide](doc/publish/github.md) for prerequisites,
230
261
  preview instructions, authentication, and troubleshooting.
231
262
 
232
- ### Desktop GUI
233
-
234
- Prefer clicking to typing? Starbash ships a desktop app (built on PySide6) that
235
- covers the same ground as the CLI — browse sessions and preview frames, edit the
236
- selection, run the pipeline and watch every stage live, tweak per-target stage
237
- exclusions, manage repositories, and build the report site.
238
-
239
- ```bash
240
- sb gui
241
- ```
242
-
243
- PySide6 is installed with Starbash, so there is nothing extra to add. The GUI is
244
- optional in the sense that you can ignore it completely and keep driving Starbash
245
- from the command line: both front ends share the same selection, config and
246
- database, so you can mix them freely.
247
-
248
263
  ## Supported commands
249
264
 
250
265
  ### Repository Management
@@ -280,23 +295,6 @@ database, so you can mix them freely.
280
295
  - `sb process auto [SESSIONNUM]` - Automatic processing. If session # is specified, process only that session; otherwise all selected sessions will be processed.
281
296
  - `sb process masters` - Generate master flats, darks, and biases from available raw frames in the current selection.
282
297
 
283
- ## Supported telescope software
284
-
285
- * N.I.N.A. - tested, seems fairly okay.
286
- * Asiair - tested, seems fairly okay.
287
- * Seestar - tested, seems fairly okay.
288
- * Dwarf3 - tested but young and possibly buggy, please report bugs if you find them.
289
- * Ekos/Kstars - not tested; please try it and file a GitHub issue if you see any problems.
290
-
291
- ## Supported tools (now)
292
- Starbash is a tool agnostic workflow manager. But it wouldn't be possible without the folling great tools.
293
-
294
- * [Siril](https://siril.org/)
295
- * [Graxpert](https://graxpert.com/) - for background and noise elimination
296
- * [blur exterminator / noise exterminator](https://www.rc-astro.com/stand-alone-rc-astro-tools/)
297
- * [starnet](https://starnetastro.com/cli-tools/) - for star removal
298
- * [Python](https://www.python.org/) (you can add Python code to recipes if necessary)
299
-
300
298
  ## Credits
301
299
  * Various reddit users who submitted anonymous crash reports from alpha 1
302
300
  * [@codegistics](https://github.com/codegistics) for kindly donating Dwarf3 test data and invaluable debugging assistance.
@@ -324,6 +322,6 @@ However, in some of my other open-source projects, I've seen the current hell PR
324
322
 
325
323
  ## License
326
324
 
327
- Copyright 2025 Kevin Hester, kevinh@geeksville.com.
325
+ Copyright 2025, 2026 Kevin Hester, kevinh@geeksville.com.
328
326
  Licensed under the [GPL v3](https://raw.githubusercontent.com/geeksville/starbash/refs/heads/main/LICENSE)
329
327
 
@@ -80,6 +80,7 @@ We have a CLI interface also...
80
80
 
81
81
  ## Features coming soon
82
82
 
83
+ * Fixed SHO/HOO auto post processing pipeline for dual narrowband OSC filters. Currently everything after pallete recomposition looks bad for those workflows (prior stage outputs are all good though)
83
84
  * Recipe 'writers guide' documentation. Currently iterating based on usage reports 😄
84
85
  * Support for mono-camera workflows (this alpha only includes osc recipes).
85
86
  * The target report can be used to auto-generate a human-friendly 'postable/shareable' report about that image.
@@ -119,7 +120,37 @@ Completion will take effect once you restart the terminal
119
120
 
120
121
  ```
121
122
 
122
- ## Use
123
+ ## Supported telescope software
124
+
125
+ * N.I.N.A. - tested, seems fairly okay.
126
+ * Asiair - tested, seems fairly okay.
127
+ * Seestar - tested, seems fairly okay.
128
+ * Dwarf3 - tested but young and possibly buggy, please report bugs if you find them.
129
+ * Ekos/Kstars - not tested; please try it and file a GitHub issue if you see any problems.
130
+
131
+ ## Supported tools (now)
132
+ Starbash is a tool agnostic workflow manager. But it wouldn't be possible without the folling great tools.
133
+
134
+ * [Siril](https://siril.org/)
135
+ * [Graxpert](https://graxpert.com/) - for background and noise elimination
136
+ * [blur exterminator / noise exterminator](https://www.rc-astro.com/stand-alone-rc-astro-tools/)
137
+ * [starnet](https://starnetastro.com/cli-tools/) - for star removal
138
+ * [Python](https://www.python.org/) (you can add Python code to recipes if necessary)
139
+
140
+ ## Desktop GUI
141
+
142
+ Prefer clicking to typing? Starbash ships a desktop app that
143
+ covers the same ground as the CLI — browse sessions and preview frames, edit the
144
+ selection, run the pipeline and watch every stage live, tweak per-target stage
145
+ exclusions, manage repositories, and build the report site.
146
+
147
+ ```bash
148
+ sb
149
+ ```
150
+
151
+ ## CLI
152
+
153
+ ** Warning: The following instructions are written wrt to the CLI. The newer GUI can do all the same things - but easier/prettier. So most users should use the GUI first **
123
154
 
124
155
  ### Initial setup
125
156
 
@@ -196,22 +227,6 @@ sb publish github # Publish to github
196
227
  See the [GitHub publishing guide](doc/publish/github.md) for prerequisites,
197
228
  preview instructions, authentication, and troubleshooting.
198
229
 
199
- ### Desktop GUI
200
-
201
- Prefer clicking to typing? Starbash ships a desktop app (built on PySide6) that
202
- covers the same ground as the CLI — browse sessions and preview frames, edit the
203
- selection, run the pipeline and watch every stage live, tweak per-target stage
204
- exclusions, manage repositories, and build the report site.
205
-
206
- ```bash
207
- sb gui
208
- ```
209
-
210
- PySide6 is installed with Starbash, so there is nothing extra to add. The GUI is
211
- optional in the sense that you can ignore it completely and keep driving Starbash
212
- from the command line: both front ends share the same selection, config and
213
- database, so you can mix them freely.
214
-
215
230
  ## Supported commands
216
231
 
217
232
  ### Repository Management
@@ -247,23 +262,6 @@ database, so you can mix them freely.
247
262
  - `sb process auto [SESSIONNUM]` - Automatic processing. If session # is specified, process only that session; otherwise all selected sessions will be processed.
248
263
  - `sb process masters` - Generate master flats, darks, and biases from available raw frames in the current selection.
249
264
 
250
- ## Supported telescope software
251
-
252
- * N.I.N.A. - tested, seems fairly okay.
253
- * Asiair - tested, seems fairly okay.
254
- * Seestar - tested, seems fairly okay.
255
- * Dwarf3 - tested but young and possibly buggy, please report bugs if you find them.
256
- * Ekos/Kstars - not tested; please try it and file a GitHub issue if you see any problems.
257
-
258
- ## Supported tools (now)
259
- Starbash is a tool agnostic workflow manager. But it wouldn't be possible without the folling great tools.
260
-
261
- * [Siril](https://siril.org/)
262
- * [Graxpert](https://graxpert.com/) - for background and noise elimination
263
- * [blur exterminator / noise exterminator](https://www.rc-astro.com/stand-alone-rc-astro-tools/)
264
- * [starnet](https://starnetastro.com/cli-tools/) - for star removal
265
- * [Python](https://www.python.org/) (you can add Python code to recipes if necessary)
266
-
267
265
  ## Credits
268
266
  * Various reddit users who submitted anonymous crash reports from alpha 1
269
267
  * [@codegistics](https://github.com/codegistics) for kindly donating Dwarf3 test data and invaluable debugging assistance.
@@ -291,5 +289,5 @@ However, in some of my other open-source projects, I've seen the current hell PR
291
289
 
292
290
  ## License
293
291
 
294
- Copyright 2025 Kevin Hester, kevinh@geeksville.com.
292
+ Copyright 2025, 2026 Kevin Hester, kevinh@geeksville.com.
295
293
  Licensed under the [GPL v3](https://raw.githubusercontent.com/geeksville/starbash/refs/heads/main/LICENSE)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "starbash"
3
- version = "0.3.4"
3
+ version = "0.3.6"
4
4
  description = "A tool for automating/standardizing/sharing astrophotography workflows."
5
5
  authors = ["Kevin Hester <kevinh@geeksville.com>"]
6
6
  readme = "README.md"
@@ -32,13 +32,13 @@ toml-repo = "^0.1.7"
32
32
 
33
33
  # Note: to use graxpert from the local tree rather than pypi use:
34
34
  # graxpert = {path = "GraXpert", extras = ["cpuonly"], develop = true}
35
- graxpert = {version = "^3.2.0a2", extras = ["cpuonly"]}
35
+ graxpert = {version = "^3.2.0a3", extras = ["cpuonly"]}
36
36
 
37
37
  # The following two libs are only needed for the (temporary) experiment of running siril scripts directly...
38
38
  # experimenting with siril-scripts/processing/VeraLux_HyperMetric_Stretch.py
39
39
  # pyqt6 is used *only* by those out-of-process siril scripts; Starbash itself never imports it,
40
40
  # so it can safely coexist with PySide6 (which the GUI *does* import).
41
- numpy = "2.2.6"
41
+ numpy = ">=2.2.6"
42
42
  pyqt6 = "^6.10.1"
43
43
  # The desktop GUI (`sb gui`) binding. A normal dependency: the GUI is a first-class
44
44
  # way to drive Starbash. "Optional" only means users may keep using the CLI instead.
@@ -63,6 +63,9 @@ library-skills = "^0.0.19"
63
63
  semble = {version = "^0.6.0", extras = ["mcp"]}
64
64
  imageio-ffmpeg = "^0.6.0"
65
65
 
66
+ [tool.poetry.group.packaging.dependencies]
67
+ pyinstaller = ">=6.17.0,<7.0.0"
68
+
66
69
  [tool.poetry.scripts]
67
70
  starbash = "starbash.main:app"
68
71
  sb = "starbash.main:app" # std alias for convenience
@@ -34,6 +34,7 @@ from starbash.check_version import check_version
34
34
  from starbash.database import (
35
35
  Database,
36
36
  ImageRow,
37
+ RepoRemoval,
37
38
  SearchCondition,
38
39
  SessionRow,
39
40
  get_column_name,
@@ -691,13 +692,21 @@ class Starbash:
691
692
  """
692
693
  return self._find_user_repo_ref(url) is not None
693
694
 
694
- def remove_repo_ref(self, url: str) -> None:
695
+ def remove_repo_ref(self, url: str) -> RepoRemoval:
695
696
  """
696
697
  Remove a repository reference from the user configuration.
697
698
 
699
+ Also drops everything the repository contributed to the index: its image
700
+ rows, and the sessions those images built. A session never spans
701
+ repositories, so all of its frames go with the repo and there is nothing
702
+ left for it to describe.
703
+
698
704
  Args:
699
705
  url: The repository URL to remove (e.g., 'file:///path/to/repo')
700
706
 
707
+ Returns:
708
+ A :class:`~starbash.database.RepoRemoval` describing what was dropped.
709
+
701
710
  Raises:
702
711
  UserHandledError: If the repository URL is not found in user configuration
703
712
  """
@@ -708,12 +717,21 @@ class Starbash:
708
717
  # indexed rows would only force a pointless re-index later.
709
718
  raise UserHandledError(f"Repository '{url}' not found in user configuration.")
710
719
 
711
- self.db.remove_repo(url)
720
+ removal = self.db.remove_repo(url)
712
721
  self.user_repo.config.get("repo-ref", []).remove(ref)
713
722
 
723
+ # Drop it from the in-memory manager too: everything that lists repos
724
+ # (``sb repo list``, the GUI's Repositories page) reads it, so without
725
+ # this the removed repository keeps showing until the app is restarted.
726
+ repo = self.repo_manager.get_repo_by_url(url)
727
+ if repo is not None:
728
+ self.repo_manager.repos.remove(repo)
729
+
714
730
  # Write the updated config
715
731
  self.user_repo.write_config()
716
732
 
733
+ return removal
734
+
717
735
  def _extend_image_header(self, headers: dict[str, Any], full_image_path: Path) -> bool:
718
736
  """Given a FITS header dictionary, possibly extend it with additional computed fields.
719
737
  Returns True if the header is invalid and should be skipped."""
@@ -810,7 +828,9 @@ class Starbash:
810
828
  # (otherwise invariants will get messed up)
811
829
  self._add_session(headers)
812
830
 
813
- def reindex_repo(self, repo: Repo, subdir: str | None = None) -> None:
831
+ def reindex_repo(
832
+ self, repo: Repo, subdir: str | None = None, clean: bool = False
833
+ ) -> RepoRemoval:
814
834
  """Scan one repo's files into the database.
815
835
 
816
836
  Progress is *reported*, never drawn: the scan publishes
@@ -825,17 +845,30 @@ class Starbash:
825
845
  Args:
826
846
  repo: the repo to scan.
827
847
  subdir: scan only this subdirectory of the repo (for debugging).
848
+ clean: drop the repo's indexed images and sessions before scanning, so
849
+ every frame counts as a first scan and its session is (re)built.
850
+
851
+ Returns:
852
+ What ``clean`` dropped from the index -- empty when not cleaning.
828
853
  """
829
854
 
830
855
  # make sure this new repo is listed in the repos table
831
856
  self.repo_db_update() # not really ideal, a more optimal version would just add the new repo
832
857
 
858
+ dropped = RepoRemoval()
833
859
  path = repo.get_path()
834
860
 
835
861
  repo_kind = repo.kind()
836
862
  if path and repo.is_scheme("file") and repo_kind != "recipe":
837
863
  logging.debug("Reindexing %s...", repo.url)
838
864
 
865
+ if clean:
866
+ # Wiping the repo's rows first is what makes the scan below a
867
+ # *full* re-read: it skips any frame already indexed, and only
868
+ # builds a session for one it meets for the first time.
869
+ dropped = self.db.reset_repo(repo.url)
870
+ logging.debug("Cleared the index for %s: %s", repo.url, dropped.summary())
871
+
839
872
  if subdir:
840
873
  path = path / subdir
841
874
  # used to debug
@@ -876,15 +909,25 @@ class Starbash:
876
909
  {"repo": repo.url, "indexed": total_files},
877
910
  )
878
911
 
879
- def reindex_repos(self) -> None:
912
+ return dropped
913
+
914
+ def reindex_repos(self, clean: bool = False) -> RepoRemoval:
880
915
  """Reindex all repositories managed by the RepoManager.
881
916
 
882
917
  Reports progress through the event bus only -- see :meth:`reindex_repo`.
918
+
919
+ Args:
920
+ clean: drop each repo's indexed images and sessions before scanning it.
921
+
922
+ Returns:
923
+ What ``clean`` dropped from the index across all repos.
883
924
  """
884
925
  logging.debug("Reindexing all repositories...")
885
926
 
927
+ dropped = RepoRemoval()
886
928
  for repo in self.repo_manager.repos:
887
- self.reindex_repo(repo)
929
+ dropped += self.reindex_repo(repo, clean=clean)
930
+ return dropped
888
931
 
889
932
  def get_recipes(self) -> list[Repo]:
890
933
  """Get all recipe repos available, sorted by priority (lower number first).
@@ -9,6 +9,7 @@ from toml_repo import Repo
9
9
  import starbash
10
10
  from starbash import console
11
11
  from starbash.app import Starbash
12
+ from starbash.database import RepoRemoval
12
13
  from starbash.paths import get_user_documents_dir
13
14
  from starbash.ui.cli import ReindexView
14
15
 
@@ -175,9 +176,12 @@ def remove(
175
176
  raise typer.Exit(code=1)
176
177
  repo_url = repo_to_remove.url
177
178
 
178
- # Remove the repo reference from user config
179
- sb.remove_repo_ref(repo_url)
179
+ # Remove the repo reference from user config. That also drops everything
180
+ # the repo contributed to the index: its frames, and the sessions those
181
+ # frames built.
182
+ removal = sb.remove_repo_ref(repo_url)
180
183
  console.print(f"[green]Removed repository: {repo_url}[/green]")
184
+ console.print(removal.summary())
181
185
 
182
186
 
183
187
  @app.command()
@@ -189,6 +193,12 @@ def reindex(
189
193
  autocompletion=complete_repo_by_url,
190
194
  ),
191
195
  ] = None,
196
+ clean: bool = typer.Option(
197
+ False,
198
+ "--clean",
199
+ help="First drop the repo's indexed images and sessions, so every frame is "
200
+ "re-read from disk and its sessions are rebuilt.",
201
+ ),
192
202
  ) -> None:
193
203
  """
194
204
  Reindex a repository by number.
@@ -200,15 +210,20 @@ def reindex(
200
210
  # one in this file is the placeholder from starbash.__init__). The view
201
211
  # must draw on the console the scan's own logging goes to.
202
212
  repo_to_reindex = repo_url_to_repo(sb, repo_url)
213
+ dropped = RepoRemoval()
203
214
 
204
215
  if repo_to_reindex is None:
205
216
  with ReindexView.for_console("Re-indexing repositories", starbash.console):
206
- sb.reindex_repos()
217
+ dropped = sb.reindex_repos(clean=clean)
218
+ if clean:
219
+ console.print(f"Cleared the index before scanning: {dropped.summary()}")
207
220
  else:
208
221
  # Get the repo to reindex
209
222
  console.print(f"Reindexing repository: {repo_to_reindex.url}")
210
223
  with ReindexView.for_console(f"Re-indexing {repo_to_reindex.url}", starbash.console):
211
- sb.reindex_repo(repo_to_reindex)
224
+ dropped = sb.reindex_repo(repo_to_reindex, clean=clean)
225
+ if clean:
226
+ console.print(f"Cleared the index before scanning: {dropped.summary()}")
212
227
  console.print(f"[green]Successfully reindexed repository {repo_to_reindex}[/green]")
213
228
 
214
229
 
@@ -16,6 +16,7 @@ type ImageRow = dict[str, Any]
16
16
 
17
17
  __all__ = [
18
18
  "Database",
19
+ "RepoRemoval",
19
20
  "SearchCondition",
20
21
  "SessionRow",
21
22
  "ImageRow",
@@ -68,6 +69,37 @@ def metadata_to_camera_id(metadata: dict[str, Any]) -> str | None:
68
69
  return camera_id
69
70
 
70
71
 
72
+ @dataclass(frozen=True)
73
+ class RepoRemoval:
74
+ """What :meth:`Database.remove_repo` dropped from the index.
75
+
76
+ Args:
77
+ images: image rows deleted along with the repository.
78
+ sessions: sessions deleted, because every frame they held came from it.
79
+ """
80
+
81
+ images: int = 0
82
+ sessions: int = 0
83
+
84
+ def __add__(self, other: RepoRemoval) -> RepoRemoval:
85
+ """Total two removals, so a multi-repo pass can report one number."""
86
+ return RepoRemoval(
87
+ images=self.images + other.images, sessions=self.sessions + other.sessions
88
+ )
89
+
90
+ def summary(self) -> str:
91
+ """Return a one-line, human readable description of what changed."""
92
+ dropped: list[str] = []
93
+ if self.images:
94
+ dropped.append(f"{self.images} indexed image(s)")
95
+ if self.sessions:
96
+ dropped.append(f"{self.sessions} session(s)")
97
+
98
+ if not dropped:
99
+ return "No indexed files or sessions were affected."
100
+ return "Removed " + " and ".join(dropped) + "."
101
+
102
+
71
103
  class Database:
72
104
  """SQLite-backed application database.
73
105
 
@@ -244,21 +276,19 @@ class Database:
244
276
  self._db.commit()
245
277
 
246
278
  # --- Convenience helpers for common repo operations ---
247
- def remove_repo(self, url: str) -> None:
248
- """Remove a repo record by URL.
279
+ def _drop_repo_index(self, cursor: sqlite3.Cursor, url: str) -> RepoRemoval:
280
+ """Delete a repo's images and the sessions those images built.
249
281
 
250
- This will cascade delete all images belonging to this repo, and all sessions
251
- that reference those images via image_doc_id.
252
-
253
- The relationship is: repos -> images (via repo_id) -> sessions (via image_doc_id).
254
- Sessions have an image_doc_id field that points to a representative image.
255
- We delete sessions whose representative image belongs to the repo being deleted.
282
+ Shared by :meth:`remove_repo` (which then drops the repo row too) and
283
+ :meth:`reset_repo` (which keeps it, so the next scan starts clean).
256
284
 
257
285
  Args:
286
+ cursor: an open cursor on the application database.
258
287
  url: The repository URL (e.g., 'file:///path/to/repo')
259
- """
260
- cursor = self._db.cursor()
261
288
 
289
+ Returns:
290
+ A :class:`RepoRemoval` counting the rows that were dropped.
291
+ """
262
292
  # Use a 3-way join to find and delete sessions that reference images from this repo
263
293
  # repo_url -> repo_id -> images.id -> sessions.image_doc_id
264
294
  cursor.execute(
@@ -274,6 +304,7 @@ class Database:
274
304
  """,
275
305
  (url,),
276
306
  )
307
+ sessions = cursor.rowcount
277
308
 
278
309
  # Delete all images from this repo (using repo_id from URL)
279
310
  cursor.execute(
@@ -283,12 +314,57 @@ class Database:
283
314
  """,
284
315
  (url,),
285
316
  )
317
+ return RepoRemoval(images=cursor.rowcount, sessions=sessions)
318
+
319
+ def reset_repo(self, url: str) -> RepoRemoval:
320
+ """
321
+ Drop everything a repository contributed to the index, keeping the repo.
322
+
323
+ Used before a re-scan (``sb repo reindex --clean``): with the image rows
324
+ gone, every frame the scan meets is a *first* scan, which is the only time
325
+ :meth:`Starbash.add_image_and_session` builds a session for it. A plain
326
+ re-index only refreshes the rows it finds, and never touches the sessions.
327
+
328
+ Args:
329
+ url: The repository URL (e.g., 'file:///path/to/repo')
330
+
331
+ Returns:
332
+ A :class:`RepoRemoval` counting the rows that were dropped.
333
+ """
334
+ cursor = self._db.cursor()
335
+ removal = self._drop_repo_index(cursor, url)
336
+
337
+ self._db.commit()
338
+
339
+ return removal
340
+
341
+ def remove_repo(self, url: str) -> RepoRemoval:
342
+ """Remove a repo record by URL, along with everything it contributed.
343
+
344
+ This cascades to every image belonging to the repo, and to the sessions
345
+ those images built: a session is only ever fed by one repository, so once
346
+ its frames are gone there is nothing left for it to describe.
347
+
348
+ The relationship is: repos -> images (via repo_id) -> sessions (via
349
+ image_doc_id, the representative image a session was built from).
350
+
351
+ Args:
352
+ url: The repository URL (e.g., 'file:///path/to/repo')
353
+
354
+ Returns:
355
+ A :class:`RepoRemoval` counting the rows that were dropped.
356
+ """
357
+ cursor = self._db.cursor()
358
+
359
+ removal = self._drop_repo_index(cursor, url)
286
360
 
287
361
  # Finally delete the repo itself
288
362
  cursor.execute(f"DELETE FROM {self.REPOS_TABLE} WHERE url = ?", (url,))
289
363
 
290
364
  self._db.commit()
291
365
 
366
+ return removal
367
+
292
368
  def upsert_repo(self, url: str) -> int:
293
369
  """Insert or update a repo record by unique URL.
294
370
 
@@ -359,19 +359,19 @@ class ToolAction(BaseAction):
359
359
  if input_files:
360
360
  desc = f"({len(input_files)} input files)"
361
361
 
362
- # Some tools might want us to pre merge all the input frames (siril merge command doesn't nicely work with images
363
- # of different sizes etc).
364
- stage_input: dict[Any, FileInfo] = context["stage_input"]
365
- for fi in stage_input.values():
366
- perhaps_merge_to(fi)
362
+ logging.info(f"Running {self.tool.name} for {self.task.name} {desc}")
363
+ try:
364
+ # Some tools might want us to pre merge all the input frames (siril merge command doesn't nicely work with images
365
+ # of different sizes etc).
366
+ stage_input: dict[Any, FileInfo] = context["stage_input"]
367
+ for fi in stage_input.values():
368
+ perhaps_merge_to(fi)
367
369
 
368
- from starbash.processed_target import ProcessedTarget
370
+ from starbash.processed_target import ProcessedTarget
369
371
 
370
- pt: ProcessedTarget = self.task.meta["processed_target"]
371
- logfile_path = pt.log_path
372
+ pt: ProcessedTarget = self.task.meta["processed_target"]
373
+ logfile_path = pt.log_path
372
374
 
373
- logging.info(f"Running {self.tool.name} for {self.task.name} {desc}")
374
- try:
375
375
  with open(logfile_path, "a", encoding="utf-8") as logfile:
376
376
  self.result = self.tool.run(
377
377
  self.commands, context=context, cwd=self.cwd, log_out=logfile, **self.parameters
@@ -31,7 +31,7 @@ class FilesystemUnavailableError(UserHandledError):
31
31
  def __init__(self, operation: str, cause: OSError) -> None:
32
32
  super().__init__(
33
33
  f"The filesystem became unavailable while {operation}. "
34
- "Check that the drive or network mount is connected, then retry."
34
+ "Check that the drive is connected (and it is not out of space), then retry."
35
35
  )
36
36
  self.cause = cause
37
37
 
@@ -26,7 +26,7 @@ def symlink_or_copy(src: str, dest: str) -> bool:
26
26
  "We recommend enabling symlinks for better performance:\n"
27
27
  "Enable Developer Mode in Windows 11 settings.\n"
28
28
  "This allows for the creation of symbolic links without requiring elevated administrator privileges.\n"
29
- "• Navigate to Settings > Privacy & security > For developers.\n"
29
+ "• Navigate to Settings > System > Advanced > For developers.\n"
30
30
  '• Toggle the "Developer Mode" option to On.'
31
31
  )
32
32
  _symlink_warning_logged = True
@@ -353,6 +353,10 @@ class GitHubService:
353
353
  raise GitHubError(
354
354
  "The GitHub refresh token has expired; run 'sb publish github --login' again"
355
355
  )
356
+ logger.warning(
357
+ "GitHub token refresh returned an unexpected response: %r",
358
+ self._safe_response(value),
359
+ )
356
360
  raise GitHubError("GitHub returned an unexpected token refresh response")
357
361
 
358
362
  def apply_token_response(self, value: dict[str, Any]) -> None: