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.

Files changed (26) hide show
  1. starbash-0.1.3/PKG-INFO +114 -0
  2. starbash-0.1.3/README.md +92 -0
  3. {starbash-0.1.1 → starbash-0.1.3}/pyproject.toml +1 -1
  4. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/app.py +82 -8
  5. starbash-0.1.3/src/starbash/commands/repo.py +133 -0
  6. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/commands/selection.py +21 -1
  7. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/database.py +141 -20
  8. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/defaults/starbash.toml +0 -32
  9. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/main.py +7 -1
  10. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/repo/manager.py +5 -0
  11. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/selection.py +36 -0
  12. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/templates/userconfig.toml +32 -0
  13. starbash-0.1.1/PKG-INFO +0 -96
  14. starbash-0.1.1/README.md +0 -73
  15. starbash-0.1.1/src/starbash/commands/repo.py +0 -68
  16. {starbash-0.1.1 → starbash-0.1.3}/LICENSE +0 -0
  17. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/__init__.py +0 -0
  18. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/analytics.py +0 -0
  19. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/commands/__init__.py +0 -0
  20. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/commands/user.py +0 -0
  21. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/defaults/__init__.py +0 -0
  22. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/paths.py +0 -0
  23. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/repo/__init__.py +0 -0
  24. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/templates/__init__.py +0 -0
  25. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/tool.py +0 -0
  26. {starbash-0.1.1 → starbash-0.1.3}/src/starbash/url.py +0 -0
@@ -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
+ ![PyPI - Version](https://img.shields.io/pypi/v/starbash)
26
+ ![GitHub branch check runs](https://img.shields.io/github/check-runs/geeksville/starbash/main)
27
+
28
+ ![app icon](https://github.com/geeksville/starbash/blob/main/img/icon.png "Starbash: Astrophotography workflows simplified")
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.
@@ -0,0 +1,92 @@
1
+ # Starbash
2
+
3
+ ![PyPI - Version](https://img.shields.io/pypi/v/starbash)
4
+ ![GitHub branch check runs](https://img.shields.io/github/check-runs/geeksville/starbash/main)
5
+
6
+ ![app icon](https://github.com/geeksville/starbash/blob/main/img/icon.png "Starbash: Astrophotography workflows simplified")
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,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "starbash"
3
- version = "0.1.1"
3
+ version = "0.1.3"
4
4
  description = ""
5
5
  authors = ["Kevin Hester <kevinh@geeksville.com>"]
6
6
  readme = "README.md"
@@ -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
- if exc:
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 critical FITS header, please submit image at https://github.com/geeksville/starbash/issues/new",
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 not config:
167
- raise ValueError(f"App config not found.")
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.info("Reindexing all repositories...")
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.clear()
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[