3838REPO_ROOT = Path (__file__ ).resolve ().parent .parent
3939SIGNALS_JSON = REPO_ROOT / "data" / "signals.json"
4040
41- RELEASE_INFO_URL = (
42- "https://raw.githubusercontent.com/AresValley/Artemis/master/config/release-info.json"
43- )
41+ RELEASE_INFO_URL = "https://raw.githubusercontent.com/AresValley/Artemis/master/config/release-info.json"
4442
4543_LOCATION_MAP : dict [str , str ] = {
4644 "worldwide" : "GLOBAL" ,
6563# Download helpers
6664# ---------------------------------------------------------------------------
6765
66+
6867def _fetch_json (url : str ) -> dict :
6968 with urllib .request .urlopen (url , timeout = 15 ) as r :
7069 return json .loads (r .read ())
@@ -97,18 +96,14 @@ def _download_db(dest_dir: Path) -> Path:
9796 extract_dir .mkdir ()
9897 with tarfile .open (tar_path ) as tf :
9998 # Safety: strip any absolute paths or '..' traversal
100- members = [
101- m for m in tf .getmembers ()
102- if not os .path .isabs (m .name ) and ".." not in m .name
103- ]
99+ members = [m for m in tf .getmembers () if not os .path .isabs (m .name ) and ".." not in m .name ]
104100 tf .extractall (extract_dir , members = members )
105101
106102 # Find data.sqlite anywhere in the extracted tree
107103 matches = list (extract_dir .rglob ("data.sqlite" ))
108104 if not matches :
109105 raise FileNotFoundError (
110- f"No data.sqlite found after extracting { tar_path } . "
111- "The Artemis-DB tar structure may have changed."
106+ f"No data.sqlite found after extracting { tar_path } . The Artemis-DB tar structure may have changed."
112107 )
113108
114109 return matches [0 ]
@@ -118,6 +113,7 @@ def _download_db(dest_dir: Path) -> Path:
118113# Discovery (for users who have Artemis installed)
119114# ---------------------------------------------------------------------------
120115
116+
121117def _find_installed_db () -> Path | None :
122118 home = Path .home ()
123119 candidates = [
@@ -140,6 +136,7 @@ def _find_installed_db() -> Path | None:
140136# Conversion helpers
141137# ---------------------------------------------------------------------------
142138
139+
143140def _slugify (name : str ) -> str :
144141 slug = re .sub (r"[^a-z0-9]+" , "-" , name .lower ()).strip ("-" )
145142 return slug [:60 ]
@@ -206,6 +203,7 @@ def _bandwidth_range(bw_values: list[int]) -> dict[str, int] | None:
206203# Database loading
207204# ---------------------------------------------------------------------------
208205
206+
209207def load_artemis (db_path : Path , limit : int = 0 , existing_ids : set [str ] | None = None ) -> list [dict ]:
210208 """Read signals from an Artemis data.sqlite and return them in Intercept's schema."""
211209 with closing (sqlite3 .connect (str (db_path ))) as conn :
@@ -281,17 +279,19 @@ def load_artemis(db_path: Path, limit: int = 0, existing_ids: set[str] | None =
281279 slug = _unique_slug (_slugify (name .strip ()), used_ids )
282280 used_ids .add (slug )
283281
284- results .append ({
285- "id" : slug ,
286- "name" : name .strip (),
287- "description" : (description or "" ).strip (),
288- "categories" : cats [sig_id ],
289- "frequency_ranges" : freq_ranges ,
290- "bandwidth_range" : _bandwidth_range (bws [sig_id ]),
291- "modulations" : mods [sig_id ],
292- "regions" : locs [sig_id ] or ["GLOBAL" ],
293- "sigidwiki_url" : sigidwiki_url ,
294- })
282+ results .append (
283+ {
284+ "id" : slug ,
285+ "name" : name .strip (),
286+ "description" : (description or "" ).strip (),
287+ "categories" : cats [sig_id ],
288+ "frequency_ranges" : freq_ranges ,
289+ "bandwidth_range" : _bandwidth_range (bws [sig_id ]),
290+ "modulations" : mods [sig_id ],
291+ "regions" : locs [sig_id ] or ["GLOBAL" ],
292+ "sigidwiki_url" : sigidwiki_url ,
293+ }
294+ )
295295
296296 if skipped_no_freq :
297297 print (f" Skipped { skipped_no_freq } signals with no frequency data" )
@@ -302,6 +302,7 @@ def load_artemis(db_path: Path, limit: int = 0, existing_ids: set[str] | None =
302302# Merge
303303# ---------------------------------------------------------------------------
304304
305+
305306def merge (existing : list [dict ], imported : list [dict ]) -> tuple [list [dict ], int , int ]:
306307 existing_names = {s ["name" ].lower () for s in existing }
307308 merged = list (existing )
@@ -320,30 +321,38 @@ def merge(existing: list[dict], imported: list[dict]) -> tuple[list[dict], int,
320321# Main
321322# ---------------------------------------------------------------------------
322323
324+
323325def main () -> None :
324326 parser = argparse .ArgumentParser (
325327 description = "Import Artemis signal database into data/signals.json" ,
326328 formatter_class = argparse .RawDescriptionHelpFormatter ,
327329 epilog = __doc__ ,
328330 )
329331 parser .add_argument (
330- "db_path" , nargs = "?" ,
332+ "db_path" ,
333+ nargs = "?" ,
331334 help = "Path to data.sqlite (omit to auto-detect installed Artemis DB)" ,
332335 )
333336 parser .add_argument (
334- "--download" , action = "store_true" ,
337+ "--download" ,
338+ action = "store_true" ,
335339 help = "Download the latest Artemis-DB tar (~290 MB) and import automatically" ,
336340 )
337341 parser .add_argument (
338- "--dry-run" , action = "store_true" ,
342+ "--dry-run" ,
343+ action = "store_true" ,
339344 help = "Show import stats without writing data/signals.json" ,
340345 )
341346 parser .add_argument (
342- "--no-merge" , action = "store_true" ,
347+ "--no-merge" ,
348+ action = "store_true" ,
343349 help = "Replace data/signals.json entirely instead of merging" ,
344350 )
345351 parser .add_argument (
346- "--limit" , type = int , default = 0 , metavar = "N" ,
352+ "--limit" ,
353+ type = int ,
354+ default = 0 ,
355+ metavar = "N" ,
347356 help = "Only process the first N signals (for testing)" ,
348357 )
349358 args = parser .parse_args ()
0 commit comments