Paepoi

Paepoi » macOS Tips » macOS Tips | 自作 macOS 用コマンド

macOS Tips | 自作 macOS 用コマンド

# 最終更新日 2023.10.09

すべて JXA 又は Puthon3 スクリプトによるコマンドです。
コピペして拡張子無しで保存して実行パーミッションを付加しパスを通したディレクトリへ。
ファイルにしようと思ったけど多分ゲートキーパーに弾かれると思うので。
筆者が付けている名前は括弧内に書いています。

img2/bin.webp
ファイルをゴミ箱に捨てる (trash)
#!/usr/bin/osascript -l JavaScript

/**
 * GNOME は以下のコマンドでファイルをゴミ箱に捨てることができる
 * gio trash ファイル名
 * 同じようにできないかなと思って JXA で作ってみた
 */

ObjC.import("Cocoa");

function run(argv) {
    let urls = [];
    for (path of argv) {
        urls.push($.NSURL.alloc.initFileURLWithPath($(path)));
    }
    $.NSWorkspace.sharedWorkspace.recycleURLsCompletionHandler($(urls), (newURLs, error)=> {
            console.log("done");
            $.NSApp.terminate(0);
        }
    );
    $.NSApplication.sharedApplication;
    $.NSApp.run;
}

// ex: ft=js.jxa

macOS 用 tree コマンド (treee)
#!/usr/bin/env python3

'''
    macOS には tree コマンドが入っていない
    自分で作ってみた、Python3 必須です
'''

import os, sys

all_dir_num = 0
all_file_num = 0

def flist(path):
    '''
        Exclude UNIX hidden files. and sorted.
    '''
    l = os.listdir(path)
    res = []
    for f in l:
        if f.startswith('.'): continue
        if f.endswith('~'): continue
        res.append(f)
    return sorted(res)

def tree(path, tab):
    files = flist(path)
    length = len(files)
    head = '├── '
    num = 1
    for f in files:
        if num == length:
            head = '└── '
        subdir = os.path.join(path, f)
        if os.path.isdir(subdir):
            if sys.stdout.isatty():
                # stdout
                print(f'{tab}{head}\033[34m{f}\033[0m')
            else:
                # Redirect
                print(f'{tab}{head}{f}')
            global all_dir_num
            all_dir_num += 1
            # Recursion
            tree(subdir, f'{tab}│   ')
        else:
            print(f'{tab}{head}{f}')
            global all_file_num
            all_file_num += 1
        num += 1

if __name__=='__main__':
    d = '.'
    if len(sys.argv) > 1:
        d = sys.argv[1]
        if d.startswith('~'):
            d = os.path.expanduser(d)
    print(d)
    tree(d, '')
    # footer
    print(f'\n{all_dir_num} directories, {all_file_num} file')

# ex: ft=py

UTI を調べる (get_uti)
#!/usr/bin/env python3
 
'''
    PyObjC を使った方法、macOS 14 Sonoma 対応
'''

import sys, UniformTypeIdentifiers

for filename in sys.argv[1:]:
    n = filename.rfind('.') + 1
    if n > 0:
        ext = filename[n:]
        uti = UniformTypeIdentifiers.UTType.typeWithFilenameExtension_(ext)
        print(f'{ext}: {uti}')


''' 下記はもう使えない

import sys, CoreServices
 
for ext in sys.argv[1:]:
    uti = CoreServices.UTTypeCreatePreferredIdentifierForTag(
        CoreServices.kUTTagClassFilenameExtension, ext, None)
    arr = CoreServices.UTTypeCopyDeclaration(uti)['UTTypeConformsTo']
    con = ','.join(arr)
    print(f'{ext}: {uti} [{con}]')
'''

# ex: ft=py

画像を WebP に変換 (img2webp)
#!/usr/bin/env python3

'''
    Python の PIL を使った方法です
'''

import sys, os, re
from PIL import Image

arg = sys.argv[1:]
for s in arg:
    if re.search(r'\.(jpe?g|png|gif)$', s, re.I):
        im = Image.open(s)
        im.save(f'{os.path.splitext(s)[0]}.webp')

# ex: ft=py

144dpi のスクリーンショットを 72dpi の WebP に変換 (ss2webp)
#!/usr/bin/env python3

'''
    スクリーンショットを直接 WebP に変換
'''

import sys, os, re
from PIL import Image

arg = sys.argv[1:]
for s in arg:
    if re.search(r'\.(jpe?g|png|gif)$', s, re.I):
        im = Image.open(s)
        # 144dip to 72dpi
        x, y = im.size
        im_s = im.resize((x//2, y//2), Image.Resampling.LANCZOS)
        im_s.save(f'{os.path.splitext(s)[0]}.webp')

# ex: ft=py

Copyright(C) sasakima-nao All rights reserved 2002 --- 2024.