PukiWikiのファイル名のデコード
1. はじめに
PukiWiki は今でも価値あるツールです。簡単な記法である Wiki のページを作れば書式が自動的に整えられるので、書式の整ったページをプログラムで簡単に自動的に大量に作れます。簡単なユーザー制限を設定できるのも便利です。
しかし、メンテナンスの面では、やや苦労します。ページごとのファイル名は、エンコードされているのでどのファイルがどのページに対応するのかわかりにくいです。以前は、pwls という便利なツールが提供されていたが、今、Google で検索しても出てきません。また、文字コードもEUC-JPにしか対応していません。
だったら作りましょう!(と偉そうに書いているが、ChatGPT に助けてもらって作ります。)
2. スクリプト
2-1. 使い方
Linux で使っていることを想定してます。ls コマンドの出力をパイプラインで渡せば、そのままデコードしてくれるようにしました。これで、いろいろなオプションなどは、ls などのコマンドに任せて、プレーンなフィルターとして機能します。
ls -ltr | cat -n | pwdecode.py
- pwdecode.py が今回のスクリプト
- cat -n を入れるのは、ls -ltr | cat -n と比較して、ファイル名を対応付けやすくするため
2-2. 実行例
普通の ls
普通のls
ls -lt *.txt | cat -n
出力結果
...
150 -rw-rw-r-- 1 www-data www-data 221 11月 29 2023 57696B69456E67696E6573.txt
151 -rw-rw-r-- 1 www-data www-data 206 11月 29 2023 57696B694E616D65.txt
pwdecode.py を通したもの
pwdecode.py を通す
ls -lt *.txt | cat -n | pwdecode.py
出力結果
...
150 -rw-rw-r-- 1 www-data www-data 221 11月 29 2023 WikiEngines.txt
151 -rw-rw-r-- 1 www-data www-data 206 11月 29 2023 WikiName.txt
...
2-3. スクリプト
pwdecode.py
#!/usr/bin/python3
###################################################
# pwdecode.py :
# Ver.0 2024-02-23
# ■ 概要
# PukiWiki の wiki/ 以下のファイル名はエンコードされている。
# これを読めるようにする。実用上は、ls を使うはずなので、
# ls に対してパイプラインで実行することを想定している。
# ■ 使用例
# ls -ltr | cat -n | pwdecode.py
# ※ cat -n を入れておくと、実際のファイル名と簡単に対応付けられる。
###################################################
import sys
import re
# PukiWikiは、utf-8 と euc_jp とがある。成功した方を採用。
def try_decode(encoded_bytes):
try:
return encoded_bytes.decode('euc_jp')
except UnicodeDecodeError:
pass
try:
return encoded_bytes.decode('utf-8')
except UnicodeDecodeError:
return None
# 各行のデコード
def decode_pukiwiki_filename(encoded_strings):
decoded_filename = ''
hex_pattern = re.compile(r'([0-9A-F]{4,})(?=\.txt$)') # エンコードされたファイル名部分を抽出
pos = 0
for match in hex_pattern.finditer(encoded_strings):
start, end = match.span()
decoded_filename += encoded_strings[pos:start] # 16進数でない部分を追加
hex_str = match.group(1)
decoded_bytes = bytes.fromhex(hex_str)
decoded_part = try_decode(decoded_bytes)
if decoded_part is not None:
decoded_filename += decoded_part
else:
decoded_filename += hex_str # デコードに失敗した場合は元の16進数の文字列を追加
pos = end
decoded_filename += encoded_strings[pos:] # 残りの部分を追加
return decoded_filename
# 標準入力を受け取り、エンコードされた部分だけをデコード。
for line in sys.stdin:
line = line.strip()
decoded_filename = decode_pukiwiki_filename(line)
print(decoded_filename)
3. コメント
- PukiWikiは、EUC-JP と UTF-8 と2種類あります。どちらのエンコーディングもサポートしています。
- 実行環境の差異も Python が吸収してくれるので、LANGが何であっても実行できます。EUC-JPの環境でも、UTF-8の環境でも、正しくデコードされたファイル名を閲覧できます。
- このプログラムは、wiki/ 以下の、.txt で終わるファイル名だけを対象としています。他のディレクトリのファイルを対象にする場合も拡張するには、正規表現をより複雑にする必要がありますね。