Skip to content

Commit 6dfd92e

Browse files
committed
add macos via airport
1 parent 294b185 commit 6dfd92e

File tree

6 files changed

+75
-13
lines changed

6 files changed

+75
-13
lines changed

setup.cfg

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = mozloc
3-
version = 1.1.2
3+
version = 1.2.0
44
author = Michael Hirsch, Ph.D.
55
author_email = scivision@users.noreply.github.com
66
url = https://github.com/scivision/mozilla-location-wifi
@@ -14,6 +14,7 @@ classifiers =
1414
Intended Audience :: Information Technology
1515
Intended Audience :: System Administrators
1616
Operating System :: POSIX :: Linux
17+
Operating System :: MacOS
1718
Operating System :: Microsoft :: Windows
1819
Programming Language :: Python :: 3
1920
Topic :: System :: Networking

src/mozloc/airport.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
""" MacOS airport functions """
2+
3+
from __future__ import annotations
4+
import typing as T
5+
import shutil
6+
import io
7+
import logging
8+
import subprocess
9+
import re
10+
11+
EXE = shutil.which("airport", path="/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources")
12+
if not EXE:
13+
raise ImportError("Could not find Airport")
14+
15+
16+
def cli_config_check() -> bool:
17+
# %% check that Airport is available and WiFi is active
18+
ret = subprocess.run([EXE, "--getinfo"], stdout=subprocess.PIPE, text=True, timeout=30)
19+
20+
if ret.returncode != 0:
21+
return False
22+
23+
stdout = ret.stdout.strip().lower()
24+
if len(stdout) == "airport: off":
25+
return False
26+
27+
if "state: running" in stdout:
28+
return True
29+
30+
logging.error("could not determine WiFi state.")
31+
return False
32+
33+
34+
def get_signal() -> list[dict[str, T.Any]]:
35+
36+
ret = subprocess.run([EXE, "-s"], timeout=30.0, stdout=subprocess.PIPE, text=True)
37+
38+
if ret.returncode != 0:
39+
logging.error("consider slowing scan cadence.")
40+
41+
pat = re.compile(r"\s*([0-9a-zA-Z\-\.]+)\s+([0-9a-f]{2}(?::[0-9a-f]{2}){5})\s+(-\d{2,3})")
42+
dat: list[dict[str, str]] = []
43+
44+
for line in io.StringIO(ret.stdout):
45+
mat = pat.match(line)
46+
if mat:
47+
ssid = mat.group(1)
48+
# optout
49+
if ssid.endswith("_nomap"):
50+
continue
51+
52+
dat.append({"ssid": ssid, "macAddress": mat.group(2), "signalStrength": mat.group(3)})
53+
54+
return dat

src/mozloc/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def log_wifi_loc(cadence_sec: float, mozilla_url: str, logfile: Path = None):
2828
logging.warning(f"cannot locate since at least 2 BSSIDs required\n{dat}")
2929
sleep(cadence_sec)
3030
continue
31+
print(dat)
3132

3233
loc = get_loc_mozilla(dat, mozilla_url)
3334
if loc is None:

src/mozloc/modules.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@
44
from .netsh import cli_config_check, get_signal
55
elif sys.platform == "linux":
66
from .netman import cli_config_check, get_signal
7+
elif sys.platform == "darwin":
8+
from .airport import cli_config_check, get_signal
79
else:
810
raise ImportError(f"MozLoc doesn't work with platform {sys.platform}")

src/mozloc/netman.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
""" Network Manager CLI (nmcli) functions """
2+
3+
from __future__ import annotations
4+
import typing as T
25
import subprocess
36
import logging
47
import shutil
58
import pandas
6-
import typing as T
7-
from io import StringIO
9+
import io
810
from time import sleep
911

1012
NMCLI = shutil.which("nmcli")
@@ -38,19 +40,19 @@ def cli_config_check() -> bool:
3840
return False
3941

4042

41-
def get_signal() -> T.List[T.Dict[str, T.Any]]:
43+
def get_signal() -> list[dict[str, T.Any]]:
4244

4345
ret = subprocess.run(NMCMD, timeout=1.0)
4446
if ret.returncode != 0:
4547
raise ConnectionError("could not connect with NetworkManager for WiFi")
4648
sleep(0.5) # nmcli errored for less than about 0.2 sec.
4749
# takes several seconds to update, so do it now.
48-
ret = subprocess.run(NMSCAN, timeout=1.0, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
50+
ret = subprocess.run(NMSCAN, timeout=1.0, stdout=subprocess.PIPE, text=True)
4951
if ret.returncode != 0:
50-
logging.error(f"consider slowing scan cadence. {ret.stderr}")
52+
logging.error("consider slowing scan cadence.")
5153

5254
dat = pandas.read_csv(
53-
StringIO(ret.stdout),
55+
io.StringIO(ret.stdout),
5456
sep=r"(?<!\\):",
5557
index_col=False,
5658
header=0,

src/mozloc/netsh.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
""" Windows NetSH functions """
2-
import subprocess
2+
3+
from __future__ import annotations
34
import typing as T
5+
import subprocess
46
import logging
57
import shutil
68
import io
@@ -27,16 +29,16 @@ def cli_config_check() -> bool:
2729
return False
2830

2931

30-
def get_signal() -> T.List[T.Dict[str, T.Any]]:
32+
def get_signal() -> list[dict[str, T.Any]]:
3133
""" get signal strength using CLI """
32-
ret = subprocess.run(CMD, timeout=1.0, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
34+
ret = subprocess.run(CMD, timeout=1.0, stdout=subprocess.PIPE, text=True)
3335
if ret.returncode != 0:
34-
logging.error(f"consider slowing scan cadence. {ret.stderr}")
36+
logging.error("consider slowing scan cadence.")
3537

36-
dat: T.List[T.Dict[str, str]] = []
38+
dat: list[dict[str, str]] = []
3739
out = io.StringIO(ret.stdout)
3840
for line in out:
39-
d: T.Dict[str, str] = {}
41+
d: dict[str, str] = {}
4042
if not line.startswith("SSID"):
4143
continue
4244
ssid = line.split(":", 1)[1].strip()

0 commit comments

Comments
 (0)