クリップスタジオの素材サムネイルを階層でカタログ化

クリスタが素材ウィンドウでサムネイルの拡大縮小に対応してくれる見込みがないので。
素材サムネイルのjpeg、png画像を取り出して、階層フォルダ作って、その中に素材名で保存するだけ。
これを画像管理ソフトで拡大して見るんだ…。
個人的にトーン素材だけあればいいので、サムネイル複数持ってるような3D素材とかは非対応。
とりあえず動くとこまで持っていければよかったので、美しさとか考えてません。
python触ってみたかったので、勉強がてら。

```
from pathlib import Path
from pathlib import PurePath
from datetime import datetime
import xml.etree.ElementTree as ET
import shutil
import os
import traceback
import re

# Clip Studio素材フォルダの場所
LIBRALY_PATH = "/Users/********/Library/CELSYS/CLIPStudioCommon/Material/"
# 出力フォルダの場所
OUT_PATH = "./クリップスタジオ素材カタログ一覧/"

# デバッグ
DEBUG = False


def log(catalog_path, name, folder_path, msg):
    print('--------')
    print('カタログ：', catalog_path)
    print('階層：', folder_path)
    print('素材名：', name)
    print('出力結果：', msg)


# 素材の名前取得
def material_name(root_element):
    return root_element.find('catalog').find('groups').find('group').find('items').find('item').find('name').text


# 素材情報のファイルパス取得
def material_info_path(root_element, mime_type):
    for file in root_element.find('files').findall('file'):
        if file.get('mime') == mime_type:
            return file.find('path').text


# 素材の階層取得
def material_folder_path(layer_path):
    root = ET.parse(layer_path).getroot()
    for datalist in root.find('info').findall('datalist'):
        if datalist.get('key') == 'foldertag':
            foldertag = datalist.find('data').text
            return foldertag.replace(':', '/')


# 既存の素材一覧バックアップ
if os.path.exists(OUT_PATH):
    out_path = PurePath(OUT_PATH)
    os.rename(OUT_PATH, (os.path.abspath(OUT_PATH) + '_' + datetime.now().strftime("%Y%m%d%H%M%S")))

# 素材場所のPathオブジェクトを生成
p = Path(LIBRALY_PATH)

# 再帰的にcatalog.xml検索
catalog_list = list(p.glob("**/catalog.xml"))
for catalog_path in catalog_list:
    org_name = ''
    name = ''
    folder_path = ''
    org_thumbnail_path = ''
    out_thumbnail_dir_path = ''

    try:
        tree = ET.parse(catalog_path)
        root = tree.getroot()

        # 素材名
        org_name = material_name(root)
        name = re.sub(r'[\\|/|:|?|.|"|<|>|\|]', '-', org_name)

        # 素材のサムネイル画像パス
        # NOTE: 多分3D素材とか複数サムネイル持ってるやつあるけど、私の対象はトーンなのでいいや
        thumbnail_path = material_info_path(root, 'image/jpeg')
        thumbnail_extension = '.jpg'
        if not thumbnail_path:
            thumbnail_path = material_info_path(root, 'image/png')
            thumbnail_extension = '.png'
        org_thumbnail_path = PurePath(LIBRALY_PATH, catalog_path.parent, thumbnail_path)

        # 最終的に出力するサムネイル画像パス
        folder_path = material_folder_path(PurePath(LIBRALY_PATH,
                                                    catalog_path.parent,
                                                    material_info_path(root, 'text/xml')))
        out_thumbnail_dir_path = PurePath("./", OUT_PATH, folder_path)
        out_thumbnail_path = PurePath(out_thumbnail_dir_path, name + thumbnail_extension)

        # サムネイル画像コピー
        if not os.path.exists(out_thumbnail_dir_path):
            os.makedirs(out_thumbnail_dir_path)
        shutil.copyfile(org_thumbnail_path, out_thumbnail_path)

        if DEBUG:
            log(catalog_path, org_name, folder_path, '成功')
    except TypeError as type_err:
        log(catalog_path, org_name, folder_path, "失敗")
    except:
        log(catalog_path, org_name, folder_path, '予期せぬ失敗')

```