MacBook Pro 16インチモデル 来た! ついに買ったのだ! いやあ嬉しいです。これまでMacBookPro15 2013 lateを使い続けていたので、とても嬉しいです。移行アシスタントは使わずクリーンな状態から必要な物を手作業で入れて育て中。夜な夜な作業して、あと何日かかるかなあ。しかし今はそれもまた楽しいのだ。
PythonでIMAPメール操作なら、IMAPClientが便利だった件
PythonでIMAPでメール受信したくなった。標準のimaplibで基本的に可能なわけですが、実は結構めんどくさい。まずフォルダ名の取得からして、結果文字列がエンコードされたままで日本語だとそのままでは読めない...。読める文字列にするには何かと面倒...。メール読みたいだけなのに、正直辛い...。
で、手元にあった本、
退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング
を改めて読んでみたら、IMAPには「IMAPClient」というのを使っている。こっちの方がよかった。
pip install imapclient
してインストール。
違いは下のよう。
# 標準のimaplibの場合 import imaplib mail = imaplib.IMAP4_SSL('imap.gmail.com') mail.login('foo@gmail.com', 'password') mail.list() #取得結果のままでは日本語文字列エンコードされてて読めない... > ('OK', [b'(\\HasNoChildren) "/" "INBOX"', b'(\\HasChildren \\Noselect) "/" "[Gmail]"', b'(\\All \\HasNoChildren) "/" "[Gmail]/&MFkweTBmMG4w4TD8MOs-"', b'(\\HasNoChildren \\Trash) "/" "[Gmail]/&MLQw33ux-"', b'(\\HasNoChildren \\Sent) "/" "[Gmail]/&kAFP4W4IMH8w4TD8MOs-"'])
# IMAPClientの場合 import imapclient server = imapclient.IMAPClient("imap.gmail.com", ssl=True) server.login(foo@gmail.com', 'password') server.list_folders() #取得結果がすでにデコード済みの文字列、日本語も読める!! > [((b'\\HasNoChildren',), b'/', 'INBOX'), ((b'\\HasChildren', b'\\Noselect'), b'/', '[Gmail]'), ((b'\\All', b'\\HasNoChildren'), b'/', '[Gmail]/すべてのメール'), ((b'\\HasNoChildren', b'\\Trash'), b'/', '[Gmail]/ゴミ箱'), ((b'\\HasNoChildren', b'\\Sent'), b'/', '[Gmail]/送信済みメール')]
これなら嬉しい。
IMAPメール本文を読むにはさらにひと工夫いるのですが、その辺は 上述の本退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミングでは、pyzmailを使っていて、確かに便利だ。pyzmailについてはまたいつか。
ラズパイのOSをRaspbian Busterにしたら、Ansibleでpip3がエラーになった件
Raspbian BusterはPython3がデフォルトで3.7系とのことで、それなら自前でビルドしなくていいから嬉しい。さっそく使おう。
公式サイトからRaspbian Buster Liteのイメージをダウンロードして、Macな私は
balenaEtcher - Home
を使って、SDカードにイメージを書き込みします。(SDカードの控えもないので、今まで使ってたやつにそのまま上書き。バックアップとかしない。(キリッ!))
で、以前Stretch時代に自分で色々入れてたものの環境の復元は、Ansibleで。Infrastructure as Codeバンザイ。こういう時に便利ですね。
と思ったら、pipモジュールでエラー。
"Failed to import the required Python library (setuptools) on raspberrypi's Python /usr/bin/python. Please read module documentation and install in the appropriate location"
#一部抜粋 pip: name: [色々と] executable: pip3
こんな感じでやってるところが、なぜか上のエラー。
いろいろググったら、私はPython3とpip3でAnsibleしたいのですが、ラズパイ側がPython2で実行されているためっぽい。
対策として、ansibleのインベントリでホスト指定の時、下のようにansible_python_interpreterを指定すると良い。
raspberrypi.local ansible_python_interpreter=/usr/bin/python3
これって、別にBusterにしたからじゃなかったかも...。でもまあいいや。
無事、Busterに移行できました!!
PowerShell DSC で Active Directory のグループ管理がしたかったら ActiveDirectoryDsc
最近ちょくちょくPowerShellを使う機会があって、で、ちょっと思い立って PowerShell DSC で Active Directory のグループ設定とかしたらどうなのかなと。DSCほぼ初めて使ったのですが。
で、Active Directoryのグループ設定をするDSCリソースとかあるのかなと思って公式見に行ったら、DSC グループ リソースは、ローカルグループだな。ADのグループ管理は?と思ってググったけど、なんか見つからない。もしかしてまさかAD管理するリソースって謹製のは無いのか、と思いかけたら、ちゃんとありました。これ、ActiveDirectoryDsc。
[Edit 2019.8.24] 名前がxActiveDirectoryからActiveDirectoryDscにかわってました。 ActiveDirectoryDsc: Rename module from xActiveDirectory · Issue #312 · PowerShell/ActiveDirectoryDsc · GitHub
Node.jsが令和に対応して、homebrewでのインストールでは--with-full-icuオプションもいらなくたっていた件
以前はhomebrewでNode.jsをインストールするとき、--with-full-icuオプションをつけていたのですが、いつの間にかその必要は無くなっていたようです。 普通にインストールして、和暦も使える。しかも、令和も対応されてますよ!
var date = new Date(Date.UTC(2019, 4, 1, 3, 0, 0)); new Intl.DateTimeFormat('ja-JP-u-ca-japanese', { era: 'long' }).format(date); '令和元年5月1日'
HomebewでのNode.jsのインストールは、--with-intl=system-icu がデフォルトになっているようです。
Elmガイドの例Timeで、初期化時に現在時間をModelにセットする
Time · An Introduction to Elmの例では、初期化時のModelのtimeがゼロだったので、現在時間で初期化したかった。やる前は瞬殺と思っていたのだが、いやいやどうにも苦戦した。どうやるのか理解するのに結構苦労してしまった。関数脳への道は遠い...。
結果こうなった。
module Main exposing (Model, Msg(..), init, main, subscriptions, update, view) import Browser import Html exposing (..) import Task import Time -- MAIN main = Browser.element { init = init , view = view , update = update , subscriptions = subscriptions } -- MODEL type alias Model = { zone : Time.Zone , time : Time.Posix } init : () -> ( Model, Cmd Msg ) init _ = ( Model Time.utc (Time.millisToPosix 0) , Task.perform SetSystemTime Time.now ) -- UPDATE type Msg = Tick Time.Posix | SetSystemTime Time.Posix update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of Tick newTime -> ( { model | time = newTime } , Cmd.none ) SetSystemTime newTime -> ( { model | time = newTime }, Cmd.none ) -- SUBSCRIPTIONS subscriptions : Model -> Sub Msg subscriptions model = Time.every 1000 Tick -- VIEW view : Model -> Html Msg view model = let hour = Time.toHour model.zone model.time |> String.fromInt |> String.pad 2 '0' minute = Time.toMinute model.zone model.time |> String.fromInt |> String.pad 2 '0' second = Time.toSecond model.zone model.time |> String.fromInt |> String.pad 2 '0' in h1 [] [ text ("時間" ++ hour ++ ":" ++ minute ++ ":" ++ second) ]
Web NTLM認証、Pythonとrequests 対 PowerShell
とあるIISのWebアプリでログインにNTLM認証を使っているサイトをスクレイピングしたかった。 まずは所望のページをgetしたいぞと。
Pythonとrequestsでやってみた。最終的にこんな感じ。
import requests from requests_negotiate_sspi import HttpNegotiateAuth session = requests.session() # ログインした後クッキーとかのため session.auth = HttpNegotiateAuth() # Windowsのカレントユーザで認証 res = session.get('どこかのURL')
ポイントは、requests-negotiate-sspi · PyPI これを使うとこで、Windowsのカレントユーザで認証してくれる。なんとスマートなコードではないか。(実はここにたどり着くまでに散々苦労したのだが...、結果よければ全てよし、ですね)
ここまでできたところで、ふと思った。どうせWindowsだけで使うモノなので、毒を食らわば皿まで郷に入っては郷に従え、ということで、PowerShellでやったらどうだろうか。結果こうなった。
$res = Invoke-WebRequest -Uri "どこかのURL" -SessionVariable session -UseDefaultCredentials
おおぅ、簡単にできるではないか。PowerShellならWindows環境のまんまで特に追加インストールもいらないしね。うれしい。