A Python library to parse Cabrillo-format amateur radio contest logs.

pip install cabrillo==0.0.4


cabrillo Build Status

A Python library to parse Cabrillo-format amateur radio contest logs.

Getting Started

Basic Parsing

>>> from cabrillo.parser import parse_log_file
>>> cab = parse_log_file('tests/CQWPX.log')
>>> cab.callsign
>>> cab.qso
[<cabrillo.qso.QSO object at 0x10cb09f28>, <cabrillo.qso.QSO object at 0x10cbc8860>]
>>> cab.text()
'START-OF-LOG: 3.0\nCREATED-BY: WriteLog V10.72C\nCALLSIGN: AA1ZZZ\n[...snip...]END-OF-LOG:\n'

You can also write to a file:

with open('out.cbr', 'w') as o:

The same works for text-file-like objects.

Finally, if you desire to parse Cabrillo data already present as a Python string, you can do so with, e.g.,

from cabrillo.parser import parse_log_text

cabrillo_text = """START-OF-LOG: 3.0

cab = parse_log_text(cabrillo_text)

Ignoring malorder

Cabrillo logs must be time-sorted. If you want to read files that are not so sorted, but other than that are Cabrillo files, you can do so by adding a keyword argument ignore_order=False to either parse_log_file or parse_log_text. If you do that, the resulting Cabrillo object will refuse to generate (potentially non-)Cabrillo output.

Matching Two QSOs in Contest Scoring

>>> # We start off with a pair with complementary data.
>>> from cabrillo import QSO
>>> from datetime import datetime
>>> qso1 = QSO('14313', 'PH', datetime.strptime('May 30 2018 10:15PM', '%b %d %Y %I:%M%p'), 'KX0XXX', 'KX9XXX', de_exch=['59', '10', 'CO'], dx_exch=['44', '20', 'IN'], t=None)
>>> qso2 = QSO('14313', 'PH', datetime.strptime('May 30 2018 10:10PM', '%b %d %Y %I:%M%p'), 'KX9XXX', 'KX0XXX', de_exch=['44', '20', 'IN'], dx_exch=['59', '10', 'CO'], t=None)
>>> qso1.match_against(qso2)
>>> qso1.freq = '14000'  # Same band, still will match.
>>> qso1.match_against(qso2)
>>> qso1.match_against(qso2, max_time_delta=1)  # Make time checking less lenient.
>>> # All flags.
>>> qso1.match_against(qso2, max_time_delta=30, check_exch=True, check_band=True)


Use these attributes to access and construct individual objects.

class Cabrillo(builtins.object)
 |  Cabrillo(check_categories=True, **d)
 |  Representation of a Cabrillo log file.
 |  Attributes:
 |        version: The only supported version is '3.0'.
 |        callsign: Call sign of station.
 |        contest: Contest identification.
 |        category_assisted: One of CATEGORY_ASSISTED.
 |        category_band: One of CATEGORY_BAND.
 |        category_mode: One of CATEGORY_MODE.
 |        category_operator: One of CATEGORY_OPERATOR.
 |        category_power: One of CATEGORY-POWER.
 |        category_station: One of CATEGORY-STATION.
 |        category_time: One of CATEGORY-TIME.
 |        category_transmitter: One of CATEGORY-TRANSMITTER. Optional for
 |          multi-op.
 |        category_overlay: One of CATEGORY-OVERLAY.
 |        certificate: If certificate by post. Boolean.
 |        claimed_score: Claimed score in int.
 |        club: Club represented.
 |        created_by: Software responsible for creating this log file.
 |          Optional, defaults to "cabrillo (Python)".
 |        email: Email address of the submitter.
 |        location: State/section/ID depending on contest.
 |        name: Log submitter's name.
 |        address: Mailing address, as a list, one entry per line.
 |        address_city: Optional granular address info.
 |        address_state_province: Optional granular address info.
 |        address_postalcode: Optional granular address info.
 |        address_country: Optional granular address info.
 |        operators: List of operators' callsigns.
 |        offtime: List containing two datetime objects denoting start and
 |          end of off-time.
 |        soapbox: List of lines of soapbox text.
 |        qso: List of all QSO objects, including ignored QSOs.
 |        valid_qso: List of all valid QSOs (excluding X-QSO) (read-only).
 |        x_qso: List of QSO objects for ignored QSOs (X-QSO only) (read-only).
 |        x_anything: An ordered mapping of ignored/unknown attributes of the Cabrillo file.
 class QSO(builtins.object)
 |  QSO(freq, mo, date, de_call, dx_call, de_exch=[], dx_exch=[], t=None, valid=True)
 |  Representation of a single QSO.
 |  Attributes:
 |      freq: Frequency in kHz in str representation.
 |      mo: Transmission mode of QSO.
 |      date: UTC time as datetime.datetime object.
 |      de_call: Sent callsign.
 |      de_exch: Sent exchange. List, first item is RST, second tends to be context exchange.
 |      dx_call: Received callsign.
 |      dx_exch: Received exchange. List, first item is RST, second tends to be context exchange.
 |      t: Transmitter ID for multi-transmitter categories in int. 0/1.
 |      valid: True for QSO that counts, False for an X-QSO.


Pull requests are appreciated!

The following instructions show how to obtain the sourcecode and execute the tests. They assume Python 3.3 or later.

For Posix plattforms (which includes Mac and Linux):

git clone
cd cabrillo
python3 -m venv python-venv
source python-venv/bin/activate
pip install -r requirements_test.txt
py.test --cov-report term-missing --cov cabrillo -v

On a Windows machine, using cmd.exe, substitute python-venv/Scripts/activate for source python-venv/bin/activate.