hamacoの日記

どうでもいい日常をたれながす日記だと思う

iOSDC Japan 2021 で色々とノベルティを作ったよ #iosdc

こんにちは! もう明日が iOSDC Japan 2021 の開催日ですね!
2021年9月17日(金) ~ 19日(日)に開催される iOSDC Japan 2021 で例年通り今年もコアスタッフをしていて、今年はノベルティを色々と作りましたよって話です!
他のことについては開催後にまた書くと思うけど、ノベルティだけでそこそこ書けそうなので先にノベルティの話を。

一般Tシャツ

_DSC0879
(photo by @TAKA_0411)

なんだかんだでカンファレンススタッフ人生が10年近くになるんですが、地味にTシャツ制作というものを一度もやったことがなかったんですよね。
特定の人に依存するようなタスクじゃなければ、大体いつも空いてるタスクがあればやる感じのスタンスで例年やっていたのでなかなかやる機会がなかったんですが、今年はとうとう花形?のTシャツ担当に。

カンファレンスのTシャツってざっくり「UnitedAthle 5001」か「Printstar 085-CVT」の2強になっていて(hamaco調べ)、もちろんどこでも選ばれているから物はとてもよいんですが、 折角自分で好きに作れるんだし、他と同じなんてそれじゃつまらんよねということでその2つを選択肢から外して、Tシャツのベース探しの旅へ。

数年前にユニクロでもオリジナルデザインのTシャツを作れることを知り、ずっと気になりつつ毎年イベントが終わってから思い出す生活をしていたんですが、Tシャツ悩んでいる時にふと思いだし、ユニクロのTシャツがカンファレンスのTシャツになっているって響きだけが面白そうだったので、今年はユニクロにすることにしました。
響きだけといいつつも、ユニクロなら参加者の皆も馴染みもあるだろうし、あれだけ有名な所だし肌触りとかも良い感じだろうと思って作りましたがどうでしたかね。私も当日着るのを楽しみにしています。

ボトルオープナー

_DSC0980
(photo by @TAKA_0411)

iOSDC Japan といえば…そう!ビールですよね(最近は茶会のオシャレドリンクもあるけど)! そんな iOSDC では懇親会で樽のビールと一緒に瓶ビールがでたりしますよね? ということで、ボトルオープナー欲しくない?とふと思ってしまったので突如追加で作りました。 このコロナのご時世使うことがあるのか…? とも思いはしましたが、来年はきっとオフライン開催になり茶会なり懇親会なりも復活するだろうしあってもいいよね!ってことで!

ボトルオープナーは携帯できるやつがあると便利だなーとたまに私が思っていたので、半分趣味で作ってしまった感じではありますが、きっと持ってると便利な時とかあるので是非使ってください! お酒飲まなくても瓶のドリンクを飲む時とか、缶ジュースを開ける時とか、iOSDC Japan 2021 ノベルティの缶ドロップを開ける時とか(!)にも使えるので是非普段から鞄に偲ばせておくと便利かと!

納期にも余裕があり、物的にもこだわれる所も多くなかったので、今年作った中では比較的サクッと作れたので特に書くような苦労話がないな…。

缶ドロップ

_DSC0977
(photo by @TAKA_0411)

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 のバージョンを上げたら解決するんじゃね? と思ってやってみたら無事解決。

https://github.com/microsoft/winget-cli/releases

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 とかを取得する必要があるので、事前に開発者モードを有効にしておくと簡単にその辺りが取得できて便利。
開発者モードを有効にするには、ユーザー設定にある「テーマ」から「開発者モード」を有効にするだけ。(なぜテーマにあるのかは謎)

f:id:hamaco:20210330181816p:plain

開発者モードを有効にすると、サーバーアイコンやサーバー名、チャンネルやメッセージなどを右クリックした時に「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 を追加する権限を付与してもらう必要があります。

f:id:hamaco:20210330181649p:plain

サーバーに Bot を追加できるかどうかは、サーバー設定のロールから自分のロールで「サーバー管理」の権限があるかどうかを確認して有効になってれば OK。

f:id:hamaco:20210330181711p:plain

メッセージを取得するコードを書く

Bot の追加ができたら、あとはもうコードを書いてメッセージを取得するだけ。

DiscordPHP のインストール

今回は DiscordPHP を使うので、まずは DiscordPHP を Composer でインストールした。

github.com

$ 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 Terminal がうるさくて、iTerm2 の Silence bell みたいな設定がないかなーと探していたら、どうやら bellStyle というのがあるらしいので設定したら静かになった。 プロファイルの設定なので、profiles の中で設定して終わり。

    "profiles":
    {
        "defaults":
        {
            "bellStyle": "none",
            ...
        },
    }

どうやら Windows Terminal 1.6 Preview だと visual とか指定ができてタブにベルアイコンがでるとかそういうのもあるらしいけど要らないので普通に none で。

久しぶりの Windows でずっとよく分からず困っていた、Shift とか Ctrl とかのモディファイアキーを押しっぱなしにしているとキーリピートが発生する件、やっぱりイライラするのでふとのどかのデフォルト設定にしたらどうなるんだろうって、プロファイルを切り替えたら発生しなくなった。 てことはやっぱり自分の設定が悪さしてるんだろうなということで、キーリピートの設定をコメントアウトしてみたら直った。 前に一度設定全部消して試してみたつもりだったけどなにか失敗してたのかなぁ。

削除した設定はこれ。Windows 10 になってからちゃんと効いてるのか若干怪しい感じでもあったのでまあ困らないんじゃないかなと思っている。

def option KeyboardDelay = enable 5 5

GitHub CLI が正式リリースされてから hub からの乗り換えをしようとしているけど、地味にリポジトリをブラウザで開くのがめんどくさかったので gh open で開けるようにエイリアスを設定したった。

$ gh alias set open 'repo view --web'

なんかどうなっているのかよく分からないけど WSL2 内の Ubuntu で実行しても Windows 側のブラウザが開くのでこれで多少 hub に近付いて便利になった。 あとは tig で見てる時に o で該当箇所をブラウザで開くのができるとサイコーなんだけどなさそうなんだよねぇ。