Skip to content

Commit 0b77c59

Browse files
committed
feat: refactor, utilize 'rich'
1 parent bb108e4 commit 0b77c59

5 files changed

Lines changed: 147 additions & 59 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ dependencies = [
2323
"python-dotenv>=1.1.0",
2424
"pytz==2024.1",
2525
"requests==2.32.3",
26+
"rich>=14.3.3",
27+
"rich-argparse>=1.7.2",
2628
"ruff>=0.11.7",
2729
"shapely==2.0.3",
2830
"six==1.16.0",
29-
"tabulate>=0.9.0",
3031
"tenacity>=9.1.2",
3132
"tzdata==2024.1",
3233
"urllib3==2.2.3",

src/coord_buffer_cli/cli.py

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,33 @@
1-
import argparse
2-
1+
from coord_buffer_cli.config import logger, parse_args
32
from coord_buffer_cli.utils import (
43
buffer_polygon,
54
list_coords_from_db,
6-
logger,
5+
print_coordinates,
76
read_coords,
87
read_coords_from_db,
9-
to_dms_coords,
108
)
119

1210

13-
def parse_args():
14-
parser = argparse.ArgumentParser(
15-
description="Creates a specified buffer around user specified area."
16-
)
17-
parser.add_argument(
18-
"-l",
19-
"--list",
20-
action="store_true",
21-
help="Prints list of available geometries and their id.",
22-
)
23-
parser.add_argument(
24-
"--msid",
25-
default=None,
26-
help="Get coords for the selected geometries.",
27-
)
28-
parser.add_argument(
29-
"-f",
30-
"--input_file",
31-
default=None,
32-
help="Path to a GeoJSON file with coordinates",
33-
)
34-
parser.add_argument(
35-
"-b", "--buffer", type=float, default=0, help="Buffer size in NM (default: 0)"
36-
)
37-
return parser.parse_args()
38-
39-
4011
def main():
4112
args = parse_args()
4213

4314
try:
4415
if args.list:
4516
list_coords_from_db()
4617
return
47-
elif args.msid:
48-
logger.info(f"Processing msid: {args.msid}")
18+
19+
if args.msid:
20+
logger.info(f"Processing MSID: {args.msid}")
4921
coords = read_coords_from_db(args.msid)
50-
elif args.input_file:
51-
logger.info(f"Processing input file: {args.input_file}")
22+
else:
23+
logger.info(f"Processing file: {args.input_file}")
5224
coords = read_coords(args.input_file)
25+
5326
buffered_gdf = buffer_polygon(coords, args.buffer)
5427
coords_df = buffered_gdf.get_coordinates()
55-
for _, row in coords_df.iterrows():
56-
print(to_dms_coords([row["y"], row["x"]]))
28+
29+
print_coordinates(coords_df)
30+
5731
except Exception as e:
5832
logger.error(f"Error processing file: {e}")
5933
return

src/coord_buffer_cli/config.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
1+
import argparse
2+
import logging
13
import os
24

35
from dotenv import load_dotenv
6+
from rich.console import Console
7+
from rich.logging import RichHandler
8+
from rich_argparse import RichHelpFormatter
49

510
load_dotenv()
611

@@ -15,3 +20,51 @@
1520
"host": os.getenv("POSTGRES_HOST"),
1621
"port": os.getenv("5432"),
1722
}
23+
24+
25+
logging.basicConfig(level="INFO", format="%(message)s", handlers=[RichHandler()])
26+
logger = logging.getLogger(__name__)
27+
28+
console = Console()
29+
30+
31+
class CustomFormatter(RichHelpFormatter):
32+
styles = {
33+
"argparse.prog": "bold cyan",
34+
"argparse.args": "cyan",
35+
"argparse.metavar": "yellow",
36+
"argparse.help": "white",
37+
}
38+
39+
40+
def parse_args():
41+
parser = argparse.ArgumentParser(
42+
prog="coord_buffer_cli",
43+
description="Creates a specified buffer around user specified area.",
44+
epilog="Ex: uv run coord_buffer_cli --msid 3982 -b 5",
45+
formatter_class=CustomFormatter,
46+
)
47+
source_group = parser.add_mutually_exclusive_group(required=True)
48+
49+
source_group.add_argument(
50+
"-l",
51+
"--list",
52+
action="store_true",
53+
help="Prints list of available geometries and their id.",
54+
)
55+
56+
source_group.add_argument(
57+
"--msid",
58+
type=int,
59+
help="Fetch coordinates for the given MSID.",
60+
)
61+
62+
source_group.add_argument(
63+
"-f",
64+
"--input_file",
65+
help="Path to a GeoJSON file.",
66+
)
67+
parser.add_argument(
68+
"-b", "--buffer", type=float, default=0.0, help="Buffer size in nautical miles."
69+
)
70+
return parser.parse_args()

src/coord_buffer_cli/utils.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,29 @@
11
import json
2-
import logging
32
import re
43
import unicodedata
54

65
import geopandas as gpd
76
import psycopg
7+
from rich.table import Table
8+
from rich.text import Text
89
from shapely.geometry import Polygon
9-
from tabulate import tabulate
1010

1111
from coord_buffer_cli.config import (
1212
BUFFER_MULTIPLIER,
1313
DB_PARAMS,
1414
DEFAULT_EPSG,
1515
METRIC_EPSG,
16+
console,
1617
)
1718

18-
logging.basicConfig(level=logging.INFO)
19-
logger = logging.getLogger(__name__)
19+
20+
def print_coordinates(coord_dataframe):
21+
console.print(f"\n[bold green]Buffered Polygon • {args.buffer} NM[/bold green]\n")
22+
for _, row in coord_dataframe.iterrows():
23+
dms = to_dms_coords([row["y"], row["x"]])
24+
lat, lon = dms.split()
25+
line = Text.assemble((lat, "yellow"), (" ", ""), (lon, "cyan"))
26+
console.print(line)
2027

2128

2229
def clean_file_name(name):
@@ -100,11 +107,16 @@ def list_coords_from_db():
100107
if not rows:
101108
raise ValueError("No geometries found")
102109

103-
print(
104-
tabulate(
105-
rows, headers=["MSID", "TMA"], tablefmt="pretty", colalign=("left",)
106-
)
107-
)
110+
table = Table(title="Available TMAs", header_style="bold magenta")
111+
table.add_column("MSID", style="cyan", justify="center")
112+
table.add_column("TMA", style="green", justify="left")
113+
114+
for (
115+
msid,
116+
name,
117+
) in rows:
118+
table.add_row(str(msid), name)
119+
console.print(table)
108120
return rows
109121

110122

uv.lock

Lines changed: 60 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)