Получение информации из ADIF-файлов

Небольшая заметка на тему получения данных из файла в формате ADIF. Будет полезна для анализа лога любительской радиостанции.

В процессе подготовки QSL карточек для позывного RP79AB, который звучал в рамках «Мемориала Победа-79«, возникла необходимость преобразовать лог в формате ADIF в таблицу Excel, содержащую только необходимые поля.

Язык Python прекрасно справляется с такой задачей. Так появился на свет несложный скрипт.

Сначала нужно установить необходимую библиотеку для работы с электронными таблицами.

pip install openpyxl

Исходный текст python-скрипта:

import os
import argparse
from openpyxl import Workbook
from openpyxl.styles import Font
import chardet

def parse_adif_to_excel(input_file, output_file):
    """
    Парсит ADIF-файл и сохраняет данные в Excel-таблицу.

    :param input_file: Имя входного ADIF-файла.
    :param output_file: Имя выходного Excel-файла.
    """
    # Проверка существования файла
    if not os.path.exists(input_file):
        print(f"Ошибка: файл '{input_file}' не найден.")
        return

    # Автоматическое определение кодировки
    try:
        with open(input_file, 'rb') as f:
            raw_data = f.read()
            result = chardet.detect(raw_data)
            encoding = result['encoding']
            print(f"Кодировка файла: {encoding}")
    except Exception as e:
        print(f"Ошибка кодировки: {e}")
        return

    # Создаём новую книгу Excel и выбираем активный лист
    wb = Workbook()
    ws = wb.active

    # Заголовки столбцов
    headers = ["Дата", "Время", "Диапазон", "Режим", "Позывной", "RST"]
    ws.append(headers)

    # Жирный шрифт для заголовков
    for cell in ws[1]:
        cell.font = Font(bold=True)

    # Настройка ширины столбцов
    column_widths = [15, 10, 10, 10, 15, 10]
    for i, width in enumerate(column_widths, start=1):
        ws.column_dimensions[chr(64 + i)].width = width

    # Чтение и парсинг ADIF-файла
    try:
        with open(input_file, 'r', encoding=encoding, errors='replace') as inp_file:
            # Читаем весь файл и разбиваем на записи по <EOR>
            adif_data = inp_file.read()
            records = adif_data.split('<EOR>')

            for record in records:
                # Извлекаем значения из тегов
                qso_date_value = extract_tag_value(record, 'QSO_DATE')
                time_on_value = extract_tag_value(record, 'TIME_ON')
                band_value = extract_tag_value(record, 'BAND')
                mode_value = extract_tag_value(record, 'MODE')
                call_value = extract_tag_value(record, 'CALL')
                rst_send_value = extract_tag_value(record, 'RST_SENT')

                # Добавляем строку в таблицу
                ws.append([qso_date_value, time_on_value, band_value, mode_value, call_value, rst_send_value])

        # Сохраняем книгу в файл
        wb.save(output_file)
        print(f"Файл Excel создан: {output_file}")

    except Exception as e:
        print(f"Ошибка открытия файла: {e}")

def extract_tag_value(record, tag):
    """Извлекает значение тега из записи."""
    start_tag = f"<{tag}:"
    start_pos = record.find(start_tag)
    if start_pos == -1:
        return '' 
    start_value = record.find('>', start_pos) + 1
    end_value = record.find('<', start_value)
    return record[start_value:end_value]

def main():
    # Настройка аргументов командной строки
    parser = argparse.ArgumentParser(description="Парсинг ADIF-файла и экспорт в Excel.")
    parser.add_argument("input_file", help="Имя входного ADIF-файла.")
    parser.add_argument("output_file", nargs='?', default="log.xlsx", help="Имя выходного Excel-файла (по умолчанию 'log.xlsx').")
    args = parser.parse_args()
    parse_adif_to_excel(args.input_file, args.output_file)

if __name__ == "__main__":
    main()

Я постарался его максимально подробно документировать. При желании, можно менять экспортируемые поля. Например, добавить поле RDA или страна по DXCC.

Скрипт принимает на вход два аргумента — входной файл adif и выходной файл xlsx. Пример использования:

python3 script.py rp79ab.adif rp79ab_list.xlsx

Так же доступна справка:

python3 script.py --help

usage: script.py [-h] input_file [output_file]

Парсинг ADIF-файла и экспорт в Excel.

positional arguments:
  input_file   Имя входного ADIF-файла.
  output_file  Имя выходного Excel-файла (по умолчанию 'log.xlsx').

optional arguments:
  -h, --help   show this help message and exit

Пример содержимого выходного Excel-файла:

Думаю, скрипт может быть полезен для анализа своего или чужого лога, для сортировки, фильтрации и анализа, или для печати наклеек на QSL-карточки.

Запись опубликована в рубрике Linux, Python, Радио с метками , . Добавьте в закладки постоянную ссылку.

2 комментария на «Получение информации из ADIF-файлов»

  1. Dmitry говорит:

    Добрый день! Спасибо большое за информацию. Немного почитал сайт ADIF. Интересно, может уже есть готовые библиотеки (предпочтительно на Java), позволяющие читать/ писать ADIF файлы? Можно, конечно, самому написать. Но будет, скорее всего, не полная поддержка стандарта. Да и не будет обновляться вместе со стандартом. В любом случае, спасибо за ссылку на официальный сайт.
    С уважением, Дмитрий, UA9MQJ.
    73!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *