starbash 0.1.8__py3-none-any.whl → 0.1.10__py3-none-any.whl
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.
Potentially problematic release.
This version of starbash might be problematic. Click here for more details.
- repo/__init__.py +2 -1
- repo/manager.py +31 -268
- repo/repo.py +294 -0
- starbash/__init__.py +20 -0
- starbash/aliases.py +100 -0
- starbash/analytics.py +4 -0
- starbash/app.py +740 -151
- starbash/commands/__init__.py +0 -17
- starbash/commands/info.py +72 -3
- starbash/commands/process.py +154 -0
- starbash/commands/repo.py +185 -78
- starbash/commands/select.py +135 -44
- starbash/database.py +397 -155
- starbash/defaults/starbash.toml +35 -0
- starbash/main.py +4 -1
- starbash/paths.py +18 -2
- starbash/recipes/master_bias/starbash.toml +32 -19
- starbash/recipes/master_dark/starbash.toml +36 -0
- starbash/recipes/master_flat/starbash.toml +27 -17
- starbash/recipes/osc_dual_duo/starbash.py +1 -5
- starbash/recipes/osc_dual_duo/starbash.toml +8 -4
- starbash/recipes/osc_single_duo/starbash.toml +4 -4
- starbash/recipes/starbash.toml +28 -3
- starbash/selection.py +115 -46
- starbash/templates/repo/master.toml +13 -0
- starbash/templates/repo/processed.toml +10 -0
- starbash/templates/userconfig.toml +1 -1
- starbash/toml.py +29 -0
- starbash/tool.py +199 -67
- {starbash-0.1.8.dist-info → starbash-0.1.10.dist-info}/METADATA +20 -13
- starbash-0.1.10.dist-info/RECORD +40 -0
- starbash-0.1.8.dist-info/RECORD +0 -33
- {starbash-0.1.8.dist-info → starbash-0.1.10.dist-info}/WHEEL +0 -0
- {starbash-0.1.8.dist-info → starbash-0.1.10.dist-info}/entry_points.txt +0 -0
- {starbash-0.1.8.dist-info → starbash-0.1.10.dist-info}/licenses/LICENSE +0 -0
starbash/toml.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import tomlkit
|
|
2
|
+
from tomlkit.toml_file import TOMLFile
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from importlib import resources
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from starbash import url
|
|
8
|
+
|
|
9
|
+
def toml_from_template(template_name: str, dest_path: Path, overrides: dict[str, Any] = {}) -> tomlkit.TOMLDocument:
|
|
10
|
+
"""Load a TOML document from a template file.
|
|
11
|
+
expand {vars} in the template using the `overrides` dictionary.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
tomlstr = (
|
|
15
|
+
resources.files("starbash")
|
|
16
|
+
.joinpath(f"templates/{template_name}.toml")
|
|
17
|
+
.read_text()
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# add default vars always available
|
|
21
|
+
vars = {
|
|
22
|
+
"PROJECT_URL": url.project
|
|
23
|
+
}
|
|
24
|
+
vars.update(overrides)
|
|
25
|
+
tomlstr = tomlstr.format(**vars)
|
|
26
|
+
|
|
27
|
+
toml = tomlkit.parse(tomlstr)
|
|
28
|
+
TOMLFile(dest_path).write(toml)
|
|
29
|
+
return toml
|
starbash/tool.py
CHANGED
|
@@ -3,6 +3,7 @@ import shutil
|
|
|
3
3
|
import textwrap
|
|
4
4
|
import tempfile
|
|
5
5
|
import subprocess
|
|
6
|
+
import select
|
|
6
7
|
import re
|
|
7
8
|
|
|
8
9
|
import logging
|
|
@@ -44,13 +45,68 @@ def expand_context(s: str, context: dict) -> str:
|
|
|
44
45
|
|
|
45
46
|
# throw an error if any remaining unexpanded variables remain unexpanded
|
|
46
47
|
unexpanded_vars = re.findall(r"\{([^{}]+)\}", expanded)
|
|
48
|
+
|
|
49
|
+
# Remove duplicates
|
|
50
|
+
unexpanded_vars = list(dict.fromkeys(unexpanded_vars))
|
|
47
51
|
if unexpanded_vars:
|
|
48
52
|
raise KeyError("Missing context variable(s): " + ", ".join(unexpanded_vars))
|
|
49
53
|
|
|
50
54
|
return expanded
|
|
51
55
|
|
|
52
56
|
|
|
53
|
-
def
|
|
57
|
+
def expand_context_unsafe(s: str, context: dict) -> str:
|
|
58
|
+
"""Expand a string with Python expressions in curly braces using RestrictedPython.
|
|
59
|
+
|
|
60
|
+
Context variables are directly available in expressions without a prefix.
|
|
61
|
+
|
|
62
|
+
Supports expressions like:
|
|
63
|
+
- "foo {1 + 2}" -> "foo 3"
|
|
64
|
+
- "bar {name}" -> "bar <value of context['name']>"
|
|
65
|
+
- "path {instrument}/{date}/file.fits" -> "path MyScope/2025-01-01/file.fits"
|
|
66
|
+
- "sum {x + y}" -> "sum <value of context['x'] + context['y']>"
|
|
67
|
+
|
|
68
|
+
Args:
|
|
69
|
+
s: String with Python expressions in curly braces
|
|
70
|
+
context: Dictionary of variables available directly in expressions
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
String with all expressions evaluated and substituted
|
|
74
|
+
|
|
75
|
+
Raises:
|
|
76
|
+
ValueError: If any expression cannot be evaluated (syntax errors, missing variables, etc.)
|
|
77
|
+
|
|
78
|
+
Note: Uses RestrictedPython for safety, but still has security implications.
|
|
79
|
+
This is a more powerful but less safe alternative to expand_context().
|
|
80
|
+
"""
|
|
81
|
+
# Find all expressions in curly braces
|
|
82
|
+
pattern = r"\{([^{}]+)\}"
|
|
83
|
+
|
|
84
|
+
def eval_expression(match):
|
|
85
|
+
"""Evaluate a single expression and return its string representation."""
|
|
86
|
+
expr = match.group(1).strip()
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
# Compile the expression with RestrictedPython
|
|
90
|
+
byte_code = RestrictedPython.compile_restricted(
|
|
91
|
+
expr, filename="<template expression>", mode="eval"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Evaluate with safe globals and the context
|
|
95
|
+
result = eval(byte_code, make_safe_globals(context), None)
|
|
96
|
+
return str(result)
|
|
97
|
+
|
|
98
|
+
except Exception as e:
|
|
99
|
+
raise ValueError(f"Failed to evaluate expression '{expr}'") from e
|
|
100
|
+
|
|
101
|
+
# Replace all expressions
|
|
102
|
+
expanded = re.sub(pattern, eval_expression, s)
|
|
103
|
+
|
|
104
|
+
logger.debug(f"Unsafe expanded '{s}' into '{expanded}'")
|
|
105
|
+
|
|
106
|
+
return expanded
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def make_safe_globals(extra_globals: dict = {}) -> dict:
|
|
54
110
|
"""Generate a set of RestrictedPython globals for AstoGlue exec/eval usage"""
|
|
55
111
|
# Define the global and local namespaces for the restricted execution.
|
|
56
112
|
# FIXME - this is still unsafe, policies need to be added to limit import/getattr etc...
|
|
@@ -88,9 +144,9 @@ def make_safe_globals(context: dict = {}) -> dict:
|
|
|
88
144
|
"__name__": "__starbash_script__",
|
|
89
145
|
"__metaclass__": type,
|
|
90
146
|
# Extra globals auto imported into the scripts context
|
|
91
|
-
"context": context,
|
|
92
147
|
"logger": logging.getLogger("script"), # Allow logging within the script
|
|
93
148
|
}
|
|
149
|
+
execution_globals.update(extra_globals)
|
|
94
150
|
return execution_globals
|
|
95
151
|
|
|
96
152
|
|
|
@@ -106,67 +162,95 @@ def strip_comments(text: str) -> str:
|
|
|
106
162
|
return "\n".join(lines)
|
|
107
163
|
|
|
108
164
|
|
|
109
|
-
def tool_run(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
result = subprocess.run(
|
|
114
|
-
cmd, input=commands, shell=True, capture_output=True, text=True, cwd=cwd
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
if result.stderr:
|
|
118
|
-
logger.warning(f"Tool error message:\n{result.stderr.strip()}")
|
|
119
|
-
|
|
120
|
-
if result.returncode != 0:
|
|
121
|
-
# If we got an error, print the entire tool stdout as a warning
|
|
122
|
-
logger.warning(f"Tool output:\n{result.stdout.strip()}")
|
|
123
|
-
raise RuntimeError(f"Tool failed with exit code {result.returncode}")
|
|
124
|
-
else:
|
|
125
|
-
logger.debug("Tool command successful.")
|
|
165
|
+
def tool_run(
|
|
166
|
+
cmd: str, cwd: str, commands: str | None = None, timeout: float | None = None
|
|
167
|
+
) -> None:
|
|
168
|
+
"""Executes an external tool with an optional script of commands in a given working directory.
|
|
126
169
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
# siril_path = "/home/kevinh/packages/Siril-1.4.0~beta3-x86_64.AppImage"
|
|
132
|
-
siril_path = "org.siril.Siril" # flatpak
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def siril_run(temp_dir: str, commands: str, input_files: list[str] = []) -> None:
|
|
136
|
-
"""Executes Siril with a script of commands in a given working directory."""
|
|
137
|
-
|
|
138
|
-
# Create symbolic links for all input files in the temp directory
|
|
139
|
-
for f in input_files:
|
|
140
|
-
os.symlink(
|
|
141
|
-
os.path.abspath(str(f)), os.path.join(temp_dir, os.path.basename(str(f)))
|
|
142
|
-
)
|
|
170
|
+
Streams stdout and stderr in real-time to the logger, allowing you to see subprocess output
|
|
171
|
+
as it happens rather than waiting for completion.
|
|
172
|
+
"""
|
|
143
173
|
|
|
144
|
-
|
|
145
|
-
script_content = textwrap.dedent(
|
|
146
|
-
f"""
|
|
147
|
-
requires 1.4.0-beta3
|
|
148
|
-
{textwrap.dedent(strip_comments(commands))}
|
|
149
|
-
"""
|
|
150
|
-
)
|
|
174
|
+
logger.debug(f"Running {cmd} in {cwd}: stdin={commands}")
|
|
151
175
|
|
|
152
|
-
|
|
153
|
-
|
|
176
|
+
# Start the process with pipes for streaming
|
|
177
|
+
process = subprocess.Popen(
|
|
178
|
+
cmd,
|
|
179
|
+
stdin=subprocess.PIPE if commands else None,
|
|
180
|
+
stdout=subprocess.PIPE,
|
|
181
|
+
stderr=subprocess.PIPE,
|
|
182
|
+
shell=True,
|
|
183
|
+
text=True,
|
|
184
|
+
cwd=cwd,
|
|
154
185
|
)
|
|
155
186
|
|
|
156
|
-
#
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
187
|
+
# Send commands to stdin if provided
|
|
188
|
+
if commands and process.stdin:
|
|
189
|
+
try:
|
|
190
|
+
process.stdin.write(commands)
|
|
191
|
+
process.stdin.close()
|
|
192
|
+
except BrokenPipeError:
|
|
193
|
+
# Process may have terminated early
|
|
194
|
+
pass
|
|
195
|
+
|
|
196
|
+
# Stream output line by line in real-time
|
|
197
|
+
assert process.stdout
|
|
198
|
+
assert process.stderr
|
|
199
|
+
|
|
200
|
+
try:
|
|
201
|
+
streams = {
|
|
202
|
+
process.stdout.fileno(): (process.stdout, logger.debug, "tool-stdout"),
|
|
203
|
+
process.stderr.fileno(): (process.stderr, logger.warning, "tool-stderr"),
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
while streams:
|
|
207
|
+
# Wait for data on any stream (with timeout for periodic checking)
|
|
208
|
+
ready, _, _ = select.select(list(streams.keys()), [], [], 0.1)
|
|
209
|
+
|
|
210
|
+
for fd in ready:
|
|
211
|
+
stream, log_func, stream_name = streams[fd]
|
|
212
|
+
line = stream.readline()
|
|
213
|
+
|
|
214
|
+
if line:
|
|
215
|
+
# Strip trailing newline and log immediately
|
|
216
|
+
line = line.rstrip("\n")
|
|
217
|
+
log_func(f"[{stream_name}] {line}")
|
|
218
|
+
else:
|
|
219
|
+
# EOF reached on this stream
|
|
220
|
+
del streams[fd]
|
|
221
|
+
|
|
222
|
+
# Check if process has terminated
|
|
223
|
+
if process.poll() is not None and not streams:
|
|
224
|
+
break
|
|
225
|
+
|
|
226
|
+
# Wait for process to complete with timeout
|
|
227
|
+
try:
|
|
228
|
+
process.wait(timeout=timeout)
|
|
229
|
+
except subprocess.TimeoutExpired:
|
|
230
|
+
process.kill()
|
|
231
|
+
process.wait()
|
|
232
|
+
raise RuntimeError(f"Tool timed out after {timeout} seconds")
|
|
233
|
+
|
|
234
|
+
returncode = process.returncode
|
|
235
|
+
|
|
236
|
+
if returncode != 0:
|
|
237
|
+
raise RuntimeError(f"Tool failed with exit code {returncode}")
|
|
238
|
+
else:
|
|
239
|
+
logger.debug("Tool command successful.")
|
|
240
|
+
finally:
|
|
241
|
+
# Ensure streams are properly closed
|
|
242
|
+
if process.stdout:
|
|
243
|
+
process.stdout.close()
|
|
244
|
+
if process.stderr:
|
|
245
|
+
process.stderr.close()
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def executable_path(commands: list[str], name: str) -> str:
|
|
249
|
+
"""Find the correct executable path to run for the given tool"""
|
|
250
|
+
for cmd in commands:
|
|
251
|
+
if shutil.which(cmd):
|
|
252
|
+
return cmd
|
|
253
|
+
raise FileNotFoundError(f"{name} not found, you probably need to install it.")
|
|
170
254
|
|
|
171
255
|
|
|
172
256
|
class Tool:
|
|
@@ -177,6 +261,12 @@ class Tool:
|
|
|
177
261
|
|
|
178
262
|
# default script file name
|
|
179
263
|
self.default_script_file = None
|
|
264
|
+
self.set_defaults()
|
|
265
|
+
|
|
266
|
+
def set_defaults(self):
|
|
267
|
+
# default timeout in seconds, if you need to run a tool longer than this, you should change
|
|
268
|
+
# it before calling run()
|
|
269
|
+
self.timeout = 10.0
|
|
180
270
|
|
|
181
271
|
def run_in_temp_dir(self, commands: str, context: dict = {}) -> None:
|
|
182
272
|
"""Run commands inside this tool (with cwd pointing to a temp directory)"""
|
|
@@ -204,14 +294,50 @@ class SirilTool(Tool):
|
|
|
204
294
|
super().__init__("siril")
|
|
205
295
|
|
|
206
296
|
def run(self, cwd: str, commands: str, context: dict = {}) -> None:
|
|
297
|
+
"""Executes Siril with a script of commands in a given working directory."""
|
|
207
298
|
|
|
208
299
|
# Iteratively expand the command string to handle nested placeholders.
|
|
209
300
|
# The loop continues until the string no longer changes.
|
|
210
|
-
expanded =
|
|
301
|
+
expanded = expand_context_unsafe(commands, context)
|
|
211
302
|
|
|
212
303
|
input_files = context.get("input_files", [])
|
|
213
304
|
|
|
214
|
-
|
|
305
|
+
temp_dir = cwd
|
|
306
|
+
|
|
307
|
+
# siril_path = "/home/kevinh/packages/Siril-1.4.0~beta3-x86_64.AppImage"
|
|
308
|
+
# Possible siril commands, with preferred option first
|
|
309
|
+
siril_commands = ["org.siril.Siril", "siril-cli", "siril"]
|
|
310
|
+
siril_path = executable_path(siril_commands, "Siril")
|
|
311
|
+
if siril_path == "org.siril.Siril":
|
|
312
|
+
# The executable is inside a flatpak, so run the lighter/faster/no-gui required exe
|
|
313
|
+
# from inside the flatpak
|
|
314
|
+
siril_path = "flatpak run --command=siril-cli org.siril.Siril"
|
|
315
|
+
|
|
316
|
+
# Create symbolic links for all input files in the temp directory
|
|
317
|
+
for f in input_files:
|
|
318
|
+
os.symlink(
|
|
319
|
+
os.path.abspath(str(f)),
|
|
320
|
+
os.path.join(temp_dir, os.path.basename(str(f))),
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
# We dedent here because the commands are often indented multiline strings
|
|
324
|
+
script_content = textwrap.dedent(
|
|
325
|
+
f"""
|
|
326
|
+
requires 1.4.0-beta3
|
|
327
|
+
{textwrap.dedent(strip_comments(expanded))}
|
|
328
|
+
"""
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
logger.debug(
|
|
332
|
+
f"Running Siril in {temp_dir}, ({len(input_files)} input files) cmds:\n{script_content}"
|
|
333
|
+
)
|
|
334
|
+
logger.info(f"Running Siril ({len(input_files)} input files)")
|
|
335
|
+
|
|
336
|
+
# The `-s -` arguments tell Siril to run in script mode and read commands from stdin.
|
|
337
|
+
# It seems like the -d command may also be required when siril is in a flatpak
|
|
338
|
+
cmd = f"{siril_path} -d {temp_dir} -s -"
|
|
339
|
+
|
|
340
|
+
tool_run(cmd, temp_dir, script_content, timeout=self.timeout)
|
|
215
341
|
|
|
216
342
|
|
|
217
343
|
class GraxpertTool(Tool):
|
|
@@ -221,7 +347,12 @@ class GraxpertTool(Tool):
|
|
|
221
347
|
super().__init__("graxpert")
|
|
222
348
|
|
|
223
349
|
def run(self, cwd: str, commands: str, context: dict = {}) -> None:
|
|
224
|
-
|
|
350
|
+
"""Executes Graxpert with the specified command line arguments"""
|
|
351
|
+
|
|
352
|
+
# Arguments look similar to: graxpert -cmd background-extraction -output /tmp/testout tests/test_images/real_crummy.fits
|
|
353
|
+
cmd = f"graxpert {commands}"
|
|
354
|
+
|
|
355
|
+
tool_run(cmd, cwd, timeout=self.timeout)
|
|
225
356
|
|
|
226
357
|
|
|
227
358
|
class PythonTool(Tool):
|
|
@@ -245,16 +376,17 @@ class PythonTool(Tool):
|
|
|
245
376
|
)
|
|
246
377
|
# No locals yet
|
|
247
378
|
execution_locals = None
|
|
248
|
-
|
|
379
|
+
globals = {"context": context}
|
|
380
|
+
exec(byte_code, make_safe_globals(globals), execution_locals)
|
|
249
381
|
except SyntaxError as e:
|
|
250
|
-
|
|
251
|
-
raise
|
|
382
|
+
raise # Just rethrow - no need to rewrap
|
|
252
383
|
except Exception as e:
|
|
253
|
-
|
|
254
|
-
raise
|
|
384
|
+
raise ValueError(f"Error during python script execution") from e
|
|
255
385
|
finally:
|
|
256
386
|
os.chdir(original_cwd)
|
|
257
387
|
|
|
258
388
|
|
|
259
389
|
# A dictionary mapping tool names to their respective tool instances.
|
|
260
|
-
tools
|
|
390
|
+
tools: dict[str, Tool] = {
|
|
391
|
+
tool.name: tool for tool in [SirilTool(), GraxpertTool(), PythonTool()]
|
|
392
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: starbash
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
4
4
|
Summary: A tool for automating/standardizing/sharing astrophotography workflows.
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Author: Kevin Hester
|
|
@@ -20,7 +20,7 @@ Requires-Dist: tomlkit (>=0.13.3,<0.14.0)
|
|
|
20
20
|
Requires-Dist: typer (>=0.20.0,<0.21.0)
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
|
|
23
|
-
# Starbash
|
|
23
|
+
# [Starbash](https://github.com/geeksville/starbash)
|
|
24
24
|
|
|
25
25
|
<img src="https://raw.githubusercontent.com/geeksville/starbash/refs/heads/main/img/icon.png" alt="Starbash: Astrophotography workflows simplified" width="30%" align="right" style="margin-bottom: 20px;">
|
|
26
26
|
|
|
@@ -33,6 +33,7 @@ A tool for automating/standardizing/sharing astrophotography workflows.
|
|
|
33
33
|
* Automatic - with sensible defaults, that you can change as needed.
|
|
34
34
|
* Easy - provides a 'seestar like' starting-point for autoprocessing all your sessions (by default).
|
|
35
35
|
* Fast - even with large image repositories. Automatic master bias and flat generation and reasonable defaults
|
|
36
|
+
* Multi-session - by default. So your workflows can stack from multiple nights (and still use the correct flats etc...)
|
|
36
37
|
* Sharable - you can share/use recipes for image preprocessing flows.
|
|
37
38
|
|
|
38
39
|
(This project is currently 'alpha' and missing recipes for some workflows, but adding new recipes is easy and we're happy to help. Please file a github issue if your images are not auto-processed and we'll work out a fix.)
|
|
@@ -67,7 +68,7 @@ See the current [TODO](TODO.md) file for work items. I'll be looking for pre-al
|
|
|
67
68
|
|
|
68
69
|
Currently the easiest way to install this command-line based tool is to install is via [pipx](https://pipx.pypa.io/stable/). If you don't already have pipx and you have python installed, you can auto install it by running "pip install --user pipx." If you don't have python installed see the pipx link for pipx installers for any OS.
|
|
69
70
|
|
|
70
|
-
Once pipx is installed just run the following **two** commands (the sb --install-completion will make TAB auto-complete automatically complete sb options (for most platforms)):
|
|
71
|
+
Once pipx is installed just run the following **two** commands (the sb --install-completion will make TAB auto-complete automatically complete sb options (for most platforms)). Installing auto-complete is **highly** recommended because it makes entering starbash commands fast - by pressing the TAB key:
|
|
71
72
|
|
|
72
73
|
```
|
|
73
74
|
➜ pipx install starbash
|
|
@@ -88,10 +89,10 @@ FIXME - add getting started instructions (possibly with a screenshare video)
|
|
|
88
89
|
## Supported commands
|
|
89
90
|
|
|
90
91
|
### Repository Management
|
|
91
|
-
- `sb repo [--verbose]` - List installed repos (use `-v` for details)
|
|
92
|
-
- `sb repo add
|
|
93
|
-
- `sb repo remove <
|
|
94
|
-
- `sb repo reindex [--force]
|
|
92
|
+
- `sb repo list [--verbose]` - List installed repos (use `-v` for details)
|
|
93
|
+
- `sb repo add [--master] [filepath|URL]` - Add a repository, optionally specifying the type
|
|
94
|
+
- `sb repo remove <REPOURL>` - Remove the indicated repo from the repo list
|
|
95
|
+
- `sb repo reindex [--force] <REPOURL>` - Reindex the specified repo (or all repos if none specified)
|
|
95
96
|
|
|
96
97
|
### User Preferences
|
|
97
98
|
- `sb user name "Your Name"` - Set name for attribution in generated images
|
|
@@ -108,18 +109,19 @@ FIXME - add getting started instructions (possibly with a screenshare video)
|
|
|
108
109
|
- `sb select date <after|before|between> <DATE> [DATE]` - Limit to sessions in the specified date range
|
|
109
110
|
- `sb select export SESSIONNUM DESTDIR` - Export the images for indicated session number into the specified directory (or current directory if not specified). If possible symbolic links are used, if not the files are copied.
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
### Setup & Configuration
|
|
112
|
+
### Selection information
|
|
114
113
|
- `sb info` - Show user preferences location and other app info
|
|
115
114
|
- `sb info target` - List targets (filtered based on the current selection)
|
|
116
115
|
- `sb info telescope` - List instruments (filtered based on the current selection)
|
|
117
116
|
- `sb info filter` - List all filters found in current selection
|
|
117
|
+
- `sb info master [KIND]` - List all precalculated master images (darks, biases, flats). Optional KIND argument to filter by image type (e.g., BIAS, DARK, FLAT)
|
|
118
|
+
|
|
119
|
+
## Not yet supported commands
|
|
118
120
|
|
|
119
121
|
### Export & Processing
|
|
120
|
-
- `sb process siril` - Generate Siril directory tree and run Siril GUI
|
|
121
|
-
- `sb process auto` - Automatic processing
|
|
122
|
-
- `sb process masters` - Generate master flats, darks, and biases from available raw frames
|
|
122
|
+
- `sb process siril [--run] SESSIONNUM DESTDIR` - Generate Siril directory tree and optionally run Siril GUI
|
|
123
|
+
- `sb process auto [SESSIONNUM]` - Automatic processing. If session # is specified process only that session, otherwise all selected sessions will be processed
|
|
124
|
+
- `sb process masters` - Generate master flats, darks, and biases from available raw frames in the current selection
|
|
123
125
|
|
|
124
126
|
## Supported tools (now)
|
|
125
127
|
|
|
@@ -138,3 +140,8 @@ We try to make this project useful and friendly. If you find problems please fi
|
|
|
138
140
|
We accept pull-requests and enjoy discussing possible new development directions via github issues. If you might want to work on this, just describe what your interests are and we can talk about how to get it merged.
|
|
139
141
|
|
|
140
142
|
Project members can access crash reports [here](https://geeksville.sentry.io/insights/projects/starbash/?project=4510264204132352).
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
Copyright 2025 Kevin Hester, kevinh@geeksville.com.
|
|
147
|
+
Licensed under the [GPL v3](LICENSE)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
repo/__init__.py,sha256=St2udJPFek-KwjagkH23h8kBYJHyIXrXjQJpL2Vjz_s,229
|
|
2
|
+
repo/manager.py,sha256=4QEt4oRzlTcf75Q7gALBFhtZS_JXOJF6apnSYozRC5c,4812
|
|
3
|
+
repo/repo.py,sha256=7EgzEDzTDuluGFbGHLz_-tracze4jPuzerXJpjUaDKU,10680
|
|
4
|
+
starbash/__init__.py,sha256=0kEchneSvvuKV334VwULs3UZSIJ9Edsfvawuq39LJmo,1146
|
|
5
|
+
starbash/aliases.py,sha256=x2be5VsHmSgwT5WCR_jMjPhnVLhd4Mu1Gw4RctzgOqI,3779
|
|
6
|
+
starbash/analytics.py,sha256=XYe7PN-pymXmmv8x1C2mUV_wecTnY9gHjczUv3fjSo8,4346
|
|
7
|
+
starbash/app.py,sha256=UObVH6dBlWiCboCgRc1uY-2hhGV7tdlHUfIySc3wXg8,43227
|
|
8
|
+
starbash/commands/__init__.py,sha256=sapJ5w5PFGUfmXtUA1bGIFTr0_gf91Gw6rgCcmzmjUw,706
|
|
9
|
+
starbash/commands/info.py,sha256=hE3c7_OlCKir5dYM73p9dFsyfhlN1MuC0j0-BFSQlSs,6162
|
|
10
|
+
starbash/commands/process.py,sha256=c5fsLX0sZRzC_8baT2aZYOpqN57jttL5YEvSJH_U3LU,5236
|
|
11
|
+
starbash/commands/repo.py,sha256=ZIIwpTtvpIiekK2FgrTMU9kNl-df4YH7oBSxOIlP-Ek,8220
|
|
12
|
+
starbash/commands/select.py,sha256=OvViVLpu3jKTgaBGKNuHxXx2QZfUVDdFqYLDoMay5E8,14773
|
|
13
|
+
starbash/commands/user.py,sha256=MIJFhhWokoaBiZ6rKqQaSVxSvO_glwG5dTGhaZy-6PA,4249
|
|
14
|
+
starbash/database.py,sha256=oHE1n4Jf7U2dfd9ONk-iQct_KPx2S11cSj_t7ZylCIg,26843
|
|
15
|
+
starbash/defaults/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
|
+
starbash/defaults/starbash.toml,sha256=drG42Q-mOy88d6F31BSbAiN_FTkiGrZSv2wz114MlpM,3112
|
|
17
|
+
starbash/main.py,sha256=DdeV_w4P__q0sTcGjGUm5hBqIDurq8DUKoDQQaawsfA,1600
|
|
18
|
+
starbash/paths.py,sha256=Xr4ZE4yWA_3zu23n8TLXa-wfLRWpQtvjTte0KTMG798,1896
|
|
19
|
+
starbash/recipes/README.md,sha256=OC0CUAL7xhxujOtEg97vrdNLZmGPLusBeOnwTo5rKN8,317
|
|
20
|
+
starbash/recipes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
|
+
starbash/recipes/master_bias/starbash.toml,sha256=GAnpwEK9AV0G5agP50nUoJVW30OMDcRTkyMkW2b3sHY,2791
|
|
22
|
+
starbash/recipes/master_dark/starbash.toml,sha256=wynSMp3fQtTY6KtZZM5FGokFxLW2XtKwWNUZOSCqDhs,827
|
|
23
|
+
starbash/recipes/master_flat/starbash.toml,sha256=8Nd8jSSwGbNLPSZn37zIzNFRsmBR-VSDYQuwCOM3qD4,1775
|
|
24
|
+
starbash/recipes/osc_dual_duo/starbash.py,sha256=CkDhm-6sE4ZC44Rvlp6hO3dmBYEA0kfVHVNkJOni7JQ,5666
|
|
25
|
+
starbash/recipes/osc_dual_duo/starbash.toml,sha256=_BkkSn-iYFYIdJANbDKKMz0xAcVSGEU9kZaKsc5r0xI,3241
|
|
26
|
+
starbash/recipes/osc_single_duo/starbash.toml,sha256=Q0JRsv3SVBWie8LeK0xfY03c2dcN5JNLjjPJQKygUDk,2127
|
|
27
|
+
starbash/recipes/starbash.toml,sha256=CDTjGGSaUFpQ7rtLpG_T6xyToBLYsOiIEkRKBeRxitQ,1546
|
|
28
|
+
starbash/selection.py,sha256=404XPXA5nFtlyrFf4uikeJ5VNPShT_h5PBkQbx11IEQ,10964
|
|
29
|
+
starbash/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
+
starbash/templates/repo/master.toml,sha256=c53CXMdIPlw9E50LRabgHfyn2qOS0dhz7nmXBx0ETQA,392
|
|
31
|
+
starbash/templates/repo/processed.toml,sha256=jVsFjCkTGmIV5RfQ2yOIotLJRqXnPhYdxpQytuSJoKg,321
|
|
32
|
+
starbash/templates/userconfig.toml,sha256=4bpUQ5WlA2Ebbl6c5QxmS2-SXV4IxmN3-H9IghepQEQ,1459
|
|
33
|
+
starbash/toml.py,sha256=aNuCqsQ33HYDpWgr_9vpDpd80h2vOU2-kBQmkUqri7c,783
|
|
34
|
+
starbash/tool.py,sha256=uNWG3P8D77NQxdEdPEhy5pFfBf6-Kk1t6HTyZnRWCeo,13560
|
|
35
|
+
starbash/url.py,sha256=lorxQJ27jSfzsKCb0QvpcvLiPZG55Dkd_c1JPFbni4I,402
|
|
36
|
+
starbash-0.1.10.dist-info/METADATA,sha256=nqI8jba7u59wnkwlChR40t8ngeGmniL4UxED2K01dl8,7999
|
|
37
|
+
starbash-0.1.10.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
38
|
+
starbash-0.1.10.dist-info/entry_points.txt,sha256=REQyWs8e5TJsNK7JVVWowKVoytMmKlUwuFHLTmSX4hc,67
|
|
39
|
+
starbash-0.1.10.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
|
40
|
+
starbash-0.1.10.dist-info/RECORD,,
|
starbash-0.1.8.dist-info/RECORD
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
repo/__init__.py,sha256=TqspuLjPSNnO38tvCGa0fJvvasgecHl6fE7m0-Lj8ho,148
|
|
2
|
-
repo/manager.py,sha256=Fc_akPK7D8sw3961DM5BCQ7O27tnEdAutg8TSNiopgI,13903
|
|
3
|
-
starbash/__init__.py,sha256=JNkBTu--Wf10eSHDwcpMS2hOp1VeTHmOGAcKPSlLbyo,618
|
|
4
|
-
starbash/analytics.py,sha256=J1J8oXGZkdovXNkqOYGv12vl3p5EZEXHSXpcMrnUwzE,4122
|
|
5
|
-
starbash/app.py,sha256=-dx92jUc7_jOJEsncubiRy5SUqMy10343MlRcm1zd9k,17921
|
|
6
|
-
starbash/commands/__init__.py,sha256=J7XuX7EMXZg2EBJLvXmm8jAfyhY7Yt9bTvoDaptp0YU,1231
|
|
7
|
-
starbash/commands/info.py,sha256=ebYQsieYzkuemCmiSIOwi7EzKJZd7W5oCdprgu3l3Tk,4135
|
|
8
|
-
starbash/commands/repo.py,sha256=nPtt7vtkq0lMwkrL8qgsptV26MEathbPp3X2fVBn_ug,4950
|
|
9
|
-
starbash/commands/select.py,sha256=mjehAiIPg_v7IZ_IAgNTXxpHjYIcAlV9oGPCLiYHbT4,11371
|
|
10
|
-
starbash/commands/user.py,sha256=MIJFhhWokoaBiZ6rKqQaSVxSvO_glwG5dTGhaZy-6PA,4249
|
|
11
|
-
starbash/database.py,sha256=w7QzgtupzfGsKoSoBsHCHhukNr2RQnAO323LCWas5dI,17539
|
|
12
|
-
starbash/defaults/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
-
starbash/defaults/starbash.toml,sha256=gciQjE2Q5QgS1aUph9Y4icI0xpYeDOALkzpAjZiabIk,1737
|
|
14
|
-
starbash/main.py,sha256=BFmR-jP6RsXh9q6Gl3_3_F_4mMkYwEBhmox6fpz0Cyo,1492
|
|
15
|
-
starbash/paths.py,sha256=BKKnSXt3tOh16o7ljDcQLtWKIiepEmud9JFtzRwDHtg,1317
|
|
16
|
-
starbash/recipes/README.md,sha256=OC0CUAL7xhxujOtEg97vrdNLZmGPLusBeOnwTo5rKN8,317
|
|
17
|
-
starbash/recipes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
starbash/recipes/master_bias/starbash.toml,sha256=KX2hFDVnLaBBULYnNnlSqXkflW4wP_04MnSaREk2IgI,2122
|
|
19
|
-
starbash/recipes/master_flat/starbash.toml,sha256=HWZXjXbTiExsC6o5QNr1-5x37PBRo7XNwBEto8Ea-LE,1430
|
|
20
|
-
starbash/recipes/osc_dual_duo/starbash.py,sha256=2cI4L6-d50-mL4hY0Oe6ad1v7g18D7ud0Hn0AlHZDOk,5788
|
|
21
|
-
starbash/recipes/osc_dual_duo/starbash.toml,sha256=xh3zEqdotRZr7eUcqel-xnQcWH8z-PUFRuWQfLp3F_E,3195
|
|
22
|
-
starbash/recipes/osc_single_duo/starbash.toml,sha256=kB-FMek0Z-8vieUfxKqmZMFNnZsSKdufSkLSgH03CkY,2117
|
|
23
|
-
starbash/recipes/starbash.toml,sha256=iZs0nLGY1kox0wa5ZzX9t2xTffy4Jbu_Q221Egnsml8,1019
|
|
24
|
-
starbash/selection.py,sha256=DPzUlls3n-sBqkwTUns2ZNaPi61PGnh7Z_ZQOC1jXYc,8347
|
|
25
|
-
starbash/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
|
-
starbash/templates/userconfig.toml,sha256=LCV69jAxLrIPXrkt6U-gU4KLKeb9MHCD1ownqG211Ns,1442
|
|
27
|
-
starbash/tool.py,sha256=S1kOTbeHTrA0meqwftgL0SA4VhJdZWWx2h1Wtwu1Izg,8749
|
|
28
|
-
starbash/url.py,sha256=lorxQJ27jSfzsKCb0QvpcvLiPZG55Dkd_c1JPFbni4I,402
|
|
29
|
-
starbash-0.1.8.dist-info/METADATA,sha256=mEG49YmhE8HSzhWni1dfS8JOzJ2rDYIB_vKI3nmFAUA,7215
|
|
30
|
-
starbash-0.1.8.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
31
|
-
starbash-0.1.8.dist-info/entry_points.txt,sha256=REQyWs8e5TJsNK7JVVWowKVoytMmKlUwuFHLTmSX4hc,67
|
|
32
|
-
starbash-0.1.8.dist-info/licenses/LICENSE,sha256=ixuiBLtpoK3iv89l7ylKkg9rs2GzF9ukPH7ynZYzK5s,35148
|
|
33
|
-
starbash-0.1.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|