starbash 0.1.8__py3-none-any.whl → 0.1.9__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.
- repo/__init__.py +2 -1
- repo/manager.py +31 -268
- repo/repo.py +294 -0
- starbash/__init__.py +20 -0
- starbash/analytics.py +4 -0
- starbash/app.py +444 -78
- starbash/commands/__init__.py +0 -17
- starbash/commands/info.py +3 -3
- starbash/commands/process.py +154 -0
- starbash/commands/repo.py +168 -77
- starbash/commands/select.py +128 -44
- starbash/database.py +237 -88
- starbash/defaults/starbash.toml +17 -0
- starbash/main.py +4 -1
- starbash/recipes/master_bias/starbash.toml +25 -8
- starbash/recipes/starbash.toml +5 -0
- starbash/selection.py +109 -45
- starbash/templates/repo/master.toml +13 -0
- starbash/templates/userconfig.toml +1 -1
- starbash/toml.py +29 -0
- starbash/tool.py +84 -12
- {starbash-0.1.8.dist-info → starbash-0.1.9.dist-info}/METADATA +18 -13
- starbash-0.1.9.dist-info/RECORD +37 -0
- starbash-0.1.8.dist-info/RECORD +0 -33
- {starbash-0.1.8.dist-info → starbash-0.1.9.dist-info}/WHEEL +0 -0
- {starbash-0.1.8.dist-info → starbash-0.1.9.dist-info}/entry_points.txt +0 -0
- {starbash-0.1.8.dist-info → starbash-0.1.9.dist-info}/licenses/LICENSE +0 -0
starbash/commands/__init__.py
CHANGED
|
@@ -20,20 +20,3 @@ def format_duration(seconds: int | float) -> str:
|
|
|
20
20
|
hours = int(seconds // 3600)
|
|
21
21
|
minutes = int((seconds % 3600) // 60)
|
|
22
22
|
return f"{hours}h {minutes}m" if minutes else f"{hours}h"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
def to_shortdate(date_iso: str) -> str:
|
|
26
|
-
"""Convert ISO UTC datetime string to local short date string (YYYY-MM-DD).
|
|
27
|
-
|
|
28
|
-
Args:
|
|
29
|
-
date_iso: ISO format datetime string (e.g., "2023-10-15T14:30:00Z")
|
|
30
|
-
|
|
31
|
-
Returns:
|
|
32
|
-
Short date string in YYYY-MM-DD format, or the original string if conversion fails
|
|
33
|
-
"""
|
|
34
|
-
try:
|
|
35
|
-
dt_utc = datetime.fromisoformat(date_iso)
|
|
36
|
-
dt_local = dt_utc.astimezone()
|
|
37
|
-
return dt_local.strftime("%Y-%m-%d")
|
|
38
|
-
except (ValueError, TypeError):
|
|
39
|
-
return date_iso
|
starbash/commands/info.py
CHANGED
|
@@ -27,7 +27,7 @@ def dump_column(sb: Starbash, human_name: str, column_name: str) -> None:
|
|
|
27
27
|
sessions = sb.search_session()
|
|
28
28
|
|
|
29
29
|
# Also do a complete unfiltered search so we can compare for the users
|
|
30
|
-
allsessions = sb.db.search_session()
|
|
30
|
+
allsessions = sb.db.search_session(("", []))
|
|
31
31
|
|
|
32
32
|
column_name = get_column_name(column_name)
|
|
33
33
|
found = [session[column_name] for session in sessions if session[column_name]]
|
|
@@ -38,7 +38,7 @@ def dump_column(sb: Starbash, human_name: str, column_name: str) -> None:
|
|
|
38
38
|
all_counts = Counter(allfound)
|
|
39
39
|
|
|
40
40
|
# Sort by telescope name
|
|
41
|
-
|
|
41
|
+
sorted_list = sorted(found_counts.items())
|
|
42
42
|
|
|
43
43
|
# Create and display table
|
|
44
44
|
table = Table(
|
|
@@ -49,7 +49,7 @@ def dump_column(sb: Starbash, human_name: str, column_name: str) -> None:
|
|
|
49
49
|
"# of sessions", style=TABLE_COLUMN_STYLE, no_wrap=True, justify="right"
|
|
50
50
|
)
|
|
51
51
|
|
|
52
|
-
for i, count in
|
|
52
|
+
for i, count in sorted_list:
|
|
53
53
|
table.add_row(i, str(count))
|
|
54
54
|
|
|
55
55
|
console.print(table)
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"""Processing commands for automated image processing workflows."""
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing_extensions import Annotated
|
|
6
|
+
|
|
7
|
+
from starbash.app import Starbash, copy_images_to_dir
|
|
8
|
+
from starbash import console
|
|
9
|
+
from starbash.commands.select import selection_by_number
|
|
10
|
+
from starbash.database import SessionRow
|
|
11
|
+
|
|
12
|
+
app = typer.Typer()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@app.command()
|
|
16
|
+
def siril(
|
|
17
|
+
session_num: Annotated[
|
|
18
|
+
int,
|
|
19
|
+
typer.Argument(help="Session number to process (from 'select list' output)"),
|
|
20
|
+
],
|
|
21
|
+
destdir: Annotated[
|
|
22
|
+
str,
|
|
23
|
+
typer.Argument(
|
|
24
|
+
help="Destination directory for Siril directory tree and processing"
|
|
25
|
+
),
|
|
26
|
+
],
|
|
27
|
+
run: Annotated[
|
|
28
|
+
bool,
|
|
29
|
+
typer.Option(
|
|
30
|
+
"--run",
|
|
31
|
+
help="Automatically launch Siril GUI after generating directory tree",
|
|
32
|
+
),
|
|
33
|
+
] = False,
|
|
34
|
+
):
|
|
35
|
+
"""Generate Siril directory tree and optionally run Siril GUI.
|
|
36
|
+
|
|
37
|
+
Creates a properly structured directory tree for Siril processing with
|
|
38
|
+
biases/, darks/, flats/, and lights/ subdirectories populated with the
|
|
39
|
+
session's images (via symlinks when possible).
|
|
40
|
+
|
|
41
|
+
If --run is specified, launches the Siril GUI with the generated directory
|
|
42
|
+
structure loaded and ready for processing.
|
|
43
|
+
"""
|
|
44
|
+
with Starbash("process.siril") as sb:
|
|
45
|
+
console.print(
|
|
46
|
+
f"[yellow]Processing session {session_num} for Siril in {destdir}...[/yellow]"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# Determine output directory
|
|
50
|
+
output_dir = Path(destdir)
|
|
51
|
+
|
|
52
|
+
# Get the selected session (convert from 1-based to 0-based index)
|
|
53
|
+
session = selection_by_number(sb, session_num)
|
|
54
|
+
|
|
55
|
+
# Get images for this session
|
|
56
|
+
|
|
57
|
+
def session_to_dir(src_session: SessionRow, subdir_name: str):
|
|
58
|
+
"""Copy the images from the specified session to the subdir"""
|
|
59
|
+
img_dir = output_dir / subdir_name
|
|
60
|
+
img_dir.mkdir(parents=True, exist_ok=True)
|
|
61
|
+
images = sb.get_session_images(src_session)
|
|
62
|
+
copy_images_to_dir(images, img_dir)
|
|
63
|
+
|
|
64
|
+
# FIXME - pull this dirname from preferences
|
|
65
|
+
lights = "lights"
|
|
66
|
+
session_to_dir(session, lights)
|
|
67
|
+
|
|
68
|
+
extras = [
|
|
69
|
+
# FIXME search for BIAS/DARK/FLAT etc... using multiple canonical names
|
|
70
|
+
("BIAS", "biases"),
|
|
71
|
+
("DARK", "darks"),
|
|
72
|
+
("FLAT", "flats"),
|
|
73
|
+
]
|
|
74
|
+
for typ, subdir in extras:
|
|
75
|
+
candidates = sb.guess_sessions(session, typ)
|
|
76
|
+
if not candidates:
|
|
77
|
+
console.print(
|
|
78
|
+
f"[yellow]No candidate sessions found for {typ} calibration frames.[/yellow]"
|
|
79
|
+
)
|
|
80
|
+
else:
|
|
81
|
+
session_to_dir(candidates[0], subdir)
|
|
82
|
+
|
|
83
|
+
# FIXME put an starbash.toml repo file in output_dir (with info about what we picked/why)
|
|
84
|
+
# to allow users to override/reprocess with the same settings.
|
|
85
|
+
# Also FIXME, check for the existence of such a file
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@app.command()
|
|
89
|
+
def auto(
|
|
90
|
+
session_num: Annotated[
|
|
91
|
+
int | None,
|
|
92
|
+
typer.Argument(
|
|
93
|
+
help="Session number to process. If not specified, processes all selected sessions."
|
|
94
|
+
),
|
|
95
|
+
] = None,
|
|
96
|
+
):
|
|
97
|
+
"""Automatic processing with sensible defaults.
|
|
98
|
+
|
|
99
|
+
If session number is specified, processes only that session.
|
|
100
|
+
Otherwise, all currently selected sessions will be processed automatically
|
|
101
|
+
using the configured recipes and default settings.
|
|
102
|
+
|
|
103
|
+
This command handles:
|
|
104
|
+
- Automatic master frame selection (bias, dark, flat)
|
|
105
|
+
- Calibration of light frames
|
|
106
|
+
- Registration and stacking
|
|
107
|
+
- Basic post-processing
|
|
108
|
+
|
|
109
|
+
The output will be saved according to the configured recipes.
|
|
110
|
+
"""
|
|
111
|
+
with Starbash("process.auto") as sb:
|
|
112
|
+
if session_num is not None:
|
|
113
|
+
console.print(f"[yellow]Auto-processing session {session_num}...[/yellow]")
|
|
114
|
+
else:
|
|
115
|
+
console.print("[yellow]Auto-processing all selected sessions...[/yellow]")
|
|
116
|
+
|
|
117
|
+
console.print(
|
|
118
|
+
"[red]Still in development - see https://github.com/geeksville/starbash[/red]"
|
|
119
|
+
)
|
|
120
|
+
sb.run_all_stages()
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@app.command()
|
|
124
|
+
def masters():
|
|
125
|
+
"""Generate master flats, darks, and biases from selected raw frames.
|
|
126
|
+
|
|
127
|
+
Analyzes the current selection to find all available calibration frames
|
|
128
|
+
(BIAS, DARK, FLAT) and automatically generates master calibration frames
|
|
129
|
+
using stacking recipes.
|
|
130
|
+
|
|
131
|
+
Generated master frames are stored in the configured masters directory
|
|
132
|
+
and will be automatically used for future processing operations.
|
|
133
|
+
"""
|
|
134
|
+
with Starbash("process.masters") as sb:
|
|
135
|
+
console.print(
|
|
136
|
+
"[yellow]Generating master frames from current selection...[/yellow]"
|
|
137
|
+
)
|
|
138
|
+
console.print(
|
|
139
|
+
"[red]Still in development - see https://github.com/geeksville/starbash[/red]"
|
|
140
|
+
)
|
|
141
|
+
sb.run_master_stages()
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@app.callback(invoke_without_command=True)
|
|
145
|
+
def main_callback(ctx: typer.Context):
|
|
146
|
+
"""Process images using automated workflows.
|
|
147
|
+
|
|
148
|
+
These commands handle calibration, registration, stacking, and
|
|
149
|
+
post-processing of astrophotography sessions.
|
|
150
|
+
"""
|
|
151
|
+
if ctx.invoked_subcommand is None:
|
|
152
|
+
# No command provided, show help
|
|
153
|
+
console.print(ctx.get_help())
|
|
154
|
+
raise typer.Exit()
|
starbash/commands/repo.py
CHANGED
|
@@ -1,99 +1,208 @@
|
|
|
1
1
|
import typer
|
|
2
2
|
from typing_extensions import Annotated
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import logging
|
|
3
5
|
|
|
6
|
+
import starbash
|
|
7
|
+
from repo import repo_suffix, Repo
|
|
4
8
|
from starbash.app import Starbash
|
|
5
|
-
from starbash import console
|
|
9
|
+
from starbash import console, log_filter_level
|
|
10
|
+
from starbash.toml import toml_from_template
|
|
6
11
|
|
|
7
12
|
app = typer.Typer(invoke_without_command=True)
|
|
8
13
|
|
|
9
14
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
def repo_enumeration(sb: Starbash):
|
|
16
|
+
"""return a dict of int (1 based) to Repo instances"""
|
|
17
|
+
verbose = False # assume not verbose for enum picking
|
|
18
|
+
repos = sb.repo_manager.repos if verbose else sb.repo_manager.regular_repos
|
|
19
|
+
|
|
20
|
+
return {i + 1: repo for i, repo in enumerate(repos)}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def complete_repo_by_num(incomplete: str):
|
|
24
|
+
# We need to use stderr_logging to prevent confusing the bash completion parser
|
|
25
|
+
starbash.log_filter_level = (
|
|
26
|
+
logging.ERROR
|
|
27
|
+
) # avoid showing output while doing completion
|
|
28
|
+
with Starbash("repo.complete.num", stderr_logging=True) as sb:
|
|
29
|
+
for num, repo in repo_enumeration(sb).items():
|
|
30
|
+
if str(num).startswith(incomplete):
|
|
31
|
+
yield (str(num), repo.url)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def complete_repo_by_url(incomplete: str):
|
|
35
|
+
# We need to use stderr_logging to prevent confusing the bash completion parser
|
|
36
|
+
starbash.log_filter_level = (
|
|
37
|
+
logging.ERROR
|
|
38
|
+
) # avoid showing output while doing completion
|
|
39
|
+
with Starbash("repo.complete.url", stderr_logging=True) as sb:
|
|
40
|
+
repos = sb.repo_manager.regular_repos
|
|
41
|
+
|
|
42
|
+
for repo in repos:
|
|
43
|
+
if repo.url.startswith(incomplete):
|
|
44
|
+
yield (repo.url, f"kind={repo.kind('input')}")
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@app.command()
|
|
48
|
+
def list(
|
|
13
49
|
verbose: bool = typer.Option(
|
|
14
50
|
False, "--verbose", "-v", help="Show all repos including system repos"
|
|
15
51
|
),
|
|
52
|
+
):
|
|
53
|
+
"""
|
|
54
|
+
lists all repositories.
|
|
55
|
+
Use --verbose to show all repos including system/recipe repos.
|
|
56
|
+
"""
|
|
57
|
+
with Starbash("repo.list") as sb:
|
|
58
|
+
repos = sb.repo_manager.repos if verbose else sb.repo_manager.regular_repos
|
|
59
|
+
for i, repo in enumerate(repos):
|
|
60
|
+
kind = repo.kind("input")
|
|
61
|
+
# for unknown repos (probably because we haven't written a starbash.toml file to the root yet),
|
|
62
|
+
# we call them "input" because users will be less confused by that
|
|
63
|
+
|
|
64
|
+
if verbose:
|
|
65
|
+
# No numbers for verbose mode (system repos can't be removed)
|
|
66
|
+
console.print(f"{ repo.url } (kind={ kind })")
|
|
67
|
+
else:
|
|
68
|
+
# Show numbers for user repos (can be removed later)
|
|
69
|
+
console.print(f"{ i + 1:2}: { repo.url } (kind={ kind })")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@app.callback()
|
|
73
|
+
def main(
|
|
74
|
+
ctx: typer.Context,
|
|
16
75
|
):
|
|
17
76
|
"""
|
|
18
77
|
Manage repositories.
|
|
19
78
|
|
|
20
79
|
When called without a subcommand, lists all repositories.
|
|
21
|
-
Use --verbose to show all repos including system/recipe repos.
|
|
22
80
|
"""
|
|
23
81
|
# If no subcommand is invoked, run the list behavior
|
|
24
82
|
if ctx.invoked_subcommand is None:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
kind = repo.kind("input")
|
|
29
|
-
# for unknown repos (probably because we haven't written a starbash.toml file to the root yet),
|
|
30
|
-
# we call them "input" because users will be less confused by that
|
|
31
|
-
|
|
32
|
-
if verbose:
|
|
33
|
-
# No numbers for verbose mode (system repos can't be removed)
|
|
34
|
-
console.print(f"{ repo.url } (kind={ kind })")
|
|
35
|
-
else:
|
|
36
|
-
# Show numbers for user repos (can be removed later)
|
|
37
|
-
console.print(f"{ i + 1:2}: { repo.url } (kind={ kind })")
|
|
83
|
+
# No command provided, show help
|
|
84
|
+
console.print(ctx.get_help())
|
|
85
|
+
raise typer.Exit()
|
|
38
86
|
|
|
39
87
|
|
|
40
88
|
@app.command()
|
|
41
|
-
def add(
|
|
89
|
+
def add(
|
|
90
|
+
path: str,
|
|
91
|
+
master: bool = typer.Option(
|
|
92
|
+
False, "--master", help="Mark this new repository for master files."
|
|
93
|
+
),
|
|
94
|
+
):
|
|
42
95
|
"""
|
|
43
96
|
Add a repository. path is either a local path or a remote URL.
|
|
44
97
|
"""
|
|
98
|
+
repo_type = None
|
|
99
|
+
if master:
|
|
100
|
+
repo_type = "master"
|
|
45
101
|
with Starbash("repo.add") as sb:
|
|
46
|
-
|
|
102
|
+
p = Path(path)
|
|
103
|
+
|
|
104
|
+
repo_toml = p / repo_suffix # the starbash.toml file at the root of the repo
|
|
105
|
+
if repo_toml.exists():
|
|
106
|
+
logging.warning("Using existing repository config file: %s", repo_toml)
|
|
107
|
+
else:
|
|
108
|
+
if repo_type:
|
|
109
|
+
console.print(f"Creating {repo_type} repository: {p}")
|
|
110
|
+
p.mkdir(parents=True, exist_ok=True)
|
|
111
|
+
|
|
112
|
+
toml_from_template(
|
|
113
|
+
f"repo/{repo_type}",
|
|
114
|
+
p / repo_suffix,
|
|
115
|
+
overrides={
|
|
116
|
+
"REPO_TYPE": repo_type,
|
|
117
|
+
"REPO_PATH": str(p),
|
|
118
|
+
"DEFAULT_RELATIVE": "{instrument}/{date}/{imagetyp}/master_{imagetyp}.fits",
|
|
119
|
+
},
|
|
120
|
+
)
|
|
121
|
+
else:
|
|
122
|
+
# No type specified, therefore (for now) assume we are just using this as an input
|
|
123
|
+
# repo (and it must exist)
|
|
124
|
+
if not p.exists():
|
|
125
|
+
console.print(f"[red]Error: Repo path does not exist: {p}[/red]")
|
|
126
|
+
raise typer.Exit(code=1)
|
|
127
|
+
|
|
128
|
+
console.print(f"Adding repository: {p}")
|
|
129
|
+
|
|
130
|
+
repo = sb.user_repo.add_repo_ref(p)
|
|
47
131
|
if repo:
|
|
48
|
-
console.print(f"Added repository: {path}")
|
|
49
132
|
sb.reindex_repo(repo)
|
|
50
133
|
|
|
51
|
-
# we don't yet write default config files at roots of repos, but it would be easy to add here
|
|
134
|
+
# we don't yet always write default config files at roots of repos, but it would be easy to add here
|
|
52
135
|
# r.write_config()
|
|
53
136
|
sb.user_repo.write_config()
|
|
54
137
|
# FIXME, we also need to index the newly added repo!!!
|
|
55
138
|
|
|
56
139
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
Use 'starbash repo' to see the repository numbers.
|
|
62
|
-
"""
|
|
63
|
-
with Starbash("repo.remove") as sb:
|
|
64
|
-
try:
|
|
65
|
-
# Parse the repo number (1-indexed)
|
|
66
|
-
repo_index = int(reponum) - 1
|
|
140
|
+
def repo_url_to_repo(sb: Starbash, repo_url: str | None) -> Repo | None:
|
|
141
|
+
"""Helper to get a Repo instance from a URL or number"""
|
|
142
|
+
if repo_url is None:
|
|
143
|
+
return None
|
|
67
144
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
console.print(
|
|
73
|
-
f"[red]Error: Repository number {reponum} is out of range. Valid range: 1-{len(regular_repos)}[/red]"
|
|
74
|
-
)
|
|
75
|
-
raise typer.Exit(code=1)
|
|
145
|
+
# try to find by URL
|
|
146
|
+
repo = sb.repo_manager.get_repo_by_url(repo_url)
|
|
147
|
+
if repo is not None:
|
|
148
|
+
return repo
|
|
76
149
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
150
|
+
# Fall back to finding by number
|
|
151
|
+
try:
|
|
152
|
+
# Parse the repo number (1-indexed)
|
|
153
|
+
repo_index = int(repo_url) - 1
|
|
80
154
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
console.print(f"[green]Removed repository: {repo_url}[/green]")
|
|
155
|
+
# Get only the regular (user-visible) repos
|
|
156
|
+
regular_repos = sb.repo_manager.regular_repos
|
|
84
157
|
|
|
85
|
-
|
|
158
|
+
if repo_index < 0 or repo_index >= len(regular_repos):
|
|
86
159
|
console.print(
|
|
87
|
-
f"[red]Error: '{
|
|
160
|
+
f"[red]Error: '{repo_url}' is not a valid repository number. Please enter a repository number or URL.[/red]"
|
|
88
161
|
)
|
|
89
162
|
raise typer.Exit(code=1)
|
|
90
163
|
|
|
164
|
+
return regular_repos[repo_index]
|
|
165
|
+
except ValueError:
|
|
166
|
+
console.print(
|
|
167
|
+
f"[red]Error: '{repo_url}' is not valid. Please enter a repository number or URL.[/red]"
|
|
168
|
+
)
|
|
169
|
+
raise typer.Exit(code=1)
|
|
170
|
+
|
|
91
171
|
|
|
92
172
|
@app.command()
|
|
93
|
-
def
|
|
173
|
+
def remove(
|
|
94
174
|
reponum: Annotated[
|
|
175
|
+
str,
|
|
176
|
+
typer.Argument(
|
|
177
|
+
help="Repository number or URL", autocompletion=complete_repo_by_url
|
|
178
|
+
),
|
|
179
|
+
],
|
|
180
|
+
):
|
|
181
|
+
"""
|
|
182
|
+
Remove a repository by number (from list).
|
|
183
|
+
Use 'starbash repo' to see the repository numbers.
|
|
184
|
+
"""
|
|
185
|
+
with Starbash("repo.remove") as sb:
|
|
186
|
+
# Get the repo to remove
|
|
187
|
+
repo_to_remove = repo_url_to_repo(sb, reponum)
|
|
188
|
+
if repo_to_remove is None:
|
|
189
|
+
console.print(f"[red]Error: You must specify a repository[/red]")
|
|
190
|
+
raise typer.Exit(code=1)
|
|
191
|
+
repo_url = repo_to_remove.url
|
|
192
|
+
|
|
193
|
+
# Remove the repo reference from user config
|
|
194
|
+
sb.remove_repo_ref(repo_url)
|
|
195
|
+
console.print(f"[green]Removed repository: {repo_url}[/green]")
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@app.command()
|
|
199
|
+
def reindex(
|
|
200
|
+
repo_url: Annotated[
|
|
95
201
|
str | None,
|
|
96
|
-
typer.Argument(
|
|
202
|
+
typer.Argument(
|
|
203
|
+
help="The repository URL, if not specified reindex all.",
|
|
204
|
+
autocompletion=complete_repo_by_url,
|
|
205
|
+
),
|
|
97
206
|
] = None,
|
|
98
207
|
force: bool = typer.Option(
|
|
99
208
|
default=False, help="Reread FITS headers, even if they are already indexed."
|
|
@@ -105,35 +214,17 @@ def reindex(
|
|
|
105
214
|
Use 'starbash repo' to see the repository numbers.
|
|
106
215
|
"""
|
|
107
216
|
with Starbash("repo.reindex") as sb:
|
|
108
|
-
|
|
217
|
+
repo_to_reindex = repo_url_to_repo(sb, repo_url)
|
|
218
|
+
|
|
219
|
+
if repo_to_reindex is None:
|
|
109
220
|
sb.reindex_repos(force=force)
|
|
110
221
|
else:
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if repo_index < 0 or repo_index >= len(regular_repos):
|
|
119
|
-
console.print(
|
|
120
|
-
f"[red]Error: Repository number {reponum} is out of range. Valid range: 1-{len(regular_repos)}[/red]"
|
|
121
|
-
)
|
|
122
|
-
raise typer.Exit(code=1)
|
|
123
|
-
|
|
124
|
-
# Get the repo to reindex
|
|
125
|
-
repo_to_reindex = regular_repos[repo_index]
|
|
126
|
-
console.print(f"Reindexing repository: {repo_to_reindex.url}")
|
|
127
|
-
sb.reindex_repo(repo_to_reindex, force=force)
|
|
128
|
-
console.print(
|
|
129
|
-
f"[green]Successfully reindexed repository {reponum}[/green]"
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
except ValueError:
|
|
133
|
-
console.print(
|
|
134
|
-
f"[red]Error: '{reponum}' is not a valid repository number. Please use a number from 'starbash repo'.[/red]"
|
|
135
|
-
)
|
|
136
|
-
raise typer.Exit(code=1)
|
|
222
|
+
# Get the repo to reindex
|
|
223
|
+
console.print(f"Reindexing repository: {repo_to_reindex.url}")
|
|
224
|
+
sb.reindex_repo(repo_to_reindex, force=force)
|
|
225
|
+
console.print(
|
|
226
|
+
f"[green]Successfully reindexed repository {repo_to_reindex}[/green]"
|
|
227
|
+
)
|
|
137
228
|
|
|
138
229
|
|
|
139
230
|
if __name__ == "__main__":
|