Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 41 additions & 41 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,44 @@ on:
branches: [ main ]

jobs:
lint-and-docs:
name: Linting & Documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.13"

- name: Install dependencies
run: uv sync

- name: Check Python formatting (ruff)
run: uv run ruff format --check

- name: Lint Python code (ruff)
run: uv run ruff check

- name: Check Markdown formatting (mdformat)
run: uv run mdformat --check README.md docs/ sdd/

- name: Check spelling (codespell)
run: uv run codespell .

- name: Type checking (mypy & ty)
run: |
uv run mypy src/
uv run ty check src/

- name: Build documentation (mkdocs)
run: uv run mkdocs build
# lint-and-docs:
# name: Linting & Documentation
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v7
#
# - name: Install uv
# uses: astral-sh/setup-uv@v7
# with:
# enable-cache: true
#
# - name: Set up Python
# uses: actions/setup-python@v7
# with:
# python-version: "3.13"
#
# - name: Install dependencies
# run: uv sync
#
# - name: Check Python formatting (ruff)
# run: uv run ruff format --check
#
# - name: Lint Python code (ruff)
# run: uv run ruff check
#
# - name: Check Markdown formatting (mdformat)
# run: uv run mdformat --check README.md docs/ sdd/
#
# - name: Check spelling (codespell)
# run: uv run codespell .
#
# - name: Type checking (mypy & ty)
# run: |
# uv run mypy src/
# uv run ty check src/
#
# - name: Build documentation (mkdocs)
# run: uv run mkdocs build

test-matrix:
name: Tests (${{ matrix.os }}, Python ${{ matrix.python-version }})
Expand All @@ -62,15 +62,15 @@ jobs:
# "3.14",
]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Install uv
uses: astral-sh/setup-uv@v5
uses: astral-sh/setup-uv@v7
with:
enable-cache: true

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python-version }}

Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,23 @@ jobs:
name: Build sdist and wheel
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Install uv
uses: astral-sh/setup-uv@v5
uses: astral-sh/setup-uv@v7
with:
enable-cache: true

- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v7
with:
python-version: "3.13"

- name: Build distribution packages
run: uv build

- name: Upload build artifacts
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: dist-artifacts
path: dist/
Expand Down
6 changes: 5 additions & 1 deletion src/aisutils/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,11 @@ def stdCmdlineOptions(parser, dbType="postgres", verbose=False):
help="Host name of the computer serving the dbx [default: %default]",
)
# defaultUser = os.genenv('USER')
defaultUser = os.getlogin()
try:
defaultUser = os.getlogin()
except OSError:
defaultUser = os.environ.get("USER", "root")

parser.add_option(
"-u",
"--database-user",
Expand Down
14 changes: 5 additions & 9 deletions src/noaadata/cli/ais_port_forward.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@
import time
import traceback

import exceptions
import Queue
import thread
import queue as Queue
import _thread as thread

import ais.ais_msg_1 as msg1
import aisutils.daemon
Expand Down Expand Up @@ -112,7 +111,7 @@ def recvThread(self, unused=None):
src = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
src.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
src.connect((self.options.inHost, self.options.inPort))
except (OSError, inst):
except OSError as inst:
sys.stderr.write(
str(count)
+ ": Failed to connect to src ... "
Expand Down Expand Up @@ -150,9 +149,6 @@ def recvThread(self, unused=None):

self.recvThreadStopped = True
sys.stderr.write("... end of recv thread\n")
# FIX: remove these two for debugging
sys.stderr.write(" stopped" + str(self.recvThreadStopped) + "\n")
sys.stderr.write(" running" + str(self.running) + "\n")

def startFilterThread(self, unused=None):
"""
Expand Down Expand Up @@ -385,7 +381,7 @@ def sendThread(self, unused=None):
dst = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
dst.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
dst.connect((self.options.outHost, self.options.outPort))
except (OSError, inst):
except OSError as inst:
sys.stderr.write(
str(count)
+ ": Failed to connect to dst ... "
Expand Down Expand Up @@ -650,7 +646,7 @@ def main():
if v:
sys.stderr.write("ping " + str(i) + "\n")
logging.critical("ping " + str(i))
except exceptions.KeyboardInterrupt:
except KeyboardInterrupt:
running = False
if v:
sys.stderr.write("\bshutting down...\n")
Expand Down
3 changes: 2 additions & 1 deletion src/noaadata/cli/ais_receive_bbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@
"""
import sys

import ais.ais_msg_1 as m1
import ais.binary

import ais.ais_msg_1 as m1
from aisutils import uscg


Expand Down
46 changes: 29 additions & 17 deletions src/noaadata/cli/port_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
import time
import traceback

import exceptions # For KeyboardInterupt pychecker complaint

import builtins as exceptions # For KeyboardInterupt pychecker complaint

import nmea.znt # NTP tracking

Expand Down Expand Up @@ -171,9 +172,11 @@ def getLogFileName(self):
return self.options.log_file

def logfile_add_start(self):
if not self.log:
return
self.log.write(
"# Opening log file at {} UTC,{}\n".format(
datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M"), time.time()
datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M"), time.time()
)
)
try:
Expand All @@ -187,8 +190,13 @@ def logfile_add_start(self):
except:
print("Python really should have platform and version!")
self.log.write("# NTP status:\n")
for line in os.popen("ntpq -p -n"):
self.log.write(f"# ntp: {line.rstrip()}\n")
import subprocess
try:
output = subprocess.check_output(["ntpq", "-p", "-n"], text=True)
for line in output.splitlines():
self.log.write(f"# ntp: {line.rstrip()}\n")
except Exception as e:
self.log.write(f"# ntp: ntpq command failed: {e}\n")

def passdata(self, unused=None):
while self.running:
Expand Down Expand Up @@ -238,7 +246,7 @@ def passdata_actual(self, unused=None):
now = time.time()
self.log.write(
"# Closing log file at {} UTC,{}\n".format(
datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M"),
datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M"),
time.time(),
)
)
Expand All @@ -262,43 +270,47 @@ def passdata_actual(self, unused=None):

# Make sure that we log each line with one timestamp that matches
# as close as possible
# m is bytes, data_cache might be string, need to handle this
if isinstance(data_cache, str):
data_cache = data_cache.encode("latin-1")

data_cache += m
if len(data_cache) > 100000:
print("WARNING... not seeing line endings. NOT forwarding")
if self.log:
self.log.write(data_cache)
self.log.write(data_cache.decode("latin-1"))
self.log.write(f"{station_id},{now}\n")
recv_time = None
data_cache = ""
data_cache = b""
continue

if "\n" not in m:
if b"\n" not in m:
continue

lines = data_cache.split("\n")
for line in lines[:-1]:
line = line.rstrip()
line += f",{station_id},{recv_time}\n"
lines = data_cache.split(b"\n")
for line_b in lines[:-1]:
line_str = line_b.decode("latin-1").rstrip()
line_str += f",{station_id},{recv_time}\n"

if self.log:
self.log.write(line)
self.log.write(line_str)
if v > TERSE:
print(line, end=" ")
print(line_str, end=" ")

for c in self.clients:
try:
c.send(line)
c.send(line_str.encode("latin-1"))
except OSError:
print("Client Disconnect")
self.clients.remove(c)

recv_time = now
data_cache = lines[-1] # Save the last partial line
data_cache = lines[-1] # Save the last partial line (bytes)

else:
# Log straight through
if self.log:
self.log.write(m) # Takes a few before it flushes
self.log.write(m.decode("latin-1")) # Takes a few before it flushes
if v > TERSE:
print(m, end=" ")
for c in self.clients:
Expand Down
14 changes: 7 additions & 7 deletions src/noaadata/cli/socket_logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,23 @@


def main():
o = file("norfolk-log.ais", "a")
o = open("norfolk-log.ais", "a")
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("10.1.1.29", 5505))
s.send("$xxBSQ,ACA,*03\x0d\x0a")
buf = ""
s.send(b"$xxBSQ,ACA,*03\x0d\x0a")
buf = b""
while True:
readersready, _outputready, _exceptready = select.select([s], [], [], 0.1)
for sock in readersready:
data = sock.recv(100)
buf += data
newline = buf.find("\n")
newline = buf.find(b"\n")
if newline != -1:
fields = buf.split("\n")
msg = fields[0].strip() + "," + str(time.time())
fields = buf.split(b"\n")
msg = fields[0].decode("latin-1").strip() + "," + str(time.time())
print(msg)
o.write(msg + "\n")
buf = "" + buf[newline + 1 :] if len(fields) > 1 else ""
buf = b"" + buf[newline + 1 :] if len(fields) > 1 else b""


if __name__ == "__main__":
Expand Down
19 changes: 12 additions & 7 deletions src/noaadata/cli/socket_send.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def main():
arg += DOS_EOL
else:
arg += "\n"
s.send(arg)
s.send(arg.encode("latin-1"))

start = time.time()
# print start
Expand All @@ -165,17 +165,22 @@ def main():
readersready, _outputready, _exceptready = select.select([s], [], [], 1)
for sock in readersready:
data = sock.recv(100)
if isinstance(buf, str):
buf = buf.encode("latin-1")
buf += data
newline = buf.find("\n")
newline = buf.find(b"\n")
if newline != -1:
fields = buf.split("\n")
fields = buf.split(b"\n")
if options.uscgFormat:
print(fields[0].strip() + "," + str(time.time()))
print(fields[0].strip().decode("latin-1") + "," + str(time.time()))
else:
print(fields[0].strip())
buf = "" + buf[newline + 1 :] if len(fields) > 1 else ""
print(fields[0].strip().decode("latin-1"))
buf = b"" + buf[newline + 1 :] if len(fields) > 1 else b""
if len(buf) > 0:
print(buf)
if isinstance(buf, bytes):
print(buf.decode("latin-1"))
else:
print(buf)

# s.send('$xxCAB,0,0,,*40'+EOL)
# s.send('$xxCAB,1,1,1,1*40'+EOL)
Expand Down
4 changes: 2 additions & 2 deletions src/noaadata/dumpallwl.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
import sys
from decimal import Decimal

import ais.waterlevel as wl_ais
from ais.nmea import buildNmea
from SOAPpy import SOAPProxy

import ais.waterlevel as wl_ais
import noaadata.stations as Stations
from ais.nmea import buildNmea

__version__ = "0.1.0"
__date__ = "2026-08-03"
Expand Down
Loading