Pythonでフォルダの内容を比較してHTML化 (for NI Maschine)

## はじめに

ふたつのフォルダを比較してHTMLで見やすく表示するプログラムを作りました。
ファイル数が少なければlsとdiffでもいいですし、[WinMerge](https://winmerge.org/)を使うとかなり見やすくなります。しかしながら数万ファイルあるとそれでも不十分です。

やりたいことは、2カラムで左右にそれぞれ階層のあるフォルダを比較して、フォルダを開いたり閉じたりできること、また必要なファイルを見つけるために検索機能もあると嬉しいです。

いろいろ探しても望むツールが見つからなかったのでPythonとJavaScriptで自作しました。Pythonでフォルダ探索をしてHTMLを出力して、階層の開閉と検索はJavaScript側で実装しています。

## ソースコード

https://github.com/aike/M2LibraryList

## デモページ

https://aike.github.io/M2LibraryList/

![ss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/c9de5636-1fd1-24af-1a28-c4b7c5322ba4.png)

検索フォームにキーワードを入れてEnterを押すと該当するもののみ表示できます。
![808.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22455/fe845772-b24b-336d-c314-fd8a661d6fdd.png)

## 実装

globを使用することで最下層のフォルダまで一気に取得できます。
```python
  file1 = glob.glob(dir1 + '**/*', recursive=True)
  file2 = glob.glob(dir2 + '**/*', recursive=True)
```

親フォルダ名を削除
```python
  file1_noroot = list(map(lambda x: x.replace('\\','/').replace(dir1, ""), file1)))
  file2_noroot = list(map(lambda x: x.replace('\\','/').replace(dir2, ""), file2)))
```

ひとつのリストに結合します。一旦setにしてからlistに戻すのは重複をまとめるためです。要はunique処理。
```python
  file3 = list(set(file1_noroot + file2_noroot))
```

Bass SynthフォルダとBass/Synthファイルの両方が存在するような場合、ソート結果が意図と違ったため、フォルダの場合は末尾に「/」をつけるようにしてからソートするようにします。ソート条件でkey=str.casefoldをつけると大文字小文字を区別せずにソートします。
```python
  # "Bass Synth"フォルダと "Bass"フォルダの子要素を正しくソートできないので、末尾にスラッシュを追加
  for i in range(len(file3)):
    if (os.path.isdir(dir1 + file3[i])) or (os.path.isdir(dir2 + file3[i])):
      file3[i] = file3[i] + "/"

  file_all = sorted(file3, key=str.casefold)
```

あとはHTMLを出力するだけです。フォルダの表示・非表示用に連番のクラス名を付与していますが長くなるので説明は省略します。詳しくはソースコードを見てください。
```python
  for f in file_all:
    # （中略） 
    print('<tr class="' + clsstr + '"><td>', end='')
    if f in file1_noroot:
      print(fname, end='')
    print("</td><td>", end='')
    if f in file2_noroot:
      print(fname, end='')
    print("</td></tr>")
```


## 作った理由

Native Instruments社の[Maschine](https://www.native-instruments.com/jp/products/maschine/production-systems/maschine/)というハードウェア／ソフトウェアがあります。サンプリングされた音源を使用して曲を作るための世界的に人気の高いツールです。MaschineはNative Instrumentsのエコシステムの中核をなすツールにもかかわらず、その商品ラインナップや追加サンプリングライブラリは非常にわかりにくくなってしまっています。

Maschineのライブラリは以下の種類があります。

- Factory Selection (1.6 GB)
- Full Factory Library (8 GB)
- Expansions

[Maschine Essentials](https://www.native-instruments.com/jp/products/maschine/maschine-accessories/maschine-essentials/)はMaschineハードウェアやKomplete Kontrolキーボードを購入するとバンドルされてくるソフトウェアで**Factory Selection**が含まれます。  

Maschine Essentialsの所有者は有償でFactory Selectionを**Full Factory Library**に[アップグレード](https://www.native-instruments.com/jp/products/maschine/maschine-accessories/upgrade-your-library/)できます。[^1]

[^1]: Full Factory Libraryは、公式でもMaschine Factory Library、Maschine 2 Factory Library、Full Maschine Factory Library、Full Maschine Libraryなどと表記が揺れています

**Expansions**は追加購入できるライブラリパックで[多くの種類が発売](https://www.native-instruments.com/jp/catalog/software/expansions/)されていますが、いずれもFull Factory Library / Factory Selectionとは内容がかぶりません。

NIの最強バンドル製品[KOMPLETE](https://www.native-instruments.com/jp/products/komplete/bundles/komplete-14-standard/compare/)シリーズにも多くのExpansionsが収録されていますが、これもFull Factory Library / Factory Selectionとは内容がかぶりません。

そして、Full Factory Library / Factory Selectionに何が収録されているか、具体的なリストは公開されていません。

そのためハードウェアを購入してFactory Selectionを所有している人は、Full Factory Libraryにアップグレードするべきかどうかを判断する情報がほとんどないのです。
そこで、今回実際にアップグレードしてみて内容を比較する表を生成することにしました。Factory SelectionとFull Factory Libraryは別のフォルダにインストールされるため、フォルダ内容を比較することで収録コンテンツの差を確認できます。