iOSDC Japan 2021 で色々とノベルティを作ったよ #iosdc
こんにちは! もう明日が iOSDC Japan 2021 の開催日ですね!
2021年9月17日(金) ~ 19日(日)に開催される iOSDC Japan 2021 で例年通り今年もコアスタッフをしていて、今年はノベルティを色々と作りましたよって話です!
他のことについては開催後にまた書くと思うけど、ノベルティだけでそこそこ書けそうなので先にノベルティの話を。
一般Tシャツ
なんだかんだでカンファレンススタッフ人生が10年近くになるんですが、地味にTシャツ制作というものを一度もやったことがなかったんですよね。
特定の人に依存するようなタスクじゃなければ、大体いつも空いてるタスクがあればやる感じのスタンスで例年やっていたのでなかなかやる機会がなかったんですが、今年はとうとう花形?のTシャツ担当に。
カンファレンスのTシャツってざっくり「UnitedAthle 5001」か「Printstar 085-CVT」の2強になっていて(hamaco調べ)、もちろんどこでも選ばれているから物はとてもよいんですが、 折角自分で好きに作れるんだし、他と同じなんてそれじゃつまらんよねということでその2つを選択肢から外して、Tシャツのベース探しの旅へ。
数年前にユニクロでもオリジナルデザインのTシャツを作れることを知り、ずっと気になりつつ毎年イベントが終わってから思い出す生活をしていたんですが、Tシャツ悩んでいる時にふと思いだし、ユニクロのTシャツがカンファレンスのTシャツになっているって響きだけが面白そうだったので、今年はユニクロにすることにしました。
響きだけといいつつも、ユニクロなら参加者の皆も馴染みもあるだろうし、あれだけ有名な所だし肌触りとかも良い感じだろうと思って作りましたがどうでしたかね。私も当日着るのを楽しみにしています。
ボトルオープナー
iOSDC Japan といえば…そう!ビールですよね(最近は茶会のオシャレドリンクもあるけど)! そんな iOSDC では懇親会で樽のビールと一緒に瓶ビールがでたりしますよね? ということで、ボトルオープナー欲しくない?とふと思ってしまったので突如追加で作りました。 このコロナのご時世使うことがあるのか…? とも思いはしましたが、来年はきっとオフライン開催になり茶会なり懇親会なりも復活するだろうしあってもいいよね!ってことで!
ボトルオープナーは携帯できるやつがあると便利だなーとたまに私が思っていたので、半分趣味で作ってしまった感じではありますが、きっと持ってると便利な時とかあるので是非使ってください! お酒飲まなくても瓶のドリンクを飲む時とか、缶ジュースを開ける時とか、iOSDC Japan 2021 ノベルティの缶ドロップを開ける時とか(!)にも使えるので是非普段から鞄に偲ばせておくと便利かと!
納期にも余裕があり、物的にもこだわれる所も多くなかったので、今年作った中では比較的サクッと作れたので特に書くような苦労話がないな…。
缶ドロップ
iOSDC の C は Candy の C(嘘です)。
今年はサポーターも復活し、スポンサーも去年と比べて増え、参加者の皆様に送るノベルティボックスの設計もなかなか大変でした(設計したのは別のスタッフ)。
その際、事前に箱のサンプルを作った時、スポンサー水やタンブラーを入れる部分の仕切りによい感じの空白スペースがあるのに気付いてしまい、そうなったらもうなにか作っていれたい気持ちが溢れてしまって、なんかここに隠すようにものを入れたいねーって言ったら OK がでたので、折角だしついでにトークンを隠そうということでなにか小物を作ることに。
流石に偶然できたデッドスペースだったので、あまり大きなものが入りそうになかったし、とりあえずフリスクみたいなのを入れようかな? フォーチュンクッキーだと中に紙が入ってるしトークンによいかもな? 小さいものなら個包装の飴玉みたいなやつとか? でもトークン入れれるかな… と思いながらふと飴玉のついでに缶ドロップのサイズを調べたらめちゃくちゃ隙間にピッタリサイズ。
その時点では缶ドロップも面白いなーと思いつつ納期も本当にギリギリだったし、ネタ枠のくせにそこまで予算(とデザイナーさんの工数)使っていいのか? という気持ちだったのですが、委員長からの OK がでて、デザイナーさんも作業できる余裕があるとのことだったので Go。
で、箱のサンプルができている = 送るノベルティが大体固まっているってことなので、つまりもうノベルティが着荷し始めてたりする時期なんですよね。
なので納期がめちゃくちゃギリギリでなんなら最初に問い合わせをした時点でちょっとアウトな感じだったんですが、直接電話したりしつつ先行して制作を始めてもらったり、デザイナーさんに急ぎ目で頑張ってもらったりしてなんとか作れたので、是非箱を隅々まで探してみてもらって当日飴を舐めながら iOSDC を見てもらえればと。
デザインもデザイナーさんが頑張ってくれたので可愛い感じになっていて、個人的には今年作った中でも結構お気に入り。
しかし、思いついちゃうんだから仕方ないけど、去年のメタルステッカーに引き続きギリギリの動きばっかりしていて心臓に悪い…。
おわり
思い付きとネタで動くタイプの人間なので今年も突如ノベルティ増やしたりして色々あったけど、どれも無事に作れてよかった!
思い付きでノベルティ増やしてはいますが、それでも色々考えたり頑張って作ってはいるので #iosdc ハッシュタグを付けて私が担当したやつだけじゃなく、ノベルティの感想とか沢山貰えると嬉しいなって!
Docker のコンテナ内で Control-P をちゃんと動くようにする
Docker 使ってて地味に不便だったのが、C-p を 1 回だけ押しても見た目上反応せず、その後他のキーを押すとようやく 1 つ前の履歴が表示されることだった。
どうせコンテナで使ってるシェルがおかしいんだろと思ってたけど、よく考えたら bash でもおかしいし、Docker の設定とかなのかなと思って調べたら C-p が DetachKey になっているのが問題らしく、~/.docker/config.json
を弄って設定を変えてあげればよいとのことなので設定したら快適になった。
{ "detachKeys": "ctrl-@" }
元々ファイルがあったので、detachKeys
の行を 1 行追加して絶対に使わなさそうなキーを指定しただけ。
こんなに簡単に解決するならもっと前にやっておけばよかったですわ。
WSL2 に割り当てるメモリを減らした
Windows を開発に使ってると、夜中にはめちゃくちゃ重たくなって辛かったので、タスクマネージャーを見てみると Vmmem ってのがメモリを 12GB くらい使っていた。Windows に 16GB しかメモリ乗ってないのに…。 調べてみると、どうやら搭載メモリの 80% を WSL2 が確保するらしく、そのせいで Windows 側がメモリ足りてないっぽくてモッサリするのかなと(最近は 50% になってるらしいが)。
流石に Windows 側で使えるメモリが 4GB しかないと、ブラウザが 1GB とか余裕で持っていくこのご時世では生きていけないので、.wslconfig
に以下のように書いて Windows でメモリを沢山使えるようにした。
[wsl2] memory=6GB swap=0
スワップを 0 にしているのは、メモリが 6GB もあれば充分だろうし、スワップしまくって SSD の寿命とか縮んでもなんかやだなーって思っただけなので、これは書かなくても別に問題はない。 もっとメモリ少なくても良いんじゃないか? という気もしなくもないが、また困ったら減らせばいいやってことで一旦このくらいにしている。
こんな感じに書いて wsl --shutdown
をしてあげればOK。
普通に Windows を再起動でも良いんだけど、私の使ってる ThinkPad がどうやらシャットダウンしてもちゃんとシャットダウンしてないっぽくて、設定が有効にならなかったので wsl --shutdown
を叩いている。
WinGetが動かなくなったけど最新版に更新したら動いた
Windows でのアプリケーションインストールに WinGet を使っているんだけど、最近久し振りに使ったらなにをやっても下記のような感じで、エラーがでてしまうようになった。 (パッケージによっては違うエラーだった気がするけど大体このエラー)
PS> winget install XXXX ... コマンドの実行中に予期しないエラーが発生しました: 0x8a150004 : Opening manifest failed
よく分からんので仕方なく普通に昔ながらのインストーラーをダウンロードしてインストール… ってやろうかと思ったんだけど、ふと WinGet のバージョンを上げたら解決するんじゃね? と思ってやってみたら無事解決。
S.M.A.R.T の総書き込み量を見たらびっくりした
M1 mac がスワップが多いからか SSD に書き込みが多くて寿命が…みたいな話を見たのでふと今の MacBook Pro の総書き込み量を見てみたら思ったよりも多くてビックリしたってだけの話。
やったこと
まず smartctl
コマンドを使えるようにしないといけないので、homebrew でサクッとインストール。
$ brew install smartmontools
インストールしたら diskutil list
コマンドで SSD がどのデバイスなのか調べる。
$ diskutil list /dev/disk0 (internal, physical): #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *500.3 GB disk0 1: EFI EFI 314.6 MB disk0s1 2: Apple_APFS Container disk1 500.0 GB disk0s2 /dev/disk1 (synthesized): #: TYPE NAME SIZE IDENTIFIER 0: APFS Container Scheme - +500.0 GB disk1 Physical Store disk0s2 1: APFS Volume Macintosh HD - Data 452.6 GB disk1s1 2: APFS Volume Preboot 80.4 MB disk1s2 3: APFS Volume Recovery 528.9 MB disk1s3 4: APFS Volume VM 7.5 GB disk1s4 5: APFS Volume Macintosh HD 11.3 GB disk1s5
今回は Fusion Drive とか起動ディスクを違うのにしてたりとか、そういう変なことは特になにもしてない普通の MacBook だったので /dev/disk0
だった。
あとはこれを smartctl
で調べるだけ。
$ sudo smartctl -a /dev/disk0 smartctl 7.2 2020-12-30 r5155 [Darwin 19.6.0 x86_64] (local build) Copyright (C) 2002-20, Bruce Allen, Christian Franke, www.smartmontools.org === START OF INFORMATION SECTION === Model Number: APPLE SSD SM0512L Serial Number: C02702400YFHCGX15 Firmware Version: CXS6AA0Q PCI Vendor/Subsystem ID: 0x144d IEEE OUI Identifier: 0x002538 Controller ID: 2 NVMe Version: <1.2 Number of Namespaces: 1 Local Time is: Thu Mar 25 13:13:51 2021 JST Firmware Updates (0x06): 3 Slots Optional Admin Commands (0x0006): Format Frmw_DL Optional NVM Commands (0x001f): Comp Wr_Unc DS_Mngmt Wr_Zero Sav/Sel_Feat Maximum Data Transfer Size: 256 Pages Supported Power States St Op Max Active Idle RL RT WL WT Ent_Lat Ex_Lat 0 + 6.00W - - 0 0 0 0 5 5 1 - 0.0400W - - 1 1 1 1 210 1200 2 - 0.0050W - - 2 2 2 2 1900 5300 === START OF SMART DATA SECTION === SMART overall-health self-assessment test result: PASSED SMART/Health Information (NVMe Log 0x02) Critical Warning: 0x00 Temperature: 42 Celsius Available Spare: 100% Available Spare Threshold: 10% Percentage Used: 81% Data Units Read: 1,642,514,638 [840 TB] Data Units Written: 1,590,124,954 [814 TB] Host Read Commands: 10,984,994,601 Host Write Commands: 7,790,862,063 Controller Busy Time: 37,645 Power Cycles: 30,250 Power On Hours: 8,266 Unsafe Shutdowns: 206 Media and Data Integrity Errors: 0 Error Information Log Entries: 0 Error Information (NVMe Log 0x01, 16 of 64 entries) No Errors Logged
Data Units Written
の所が総書き込み量なんだけど、814 TB とかになっていて寿命ヤベーんじゃねーの?って感じでドキドキ。
でも、よく見てみるとそのちょっと上にある Percentage Used
が 81% だったので、この SSD の寿命は 1000TB まではセーフっぽくて、多分もう1年弱は持つのかな? セフセフ。
DiscordPHP を使って Discord のメッセージを取得した #phperkaigi
はじめに
先日開催した PHPerKaigi 2021 で、Ask the Speaker など参加者同士のコミュニケーションのために Discord を利用した。
以前開催した iOSDC Japan 2020 ではボイスチャットが結構使われていたので、PHPerKaigi でも当初の想定ではボイスチャットがメインでテキストチャットはあまり使われない想定だった。
しかし PHPer にはテキストチャットの方が需要が高いみたいで結構テキストでのやり取りがメインになっていたので、最終日の表彰の時とかにそのデータを使わないのも勿体ないかなと思い Discord のメッセージを取得する Bot を書いた。
Discord の Bot を作るのは結構簡単だったんだけど、会期中にサクッと作るにはちょっとめんどくさいことも多かったので、次回以降のスタッフ業の時の為にどうやったかをメモとして残しておく。
ちなみに参考にしたサイトは下記。
Bot を Discord のサーバーに追加
まずは Discord で対象のサーバーに Bot を追加する必要があるので Bot を追加する。
事前準備
Discord の API を叩く時にサーバーID とかチャンネルID とかを取得する必要があるので、事前に開発者モードを有効にしておくと簡単にその辺りが取得できて便利。
開発者モードを有効にするには、ユーザー設定にある「テーマ」から「開発者モード」を有効にするだけ。(なぜテーマにあるのかは謎)
開発者モードを有効にすると、サーバーアイコンやサーバー名、チャンネルやメッセージなどを右クリックした時に「IDをコピー」というのが増えるので、簡単にそれぞれの ID を取ることができて Bot を作るのが捗る(というか他の方法を知らない)。
Bot の作成
Discord の Bot 自体を作るのはめちゃくちゃ簡単で、Discord Developer Portal から New Application をクリックして名前を入力して、Settings > Bot から Add bot を押すだけで OK。
ちなみにこの時 test
みたいにめちゃくちゃよく使われるような名前にすると、アプリケーションは作れるけど Bot を作ろうとすると怒られるので、ある程度ちゃんとした名前で作る必要あり。
Bot をサーバーに追加する
Bot を作ったら、Settings > General Information に行き、CLIENT ID をコピーして、下記 URL の {CLIENT_ID}
部分を置き換えてブラウザでアクセス。
https://discordapp.com/oauth2/authorize?&client_id={CLIENT_ID}&scope=bot&permissions=0
アクセスすると Bot をサーバーに追加する画面が表示されるので、対象のサーバーを選択して「認証」をクリック。
サーバー管理者じゃなかったりしてプルダウンに対象のサーバーがでてこない時は、サーバー管理者に確認して Bot を追加する権限を付与してもらう必要があります。
サーバーに Bot を追加できるかどうかは、サーバー設定のロールから自分のロールで「サーバー管理」の権限があるかどうかを確認して有効になってれば OK。
メッセージを取得するコードを書く
Bot の追加ができたら、あとはもうコードを書いてメッセージを取得するだけ。
DiscordPHP のインストール
今回は DiscordPHP を使うので、まずは DiscordPHP を Composer でインストールした。
$ composer require team-reflex/discord-php
新規メッセージを取得するコードを書く
まずは誰かが新規でメッセージを投稿したら、それを取得して保存する処理を書く。 といってもめちゃくちゃ簡単でこのくらいのコードを書くだけで動きっぱなしになり、新規投稿があると標準出力に投稿者名と内容が流れてくるようになった。
<?php use Discord\Discord; use Discord\Parts\Channel\Message; use Discord\WebSockets\Event; require_once __DIR__ . '/vendor/autoload.php'; $token = '{TOKEN}'; // Developer Portal から取得した Bot のトークン $discord = new Discord(['token' => $token]); $discord->on('ready', function (Discord $discord) { $discord->on(Event::MESSAGE_CREATE, function (Message $message, Discord $discord) { echo "{$message->author->username}: {$message->content}" . PHP_EOL; // 実際はここでメッセージを DB とかなにかに保存する }); }); $discord->run();
最初、最後の $discord->run();
を書いていなくてなんで動かないか謎だったけど、Qiita をよく見たら書いてあった。
過去のメッセージを取得するコードを書く
PHPerKaigi 2021 の Day1 の途中から取得を始めたため、過去の投稿を取得する必要があったので、Discord のチャンネル毎に過去の投稿を全部取得するコードも書いた。
実際はチャンネルをループで回して全部取得したけど、サンプルは1つのチャンネルの全投稿を取得しています。
<?php use Discord\Discord; use Discord\Helpers\Collection; use Discord\Parts\Channel\Channel; use Discord\WebSockets\Event; require_once __DIR__ . '/vendor/autoload.php'; $token = '{TOKEN}'; // Developer Portal から取得した Bot のトークン $channel_id = '{CHANNEL_ID}'; // チャンネル名を右クリックから「IDをコピー」で取得したチャンネルID function getMessageHistories(Channel $channel, array $option = []) { $channel->getMessageHistory($option)->done(function (Collection $messages) use ($channel) { foreach ($messages as $message) { echo "{$message->author->username}: {$message->content}" . PHP_EOL; // 実際はここでメッセージを DB とかなにかに保存する } if (count($messages) === 100) { getMessageHistories($channel, ['before' => $message]); } }); } $discord = new Discord(['token' => $token]); $discord->on('ready', function (Discord $discord) use ($channel_id) { $channel = $discord->getChannel($channel_id); getMessageHistories($channel); }); $discord->run();
おわりに
前回の iOSDC Japan 2020 から引き継いだコードもあるが、今回「ニコニコ生放送」「Twitter」「Discord」と投稿内容を取得したなかでは Discord が圧倒的に楽だった。
使ったライブラリのおかげもあると思うけど、殆ど自分でコードを書かなくてもリアルタイムに新規投稿を取得でき、めんどくさいことを考えなくて済んだのはよい。
まあ Twitter もちゃんと Streaming API を使えば楽だったんだろうけど、結構昔に書いたコードの焼き直しで済ませてしまったので…。
SQLite 3 でデータを JSON で出力する
PHPerKaigi 2021 で、SQLite にぶち込んでたデータを JSON 形式にして渡す必要があったので、SQLite のデータを JSON にする方法を調べたらめっちゃ簡単に JSON で出力できたって話。
SQLite 3.33.0 から、出力モードに JSON が選べるようになったらしく、なにか特別なことをしなくても出力モードの変更と、結果の出力先の指定をしてあげるだけでよかった。
sqlite> .mode json sqlite> .once 'phperkaigi-tweets-day1.json' sqlite> SELECT * FROM tweets WHERE created_at BETWEEN '2021-03-27 00:00:00' AND '2021-03-27 23:59:59' ORDER BY created_at; sqlite> .exit
これだけで、カレントディレクトリに phperkaigi-tweets-day1.json
ができあがるのでおしまい。 めっちゃ簡単でしたわー。
■
久しぶりの Windows でずっとよく分からず困っていた、Shift とか Ctrl とかのモディファイアキーを押しっぱなしにしているとキーリピートが発生する件、やっぱりイライラするのでふとのどかのデフォルト設定にしたらどうなるんだろうって、プロファイルを切り替えたら発生しなくなった。 てことはやっぱり自分の設定が悪さしてるんだろうなということで、キーリピートの設定をコメントアウトしてみたら直った。 前に一度設定全部消して試してみたつもりだったけどなにか失敗してたのかなぁ。
削除した設定はこれ。Windows 10 になってからちゃんと効いてるのか若干怪しい感じでもあったのでまあ困らないんじゃないかなと思っている。
def option KeyboardDelay = enable 5 5