自分の Tweet は API で取ってきておおむね nDiki の記事にまとめてあるのですが、使い始めの頃はそんなことをしていなかったので手元にデータとして取ってありませんでした。公式機能で全ツイート履歴ダウンロードができるのは知っていましたがそのうちと思いつつずっとやり忘れていたので、ようやく腰を上げて全ツイート履歴リクエストを設定からしてみたところ、ほどなくして準備完了のメールが届きました。
ダウンロードした ZIP ファイルの中をみると、予想していた通り人間用に HTML ファイルがありました。そしてそれ以外に CSV 形式ファイル・JSON 形式ファイルが含まれていてきちんと利用しやすい形になっていて良くできているなと感心してしまいました。良いですね。
きちんと README.txt をみてみたら HTML ファイル (index.html) は JSON 形式ファイルを読んで表示するページになってました。なるほど。API のレスポンス仕様と同じ JSON 形式をエクスポートデータにしているのですね。
「Markdown で書いているノートを Web ブラウザで見るのに MkDocs を使う」とつぶやいたら @bsdhack 氏が Grip を紹介してくれました。
私はgithubなどのmdファイル(https://t.co/nyoqRnjsN7)を読むために python製の grip 使って↓なスクリプトを書いて使ってます。
— Mitzyuki IMAIZUMI (@bsdhack) 2018年2月28日
grip --export ${1:-README.md} - | w3m -T text/html
さっそく試してみました。
$pip2 install grip
でインストールしたら Markdown ファイルを指定して Grip を起動します。
grip index.md
Grip が http://localhost:6419/ で Web サーバとして立ち上がるので Web ブラウザでアクセスすると index.md の HTML 変換されたものを見ることができます。なお
grip -b index.md
とすれば起動と同時に Web ブラウザで開いてくれます。URL でパスを指定すればそのまま同じ/サブディレクトリにある Markdown ファイルもプレビューできるので、ハイパーリンク付けをしておくことでドキュメント群をブラウジングすることもできます。なるほどお手軽で便利。 GitHub 上とほぼ同様の見慣れたデザインになるのがいいですね。
そもそも Grip は「GitHub Readme Instant Preview」で GitHub 上での表示確認のためのツールで、 GitHub の REST API を使ってレンダリング結果を生成しているので当然といえば当然だったりはします。
ただそのかわり GitHub の API を使うので
と場合によっては不便な部分があります。なお後者については GitHub Enterprise があるなら Grip でそちらを指定するとう手もあります。
GitHub に push する前にチェックしたい時はもちろん、それ以外でさっと Web ブラウザで見てみたい時にも便利なツールですね。
https://api.twitter.com/1.1/direct_messages/new.json
https://api.twitter.com/1.1/direct_messages/show.json
https://api.twitter.com/1.1/direct_messages.json
https://api.twitter.com/1.1/direct_messages/sent.json
https://api.twitter.com/1.1/direct_messages/destroy.json
ちょっとしたメモを Alfred for Mac から一発で TaskPaper ファイルに挿入したい。Packal 上に TaskPaper のための多機能な Alfred Workflow があるので入れたんだけれど、うまくタスク追加ができないことがあるので、自前でスクリプトを作って Alfred から呼ぶことにした。
TaskPaper ファイルはテキストファイルなので書き慣れている Perl でスクリプトを書いてもいいんだけれど、 編集の競合が避けられるし parser も書かなくて済むしということで TaskPaper の API を使うことにした。
JavaScript for Automation (JXA) を使えば JavaScript コードで TaskPaper API を呼べるっぽい。
以下指定した TaskPaper ファイルに Inbox: プロジェクトがなければ追加した上でその子供としてノートを挿入するコード(エラー処理割愛。実際にはタイムスタンプとかもノートにつけるようにした)。
#!/usr/bin/env osascript -l JavaScript function TaskPaperContext(editor, options) { let inbox = editor.outline.evaluateItemPath("//Inbox:")[0]; if (!inbox) { inbox = editor.outline.createItem("Inbox:"); let projects = editor.outline.evaluateItemPath('@type = project') if (projects.length == 0) { editor.outline.root.appendChildren(inbox) } else { editor.outline.root.insertChildrenBefore(inbox, projects[0]); } } let items = ItemSerializer.deserializeItems(options.text, editor.outline, ItemSerializer.TEXTMimeType) editor.setCollapsed(items[0]) inbox.appendChildren(items, inbox.firstChild) } function run(argv) { Application('TaskPaper').open(argv[0]).evaluate({ script:TaskPaperContext.toString(), withOptions: {text: argv[1]} }) }
これを inbox.scpt というファイルで保存し実行権限を与えれば
./inbox.scpt $HOME/tmp/test.taskpaper こんにちはこんにちは!!
という感じで呼び出せるようになる。
あとは Alfred Workflow を作ってそこからこのスクリプトを実行すれば OK だ。
Slack コール(ビデオ通話)では動画表示用の小さいウインドウが最前面で表示される。これを MacBook Pro 内蔵ディスプレイの上部中央、内蔵カメラの直下に配置すると自然とカメラの方に視線が行くようになる。 one-on-one ミーティングなど視線を大切にしたい時に便利だ。
一方最近使っているビデオ会議ツール Google Meet (旧 Google Hangouts Meet) は Google Chrome でアクセスして使う形(Mac)のため同じことができない(Meet を開いているウィンドウは Chrome の装飾がついて大きいし、特定の Chrome のウィンドウだけを最前面に置くこともできない)。
なんかいい方法ないかなと思っていたところ Picture-in-Picture Extension (by Google) という Google Chrome 拡張機能を発見。
Google 公式の拡張機能だ。これを使うと Picture-in-Picture Web API に対応している YouTube などのサービスの動画部分をフローティングウインドウとして最前面に表示させることができる。Google Meet のビデオ会議ページで使ってみたところ、動画部分をフローティングさせられた。1対1で画面共有無しの場合はこれでいけるぞ。
拡張子 md の Markdown ファイルを「バックアップと同期」アプリで新規に同期したり、 Web 版の Google ドライブでアップロードしたりすると MIME タイプが text/markdown となり全文検索対象にならない。不便。
StackEdit は Google ドライブに送る時の MIME タイプを設定で text/plain を選べるようにすることで問題を回避しているようだ。
クラウドストレージ上のファイルを管理するためのコマンドラインプログラム rclone でアップロードするとどうだろうと思ってやってみたところ、ちょっと設定をいじれば拡張子 md の Markdown ファイルを text/plain で Google ドライブにアップロードできることがわかった。
rclone では Google Drive API で新しいファイルを作成する際に、rclone 側で MIME タイプを判定している。内部的には Go の mime パッケージを使っている。
このパッケージは UNIX 系の環境では mime.type ファイルがあれば参照するようになっていたので macOS Catalina にあった /etc/apache2/mime.type ファイルの text/plain 行に md を追加して試したところ、めでたく text/plain として Google ドライブにアップロードできた。全文検索対象になることも確認。
ちなみに「バックアップと同期」アプリは /etc/apache2/mime.type 変更の影響を受けなかった。
rclone での方法が分かったわけだけれど、実際のところ Markdown ファイルの Google ドライブとの同期や読み書きを rclone だけに限定するわけにもいかないな。引き続き拡張子 txt で管理するのが現実的のようだ。
Obsidian Sync と Obsidian Publish を早期割引購入が2021年9月30日までとのアナウンスがあった。Obsidian Publish は2月に購入し便利に使って満足している。
Obsidian vault の同期は Dropbox で済ませてきたので Obsidian Sync は見送ってきたのだけれど、将来使いたくなった時に「早期割引で購入していればよかった」なったら悔しいので、検討の上購入しちゃうことにした。
$48/年。クレジットカード決済での換算レート112.711円で、支払い額は5,410円だ。
個人的なノートは信頼できそうなクラウドサービスとだけ同期したい。まだ信頼できるに至っていない場合は暗号化して同期したい。確認したら Obsidian Sync は end-to-end encryption とのことなのでクリア。
Android デバイスで Obsidian を使うのに FolderSync Pro で同期をしてきたのだけれど、いろいろ気を使うことが多いのが不満だった。
と工夫してきたけれど、それでも競合の心配は尽きなかった。
Obsidian Sync だとアプリを起動したタイミングで同期 & 編集中にセミリアルタイムで同期される。デスクトップアプリと Android アプリの両方で同じノートを開いて一方で編集すると、何秒か置いて他方に反映されていく。ヘルプによれば約10秒毎にバージョン履歴が保存されるとのことだ。競合の心配が減るのが嬉しい。
Dropbox 等のクラウドストレージへの同期だと(多分大丈夫だと思うけれど) API 利用のリミットレートが気になってしまうけれど、 Obsidian 純正のサービスだとその心配をしなくてもいいというのもあるね。
Obsidian for Android の同期の選択肢は Obsidian Sync かデバイスのローカルストレージと同期できるクラウドストレージ。一方 Obsidian for iOS は Obsidian Sync か iCloud Drive が選択肢。
併用したいとなった時には Obsidian Sync が必要になるんだよね。実際そこがネックで iPhone では Obsidian を使っていなかったんだけれど、 Obsidian Sync を買ったのでこれからは両方使えるようになった。そのうち iPhone でも使ってみようかな。
Obsidian を起動して vault を開いていれば、ノートを iA Writer で編集したりスクリプトで書き換えたりしても検知してちゃんと同期してくれる。良い。
一方 vault を開いていないと同期されない。うっかり開き忘れていて同期されてなかったというのはありそう。そこが Dropbox などと違うところなのでちょっと注意が必要だ。
早期割引とはいえ同期だけで $4 はなかなかいいお値段である。
これで合計 $194/年、110円/ドル計算だと 21,340円/年だ。ひえー。
[ サブスクリプションサービス ]
Twitter API v2 と v1.1 の無料アクセスサポートを2023年2月9日に終了するとの発表があり、大騒ぎになっている。終了までの期間が短いという点で大事ではあるが、ソーシャルメディア事業者としての総合的な判断なのだろうと受け止めている。
13年ぐらい前から1時間に1回自分の Tweets を取得させていたスクリプトもついに止まるのかな。確認すると連携アプリとして許可したのは2009年12月28日だった。その前はフィード取得で実現していたはず。 Tweets の Web 日記化を手動でやるのはちょっと時間がもったないしどうしたものか。
振り返ってみると2007年4月6日に Twitter アカウントを作成し、翌日にはiモード経由で Tweet するプログラムを書いたりしていたんだな。
Naney (なにい) です。株式会社MIXIで SNS 事業の部長をしています。
※本サイトの内容は個人的見解であり所属組織とは関係ありません。