Tablacus Explorerで選択したアイテムをJScriptからpythonに渡して一括リネーム 

# はじめに
なんか作業でフォルダの中身がわさわさしてくると、一括でリネームしたくなる時もある。

できたもの。
![renamer.gif](https://qiita-image-store.s3.amazonaws.com/0/26677/7f7e7b8d-c748-e9ee-369d-1c12e0a9bc07.gif)



要望としては、

* GUI実行
    * GUI操作は普段使ってる[Tablacus Explorer](http://www.eonet.ne.jp/~gakana/tablacus/explorer.html)でやりたい
    * 対象選択はファイラー上詳細表示からマウスでびろっと選んでボタン1発
    * 日本語ファイル名だとシェル入力つらいし
* ロジック部分は気軽に記述できるように
    * 毎度同じなので置換ルールは決め打ちでいい
    * pythonとかそれなりに慣れてる言語でやりたい
    * おいおい処理追加するかも

# 実装
## ボタンの作成とJScript
Tablacus Explorer上のツールバーにボタン追加する。

それっぽいところ右クリック→"追加"でダイアログを開く。

```JS
//名前:(適当)
//タイプ:JScript
//オプション:(以下コード)
//アイコン:(適当)

var FV = GetFolderView(Ctrl, pt);
var Selected = FV.SelectedItems();

if (Selected) {
    var dat = "";
    for (var i = 0; i < Selected.Count; i++) {
      dat += "\"" + Selected.Item(i).Path + '\" ';
    }
    if (dat == "") {
      alert("not selected.");
    } else {
	    wsh.Run("C:/foo/Src/Python27/python.exe C:/foo/Sample/rename_selected.py " + dat);
    }
}

//コードコピペしたら"追加"で"OK"
```

中身としては、

- 選択アイテムのリストを取得
- そのリストからフルパス抜き出す
- フルパスを"(フルパス1)" "(フルパス2)" ...な感じに文字列へ結合
- 結合文字列を引数として後述のpythonスクリプトに引数で食わせる

## pythonでリネーム
よしなに自分の実行環境にスクリプトを作成。

```python:rename_selected.py

# coding: Shift_JIS
import os
import sys

def get_selected_list(param):
    target_list = []
    if len(param) > 1:
        for folder in param:
            folder = unicode(folder, encoding='shift-jis').replace(unicode("\\", encoding='shift-jis'), "/")
            target_list.append(folder)
    return target_list

def rename_folder(src_path):
    dst_path = src_path

    # 置換ルールは適当に、以下は特定の単語をトリムする例
    # フルパスマッチだから途中でひっかかったらと思うと邪悪である
    dst_path = dst_path.replace(unicode(" - コピー", encoding='shift-jis'), "")
    dst_path = dst_path.replace(unicode(" (1)", encoding='shift-jis'), "")
    dst_path = dst_path.replace(unicode("_yymmdd", encoding='shift-jis'), "")
    if not os.path.isdir(dst_path):
        os.rename(src_path, dst_path)

if __name__ == "__main__":
    folder_list = get_selected_list(sys.argv)
    for folder in folder_list:
        rename_folder(folder)


```

中身は日本語のファイルシステムいじるのが辛かったくらいでまんまなもの。
(好きにやりたいといいつつ、特に高度な正規表現とかと戦ったわけでもない)

# 実装それぞれのもやっとポイント
## Tablacus Explorer上で選択した対象への処理をpythonで記述
Tablacus Explorerってなんかスクリプト拡張?できるんだわぁいと探ってみたけど、当然のように[JScript](https://msdn.microsoft.com/ja-jp/library/72bd815a(v=vs.100).aspx)ってなんですか?となった。

で、とりまJScriptでの記述を最小にして可能な処理をpythonに投げたかったけど、"(キーワード) JScript -javascript"でググるのめんどくさい...

そして、多少わかってくると以下な差分が地味にじわじわ効いてくる...
[MDIE用スクリプトをTablacus Explorerへ移植する際の注意点。オブジェクトの対比など。](http://xiuwu9929.php.xdomain.jp/articles/2015/0102)

なんとか以下とかもたどり着いて無事かけた。

- [某所で要望のあったスクリプトを3つ書いてみました。 ・フォルダ構成のみクリップボードにコピー var CreateFolderOnly2 = function (path, dest, Items, nAdd){ api.SetWindowText(te.hwnd, path); CreateFolder(dest);…](http://tablacus.hatenablog.com/entry/2015/07/14/224503)
- [プログラミングしていく上でのメモを日々記録するブログ](http://kujirahand.com/blog/index.php?JScript%E3%81%A7%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E5%AE%9F%E8%A1%8C)

要素技術的には以下などが必要だった。

- Tablacus上選択アイテムの取得
- 選択アイテムのフルパスの取得
- alertデバッグ
- JScripから外部スクリプトの呼び出し
- 空白や記号など含む日本語引数渡し
- (カレントパスはいるかと思ったけどいらなかった、とれたけど)

## 日本語ファイルシステムと戦うのつらい
なんでまだpython2.7地獄から抜け出せてないのか、いかんいかん

# 所感
最近Tablacus Explorer上でちょっとしたスクリプト書いて、そこからpythonなりローカルの実行系を呼び出すスクリプトをよく書いてる。
完全にブラウザ上でブックマークレット+自作野良アドオンでやってたのと同じではある。

個人的にはやはりGUIの処理をいかにCUIやプログラミング言語の処理に繋げられるか?が大事なのでそれぞれの垣根をいい感じに超えられるといいなと。

ちなみに別途独立したGUIアプリを作ることもできるかもだけど、そうはしなかった。
普段開いてるアプリの中で完結したかったというか、狭いディスプレイ空間に余分なアプリは起動させっぱにしたくなかったので。
ファイラーの端っこにボタン足せるので十分。

以上。