commentsこの文書作成時の環境は以下です。小規模なスクリプトにPythonを使いたい小規模なスクリプトにPythonを使いたいログとかをごちゃごちゃ弄るスクリプトは今までbatやPowerShellを主に使ってきた。PowerShellはともかくbatは二度と書きたくないので、高級言語で簡単なスクリプトを書けるようになろうってんでやり玉に挙がったのがPython。なんか最近人気みたいだし。何よりparseargsっていうコマンドラインパーサが標準で用意されているらしい。これがとても魅力的だった。チュートリアルを上から順番にやるってめんどくさいじゃんチュートリアルを上から順番にやるってめんどくさいじゃんこの考えはあんまり良くない考え方だと思うけど、事情により「学習のための時間」が取れないことだってあるのだ。Pythonをこれから長期的に使っていくとした場合、チュートリアルを上から実践していくのが、最終的にコストが小さくなるであろう。時間があるならチュートリアルを上から順番にやればいいし、今後やるつもりだがすぐに動くスクリプトを要求されたので付け焼刃でPythonスクリプトを書いていく。パッケージが充実しているのでオススメ。python3ついでにPythonのIDEであるPyCharmも入れとこう。JetBrains製のIDE好きよ。pythonインタプリタでHelloって言うとHelloって返してくれる。Pythonは挨拶ができるいいやつだ。World!')まあなんとなくわかる。pythonshebang(シェバン)行と呼ばれるものらしい。pythonに解決されることを意味するようだ。詳しくは呼んでいないがWindows環境でも書いておくと可搬性が上がるらしい。-*-ソースコードの1行目または2行目にソースコードのエンコード形式を記載するらしい。標準モジュールの読み込みと利用標準モジュールの読み込みと利用pythonの標準モジュールであるsysモジュールを読み込み、利用している。インタープリターにビルトインされています。ドキュメントとのこと。World!を出力している。なんか作ってみるなんか作ってみる(必要に迫られたので)ディレクトリ内のテキストを結合するツールを作成する。Pythonを使わずとも、あるいはPythonでももっと簡単な方法があるだろうけど、あえて不慣れなPythonで。sys.stdout.write(line)特徴的なのはオフサイドルール4に従ってブロックが記述されていることだろうか。parser.parse_args()動的型付けで特に宣言なくいきなり変数に代入が可能な模様。文は改行で区切るのが普通らしい。sys.exit(1)if文。条件式は()でくくらないのが普通らしい。論理演算がnotやandなどの英単語なのが読みやすくておしゃれ。ちなみに、elseとifではブロックが深くなっていって具合が悪いのでelifというキーワードを用いる模様。Pythonで共通してブロックの開始は:でブロックの終了はインデントが戻るところ。sys.stdout.write(line)今回はリストのイテレーション。:でxxxコレクションの中身をイテレーションするみたい。withはC#のusing構文やJavaのtry-with-resource構文に相当するキーワード。ブロック終了で資源が回収されるらしい。やってることは全部のファイルを全部のファイルごとに一行ずつ標準出力に書くとか頭の悪いことしてるので、もうちょっと頭良く処理する例を作ればよかった。感想感想ブラックボックスで構わないちょっとしたツールなんかを作るときは便利だな~って感じ。↩インデントでブロックを表現する記法。commentsこの文書作成時のChromeバージョンは以下です。やりたいことやりたいことTwitterタイムライン上の画像で右クリックコンテキストメニューしたときに以下を取得したい。画像投稿者のユーザー名ツイートID複数画像の何枚目か(twitterは1ツイートに4枚まで画像を添付できる)右クリックしたコンテキストのソースURLぐらいしか手掛かりがないので、表示中のTwitterのDOMを解析して解決する。TwitterのDOM構成が変わると動かなくなる。Scriptsは特定のページに埋め込まれ、ページのDOMにアクセス可能だ。今回はtwitter.comの中ならどこでも埋め込むようにする。jQueryも使うので埋め込んでおく。...}content_scriptsが配列であることからわかるように、複数のページにスクリプトを埋め込むことができる。Scriptが埋め込まれたページ、これらは別コンテキストである。他のコンテキストの処理を呼び出す場合には、Chrome経由でメッセージ通信を行う必要がある。Scriptにメッセージを送信する。ScriptでDOM解析した結果をEventPage側で同期的に処理する。呼び出す場合はchrome.tabs.sendMessage()を使う。それ以外を呼び出す場合はchome.runtime.sendMessage()を使う。);}chrome.contextMenus.onClicked.addListener(messageToGetTweetInfo);...コンテキストメニューを開いたページにメッセージを送る場合は、contextMenus.onClicked.addListener()で登録した関数の第2引数(tab)のidプロパティをtabs.sendMessage()の第1引数に入れるとよい。tabs.sendMessageの第2引数には、受信側で行う処理を一意に特定できる識別子を入れるとよい。同期メッセージの結果はコールバックの引数として取得できる。ポップアップ起動時など、tabのidが不明な場合は、chrome.tabs.queryを用いてタブを取得する。受信側受信側chrome.runtime.onMessageイベントリスナーを登録する。結果の返送は第3引数のハンドラを利用する。DOMを読むDOMを読むjQueryで泥臭く読む。twimg.comのURLをsrcに持つimgタグを検索するところからスタート。これでユーザー名、ツイートID、画像が何枚目かを取得できた。commentsこの文書作成時のChromeバージョンは以下です。やりたいことやりたいことtwitterタイムライン上の画像のオリジナルイメージを右クリックからダウンロード可能にする。pbs.twing.comソースのときだけメニューを表示するpbs.twing.comソースのときだけメニューを表示するcontextMenus.createのプロパティを書く。contextsをimageに絞り、画像の上だけでメニューを表示するように、documentUrlPatternsで、twitter.comのみでメニューを表示するように、targetUrlPatternsで、画像のソースがpbs.twimg.comの場合のみにメニューを表示するように変更。URLを指定してダウンロードURLを指定してダウンロードdownloads.downloadのAPIでソースのURLに:origを付加してDLする。});}chrome.downloads.onDeterminingFilename.addListener(renameDownloads);chrome.contextMenus.onClicked.addListener(downloadImage);saveAsプロパティをtrueにすると、ダウンロード時に「名前を付けて保存」ダイアログが展開するようになる。ファイル名を変更するファイル名を変更するそのままDLすると拡張子がjpg_origとなり使い勝手が悪いので、downloads.onDeterminingFilenameイベントを使用して_origを取り除く。downloads.downloadのコールバック引数でダウンロードIDが取得できるので、DownloadItem.Idと比較することで、今回ダウンロードしたもののみ変更することができる。APIを利用するので、manifestのpermissionにdownloadsを追加する。...}以上でオリジナル画像のダウンロードが可能になった。次はコンテキスト間を通信して、ユーザー名とツイートIDをDOMから取得する。commentsこの文書の作成時点の環境は以下です。5.1.15063.909標記のおとり。以下のようにリダイレクトでファイル出力すると、BOM付きUTF16リトルエンディアンでエンコードされる。探した感じではリダイレクトのエンコードを指定する方法は見つからない。代わりにOut-Fileコマンドレットが利用できる。UTF-8BOMなしは自前でがんばる必要がある。いくつか方法がありそうだが、例えばText.Encoding.UTF8.GetBytes()でUTF8のByte列を取得し、Set-Contentコマンドレットで出力する方法は以下。BytePowerShellがちょっと嫌いになった。エンコードの違いに気付かなかった自分が悪いんだけどね。commentsこの文書作成時のChromeバージョンは以下です。作りたいもの作りたいもの世の中には絵がうまい人が溢れている。のちのち資料として利用するために画像を保存するわけだけど、twitterに投稿されたオリジナルの画像をローカルに保存するのは結構手間。名前を付けて画像を保存で保存する既存のものとしてはコンテキストメニューからオリジナル画像をDLするChrome拡張がいくつか公開されている。Imageこれらの拡張は便利なのだが、デフォルトファイル名がいまいちで利用しにくい。そこでユーザー名とツイートIDでリネームするChromeExtensionを作成しようとした。ChromeExtensionはじめてのChromeExtension以下は公式ドキュメントにだいたい書いてあることです。ChromeExtension概要ChromeExtension概要ChromeExtensionはChromeに機能を追加するソフトウェアで、JavaScriptで動作する。ChromeExtensionは主に以下のコンテキストから構成されているようだ。Pageこれらのコンテキストをマニフェストファイルに記載することでChromeがこれを解釈できるようなる。他にもOptionPageなどがあるようだが、メインは上記の3種類のコンテキスト。Action)ChromeExtension独自のHTMLページを表示する。インストールすると右上に表示されるアイコンをクリックするとHTMLページがポップアップする。Actionは特定ページでのみ利用できる。Actionが利用できないときは、アイコンはグレーアウトする。Actionのどちらか、または利用しない場合はどちらも記載しない。Script特定のページにスクリプトとスタイルシートを埋め込む。埋め込んだページのDOM操作が可能。ページ内のスクリプトとは独立して動作するので、ページが持っている関数などは利用できない。Pageバックグラウンドでスクリプトを動作させる。目に見えないWebページが存在してそこにスクリプトが埋め込まれるイメージ。PageとなりChromeに常駐する。!!右クリックからこんにちは世界!ディレクトリ構成プロジェクトルートディレクトリにmanifest.jsonを配置する。今回は以下の配置とした。アイコンはIncscapeで適当に準備した。公式ドキュメントを読みながら必要そうなものを追加していく。]}スクリプトスクリプトを書く。Page)を参考に書く。Pageに対応していないので、こちらを参考にすると詰まる。2chrome.runtime.onInstalledイベントでコンテキストメニューを作成する。イベントページ起動のタイミングでコンテキストメニューのonClickedイベントに世界とこんにちはを登録する。});});chrome.contextMenus.onClicked.addListener(helloWorld);デバッグ実行chrome://extensionsにディレクトリをまるごとドラッグアンドドロップすると、インストールが完了する。ページ」をクリックするとイベントページを確認することができる。実行するとConsoleが世界とこんにちはすることを確認できた!次はpbs.twing.comから画像をダウンロードする。利用可能なら青バッジが付く仕様だったときもあったようだ。UI的にはアイコンはモノクロでないほうがよさそうだ。Pageでは利用できないようだ。ドキュメントに書いてある。NewBloggerThemes.com。