0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PukiWikiのファイル名のデコード

Last updated at Posted at 2024-02-23

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 で終わるファイル名だけを対象としています。他のディレクトリのファイルを対象にする場合も拡張するには、正規表現をより複雑にする必要がありますね。
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?