くりにっき

フルスタックキュアエンジニアです

CIのバッジを並べて表示するだけのサイトを作った

https://sue445.github.io/my-ci-badges

github.com

モチベーション

gemやアプリなどを40個くらいメンテしてて一応全てでweekly ビルドを実行してるのですが、CIのバッジが各リポジトリにしか貼っていなくてCIのステータスをまとめて見るためのポータルサイトが欲しかったので作りました。*1

製作時間半日くらい

f:id:sue445:20170917172732p:plain

使ってる技術

  • Bootstrap v4.0.0-beta
    • いつものようにbootstrap使おうと思ったら4系が出てたので雑に投入
  • Vue.js
    • 「いつもMithril.js を使ってるのでたまには違うのを使うか」っていう雑な理由でVue.jsを採用

デプロイ周り

GitHub Pagesを使ってるのでGitHubにpushするだけ。CIいらずで楽

*1:ビルド結果も個人Slackに全部流してるんだけどさすがに40個同時だとログが流れて気づかないことがたまにある

tweet_sanitizerというgemを作った

退院後の初gem情報です

github.com

どんなgemか?

Twitter APIで取得したツイートの内容から

  • full_text (140文字より長いツイート)があればそれを積極的に使う
  • 短縮URLの t.co を元のURLに戻す
  • ツイートの末尾に含まれてる添付画像などのURLを除去
  • ><&gt;&lt; などにエスケープされているので、エスケープを解除

などのサニタイズ処理を行います

モチベーション

Twittodon のロジックをgem化しています

sue445.hatenablog.com

twittodonのツイートのサニタイズ周りの処理にバグがあったんですが、

という理由でgem化してテストコードをリファクタリングしつつバグ修正しました *1

使い方

tweet_sanitizerを使わない場合

普通に twitter のgemを使った場合

tweet = @client.status("https://twitter.com/github/status/866677968608927744")
tweet.text
#=> "Introducing GitHub Marketplace, a new place to browse and buy integrations using your GitHub account.… https://t.co/dK0Tmcmm72"

tweet_sanitizerを使った場合

using TweetSanitizer::TwitterExtension

extended_tweet = @client.status("https://twitter.com/github/status/866677968608927744", tweet_mode: "extended")
extended_tweet.sanitized_text
#=> "Introducing GitHub Marketplace, a new place to browse and buy integrations using your GitHub account. https://github.com/blog/2359-introducing-github-marketplace-and-more-tools-to-customize-your-workflow"

using TweetSanitizer::TwitterExtension すると生える #sanitized_text でいい感じにサニタイズできます

ツイート取得時の tweet_mode: "extended" がないと前述の full_text がレスポンスで返ってこないので必須です

#status メソッド以外でもツイートを取得しそうなAPI#search とか)のオプションに tweet_mode: "extended" を渡せばたいてい対応してます

参考

Upcoming changes to Tweets — Twitter Developers

詳しくはREADME読んでください

ユースケース

APIで取得したツイートをmastodonなど他のツールに流したり、DBに保存したいような場合に便利かもしれません

入院中に持っていってよかったもの

突然ですが持病が悪化して2週間ほど入院していました

入院時に個人的に持っていってよかったものなどをシェアしたいと思います。おみまいに持っていく品物の参考にしてください

前提

  • 自分が入院してた病院はそこそこ大きかったので、入院生活に必要な日用品はだいたい売ってた
  • 前回入院したのと同じ病院(いわゆるリピーター)なので、売店に売ってないものをピックアップして持っていった
  • 病院内は基本的に自分のテザリング以外のネットは使用不可
    • 自分が入院してた病院では差額料金でネット付きの病室もあったんだけど、どんなネット環境なのかは不明
    • 自分の場合月7GB制限があったので極力テザリングには頼りたくなかった

持っていってよかったもの

Kindle Paperwhite 32GB、マンガモデル

Kindle Paperwhite 32GB、マンガモデル、Wi-Fi 、ブラック

Kindle Paperwhite 32GB、マンガモデル、Wi-Fi 、ブラック

ぶっちぎりでコレ。普通のpaperwhiteだと4GBしかないけど、こいつは唯一の32GBモデル。カタログスペックで700冊保存可能。

入院前日に「これはこのままいくと入院するだろうな」と予感はしてたので、一晩かけて自宅Wi-Fiで300冊近い漫画を全部DLしていました。

前述の通り病院でネットは頼れないので、ローカルに全部保存できるだけの大容量は超重要

ちなみに入院中に

を読んでいました。

病院の消灯は21時だったのですが、Kindleのバックライトを落とせば消灯中でも周りに迷惑かけることなく本を読めたのは良かったです。

ちょっと意外だったのはKindleがネットにつながってないと本を読み終わった後の続刊の表示が出なかったこと。

ノートPC

体調がいい時は手持ちのiPhoneテザリングしてたまにコード書いてました

ちなみに入院時に書いてたコードはこちらになります。両方ともマージされてるのでGitLab v9.5.0でリリースされるはず。*1

余談ですがGitLabのリポジトリが大きすぎて(おそらく1GB超え)テザリングでcloneしたらパケ死しかけました。リポジトリくらいは家でcloneしとけばよかったかなぁw

f:id:sue445:20170811152229p:plain

うちわ

f:id:sue445:20170811152607j:plain

集団病室だと体温調整がしづらいのでうちわを持っていって正解でした。大して荷物にならない上に、あると何かと便利

ちなみに上のうちわは先日 長谷川町子美術館サザエさん展に行った時にもらったうちわです。

タップ

病室内は1人で使えるコンセントの数に限りがあるので分岐できるタップがあると重宝

あと、長めの延長コードが1本あればベッドの中からスマホ操作できるので便利

ポータブルテレビ

病院内のテレビはカード制(自分が入院してたところは1000円で2時間)だったので、ポータブルテレビ持ってるのであれば持ってった方がいいです

ワンセグ受信アダプタ DSテレビ

ワンセグ受信アダプタ DSテレビ

ちなみにDSテレビは10年くらい愛用していますが、いまだにTVの旅をコンプしていません

f:id:sue445:20170811153829j:plain

イヤホン

自分が入院した病院はテレビ見るのにイヤホン必須でした。売店に売ってはいたんだけど普段使いのイヤホンの方がよかったので持っていってよかったです

病院で買ったもの

耳栓

入院時に隣の人のいびきがうるさくて眠れなかった時があったので、買っといてよかった

買っておけばよかったもの

アイマス

消灯後もたまに同室の別の患者さんの点滴交換とかで(全部じゃないけど)電気がついてその度に目が覚めてたので、買っとけばよかったかなと後悔

【追記】持っていけばよかったもの

New3DS LL

DSテレビ用のDSi LLは持って行ってたのですが、New3DSも持っていけばよかったかなぁと後悔。*2

VCなどのDL済ソフトがいくつか入ってたので暇つぶしにはなったはず。

ドラクエ11の発売直後だったので家でDLして入院中にプレイするという選択肢もあった

おまけ1: 病院食変遷

入院1~7日目

お茶と水はOKだったけどご飯食べていません(´・ω・`)

入院8日目の病院食

f:id:sue445:20170807122428j:plain

8日目にして食事解禁。

こんな流動食ですが1週間絶食後だったのでむちゃくちゃ嬉しかったです

入院12日目(最終日)の病院食

f:id:sue445:20170811122220j:plain

途中で五分粥を経由して全粥までランクアップ

慣れると病院食も美味しいんですが、いかんせん消化がよすぎてすぐにお腹が空くのが難点

おまけ2: 8月のパケット利用状況

f:id:sue445:20170811154750p:plain

7/31~8/11まで入院してたので、↑は実質8月分のパケット使用量

残り0.22GB、いろいろとヤバかった。

まったく、家のWi-Fiは最高だぜ!

*1:この修正が本家に取り込まれないと自作ツールでGitLab API v4対応できなかったので、入院中でも対応する必要があった

*2:だったら最初からNew3DS LL + DSテレビ装備にすればええやんっていうツッコミもありそうなのですが、New3DS LLはスロットの形状の関係でDSテレビがささらないのです

rubocopでcop単位でコミットする

「rubocopでauto correct(自動修正)したものをコミットする時はまとめてコミットするのではなくてcop単位でコミットした方が後から履歴が見やすい」って言われたことがあったので実践してみました

rubocop --auto-correctしたものをまとめてコミットした時

こんな感じ

https://github.com/sue445/rubicure/commit/debe943

f:id:sue445:20170713000023p:plain

各cop単位で --auto-correct したものをコミットした時

こんな感じ

https://github.com/sue445/rubicure/compare/338f230...760c2d2

f:id:sue445:20170713000434p:plain

f:id:sue445:20170713115718p:plain

どのcopでどんな修正がされるかがコミットを見るだけで一発で分かると思います

面倒くさいので自動化した

rubocop実行後にコンソールに出力されたcop名に対して手動で rubocop --auto-correct --only ~ しつつコミットするのは意外に面倒くさいです

そこで rubocop --auto-correct --only ~git commit を自動化するためのスクリプトを作りました。ご査収ください

gist.github.com

使い方

アプリのディレクトリに移動して下記のようにスクリプトを実行するだけです

bundle exec ruby /path/to/rubocop_auto_correct_commit.rb

さっきのコミットもこのスクリプトでcommitしています

小ネタ

今回のポイントは rubocop --format=jsonjson出力しているところです

rubocopの実行結果をjsonで出せば他のツールから使いやすくて便利。

jsonの仕様はここを参照

https://github.com/bbatsov/rubocop/blob/v0.49.1/manual/formatters.md#json-formatter

追記

公開直後に有識者からの マサカリ 熱い反応><

id:onk

id:Pocke

2020/3/24追記

このスクリプトはgem化してるので使いたい人はこちらをご覧ください

sue445.hatenablog.com

github.com

compact_blankというgemを作った

なんやかんやで久しぶりにgem作りました

どんなgem?

Array#compactHash#compact *1だとnilを除外したArrayやHashを作ることができますが、空文字も除外したいことがちょいちょいあるので作りました。 *2

使い方

refinementsを使ってるので using CompactBlank を書いた場所のみ compact_blankcompact_blank! が生えます

Array#compact_blank, Array#compact_blank!

compact_blank!(ビックリマークがついてるメソッド)は自分自身を破壊的に変更します。(変更時は self が返って、変更されなかった時は nil が返るのも #compact! 準拠です)

using CompactBlank

array = ["a", nil, "b", ""]

array.compact
#=> ["a", "b", ""]

array.compact_blank
#=> ["a", "b"]

array.compact_blank!
#=> ["a", "b"]
array
#=> ["a", "b"]

Hash#compact_blank, Hash#compact_blank!

using CompactBlank

hash = { a: "1", b: nil, c: "3", d: "" }

# NOTE: Hash#compact is feature of activesupport
hash.compact
#=> {:a=>"1", :c=>"3", :d=>""}

hash.compact_blank
#=> {:a=>"1", :c=>"3"}

hash.compact_blank!
#=> {:a=>"1", :c=>"3"}
hash
#=> {:a=>"1", :c=>"3"}

やってること

20行ちょいの雑なモンキーパッチです https://github.com/sue445/compact_blank/blob/v0.1.0/lib/compact_blank.rb

*1:Array#compact はRuby本体のメソッドだけど Hash#compactはactivesupportのメソッド

*2:まぁ真面目に array.reject(&:blank?) や hash.reject{|_, v| v.blank? } を書いてもよかったんですが、同じ記述を3個以上書くことになってつらくなったのでgem化した

ドリコムで使ってるgem一覧 #railsdm

先日 【増枠】Rails Developers Meetup #2 でLTした時の資料です。ご査収ください

rails-developers-meetup.connpass.com

資料

スライド版

sue445.github.io

markdown

github.com

当日の質問

覚えてる範囲で

社内gemにするかOSSするかどう切り分けてる?

  • 基本的には外に出すこと前提で作ってる
    • 理由:みんなに使ってもらえた方がフィードバックが得られやすいし、Travis CIなどのエコシステムも利用できる
  • ビジネスロジックを抽出していたり、社内コンテキスト*1に依存してるような場合は社内gemにしてる
  • OSSにするとどうしても汎用化しちゃいがちでEasyから外れてしまうので、社内利用用途に絞ることでEasyを維持*2しているケースもある

詳しくは以前エントリに書きました

sue445.hatenablog.com

どうでもいい情報

*1:capistrano系の社内gemは社内インフラ構成前提になってる

*2:イージーをいじ

TwittodonというTwitterからMastodonに流すボットを作った

ここ最近作ってた便利ツールの共有です

Twittodonとは?

Twitterからの任意のツイートをMastodonに流すためのボットです

github.com

ちなみにTwittodon(ついっとどん)とはTwitter + Mastodonの造語です

サンプル

f:id:sue445:20170601004222p:plain

https://precure.ml/@sue445/85064

  • Twitterの検索クエリにマッチしたツイートをMastodonにトゥートする
  • ツイートに画像が含まれていればMastodonにもアップロードして画像付きのトゥートにする
  • トゥートに元ツイートへのリンクを付与
  • ツイートに短縮URL(t.co)が含まれていた場合、短縮前の元URLの状態でトゥートに含める

といったことをやっています

使い方

TwitterMastodonAPIを使うためのトークンを取得する部分は手動ですが*1Heroku のアカウントがあればその後のサーバへのデプロイはDeploy to Herokuボタンを使ってワンクリックでデプロイできます。

f:id:sue445:20170601005523p:plain

Twitterの検索条件はHeroku Schedulerのジョブに渡せます。

f:id:sue445:20170601005947p:plain

詳しくは https://github.com/sue445/twittodon/blob/master/GETTING_STARTED.md を読んで下さい

Twitter -> Mastodon トゥート同期アプリ」との違い

似たようなサービスで Twitter -> Mastodon トゥート同期アプリ というのがあります。

sync.twi2mstdn.space

Twitter -> Mastodon トゥート同期アプリ」だと連携したTwitterアカウントのツイートを全てMastodonに送るようですが、TwittodonだとMastodonに送るツイートを検索条件で指定することができます。

検索APIを使っているので、自分以外のツイートもMastodonに送れます。

イメージ的にはIFTTTの「Post to Slack when a tweet matches your search term(Twitterの検索条件にマッチしたツイートをSlackに送るアプレット)」のMastodon版を目指して作っています。

ifttt.com

最後に

最初のトークンの取得が手動なのが面倒かもしれませんが*2、ワンクリックでデプロイできるようにしたりTwitterの画像をMastodonに再アップロードなどいろいろ作り込んでいて便利なので是非ご利用ください。

また、インスタンスによってはボット利用が禁止されたり制限されてる場合もあるので節度をもって使うようにしてください。

*1:GETTING_STARTEDに手順は全部書いてる

*2:その手順を簡略化するためのアプリの作成もなくはなかったんですが、これ以上簡単にしすぎるとボットが作られ放題でそれはそれで治安が悪くなりそうな予感があったので、最低限トークンの取得くらい手順書見ながら自力でどうにかできる人だけに使ってほしいという思いでふるいにかけるために現状の仕様にしています