tag:crieit.net,2005:https://crieit.net/users/mogya/feed daisuke furukawaの投稿 - Crieit Crieitでユーザーdaisuke furukawaによる最近の投稿 2020-12-13T15:45:18+09:00 https://crieit.net/users/mogya/feed tag:crieit.net,2005:PublicArticle/16351 2020-12-13T15:34:50+09:00 2020-12-13T15:45:18+09:00 https://crieit.net/posts/2020-5fd5b60a57eb5 2020年買ってよかったものと、買ったけど微妙だったもの <p><a target="_blank" rel="nofollow noopener" href="https://nabettu.com/12438d281302464e9b1e78c07767af84">2020年買ってよかったものと、買ったけど微妙だったもの</a> が良かったのでぼくもやってみる</p> <h1 id="微妙だったもの"><a href="#%E5%BE%AE%E5%A6%99%E3%81%A0%E3%81%A3%E3%81%9F%E3%82%82%E3%81%AE">微妙だったもの</a></h1> <h2 id="Xiaomi Miband4 シャオミ スマートウォッチ"><a href="#Xiaomi+Miband4+%E3%82%B7%E3%83%A3%E3%82%AA%E3%83%9F+%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%82%A6%E3%82%A9%E3%83%83%E3%83%81">Xiaomi Miband4 シャオミ スマートウォッチ</a></h2> <p><a href="https://crieit.now.sh/upload_images/fa4a63c2d3adeeec9f218cc2948f737f5fd5a1628da47.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/fa4a63c2d3adeeec9f218cc2948f737f5fd5a1628da47.jpg?mw=700" alt="Xiaomi Miband4 シャオミ スマートウォッチ" /></a></p> <p>タバタ式トレーニングをやるぞ、ということで心拍計として買ったのだけど、計測結果が信用ならない感じで、もう自分で数えればよくね?ってなった。色々工夫して使おうとしてたのだけど、結局どうにもならなかったので売却。</p> <h2 id="スマートスピーカー"><a href="#%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%82%B9%E3%83%94%E3%83%BC%E3%82%AB%E3%83%BC">スマートスピーカー</a></h2> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5fd5a6e2923c0.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5fd5a6e2923c0.png?mw=700" alt="image.png" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://store.google.com/jp/product/google_nest_mini">GoogleNestMini</a></p> <p>ぼくの部屋につけて性能評価中なんだけど、明かりつけるのは壁スイッチで困ってないし、暖房とかいちいちswitchbotつけるの面倒だし、ということで、「音楽かけて」以外の用途がなくて、たんなるスピーカーになっている。それで十分といえば十分なんだけど。</p> <h1 id="良かったもの"><a href="#%E8%89%AF%E3%81%8B%E3%81%A3%E3%81%9F%E3%82%82%E3%81%AE">良かったもの</a></h1> <h2 id="スマートロック"><a href="#%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%83%AD%E3%83%83%E3%82%AF">スマートロック</a></h2> <p><a href="https://crieit.now.sh/upload_images/618a8d040b7c5f0db948ddc6edfcadb15fd5a55dee6f0.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/618a8d040b7c5f0db948ddc6edfcadb15fd5a55dee6f0.png?mw=700" alt="Qrio Lock (キュリオロック) スマホで自宅カギを解施錠できるスマートロック Q-SL2" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://amzn.to/3qUV2qa">Qrio Lock (キュリオロック) スマホで自宅カギを解施錠できるスマートロック Q-SL2</a></p> <p>日々快適に動作していて、鍵を持ち歩かなくなった。</p> <h2 id="Fire TV Stick 4K"><a href="#Fire+TV+Stick+4K">Fire TV Stick 4K</a></h2> <p>古いのはもっさり使い勝手が悪かったのだけど、新型はメモリもCPUも改善したらしく、サクサク動くようになった結果毎日使うようになりました。<br /> YouTubeで動画見ながら運動しています。</p> <h2 id="靴"><a href="#%E9%9D%B4">靴</a></h2> <p>ついに靴とか服もAmazonで買うようになってしまった。3つ4つまとめて取り寄せて、気に入ったの以外は返品する。</p> <p>返品しまくりになるのは抵抗感があったんだけど、Amazonがそうしろと言っているし、<br /> <a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/b/ref=fst_h1_st_2?node=4615721051">Amazon.co.jp: 試着後の返品・送料無料: ファッション</a><br /> 慣れてくると試着とかせずに「この間の靴を再注文」ってやるようになるので、おそらく長い目で見ればAmazonも損をしてないのだと思う。</p> <h2 id="スティック茶こし"><a href="#%E3%82%B9%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF%E8%8C%B6%E3%81%93%E3%81%97">スティック茶こし</a></h2> <p><a href="https://crieit.now.sh/upload_images/618a8d040b7c5f0db948ddc6edfcadb15fd5a3a955b0f.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/618a8d040b7c5f0db948ddc6edfcadb15fd5a3a955b0f.png?mw=700" alt="KINTO (キントー) 茶こし LOOP ティーストレーナー ブラック" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://amzn.to/3gHFzVp">KINTO (キントー) 茶こし LOOP ティーストレーナー ブラック</a></p> <p>茶葉をこれですくって湯に入れるとお茶が飲める。一人二人だと急須で入れるよりこっちのほうが楽なので愛用しています</p> <h2 id="surface変換ケーブル"><a href="#surface%E5%A4%89%E6%8F%9B%E3%82%B1%E3%83%BC%E3%83%96%E3%83%AB">surface変換ケーブル</a></h2> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5fd5b47794ac2.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5fd5b47794ac2.png?mw=700" alt="image.png" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://amzn.to/3gLsHxB">Surface Pro 充電ケーブル 15V PD充電対応 Surface Connect to USB-C充電</a></p> <p>独自のコネクタを採用していて充電器が必要なsurfaceも、この変換コネクタをつかうことでUSB-C充電ができるようになりました。<br /> 力不足な充電器だとヤバそうな挙動を示すので駄目かと思っていましたが、<a target="_blank" rel="nofollow noopener" href="https://amzn.to/3a2tyc5">窒化ガリウム採用のハイパワー充電器</a> なら充電できる。</p> <h2 id="『飲むフランク』&プレミアム生ハム"><a href="#%E3%80%8E%E9%A3%B2%E3%82%80%E3%83%95%E3%83%A9%E3%83%B3%E3%82%AF%E3%80%8F%EF%BC%86%E3%83%97%E3%83%AC%E3%83%9F%E3%82%A2%E3%83%A0%E7%94%9F%E3%83%8F%E3%83%A0">『飲むフランク』&プレミアム生ハム</a></h2> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5fd5b80a7b4b1.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5fd5b80a7b4b1.png?mw=700" alt="image.png" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://www.tabechoku.com/products/13768">【ギフトボックス】肉汁ドバーっ!と『飲むフランク』&プレミアム生ハム(熨斗付き)</a></p> <p>食べチョクは開発に関わるとともに、生産者さんにお礼を言えるというシステムが面白いので普通にユーザーとしても使っている。<br /> 販売単位が大きすぎて二人暮らしだと持て余す商品も多いのだけど、フランク&生ハムは、日持ちもするし毎日少しづつ使えるのでリピ買いになった。<br /> 生ハムはチーズと一緒にクラッカーに乗せてもいいし、サンドイッチにパスタに、活躍の場がいっぱいあるので家にあると便利です。</p> <h1 id="とてもよかったもの"><a href="#%E3%81%A8%E3%81%A6%E3%82%82%E3%82%88%E3%81%8B%E3%81%A3%E3%81%9F%E3%82%82%E3%81%AE">とてもよかったもの</a></h1> <h2 id="動物マスク"><a href="#%E5%8B%95%E7%89%A9%E3%83%9E%E3%82%B9%E3%82%AF">動物マスク</a></h2> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5fd5b0af2f838.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5fd5b0af2f838.png?mw=700" alt="キツネマスク" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://hantensomeya.thebase.in/items/28340718">狐(キツネ)|動物マスク 水野染工場</a></p> <p>外出するたびにかわいいですねと声をかけられ、電車の中で向かいの子供が「ままー、パンダさん🐼」って言っているのが聞こえたりする、大人気マスク。ぼくがキツネでおくさまがパンダ着けています。</p> <p>時節柄マスクは付けないわけにいかないので、こういうのをつけることでちょっとでも気持ちが明るくなればいいなと思っています。</p> <p>いまだとクリスマスとか正月用マスクもあるよ。<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5fd5b16a75eb7.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5fd5b16a75eb7.png?mw=700" alt="image.png" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://hantensomeya.thebase.in/categories/2791228">イベントマスク 水野染工場</a></p> daisuke furukawa tag:crieit.net,2005:PublicArticle/16026 2020-08-09T13:31:47+09:00 2020-08-12T11:33:36+09:00 https://crieit.net/posts/spreadsheet-scraping Googleスプレッドシートでスクレイピング <p>スクレイピングがやりたかったんだけど、サーバの管理がめんどくさくなったので、Googleスプレッドシートの上でスクレイピングを出来るようにした。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2fb0bc27cbc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2fb0bc27cbc.png?mw=700" alt="image.png" /></a></p> <h1 id="やりたいこと"><a href="#%E3%82%84%E3%82%8A%E3%81%9F%E3%81%84%E3%81%93%E3%81%A8">やりたいこと</a></h1> <p>献血で、400mlAB型の血液が不足してます、A型は今大丈夫です、みたいな情報が、献血センターのwebサイトに掲載されるようになった。<br /> たとえば <a target="_blank" rel="nofollow noopener" href="https://www.bs.jrc.or.jp/th/miyagi/">宮城県赤十字血液センター</a>の今週の献血状況。AB型の人は成分献血にするか、次の機会にしたほうが良いらしい。<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2f346e54241.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2f346e54241.png?mw=700" alt="image.png" /></a></p> <p>これ以外の県も、<a target="_blank" rel="nofollow noopener" href="http://www.jrc.or.jp/search/bloodcenter/index.html">各県の献血センター</a>に掲載されている<br /> こういう情報をオープンにしてくれたのはとてもうれしいことなんだけど、webページに掲載されたって、ぼくらがわざわざ見に行かない限り気が付かない。できればこう、SNSで「今週の献血状況」みたいなことを発表してくれるといいよね。そしたら、「あ、AB型足りない?今週は余裕があるからじゃあぼく行くね」みたいなことが出来ていいと思うのよ。</p> <p>ないなら作れの精神で、とりあえずWebページ上にあるデータを毎日取得して蓄積してみることにした。あとでグラフとか需要の波が見られたら面白そうじゃない?</p> <p>でもそのためにサーバとか管理するのもなあ。もうちょっと気軽にやれる方法はないの?</p> <h1 id="GoogleAppsScript"><a href="#GoogleAppsScript">GoogleAppsScript</a></h1> <p>Googleスプレッドシートには、GoogleAppsScript(gas)というスクリプト機能があって、JavaScriptでスプレッドシートのセルの値を読み書きしたり、ボタンを押すとメソッドを実行するようにしたりすることが出来る。<br /> <a target="_blank" rel="nofollow noopener" href="https://developers.google.com/apps-script/reference/url-fetch/url-fetch-app">UrlFetchApp</a>というライブラリがあってWebページをダウンロードすることも出来る。あと時刻を設定して指定した関数を起動したりする機能もある。ということは、タイマーで定期的にWebページを取得させることが出来る。サーバレスでスクレイピングができるとかなり嬉しい。</p> <p>ただDomパーサーがないので、取ってきたHTMLは正規表現で切り出さないといけない。サーバの管理すらしたくない駄目人間にそれはちょっと厳しい。</p> <h1 id="ImportXML"><a href="#ImportXML">ImportXML</a></h1> <p>スプレッドシートには、<a target="_blank" rel="nofollow noopener" href="https://support.google.com/docs/answer/3093342?hl=ja">importXML</a>というメソッドがある。<br /> これを使うと、URLとXPathを書くだけでそのページの該当箇所を取ってきてセルに入れてくれるすごいメソッド。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2f4e4747b9c.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2f4e4747b9c.png?mw=700" alt="image.png" /></a></p> <p>ただこれ簡単メソッドだけに色々問題があって、<br /> ・厳密にXMLとして解釈しようとするので、乱暴なHTMLのページは取得できないことが多い<br /> ・JSの解釈もしてくれないぽい<br /> ・XPath書くの面倒w<br /> ・取得タイミングが制御できない</p> <p>最後のがわりと致命的で、キャッシュ制御がブラックボックスなので、ページが更新されても内容が更新されなかったり、予想されないタイミングでキャッシュが破棄されて内容が更新されていたりする。</p> <p>現時点の内容がわかれば十分な用途には便利なんだけど、毎日データを取ってくるような用途にはちょっと使いにくい。</p> <h1 id="cheeriogs"><a href="#cheeriogs">cheeriogs</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/cheeriojs/cheerio">cheerio</a>は、jQueryぽい文法でHTMLをパースすることが出来るnode.jsライブラリ。ブラウザじゃなくてもjQueryぽくHTMLを解析できるので、スクレイピングのときに便利。<br /> 残念ながらgasにはサイズ制限があるので、npm install cheerio みたいに気軽に使うことは出来ないんだけど、代わりにつかえるgas library でcheerioを使えるようにしてくれた <a target="_blank" rel="nofollow noopener" href="https://github.com/tani/cheeriogs">cheeriogs</a> という神がいるので、これを使うとスプレッドシートのスクリプト内でもHTMLをパースして内容を取ってくることが出来る。これですべての材料は揃った。</p> <h1 id="実装"><a href="#%E5%AE%9F%E8%A3%85">実装</a></h1> <p>スプレッドシートのメニューからスクリプトエディタを立ち上げる。<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2f759697cfa.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2f759697cfa.png?mw=700" alt="image.png" /></a></p> <p>リソース- ライブラリ でライブラリ画面を開いて、<a target="_blank" rel="nofollow noopener" href="https://github.com/tani/cheeriogs">cheeriogs</a> に書いてあるIDを入力してcheerioライブラリをインポート。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2f7639e92dd.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2f7639e92dd.png?mw=700" alt="image.png" /></a></p> <p>あとは、こんな感じで書けばページの内容を取得できる。</p> <pre><code>const content = UrlFetchApp.fetch(url).getContentText(); const $ = Cheerio.load(content); const title = $("title").first().text(); ret["title"] = title; ret["description"] = $("meta[name='description']").first().attr("content"); ret["pref"] = title.replace("赤十字血液センター|日本赤十字社","") ret["demand_date"] = $(".center-main-today-timedate").first().text(); ret["demands"] = []; $(".center-main-today-types-state").each((index, element) => { ret["demands"][index] = $(element).text(); }) : </code></pre> <p>まんまjQueryでしょ?</p> <p>このあと、スプレッドシートに載っている前回の結果を右にずらして左端に今回の結果を追加したりする処理があるんだけど、そこはたんなるgasのスプレッドシート操作なので省略。</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/tani/cheeriogs">cheeriogs</a> をつかうことで、献血の需給状況をスクレイピングすることが出来るようになった。タイマーで毎日起動するようにしたので、現在は放置しておいても毎日夜中にその日の情報をとってきてくれるようになっている。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2f78ff6c048.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5f2f78ff6c048.png?mw=700" alt="image.png" /></a></p> <p>単なるスプレッドシートなので、条件付き書式(セルの色塗り)とかはスクリプトと無関係に出来てしまうのも便利。</p> <p>gasはrubyでいうirbみたいな即時実行ツールがないし、デバッガも貧弱なので、そんなに開発体験が良いわけではない。<br /> でも無料で使えるし、タイマーとか便利だし、なによりスプレッドシートという強力なアウトプット窓口を使えるので、サービスの管理画面なんかはこれで作るのもありだなあ、と思った。</p> <p>あとはこれをtwitter botにすれば良いんだけど、例の感染症騒ぎで献血が逼迫した結果、今はどのエリアもみんな「成分献血:非常に困っています」しか出なくなってしまっている。この状況だと、献血を知っている人は献血したら次回の予約をして行く感じになっていて、Twitterで状況を知らせてくれると嬉しいとかいう感じじゃない。<br /> 今必要なのは、献血についてあんま知らない人が「えーそんな足りないの?」ということで献血にチャレンジしてくれることなので、この記事を見た人、ぜひご協力をお願いします。献血は不要不急じゃなくて必要なタスクです!</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15869 2020-04-25T21:07:31+09:00 2020-04-26T09:22:46+09:00 https://crieit.net/posts/CutYourOwnHair 自分で散髪するノウハウ <p>自分で散髪するノウハウの需要が高まってるので書いてみる。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5ea3eed726568.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5ea3eed726568.png?mw=700" alt="image.png" /></a></p> <h1 id="変にならない?"><a href="#%E5%A4%89%E3%81%AB%E3%81%AA%E3%82%89%E3%81%AA%E3%81%84%EF%BC%9F">変にならない?</a></h1> <p>この人見て変な頭だと思ったらやめておこう</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5ea3ef987f457.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5ea3ef987f457.png?mw=700" alt="image.png" /></a></p> <p>思わなかったら、つまりこのノウハウは大丈夫ってことです。この髪型で10年生きてきて、変と言われたことはないのできっと大丈夫。<br /> 自分で切ってると言っても「わかんなかった」と言われているので、きっと大丈夫。</p> <p>( これもし大丈夫じゃなかった場合ぼくの人生が10年分くらい否定されることになるから、こういうの書くのって勇気がいるよねw )</p> <h1 id="向き不向き"><a href="#%E5%90%91%E3%81%8D%E4%B8%8D%E5%90%91%E3%81%8D">向き不向き</a></h1> <p>起用不器用はたぶん関係ない。そんな難しくないので。</p> <p>それよりも、頭の形が凹んでたり歪んでたりする方は、自分でやっちゃうと頭の形がモロに出て目立つので、そういう方はプロに任せたほうがいいかも。頭の形に自信があれば一回やってみるのがおすすめ。<br /> 失敗しても一ヶ月くらいすればわかんなくなるし、最悪理髪店に戻っても損失はバリカン代数千円程度です。</p> <h1 id="用意するもの"><a href="#%E7%94%A8%E6%84%8F%E3%81%99%E3%82%8B%E3%82%82%E3%81%AE">用意するもの</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/dp/B001MBV4UQ/ref=cm_sw_r_tw_dp_U_x_XL-OEbQRVV5AG">パナソニックのバリカン カットモード</a></p> <p>別に他のでもいいのだけど、安くて安定してるのでオススメ。数年は余裕で使えます。この御時世でちょっと手に入りにくくなってるけど、普段だと4000円弱で手に入ります。</p> <p>あと100円ショップで入手すると便利なもの</p> <p><strong>ブルーシート</strong></p> <p> 下に敷いてから散髪すると、切った髪の毛の回収が楽になります。フローリングの部屋で切って掃除機かけるとか、新聞紙を敷いておいてそれごと捨てちゃうとか、人によって好みがあるらしい。</p> <p><strong>ホウキとチリトリ</strong></p> <p> 掃除用。ちゃんと掃除機かければいらないはずなんだけど、なんのかんのであると便利。</p> <p><strong>大きいハサミ</strong>, <strong>鏡</strong></p> <p> 上級編で使います<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5ea429eaec988.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5ea429eaec988.png?mw=700" alt="image.png" /></a></p> <h1 id="初級編"><a href="#%E5%88%9D%E7%B4%9A%E7%B7%A8">初級編</a></h1> <p>カットモードには12mmのアタッチメントが付いてるので、これでバッサリやっちゃえば丸刈りになります。慣れるまではこれで行きましょ。</p> <h1 id="中級編"><a href="#%E4%B8%AD%E7%B4%9A%E7%B7%A8">中級編</a></h1> <p>全体を12mmでカットした後、耳とか後ろの、いわゆる裾部分だけ9mmで刈直しておくと髪の毛がうっとおしくならないし、丸刈り感が薄れていい感じになります。</p> <h1 id="上級編"><a href="#%E4%B8%8A%E7%B4%9A%E7%B7%A8">上級編</a></h1> <p>おでこの部分だけバリカンかけずに残しておいて、鏡を見ながら水平に整えると、冒頭の写真の髪型になります<br /> バリカンした部分とのつなぎ目が難しくて、うえの写真だってよーく見ると変なんだけど、案外ばれないです。</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>妹の結婚式の時、何年かぶりに理髪店に行ったら、「なんか変わった髪型だなーと思いました。自分でやられてるんですね」と言われたので、プロが見ると自分でカットしてるのはわかっちゃうらしい。でもべつにそれが理由で叩き出されたりしなくて、普通に整えてくれたので、一回自分でやったら二度と理髪店に戻れないなんてことはないです。「自分でやったけどうまく行かないので戻ってきました。てへ☆」とか言っておけば大丈夫。</p> <p>でも自分でできるようになれば予約も待ち時間も移動時間も不要になって、お店の人と何話していいか悩まなくていいし、コスパ圧倒的にいいので、ぜひお試しください☆</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15781 2020-03-28T11:50:27+09:00 2020-03-28T11:52:57+09:00 https://crieit.net/posts/work-at-home 在宅ワークが二人いることに伴う諸問題とその対策 <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ひと家庭で二人以上テレワークor在宅フリーランスの人がいるご家庭で、昼ご飯誰がどうするかとか、打ち合わせの時どうしてるかとか、どうしても入り込んでくる家や相手のアレコレをお互い負担なく過ごす工夫を知りたいこの頃</p>— 輝竜司(作業中)|『蜘蛛ですが』2020年アニメ化! (@citrocube) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/citrocube/status/1243672820866879488?ref_src=twsrc%5Etfw">March 27, 2020</a></blockquote> <p>なるほどそういうことが悩みになるのか。</p> <p>フリーランス夫妻歴10年のうちのケースを紹介します。</p> <p><a href="https://crieit.now.sh/upload_images/10cf480b4ca1dfc32b1afac8164729325e7ebab216a88.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/10cf480b4ca1dfc32b1afac8164729325e7ebab216a88.png?mw=700" alt="image" /></a></p> <h1 id="仕事部屋は必要"><a href="#%E4%BB%95%E4%BA%8B%E9%83%A8%E5%B1%8B%E3%81%AF%E5%BF%85%E8%A6%81">仕事部屋は必要</a></h1> <p>ふたりとも場所を選ばない仕事なのでわりと気軽に引っ越すことが出来て、よい仕事場所を求めて過去4-5回引っ越しを繰り返している。部屋があったりなかったりいろいろ試したんだけど、やっぱり仕事部屋は必要。</p> <p>ないと、テレカン中に家族が入ってくるとか、ポモドーロが一個崩壊するなどの事故が起きる。逆に「仕事中だから声をかけるな」みたいな事を言ってしまうと、いつ声をかけていいかわからないので家族不和の原因になってよくない</p> <p>例外として、高いタワーマンションでビジネスフロアがついているとか、近所のコワーキングスペースを定期契約してそこで仕事をすることにする手もある。でもそれは今回のテーマと外れるのでスキップ。</p> <h1 id="時間を区切る"><a href="#%E6%99%82%E9%96%93%E3%82%92%E5%8C%BA%E5%88%87%E3%82%8B">時間を区切る</a></h1> <p>うちでは朝食7:00、昼食12:00、おやつ15:00、夕食18:00と決めている。この時間前30分は仕事中でも割り込んで声をかけて良いルールで、「ご飯できたよー」って呼ばれたりする。<br /> なのでこの時間にかぶりそうだったら、ポモドーロじゃなくてタスク整理をするとか、いっそ早い目にリビングに移動して食事の用意を手伝ったりする。</p> <p>逆にそれ以外の時間仕事部屋にこもっていたら、それは仕事中なので原則声をかけないマナー。</p> <h1 id="食事作る人は決めておく"><a href="#%E9%A3%9F%E4%BA%8B%E4%BD%9C%E3%82%8B%E4%BA%BA%E3%81%AF%E6%B1%BA%E3%82%81%E3%81%A6%E3%81%8A%E3%81%8F">食事作る人は決めておく</a></h1> <p>朝食と夕食はぼく、昼食はおくさまが作ることにしている。もちろん忙しかったり病気のときは随時交代するけど。</p> <p>一人暮らし自宅で仕事だと、食事はぜんぶUberEatsとか、全食<a target="_blank" rel="nofollow noopener" href="http://www.comp.jp/">COMP</a> みたいな極端な人もいて、それはそれで時間効率良さそうなんだけど、家族仲と健康と時間効率のバランスを考えた結果、せめて一日一食は野菜とか肉とかバランスの取れたものを食べたほうが良さそうということで、うちではお昼ごはんをそういうメニューにすることにしている。</p> <p>朝と夜は軽食で、気が向いたときはネットで見つけた面白メニューを作ることもあるし、そうでないときはピザとかパスタとかそうめんとかシリアルが多い。あと神戸なので、週に一度は素敵なおみせでパンをかってきて食べる日もある。</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ホットサンドメーカー楽しいよ? うちのはちょっと違うけど。 <a target="_blank" rel="nofollow noopener" href="https://t.co/ItgeWl0ID9">pic.twitter.com/ItgeWl0ID9</a></p>— もぎゃ(daisuke furukawa) (@mogya) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/mogya/status/1219545000695889920?ref_src=twsrc%5Etfw">January 21, 2020</a></blockquote> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">神戸おいしいものが多すぎるので、「サラダと一緒に食べたら甘パンもサンドイッチと見なす」「おやつと合体すれば晩ごはんにケーキもあり」などの抜け穴を見つけるスキルが急成長している。ちなみに写真は夜アイスと合体した今日の晩ごはん😝 <a target="_blank" rel="nofollow noopener" href="https://t.co/UroJZA8KTC">pic.twitter.com/UroJZA8KTC</a></p>— もぎゃ(daisuke furukawa) (@mogya) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/mogya/status/1128629326696443907?ref_src=twsrc%5Etfw">May 15, 2019</a></blockquote> <h1 id="がっつりディ"><a href="#%E3%81%8C%E3%81%A3%E3%81%A4%E3%82%8A%E3%83%87%E3%82%A3">がっつりディ</a></h1> <p>今日はガッツリコード書くことに集中したい。食事で中断されたくない!という日は「今日はお昼食べないで外で仕事します」と宣言して外で仕事をすることにしている。近所のコワーキングスペースとか、ネットカフェとか。あと後述するスーパー銭湯とか。</p> <p>お買い物の都合があるのでできれば前日までに宣言のこと、ということになっていて、このへんは共同生活ゆえに仕方ない制限かなと。最悪当日宣言でもどうにかならないことはないのだけれど、「家族仲を生贄に効率神を召喚」みたいな技なのであまり使いたくない。</p> <h1 id="お風呂ディ"><a href="#%E3%81%8A%E9%A2%A8%E5%91%82%E3%83%87%E3%82%A3">お風呂ディ</a></h1> <p>近所にスーパー銭湯があって、ここには漫画とパソコンのフロアが用意されているので、ノートパソコンを持ち込むと仕事をすることも出来てしまう。おうちでしごとするのに飽きると「温泉行こー」ということでここで一日仕事をしつつ温泉入り放題の日を作ることもある。</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>Twitterなどで、ひとり暮らししてコード書くのに全力投入している人を見ると羨ましいなあと思ったりするし、ある程度試してみたことはあるのだけれど、運動をサボると肩腰に来るし、食生活に手を抜くとだんだん体調が崩れていって結局集中できなくなったりするので、規則正しい生活をしていても、アウトプットできる量はそんなには変わらないのだと思う。</p> <p>もちろん人によって家族によって何を快適に思うかはそれぞれ異なるので、うちの例がすべての家庭でフィットするわけじゃないのだけれど、なんかの参考になれば幸いです。</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15749 2020-03-06T09:34:49+09:00 2020-03-07T09:31:54+09:00 https://crieit.net/posts/netlify-redirect-nuxt nuxt.jsプロジェクトをnetlifyで公開してredirectを使うときの罠 <hr /> <p>3/6 11:15追記</p> <p>サブディレクトリにあるときだけ発生する問題ぽい。問題をまとめてサポートに報告しました https://community.netlify.com/t/subdirectory-and-publish-directory-redirection/10120</p> <hr /> <p>netlifyにはnetlity.tomlという設定ファイルを書くといろいろ設定ができることになっていて、従来nginxでやっていたような各種リダイレクトも、ここに書くことで実行してくれることになっている。<br /> <a target="_blank" rel="nofollow noopener" href="https://docs.netlify.com/configure-builds/file-based-configuration/#redirects">Syntax for the Netlify configuration file</a></p> <p>これと、nuxt.jsみたいにビルド結果をサブディレクトリに出力するツールが組み合わさるとちょっと予想しない対応が必要になる話。</p> <hr /> <p>ルートディレクトリに配置したnetlify.tomlにビルドとリダイレクトの設定を書く。</p> <pre><code>[build] base = "front/" publish = "dist/" command = "npm run generate" [[redirects]] from = "https://gisyohub.netlify.com/" to = "https://gisyohub.com/" status = 301 force = true </code></pre> <p>結果、ビルドはしてくれるのだけれど、リダイレクトは動かない。</p> <p>ぼくの実験結果だと、同じファイルをコピーして、staticディレクトリにもnetlify.tomlを配置してあげると、ビルドする時dist/にコピーされて、その結果redirectが動作するようになる。</p> <p>おそらくnetlifyは、ビルド時はルートディレクトリにあるnetlify.tomlを見るけど、リダイレクトのときはpublishディレクトリにあるnetlify.tomlを見ているらしい。実装の都合は何となく分かるんだけど、せめてドキュメントに明示してほしい感じ。</p> <p>こことかここで話題に上がってるんだけど、バグとしては認めてもらえなかったぽい。<br /> <a target="_blank" rel="nofollow noopener" href="https://community.netlify.com/t/redirects-within-netlify-toml-not-working/1731">https://community.netlify.com/t/redirects-within-netlify-toml-not-working/1731</a><br /> <a target="_blank" rel="nofollow noopener" href="https://community.netlify.com/t/netlify-toml-folder-with-nuxtjs-and-netlify-cli/4659/3">https://community.netlify.com/t/netlify-toml-folder-with-nuxtjs-and-netlify-cli/4659/3</a></p> <p>シンプル再現環境を作ればバグだと認めてもらえそうな気がするんだけど、この問題のミニマム環境って何で作るのがいいのだろう。nuxtとかの開発環境なしに、index.htmlだけをnetlifyで公開するような構成って作れるのかな?</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15744 2020-03-03T16:09:10+09:00 2020-03-03T16:09:10+09:00 https://crieit.net/posts/docker-build-volume docker build中にVolumeの中身は参照することが出来ない <p>railsの開発中に、ホストのrailsディレクトリをまるごとコンテナ内で参照してgemもここに入れちゃいたい、そしたらコンテナ作成のたびにbundle installし直さなくて済むし、みたいな需要があって。</p> <pre><code>volumes: - ./:/rails </code></pre> <p>みたいなことを書いて、dockerfile内で</p> <pre><code>WORKDIR /rails/ RUN bundle install -j4 --retry=3 && \ bundle clean </code></pre> <p>しようとすると、/rails/Gemfileが見えないからインストールが上手く行かない、というようなことが起こる。</p> <p>よくわかんないんだけどbashで入って改めてbundle installすればインストールできるからまあいいか、みたいないい加減な運用をしていた。</p> <p>んで、heroku環境で運用しようとすると、アクセスが来た時点でbundle installが走り出して、当然timeoutするのでコンテナが殺されて、あやふやな理解じゃだめだね、ということに気づいた。</p> <h1 id="dockerのvolumeはbuild中に中身を参照できない。"><a href="#docker%E3%81%AEvolume%E3%81%AFbuild%E4%B8%AD%E3%81%AB%E4%B8%AD%E8%BA%AB%E3%82%92%E5%8F%82%E7%85%A7%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84%E3%80%82">dockerのvolumeはbuild中に中身を参照できない。</a></h1> <p>Dockerfileの中に書いたコマンドは、CMDとENTRYPOINT以外、buildのときに実行される。で、このタイミングでは、volumeの中身を読み書きすることは出来ない。<br /> volumeはdocker runの時初めてマウントされる。なので、volumeの中のファイルに依存したコマンドを実行したり、volumeの中に書き込むようなコマンドは、docker run以降にしないといけない。</p> <p>なんでかというと、docker buildコマンドに-vオプションがないから。<br /> <a target="_blank" rel="nofollow noopener" href="https://docs.docker.com/engine/reference/commandline/build/">https://docs.docker.com/engine/reference/commandline/build/</a></p> <p>つまり、volumeはそういう仕様なのだ。</p> <p>docker build -v作ろうよ、というissueは過去何度か立ち上がっているのだけれど、こんな感じで却下されている</p> <blockquote> <p>I think you'll find you get a lot of resistance to a build -v option. The docker team has been very opposed to flags which introduce non-reproducability between builds.<br /> (私訳: build -vオプションには多くの抵抗があると思います。 Dockerチームは、ビルド間に再現性のないフラグを導入することに非常に反対しています)<br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/moby/moby/issues/17745#issuecomment-236785473">https://github.com/moby/moby/issues/17745#issuecomment-236785473</a></p> </blockquote> <p>そんなこと言ったらCOPYだって環境に依存して再現性がなくなる気がするんだけど。<br /> とにかくそんな仕様で、build中に読み書きすることが出来ないので、/railsに読み書きしようとして失敗していたと。ふむ。</p> <h1 id="どうするのが良いか"><a href="#%E3%81%A9%E3%81%86%E3%81%99%E3%82%8B%E3%81%AE%E3%81%8C%E8%89%AF%E3%81%84%E3%81%8B">どうするのが良いか</a></h1> <p>開発環境だったら、起動後のbashからbundle installするか、CMDで起動するスクリプト内でbundle installする運用でも別に困らない。</p> <p>本番だと、上で述べたようにherokuでアクセスが来てからbundle installがはじまる、みたいなことになるのは困るので、ちゃんとbuild時にbundle installを終わらせておく必要がある。<br /> 本番環境でソースを書き換えて即時実行なんて需要はないはずなので、ホストのファイルシステムをマウントするのではなくて、COPYでまるごとコピーするのが正解。<br /> これはなぜかdocker build中でも実行できるので、必要なディレクトリを全部COPYしてbundle installすれば、build中でも実行することができる。</p> <p>Dockerfile.production</p> <pre><code>WORKDIR /rails/ COPY . /rails/ RUN echo 'gem: --no-rdoc --no-ri' >> "$HOME/.gemrc" ENV GEM_HOME /usr/local/bundle ENV PATH $GEM_HOME/bin:$PATH RUN gem install bundler \ && bundle config --local path "$GEM_HOME" \ && bundle config --local bin "$GEM_HOME/bin" ENV BUNDLE_APP_CONFIG $GEM_HOME RUN bundle install -j4 --retry=3 && bundle clean CMD ["rails", "server", "-b", "0.0.0.0"] </code></pre> daisuke furukawa tag:crieit.net,2005:PublicArticle/15731 2020-02-22T10:10:40+09:00 2020-02-22T10:10:40+09:00 https://crieit.net/posts/docker dockerで本番環境と開発環境を使い分ける方法いろいろ <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">dev環境とprod環境で別のDockerfile使うってできるのかなdev環境ではホットリロードしたいからspring-boot:runで動かしてるけど,本番は実行可能jarにして動かしたい🐳</p>— ysek (@uuusu_) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/uuusu_/status/1221101379214696448?ref_src=twsrc%5Etfw">January 25, 2020</a></blockquote> <p>よくあるよね。ちょうど今書いているプロダクトがいろいろ使っているので説明してみる</p> <h1 id="基本1:環境別のファイルを使う"><a href="#%E5%9F%BA%E6%9C%AC%EF%BC%91%EF%BC%9A%E7%92%B0%E5%A2%83%E5%88%A5%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E4%BD%BF%E3%81%86">基本1:環境別のファイルを使う</a></h1> <p>希望:Dockerfile.developmentとDockerfile.productionみたいなのを用意して使い分けたい</p> <p>docker build -f Dockerfile.development という具合にして指定することができる</p> <p><a target="_blank" rel="nofollow noopener" href="http://docs.docker.jp/engine/reference/commandline/build.html">http://docs.docker.jp/engine/reference/commandline/build.html</a></p> <h1 id="基本2:start.shで分岐"><a href="#%E5%9F%BA%E6%9C%AC%EF%BC%92%EF%BC%9Astart.sh%E3%81%A7%E5%88%86%E5%B2%90">基本2:start.shで分岐</a></h1> <p>希望:毎回ファイルを指定するのめんどくさい。一個で実現できないの?</p> <p>Dockerfileじゃなくて、最後に起動するstart.sh的なファイルの中なら、シェルスクリプトだから何だって書ける。</p> <p>Dockerfile</p> <pre><code>: CMD ["sh", "start.sh"] </code></pre> <p>start.sh</p> <pre><code>: if [ "$NODE_ENV" = "development" ] then # develop環境の処理 else # それ以外の処理 fi </code></pre> <p>冒頭の用途ならこれで十分な気がする。javaは知らないけど、たぶんdevとかprodcutionを指定する環境変数みたいなのはあるよね。</p> <p>ただ、何でもかんでもstart.shにいれると、docker layer cacheが効かなくなってbuildの重いコンテナになってしまう。ライブラリのインストールみたいに重たい処理を切り替えたいときはDockerfileから分けたほうが良い。</p> <h1 id="docker-composeを使う"><a href="#docker-compose%E3%82%92%E4%BD%BF%E3%81%86">docker-composeを使う</a></h1> <p>dockerと使い分けがよくわからないDocker-composeだけど、ちゃんと使うといろいろ便利な機能がある。ビルドするファイルを環境変数で指定できるのもその一つ</p> <p>docker-compose.production.yml</p> <pre><code> rails: build: dockerfile: docker/Dockerfile.production </code></pre> <p>こんな感じでproduction用のdocker-composeファイルを用意して</p> <pre><code>export COMPOSE_FILE=docker/docker-compose.development.yml </code></pre> <p>こんなふうに環境変数でファイルを指定しておけば、普段は、 <code>docker-compose build</code> という具合に、特に意識せずに使うことができる<br /> buildとかrun程度の普段の用事ならdocker-composeで全部できるので、使い分けのことはあまり考えずに過ごせる。</p> <h1 id="おまけ:ディレクトリを整理する"><a href="#%E3%81%8A%E3%81%BE%E3%81%91%EF%BC%9A%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA%E3%82%92%E6%95%B4%E7%90%86%E3%81%99%E3%82%8B">おまけ:ディレクトリを整理する</a></h1> <p>この手の使い分けをすると、プロジェクトのルートディレクトリにやたらとファイルが散逸する問題が起きる</p> <pre><code>|-- README.md |-- .circleci |-- deploy.sh |-- docker-compose.development.yml |-- docker-compose.production.yml |-- Dockerfile.development |-- Dockerfile.production |-- .env |-- (他にもプロダクトのファイルがいっぱい) </code></pre> <p>気にしなければいいと言えばいいのだけれど、服装の乱れは風紀の乱れ、プロジェクトの破綻はこういうところからやってくる!という感じで気になる人は、サブディレクトリに片付けよう</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/mogya/items/73d2dae6c429926bf731">docker関連ファイルをサブディレクトリに配置する</a></p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15708 2020-02-04T14:05:06+09:00 2020-02-04T14:36:45+09:00 https://crieit.net/posts/Update-your-client-software-to-continue-using-Let-s-Encrypt "Update your client software to continue using Let's Encrypt" <p>Let's Encryptからそんなメールが来たあなた、さてはサーバソフトウェアの更新をサボっていますね?ぼくもです😀</p> <p>これが来た人が何をしないといけないのかをまとめました。簡単に言うと certbot を更新しましょう</p> <h1 id="何言われてるの?"><a href="#%E4%BD%95%E8%A8%80%E3%82%8F%E3%82%8C%E3%81%A6%E3%82%8B%E3%81%AE%EF%BC%9F">何言われてるの?</a></h1> <blockquote> <p>According to our records, the software client you're using to get Let's<br /> Encrypt TLS/SSL certificates issued or renewed at least one HTTPS certificate<br /> in the past two weeks using the ACMEv1 protocol. Your client's IP address was:</p> <p><strong><em>.</em></strong>.<strong><em>.</em></strong></p> </blockquote> <p>ここ二週間の記録によると、Let's Encrypt TLS/SSL 証明書を取るために使っているクライアント、ACMEv1 プロトコルを使ってるようです。IPアドレスはこれ</p> <blockquote> <p>Beginning June 1, 2020, we will stop allowing new domains to validate using<br /> the ACMEv1 protocol.<br /> You should upgrade to an ACMEv2 compatible client before then, or certificate issuance will fail. For most people, simply upgrading to the latest version of your existing client will suffice.</p> </blockquote> <p>2020/01/01から、ACMEv1プロトコルでのドメイン認証は停止されます。<br /> ACMEv2を使うクライアントソフトウェアに移行しないと、証明書が更新できなくなります。大多数の人にとっては、単に使っているクライアントソフトウェアを更新すればよいはずです。</p> <p>(訳注 それ以外の人についての説明があるけど、そんな人はこの記事読まないので中略)</p> <blockquote> <p>ACMEv1 API deprecation details can be found in our community forum:<br /> <a target="_blank" rel="nofollow noopener" href="https://community.letsencrypt.org/t/end-of-life-plan-for-acmev1">https://community.letsencrypt.org/t/end-of-life-plan-for-acmev1</a></p> </blockquote> <p>ACMEv1 APIの廃止についての詳細はコミュニティフォーラムで見ることが出来ます。<br /> <a target="_blank" rel="nofollow noopener" href="https://community.letsencrypt.org/t/end-of-life-plan-for-acmev1">https://community.letsencrypt.org/t/end-of-life-plan-for-acmev1</a><br /> (訳注 廃止の進め方の話題なので、ぼくらが何をするかの説明は載ってないぽい)</p> <h1 id="どうすりゃいいの?"><a href="#%E3%81%A9%E3%81%86%E3%81%99%E3%82%8A%E3%82%83%E3%81%84%E3%81%84%E3%81%AE%EF%BC%9F">どうすりゃいいの?</a></h1> <p>certbotを更新すればOKです。</p> <p>ぼくの使っているCentOSだと</p> <pre><code>$ sudo yum update certbot : ================================================================================================= Package Arch Version ================================================================================================= Updating: certbot noarch 1.0.0-1.el7 python-requests noarch 2.6.0-8.el7_7 : Updating : certbot-1.0.0-1.el7.noarch Complete! </code></pre> <p>という感じでした。</p> <p>certbotには<a target="_blank" rel="nofollow noopener" href="https://qiita.com/mogya/items/f43334fd531888c4774f">自動更新のためのtimerがついている</a>ので、これを使っている人は念の為リロードしておきましょう</p> <pre><code>$ sudo systemctl daemon-reload </code></pre> <p>自分でcrontab書いた人は自前でなんとかしてね。せっかくcertbotがtimerを用意してくれているので、こっちを使うことをおすすめするよ。</p> <h1 id="動作確認"><a href="#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D">動作確認</a></h1> <p>一回手動で動かしておけばいいかなと。</p> <pre><code>$ sudo systemctl start certbot-renew $ sudo systemctl status certbot-renew * certbot-renew.service - This service automatically renews any certbot certificates found Loaded: loaded (/usr/lib/systemd/system/certbot-renew.service; static; vendor preset: disabled) Active: inactive (dead) since Tue 2020-02-04 13:06:36 JST; Process: 27876 ExecStart=/usr/bin/certbot renew ... Main PID: 27876 (code=exited, status=0/SUCCESS) Feb 04 13:06:36 linode10.mogya.com certbot[27876]: Processing /etc/letsencrypt/renewal/oasis.mogya.com.conf Feb 04 13:06:36 linode10.mogya.com certbot[27876]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Feb 04 13:06:36 linode10.mogya.com certbot[27876]: Cert not yet due for renewalbot-renew.timer Feb 04 13:06:36 linode10.mogya.com certbot[27876]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Feb 04 13:06:36 linode10.mogya.com certbot[27876]: The following certs are not due for renewal yet: Feb 04 13:06:36 linode10.mogya.com certbot[27876]: /etc/letsencrypt/live/oasis.mogya.com/fullchain.pem expires on 2020-04-09 (skipped) Feb 04 13:06:36 linode10.mogya.com certbot[27876]: No renewals were attempted. Feb 04 13:06:36 linode10.mogya.com certbot[27876]: No hooks were run. Feb 04 13:06:36 linode10.mogya.com certbot[27876]: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Feb 04 13:06:36 linode10.mogya.com systemd[1]: Started This service automatically renews any certbot certificates found. </code></pre> <p>こんな感じで、"Cert not yet"(期限がまだだから更新しなかったよ)的なログが出れば大丈夫かと思います。</p> <p>心配な人は、expires on の日付にリマインダを仕掛けておいて動作確認しましょう</p> <h1 id="その他"><a href="#%E3%81%9D%E3%81%AE%E4%BB%96">その他</a></h1> <p> たまにルータなんかが勝手にLet's Encrypt にアクセスして証明書をとってくる仕組みになっているものがあるらしいです。<br /> 自分で証明書を取得した記憶がないのにこのメールを受け取った人は、この記事の対象じゃないので、ルータメーカーのサポートに相談するのがいいんじゃないかと思います。</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15683 2020-01-15T22:20:27+09:00 2020-01-15T22:25:17+09:00 https://crieit.net/posts/twittergem Twitter Gemの現状と、メンテされていないGemを使い続ける方法 <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>Twitter Gemがメンテされなくなっているので、自分が気になる不具合の修正を取り込んだ <a target="_blank" rel="nofollow noopener" href="https://github.com/mogya/twitter-gem">mogya/twitter-gem</a> を作ったよ。</p> <h1 id="Twitter Gemの現状"><a href="#Twitter+Gem%E3%81%AE%E7%8F%BE%E7%8A%B6">Twitter Gemの現状</a></h1> <p>RubyでTwitterAPIを使うには、<a target="_blank" rel="nofollow noopener" href="https://github.com/sferik/twitter">sferik/twitter</a> が定番になっています。gem install twitterして入るのもこのGemだし、Twitter開発者サイトでも紹介されている著名なGemです。</p> <p>が、このライブラリは2018/6のコミットを最後にアップデートが行われていなくて、たくさんのPRが残ったままになっています。<br /> もはやコードが完璧でいかなる修正も必要ないのであればそれでもいいのですけど、ぼくがさわった範囲でも結構困るような不具合があって、それに対する修正PRが出されているのだけれど、マージされないまま放置されているのが現状です。</p> <p>OSSというのはそういうものなので、sferikさんを責める気は全然ありません。長い間メンテしてくださってありがとうございます。とはいえ、現に今TwitterAPIを使いたいのに不具合で動かないのは困る。</p> <h1 id="extended mode問題"><a href="#extended+mode%E5%95%8F%E9%A1%8C">extended mode問題</a></h1> <p>例えば、tweet_mode=extendedにした時、textが取れなくなる。<br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/sferik/twitter/issues/813">Cannot retrieve text · Issue #813</a></p> <pre><code>client = ... status = client.status(1216628579099766784, tweet_mode: "extended") status.text => <null> status.full_text => <null> </code></pre> <p>tweet_modeは2017年ごろに導入された後方互換性のためのフラグで、最近のTwitterクライアントは、基本tweet_mode: "extended"で利用することが想定されています。それを付けて呼び出すとツイート本文が取れないという、かなり基本的な部分で困る不具合です。</p> <p>当然複数の修正が提案されているのですが、どれもマージされないまま放置されてしまっています。</p> <p>ぶっちゃけこの問題だけなら、PRのコードをコピペしてinitialize/twitter_patch.rbみたいなファイルに書いておけばごまかせるわけですが、今後もこのライブラリが更新されないということは、こいつのせいでRailsがアップデートできないとか、新しいRubyを利用できないといった問題が予想されます。</p> <h1 id="後継Gemを探せ"><a href="#%E5%BE%8C%E7%B6%99Gem%E3%82%92%E6%8E%A2%E3%81%9B">後継Gemを探せ</a></h1> <p>Twitterで相談したところ、こういうときの後継Gemを探す方法を教えてもらいました</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">有名なgemがメンテ放置されて、有用そうなPRがいっぱい放置された状態になってるのね。forkしてそういうパッチを取り込んだものを公開している人がたぶんいると思うんだけど、そういうリポジトリを探す方法ってないもんでしょうか?</p>— もぎゃ(daisuke furukawa) (@mogya) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/mogya/status/1216900590959071233?ref_src=twsrc%5Etfw">January 14, 2020</a></blockquote> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Insights タブの中の Network graph を見ると、最近も開発・メンテされている Fork 先のリポジトリを見つけることができると思います。<a target="_blank" rel="nofollow noopener" href="https://t.co/pZy6jEvSFu">https://t.co/pZy6jEvSFu</a></p>— peaceiris (@piris314) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/piris314/status/1217093903913906178?ref_src=twsrc%5Etfw">January 14, 2020</a></blockquote> <p>実際に見たのがこちら。<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e1f0c6b8fa25.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e1f0c6b8fa25.png?mw=700" alt="image.png" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/sferik/twitter/network">https://github.com/sferik/twitter/network</a></p> <p>右に行くほど新しいブランチで、sferikさんのオリジナルからforkしている人をたくさん見つけることができます。PR名が出ているので、その人が何をしたのかだいたい分かります。</p> <p>●をクリックすると該当レポジトリを見ることができるのですが、たいていの人は、sferikさんのコードになんか修正を加えてそのまま終わっています。ぼくみたいに特定の問題について困ったから、そこだけ修正して使っておこうという感じですね。</p> <p>ただそれだと、RubyとかRailsの更新についていけなくなるのが困る。そう思ってリポジトリを次々みていくと、ピンとくる名前を見つけました。</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/zendesk/twitter">https://github.com/zendesk/twitter</a></p> <p>ZenDeskはユーザーサポートを一元化するための有名サービスで、Twitterからの問い合わせも対応できるようになっています。ここで使われているのなら継続的にメンテしてくれることを期待できそうです。</p> <p>そうおもって更新履歴を見ると<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e1f0d08e4a85.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e1f0d08e4a85.png?mw=700" alt="image.png" /></a><br /> あたらしいRubyへの対応とか、動かない箇所の修正とか、去年の夏まで継続的に修正が加えられています。これなら期待できそう。</p> <p>ただひとつ問題なのは、最初に述べたextended textへの対応は入ってないようです。Zendeskの人は困ってないのかなあ。</p> <h1 id="俺Gemを作る"><a href="#%E4%BF%BAGem%E3%82%92%E4%BD%9C%E3%82%8B">俺Gemを作る</a></h1> <p>しょうがないので、zendesk/twitterからさらにForkしてmogya/twitter_gem を作ることにしました(mogya/twitterは他の名前で使ってしまっているので、別の名前にしてあります)</p> <p>zendesk/twitterをForkしたあと、自分が取り込みたいPRを持ってきてマージします。この記事が参考になりました。<br /> <a target="_blank" rel="nofollow noopener" href="https://chaika.hatenablog.com/entry/2017/04/01/073057">GitHub 特定のPRをForkしたローカルリポジトリに取ってきたい - かもメモ</a></p> <pre><code>[ ~/develop/twitter-gem]$ git remote add sferik [email protected]:sferik/twitter.git [ ~/develop/twitter-gem]$ git remote -v origin [email protected]:mogya/twitter-gem.git (fetch) origin [email protected]:mogya/twitter-gem.git (push) sferik [email protected]:sferik/twitter.git (fetch) sferik [email protected]:sferik/twitter.git (push) [ ~/develop/twitter-gem]$ git fetch sferik pull/913/head:fulltext agent key RSA SHA256:+UeiGLqOys7Ur3KBSq4c10jM4fWlFnacby3izYyfMZg returned incorrect signature type From github.com:sferik/twitter * [new ref] refs/pull/913/head -> fulltext 10:37:03[daisuke@linode17 ~/develop/twitter-gem]$ git push origin fulltext : remote: Create a pull request for 'fulltext' on GitHub by visiting: remote: https://github.com/mogya/twitter-gem/pull/new/fulltext remote: To github.com:mogya/twitter-gem.git * [new branch] fulltext -> fulltext </code></pre> <p>このままgitでマージしても良さそうなのだけれど、なんとなくgithub上でPR作ってマージしておきました。<br /> <a target="_blank" rel="nofollow noopener" href="https://github.com/mogya/twitter-gem/pull/1">https://github.com/mogya/twitter-gem/pull/1</a></p> <p>ついでにtravis-ciもぼくのものに置き換えたところ、無事テストがPassしたようです。<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e1f0fa0db458.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e1f0fa0db458.png?mw=700" alt="image.png" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://travis-ci.org/mogya/twitter-gem">https://travis-ci.org/mogya/twitter-gem</a></p> <p>出来上がったのがこちら。<a target="_blank" rel="nofollow noopener" href="https://github.com/mogya/twitter-gem">mogya/twitter-gem</a></p> <p>Gemfileに gem "twitter"と書くところでぼくのリポジトリを指定します</p> <pre><code>gem 'twitter', github: 'mogya/twitter-gem' </code></pre> <p>使ってみる</p> <pre><code>[2] pry(main)> client = ... [3] pry(main)> status = client.status(1216628579099766784, tweet_mode: "extended") [4] pry(main)> status.text => "「実際にアプリ☆メーカーも、それまでに作ったサービスで宣伝して初期ユーザーを集めました。そしてマシュマロも、アプリ☆メーカーから初期ユーザーを集めました。雪だるま式戦術がうまくいった例です。」 「持たざる者」の集客方法|だーすー @Neko_Inu_ #note https://t.co/hKs4NfSQTj" [5] pry(main)> status.uris => [#<Twitter::Entity::URI:0x00005582b377a638 @attrs={:url=>"https://t.co/hKs4NfSQTj", :expanded_url=>"https://note.com/neko_inu/n/nfae33c222614", :display_url=>"note.com/neko_inu/n/nfa\u2026", :indices=>[134, 157]}>] </code></pre> <p>よし完璧。Network graphにも、mogyaの名前が表示されるようになりました。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e1f0db40a4fc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e1f0db40a4fc.png?mw=700" alt="image.png" /></a></p> <p>当面はこの状態で、zendeskの人がなにかアップデートしたら取り込むし、ぼくが使っていて困る不具合を他に見つけたらPRを取り込む感じで運用しようと思っています。</p> <p>ここからさらに、みんなに呼びかけて支持者を集めて、sferikさんからTwitter Gemの管理権を禅譲してもらえば、ぼくがTwitter Gemのメンテナになることができる可能性があります。OSS contributorの名前は憧れるし、語学力的にできないこともなかろうと思うのですが、普通に考えるとZendeskのみなさまのほうがふさわしいと思うし、なにより、TwitterのすべてのAPIについて使い方を把握して、いま出ているissueを全部さばくとなると、それはちょっと片手間ではできなさそう。<br /> どっか困っている会社さんが毎月5万円くらい払ってくれるということであれば検討するので、興味のある方は<a target="_blank" rel="nofollow noopener" href="https://twitter.com/mogya">ご連絡</a>ください:-)</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15643 2019-12-27T23:15:26+09:00 2019-12-27T23:27:59+09:00 https://crieit.net/posts/a678fd16b833d69fcbf5e9562eff917b 個人開発者のためのクラウドソーシング発注入門 <p>この記事はcrieitの<a href="https://crieit.net/advent-calendars/2019/crieit">なんでも Advent Calendar 2019</a>の27日目の記事です。嘘です。</p> <p><a href="https://crieit.net/posts/8fd51af2c82ad86fea6c891b4c3564f6">シモネタサイトの解説記事</a>の中で、お金出してイラストレーターさんに描いていただいた話が興味を持っていただいているみたいなので、クラウドソーシングでデザイナさんにお金を払ってなんかしてもらう系のノウハウをまとめました。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e0614e97af5d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e0614e97af5d.png?mw=700" alt="image.png" /></a></p> <h1 id="クラウドソーシング"><a href="#%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%82%BD%E3%83%BC%E3%82%B7%E3%83%B3%E3%82%B0">クラウドソーシング</a></h1> <p>クラウドソーシングって、やばいブログの記事量産とか、安すぎてブラック労働、みたいな感じで良くない印象を持たれていることも多いみたいです。<br /> 実際のところは、無数に仕事があるんだからホワイトな仕事もあればブラックな仕事もあるし、そんなの現実社会と一緒でしょ、駄目なもののほうが面白いから目立つだけじゃないの、というのが個人的な感想。</p> <p>でも仮に条件の良くない仕事がいっぱいあるのだったら、普通の条件で仕事を発注するだけでぼくらは相対的に優良な発注者ということになります。息をするだけで褒めてもらえる異世界転生の世界!</p> <h2 id="お金ないんだけど?"><a href="#%E3%81%8A%E9%87%91%E3%81%AA%E3%81%84%E3%82%93%E3%81%A0%E3%81%91%E3%81%A9%EF%BC%9F">お金ないんだけど?</a></h2> <p>いやいやそう言ってそれなりに持ってるでしょ?<del>ちょっとジャンプしてみ?</del></p> <p>例えばこれとか魔法にしか見えないじゃないですか?</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/%E6%9C%AC%E6%97%A5%E3%81%AE%E3%82%A4%E3%83%A9%E3%83%AC?src=hash&ref_src=twsrc%5Etfw">#本日のイラレ</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/Illustrator?src=hash&ref_src=twsrc%5Etfw">#Illustrator</a>七宝文様のつくりかた その2。前半の線ver.は前回のまま。後半の塗りver.をちょっと改良しました。 <a target="_blank" rel="nofollow noopener" href="https://t.co/TqTTLKzLAh">pic.twitter.com/TqTTLKzLAh</a></p>— コロ / イラレ職人 (@coro46) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/coro46/status/1157622133880545282?ref_src=twsrc%5Etfw">August 3, 2019</a></blockquote> <p>最初の頃これ見て「すげー、覚えよう!」と思っていたのですが、ある時気づきました。それってデザイナさんが『phpの文法を覚えよう』って言ってるのと一緒だよね?<br /> ぼくらにとってプログラミング言語の文法とか、エディタのショートカットは毎日使うから勝手に覚えるものであって、頑張って記憶とかしても意味ないよなーと思うじゃないですか。便利なライブラリとか、べつに意識して探さなくてもTwitterで遊んでいるうちに勝手に知識が入ってきて、必要になったら「なんかあったよね、どこだっけ」って探せば簡単に出てくるものじゃないですか。</p> <p>同じように、デザイナさんはillustratorを日々使ってるからショートカットとか勝手に覚えているし、街を歩けば「あ、七種泰史さんのフォント」みたいなことを自動的に考えちゃうものなのです。</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">これ!このセンス!ぼくら見てもなんとも思わない文字、デザイナさんが見ると「あ、あのフォントだ」って見えるの!優秀なデザイナさんはフォントいっぱい持ってて、ふさわしいフォントを選んでくれる。そうするとデザインがバシッと引き締まる! <a target="_blank" rel="nofollow noopener" href="https://t.co/mLVoN0Lrub">https://t.co/mLVoN0Lrub</a></p>— もぎゃ(daisuke furukawa) (@mogya) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/mogya/status/1167324634120740865?ref_src=twsrc%5Etfw">August 30, 2019</a></blockquote> <p>なので、Webサイトでイラストが必要とか、なんかデザインが締まらないんだけどどうしていいかわからないという時、ぼくらがillustratorでドーナツ一個書くのにも四苦八苦している状態で頑張るより、「こんな感じのイラストがほしいんです」ってお願いしてサクッとやっていただいたほうが効率的な時間の使い方なんじゃないのかなと思っています。</p> <h2 id="発注先"><a href="#%E7%99%BA%E6%B3%A8%E5%85%88">発注先</a></h2> <p> ぼくは<a target="_blank" rel="nofollow noopener" href="https://crowdworks.jp">クラウドワークス</a> を使っています。もともと<a target="_blank" rel="nofollow noopener" href="https://www.lancers.jp">ランサーズ</a>使ってたのですが、クラウドワークスのほうがいい感じで仕事してもらえることが多かったので、最近はクラウドワークスで依頼することが増えています。<br /> イラスト特化の<a target="_blank" rel="nofollow noopener" href="https://skima.jp/">SKIMA</a>というサイトもあるのですが、Webサイトの部品というよりは、壁に飾る絵描いてください、みたいな雰囲気があわなくてまだ試したことがないです。</p> <h2 id="発注内容"><a href="#%E7%99%BA%E6%B3%A8%E5%86%85%E5%AE%B9">発注内容</a></h2> <p> Webサイトに使うアイコンとか、今回のようなイラストをお願いすることが多いです。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://www.lancers.jp/work/detail/8257">地図に表示するためのアイコン画像の依頼</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://www.lancers.jp/work/detail/61584">足りないアイコンが出てきたので追加依頼</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://crowdworks.jp/public/jobs/4578221">シモネタサイトのイラスト依頼</a></li> </ul> <p>サイトまるごとデザインみたいなのは、一回お願いしたことがあったのですが、出来上がったあとで開発の方向性が間違っていることに気がついてドンガラガッシャンする羽目になるという痛い経験をしたことから、よほどサイト内容が固まって、あとはデザインを良くすれば勝てる!みたいな状態にならない限りもうやらないんじゃないかなあ。</p> <h2 id="コンペと固定報酬"><a href="#%E3%82%B3%E3%83%B3%E3%83%9A%E3%81%A8%E5%9B%BA%E5%AE%9A%E5%A0%B1%E9%85%AC">コンペと固定報酬</a></h2> <p>クラウドワークスの依頼形式は3つあって、コンペと固定報酬、時給制です。</p> <p>このうち時給制については、使ったことないのでパスします。時給制で雇って、方向性の相談から製作まで全部やっていただくのはちょっと憧れますが、だいぶ金額の大きな仕事になっちゃうので、個人開発でここまでつっこむのは難しいんじゃないかなあ</p> <p>コンペは、テーマを決めて皆様に応募してもらって、その中から一番いいものを選ぶ形式。コンペにできるものなら、コンペおすすめです。できたものを見て選べばいいので選ぶのが簡単。</p> <p>ただ応募するデザイナさんの立場に立つと、応募して選ばれないと一円ももらえないので、あんまり大規模な仕事をコンペにすると、やってられまへんわということになって応募してもらえなくなります。そういう仕事は固定報酬にすることになると思います。</p> <p>ぼくは基本コンペでお願いして、その人がよかったら、追加発注とか、同様にお願いできそうな仕事のときは固定報酬で同じ人にお願いするようにしています。いい人がいたらずっと固定の依頼になりそうなものなのですが、そんなに頻繁に依頼するわけじゃないので、「前回依頼していたあの人」と思ったら退会していて連絡がつかなくなることがよくありますw</p> <p>あと、個人的にオススメのやり方。イラスト5点とかお願いするときに「一点だけ作って応募してください。選ばれたら、残りも制作して納品をお願いします」というスタイルにすると、ぼくはコンペ形式で選ぶのが楽だし、デザイナさんも、5点作ってコンペ負けして一円にもならない、みたいな悲劇を回避することができます。過去何回か試して好評頂いているので、よかったら試してみてください</p> <h2 id="金額の決め方"><a href="#%E9%87%91%E9%A1%8D%E3%81%AE%E6%B1%BA%E3%82%81%E6%96%B9">金額の決め方</a></h2> <p>金額は、類似の依頼を見て決めます。<br /> <a target="_blank" rel="nofollow noopener" href="https://crowdworks.jp/public/jobs?category=jobs&order=score&ref=mypage_nav1">検索ページ</a>から今出てる依頼を検索できるので、「この金額なら応募が殺到する」「この金額なら応募は来ない」というのがわかります。<br /> ぶっちゃけ応募が殺到すると見るだけでも手間がかかるので、倍のお値段でいい仕事してもらおう、みたいなやり方はあんまおすすめできません。優秀なデザイナさんの成果に報いるのは、二回目以降の固定依頼の時がいいんじゃないかと思います。</p> <h2 id="人を集める"><a href="#%E4%BA%BA%E3%82%92%E9%9B%86%E3%82%81%E3%82%8B">人を集める</a></h2> <p>クラウドワークスには、デザイナさんに対して「みてみて」って通知を送る機能があります。<br /> クリック一つで送ることができて、一つのお仕事に付き20人まで送ることができるので、「あれ?意外と集まらない?」と思ったときのブーストに使うのがいいかと思います。<br /> 「昔やってたけどもうクラウドソーシングは受けてないんです」みたいな人は通知を送っても見てもらえないので、狙い目はクラウドワークスに登録したばっかりの人です。<br /> 「イラスト」とかのキーワードで検索して、新着順でソートします。ざっと見て問題のなさそうな人片っ端から「みてみて」を押していきましょう。大丈夫。クラウドワークスに登録したばっかりの人でも、ぼくらが自分でやるよりはるかに優秀な人ばっかりです。</p> <p>あと、週末デザイナー(平日会社員)という方が結構いるので、「応募ない?」と思っても土日は様子見るのもいいと思います</p> <h1 id="気持ちよくお仕事をしていただくために"><a href="#%E6%B0%97%E6%8C%81%E3%81%A1%E3%82%88%E3%81%8F%E3%81%8A%E4%BB%95%E4%BA%8B%E3%82%92%E3%81%97%E3%81%A6%E3%81%84%E3%81%9F%E3%81%A0%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AB">気持ちよくお仕事をしていただくために</a></h1> <h2 id="直し"><a href="#%E7%9B%B4%E3%81%97">直し</a></h2> <p>デザイン作っていただいたあとで、「やっぱこうしてほしいです」「違うデザインで」みたいなことを言うのを「直し」といいます。プログラマならこういうの嫌いなのはわかりますよね。<br /> とはいえ全く直さないと意図したものがもらえないので、どのくらい直してもらうつもりか明記しておくと良さそうです。</p> <p>「ラフ提出→承認→制作→直し(一回まで)」だとわりと受け入れてもらいやすいと思います。</p> <p>(ラフ: 色塗りとかレイヤー整理とか時間のかかるところはやってないけど、だいたい方向性の分かる程度のデザイン)</p> <p>最近は慣れてきたので、「ラフ提出→承認→制作→直しなし」で依頼することも多いです。細かいところはデザイナさんを信じる!</p> <h2 id="用途について"><a href="#%E7%94%A8%E9%80%94%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">用途について</a></h2> <p>プログラマの場合、勤務時間中に書いたコードは納品先のもので、そのあと何しようがお客さんの勝手という契約が一般的ですが、デザイナさんの世界では、デザインというのは用途を指定して発注することになっています。例えば「このチラシで使います」って発注した場合、他のチラシに転用したり、webサイトに使うのはNGです。</p> <p>この辺の説明がわかりやすい。<br /> <a target="_blank" rel="nofollow noopener" href="https://www.ddc.co.jp/%E3%83%95%E3%83%AC%E3%83%83%E3%82%B7%E3%83%A5%E3%83%97%E3%83%AA%E3%83%B3%E3%83%88/%E5%8D%B0%E5%88%B7%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E8%91%97%E4%BD%9C%E6%A8%A9%E3%83%BB%E7%89%88%E6%A8%A9.html">印刷デザインのデータの著作権(版権)は誰のもの?</a></p> <p>業界の慣習は尊重したいのですが、ぶっちゃけ個人開発においてこれは非現実的です。挿絵として依頼した画像だけどいい感じだったのでfaviconにも使いたいとか普通にあるし、ぶっちゃけ便利な画像があれば別のサイトでも使いたいでしょ?何年かたって元の絵を描いたデザイナさんに連絡がつくとも限らないですし。</p> <p>そういうことに配慮したのか、クラウドワークスでは(ランサーズも)、利用規約で著作権の譲渡が定められています。<br /> つまり、デザインで一般的な考え方ではなくて、素人が思う「作ってもらったものはオレのもの理論」が通るということです。</p> <p>とはいえ相手の商習慣に配慮しておいたほうが気持ちよく仕事していただけるのは確かなので、一言書いておくと、「あ、配慮してくれてるんだなあ」と思ってもらえるかもしれません。</p> <blockquote> <p>クラウドワークスの利用規約では、取引完了した段階で著作権はクライアントに移転・帰属する事になっています( https://crowdworks.jp/pages/agreement.html )<br /> これを前提に、納品していただいた画像等は無断で適宜編集して他の用途に使う可能性があるので予めご了承ください</p> </blockquote> <p>あと、著作権を譲渡してもらうと、制作物はぼくらの物になって、デザイナさん自身がポートフォリオに載せるにも許可が必要になってしまいます。ぼくらそんなことは望んでいないと思うので、ここも一言書いておいてあげると、ちょっと恩を売れるかなと思います😜</p> <blockquote> <p>ただし、納品していただいた画像をデザイナさんが別の用途に使うことは全く制限しません。他の仕事に使ったり、ポートフォリオに掲載したり、自由に使ってもらって大丈夫です</p> </blockquote> <h2 id="謝辞について"><a href="#%E8%AC%9D%E8%BE%9E%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">謝辞について</a></h2> <p>あんま関係ないような気がするのですが、一応毎回、謝辞載せて宣伝に協力しますよということを書くようにしています。</p> <blockquote> <p>もし希望があれば「アイコンはこの人に作っていただきました」みたいな感じで、ブログやサイトなどで謝辞つけます!</p> </blockquote> <h2 id="アウトプット形式について"><a href="#%E3%82%A2%E3%82%A6%E3%83%88%E3%83%97%E3%83%83%E3%83%88%E5%BD%A2%E5%BC%8F%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">アウトプット形式について</a></h2> <p>サイトのデザインが変わったとき、イラストのサイズを変えたり、ちょっと他のところに転用したりしたい、ということを考えると、あとで変更が効くフォーマットでもらっておくと便利です。<br /> illustratorが使える人は、レイヤー分けされたaiでもらっておくと、背景を消してオブジェクトだけ取り出したり、サイズを変えて任意のサイズで取り出したりできるようになります。<br /> Adobe税が払えない方は、svgにしておくとサイズ変更できるので、比較的扱いやすいかと思います。</p> <p>※ この間仕事お願いしたデザイナーさんは、何も聞かずにpngとjpegとsvgとaiをアップロードしてくれて、「こいつ...デキる!」って思いましたw</p> <blockquote> <p>30px-400pxくらいの任意のサイズでアイコンを作れるように、svg形式での納品をお願いします。コンペ時点ではpngやjpegで大丈夫です</p> </blockquote> <h2 id="イメージの伝え方"><a href="#%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%81%AE%E4%BC%9D%E3%81%88%E6%96%B9">イメージの伝え方</a></h2> <p>クラウドソーシングサイトでは、標準テンプレートみたいなのを使ってイラストのイメージを伝えるように誘導してきます。<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e060bcd09382.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5e060bcd09382.png?mw=700" alt="image.png" /></a></p> <p>でもまあ、こんなんで伝わるんだったら苦労しないよね。</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.irasutoya.com/">いらすとや</a>さんの画像とかを使ってとりあえず仮で作っちゃって、このサイトのここに使う画像がほしい! ってお願いするか、どこか別のサイトを示して、「こんな感じのがほしいと思っています」って言ったほうが早い気がしています。</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15608 2019-12-15T08:56:58+09:00 2019-12-16T09:00:03+09:00 https://crieit.net/posts/8fd51af2c82ad86fea6c891b4c3564f6 シモネタサイトを全力で作ったよ <p>この記事は<a target="_blank" rel="nofollow noopener" href="https://qiita.com/advent-calendar/2019/kuso-app2">クソアプリ2 Advent Calendar 2019</a> 15日目の記事です。14日目は<a target="_blank" rel="nofollow noopener" href="https://twitter.com/endo_hizumi">endo_hizumi</a>さんの「<a target="_blank" rel="nofollow noopener" href="https://qiita.com/endo_hizumi/items/2de99fafa424e04b4375">お前らのクソアプリは間違えてる</a>」。わーい!寿司が回ってるよ!ぼくの思ってた廻る寿司となんか違う!</p> <h1 id="クソアプリが作れない"><a href="#%E3%82%AF%E3%82%BD%E3%82%A2%E3%83%97%E3%83%AA%E3%81%8C%E4%BD%9C%E3%82%8C%E3%81%AA%E3%81%84">クソアプリが作れない</a></h1> <p>ということで、年末のお祭りを名目に、肩の力を抜いてなんでも公開するといいよ!という趣旨のクソアプリカレンダー、ずっと眺めていたのですが、なかなか参加できなかったのですよね。あっという間にうまるのもあるけど、それ以上に、自分マジメなので、そういうのを作るのが苦手なのです。</p> <p>どれくらいマジメかというと、中学高校と学級委員長を歴任していました。委員長は何がいいかというと、委員長という役割をしておけば、クラスのなかに居場所がなくなることがないのですよね!</p> <p>そんな人間にクソアプリを作れだと?無理に決まっている。予約日が15日なのに一週間も前に完成させて<a target="_blank" rel="nofollow noopener" href="https://blog.nabettu.com/entry/bugbash">バグバッシュ</a>しちゃったじゃないか!</p> <h1 id="誰でもできるクソアプリ"><a href="#%E8%AA%B0%E3%81%A7%E3%82%82%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%AF%E3%82%BD%E3%82%A2%E3%83%97%E3%83%AA">誰でもできるクソアプリ</a></h1> <p>こうなることはわかっていたので、対策を立てておきました。出来栄えがクソなんじゃなくて、ネタがクソならクソアプリ。小学生のごとくウンコとかオシッコとか言っておけばなにを作ってもクソアプリになるに違いない!</p> <p>【警告】 以降、<strong>全力でシモネタ</strong>です。そういうのがお好きでない方はこれ以上読まないことをおすすめします。</p> <p><img src="https://placehold.jp/50x300.png" alt="空白" /></p> <p>(警告したからね?もう遠慮しないよ!?)</p> <p><img src="https://placehold.jp/50x300.png" alt="空白" /></p> <p>というわけで作りました。</p> <h1 id="ギガントおちんちんランキング"><a href="#%E3%82%AE%E3%82%AC%E3%83%B3%E3%83%88%E3%81%8A%E3%81%A1%E3%82%93%E3%81%A1%E3%82%93%E3%83%A9%E3%83%B3%E3%82%AD%E3%83%B3%E3%82%B0">ギガントおちんちんランキング</a></h1> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5df44bceb3d25.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5df44bceb3d25.png?mw=700" alt="image.png" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://mogya.github.io/ochinRank/">ギガントおちんちんランキング</a>🎉</p> <p>おちんちんの太さを測って入力すると、日本で何番目くらいの太さなのかわかります。<br /> <strong>もちろん</strong>結果をTwitterでシェアしてみんなに自慢することが出来ます。</p> <h1 id="なんで太さ?"><a href="#%E3%81%AA%E3%82%93%E3%81%A7%E5%A4%AA%E3%81%95%EF%BC%9F">なんで太さ?</a></h1> <p>いにしえの昔、<a target="_blank" rel="nofollow noopener" href="http://pandora.nu/pha/ochinchin/">ハイパーオチンチンランキング</a> というサイトがあったのです。<br /> おちんちんの長さを入力すると順位を調べてくれるこのサイト、それはもうバズりました。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5df44e0e9b814.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5df44e0e9b814.png?mw=700" alt="image.png" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://b.hatena.ne.jp/entry/pandora.nu/pha/ochinchin/">https://b.hatena.ne.jp/entry/pandora.nu/pha/ochinchin/</a></p> <p>しかし、このサイトが登場したその当時、SNSは今ほど一般的ではなくて、どんなサイトでもtwitterシェアボタンがあるのが当たり前という時代ではなかったのです。</p> <p>これだけ面白いサイトが!ここにシェアボタンがあれば!絶対バズるのに!</p> <p>何回か持論を展開したのですが、みんなおもしろネタとして受け取るばっかりで作る人がいないので自分で作ることにしました。</p> <p>リスペクト的な意味を込めて、長さじゃなくて太さにしてあります。</p> <h1 id="技術的な話"><a href="#%E6%8A%80%E8%A1%93%E7%9A%84%E3%81%AA%E8%A9%B1">技術的な話</a></h1> <p>大前提として、このサイトを<strong>いつまでもメンテしたくない</strong>というのがあります。今クソアプリ用のテンションで吹っ切れてるからおちんちんとか平気で書いているけど、年が明けてこれのメンテナンスを継続する自信はない。おちんちんのことは完全に忘れて次のサービスに取り掛かりたい。</p> <p>自前サーバに載せてなんかの弾みにうっかり消して「もぎゃさん、おちんちんが落ちてるんですけど?」とかいうメンションをもらったりしたら、確実にそんなサイトはなかったことにしてしまう気がします。</p> <p>だからといってFirebaseみたいなのも、お財布に火が付きそうで怖い。</p> <p>放っておいたらいつまでも維持されて、アクセス従量課金じゃないサーバ。</p> <p>あります。<a target="_blank" rel="nofollow noopener" href="https://pages.github.com/">Github pages</a>です。Githubのアカウントさえあれば無料で使えて、リポジトリを消さない限り維持される、高負荷でもそうそう落ちたりしない、理想のサーバ!</p> <p>Github Pagesは静的サイトしか保持してくれないので、開発言語はJS<br /> しかありえない。去年作った<a target="_blank" rel="nofollow noopener" href="https://github.com/mogya/qiitaRank">qiitaRank</a> では、index.htmlにvue.jsをscriptタグで取り込む簡単実装だったので、これをコピペしてサクッと作りました。</p> <h2 id="OGP問題"><a href="#OGP%E5%95%8F%E9%A1%8C">OGP問題</a></h2> <p>Twitterシェアが命のサービスなので、シェアしたときの見た目が大事です。くすっと笑ってぼくも使ってみようと思えるサイトでないといけない。そのためにはOGP画像が必須ですが、Twitterのクローラーはそんなに賢くないので、JSで生成した動的画像をOGPとして使うことが出来ません。<br /> かといってSSRみたいな高度なことをするためにはホストするサーバが必要、CircleCIで頑張る...うー、めんどくさいな。</p> <p>3日くらい考えてひらめきました。「そもそも動的である必要はないよね」</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/mogya/ochinRank/tree/master/static">ソースコード</a>見ていただくとわかりますが、結果ページは独立したHTMLファイルになっています。結果ページの役割は、TwitterにOGP画像を返すこと。人間がアクセスしてきたらトップページにリダイレクトさせます。</p> <pre><code><meta property="og:image" content="https://mogya.github.io/ochinRank/img/cannon_ogp.png" /> <meta property="og:description" content="あなたの太さはどれくらい?全国平均どれくらいなのか見てみよう!" /> <meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:site:id" content="mogya" /> <title>ギガントおちんちんランキング</title> </head> <body> <script> window.location.href = './' </script> </body> </html> </code></pre> <p>違いはOBP画像だけなんだから、nuxt.jsみたいなの使えば生成できそうですが、意識低く、結果と同じだけのHTMLファイルをそのまま保持しています。</p> <p>あとはindex.htmlで、結果に応じてシェアするURLを分けてあげれば出来上がりです。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5df45a1ddac79.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5df45a1ddac79.png?mw=700" alt="image.png" /></a></p> <h2 id="IE対策"><a href="#IE%E5%AF%BE%E7%AD%96">IE対策</a></h2> <p>サイトの趣旨がとてもオチンチンなので、エンジニアではない方がアクセスすることを想定する必要があります。IEで開くと...動かん。</p> <p>Vue.jsのコードは近代的なブラウザを前提にしているので、IEで動かすのは難しいのです。<a target="_blank" rel="nofollow noopener" href="https://polyfill.io/v3/">Polyfill.io</a>入れたら動くんでしょ?と思っていたのですが、scriptタグで取り込むvue.jsは、script部分で新しい記法(テンプレートリテラルとか)をつい使っちゃうので、かなり無理があります。</p> <p>しばらく頑張ったのですが、どうにもならんので、さっき回避したはずのNuxt.jsを入れてgenerateモードでページを生成してもらうことにしました。このやり方ならbabelがIEの差異を吸収したページを生成してくれるので、IEでも動かすことが出来ます。</p> <h2 id="Nuxt.js on Github pages"><a href="#Nuxt.js+on+Github+pages">Nuxt.js on Github pages</a></h2> <p>Nuxt.jsで生成したページをGithub pagesで動かす方法は<a target="_blank" rel="nofollow noopener" href="https://ja.nuxtjs.org/faq/github-pages/">ここ</a>に載っています(vue.js周りのドキュメント充実度すごいよね)</p> <p>簡単にいうと、URLがexample.com/_nuxt/hoge.js みたいなんじゃなくて https://mogya.github.io/ochinRank/ という具合にサブディレクトリになるので、それを考慮したHTMLが生成されるように設定する必要があります。</p> <pre><code>export default { router: { base: '/<repository-name>/' } } </code></pre> <p>あと、github pagesは基本レポジトリにあげたコードを全部公開してしまいます。generateしたファイルだけ公開するために、「masterブランチのdocsディレクトリ下だけを公開」モードを使うことにしました。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5df4580c9685d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5df4580c9685d.png?mw=700" alt="image.png" /></a></p> <p>nuxt.config.jsの設定を変更して、distの代わりにdocsディレクトリにHTMLを生成するようにします。</p> <pre><code>export default { generate: { dir: 'docs' }, </code></pre> <p>docsディレクトリはそんな使い方をするものじゃない?クソアプリだからね。</p> <h1 id="シモネタライセンス問題"><a href="#%E3%82%B7%E3%83%A2%E3%83%8D%E3%82%BF%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9%E5%95%8F%E9%A1%8C">シモネタライセンス問題</a></h1> <h2 id="いらすとやライセンス"><a href="#%E3%81%84%E3%82%89%E3%81%99%E3%81%A8%E3%82%84%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9">いらすとやライセンス</a></h2> <p>当初このサイト、イラストは安定の<a target="_blank" rel="nofollow noopener" href="https://www.irasutoya.com/">いらすとや</a> を使わせていただく予定でした。自由に使えてなんでも揃ってるぼくらの素材サイト。くすっと笑うのにトーンもあってるよね。しかし。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5df45b1c85a78.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5df45b1c85a78.png?mw=700" alt="image.png" /></a></p> <p><strong>ですよね</strong>。おちんちんランキングはジョークサイトであってアダルトサイトじゃないと思っているのですが、こういうのは結局の所いらすとやさんがどう受け止めるかの問題になってしまいます。<br /> いらすとやさんがあれだけ寛容な条件を用意してくれているのに、「ぼくはアダルトサイトじゃないと思いました」っていう名目で利用を強行して炎上したりすると、いらすとやさんにご迷惑がかかりそう。</p> <p>ということでお金出してイラストレーターさんに描いてもらいました。クソアプリなのに!<br /> <a target="_blank" rel="nofollow noopener" href="https://crowdworks.jp/public/jobs/4578221">【一点で応募可能】 Twitterのシェア用画像5点の依頼/外注|イラスト作成の仕事</a></p> <p>でもおかげでなかなかいいデザインになったと思います。太さに応じてTwitterシェアしたときの画像が変わるようになっているので、ぜひシェアして見てくださいね。</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15575 2019-12-02T14:49:05+09:00 2019-12-03T19:54:02+09:00 https://crieit.net/posts/5c01a10cb115b3b30aa9ae8b4378bf3d スタバハック <p>午前中はだいたいスタバでコード書いている。<br /> 前の日のうちにやること決めておいて、午前中に成果を出しておけば、午後は心穏やかに過ごせるのがいいですね。</p> <p>ということで2ヶ月位通ってみてわかった、スタバでコード書いて成果を出すためのノウハウです。</p> <h1 id="[困] スタバ怖い"><a href="#%5B%E5%9B%B0%5D+%E3%82%B9%E3%82%BF%E3%83%90%E6%80%96%E3%81%84">[困] スタバ怖い</a></h1> <p> スタバ恐怖症の人が結構いて、呪文怖い/何を頼んでいいかわからないのと、店員さんに話しかけられるのが苦手、の2パターンあるようです。</p> <p>最短注文メソッドがこちら</p> <p>「本日のコーヒー、ホットのトールサイズ、マグカップで」</p> <p>本日のコーヒーは、ぼくらみたいに「ぶっちゃけなんでもいい」というお客さんのためにスタンバイしているコーヒーで、お手頃価格ですぐ出てくるという、いちばん大事な特徴を抑えています。<br /> 日々変わるので、好みじゃない味の日もありますが、コーヒーなんて場所代なんだから、苦かろうが酸っぱかろうがそんなことは些細な問題ですよね。</p> <p>トールサイズは、飲み物のサイズです。スタバ独特なサイズの呼び方、苦手な人が多いと思うのですが、全部覚える必要はありません。トールサイズだけ覚えておけばOK。<br /> それすら出てこないときは「一番大きいので」という逃げ道もあります。</p> <p>マグカップは、店内用のマグカップか、紙コップに入れてもらうかの選択です。聞かれて応答すると時間の無駄なので呪文として覚えましょう。</p> <p>紙コップにしてもらうと途中で退店することにしたとき便利なので、先日まで紙コップがおすすめだったのですが、公明党が軽減成立なんて余計なことを考えついた結果、スタバの店員さんは持ち帰りと店内飲食を確認しないといけなくなったので、紙コップと言うと「店内ご利用ですか?」「はい」という余計な会話をしないといけなくなりました。<br /> これを避けるため、マグカップで注文します。これは持って帰れないので、会話を一個減らすことが出来ます。</p> <p>ということでもう一回。</p> <p>「本日のコーヒー、ホットのトールサイズ、マグカップで」</p> <p>これでお金払ったらすぐ飲み物を持って席に逃げることが出来ます。パソコンでTwitter開けばぼくらの世界。もう恐れるものはなにもない!</p> <h1 id="[困]コーヒー苦手"><a href="#%5B%E5%9B%B0%5D%E3%82%B3%E3%83%BC%E3%83%92%E3%83%BC%E8%8B%A6%E6%89%8B">[困]コーヒー苦手</a></h1> <p>勘違いしている方が多いのですが、スタバはコードを書くための場所です(断言)<br /> コーヒーを飲みたい方とか、出勤前に買っていく方とかもいますが、あれはスタバが経営を安定させるためにやってることであって、本来スタバはコードを書くための場所なのです(二回目)</p> <p>なので、実はスタバにはコーヒーじゃないものも結構あります。</p> <p>問題なのは、下手なものを頼むと注文時間が長くなってMPが減ることです。おしゃれなサイトで紹介されているナントカフラペチーノとか頼むと、受け取りカウンターで待たされるので、これは避けたい。本日のコーヒーなみに早く出てくるコーヒー以外のメニュー...</p> <p>あります。紅茶です。紅茶はカップにお湯入れてティーバック入れるだけの簡単作業なので、これもレジでそのまま出してくれます。<br /> 紅茶専門店みたいにちゃんと淹れたものじゃないですが、ぶっちゃけぼくらにとって飲み物は場所代なので(ry</p> <p>紅茶メニューがここにあるので、スタバの常連になったら、一個覚えておくといいかもしれません。<br /> <a target="_blank" rel="nofollow noopener" href="https://www.starbucks.co.jp/beverage/#beverage_tea">https://www.starbucks.co.jp/beverage/#beverage_tea</a></p> <p>ほうじ茶とか覚えやすくておすすめです。</p> <h1 id="[困] Wi-Fiが切れる"><a href="#%5B%E5%9B%B0%5D+Wi-Fi%E3%81%8C%E5%88%87%E3%82%8C%E3%82%8B">[困] Wi-Fiが切れる</a></h1> <p>スタバのWi-Fiはチェーン系の中で安定して動くほうだと思うのですが、一時間に一回利用規約に同意しないといけないので、そのタイミングで一回切れてしまいます。<br /> で、再開しようと思うと、一回Wi-Fiを切ってつなぎ直して集中力が...</p> <p>このURLをブックマークに入れておくと、その場で接続画面が出てくるのですんなりつなぎ直すことが出来ます。</p> <p><a target="_blank" rel="nofollow noopener" href="http://connectivitycheck.gstatic.com/generate_204">WiFi接続</a></p> <p>AndroidスマホがWi-Fiの動作確認のためにつなぐGoogleのページです。中途半端なサイトをつかうと、HTTPS警告が出てきたりして苦労することが多いのですが、このURLはまさに接続確認のために作られているので、確実にログイン画面が出てきます。</p> <h1 id="[おまけ] バターミルクビスケット"><a href="#%5B%E3%81%8A%E3%81%BE%E3%81%91%5D+%E3%83%90%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%AB%E3%82%AF%E3%83%93%E3%82%B9%E3%82%B1%E3%83%83%E3%83%88">[おまけ] バターミルクビスケット</a></h1> <p>スタバの食べ物は全体に高いのであんまおすすめしないのですが、小腹がすいたときはこれがおすすめです。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de4a1443f48c.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de4a1443f48c.png?mw=700" alt="image.png" /></a></p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">スタバのバターミルクビスケットが美味しい。自慢の水蒸気トースターが威力を発揮する( ・ิω・ิ) <a target="_blank" rel="nofollow noopener" href="https://t.co/lgVN9D8AKo">pic.twitter.com/lgVN9D8AKo</a></p>— もぎゃ🔌(daisuke furukawa) (@mogya) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/mogya/status/1189859778379386886?ref_src=twsrc%5Etfw">October 31, 2019</a></blockquote> daisuke furukawa tag:crieit.net,2005:PublicArticle/15571 2019-12-01T11:37:30+09:00 2019-12-01T14:03:53+09:00 https://crieit.net/posts/200L マンションベランダに200Lの水槽を作った話 <p>この記事は、<a target="_blank" rel="nofollow noopener" href="https://adventar.org/calendars/4209">farmtory Advent Calendar 2019</a> の初日です。</p> <p>夏の趣味として水耕栽培でミニトマトを作るというのをやっていて、その縁で<a target="_blank" rel="nofollow noopener" href="https://note.com/murasaki/m/meffc4264a313">farmtory-lab</a> というのに誘ってもらいました。衣食住を実現する小さな工場を作る、身の回りで使うものを自分で作る、といったテーマで、レーザーカッターや3Dプリンタはもちろん、ぼくには説明もできないような奇想天外な道具を使いこなして、食べ物はもちろん、服とかキーボードとか家とかお茶とか作っている人たちです。</p> <p>正直自分はそこまでガチじゃないのですが、レーザーカッターとか好きだし、farmtoryの概念は好きだし、なにより advent calendarが空いていたのでw ぼくがやっている水耕栽培の話をさせてください。</p> <h1 id="2018年の水耕栽培"><a href="#2018%E5%B9%B4%E3%81%AE%E6%B0%B4%E8%80%95%E6%A0%BD%E5%9F%B9">2018年の水耕栽培</a></h1> <p>2018年は、それ以前から続く大型化の流れを受けて、水タンクと栽培槽に衣装ケースを使って、1本のトマトから150個の収穫を実現しました。<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de3267ce9d54.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de3267ce9d54.png?mw=700" alt="image.png" /></a></p> <p>衣装ケースは、サイズとしてはいい感じだったのですが、紫外線で劣化してある日突然崩壊するという弱点がありました。これがなかったら夏後半もっと収穫できたはず...<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de31ebd498c4.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de31ebd498c4.png?mw=700" alt="image.png" /></a></p> <p>あと、栽培容器としては深すぎて、ポンプで循環させていても思ったほど養液が移動していなかったのではないか?という感触がありました。<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de31e97081de.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de31e97081de.png?mw=700" alt="image.png" /></a></p> <h1 id="2019年の水耕栽培"><a href="#2019%E5%B9%B4%E3%81%AE%E6%B0%B4%E8%80%95%E6%A0%BD%E5%9F%B9">2019年の水耕栽培</a></h1> <p>これを踏まえて、2019年はこんなふうに考えました</p> <ul> <li>栽培容器に深さは必要でないけど、紫外線で劣化しない何か他の容器を見つけてくる必要がある</li> <li>水タンクは、引き続き大容量化したい。去年は茨城県の庭で水道が使えたけど、今年はホースで水を引っ張るので、大容量タンクがないと毎日水を運ぶのが大変。</li> </ul> <p>衣装ケースより大きくて、プラスチック以外の素材できていて、安価に手に入るもの...</p> <p>世間的に事例を見ていると、スタイロフォームや角材を使って自作する人が多いようです。しかしそういう素材は大きく重いので、都会で車なしベランダ水耕栽培という成約でやっているうちには適さないのです...</p> <p>プロには専用の容器があるのですが、こんなものを自宅で受け取って、ベランダに通じる窓を通せるとは思えません...</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de326a5e2430.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de326a5e2430.png?mw=700" alt="image.png" /></a><a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/dp/B004OCSF6G/ref=cm_sw_r_tw_dp_U_x_4BY4Db41NFDM4">スイコー ホームローリータンク 200L (レモン)</a></p> <h1 id="栽培容器を作ろう"><a href="#%E6%A0%BD%E5%9F%B9%E5%AE%B9%E5%99%A8%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86">栽培容器を作ろう</a></h1> <p>ということで見つけてきたのがこちら。<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0f308694c2.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0f308694c2.png?mw=700" alt="image.png" /></a><br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0f6481a235.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0f6481a235.png?mw=700" alt="image.png" /></a> (<a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/dp/B001KWH8QQ/ref=cm_sw_r_tw_dp_U_x_eyp4DbB9QAHP3">特大ポリ袋</a>)</p> <p>ワイヤーラティスで枠を作って、袋貼れば水を貯められるだろ、という作戦です。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0f5cc2d963.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0f5cc2d963.png?mw=700" alt="image.png" /></a></p> <p>適当にワイヤーを曲げて針金でつないで、車の遮光用シート(100均)の上から袋はって出来上がりです。これだと光が差し込んで水が濁ってしまうので、さらにぐるっと遮光シートで覆います。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0fea787e14.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0fea787e14.png?mw=700" alt="image.png" /></a></p> <p>棺桶っぽい...</p> <h1 id="水槽を作ろう"><a href="#%E6%B0%B4%E6%A7%BD%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86">水槽を作ろう</a></h1> <p>最近の水耕栽培は、トマトが根を張る栽培槽の他に、養液を貯めておくタンクを別に設置してポンプで回すことにしています。<br /> トマトがどれだけ根を張るかで収穫が左右されるので、できる限り根を張るスペースを確保したい、そのためには可能な限り大きな容器が望ましい。<br /> そして大きく根を張ったトマトはとんでもない量の水を消費するので、その消費に耐えられるサイズのタンクも必要になります。</p> <p>経験的に夏最盛期の水消費量は20L/日。20Lのタンクだと1日たりとも給水を休めない(=旅行が許されない)ことになるので、手間を考えると一週間、140Lはほしいところです。</p> <p>ワイヤーラティス作戦で行くとしても、140Lの水を貯めておける袋が必要になります。そんなもの...あったw</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de3255ab5e7e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de3255ab5e7e.png?mw=700" alt="image.png" /></a><br /> <a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/gp/product/B000TGFEII/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1">タンスも入る超特大ポリ袋</a></p> <p>一枚1700円と決して安くはないですが、<a target="_blank" rel="nofollow noopener" href="https://www.amazon.co.jp/dp/B004OCQU6S/ref=cm_sw_r_tw_dp_U_x_VIp4DbNT9Z2W2">農業用タンク</a> をベランダに搬入するよりはずっと現実的です。</p> <p>ラティスを針金で止めて枠を作って</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0ff1aeb0d9.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0ff1aeb0d9.png?mw=700" alt="image.png" /></a></p> <p>内側にプラダン、外から遮光シートを貼り付けます(プラダンがないと、袋が網目に押し付けられることになっちゃうので、たぶんそこから破けちゃうというアドバイスを頂きました)</p> <p>そんなこんなで出来上がった水槽がこちら。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0f5383daca.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0f5383daca.png?mw=700" alt="image.png" /></a></p> <p>2m×40cm×40cm、貯水容量はなんと200L。二週間近く耐えられる安心仕様!<br /> ここからポンプで水を汲み上げて、栽培槽に給水。栽培槽でトマトが飲みきれなかった分は下から養液層に戻るようになっています。去年より薄くて養液が行き渡りやすくなりましたが、根を張るスペース自体は十分に確保されているはずです。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0f94e7ec15.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0f94e7ec15.png?mw=700" alt="image.png" /></a></p> <h1 id="運用"><a href="#%E9%81%8B%E7%94%A8">運用</a></h1> <p>で、水を入れてみた写真がこちら</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de3265db26b2.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de3265db26b2.png?mw=700" alt="image.png" /></a></p> <p>やばいw</p> <p>明らかに水圧で歪んでます。とは言え夏も近づき、新作を作っている暇はなさそう。仕方がないので、半分のまでしか水を入れない安全運転にすることにしました。</p> <h1 id="成果"><a href="#%E6%88%90%E6%9E%9C">成果</a></h1> <p>収穫数は、去年を大きく上回る433個に達しました。大型化させて栽培槽を薄くする作戦がうまくいったのかなと思っています。<br /> ただ、(写真撮り忘れたのだけど!)終盤にあけてみると、幅いっぱいに根が張る一方、末端の方は届かなかったみたいなので、来年は深さと長さ維持、より幅広で作ってみるのがいいのかなと考えています。</p> <p>惜しむらくは、8月の末にポンプが故障して、その事に気づかないまま一週間以上が経過してしまった結果、樹がすっかり傷んでしまって、9月の残暑に収穫ができなくなってしまったことです。あれがなかったら500個いけたのに...</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de3206a7e661.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de3206a7e661.png?mw=700" alt="image.png" /></a></p> <p>IoT監視は後回しにしていたのですが、さすがにそろそろ考えたほうが良さそう。</p> <h1 id="2020年の計画"><a href="#2020%E5%B9%B4%E3%81%AE%E8%A8%88%E7%94%BB">2020年の計画</a></h1> <p>プロから見るとびっくり安価な素材で作った水槽なのですが、意外と行けるので、補強して来年も使おうと思っています。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0fcb30074d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0fcb30074d.png?mw=700" alt="image.png" /></a><br /> アングル材で補強してあげれば、水圧にも耐えられるはず。</p> <p>でもって、作り直した栽培槽をアングルの上に配置すれば、2階建てでかっこよさそう。<br /> <a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0fd9bd6c32.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de0fd9bd6c32.png?mw=700" alt="image.png" /></a></p> <p>あと、野放図にトマトを伸ばした結果、ベランダから溢れ出して下の階にご迷惑おかけしそうだったので、慌てて引っ張り上げることになったので、ここはなんか考えないといけません。<br /> プロだと、庭の真ん中に作って東屋みたいに育てるのが主流なのですが、</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de3262c4da9e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5de3262c4da9e.png?mw=700" alt="image.png" /></a>(<a target="_blank" rel="nofollow noopener" href="http://suikouqa.blog.fc2.com/blog-entry-338.html">農業用栽培槽で自作水耕 配管について2</a>)</p> <p>ベランダは前からしか日が差さないので、栽培可能な体積が限られるのですよね。どんな棚を作ればいいのか、考えているところです。</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15515 2019-10-29T17:42:48+09:00 2019-10-29T17:45:13+09:00 https://crieit.net/posts/systemd-timer systemd/timerを使ってサーバを毎晩リブートさせる <p>サーバを定期的に再起動したいという需要は常に存在します。</p> <p>どっかの誰かが開放し忘れたコードにより徐々に減っていく空きメモリ。原因を追求するより、定期的に再起動しちゃえば一発解決だよね🧙</p> <p>なんか時々落ちるこのサービス、いっそ定期的にサーバを再起動しておけば、たとえ落ちたとしても復活するから、大体の時間は動いてるサービスにできるんじゃないの?😈</p> <p>いいことか悪いことか、かっこいいかどうかはともかくとして、定期的にサーバを再起動しておけば解決できるある種の問題が存在することは事実です。問題の先送りだって一つの技術力ですし(後ろめたいときって前置きが長くなるよね)</p> <p>ともかくそういうわけで何らかの理由でサーバを定期的に再起動させたいときの設定です。</p> <p>CentOS7から標準になったSystemdのTimer機能を使います</p> <h1 id="serviceの作成と登録"><a href="#service%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%A8%E7%99%BB%E9%8C%B2">serviceの作成と登録</a></h1> <pre><code class="shell-session">$ sudo nano /etc/systemd/system/reboot.service </code></pre> <pre><code class="config">[Unit] Description=Scheduled Reboot [Service] Type=simple ExecStart=/usr/bin/systemctl --force reboot </code></pre> <p>こうやって出来たserviceファイルを</p> <pre><code class="console">sudo systemctl enable reboot </code></pre> <p>で登録します。</p> <p>この段階で、</p> <pre><code class="console">sudo systemctl start reboot </code></pre> <p>ってたたいてあげると、サーバが予告なく再起動するかと思います。</p> <p>Q: rebootコマンドじゃないの?<br /> A: rebootとかhaltはCentOS7から非推奨になりました<br /> <a target="_blank" rel="nofollow noopener" href="https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-power">10.4. システムのシャットダウン、サスペンド、休止状態 Red Hat Enterprise Linux 7 | Red Hat Customer Portal</a></p> <h1 id="Timerの作成と登録"><a href="#Timer%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%A8%E7%99%BB%E9%8C%B2">Timerの作成と登録</a></h1> <h1 id="serviceの作成と登録"><a href="#service%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%A8%E7%99%BB%E9%8C%B2">serviceの作成と登録</a></h1> <pre><code class="shell-session">$ sudo nano /etc/systemd/system/reboot.timer </code></pre> <pre><code class="config">[Unit] Description=schedule reboot [Timer] Unit=reboot.service OnCalendar=*-*-* 5:30:00 [Install] WantedBy=timers.target </code></pre> <p>この例では毎朝5:30に再起動する記述になっています</p> <pre><code class="console">sudo systemctl enable reboot.timer sudo systemctl start reboot.timer </code></pre> <p>で登録します。</p> <pre><code class="console">$ sudo systemctl list-timers --all NEXT LEFT LAST PASSED UNIT ACTIVATES Tue 2019-10-29 17:04:33 JST 4min 59s left n/a n/a systemd-tmpfiles-clean.timer systemd-t Wed 2019-10-30 05:30:00 JST 12h left n/a n/a reboot.timer reboot.se n/a n/a n/a n/a systemd-readahead-done.timer systemd-r </code></pre> <p>という具合に、次の5:30にrebootが予定されていれば出来上がりです。よい再起動ライフを!</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15449 2019-10-04T05:08:06+09:00 2019-10-04T05:29:33+09:00 https://crieit.net/posts/ssh リモート開発には、sshトンネルが便利 <p><a href='https://note.mu/masuidrive/n/need1723d456b' target='_blank'>code-serverを使ってブラウザ上だけでセキュアで快適に開発してみる|masuidrive|note</a></p> <p>増井さんキター!<br /> だよね?もはやローカルPCで開発とかしないよね?時代はリモートだよね!?</p> <p>記事に書かれているとおり、リモート開発では、ポートの開閉が問題になります。ローカル開発で気軽にlocalhost:3000にアクセスするような感覚でサーバのポートを開けると、全世界から3000番にアクセス可能になってしまいます。自分のIPアドレスを調べて限定公開すればいい?毎回そんな面倒なことやってられないよ。</p> <p>そのソリューションとしてVPNはりました、ということだったのですが。記事見て分かる通り、VPNもめんどくさいのですよね。過去何回かトライして、だいたいVPNサーバの維持がめんどくさくなって諦めています。</p> <p>代わりに使っているのが、SSHのport_forwarding。</p> <p>sshの設定ファイルに、こんな具合に書いておきます。</p> <pre><code>Host linode17 HostName xxx.xxx.xxx.xxx LocalForward 127.0.0.1:3000 127.0.0.1:3000 LocalForward 127.0.0.1:1337 127.0.0.1:1337 </code></pre> <p>んでいつものようにサーバプロセスを立ち上げてlocalhost:1337にアクセスすると</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d964d57b03cc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d964d57b03cc.png?mw=700" alt="image.png" /></a></p> <p>ほい来た。</p> <p>sshのport_forwadingというのは、sshの接続のついでに、ローカルのポートをサーバのポートにつないどいてね、という機能です。SSHでつないだ接続(トンネル)の中をデータが流れるので、SSHトンネルとも呼ばれます。<br /> <a href='https://www.ssh.com/ssh/tunneling/example' target='_blank'>SSH port forwarding - Example, command, server config | SSH.COM</a><br /> <a href='https://www.manpagez.com/man/5/ssh_config/' target='_blank'>man page ssh_config section 5</a><br /> SSH接続が前提の機能なので、当然そのポートにアクセスできるのは自分だけに限定されます。</p> <p>この方法の嬉しいところは、WEB開発で当たり前のように使うsshの設定ファイルに書くだけですべてが完了するところです。開発サーバの他にもう一台サーバを維持したりしなくていいし、接続を忘れて「あれ?つながらない?」みたいなことにもならない。</p> <p>2つ3つの開発を並行していて、localhost:3000の奪い合いになるのはWEB開発あるあるですが、リモートに用途ごとの開発サーバを用意しておけば、接続を切り替えるだけで毎回localhost:3000を使うことができるのも地味に嬉しい。</p> <p>一方で、VPNを用意しておくと、公衆無線LANなんかで接続するときの安心感が大きいので、そこはトレードオフですね。</p> <p>よかったらお試しください。</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15364 2019-08-30T17:38:11+09:00 2019-09-11T10:16:48+09:00 https://crieit.net/posts/hadolint-Dockerfile-VSCode-CentOS hadolintでDockerfileの書き方を叱ってもらう(VSCode, CentOS) <p>最近の開発環境はとても親切になっていて、コードの補完とか、良くないコードの指摘とか、もはや君が書いてくれたらいいんじゃない?と言いたくなるくらいいろんな機能が充実してきている。</p> <p>順調に飼いならされているぼくは、いろんなツールに叱ってもらいながらコードを書くのが当たり前になっていて、そうすると、叱ってくれない箇所があるとむしろ不安になってしまう。</p> <p>そんなわけで不安になるものの一つがDockerのファイルで、dockerfileとかは<a target="_blank" rel="nofollow noopener" href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/">ベストプラクティス</a>があるんだから、それに沿って書き方チェックしてくれたらいいのになーと思っていた。</p> <p>そしたら、そういうのがあることを教えてもらった。</p> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">雑に書いたdockerfileやdocker-compose.ymlを添削してくれるサービスがほしい</p>— ナガモト@Glideエンジニア (@ngmt83) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/ngmt83/status/1165944603867877376?ref_src=twsrc%5Etfw">August 26, 2019</a></blockquote> <blockquote class="twitter-tweet"><p lang="ja" dir="ltr">lint?もしかしてと思ったらありました!<a target="_blank" rel="nofollow noopener" href="https://t.co/oQqFRTYtI4">https://t.co/oQqFRTYtI4</a></p>— ナガモト@Glideエンジニア (@ngmt83) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/ngmt83/status/1165952421136220160?ref_src=twsrc%5Etfw">August 26, 2019</a></blockquote> <p>これは使ってみるしかない。すでに何人もの人が試していて日本語の記述もいっぱいあるので、ここではぼくの普段使っている環境 VSCode + CentOS での手順をメモ。</p> <p><a href="https://crieit.now.sh/upload_images/7f75bcaa94abb7a0778c2c80d92e41ce5d68dfa4e2903.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7f75bcaa94abb7a0778c2c80d92e41ce5d68dfa4e2903.png?mw=700" alt="68747470733a2f2f6861646f6c696e742e6769746875622e696f2f6861646f6c696e742f696d672f6361745f636f6e7461696e65722e706e67.png" /></a></p> <h1 id="hadolintのインストール"><a href="#hadolint%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">hadolintのインストール</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/hadolint/hadolint">公式サイト</a>によると、</p> <blockquote> <p>You can download prebuilt binaries for OSX, Windows and Linux from the latest release page.</p> </blockquote> <p>ということなので、<a target="_blank" rel="nofollow noopener" href="https://github.com/hadolint/hadolint/releases">リリースページ</a>からダウンロードしてきたファイルをそのまま実行するのがいいらしい。</p> <p>apt-getで入れないと不安になっちゃうけど、まあ新しいツールはそんなもんよね</p> <pre><code>[ ~]$ cd /usr/local/bin/ [ /usr/local/bin]$ sudo curl -L -O https://github.com/hadolint/hadolint/releases/download/v1.17.1/hadolint-Linux-x86_64 [sudo] daisuke のパスワード: % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 611 0 611 0 0 1615 0 --:--:-- --:--:-- --:--:-- 1616 100 3216k 100 3216k 0 0 598k 0 0:00:05 0:00:05 --:--:-- 678k [ /usr/local/bin]$ sudo chmod +x hadolint-Linux-x86_64 </code></pre> <p>試しに実行してみる</p> <pre><code>[ /usr/local/bin]$ hadolint-Linux-x86_64 ~/develop/dengen_map/docker/front/Dockerfile /home/daisuke/develop/dengen_map/docker/front/Dockerfile:3 DL3008 Pin versions in apt get install. Instead of `apt-get install <package>` use `apt-get install <package>=<version>` /home/daisuke/develop/dengen_map/docker/front/Dockerfile:3 DL3015 Avoid additional packages by specifying `--no-install-recommends` </code></pre> <p>叱ってもらえる!</p> <h1 id="VSCodeから実行"><a href="#VSCode%E3%81%8B%E3%82%89%E5%AE%9F%E8%A1%8C">VSCodeから実行</a></h1> <p>VSCodeには、<a target="_blank" rel="nofollow noopener" href="https://marketplace.visualstudio.com/items?itemName=exiasr.hadolint">hadolint</a> というプラグインが用意されている。これをインストールして、設定画面からhadolintのパスを設定する</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d68de8e5775d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d68de8e5775d.png?mw=700" alt="image.png" /></a></p> <p>そうすると、つぎからDockerfileを編集したときに、こんなふうに叱ってもらえるようになる!幸せ!もっと叱って!</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d68df284ceda.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d68df284ceda.png?mw=700" alt="image.png" /></a></p> <p>いまのところ、docker-compose.ymlまでは見てくれないらしい。構文チェックだけでもやってくれるツールがほしいなあ。</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15291 2019-07-31T22:46:21+09:00 2019-08-02T10:12:22+09:00 https://crieit.net/posts/spec-Time-zone-now 月末だけ失敗するspecテストと対策(テストを時刻に依存させるな運動) <p>この記事で言う現在時刻というのは、例えばTime.zone.nowとか、Date.current, Date.todayのような、今日とか現在時刻、をとってくるメソッドのことです。<br /> railsではtimezoneの扱いを大事にするため、Time.nowじゃなくてTime.zone.nowを使う、みたいなノウハウがありますが、今回の話はそれとは関係がありません。<br /> specテストにおいて、そういう「現在時刻に関するメソッド」を安易に使うと、「特定の日だけ落ちるテスト」「特定の時間だけ落ちるテスト」になりやすいのでやめよう、という話。</p> <h1 id="例えばこんなケース"><a href="#%E4%BE%8B%E3%81%88%E3%81%B0%E3%81%93%E3%82%93%E3%81%AA%E3%82%B1%E3%83%BC%E3%82%B9">例えばこんなケース</a></h1> <blockquote> <p>渡されたdateに対して、その月の残りの日付を配列で返す関数 remaining_days_of_month を作ります。例えば 1/28が渡されたら、<strong><em>[29,30,31]</em></strong> を返します。31日だと、残りの日付はないので <strong><em>[]</em></strong> です</p> </blockquote> <p>コーディングテストに良さそうな題材ですね。これをどうにかして実装したとして、この関数に対するspecテストを考えましょう。</p> <p>「これ、引数に渡したその日は含まれないのよね」</p> <pre><code class="ruby">it 'not contains the day' do expect(remaining_days_of_month(Time.zone.today)).not_to include Time.zone.today.day end </code></pre> <p>「で、その次の日から始まる、と」</p> <pre><code class="ruby">it 'contains next day' do expect(remaining_days_of_month(Time.zone.today)).to include Date.tomorrow.day end </code></pre> <p>いろいろつっこみどころはあるかと思いますが、話の都合で、これがコードレビューを通ったことにしましょう。テストはなにか書いてあればOKという職場、あるでしょ?</p> <h1 id="月末の悲劇"><a href="#%E6%9C%88%E6%9C%AB%E3%81%AE%E6%82%B2%E5%8A%87">月末の悲劇</a></h1> <p>月末の夜、リリースに向けてコードを書く職場で悲鳴が上がります。<br /> 「なんかテスト落ちてるぞ!」<br /> 「Aくん、rspec落ちてるから確認して」</p> <p>AくんはCircleCIで落ちた箇所を確認します。おかしいな。こんなところ触ってないのに、これ一体何なんだろう...触ったこともないところだから全然わからん...これぼく関係ないんじゃないの?だからテストって嫌いなんだ...</p> <h1 id="問題"><a href="#%E5%95%8F%E9%A1%8C">問題</a></h1> <p>簡単な例なので大半の方は気づいていると思いますが、問題のコードはこれです。</p> <pre><code class="ruby">it 'contains next day' do expect(remaining_days_of_month(Time.zone.today)).to include Date.tomorrow.day end </code></pre> <p>このコード、通常はテストが通りますが、月末最終日に限り、Time.zone.todayはその月、Date.tomorrowは翌月を指すようになるのでテストが失敗します。</p> <p>この一行なら誰だってわかるけど、これ10行くらい書いた中に埋め込まれると結構わからなくなるのです....</p> <h1 id="対策"><a href="#%E5%AF%BE%E7%AD%96">対策</a></h1> <p>よく言われる対策は「TimeCop / TimeHelpersを使って時間を固定する」です。</p> <p>ですが、正直この程度のことにそんな大道具持ち出すのもどうなのよ、そういうことしていると、今度は開放し忘れて別の箇所で悲劇を引き起こすんじゃないの?</p> <p>ぼくがすすめている対策は、「rspecで現在時刻は使わない」です。</p> <p>例えば今回のテストはどう書くのが正解だったのか。</p> <pre><code class="ruby">describe 'remaining_days_of_month' do it 'contains remaining days' do let(:date) { Date.new(2019, 1, 28) } expect(remaining_days_of_month(date)).to match_array [29, 30, 31] end end </code></pre> <p>テスト日付を固定します。そうすると答えもおのずから決まるから、includeじゃなくてmatch_arrayで確認することができる。</p> <p>そもそも、テストを実施する日によってテスト内容が変わる時点でおかしいですよね。specテストに書いたコードにバグがあっても、specテストをspecテストすることはできないのだから、テストは可能な限りシンプルなロジックであるべきで、Time.zone.nowみたいに値が変わるものを使うのは良くないことです。</p> <h1 id="よくある反論"><a href="#%E3%82%88%E3%81%8F%E3%81%82%E3%82%8B%E5%8F%8D%E8%AB%96">よくある反論</a></h1> <p>よくある反論は、「現在時刻使っておけばいろんな日付が試せるから潜在バグを洗い出せるよ」です。</p> <p><strong>甘えるんじゃねえ!</strong></p> <p>その潜在バグとやらが自分の手元で見つかるのならともかく、わけのわからんタイミングで爆発して始末させられる方の身にもなってください。</p> <p>境界値が不安なのであれば、自分でテストを書きましょう</p> <pre><code class="ruby"> it 'contains remaining days' do let(:date) { Date.new(2019, 1, 28) } expect(remaining_days_of_month(date)).to match_array [29, 30, 31] end it 'return empty at the end of the month' do let(:date) { Date.new(2019, 1, 31) } expect(remaining_days_of_month(date)).to match_array [] end </code></pre> <h1 id="使っても良いケース"><a href="#%E4%BD%BF%E3%81%A3%E3%81%A6%E3%82%82%E8%89%AF%E3%81%84%E3%82%B1%E3%83%BC%E3%82%B9">使っても良いケース</a></h1> <p>メソッド内に現在時刻が使われている場合、テスト側も現在時刻を使わざるを得ないケースがあります。<br /> 例えば、「今日以降の日付を配列で返す関数」のような場合です。</p> <p>ただこの場合でも、こういう実装にしてあれば、現在時刻を使わなくてもテストすることができます。</p> <pre><code class="ruby"># 指定された日以降の日付を配列で返す. 省略すると当日が使われる def remaining_days_of_month(date = Time.zone.today) : </code></pre> <p>この辺の実装の工夫について、下記が詳しいです。</p> <p><a target="_blank" rel="nofollow noopener" href="https://techlife.cookpad.com/entry/2016/05/30/183947">「現在時刻」を外部入力とする設計と、その実装のこと</a></p> <p>で、いろいろな事情によりそこまでやれない場合に、TimeHelpersで時間を固定した上で、Time.zone.now/Time.zone.todayを使うのは仕方ないかなあ、という感じですね。<br /> specテストにおいて、固定しないTime.zone.now/Time.zone.todayを使ってよい場面は存在しません。</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>現在時刻を使うことによって、月末だけ失敗するrspecバグを埋め込むパターンを説明しました。</p> <p>いくつかのrailsプロジェクトを渡り歩いていて、このルールはあたりまえのように守られているところもあれば、どんなに説明してもご理解いただけないところもあったりして苦労しています。<br /> この記事を示すことで誰でもわかってもらえるようになるといいなあ。</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/15222 2019-07-10T21:56:27+09:00 2019-07-10T22:13:04+09:00 https://crieit.net/posts/twitter-url-URL [twitter] url単位で検索に表示されなくなるURLバン現象についてまとめ <h1 id="シャドウバン類似の、URLバン問題"><a href="#%E3%82%B7%E3%83%A3%E3%83%89%E3%82%A6%E3%83%90%E3%83%B3%E9%A1%9E%E4%BC%BC%E3%81%AE%E3%80%81URL%E3%83%90%E3%83%B3%E5%95%8F%E9%A1%8C">シャドウバン類似の、URLバン問題</a></h1> <p>Twitterで、自分のツイートが検索に表示されなくなる、シャドウバンという現象があるらしいということがここ数年明らかになりつつあります。<br /> <a target="_blank" rel="nofollow noopener" href="https://nagished.com/20190302/twitter-shadowban">Twitterのシャドウバン(Shadowban)は3種類!確認・対処方法を解説します | ナギサものおき</a></p> <p>これはこれで問題なのですが、個人開発者の間で、これとは別に、URL単位で検索から外される措置があるのではないか、というのが話題になっています。</p> <p><a href="https://crieit.now.sh/upload_images/12562ae1008570d98f6b4f346c4b7f485d25d8c72ef6e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/12562ae1008570d98f6b4f346c4b7f485d25d8c72ef6e.png?mw=700" alt="akuma_shadow.png" /></a></p> <p>たとえばこれは、"news.yahoo.co.jp"の検索結果です。当然、ヤフーニュースの記事について言及しているツイートがたくさん出てきます。<br /> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/search?f=tweets&vertical=default&q=news.yahoo.co.jp&src=typd">https://twitter.com/search?f=tweets&vertical=default&q=news.yahoo.co.jp&src=typd</a></p> <p>一方、旅のクイズサイトKoretteの検索結果はこちらです。<br /> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/search?f=tweets&q=korette.fun&src=typd">https://twitter.com/search?f=tweets&q=korette.fun&src=typd</a></p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d25dbecb17e3.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d25dbecb17e3.png?mw=700" alt="image.png" /></a><br /> 検索結果一件!Koretteはそんなにマイナーなサービスなのでしょうか?違います。</p> <p>このツイートも出てきてないし、</p> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">【正解しました!】札幌ドームにおいて音楽イベントを初めて行なったアーティストは? <a target="_blank" rel="nofollow noopener" href="https://t.co/0XTEGA68Dt">https://t.co/0XTEGA68Dt</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/Korette?src=hash&ref_src=twsrc%5Etfw">#Korette</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/%E5%8C%97%E6%B5%B7%E9%81%93?src=hash&ref_src=twsrc%5Etfw">#北海道</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/%E6%9C%AD%E5%B9%8C%E5%B8%82?src=hash&ref_src=twsrc%5Etfw">#札幌市</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/%E6%9C%AD%E5%B9%8C%E3%83%89%E3%83%BC%E3%83%A0?src=hash&ref_src=twsrc%5Etfw">#札幌ドーム</a></p>— nami (@nami88798557) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/nami88798557/status/1148435890651332608?ref_src=twsrc%5Etfw">2019年7月9日</a></blockquote> <p>このツイートも。</p> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">「上川町とかみっきーに詳しくなれるクイズ」7問中7問正解(正解率100%)でした。全問正解、すごいぽわん! <a target="_blank" rel="nofollow noopener" href="https://t.co/pR42tky0cR">https://t.co/pR42tky0cR</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/Korette?src=hash&ref_src=twsrc%5Etfw">#Korette</a> <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/%E4%B8%8A%E5%B7%9D%E7%94%BA%E3%81%A8%E3%81%8B%E3%81%BF%E3%81%A3%E3%81%8D%E3%83%BC%E3%81%AB%E8%A9%B3%E3%81%97%E3%81%8F%E3%81%AA%E3%82%8C%E3%82%8B%E3%82%AF%E3%82%A4%E3%82%BA?src=hash&ref_src=twsrc%5Etfw">#上川町とかみっきーに詳しくなれるクイズ</a></p>— 黒らべる (@yu1020beer) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/yu1020beer/status/1146949198979297281?ref_src=twsrc%5Etfw">2019年7月5日</a></blockquote> <p>ぼくのツイートも。</p> <blockquote class="twitter-tweet" data-conversation="none" data-lang="ja"><p lang="ja" dir="ltr">ちなみにこれのクイズも作りました<a target="_blank" rel="nofollow noopener" href="https://t.co/3NVMQLhvzQ">https://t.co/3NVMQLhvzQ</a></p>— もぎゃ🔌(daisuke furukawa) (@mogya) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/mogya/status/1148443096268468224?ref_src=twsrc%5Etfw">2019年7月9日</a></blockquote> <p>いずれも、https://shadowban.eu で確認する限り、shadowbanされていないアカウントです。Koretteと無関係なツイートについては普通に検索結果に表示されます。</p> <p>さらに、ツイートにつけてあるハッシュタグ <a target="_blank" rel="nofollow noopener" href="https://twitter.com/hashtag/%E6%9C%AD%E5%B9%8C%E9%96%8B%E6%8B%93%E3%82%AF%E3%82%A4%E3%82%BA?f=tweets&vertical=default&src=hash">#札幌開拓クイズ</a> についてはこの惨状です。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d25db66519de.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d25db66519de.png?mw=700" alt="image.png" /></a></p> <p>このことから、おそらくURLやキーワード単位で検索結果を表示させない制御が働いているのではないかと考えています。</p> <p>これは個人開発者にとってとても痛いです。<br /> URL単位で検索することは、サービスについて感想をツイートしてくれているユーザーさんを見つける有力な手段だからです。これは推測ですが、おそらくトレンドなどにも出なくなっているので、サービスを知ってもらう重要な武器を一つ失っていることにもなります。</p> <h1 id="傾向と対策"><a href="#%E5%82%BE%E5%90%91%E3%81%A8%E5%AF%BE%E7%AD%96">傾向と対策</a></h1> <p>個人開発者がたくさん集まる<a target="_blank" rel="nofollow noopener" href="https://scrapbox.io/admin-guild-pr/%E9%81%8B%E5%96%B6%E8%80%85%E3%82%AE%E3%83%AB%E3%83%89">運営者ギルド</a>に集まる開発者たちが、自分たちのサービスを次々にBANされて泣きそうになりながら学んだ傾向としては、次のようなものが上げられます。</p> <ul> <li>当然だが、サービス開始直後はBANされていないので、普通に検索することができる</li> <li>サービス開始後数日くらいで、順調にユーザーが増えてきたと思ったら突然検索できなくなる</li> <li>一度適用されると、解除してもらう手段はない。何人もの開発者が問い合わせを試みましたが、一度も解除に成功したことはありません</li> <li>サービスごと移転してドメインを変えれば復活できるけど、またBANされる可能性も当然ある</li> <li>「結果をシェアしよう」みたいな機能で、類似度の高いテキストにURLとハッシュタグをつけてツイートしてもらうと、ほぼ確実にBANされる</li> <li>.fun は .comに比べてBANされやすい、という説がある(たんにURLが変わってそれ以降はBANされずに済んでいるだけの可能性もある)</li> </ul> <blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">これでようやくtwitterでタグ検索ができるようになった。旧ドメインはどうやら.funのTLDがダメだったぽい。ツイッターから完全にurlじゃないもの扱いされてた。メジャーじゃないTLDは地雷という学びを得た。</p>— れとるときゃりー (@retoruto_carry) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/retoruto_carry/status/1079956953248423936?ref_src=twsrc%5Etfw">2019年1月1日</a></blockquote> <ul> <li>[知見] サービスからゲーム結果などをツイートしてもらう場合は、URLをそのまま書かずにbit.lyで圧縮してからツイートしてもらうようにすると、BANされないぽい <ul> <li>今話題の #本田とカードバトル もbit.ly圧縮を使っています</li> </ul></li> </ul> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d25e06513636.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5d25e06513636.png?mw=700" alt="image.png" /></a></p> <ul> <li><p>たんにみんなの感想を見るだけであれば、Yahooリアルタイム検索 で探すのが現実的な回避手段</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://search.yahoo.co.jp/realtime/search;_ylt=A2RCL6kj4yVdIHEAEw9ol_p7?p=korette&ei=UTF-8">「korette」のYahoo!検索(リアルタイム)</a></li> </ul> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1></li> <li><p>TwitterはURLとハッシュタグをつけたツイートをしてもらうと、そのURLやハッシュタグ単位で検索ができなくなる URLバン とでも呼ぶべき現象が存在する</p></li> <li>Twitterの中の人、見てたらなんとかしてください。ぼくらはTwitterのユーザーが楽しめるサービスを作って楽しんでもらっているのに、どうしてこんな仕打ちを受けないといけないのですか</li> <li><a target="_blank" rel="nofollow noopener" href="https://scrapbox.io/admin-guild-pr/%E9%81%8B%E5%96%B6%E8%80%85%E3%82%AE%E3%83%AB%E3%83%89">運営者ギルド</a> では、こんな情報も含め、サービス開発をする上で必要となる宣伝や運営などの知見を交換したり、相互にバグだしを手伝うなどの活動を行っています。自分のサービスを運営している人なら誰でも参加できますので、個人開発者の方、ぜひ参加してください。</li> </ul> daisuke furukawa tag:crieit.net,2005:PublicArticle/15020 2019-05-24T21:12:29+09:00 2020-06-19T01:11:43+09:00 https://crieit.net/posts/0844f0a6d109b77928b379312864b349 コードレビュー ありがちな問題への対処例 <p>コードレビュー、これまでいろんなプロジェクトで経験して、意外と使われていないノウハウがあったり、風習が違ってつらみがあったりしたので、いろいろまとめてみる。</p> <p><a href="https://crieit.now.sh/upload_images/59e6f87236364088724deab5e88fa7725ce7d6c371b60.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/59e6f87236364088724deab5e88fa7725ce7d6c371b60.png?mw=700" alt="zeikan_shinsa.png" /></a></p> <h1 id="指摘事項について"><a href="#%E6%8C%87%E6%91%98%E4%BA%8B%E9%A0%85%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">指摘事項について</a></h1> <p>よくある話<br /> - 駄目コードを憎んで人を憎まず。駄目なのはコードであって人格じゃない<br /> - 指摘する人は人格攻撃せずにコードのどこが悪いのかを指摘しましょう<br /> - 指摘される人も、言われているのはコードの問題であって人間の問題じゃないので、素直な心で受け止めよう</p> <p>この辺はみんな知ってると思うので略。ぼくが思う大事なルール</p> <blockquote> <p>コードレビューで指摘された内容は、<strong>対応必須ではない</strong></p> </blockquote> <p>理由: 対応必須にすると、「これ言ったらリリースできなくなるよね」みたいな忖度が発生してコメントできない人が出現するから。</p> <p>絶対ダメとは言わないけど、あまりよくはない、みたいな指摘については、そのときは急ぐからリリースするけど、次回から気をつけるとかがありうるよね。そういう指摘ができなくなる対応必須ルールはみんなの成長を阻害するのでやめたほうが良い。</p> <ul> <li>Q:なんでも指摘を無視してリリースできちゃう?</li> <li>A:そういうことにはならない。"Approveについて"参照</li> </ul> <h1 id="Approveについて"><a href="#Approve%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">Approveについて</a></h1> <p>レビューアーは、「このPRがプロダクトにマージされて良い」と思えばapprove(👍)をつける。これが一定数集まったらリリースしてOK、というのが一般的なルール。</p> <h2 id="レビュアーの行動"><a href="#%E3%83%AC%E3%83%93%E3%83%A5%E3%82%A2%E3%83%BC%E3%81%AE%E8%A1%8C%E5%8B%95">レビュアーの行動</a></h2> <h3 id="approveだけする"><a href="#approve%E3%81%A0%E3%81%91%E3%81%99%E3%82%8B">approveだけする</a></h3> <p>問題ない。でもできれば、ちょっと感想とか、「こういう観点で見ました」「こういう点が気になったのでチェックして、問題ないことが確認できました」みたいなコメントがあると、あとからレビューする人は別の観点からチェックすることができて嬉しい</p> <h3 id="approve+コメント"><a href="#approve%EF%BC%8B%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88">approve+コメント</a></h3> <p>単なる感想とか、気になるけどまあ直さずにリリースしてもいいでしょ、程度の問題のとき</p> <h3 id="approveせずにコメント"><a href="#approve%E3%81%9B%E3%81%9A%E3%81%AB%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88">approveせずにコメント</a></h3> <p>この指摘を直さないのなら自分はリリースに合意できない、という意思表示。<br /> ただし、approve数のルールによっては、自分が合意しないけどリリースされることはありうる。絶対ダメなコードについては強く指摘して他の人の注意をひこう</p> <hr /> <p>5/29 追記 Twitterで指摘いただいた。絶対ダメなコードはこれで止めるのが良いね。</p> <blockquote class="twitter-tweet" data-cards="hidden" data-lang="ja"><p lang="ja" dir="ltr">GitHubのプルリクには "Request Changes" というものがあるので、リリースに合意できないときはコメントだけじゃなくて "Request Changes" を使うと良い。 <a target="_blank" rel="nofollow noopener" href="https://t.co/NDWUEIyVGL">https://t.co/NDWUEIyVGL</a></p>— 神速 (@sinsoku_listy) <a target="_blank" rel="nofollow noopener" href="https://twitter.com/sinsoku_listy/status/1132862265038856192?ref_src=twsrc%5Etfw">2019年5月27日</a></blockquote> <hr /> <h2 id="Approveいくつ問題"><a href="#Approve%E3%81%84%E3%81%8F%E3%81%A4%E5%95%8F%E9%A1%8C">Approveいくつ問題</a></h2> <p>そんなルールのもとで、いくつapproveを集めたらリリースしていいことにするか</p> <h2 id="一人合意すればOK"><a href="#%E4%B8%80%E4%BA%BA%E5%90%88%E6%84%8F%E3%81%99%E3%82%8C%E3%81%B0OK">一人合意すればOK</a></h2> <p>一定数までは、リリースに必要な合意数とコードの品質は比例するので、一人だと品質が微妙になる。<br /> でも、スタート直後のベンチャーなんかだと、スピードを優先して一人合意にするのはアリ。あと、CTO的な人がいて、その人が合意したらOKというパターンもある。<br /> 10人もいるのに一人合意でOKにすると、いい加減なOKを出すやつが出て致命的な問題が見逃されるリスクが出てくるので、もうちょっとしっかりやりたい</p> <h2 id="全員合意"><a href="#%E5%85%A8%E5%93%A1%E5%90%88%E6%84%8F">全員合意</a></h2> <p>あまりおすすめしない。少数ならやっても良いかも知れないけど、10人のチームでこれをやると、それぞれ9人分のPRを見ないといけなくなって死ぬ</p> <h2 id="2-3"><a href="#%EF%BC%92%EF%BC%8D%EF%BC%93">2-3</a></h2> <p>これくらいがおすすめ。このやり方のキモは、合意を集めるためにある程度の指摘に対応しないといけないこと。</p> <p>「指摘事項について」で書いたとおり、指摘事項は無視ができる。そのかわりレビューアーは、「直さないのだったらapproveしません」権を持つ。<br /> レビューしてもらう人は、approveを集めるために、ある程度の指摘事項には対応しないといけなくなる。結果的に、一人厳しすぎる人の指摘はスルーできるけど、みんなが駄目だと思うような項目はスルーできなくなる</p> <h1 id="マージボタンを押す人問題"><a href="#%E3%83%9E%E3%83%BC%E3%82%B8%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%92%E6%8A%BC%E3%81%99%E4%BA%BA%E5%95%8F%E9%A1%8C">マージボタンを押す人問題</a></h1> <p>合意を集めた後、誰がマージボタンを押すか問題。<br /> 誰でも良さそうな気がするけど、いろいろ妙味があるので、これも決めておいたほうが良い</p> <h2 id="特定の人が押す"><a href="#%E7%89%B9%E5%AE%9A%E3%81%AE%E4%BA%BA%E3%81%8C%E6%8A%BC%E3%81%99">特定の人が押す</a></h2> <p>チームのリーダー的な立ち位置の人がいて、その人がマージボタンを押す。<br /> 当然その人は全部のコードに目を通すことになるので、プロダクトについてほぼ何でも知っている人みたいな位置になる。</p> <p>そういう人がいるとみんな頼もしいし便利なんだけど、その人の負荷はとても高く、退職したり爆発四散してしまったりするとプロジェクトが一気にピンチに陥るので、初期のベンチャー以外ではあまりおすすめしない。</p> <p>別案として、プロダクトオーナーみたいな人が押すという手もある。技術的に深く理解している必要はなくて、「エンジニアがみんな合意してるから大丈夫だろ」みたいな感じで押す。どんな機能が導入されたかプロダクトオーナーが把握できるのがメリット</p> <h2 id="レビュイーが押す"><a href="#%E3%83%AC%E3%83%93%E3%83%A5%E3%82%A4%E3%83%BC%E3%81%8C%E6%8A%BC%E3%81%99">レビュイーが押す</a></h2> <p>レビュイー、つまりPRを作ってレビューしてもらう人がマージボタンを押す。とてもおすすめのルール。</p> <p>このルールのポイントは「👍が集まったら、マージボタンを<strong>押しても良い</strong>」にしておくこと。つまり、「👍集まったけど、この機能にとても詳しいAさんにも見てほしいからもうちょっと待とう」「👍集まったけど、この指摘は重要なので対応しておきたい」というようなことが出来る。<br /> 逆に「いまはスケジュール的に押しているから、最低限の👍でリリースする」という判断もありうる</p> <h1 id="ひよっこ問題"><a href="#%E3%81%B2%E3%82%88%E3%81%A3%E3%81%93%E5%95%8F%E9%A1%8C">ひよっこ問題</a></h1> <p>駆け出しエンジニアみたいな人がいて、普通のコードレビューが成立しなくなる問題に対する対処</p> <h2 id="甘すぎるapprove問題"><a href="#%E7%94%98%E3%81%99%E3%81%8E%E3%82%8Bapprove%E5%95%8F%E9%A1%8C">甘すぎるapprove問題</a></h2> <p>👍一個でリリース可能で、ひよっこが合意したらそれでリリースできてしまう、みたいな問題。</p> <p>放置してしまうと「責任が取れないからapproveしない」みたいな遠慮をすることになってしまって、成長のためにとても望ましくない状態になる。ひよっこが👍したあとで先輩から厳しい指摘がついて「そういうところを見るのか!」ってなる方が良いですよね。</p> <p>必要な👍数を増やすという手もあるんだけど、「マージボタンはレビュイーが押す」ルールの導入がおすすめ。これがあれば、「彼の合意だけでリリースするのはまずいのでもうひとり見てくれるまで待とう」というブレーキをかけることが出来る。<br /> 逆に、「些細なPRなので彼一人でも良いだろ」という判断もできて、柔軟な対処が可能になるのもうれしい。</p> <h2 id="レビューが成立しない問題"><a href="#%E3%83%AC%E3%83%93%E3%83%A5%E3%83%BC%E3%81%8C%E6%88%90%E7%AB%8B%E3%81%97%E3%81%AA%E3%81%84%E5%95%8F%E9%A1%8C">レビューが成立しない問題</a></h2> <p>ひよっこの書いたコードがアレすぎて、<br /> - どこから指摘していいかわからない<br /> - 指摘が大量について対処できなくなる<br /> - ひよっこの心が折れちゃう</p> <p>等に関する対応。</p> <p>「PRを出す前に、隣の人にチェックしてもらってください」がオススメ。メンターさんとか教育係でもいいし、持ち回りでもよい。</p> <h1 id="巨大PR問題"><a href="#%E5%B7%A8%E5%A4%A7PR%E5%95%8F%E9%A1%8C">巨大PR問題</a></h1> <p>リファクタリングとかで、何十ファイルにも及ぶ巨大PRができてしまって誰もレビューできなくなる問題</p> <h2 id="分割する"><a href="#%E5%88%86%E5%89%B2%E3%81%99%E3%82%8B">分割する</a></h2> <p>approveをあつめるのはレビューイーの責務なので、見てもらえる程度のサイズに分割して小さなPRに分ける。</p> <p>理想的なんだけど、大変な修正をしたのにPR分割しろと言われると、心が折れちゃうよね...</p> <h2 id="説明会"><a href="#%E8%AA%AC%E6%98%8E%E4%BC%9A">説明会</a></h2> <p>時間を決めて会議室にあつめたり、オンライン会議をして、コードについてみんなに説明する場を持つ。その場で質疑応答して、最後にみんなの合意をもらうことで、approveの代わりにする。</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>過去いくつかのプロジェクトでコードレビューして、これは良かった、これは辛かった、というノウハウを書いてみました。<del>いかがでしたか</del> これが絶対のルールというわけじゃないので、うちではこうしているとかあれば聞かせてください。</p> daisuke furukawa tag:crieit.net,2005:PublicArticle/14963 2019-05-04T10:08:55+09:00 2019-05-22T23:50:34+09:00 https://crieit.net/posts/VSCode-Remote-Development VSCodeのRemote Development機能が革命的な話。 <h1 id="背景"><a href="#%E8%83%8C%E6%99%AF">背景</a></h1> <p>今月始めにMicrosoftから<a target="_blank" rel="nofollow noopener" href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack">Remote Development Extension Pack</a>. というのが発表された。簡単に言うと、VSCodeでコードを書くOSとプラグインが実行されるOSを別にすることが出来る。</p> <p>よくあるパターンで、「MacでNokogiriがビルドできません」「WindowsでESLintを実行するにはどうしたら良いですか」みたいな質問がある。<br /> 最終的にサービスを公開するときにはどうせLinux使うのに、開発するときしか使わない別のOSで同じものを動かす苦労って無駄だよなあ、と思っていた。</p> <p>じゃあ最初からLinuxで開発すればいいかというと、最近の高度化したWeb開発はIDEの支援なしに実行することが困難で、RubyだったらRuboCop、JavaScriptだったらPrettierやESLintで文法チェックしてもらわないと人類にはついていけない。これらを動かすためには開発環境をIDEと同じOSで動かす必要があって、そのためには上記の質問に悩まないといけない...というのが実情だった。</p> <p>そういう悩みを解決するのが、VSCodeのRemoteDevelopmentだ。VSCodeはWindowsやMacで動かしつつ、SSHやDocker、WSLなどで動作するLinuxマシン上にあるソースコードを編集し、linuxマシン上でプラグインを動かすことが出来る。つまり、Windows/MacにはVSCodeさえあればよくて、ほかは全部Linux上で実行することが出来る。もはやNokogiriのビルドに悩む必要がなくなる!</p> <h1 id="やってみた"><a href="#%E3%82%84%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F">やってみた</a></h1> <h2 id="インストール"><a href="#%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB">インストール</a></h2> <p>やり方はここで解説されている。早速やってみた。<br /> <a target="_blank" rel="nofollow noopener" href="https://code.visualstudio.com/blogs/2019/05/02/remote-development#_get-started">Remote Development with VS Code</a></p> <p>Remote Developmentはまだベータ版の機能なので、実行するためには<a target="_blank" rel="nofollow noopener" href="https://code.visualstudio.com/insiders/">Insiders</a> というβ版を使う必要がある。これは既存のVSCodeとは別のアプリケーションとして動作して、既存の環境を壊さないのでむしろ便利かも。</p> <p>インストールが完了したら、ExtenstionsからRemoteDevelopmentをインストールする。ブラウザで開いてInstallクリックすると既存のVSCodeの方に入っちゃうので注意。サイドバーのExtenstionから「Remote Development」と入力してインストールする</p> <p><a href="https://crieit.now.sh/upload_images/5bdf259a1402024ea7590a7f95f091515cccddd781e92.PNG" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/5bdf259a1402024ea7590a7f95f091515cccddd781e92.PNG?mw=700" alt="1.PNG" /></a></p> <h2 id="マシンに接続"><a href="#%E3%83%9E%E3%82%B7%E3%83%B3%E3%81%AB%E6%8E%A5%E7%B6%9A">マシンに接続</a></h2> <p>Linuxマシンに接続する方法はいろいろあるけど、今回は既存のマシンにlinux接続することにした。Ctrl+Chift+P でコマンドパレットから"Remote-SSH: Connect to Host"を実行</p> <p><a href="https://crieit.now.sh/upload_images/1ae06851b325290cab9249e6900b8e8e5cccde482aa12.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/1ae06851b325290cab9249e6900b8e8e5cccde482aa12.png?mw=700" alt="2.png" /></a></p> <p>WindowsのPuttyで接続を管理していると、その設定ファイルの内容をインポートしてくれる(!)</p> <p><a href="https://crieit.now.sh/upload_images/7c2667c852e03503e787726fe43924c65cccdf0d45388.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7c2667c852e03503e787726fe43924c65cccdf0d45388.png?mw=700" alt="3.png" /></a></p> <p>ハマりポイント:Linux側にtmuxが入っているとうまく接続できないので、bash_profile編集して外して上げる必要がある。</p> <p>接続完了。Open Fileを選ぶと、linuxマシン上のファイルを編集することになっている。</p> <p><a href="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5cccdfda19cfc.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9d08c6d37e5274805ec35413f543d5ed5cccdfda19cfc.png?mw=700" alt="image.png" /></a></p> <h2 id="プラグインを使う"><a href="#%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3%E3%82%92%E4%BD%BF%E3%81%86">プラグインを使う</a></h2> <p>ここまではSSH経由でファイルマウントしたりする機能を使えばできないこともなかったので、今までできなかったことに挑戦。</p> <p>ExtenstionからESLintとPrettierをインストール。WindowsのVSCodeからインストールしても、linuxで実行したほうが良い機能はlinux側にインストールされる。なにそれすごい...</p> <p><a href="https://crieit.now.sh/upload_images/4e666ef886c9e8a06373e868ad228d085ccce14790f36.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/4e666ef886c9e8a06373e868ad228d085ccce14790f36.png?mw=700" alt="4.png" /></a></p> <p>設定から、Format on Saveを有効に。<br /> <a href="https://crieit.now.sh/upload_images/b5b83f209eb98e6a00fc0c5745bdf34d5ccce183e9338.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/b5b83f209eb98e6a00fc0c5745bdf34d5ccce183e9338.png?mw=700" alt="5.png" /></a></p> <p>で、こういう許されないJavaScriptを書いて保存すると...</p> <p><a href="https://crieit.now.sh/upload_images/c0035fccebd3ac3cdaed1f1c228289135ccce1a3ce7b6.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c0035fccebd3ac3cdaed1f1c228289135ccce1a3ce7b6.png?mw=700" alt="6.png" /></a></p> <p>勝手に整形される。ぼくらが夢見ていた機能!WindowsにはVSCodeしかインストールしていないのにlinuxの機能が使える!</p> <p><a href="https://crieit.now.sh/upload_images/30536cf6fc3a926b7c934376b4f0150f5ccce1d46db64.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/30536cf6fc3a926b7c934376b4f0150f5ccce1d46db64.png?mw=700" alt="7.png" /></a></p> <p>Prettierだけだと、ぶっちゃけlinux上で上書きされたファイルを読んでるだけのような気もするので、あとでESLintも試してみよう</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>ということで、WindowsにインストールしたVSCodeからlinuxの開発ツールの支援を受けつつコードを書くことが出来るようになった。</p> <p><a href="https://crieit.net/posts/Windows">さいきんMacイケてないと思わない?</a> とかっこいいこと言ってSurfaceに移ったのだけど、パワー不足で仮想マシンを使うのが辛かったり、hyper-Vでlinux動かしてもESLintが使えなかったりして、やっぱりMacに戻らないと駄目かなあ、もうちょっとなんとか...と思っているところだった。</p> <p>RemoteDevelopmentがあれば、ネットの向こうで実行しているlinux VPSに対してVSCodeの各種支援機能を実現することが出来る。こうなってしまえば、もはやWindowsであれが動かないこれが動かないと悩む必要がなくなる。</p> <p>数年前まで、開発マシンをインターネットの向こうに置くと、通信環境が確保できないと開発できないのがネックだったんだけど、最近どこでも無線LAN使えるし、テザリングもあるので、SSHでつなぐ程度の回線で良ければほぼ人権レベルに確保できるようになってきた。</p> <p>この先5Gのモバイル接続が普及すれば、インターネット上で開発する動きはますます加速することが予想される。そういう予想のもとに提供されたのがAmazonの<a target="_blank" rel="nofollow noopener" href="https://aws.amazon.com/jp/cloud9/">Cloud9</a>だったんだけど、MicrosoftはVSCodeという強力なツールに機能を追加することで同様の機能をよりスマートに実現してみせた。</p> <p>GitHubの買収、TypeScript、VSCodeの提供と、あっという間にWEB開発の主流を抑えつつあるMicrosoftが、唯一ネックだったIDEの実行環境を埋めるツールを出してきて、最近のMicrosoftはイケてるよね。</p> daisuke furukawa