pythonからmacOSの通知センターを操る方法

pythonで出力する文字列をmacの通知で表示したいと思ってます
python mac 通知で検索した結果いくつか選択肢が出てきたので整理してみます
(逐次参考にさせて頂いたサイトを載せて行きます)

選択肢

  1. terminal-notifier github.com macOSの通知を操作できるコマンドラインツール

  2. Alerter dev.classmethod.jp macOSの通知を扱えるコマンドラインツール

  3. AppleScriptのdisplay notificationコマンドとosモジュール qiita.com

選んだのは、3.

コマンドラインツールをインストールすれば簡単に実現できそうですが、AppleScliptが色々できて面白そうなのでこれを機に調べてみたくなりました

さて、AppleScliptを用いて「pythonからmacOSの通知を操る方法」は、一通り調べた結果以下のような手順を踏めばできそうです

1. pyhonでos.system()の引数にosascriptコマンドを入力して実行
2. サブシェルでosascriptコマンドが実行される
3. AppleScliptのdisplay notificationが実行される
4. macOSの通知に文字列が表示される

ひとつずつ調べていこう

1. os.system(COMMAND)とは?

16.1. os --- 雑多なオペレーティングシステムインタフェース — Python 3.6.6rc1 ドキュメント

os.systemはpythonに標準で入っているosモジュールで使える
公式ドキュメントに沿ってosモジュールをお勉強しようと思ったのですが、わからない単語の嵐で全然理解できなかったので、今回はos.system()についてのみ調べます。

以下公式ドキュメントから引用

サブシェル内でコマンド (文字列) を実行します。この関数は標準 C 関数 system() を使って実装されており、system() と同じ制限があります。sys.stdin などに対する変更を行っても、実行されるコマンドの環境には反映されません。command が何らかの出力を生成した場合、インタープリターの標準出力ストリームに送られます。


全然わからんんんんんんn宇宙後かょ
分からない単語を列挙して1つずつ理解しよう

* サブシェル
sub shell ( csh )
コマンド:鐃緒申鐃瞬ワ申鐃緒申鐃緒申: UNIX/Linuxの部屋

シェル内でコマンドを()で囲って実行することで起動するシェル。これによって起動したプログラムを子プロセスと呼ぶ(起動した側は親プロセス)。子プロセスで別ディレクトリに移動しても、子プロセスが終了すれば親プロセス=つまり元のディレクトリに戻ってくる


* 標準C関数system()
シェルコマンドを実行できるC言語の関数


* sys.stdin
29.1. sys — システムパラメータと関数 — Python 3.6.5 ドキュメント,
algorithm.joho.info

pythonでキーボードからの標準入力ができる


* 標準出力ストリーム
nononochi.hatenablog.jp
標準ストリーム:Unix系OSでプロセスと端末間の接続としてはじめから接続されている入出力のチャネル(チャネル=データの通路)
標準入力(stdin) デフォはキーボード
標準出力(stdout) デフォはディスプレイ
標準エラー出力(stderr) デフォはディスプレイ
と3つの入出力がある

つまり?

pythonのos.system('COMMAND')は、引数に入力された文字列を子プロセスとして実行する。この関数はC言語のsystem()関数を使って実装されており当該関数と同様の制約がある。引数に入力した文字列により何かしらの出力が発生したら、それはインタプリタに出力される

→ということは、os.system()を使えばpythonbashのコマンドであるlsやcdが使えるし、cdでディレクトリを移動してもpythonのプログラムが終了すれば元のディレクトリに戻るよ、って事ですか?なるほどわからん

2. osascriptコマンドとは?

コマンド/osascript - MacWiki

ターミナルでAppleScliptを実行するためのコマンド
osascript <ファイル>コマンドラインからスクリプトファイルを呼びだして実行できたり、osascript -e 'コード'でコードを入力することでも実行できる。


3. AppleScliptのdisplay notificationとは?

alvinalexander.com

通知センターに通知できるAppleScliptのコマンド

まとめ

os.system('COMMAND')の引数にosascript -e 'display notification "出力する文字列"'と入力することでpythonから通知センターの通知を操れるのだ

試しにAppleScliptで遊んでみる

pythonからdisplay notificationする前にちょっとAppleScliptで遊んでみたいと思います。
このサイトを参考にしました

鳶嶋工房 / AppleScript / 入門 / AppleScriptってなに?

当該サイトではスクリプトエディタからファイルを新規作成してますが、めんどくさかったのでターミナルからosascriptコマンドで実行してみます

環境

Mac book pro (13-inch, 2017, Two Thunderbolt 3 ports)
macOS High Sierra ver10.13.4

  • ビープ音
$ osascript -e 'beep 2'  #2回鳴る
$ osascript -e 'beep 4'  #4回鳴る
  • ダイアログ
$ osascript -e 'display dialog "Hello World"'
button returned:OK

f:id:Atc:20180625184648p:plain
画像でけぇ...

  • 通知
osascript -e 'display notification "こんにちは世界"'

f:id:Atc:20180625185149p:plain


pythonから実行してみる

>>> import os
>>> a = 'Hello'
>>> os.system("osascript -e 'display notification\" {}\"'".format(a))
0

↓↓
f:id:Atc:20180625185836p:plain
やったぜ〜〜!!
ちなみに出力結果の「0」はコマンドが成功した際に返されるそうです