starbash 0.1.1__tar.gz → 0.1.3__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.
Potentially problematic release.
This version of starbash might be problematic. Click here for more details.
- starbash-0.1.3/PKG-INFO +114 -0
- starbash-0.1.3/README.md +92 -0
- {starbash-0.1.1 → starbash-0.1.3}/pyproject.toml +1 -1
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/app.py +82 -8
- starbash-0.1.3/src/starbash/commands/repo.py +133 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/commands/selection.py +21 -1
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/database.py +141 -20
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/defaults/starbash.toml +0 -32
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/main.py +7 -1
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/repo/manager.py +5 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/selection.py +36 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/templates/userconfig.toml +32 -0
- starbash-0.1.1/PKG-INFO +0 -96
- starbash-0.1.1/README.md +0 -73
- starbash-0.1.1/src/starbash/commands/repo.py +0 -68
- {starbash-0.1.1 → starbash-0.1.3}/LICENSE +0 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/__init__.py +0 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/analytics.py +0 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/commands/__init__.py +0 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/commands/user.py +0 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/defaults/__init__.py +0 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/paths.py +0 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/repo/__init__.py +0 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/templates/__init__.py +0 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/tool.py +0 -0
- {starbash-0.1.1 → starbash-0.1.3}/src/starbash/url.py +0 -0
starbash-0.1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: starbash
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary:
|
|
5
|
+
License-File: LICENSE
|
|
6
|
+
Author: Kevin Hester
|
|
7
|
+
Author-email: kevinh@geeksville.com
|
|
8
|
+
Requires-Python: >=3.12,<3.15
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Requires-Dist: astropy (>=7.1.1,<8.0.0)
|
|
14
|
+
Requires-Dist: multidict (>=6.7.0,<7.0.0)
|
|
15
|
+
Requires-Dist: platformdirs (>=4.5.0,<5.0.0)
|
|
16
|
+
Requires-Dist: restrictedpython (>=8.1,<9.0)
|
|
17
|
+
Requires-Dist: rich (>=14.2.0,<15.0.0)
|
|
18
|
+
Requires-Dist: sentry-sdk (>=2.42.1,<3.0.0)
|
|
19
|
+
Requires-Dist: tomlkit (>=0.13.3,<0.14.0)
|
|
20
|
+
Requires-Dist: typer (>=0.20.0,<0.21.0)
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# Starbash
|
|
24
|
+
|
|
25
|
+

|
|
26
|
+

|
|
27
|
+
|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
A tool for automating/standardizing/sharing astrophotography workflows.
|
|
31
|
+
|
|
32
|
+
# Current status
|
|
33
|
+
|
|
34
|
+
Not quite ready 😊. But making good progress.
|
|
35
|
+
|
|
36
|
+
See the current [TODO](TODO.md) file for work items. I'll be looking for pre-alpha testers/feedback soon.
|
|
37
|
+
|
|
38
|
+
## Current features
|
|
39
|
+
|
|
40
|
+
* Automatically recognizes and auto-parses the default NINA, Asiair and Seestar raw file repos (adding support for other layouts is easy)
|
|
41
|
+
* Multisession support by default (including automatic selection of correct flats, biases and dark frames)
|
|
42
|
+
* 'Repos' can contain raw files, generated masters, preprocessed files, or recipes.
|
|
43
|
+
|
|
44
|
+
## Features coming soon
|
|
45
|
+
|
|
46
|
+
* Automatically performs **complete** preprocessing on OSC (broadband, narrowband or dual Duo filter), Mono (LRGB, SHO) data. i.e. give you 'seestar level' auto-preprocessing, so you only need to do the (optional) custom post-processing.
|
|
47
|
+
* Generates a per target report/config file which can be customized if the detected defaults or preprocessing are not what you want
|
|
48
|
+
* 'Recipes' provide repeatable/human-readable/sharable descriptions of all processing steps
|
|
49
|
+
* Repos can be on the local disk or shared via HTTPS/github/etc. This is particularly useful for recipe repos
|
|
50
|
+
* Uses Siril and Graxpert for its pre-processing operations (support for Pixinsight based recipies will probably be coming at some point...)
|
|
51
|
+
* The target report can be used to auto generate a human friendly 'postable/sharable' report about that image
|
|
52
|
+
* Target reports are sharable so that you can request comments by others and others can rerender with different settings
|
|
53
|
+
|
|
54
|
+
## Installing
|
|
55
|
+
|
|
56
|
+
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.
|
|
57
|
+
|
|
58
|
+
Once pipx is installed just run:
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
pipx install starbash
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Supported commands
|
|
65
|
+
|
|
66
|
+
### Setup & Configuration
|
|
67
|
+
- `sb setup` - Configure starbash via a brief guided process
|
|
68
|
+
- `sb info` - Show user preferences location and other app info
|
|
69
|
+
|
|
70
|
+
### Repository Management
|
|
71
|
+
- `sb repo [--verbose]` - List installed repos (use `-v` for details)
|
|
72
|
+
- `sb repo add <filepath|URL>` - Add a repository
|
|
73
|
+
- `sb repo remove <REPONUM>` - Remove the indicated repo from the repo list
|
|
74
|
+
- `sb repo reindex [--force] [REPONUM]` - Reindex the specified repo (or all repos if none specified)
|
|
75
|
+
|
|
76
|
+
### User Preferences
|
|
77
|
+
- `sb user name "Your Name"` - Set name for attribution in generated images
|
|
78
|
+
- `sb user email "foo@example.com"` - Set email for attribution in generated images
|
|
79
|
+
- `sb user analytics <on|off>` - Turn analytics collection on/off
|
|
80
|
+
|
|
81
|
+
### Selection & Filtering
|
|
82
|
+
- `sb selection` - Show information about the current selection
|
|
83
|
+
- `sb selection any` - Remove all filters (select everything)
|
|
84
|
+
- `sb selection target <TARGETNAME>` - Limit selection to the named target
|
|
85
|
+
- `sb selection telescope <TELESCOPENAME>` - Limit selection to the named telescope
|
|
86
|
+
- `sb selection date <after|before|between> <DATE> [DATE]` - Limit to sessions in the specified date range
|
|
87
|
+
|
|
88
|
+
### Viewing Data
|
|
89
|
+
- `sb session` - List sessions (filtered based on the current selection)
|
|
90
|
+
- `sb target` - List targets (filtered based on the current selection)
|
|
91
|
+
- `sb instrument` - List instruments (filtered based on the current selection)
|
|
92
|
+
- `sb filter` - List all filters found in current selection
|
|
93
|
+
|
|
94
|
+
### Export & Processing
|
|
95
|
+
- `sb export <dirs|BIAS|LIGHT|DARK|FLAT> [DIRLOC]` - Export data
|
|
96
|
+
- `sb process siril` - Generate Siril directory tree and run Siril GUI
|
|
97
|
+
- `sb process auto` - Automatic processing
|
|
98
|
+
- `sb process masters` - Generate master flats, darks, and biases from available raw frames
|
|
99
|
+
|
|
100
|
+
## Supported tools (now)
|
|
101
|
+
|
|
102
|
+
* Siril
|
|
103
|
+
* Graxpert
|
|
104
|
+
* Python (you can add python code to recipies if necessary)
|
|
105
|
+
|
|
106
|
+
## Supported tools (future?)
|
|
107
|
+
|
|
108
|
+
* Pixinsight?
|
|
109
|
+
* Autostakkert?
|
|
110
|
+
|
|
111
|
+
## Developing
|
|
112
|
+
|
|
113
|
+
We try to make this project useful and friendly. If you find problems please file a github issue.
|
|
114
|
+
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.
|
starbash-0.1.3/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Starbash
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+
|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
A tool for automating/standardizing/sharing astrophotography workflows.
|
|
9
|
+
|
|
10
|
+
# Current status
|
|
11
|
+
|
|
12
|
+
Not quite ready 😊. But making good progress.
|
|
13
|
+
|
|
14
|
+
See the current [TODO](TODO.md) file for work items. I'll be looking for pre-alpha testers/feedback soon.
|
|
15
|
+
|
|
16
|
+
## Current features
|
|
17
|
+
|
|
18
|
+
* Automatically recognizes and auto-parses the default NINA, Asiair and Seestar raw file repos (adding support for other layouts is easy)
|
|
19
|
+
* Multisession support by default (including automatic selection of correct flats, biases and dark frames)
|
|
20
|
+
* 'Repos' can contain raw files, generated masters, preprocessed files, or recipes.
|
|
21
|
+
|
|
22
|
+
## Features coming soon
|
|
23
|
+
|
|
24
|
+
* Automatically performs **complete** preprocessing on OSC (broadband, narrowband or dual Duo filter), Mono (LRGB, SHO) data. i.e. give you 'seestar level' auto-preprocessing, so you only need to do the (optional) custom post-processing.
|
|
25
|
+
* Generates a per target report/config file which can be customized if the detected defaults or preprocessing are not what you want
|
|
26
|
+
* 'Recipes' provide repeatable/human-readable/sharable descriptions of all processing steps
|
|
27
|
+
* Repos can be on the local disk or shared via HTTPS/github/etc. This is particularly useful for recipe repos
|
|
28
|
+
* Uses Siril and Graxpert for its pre-processing operations (support for Pixinsight based recipies will probably be coming at some point...)
|
|
29
|
+
* The target report can be used to auto generate a human friendly 'postable/sharable' report about that image
|
|
30
|
+
* Target reports are sharable so that you can request comments by others and others can rerender with different settings
|
|
31
|
+
|
|
32
|
+
## Installing
|
|
33
|
+
|
|
34
|
+
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.
|
|
35
|
+
|
|
36
|
+
Once pipx is installed just run:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
pipx install starbash
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Supported commands
|
|
43
|
+
|
|
44
|
+
### Setup & Configuration
|
|
45
|
+
- `sb setup` - Configure starbash via a brief guided process
|
|
46
|
+
- `sb info` - Show user preferences location and other app info
|
|
47
|
+
|
|
48
|
+
### Repository Management
|
|
49
|
+
- `sb repo [--verbose]` - List installed repos (use `-v` for details)
|
|
50
|
+
- `sb repo add <filepath|URL>` - Add a repository
|
|
51
|
+
- `sb repo remove <REPONUM>` - Remove the indicated repo from the repo list
|
|
52
|
+
- `sb repo reindex [--force] [REPONUM]` - Reindex the specified repo (or all repos if none specified)
|
|
53
|
+
|
|
54
|
+
### User Preferences
|
|
55
|
+
- `sb user name "Your Name"` - Set name for attribution in generated images
|
|
56
|
+
- `sb user email "foo@example.com"` - Set email for attribution in generated images
|
|
57
|
+
- `sb user analytics <on|off>` - Turn analytics collection on/off
|
|
58
|
+
|
|
59
|
+
### Selection & Filtering
|
|
60
|
+
- `sb selection` - Show information about the current selection
|
|
61
|
+
- `sb selection any` - Remove all filters (select everything)
|
|
62
|
+
- `sb selection target <TARGETNAME>` - Limit selection to the named target
|
|
63
|
+
- `sb selection telescope <TELESCOPENAME>` - Limit selection to the named telescope
|
|
64
|
+
- `sb selection date <after|before|between> <DATE> [DATE]` - Limit to sessions in the specified date range
|
|
65
|
+
|
|
66
|
+
### Viewing Data
|
|
67
|
+
- `sb session` - List sessions (filtered based on the current selection)
|
|
68
|
+
- `sb target` - List targets (filtered based on the current selection)
|
|
69
|
+
- `sb instrument` - List instruments (filtered based on the current selection)
|
|
70
|
+
- `sb filter` - List all filters found in current selection
|
|
71
|
+
|
|
72
|
+
### Export & Processing
|
|
73
|
+
- `sb export <dirs|BIAS|LIGHT|DARK|FLAT> [DIRLOC]` - Export data
|
|
74
|
+
- `sb process siril` - Generate Siril directory tree and run Siril GUI
|
|
75
|
+
- `sb process auto` - Automatic processing
|
|
76
|
+
- `sb process masters` - Generate master flats, darks, and biases from available raw frames
|
|
77
|
+
|
|
78
|
+
## Supported tools (now)
|
|
79
|
+
|
|
80
|
+
* Siril
|
|
81
|
+
* Graxpert
|
|
82
|
+
* Python (you can add python code to recipies if necessary)
|
|
83
|
+
|
|
84
|
+
## Supported tools (future?)
|
|
85
|
+
|
|
86
|
+
* Pixinsight?
|
|
87
|
+
* Autostakkert?
|
|
88
|
+
|
|
89
|
+
## Developing
|
|
90
|
+
|
|
91
|
+
We try to make this project useful and friendly. If you find problems please file a github issue.
|
|
92
|
+
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.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from importlib import resources
|
|
3
3
|
from pathlib import Path
|
|
4
|
-
|
|
4
|
+
import typer
|
|
5
5
|
import tomlkit
|
|
6
6
|
from tomlkit.toml_file import TOMLFile
|
|
7
7
|
import glob
|
|
@@ -10,6 +10,7 @@ from astropy.io import fits
|
|
|
10
10
|
import itertools
|
|
11
11
|
from rich.progress import track
|
|
12
12
|
from rich.logging import RichHandler
|
|
13
|
+
|
|
13
14
|
from starbash.database import Database
|
|
14
15
|
from starbash.repo.manager import Repo
|
|
15
16
|
from starbash.tool import Tool
|
|
@@ -117,7 +118,8 @@ class Starbash:
|
|
|
117
118
|
|
|
118
119
|
def __exit__(self, exc_type, exc, tb) -> bool:
|
|
119
120
|
handled = False
|
|
120
|
-
|
|
121
|
+
# Don't suppress typer.Exit - it's used for controlled exit codes
|
|
122
|
+
if exc and not isinstance(exc, typer.Exit):
|
|
121
123
|
handled = analytics_exception(exc)
|
|
122
124
|
self.close()
|
|
123
125
|
return handled
|
|
@@ -128,11 +130,12 @@ class Starbash:
|
|
|
128
130
|
date = header.get(Database.DATE_OBS_KEY)
|
|
129
131
|
if not date or not image_type:
|
|
130
132
|
logging.warning(
|
|
131
|
-
"Image %s missing
|
|
133
|
+
"Image %s missing either DATE-OBS or IMAGETYP FITS header, skipping...",
|
|
132
134
|
f,
|
|
133
135
|
)
|
|
134
136
|
else:
|
|
135
137
|
exptime = header.get(Database.EXPTIME_KEY, 0)
|
|
138
|
+
telescop = header.get(Database.TELESCOP_KEY, "unspecified")
|
|
136
139
|
new = {
|
|
137
140
|
Database.FILTER_KEY: filter,
|
|
138
141
|
Database.START_KEY: date,
|
|
@@ -142,6 +145,7 @@ class Starbash:
|
|
|
142
145
|
Database.NUM_IMAGES_KEY: 1,
|
|
143
146
|
Database.EXPTIME_TOTAL_KEY: exptime,
|
|
144
147
|
Database.OBJECT_KEY: header.get(Database.OBJECT_KEY, "unspecified"),
|
|
148
|
+
Database.TELESCOP_KEY: telescop,
|
|
145
149
|
}
|
|
146
150
|
session = self.db.get_session(new)
|
|
147
151
|
self.db.upsert_session(new, existing=session)
|
|
@@ -156,16 +160,86 @@ class Starbash:
|
|
|
156
160
|
conditions = self.selection.get_query_conditions()
|
|
157
161
|
return self.db.search_session(conditions)
|
|
158
162
|
|
|
163
|
+
def get_session_images(self, session_id: int) -> list[dict[str, Any]]:
|
|
164
|
+
"""
|
|
165
|
+
Get all images belonging to a specific session.
|
|
166
|
+
|
|
167
|
+
Sessions are defined by a unique combination of filter, imagetyp (image type),
|
|
168
|
+
object (target name), telescope, and date range. This method queries the images
|
|
169
|
+
table for all images matching the session's criteria in a single database query.
|
|
170
|
+
|
|
171
|
+
Args:
|
|
172
|
+
session_id: The database ID of the session
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
List of image records (dictionaries with path, metadata, etc.)
|
|
176
|
+
Returns empty list if session not found or has no images.
|
|
177
|
+
|
|
178
|
+
Raises:
|
|
179
|
+
ValueError: If session_id is not found in the database
|
|
180
|
+
"""
|
|
181
|
+
# First get the session details
|
|
182
|
+
session = self.db.get_session_by_id(session_id)
|
|
183
|
+
if session is None:
|
|
184
|
+
raise ValueError(f"Session with id {session_id} not found")
|
|
185
|
+
|
|
186
|
+
# Query images that match ALL session criteria including date range
|
|
187
|
+
conditions = {
|
|
188
|
+
Database.FILTER_KEY: session[Database.FILTER_KEY],
|
|
189
|
+
Database.IMAGETYP_KEY: session[Database.IMAGETYP_KEY],
|
|
190
|
+
Database.OBJECT_KEY: session[Database.OBJECT_KEY],
|
|
191
|
+
Database.TELESCOP_KEY: session[Database.TELESCOP_KEY],
|
|
192
|
+
"date_start": session[Database.START_KEY],
|
|
193
|
+
"date_end": session[Database.END_KEY],
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
# Single query with all conditions
|
|
197
|
+
images = self.db.search_image(conditions)
|
|
198
|
+
return images if images else []
|
|
199
|
+
|
|
200
|
+
def remove_repo_ref(self, url: str) -> None:
|
|
201
|
+
"""
|
|
202
|
+
Remove a repository reference from the user configuration.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
url: The repository URL to remove (e.g., 'file:///path/to/repo')
|
|
206
|
+
|
|
207
|
+
Raises:
|
|
208
|
+
ValueError: If the repository URL is not found in user configuration
|
|
209
|
+
"""
|
|
210
|
+
# Get the repo-ref list from user config
|
|
211
|
+
repo_refs = self.user_repo.config.get("repo-ref")
|
|
212
|
+
|
|
213
|
+
if not repo_refs:
|
|
214
|
+
raise ValueError(f"No repository references found in user configuration.")
|
|
215
|
+
|
|
216
|
+
# Find and remove the matching repo-ref
|
|
217
|
+
found = False
|
|
218
|
+
refs_copy = [r for r in repo_refs] # Make a copy to iterate
|
|
219
|
+
for ref in refs_copy:
|
|
220
|
+
ref_dir = ref.get("dir", "")
|
|
221
|
+
# Match by converting to file:// URL format if needed
|
|
222
|
+
if ref_dir == url or f"file://{ref_dir}" == url:
|
|
223
|
+
repo_refs.remove(ref)
|
|
224
|
+
found = True
|
|
225
|
+
break
|
|
226
|
+
|
|
227
|
+
if not found:
|
|
228
|
+
raise ValueError(f"Repository '{url}' not found in user configuration.")
|
|
229
|
+
|
|
230
|
+
# Write the updated config
|
|
231
|
+
self.user_repo.write_config()
|
|
232
|
+
|
|
159
233
|
def reindex_repo(self, repo: Repo, force: bool = False):
|
|
160
234
|
"""Reindex all repositories managed by the RepoManager."""
|
|
161
235
|
# FIXME, add a method to get just the repos that contain images
|
|
162
236
|
if repo.is_scheme("file") and repo.kind != "recipe":
|
|
163
237
|
logging.debug("Reindexing %s...", repo.url)
|
|
164
238
|
|
|
239
|
+
whitelist = None
|
|
165
240
|
config = self.repo_manager.merged.get("config")
|
|
166
|
-
if
|
|
167
|
-
|
|
168
|
-
whitelist = config["fits-whitelist"]
|
|
241
|
+
if config:
|
|
242
|
+
whitelist = config.get("fits-whitelist", None)
|
|
169
243
|
|
|
170
244
|
path = repo.get_path()
|
|
171
245
|
if not path:
|
|
@@ -191,7 +265,7 @@ class Starbash:
|
|
|
191
265
|
items = header.items()
|
|
192
266
|
headers = {}
|
|
193
267
|
for key, value in items:
|
|
194
|
-
if key in whitelist:
|
|
268
|
+
if (not whitelist) or (key in whitelist):
|
|
195
269
|
headers[key] = value
|
|
196
270
|
logging.debug("Headers for %s: %s", f, headers)
|
|
197
271
|
headers["path"] = str(f)
|
|
@@ -207,7 +281,7 @@ class Starbash:
|
|
|
207
281
|
|
|
208
282
|
def reindex_repos(self, force: bool = False):
|
|
209
283
|
"""Reindex all repositories managed by the RepoManager."""
|
|
210
|
-
logging.
|
|
284
|
+
logging.debug("Reindexing all repositories...")
|
|
211
285
|
|
|
212
286
|
for repo in track(self.repo_manager.repos, description="Reindexing repos..."):
|
|
213
287
|
self.reindex_repo(repo, force=force)
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
from typing_extensions import Annotated
|
|
3
|
+
|
|
4
|
+
from starbash.app import Starbash
|
|
5
|
+
from starbash import console
|
|
6
|
+
|
|
7
|
+
app = typer.Typer(invoke_without_command=True)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@app.callback()
|
|
11
|
+
def main(
|
|
12
|
+
ctx: typer.Context,
|
|
13
|
+
verbose: bool = typer.Option(
|
|
14
|
+
False, "--verbose", "-v", help="Show all repos including system repos"
|
|
15
|
+
),
|
|
16
|
+
):
|
|
17
|
+
"""
|
|
18
|
+
Manage repositories.
|
|
19
|
+
|
|
20
|
+
When called without a subcommand, lists all repositories.
|
|
21
|
+
Use --verbose to show all repos including system/recipe repos.
|
|
22
|
+
"""
|
|
23
|
+
# If no subcommand is invoked, run the list behavior
|
|
24
|
+
if ctx.invoked_subcommand is None:
|
|
25
|
+
with Starbash("repo-list") as sb:
|
|
26
|
+
repos = sb.repo_manager.repos if verbose else sb.repo_manager.regular_repos
|
|
27
|
+
for i, repo in enumerate(repos):
|
|
28
|
+
if verbose:
|
|
29
|
+
# No numbers for verbose mode (system repos can't be removed)
|
|
30
|
+
console.print(f"{ repo.url } (kind={ repo.kind})")
|
|
31
|
+
else:
|
|
32
|
+
# Show numbers for user repos (can be removed later)
|
|
33
|
+
console.print(f"{ i + 1:2}: { repo.url } (kind={ repo.kind})")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@app.command()
|
|
37
|
+
def add(path: str):
|
|
38
|
+
"""
|
|
39
|
+
Add a repository. path is either a local path or a remote URL.
|
|
40
|
+
"""
|
|
41
|
+
with Starbash("repo-add") as sb:
|
|
42
|
+
sb.user_repo.add_repo_ref(path)
|
|
43
|
+
# we don't yet write default config files at roots of repos, but it would be easy to add here
|
|
44
|
+
# r.write_config()
|
|
45
|
+
sb.user_repo.write_config()
|
|
46
|
+
# FIXME, we also need to index the newly added repo!!!
|
|
47
|
+
console.print(f"Added repository: {path}")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@app.command()
|
|
51
|
+
def remove(reponum: str):
|
|
52
|
+
"""
|
|
53
|
+
Remove a repository by number (from list).
|
|
54
|
+
Use 'starbash repo' to see the repository numbers.
|
|
55
|
+
"""
|
|
56
|
+
with Starbash("repo-remove") as sb:
|
|
57
|
+
try:
|
|
58
|
+
# Parse the repo number (1-indexed)
|
|
59
|
+
repo_index = int(reponum) - 1
|
|
60
|
+
|
|
61
|
+
# Get only the regular (user-visible) repos
|
|
62
|
+
regular_repos = sb.repo_manager.regular_repos
|
|
63
|
+
|
|
64
|
+
if repo_index < 0 or repo_index >= len(regular_repos):
|
|
65
|
+
console.print(
|
|
66
|
+
f"[red]Error: Repository number {reponum} is out of range. Valid range: 1-{len(regular_repos)}[/red]"
|
|
67
|
+
)
|
|
68
|
+
raise typer.Exit(code=1)
|
|
69
|
+
|
|
70
|
+
# Get the repo to remove
|
|
71
|
+
repo_to_remove = regular_repos[repo_index]
|
|
72
|
+
repo_url = repo_to_remove.url
|
|
73
|
+
|
|
74
|
+
# Remove the repo reference from user config
|
|
75
|
+
sb.remove_repo_ref(repo_url)
|
|
76
|
+
console.print(f"[green]Removed repository: {repo_url}[/green]")
|
|
77
|
+
|
|
78
|
+
except ValueError:
|
|
79
|
+
console.print(
|
|
80
|
+
f"[red]Error: '{reponum}' is not a valid repository number. Please use a number from 'repo list'.[/red]"
|
|
81
|
+
)
|
|
82
|
+
raise typer.Exit(code=1)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
@app.command()
|
|
86
|
+
def reindex(
|
|
87
|
+
reponum: Annotated[
|
|
88
|
+
str | None,
|
|
89
|
+
typer.Argument(help="The repository number, if not specified reindex all."),
|
|
90
|
+
] = None,
|
|
91
|
+
force: bool = typer.Option(
|
|
92
|
+
default=False, help="Reread FITS headers, even if they are already indexed."
|
|
93
|
+
),
|
|
94
|
+
):
|
|
95
|
+
"""
|
|
96
|
+
Reindex a repository by number.
|
|
97
|
+
If no number is given, reindex all repositories.
|
|
98
|
+
Use 'starbash repo' to see the repository numbers.
|
|
99
|
+
"""
|
|
100
|
+
with Starbash("repo-reindex") as sb:
|
|
101
|
+
if reponum is None:
|
|
102
|
+
sb.reindex_repos(force=force)
|
|
103
|
+
else:
|
|
104
|
+
try:
|
|
105
|
+
# Parse the repo number (1-indexed)
|
|
106
|
+
repo_index = int(reponum) - 1
|
|
107
|
+
|
|
108
|
+
# Get only the regular (user-visible) repos
|
|
109
|
+
regular_repos = sb.repo_manager.regular_repos
|
|
110
|
+
|
|
111
|
+
if repo_index < 0 or repo_index >= len(regular_repos):
|
|
112
|
+
console.print(
|
|
113
|
+
f"[red]Error: Repository number {reponum} is out of range. Valid range: 1-{len(regular_repos)}[/red]"
|
|
114
|
+
)
|
|
115
|
+
raise typer.Exit(code=1)
|
|
116
|
+
|
|
117
|
+
# Get the repo to reindex
|
|
118
|
+
repo_to_reindex = regular_repos[repo_index]
|
|
119
|
+
console.print(f"Reindexing repository: {repo_to_reindex.url}")
|
|
120
|
+
sb.reindex_repo(repo_to_reindex, force=force)
|
|
121
|
+
console.print(
|
|
122
|
+
f"[green]Successfully reindexed repository {reponum}[/green]"
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
except ValueError:
|
|
126
|
+
console.print(
|
|
127
|
+
f"[red]Error: '{reponum}' is not a valid repository number. Please use a number from 'starbash repo'.[/red]"
|
|
128
|
+
)
|
|
129
|
+
raise typer.Exit(code=1)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
if __name__ == "__main__":
|
|
133
|
+
app()
|
|
@@ -31,11 +31,31 @@ def target(
|
|
|
31
31
|
with Starbash("selection-target") as sb:
|
|
32
32
|
# For now, replace existing targets with this one
|
|
33
33
|
# In the future, we could support adding multiple targets
|
|
34
|
-
sb.selection.
|
|
34
|
+
sb.selection.targets = []
|
|
35
35
|
sb.selection.add_target(target_name)
|
|
36
36
|
console.print(f"[green]Selection limited to target: {target_name}[/green]")
|
|
37
37
|
|
|
38
38
|
|
|
39
|
+
@app.command()
|
|
40
|
+
def telescope(
|
|
41
|
+
telescope_name: Annotated[
|
|
42
|
+
str,
|
|
43
|
+
typer.Argument(
|
|
44
|
+
help="Telescope name to add to the selection (e.g., 'Vespera', 'EdgeHD 8')"
|
|
45
|
+
),
|
|
46
|
+
],
|
|
47
|
+
):
|
|
48
|
+
"""Limit the current selection to only the named telescope."""
|
|
49
|
+
with Starbash("selection-telescope") as sb:
|
|
50
|
+
# For now, replace existing telescopes with this one
|
|
51
|
+
# In the future, we could support adding multiple telescopes
|
|
52
|
+
sb.selection.telescopes = []
|
|
53
|
+
sb.selection.add_telescope(telescope_name)
|
|
54
|
+
console.print(
|
|
55
|
+
f"[green]Selection limited to telescope: {telescope_name}[/green]"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
39
59
|
@app.command()
|
|
40
60
|
def date(
|
|
41
61
|
operation: Annotated[
|