macOS: Get UTI (Ventura)

macOS 13 Ventura で以下の関数が使えなくなった件。

# Deprecated
UTTypeCreatePreferredIdentifierForTag

UTI を調べる方法にて検索するとメッチャ見つかります。
でももう使えません、別の方法を探す。

UTType | Apple Developer Documentation

UTType クラスに typeWithFilenameExtension メソッドがある。
+ だから static method ですね、これ使えるかも。
以下 PyObjC です、他言語の人は変換してね。

#!/usr/bin/env python3

'''
    PyObjC @ Get UTI
'''

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}')


''' Deprecated

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

get uti

よしデジカメ RAW ファイルでも問題なく UTI が得られるぞと。
本サイトのほうも書き換えしておきます。
しかし以前貼ったスクリプトで WebP 化したけど文字がチト見づらいな。
これも要改良かな、ということで。

aoji

今日はアオジが撮れました。

Kawasemi

今日もキジポイントへ、いや勝手に名付けているだけです。
いい天気だ、カワセミが道中の五条川で大サービスしてくれた。

kawasemi

トリミング無し、いや 300 万画素に縮小しましたけど。
これだけ綺麗に撮影できると雌だとはっきり解ります。

kawasemi

LUMIX の「生命力・生命美」な絵作りはカワセミにぴったり。
でも LUMIX G99 なのでプロキャプチャが使えず。

kawasemi

連写じゃコレが精一杯、いやヘタクソなだけですけど。
AF が最初に合った時点で MF に切り替えたほうがいいのかな?

kawasemi

ボディを E-M5 に換装、プロキャプチャ様様です。
場所が悪く枝の前ボケが入ってしまったけどやっぱりコレだよ。

G99 と E-M5、一長一短で困る。
Dual I.S. と使いやすいボタン配置と Luminar Neo との相性。
小型軽量とプロキャプチャと AI ノイズリダクション。

G9pro や OM-1 を手に入れても一長一短は解決しないっていう。
いっそ EOS R7、いやなんでもない。
ついでに、オリンパスレンズの MF クラッチは LUMIX でも有効なのね。
今年の桜は LUMIX で撮影してみるか。

ところで Luminar neo を 1.6.4 にアップデート。
[L, T, E] キーでビューを切り替えできるようになった。
やっぱりアレはバグだったのか、変だなと思っていた。

今日もキジは現れず。

Hibari

昨日の遅番出勤中に田圃にてキジを発見、当然カメラは無い。
今日も来るかもしれない、と同じ田圃で張り込みをすることに。

sekirei

出待ち中に LUMIX G99 の追尾 AF ターゲットを試してみる。
EVF を覗いた状態でタッチパネルでターゲットを指定、簡単だね。
このサイズ以上ならしっかり追尾してくれる、オリンパスは…
ターゲット枠より小さいと容赦無く背景に抜けるのはしかたがない。
大きめで動き回る被写体には使えるかも。

hibari

ヒバリ、E-M5 ボディにて少しクロップ。
G99 の直後に使うとやはりグリップが欲しくなる、てか持ちづらい。
完全に慣れなんだけど G99+100-400 を持つと「コレコレ」ってなる。
OM-1 とかでも「コレコレ」感が出るのかな?いやまだ買わないけど。
てかもうヒバリがいるのか、今までドコにいっていたんだろう?

hibari

別の場所でこれもヒバリ、G99 ボディにて少しクロップ。
今更だけど Dual I.S. ってスゲェな、E-M5 手ぶれ補正よりいい。
補正自体はどっこいだけどコッチはレンズを振っている時にも補正するのが。
これが本当にありがたい、比べないと気にしないかもだけど。

Luminar Neo 現像はやっぱり LUMIX のほうが綺麗に、Standard が選べるし。
キジは現れず、明日はどうしよう。

Escape

INI ファイルの読み書きページを更新しました。
INI ファイルの読み書き – Paepoi

セクションを見つける正規表現に最初戸惑った。

EXP = r'^\[\w+\]$'

でイケると思ったけど文字列に半角スペースがあると認識できない。
半角スペースを使うなで済ませようとも思ったけど。

EXP = r'^\[[^\]]+\]$'

そうだ「閉じブラケット以外の文字列なら何でもいい」にすれば!
こんなアホな思いつきに対応できる正規表現ってやはり面白い。

とほほの正規表現入門 – とほほのWWW入門
ところで、とほほさんで見た「ブラケット内は記号の意味を失う」なんですが。

#! /usr/bin/env python3

import re

# [..] にマッチさせる正規表現
EXP = r'^\[[^\]]+\]$'
# EXP = r'^\[[^]]+\]$' # Python OK

a = ['[test]', '[test2]', '[test3] ', ' [test4]', '[test 5]']

for s in a:
    if re.search(EXP, s):
        print(s)

Python

#! /usr/bin/env php

<?php

// [..] にマッチさせる正規表現
$EXP = '/^\[[^\]]+\]$/';
// $EXP = '/^\[[^]]+\]$/'; # PHP OK

$a = ['[test]', '[test2]', '[test3] ', ' [test4]', '[test 5]'];

foreach ($a as $s) {
    if (preg_match($EXP, $s))
        echo $s.PHP_EOL;
}
?>

PHP

#! /usr/bin/gjs

// [..] にマッチさせる正規表現
const EXP = /^\[[^\]]+\]$/;
//const EXP = /^\[[^]]+\]$/; // Gjs NO

let a = ['[test]', '[test2]', '[test3] ', ' [test4]', '[test 5]'];

for (let s of a) {
    if (EXP.test(s)) {
        print(s)
    }
}

Gjs ダメだった。

JavaScript エンジンは複数あるので全部かどうかは試していないけど。
エスケープすれば全部イケたのでブラケット内もエスケープしたほうがいいかと。

deprecated: SafeConfigParser

Python 3.11 は SafeConfigParser が非推奨になっていた。

deprecated

3.12 で完全削除のようです、3.11 は一応まだ動く。
今のうちに 2013 年に作った下記ページを書き換えとかないと。

INI ファイルの読み書き – Paepoi

てか GTK3 のコードだし、require_version していないし。
それと文字列をシングルクォートに統一でココは手をつけていないし。
自作クラスのほうも今なら正規表現にするし。

configparser — 設定ファイルのパーサー ? Python 3.11.1 ドキュメント

configparser.ConfigParser にすればいいのかな?
GTK4 で書き換えしてみよう。

#! /usr/bin/env python3

import os, configparser, gi
gi.require_version('Gtk', '4.0')
from gi.repository import Gtk

INI = 'test.conf'

class Win(Gtk.ApplicationWindow):
    '''
        ini(conf) の読み書き例
        Window の位置と大きさを保存と復元
    '''
    def __init__(self, a):
        '''
            起動時に ini を読み込む
            GTK4 は位置指定できないのかな?
        '''
        Gtk.ApplicationWindow.__init__(self, application=a, title='ini')
        # 設定ファイルを探す
        if os.path.exists(INI):
            # configparser を作成し読み込む
            conf = configparser.ConfigParser()
            conf.read(INI)
            # 後での追記を考えて has_opthon しておこう
            cx = 200
            cy = 200
            if conf.has_option('window', 'width'):
                cx = conf.getint('window', 'width')
            if conf.has_option('window', 'height'):
                cy = conf.getint('window', 'height')
            self.set_default_size(cx, cy)

    def do_close_request(self):
        '''
            GTK3 では do_delete_event
            終了時に ini に書き込み
        '''
        conf = configparser.ConfigParser()
        if os.path.exists(INI):
            conf.read(INI)
        # [window] セクションが存在しなければ追加
        if not 'window' in conf.sections():
            conf.add_section('window')
        # サイズを取得(タプルで戻る)して conf にセット
        cx, cy = self.get_default_size()
        conf.set('window', 'width', str(cx))
        conf.set('window', 'height', str(cy))
        # ファイルに書き込む
        with open(INI, 'w') as f:
            conf.write(f)
        return False

app = Gtk.Application()
app.connect('activate', lambda a: Win(a).present())
app.run()

これでイケるようだ。
そういえば GTK4 でウインドウの位置指定ってまだ調べていなかったな。