Programming」カテゴリーアーカイブ

GNOME 3.38 Gjs

すっかり遅くなってしまったけど、GNOME 3.38 の変更点。
筆者に関係ありそうなのは Gjs だけだな。

開発者、システム管理者向けの新規事項

String.replaceAll() なんかはメソッド名で別るんだけーがさぁ。
?? と ?. オペレーターの追加、とあるけど説明無し、何だよコレ。
「 javascript nullish check 」で検索。

JavaScriptのOptional ChainingとNullish Coalescing Operatorでnullやundefinedと戦う

#!/usr/bin/gjs
 
//const p = console?.log ?? print;  // Error
const p = this.console?.log ?? print;
p("SUZUKIS Motorcycle is Cool!");

Gjs には console オブジェクトが無い、ということで単純にやってみた。
オブジェクトを直接 (undefined|null) かどうかは調べられないのね。
プロパティが (undefined|null) かどうかのチェックということね。
グローバルオブジェクトはルートの this から辿れる、いやこんな使い方普通はしない。

#!/usr/bin/gjs

if (typeof console === 'undefined')
    print('print');
else
    console.log('console');

undefined だけなら昔ながらの方法があるし、筆者も使っていた。
null かどうかも調べたい時に or 演算する手間が省けるようです。
というかコレ ES2020 の新規機能ってことみたい。

JavaScriptの次の仕様ES2020で追加されることが決定した新機能まとめ – ICS MEDIA

これ以外の ES2020 も使えるかテスト。
import 関数は使えない。
Promise はエラー、よくわからない。
matchAll は動く、Gjs では詳細は出力されないけど。
globalThis は Gjs では関係ない、てか this でよくね?
BigInt は GNOME 3.36 で既に対応していた。

ということで、今日の木曽川。

tsugumi

ツグミ、でかいスズメじゃないよ冬しかいないよ。

kogera

コゲラ、この可愛らしさでキツツキってのがまた。

enaga

エナガ、シジュウカラやメジロと混群していた。

今日はカメラを持った人を結構見た、巨大な白レンズも何人か。
けれど皆カモばかり撮っていた、小鳥も沢山いるのにもったいない。
てか爺さんばかり、なんか道の駅のバイク置き場カヨって感じ。
若い人も電車やコスプレばかりじゃなく小鳥も撮ろうよ。

PyGObject Exif

わざわざ八田川まで通っていた日々は、意味あったジャン。
メジロやキセキレイを見つけた、これらも五条川で見たことない。

メジロってスズメより小さくてカワイイんだよ。
団体行動しかしないからスズメみたいにドコにでもいるわけじゃないんだよ。
しかも全然木から降りてこないし常にアクロバットに動き回っているんだよ。

mejiro

というわけで撮りにいってきた。
キセキレイはまだ一度しか見たことないな、普段ドコにいるんだろう?
ちなみにカワセミは前回とまったく同じ橋の日陰にいた。

ところで。

Fedora の場合 Exif 情報を得るには GExiv2 を使えばいい。
と書いたけど前回の PyObjC のように一覧表示する方法は知らなかった。
ということでチト調べよう。

C
gexiv2/gexiv2-metadata-exif.cpp ? master ? GNOME / gexiv2 ? GitLab

PyGObject
GExiv2.Metadata – Classes – GExiv2 0.10

get_exif_tags で配列を得て get_tag_string すればよさそう。
やってみたら Exif.Panasonic から始まる LUMIX 独自タグがズラリ。
Exif.Panasonic.LensType だけは取得したいな。
最後の LensType だけで見分けしたけど他のメーカーも同じなのかは知らない。

基本的には Exif.Image と Exif.Photo 接頭子のものだけ得られればよさげ。
あと邪魔なので省いたタグについてはソース内の URL で。
ということでこんなコードに。

#!/usr/bin/env python3

import sys, gi
gi.require_version('GExiv2', '0.10')
from gi.repository import GExiv2

def get_exif_dict(filename):
    metadata = GExiv2.Metadata()
    metadata.open_path(filename)
    tags = metadata.get_exif_tags()
    res = {}
    for tag in tags:
        if tag == 'Exif.Photo.MakerNote':
            # https://www.exiv2.org/makernote.html
            continue
        elif tag == 'Exif.Image.PrintImageMatching':
            # https://kotobank.jp/word/PRINT%20Image%20Matching-12107
            continue
        elif tag.startswith('Exif.Image.0x'):
            # https://exiftool.org/TagNames/EXIF.html
            continue
        elif tag.startswith('Exif.Image') or \
                tag.startswith('Exif.Photo') or \
                tag.endswith('LensType'):
            value = metadata.get_tag_string(tag)
            print(f'{tag}: {value}')

d = get_exif_dict(sys.argv[1])

exif

これと PyObjC 版の出力を比較すれば両方で使えるツールを作れそう。
ぶっちゃけデジイチの時点で mac 用しか需要なんて無いんだけど。

PyObjC Exif

よし休日だ。
今日こそ、今度こそは五条川でカワセミを見つけて撮影してやるぞ!
と昼前に遊歩道へ行って十分後。

こんなにあっさり。
わざわざ八田川まで通っていた日々は何だったんだろう。
まあいい、次は狩りの瞬間を撮りたいな。

ところで。

Fedora の場合 Exif 情報を得るには GExiv2 を使えばいい。
macOS の場合はどうすればいいんだろう、ちゃちゃっと検索。

@macosx: NSImage Exif (metadata)

CGImageSource なんてものが SDK にあるみたい。
連想配列を使うのなら PyObjC で書くとスゲェ簡単だぞ。
ImageIO SDK の Objective-c Bridge は以下にあった。

/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/Quartz

ということでエラー処理を省いて PyObjC で書き換えてみた。
メソッドの場合は引数の数だけアンダーバーが必要なのを忘れずに。

#!/usr/bin/env python3

from AppKit import *
from Quartz.ImageIO import *
import sys

def get_exif_dict(filename):
    url = NSURL.fileURLWithPath_(filename)
    source = CGImageSourceCreateWithURL(url, None)
    data = CGImageSourceCopyPropertiesAtIndex(source, 0, None)
    return data #['{Exif}']

d = get_exif_dict(sys.argv[1])
print(d)

以上。

macos_exif

dict の中に更に {ExifAux} 等の dict があって細かく情報が得られる。
CFDictionaryRef も Python の dict 同様に添字でアクセスできる。
こんなに楽チンなのに PyObjC って全然流行らないのは何故だろう。

レンズの名前まで記録しているのね、こういう情報が残っていると助かる。
野鳥撮影は楽しいよ、プログラミングの楽しさになんか似ている。

GtkDialog

GtkDialog のボタンをメッセージが長くても幅いっぱいに広げる方法が解った。
action_area って実は GtkButtonBox だった。

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
 
dlg = Gtk.Dialog()
dlg.vbox.pack_start(Gtk.Label(label='a'*50, visible=True), False, False, 30)
dlg.add_button('_OK', Gtk.ResponseType.CLOSE)
dlg.add_button('_Cancel', Gtk.ResponseType.CLOSE)

# Expand
area = dlg.get_action_area()
area.props.layout_style = Gtk.ButtonBoxStyle.EXPAND

dlg.run()
dlg.destroy()

expand_buttons

それだけだったのか。。。。。

ついでに解った。
use-header-bar property を 1 にすれば buttons が headerbar になる。

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
 
dlg = Gtk.Dialog(use_header_bar=1)
dlg.vbox.pack_start(Gtk.Label(label='Titlebar Buttons', visible=True), False, False, 30)
dlg.add_button('SUZUKI', Gtk.ResponseType.CLOSE)
dlg.add_button('MotorCycle', Gtk.ResponseType.CLOSE)
dlg.add_button('Cool', Gtk.ResponseType.CLOSE)

dlg.run()
dlg.destroy()

titlebar_buttons

そうだったのか。。。。。

それとタイトルバーを消す方法なんだが。
非表示の GtkTitleBar をセットすればとりあえず消すことはできると解った。
でも角が丸くならない、色々試したけど上手くいかない。
で思いついた、GtkMessageDialog のボタンを使わず add_button すればよくね?

#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
 
dlg = Gtk.MessageDialog(text='SUZUKI MotorCycle is Bery Cool!', visible=True)
dlg.add_button('_OK', Gtk.ResponseType.CLOSE)
dlg.add_button('_Yes', Gtk.ResponseType.CLOSE)
dlg.add_button('_Agree', Gtk.ResponseType.CLOSE)

dlg.run()
dlg.destroy()

no_titlebar_dialog

何故今迄気が付かなかったんだ。。。。。

てか、統一感を出そうとするなら GtkMessageDialog 継承が一番じゃん。
そんなこんなで我がアプリは結局コレに書き換え。
prev のファイル名表示を追加しようと思ったけどゴチャゴチャするのでヤメ。
Comipoli 0.4.1 公開、本サイト更新のお知らせは久々だな。

ところで、この件でソースコードを見てやろうって思ったんだが。

gtk/gtkmessagedialog.c at master ? GNOME/gtk ? GitHub

gtk_widget_add_css_class という関数を見つけたんだけど。

GtkWidget: GTK 4 Reference Manual

コレって GTK4 からの関数なんですけど。
え、もしかして次の GNOME から GTK4 なんですか?

Intl

Intl といえばもちろんスズキのイントルーダークラシックです。
ジャメリカン 400 の中では一番デカくてカッコイイよね。
ネクラはインテルくらいしかボケが思いつかないだろ、スズ菌でよかったぜ。
というボケは置いておいて。

Intl.ListFormat – JavaScript | MDN

listformat

Intl.ListFormat にはコンストラクタがありません、ってなんじゃそりゃ!

firefox

Firefox で F12 からコンソールならやはり普通に使える。
普段はまったく使っていないのが丸分かりなスクショなことは気にしない。
Gjs は同じ SpiderMonkey だけど同じ Intl を使っているんじゃないんだな。

PluralRules は ja-JP を指定すると全部 other になる、Firefox でも同じ。
Collator は日本語では無意味。
MDN では赤文字な RelativeTimeFormat にはバッチリ対応。
そんなこんなでなんとも中途半端なまとめになってしまった。

JavaScript Intl – Paepoi

これしか更新していないのに盆休みが終わってしまった。
まあいいか、この夏はカワセミに出会えたというだけでおいらは満足だ。
前回は直張りするのを忘れたね、同じのじゃツマランから別アングルのを。