import csv
import os
import re
# JI1FGX/DU9 Kouichi Ueno
# 2024/12/11
# TEXTtoCSV.0.0.4.py
#
# ARRLのDXCCリストのテキストバージョンからCSVファイルを作るためのソフトウェアです
# TEXTtoCSV.0.0.4.pyを実行するためにはPythonのインストールが必要です。
# Pythonのインストールは、公式サイト(https://www.python.org/downloads/)から行えます。
#
# DXCCリストはこのURLにあります。
# https://www.arrl.org/files/file/DXCC/2022_Current_Deleted.txt
# ?fbclid=IwY2xjawHGCUlleHRuA2FlbQIxMAABHSpoK2uUB3J5nKtnAjPJtJ0
# 1VUgUnIFpkRNY2s6cbowNvBXPnSUqr8uHnA_aem__JJWBzpbcoBSbzwvk8paPQ
# ダウンロードするかコピー&ペーストで input.txtの名前で フォルダーに保存してください。
# 下処理としてはヘッダー文章は削除してください。
#
# 保存ディレクトリはデフォルトでC:\Logsになっています。 適当に変えてください。
# 実行するとoutput.csvというファイルをデフォルトディレクトリに作ります。
# テキストファイルに含まれている(数字)、*、#、^を取り除きCSVファイルを作ります。
#
# ロシアのコールサインルールが分かりにくかったので独自にルールリストを作りました。
# UA-UI1-7,RA-RZ* European Russia
# UA-UI8-0,RA-RZ* Asiatic Russia
#
# 同梱してあるファイル
# TEXTtoCSV.0.0.4.py このプログラム
# input.txt ARRLからダウンロードしたテキストファイル
# output.csv 変換後のサンプルファイル
# Russia_Call_Rules.csv デフォルトデレクトリーに置いておいてください
# Readme.txt
#
# 開発裏話
# プログラム自体はChatGPTが書いています。
# 私は仕様を伝えてそれに答える形でPythonのソースコードを送り返してきます。
# 機能追加や細かい修正も指示していきます。
# テキストファイルからCSVへの変換や不要文字の削除などはものの数分でできました。
# ところがDXCCリストに含まれているイレギュラーな文字を1文字消すのにChatGPTはてこずりました。
# 具体的には T8,(21) のカッコつきの、カンマの削除これはすぐに出来たのですが
# Z6(1),(55)このカンマを取るのに沢山のやり取りをしました。 この正規表現を書かせると必要なカンマまで消してしまうのです。
# 何度も正常な処理が出来るバージョンに戻しては書かせるの繰り返しに半日。
# こちらから具体的な提案をしてやっと出来上がりました。
# デフォルトディレクトリとファイル名
default_dir = 'C:\\Logs'
input_filename = os.path.join(default_dir, 'input.txt')
output_filename = os.path.join(default_dir, 'output.csv')
output_temp_filename = os.path.join(default_dir, 'output_temp.csv')
russia_rules_filename = os.path.join(default_dir, 'Russia_Call_Rules.csv')
try:
# 入力ファイルの指定
input_file = input(f'入力ファイル名を指定してください (デフォルト: {input_filename}): ') or input_filename
if not os.path.exists(input_file):
raise FileNotFoundError(f'ファイルが見つかりません: {input_file}')
# 出力ファイルの指定
output_file = input(f'出力ファイル名を指定してください (デフォルト: {output_filename}): ') or output_filename
# 出力ファイルが存在する場合の確認
if os.path.exists(output_file):
overwrite = input(f'{output_file} は既に存在します。上書きしますか? (y/n): ').strip().lower()
if overwrite != 'y':
print('処理を中止しました。')
exit()
# output_temp.csvの作成処理(自動的に作成)
with open(input_file, 'r', encoding='utf-8') as infile, open(output_temp_filename, 'w', newline='', encoding='utf-8') as outfile:
csv_writer = csv.writer(outfile, quoting=csv.QUOTE_MINIMAL)
for line in infile:
# 行の前後のスペースを削除
line = line.strip()
# 括弧内の数字を削除 (T8以外の行にも対応)
line = re.sub(r'\(\d+\)', '', line) # 括弧内の数字を削除
# 不要な記号を削除(ただし、ハイフンは残す)
line = re.sub(r'[^\w\s,-]', '', line) # ^, #, *, ^, (, ) を削除(ハイフンは除外)
# 行の先頭の余分なスペースを削除
line = line.lstrip()
# カンマで分割してリストを作成
parts = line.split()
# 特定のカラムの結合(国名とその他の情報)
if len(parts) >= 3:
callsign = parts[0]
continent_and_numbers = parts[-4:] # 最後の4つを取得
country_name = ' '.join(parts[1:-4]) # 第2カラム以降、スペースを含む部分を結合
# 行をCSVとして書き込む
row = [callsign, country_name] + continent_and_numbers
csv_writer.writerow(row)
print(f'output_temp.csvが自動的に作成されました: {output_temp_filename}')
# 2行の難解なロシアコールルールを削除するか確認(不要な場合の処理)
delete_russia_rules = input('2行の難解なロシアコールルールを削除しますか? (y/n): ').strip().lower()
if delete_russia_rules == 'y':
# 不要なロシアコールルールを削除
with open(output_temp_filename, 'r', encoding='utf-8') as infile:
lines = infile.readlines()
# "Asiatic Russia" または "European Russia" を含む行を削除
lines = [line for line in lines if not re.search(r'(European|Asiatic) Russia', line)]
# フィルタリング後の内容を書き戻す
with open(output_temp_filename, 'w', newline='', encoding='utf-8') as outfile:
outfile.writelines(lines)
print('output_temp.csvから不要な行を削除しました。')
# ロシアコールルールを読み込むか確認
load_russia_rules = input('ロシアコールルールを読み込みますか? (y/n): ').strip().lower()
if load_russia_rules == 'y':
if os.path.exists(russia_rules_filename):
with open(russia_rules_filename, 'r', encoding='utf-8') as russia_file:
russia_lines = russia_file.readlines()
# ロシアコールルールを出力ファイルの末尾に追加
with open(output_temp_filename, 'a', newline='', encoding='utf-8') as outfile:
outfile.writelines(russia_lines)
print(f'ロシアコールルールを {output_filename} の末尾に追加しました。')
else:
print(f'{russia_rules_filename} は存在しません。ロシアコールルールの追加をスキップしました。')
else:
print('ロシアコールルールの削除をスキップしました。')
# 異常処理を実行 (output_temp.csv → output.csv)
# ここで異常処理プログラムを実行
with open(output_temp_filename, 'r', encoding='utf-8') as infile, open(output_file, 'w', encoding='utf-8') as outfile:
for line in infile:
# 行を処理
modified_line = line
# ダブルクォーテーションで囲まれた文字列の2番目のダブルクォーテーションの前にあるカンマを削除
if '"' in modified_line:
# 文字列内の最初と2番目のダブルクォーテーションの間にカンマがあれば削除
parts = modified_line.split('"')
if len(parts) > 2:
# ダブルクォーテーション間にカンマがあれば削除
parts[1] = parts[1].rstrip(',') # 1番目のクォート内の末尾にカンマがあれば削除
modified_line = '"'.join(parts)
# 加工した行を出力ファイルに書き込み
outfile.write(modified_line)
print(f'最終的な変換が完了しました: {output_file}')
# output_temp.csv を削除
os.remove(output_temp_filename)
# print(f'{output_temp_filename} を削除しました。')
except FileNotFoundError as e:
print(e)
except KeyboardInterrupt:
print('\n操作が中断されました。')
except Exception as e:
print(f'エラーが発生しました: {e}')