starbash 0.3.5__tar.gz → 0.3.7__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.5 → starbash-0.3.7}/PKG-INFO +1 -1
  2. {starbash-0.3.5 → starbash-0.3.7}/pyproject.toml +1 -1
  3. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/tool/rcastro.py +3 -0
  4. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/tool/starnet.py +54 -3
  5. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/pages/wizard.py +44 -17
  6. {starbash-0.3.5 → starbash-0.3.7}/LICENSE +0 -0
  7. {starbash-0.3.5 → starbash-0.3.7}/README.md +0 -0
  8. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/__init__.py +0 -0
  9. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/aliases.py +0 -0
  10. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/analytics.py +0 -0
  11. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/app.py +0 -0
  12. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/assets/__init__.py +0 -0
  13. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/assets/check.png +0 -0
  14. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/assets/favicon.ico +0 -0
  15. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/assets/icon.png +0 -0
  16. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/assets/icon.svg +0 -0
  17. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/assets/starbash.desktop.in +0 -0
  18. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/check_version.py +0 -0
  19. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/commands/__init__.py +0 -0
  20. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/commands/gui.py +0 -0
  21. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/commands/info.py +0 -0
  22. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/commands/process.py +0 -0
  23. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/commands/publish.py +0 -0
  24. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/commands/repo.py +0 -0
  25. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/commands/select.py +0 -0
  26. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/commands/user.py +0 -0
  27. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/database.py +0 -0
  28. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/defaults/__init__.py +0 -0
  29. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/defaults/starbash.toml +0 -0
  30. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/doit.py +0 -0
  31. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/doit_types.py +0 -0
  32. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/dwarf3.py +0 -0
  33. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/events.py +0 -0
  34. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/exception.py +0 -0
  35. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/filtering.py +0 -0
  36. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/fits.py +0 -0
  37. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/interaction.py +0 -0
  38. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/linux.py +0 -0
  39. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/main.py +0 -0
  40. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/os.py +0 -0
  41. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/parameters.py +0 -0
  42. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/paths.py +0 -0
  43. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/preferences.py +0 -0
  44. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/processed_target.py +0 -0
  45. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/processing.py +0 -0
  46. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/processing_like.py +0 -0
  47. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/publish/__init__.py +0 -0
  48. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/publish/credentials.py +0 -0
  49. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/publish/github.py +0 -0
  50. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/publish/github_publish.py +0 -0
  51. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/publish/github_service.py +0 -0
  52. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/recipes/README.md +0 -0
  53. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/recipes/__init__.py +0 -0
  54. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/recipes/crop.py +0 -0
  55. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/recipes/osc.py +0 -0
  56. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/recipes/report_registration.py +0 -0
  57. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/report.py +0 -0
  58. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/rich.py +0 -0
  59. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/run_state.py +0 -0
  60. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/safety.py +0 -0
  61. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/score.py +0 -0
  62. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/selection.py +0 -0
  63. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/sim_siril/__init__.py +0 -0
  64. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/sim_siril/connection.py +0 -0
  65. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/sim_siril/enums.py +0 -0
  66. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/sim_siril/utility.py +0 -0
  67. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/siril/import_registration.py +0 -0
  68. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/stage_utils.py +0 -0
  69. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/stages.py +0 -0
  70. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/__init__.py +0 -0
  71. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/repo/master.toml +0 -0
  72. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/repo/processed.toml +0 -0
  73. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/report/Gemfile +0 -0
  74. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/report/README.md.jinja +0 -0
  75. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/report/__init__.py +0 -0
  76. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/report/_config.yml +0 -0
  77. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/report/default.html +0 -0
  78. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/report/index.md.jinja +0 -0
  79. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/report/target.md.jinja +0 -0
  80. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/target/master.toml +0 -0
  81. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/target/processed/about.toml +0 -0
  82. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/target/processed/main.toml +0 -0
  83. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/target/processed/sessions.toml +0 -0
  84. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/templates/userconfig.toml +0 -0
  85. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/toml.py +0 -0
  86. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/tool/__init__.py +0 -0
  87. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/tool/base.py +0 -0
  88. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/tool/context.py +0 -0
  89. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/tool/graxpert.py +0 -0
  90. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/tool/python.py +0 -0
  91. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/tool/siril.py +0 -0
  92. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/__init__.py +0 -0
  93. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/cli.py +0 -0
  94. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/cli_events.py +0 -0
  95. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/__init__.py +0 -0
  96. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/app.py +0 -0
  97. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/bridge.py +0 -0
  98. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/desktop.py +0 -0
  99. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/interaction.py +0 -0
  100. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/jobs.py +0 -0
  101. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/launcher.py +0 -0
  102. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/main_window.py +0 -0
  103. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/models.py +0 -0
  104. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/pages/__init__.py +0 -0
  105. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/pages/base.py +0 -0
  106. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/pages/dashboard.py +0 -0
  107. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/pages/masters.py +0 -0
  108. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/pages/processing.py +0 -0
  109. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/pages/publish.py +0 -0
  110. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/pages/repositories.py +0 -0
  111. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/pages/sessions.py +0 -0
  112. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/pages/settings.py +0 -0
  113. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/pages/targets.py +0 -0
  114. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/services.py +0 -0
  115. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/theme.py +0 -0
  116. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/widgets/__init__.py +0 -0
  117. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/widgets/busy_indicator.py +0 -0
  118. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/widgets/file_links.py +0 -0
  119. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/widgets/github_login.py +0 -0
  120. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/widgets/hover_preview.py +0 -0
  121. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/widgets/image_viewer.py +0 -0
  122. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/widgets/log_view.py +0 -0
  123. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/widgets/master_picker.py +0 -0
  124. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/widgets/selection_panel.py +0 -0
  125. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/widgets/stat_card.py +0 -0
  126. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/widgets/tool_warning.py +0 -0
  127. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/ui/qt/workers.py +0 -0
  128. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/url.py +0 -0
  129. {starbash-0.3.5 → starbash-0.3.7}/src/starbash/windows.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: starbash
3
- Version: 0.3.5
3
+ Version: 0.3.7
4
4
  Summary: A tool for automating/standardizing/sharing astrophotography workflows.
5
5
  License-File: LICENSE
6
6
  Author: Kevin Hester
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "starbash"
3
- version = "0.3.5"
3
+ version = "0.3.7"
4
4
  description = "A tool for automating/standardizing/sharing astrophotography workflows."
5
5
  authors = ["Kevin Hester <kevinh@geeksville.com>"]
6
6
  readme = "README.md"
@@ -5,6 +5,7 @@ import json
5
5
  import logging
6
6
  import os
7
7
  import re
8
+ import sys
8
9
  from typing import Any
9
10
 
10
11
  from starbash.tool.base import (
@@ -66,6 +67,8 @@ class RCAstroTool(ExternalTool):
66
67
  # plenty of workflows never use them.
67
68
  ToolSeverity.OPTIONAL,
68
69
  )
70
+ if sys.platform == "win32":
71
+ self.commands.append(r"C:\Program Files\RC-Astro\CLI\rc-astro.exe")
69
72
 
70
73
  def set_defaults(self) -> None:
71
74
  super().set_defaults()
@@ -66,8 +66,15 @@ class StarnetTool(SirilTool):
66
66
 
67
67
  @staticmethod
68
68
  def _siril_config_dir() -> Path:
69
- """Location of the config directory of a natively installed Siril (OS-appropriate)."""
70
- return Path(PlatformDirs("siril").user_config_dir)
69
+ """Location of the config directory of a natively installed Siril (OS-appropriate).
70
+
71
+ ``appauthor=False`` matters on Windows: platformdirs appends the app author
72
+ (which defaults to the app name) *and* the app name, so ``PlatformDirs("siril")``
73
+ would resolve to ``AppData\\Local\\siril\\siril``. Siril keeps its config in
74
+ ``AppData\\Local\\siril`` (single level), so the author directory is dropped.
75
+ On Linux/macOS ``appauthor`` is ignored, so this is safe everywhere.
76
+ """
77
+ return Path(PlatformDirs("siril", appauthor=False).user_config_dir)
71
78
 
72
79
  @staticmethod
73
80
  def _siril_flatpak_config_dir() -> Path:
@@ -222,14 +229,58 @@ class StarnetTool(SirilTool):
222
229
  self._starnet_available = True
223
230
  return self._starnet_available
224
231
 
232
+ def invalidate_availability(self) -> None:
233
+ """Forget the cached StarNet probe, so the next check re-probes.
234
+
235
+ This tool keeps its own cache (``_starnet_available``, plus
236
+ ``_starnet_dangling`` for a StarNet that has gone missing since the probe),
237
+ and ``is_available`` never reads ``ExternalTool._is_available``: the base
238
+ implementation would therefore clear Siril's cached answer while StarNet's
239
+ stayed behind. The GUI setup wizard's *Re-check* button is the caller that
240
+ needs this - without the override it could never notice a StarNet installed
241
+ while the wizard was open.
242
+ """
243
+ self._starnet_available = None
244
+ # A stale path only describes the probe it was found in, so it goes with
245
+ # ``is_available``'s cached answer: a re-check that now succeeds must not
246
+ # keep reporting the last run's dead setting.
247
+ self._starnet_dangling = None
248
+ super().invalidate_availability()
249
+
225
250
  def missing_message(self) -> str:
226
- """Explain which of the two StarNet prerequisites is missing."""
251
+ """Explain which of StarNet's prerequisites is missing.
252
+
253
+ Three cases need three different fixes, so they are checked in order: Siril
254
+ missing (nothing can run), StarNet missing (nothing to run), and StarNet
255
+ present but Siril not able to use it. The install check is done here rather
256
+ than from the cached probe because "is StarNet installed *at all*" is
257
+ independent of what Siril's config says - a stale setting must not be
258
+ reported as an installed-but-misconfigured StarNet.
259
+ """
227
260
  if not super().is_available:
228
261
  # StarNet is a Siril plugin, so Siril has to come first.
229
262
  return (
230
263
  f"StarNet is a Siril plugin, but Siril was not found. Install Siril from "
231
264
  f"{SIRIL_INSTALL_URL} and then StarNet from {self.install_url}"
232
265
  )
266
+ if _find_starnet_executable() is None:
267
+ # No StarNet anywhere we look, so there is nothing for Siril to be pointed
268
+ # at yet and installing it is the only fix.
269
+ if self._starnet_dangling:
270
+ # Siril *does* name a StarNet, that install is simply gone - so the
271
+ # stale path is what the user will trip over. Say both: the download
272
+ # to make, and the setting that is waiting for something else.
273
+ return (
274
+ f"StarNet is not installed. Siril is configured to use "
275
+ f"{self._starnet_dangling}, but that file no longer exists - install "
276
+ f"StarNet from {self.install_url} and then point Siril at it "
277
+ f"(Preferences > Miscellaneous)"
278
+ )
279
+ return (
280
+ f"StarNet is not installed. Starbash could not find a starnet2 executable "
281
+ f"on your PATH or in StarNet's usual install location; download and "
282
+ f"install it from {self.install_url}"
283
+ )
233
284
  if self._starnet_dangling:
234
285
  return (
235
286
  f"StarNet is configured in Siril as {self._starnet_dangling}, but that "
@@ -677,25 +677,45 @@ class ToolsPage(SetupPage):
677
677
 
678
678
  # --- probing ----------------------------------------------------------
679
679
  @staticmethod
680
- def _recheck_required() -> list[ToolStatus]:
681
- """Re-probe the required tools, then report which are still missing.
682
-
683
- ``is_available`` caches its first answer, so a user who installs Siril
684
- while this page is open would otherwise keep seeing "missing" forever.
680
+ def _reprobe_tools() -> list[ToolStatus]:
681
+ """Drop **every** tool's cached probe, then report which gating tools are missing.
682
+
683
+ ``is_available`` caches its first answer for the life of the process, so a
684
+ refresh that does not drop that cache keeps reporting whatever the first
685
+ probe saw - and this page exists to notice a tool the user installed while
686
+ the wizard was open. All tools are re-probed, not just the ones that gate
687
+ the page: the cache is process-wide, and the main window's warning bar
688
+ re-reads it (`ToolWarningPanel.refresh()`) the moment the wizard closes, so a
689
+ StarNet installed during the wizard must not leave a stale bar behind.
690
+
691
+ Cheap enough for the GUI thread: every probe is a few filesystem lookups
692
+ (``shutil.which``/``Path.is_file``, plus StarNet reading Siril's config) and
693
+ no tool is ever executed to test it.
685
694
  """
686
695
  for tool in tools.values():
687
- if tool.status().severity >= ToolSeverity.REQUIRED:
688
- tool.invalidate_availability()
696
+ tool.invalidate_availability()
689
697
  return _required_tools_missing()
690
698
 
691
- def _on_recheck(self) -> None:
692
- """*Re-check* for one tool: forget the cached probe and repaint."""
693
- missing = self._recheck_required()
699
+ def _on_recheck(self, key: str) -> None:
700
+ """*Re-check* one row's tool: forget its cached probe, re-probe, repaint.
701
+
702
+ Only the row's **own** tool is re-probed: re-checking used to invalidate just
703
+ the tools that gate the page, which left a *recommended* tool's row (StarNet
704
+ has a button too) reading a cached answer for ever. ``_reprobe_tools()`` is
705
+ the wider path, taken when the page is left.
706
+ """
707
+ tool = tools.get(key)
708
+ if tool is not None:
709
+ tool.invalidate_availability()
710
+ # Read the status *now*, so the line below describes the re-probe rather
711
+ # than whatever refresh() saw before it.
712
+ status = next((s for s in tool_statuses() if s.key == key), None)
694
713
  self.refresh()
695
- if missing:
696
- self._status.setText(f"Still not found: {', '.join(t.name for t in missing)}")
697
- else:
698
- self._status.setText("Everything found — you can continue.")
714
+ if status is None: # a key with no registered tool: the repaint says enough
715
+ return
716
+ self._status.setText(
717
+ f"Found {status.name}." if status.available else f"Still not found: {status.name}"
718
+ )
699
719
 
700
720
  def _on_install(self, url: str) -> None:
701
721
  """Open a tool's install page in the user's browser."""
@@ -727,7 +747,9 @@ class ToolsPage(SetupPage):
727
747
  install.clicked.connect(lambda _checked=False, u=url: self._on_install(u))
728
748
  line.addWidget(install)
729
749
  recheck = QPushButton("Re-check")
730
- recheck.clicked.connect(lambda _checked=False: self._on_recheck())
750
+ # The row's own tool, not the page's gate: a *recommended* tool's row
751
+ # gets this button too, and only that tool's cache needs dropping.
752
+ recheck.clicked.connect(lambda _checked=False, k=status.key: self._on_recheck(k))
731
753
  line.addWidget(recheck)
732
754
 
733
755
  self._rows.addWidget(row)
@@ -760,8 +782,13 @@ class ToolsPage(SetupPage):
760
782
  return not _required_tools_missing()
761
783
 
762
784
  def validatePage(self) -> bool: # noqa: N802 - Qt API
763
- """Belt to :meth:`isComplete`'s braces, and the loud re-run failure."""
764
- missing = self._recheck_required()
785
+ """Belt to :meth:`isComplete`'s braces, and the loud re-run failure.
786
+
787
+ Leaving the page re-probes *every* tool (see :meth:`_reprobe_tools`), which is
788
+ also what makes the main window's warning bar correct as soon as the wizard
789
+ closes: it re-reads the same cached answers.
790
+ """
791
+ missing = self._reprobe_tools()
765
792
  self.refresh()
766
793
  if not missing:
767
794
  return True
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes