<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>shigeta.dev</title>
    <link rel="alternate" type="text/html" href="https://shigeta.dev/" />
    <link rel="self" type="application/atom+xml" href="https://shigeta.dev/atom.xml" />
    <id>tag:localhost,2023-11-15:/shigeta.dev/3</id>
    <updated>2023-12-01T05:51:11Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro</generator>

<entry>
    <title>ブログ記事を聴こう - Untitled Folder</title>
    <link rel="alternate" type="text/html" href="https://shigeta.dev/blog/2023/12/speech-this-article.html" />
    <id>tag:localhost,2023:/shigeta.dev/blog//4.10</id>

    <published>2023-12-01T01:00:00Z</published>
    <updated>2023-12-01T05:51:11Z</updated>

    <summary>こんにちは。こちらは Movable Type Advent Calendar ...</summary>
    <author>
        <name>shigeta</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://shigeta.dev/blog/">
        <![CDATA[<p>こんにちは。こちらは <a href="https://adventar.org/calendars/8999" target="_blank" rel="noopener">Movable Type Advent Calendar 2023</a> 向けの記事です。</p>]]>
        <![CDATA[<p>2023年のトップバッターをいただきましてありがとうございます！</p>
<p>改めまして、こんにちは。重田です。シックス・アパートでエンジニアをしています。</p>
<p>今回は「ブログ記事を読む」のではなく「ブログ記事を聴く」ことにチャレンジします。</p>
<h2>聴く？</h2>
<p>ブログ記事を聴くというとやはりポッドキャストが真っ先に頭に浮かびますよね。しかしポッドキャストだと mp3 など音声ファイルを別途用意する必要があります。音声ファイルを準備するにはツールやウェブサービスに頼る必要がありますし、作成した音声ファイルをホスティングする必要もあり、ポッドキャストを導入するには少し手間がかかります。</p>
<p>Chrome、Edge、Firefox など主要ブラウザにはウェブ音声 API （Web Speech API）が搭載されているので、JavaScript を使ってテキストを読み上げることができます。</p>
<p>今回は Web Speech API を使ってブラウザにブログ記事を朗読してもらいます。読者である私たちはブログ記事を聴くことができるというわけです。</p>
<h2>Web Speech API</h2>
<p>Web Speech API は <a href="https://developer.mozilla.org/ja/docs/Web/API/Web_Speech_API" target="_blank" rel="noopener">MDN の解説</a>に詳しく書いてあります。</p>
<p>Web Speech API は大きく2つに分かれます。一つは音声認識、もう一つは音声合成です。この記事では音声合成を使います。（音声認識は触れません。）</p>
<p>では音声合成の代表的な2つのインターフェースを把握しておきましょう。</p>
<h3>SpeechSynthesis インターフェース</h3>
<p>音声合成は <a href="https://developer.mozilla.org/ja/docs/Web/API/SpeechSynthesis" target="_blank" rel="noopener">SpeechSynthesis</a> インターフェースを使います。</p>
<h4>プロパティ</h4>
<p>プロパティは次の3つです。</p>
<ul>
<li>paused</li>
<li>pending</li>
<li>speaking</li>
</ul>
<p>これらのプロパティで SpeechSynthesis インターフェースの状態がわかります。paused は一時停止中かどうか、pending はキューに溜まっている音声があるかどうか、speaking は現在再生中かどうか、を判定できます。</p>
<p>paused と speaking はイメージできると思いますが、pending のキューについて「どういうこと？」と思った方もいらっしゃると思います。SpeechSynthesis インターフェースはキューになっていますので、音声をどんどん追加していくことが可能なのです。しかしながら、このキューに触れるインターフェースがないので、追加した後に操作することができませんし、何個追加されているかも知ることはできません。代わりに pending プロパティでキューに何かある、ということを知ることができます。</p>
<h4>メソッド</h4>
<p>主に利用するのは次のメソッドだと思います。</p>
<ul>
<li>getVoices</li>
<li>speak</li>
<li>pause</li>
<li>resume</li>
<li>cancel</li>
</ul>
<p>getVoices メソッドはブラウザが持っている音声を配列で返します。SpeechSynthesisVoice オブジェクトの配列になっています。言語ごとに複数の音声があるので必要な音声を getVoices メソッド経由で入手します。</p>
<p>speak メソッドは再生に利用します。pause メソッドは再生中の音声を一時停止し、resume メソッドで一時停止を解除します。cancel メソッドで再生の終了をします。</p>
<h3>SpeechSynthesisUtterance インターフェース</h3>
<p><a href="https://developer.mozilla.org/ja/docs/Web/API/SpeechSynthesisUtterance" target="_blank" rel="noopener">SpeechSynthesisUtterance</a> は再生したい文字列を格納します。</p>
<h4>コンストラクタ</h4>
<p>引数に再生したい文字列を渡します。再生したい文字列を渡すのに text プロパティを使うこともできます。</p>
<h4>プロパティ</h4>
<p>主に利用するのは次のプロパティでしょうか。</p>
<ul>
<li>voice</li>
<li>rate</li>
<li>pitch</li>
</ul>
<p>voide プロパティは音声を設定します。音声は SpeechSynthesis インターフェースの getVoices メソッドで取得します。再生したい言語にあった音声を voice プロパティに設定します。</p>
<p>rate プロパティは再生速度を指定します。デフォルトは1が設定されています。min が 0.1 で max が 10 です。2が2倍速らしいので最大10倍速までいけます。</p>
<p>pitch プロパティは音の高低です。デフォルトは1が設定されています。min が 0 で max が 2 です。</p>
<h4>イベント</h4>
<p>イベントは SpeechSynthesis インターフェースのメソッドと関連しています。start は再生時、pause は一時停止時、resume は一時停止を解除したとき、end は終了時、error はエラー時に発火します。次の例は終了時にコンソールに end と残す方法です。</p>
<pre><code>
ut = new SpeechSynthesisUtterance("Hello world");
ut.onend = function(ev) {
  console.log("end");
};
</code></pre>
<p></p>
<p>以上、SpeechSynthesis と SpeechSynthesisUtterance を理解していれば十分です。</p>
<h3>実装</h3>
<p>では Developer Tools の console でも実行できる実装をみてみましょう。</p>
<p>window オブジェクトに speechSynthesis オブジェクトがぶら下がっているのでこれを使います。</p>
<pre><code>
window.speechSynthesis.speak(new SpeechSynthesisUtterance("Hello world")) 
</code></pre>
<p>speak メソッドの引数に SpeechSynthesisUtterance のインスタンスを渡します。SpeechSynthesisUtterance のコンストラクタの引数には喋らせたい文字列を渡します。</p>
<p>次のように日本語を入れたら喋らない場合があります。</p>
<pre><code>
window.speechSynthesis.speak(new SpeechSynthesisUtterance("こんにちは")) 
</code></pre>
<p>これは SpeechSynthesisUtterance の voice プロパティに日本語対応した声を当てれば解決します。</p>
<pre><code>
ut = new SpeechSynthesisUtterance("こんにちは"); // 喋る内容を定義
voices = window.speechSynthesis.getVoices(); // 声のリストを取得
for (v of voices) { if (v.lang.match(/^ja/i)) { ut.voice = v; break; } } // 日本語の声を検索
window.speechSynthesis.speak(ut); // 喋る！
</code></pre>
<p>利用可能な声は SpeechSynthesis の getVoices メソッドで取得できます。getVoices メソッドは SpeechSynthesisVoice オブジェクトの配列が返ってきます。SpeechSynthesisVoice には lang プロパティがあり、<a href="https://www.rfc-editor.org/info/bcp47" target="_blank" rel="noopener">BCP 47 </a>形式（ 例: ja-JP ）で値が格納されているので、それで調べるのがよさげです。</p>
<p>といった感じで文字列を聴く（音声を再生する）ことができます。簡単ですね。</p>
<h2>Movable Type に組み込む</h2>
<p>ブログ記事に音声プレイヤーを埋め込んでみましょう。</p>
<h3>テンプレート</h3>
<p>音声プレイヤー用に新しくテンプレートモジュールを用意して、記事アーカイブテンプレートに追記します。</p>
<h4>テンプレートモジュール</h4>
<p>次のような内容で SpeechPlayer テンプレートモジュールを用意します。</p>
<pre><code>
&lt;style&gt;
#speech-player {
  right: 15px;
  bottom: 15px;
  padding: 20px;
  position: fixed;
  text-align: right;
  border: 1px solid #000;
  border-radius: 20px;
  background-color: rgba(240, 255, 255, 0.2);
}

#speech-player button {
  padding: 7px;
  margin: 0px 5px 0px 5px;
}
&lt;/style&gt;
&lt;div id="speech-player"&gt;
  &lt;form&gt;
    &lt;p&gt;&lt;mt:BlogLanguage&gt; で話します。&lt;/p&gt;
    &lt;button id="speech" type="submit"&gt;Speech&lt;/button&gt;
    &lt;button id="pause" type="button" disabled&gt;Pause&lt;/button&gt;
    &lt;button id="resume" type="button" disabled&gt;Resume&lt;/button&gt;
    &lt;button id="stop" type="button" disabled&gt;Stop&lt;/button&gt;
    &lt;fieldset&gt;
      &lt;input type="radio" name="rate" id="rateSlow" value="0.7"&gt;&lt;label for="rateSlow"&gt;ゆっくり&lt;/label&gt;
      &lt;input type="radio" name="rate" id="rateMedium" value="0.9" checked&gt;&lt;label for="rateMedium"&gt;普通&lt;/label&gt;
      &lt;input type="radio" name="rate" id="rateFast" value="1.1"&gt;&lt;label for="rateFast"&gt;速く&lt;/label&gt;
      &lt;input type="radio" name="rate" id="rateAnimal" value="2.0"&gt;&lt;label for="rateAnimal"&gt;どうぶつ&lt;/label&gt;
    &lt;/fieldset&gt;
  &lt;/form&gt;
&lt;/div&gt;
&lt;script&gt;
const synthesis = window.speechSynthesis;

document.querySelector("#pause").onclick = function(ev) {
  synthesis.pause();
  document.querySelector("#pause").disabled = true;
  document.querySelector("#resume").disabled = false;
  document.querySelector("#stop").disabled = true;
};

document.querySelector("#resume").onclick = function(ev) {
  synthesis.resume();
  document.querySelector("#pause").disabled = false;
  document.querySelector("#resume").disabled = true;
  document.querySelector("#stop").disabled = false;
};

document.querySelector("#stop").onclick = function(ev) {
  synthesis.cancel();
  document.querySelector("#speech").disabled = false;
  document.querySelector("#pause").disabled = true;
  document.querySelector("#resume").disabled = true;
  document.querySelector("#stop").disabled = true;
  document.querySelectorAll('input[name="rate"]').forEach(function(el) {
      el.disabled = false;
  });
};

document.querySelector("#speech-player form").onsubmit = function(ev) {
  ev.preventDefault();
  if (synthesis.speaking || synthesis.paused || synthesis.pending) {
    alert("ほかで再生中なので再生できません。");
    return;
  }
  const blogLanguage = "&lt;mt:BlogLanguage&gt;";
  const regex = new RegExp("^" + blogLanguage, "i");
  synthesis.getVoices().forEach(function(voice) {
    if (voice.lang.match(regex)) {
      synthesis.voice = voice;
    }
  });
  const text = document.querySelector('.entry-asset').textContent;
  const utterance = new SpeechSynthesisUtterance(text);
  utterance.rate = document.querySelector('input[name="rate"]:checked').value;
  utterance.onend = function(ev) {
    document.querySelector("#speech").disabled = false;
    document.querySelector("#pause").disabled = true;
    document.querySelector("#resume").disabled = true;
    document.querySelector("#stop").disabled = true;
    document.querySelectorAll('input[name="rate"]').forEach(function(el) {
      el.disabled = false;
    });
  };
  utterance.onerror = function (ev) {
    console.log(ev.constructor.name + ":" + ev.error);
  };
  utterance.lang = blogLanguage;
  synthesis.speak(utterance);
  document.querySelector("#speech").disabled = true;
  document.querySelector("#pause").disabled = false;
  document.querySelector("#stop").disabled = false;
  document.querySelectorAll('input[name="rate"]').forEach(function(el) {
    el.disabled = true;
  });
}
&lt;/script&gt;
</code></pre>
<h4>記事アーカイブテンプレート</h4>
<p>上で作成した SpeechPlayer テンプレートモジュールを の前に埋め込みます。次のように body タグを閉じる直前に入れます。</p>
<pre><code>
    &lt;$mt:Include module="SpeechPlayer"$&gt;
    &lt;/body&gt;
</code></pre>
<h3>確認</h3>
<p>次のスクリーンショットのようにページの右下にプレイヤーが表示されます。Speech ボタンで再生します。再生中は Pause ボタンと Stop ボタンが有効になります。Pause ボタンを押すと Resume ボタンが有効になります。最後まで再生すると Speech ボタンが再度有効になります。</p>
<p><img alt="Screenshot 2023-11-27 at 00-14-24 ブログ記事を聴こう - Untitled Folder.png" src="https://shigeta.dev/blog/assets/046550f9d3d466edabc2c063115ac76bfdc7b729.png" width="337" height="135" class="mt-image-none"></p>
<p>前述の通り SpeechSynthesis は SpeechSynthesisUtterance をキューするので、Speech ボタンを連打すると押した回数だけ記事の再生を繰り返してしまうので、一度だけ再生するように再生後は Speech ボタンを無効化しています。</p>
<p>SpeechSynthesisUtterance の rate プロパティに速度を設定するようにしました。ゆっくりは 0.7、普通は 0.9、速くは 1.1、どうぶつは 2 を設定しています。「どうぶつ」というは人気の森のゲームみたいな喋り方です。</p>
<h2>さらにハックする</h2>
<p>この記事で実装はしませんが、前述の例から次のアイデアが考えられます。</p>
<h3>声の選択</h3>
<p>Movable Type のテンプレートでは <a href="https://www.movabletype.jp/documentation/appendices/tags/bloglanguage.html" target="_blank" rel="noopener">MTBlogLanguage</a> を使って自動的に音声を選択しました。Mac Firefox の場合、かつブログの言語設定が日本語（ja）を使っている場合は SpeechSynthesis の ja-JP を使う音声は1つ（Kyoko）だけでしたので特に問題ありません。しかし、Chrome では4つ（Hattori、Kyoko、O-Ren、Google 日本語）ありました。en-US はもっとたくさんの音声があり、自動的に選ぶよりはどれかを選択したい読者もいることでしょう。そこで音声を選択できるように対応したら汎用性が上がると思います。SpeechSynthesis インターフェースの getVoices メソッドで音声を列挙できますので言語選択フォームを追加してあげるとよいでしょう。以下のような感じで言語に合ったリストを確認できます。</p>
<pre><code>
window.speechSynthesis.getVoices().forEach((v) =&gt; { if (v.lang.match(/^ja/i)) { console.log(v.name) } })
</code></pre>
<h3>範囲を選択した再生</h3>
<p>今回の例ではブログ記事全体を textContent で抽出しているので問答無用で全体を再生していますが、特にコードのところは何を言っているのか意味不明な印象もあったでしょう。pre タグは飛ばすとか範囲選択された部分のみを再生するとかそういった機能があるとより聴きやすくなると思います。textContent ではなく読みやすさを重視して記事内容をフィルタリングしてから SynthesisUtterance を用意すると音声再生を利用する読者も増えるかもしれませんね。</p>
<h2>まとめ</h2>
<p>今回はブラウザのウェブ音声 API の音声合成を使ってブログ記事を聴くことについて取り上げました。自然な喋り方ではないので違和感があるかもしれませんが、逆にこのくらいでも十分と感じる方もいらっしゃると思います。今回の記事で何か実装のヒントになれば幸いです。</p>
<p>Happy coding!</p>
<p></p>
<p>（2023/12/01 14:24 追記）</p>
<p>Mac の Frefox と Safari では「どうぶつ」を選んだときに何を言っているかわからない、まさにどうぶつの人気シリーズの森のキャラクターみたいな声だったんですが、Chrome だと割とちゃんと聴こえてしまうというオチにならない結果があることを教えていただきました。ぜひ Firefox や Safari でお楽しみください！</p>
<p>加えて、ブラウザごとに挙動に違いがある点に注意して使いたい API ですね。</p>
<p></p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/_rRdFPVwh0I?si=9LDXnLmgDfbZ-t4C&amp;start=7" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<p></p>
<h2>See Also</h2>
<ul>
<li><a href="https://adventar.org/calendars/8999" target="_blank" rel="noopener">Movable Type Advent Calendar 2023</a></li>
<li><a href="https://developer.mozilla.org/ja/docs/Web/API/Web_Speech_API" target="_blank" rel="noopener">ウェブ音声 API</a></li>
<li><a href="https://developer.mozilla.org/ja/docs/Web/API/SpeechSynthesis" target="_blank" rel="noopener">SpeechSynthesis</a></li>
</ul>]]>
    </content>
</entry>

<entry>
    <title>Movable Type の OpenAPI スキーマ対応をご存知ですか？ - Untitled Folder</title>
    <link rel="alternate" type="text/html" href="https://shigeta.dev/blog/2022/12/movable-type-openapi.html" />
    <id>tag:localhost,2022:/shigeta.dev/blog//4.11</id>

    <published>2022-12-02T01:00:00Z</published>
    <updated>2023-11-25T15:12:03Z</updated>

    <summary>こんにちは。こちらは Movable Type Advent Calendar ...</summary>
    <author>
        <name>shigeta</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://shigeta.dev/blog/">
        <![CDATA[<p>こんにちは。こちらは <a href="https://adventar.org/calendars/7425" target="_blank" rel="noopener">Movable Type Advent Calendar 2022</a> 向けの記事です。</p>]]>
        <![CDATA[<p>改めまして、こんにちは。重田です。（公開当初は名乗っていなかったので）</p>
<p>Advent Calendar 初参加なのでお手柔らかにお願いします！</p>
<p>先日 <a href="https://mtddc2022.mt-tokyo.net/" target="_blank" rel="noopener">MTDDC Meetup TOKYO 2022</a> の<a href="https://mtddc2022.mt-tokyo.net/session/mt01.html" target="_blank" rel="noopener">キーノート</a>でも触れられていましたが、<a href="https://www.sixapart.jp/press_releases/2022/11/16-1100.html" target="_blank" rel="noopener">次期 Movable Type が2023年秋にリリース</a>されるそうです。Movable Type 8 となり、その<a href="https://www.movabletype.jp/blog/mt8-overview.html" target="_blank" rel="noopener">機能概要も公開</a>されました。</p>
<p>その機能概要の新機能・機能強化でも触れられていますが、</p>
<blockquote>
<p><span style="font-weight: 400;">OpenAPI JSON Schema にはすでに対応済 (r.5201)</span></p>
</blockquote>
<p><span style="font-weight: 400;">とありますようにすでに Movable Type に OpenAPI スキーマを出力する機能がついているのをご存知でしょうか？</span></p>
<p><span style="font-weight: 400;">そこで今回は OpenAPI スキーマについて紹介します。</span></p>
<h2>Movable Type の OpenAPI スキーマ</h2>
<p>OpenAPI スキーマのエンドポイントには MTDataAPIScript （デフォルトでは mt-data-api.cgi）に v1 〜 5 のバージョンを付与してアクセスします。</p>
<p>例えば管理画面の URL が https://app.example.com/cgi-bin/mt/mt.cgi の場合、おおよそ次のような URL になります。</p>
<ul>
<li>https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v1/</li>
<li>https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v2/</li>
<li>https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v3/</li>
<li>https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v4/</li>
<li>https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v5/</li>
</ul>
<p>それぞれのバージョンで対応しているリソースが異なりますので、バージョンごとにスキーマも異なります。</p>
<p>JSON 形式でレスポンスが返ってきます。この JSON のフォーマットは <a href="https://swagger.io/specification/" target="_blank" rel="noopener">OpenAPI Specification</a> に準拠しています。</p>
<p>これまでの一般的な ウェブサービスの REST API を利用する場合、送信パラメータやレスポンスの内容はそのウェブサービスの公式ドキュメントを読んでから利用することが多かったと思います。それを汎用的な JSON スキーマ形式で提供してクライアント側やサーバ側で利用しやすいように定義したのが OpenAPI スキーマです。</p>
<p>OpenAPI スキーマには送信パラメータやレスポンスの型情報も含まれているので、Data API クライアントを自作する場合に入力値の検証やレスポンス値の利用もより安全になると思います。</p>
<p><a href="https://www.movabletype.jp/" target="_blank" rel="noopener">Movable Type のドキュメントサイト</a>の<a href="https://www.movabletype.jp/developers/data-api/" target="_blank" rel="noopener">開発者ポータル</a>でも REST API のドキュメントを提供しています。バージョンごとに API リファレンスを提供していますが、これらも OpenAPI スキーマをベースに生成しています。</p>
<p>このようにプログラムからだけでなくドキュメント生成まで API に関することを幅広く利用できるのが OpenAPI スキーマのメリットだと思います。</p>
<h2>OpenAPI スキーマを利用する</h2>
<p>早速、OpenAPI スキーマを利用して Data API を試してみたいと思います。人気があるツールでもある <a href="https://swagger.io/tools/swagger-ui/" target="_blank" rel="noopener">Swagger UI</a> を紹介します。</p>
<h3>Swagger UI</h3>
<p>Swagger UI は OpenAPI スキーマを出力するエンドポイントの URL を入力すると自動的に API 一覧を生成しプレイグラウンドとして API を利用できます。（Swagger UI の<a href="https://petstore.swagger.io/" target="_blank" rel="noopener">ライブデモ</a> があります。エンドポイントに <a href="https://petstore.swagger.io/v2/swagger.json" target="_blank" rel="noopener">https://petstore.swagger.io/v2/swagger.json</a> を指定して API の一覧を表示しています。）</p>
<p>同じように Movable Type の OpenAPI スキーマを利用して Data API を体験してみましょう。</p>
<p>個人的に Swagger UI を利用するのに手っ取り早いと感じるのは Docker を使うやり方です。<a href="https://swagger.io/docs/open-source-tools/swagger-ui/usage/installation/" target="_blank" rel="noopener">Swagger UI のインストールドキュメント</a>に Docker の章がありますので参照してみてください。</p>
<p>docker コマンドで起動できましたら画面上部の URL 入力フォームにご自身の Movable Type の OpenAPI スキーマのエンドポイント（例: <code>https://app.example.com/cgi-bin/mt/mt-data-api.cgi/v5/</code> ）を入力し Explore ボタンを押すと Movable Type Data API のエンドポイント一覧が読み込まれます。</p>
<p><img alt="40-Screen Shot 2022-11-30 at 11.41.26.png" src="https://shigeta.dev/blog/assets/40-Screen%20Shot%202022-11-30%20at%2011.41.26.png" width="617" height="40" class="mt-image-none"></p>
<h4>認証</h4>
<p>Movable Type の開発者ポータルにある<a href="https://www.movabletype.jp/developers/data-api/quick-start/" target="_blank" rel="noopener">クイックスタートガイド</a>のユーザー認証とアクセストークンの章にありますが、Data API で直接サインインする場合は <code>POST http(s)://path/to/mt-data-api.cgi/v2/authentication</code> を使います。</p>
<p>そして得られたアクセストークンを使います。クイックスタートガイドにありますように</p>
<blockquote>
<p>アクセストークンは、<strong>X-MT-Authorization</strong> リクエストヘッダーに <strong>MTAuth accessToken=&lt;ACCESS_TOKEN&gt;</strong>という形式で指定します。</p>
</blockquote>
<p>とありますので、Swagger UI の認証（鍵のアイコン）のところで以下のダイアログが出ましたら、入力フォームのところには <strong>MTAuth accessToken=アクセストークン</strong> を入力してください。</p>
<p><img alt="44-Screen Shot 2022-11-30 at 16.57.23.png" src="https://shigeta.dev/blog/assets/44-Screen%20Shot%202022-11-30%20at%2016.57.23.png" width="448" height="300" class="mt-image-none"></p>
<p>これで認証が必要な API も利用できるようになると思います。</p>
<h3>OpenAPI テーマ</h3>
<p>ご自身で Docker で Swagger UI を立ち上げる以外の方法として Movable Type のテーマを作ってみました。</p>
<ul>
<li><a href="https://github.com/comewalk/mt-theme-swagger-ui" target="_blank" rel="noopener">https://github.com/comewalk/mt-theme-swagger-ui</a></li>
</ul>
<p>これは <a href="https://www.npmjs.com/package/swagger-ui-dist" target="_blank" rel="noopener">Swagger UI Dist</a> を利用したインデックスページのみを作るテーマです。</p>
<p>Data API の動作確認用のウェブサイトを作り、このテーマを適用するとインデックスページが Swagger UI が適用されたページとなります。インデックステンプレートに</p>
<pre><code>
url: '&lt;$mt:AdminCGIPath$&gt;&lt;$mt:DataAPIScript$&gt;/v5/',
</code></pre>
<p>と記述されていますので、動作確認用のウェブサイトの URL で Data API v5 のエンドポイントが自動的に設定されます。</p>
<p>開発用途でお使いいただくのに便利だと思います。</p>
<p><img alt="41-Screen Shot 2022-11-30 at 11.52.09.png" src="https://shigeta.dev/blog/assets/41-Screen%20Shot%202022-11-30%20at%2011.52.09.png" width="434" height="312" class="mt-image-none"></p>
<h2>OpenAPI スキーマから Data API クライアントを作る</h2>
<p>Swagger UI でも十分に Data API の体験ができますが、OpenAPI スキーマをさらに利用してみたいと思います。</p>
<p>Data API は主にプログラムから利用すると思います。</p>
<p>OpenAPI スキーマから各種プログラミング言語用のクライアントを生成するツールがありますのでそれを紹介します。</p>
<p>有名どころとしては <a href="https://openapi-generator.tech/" target="_blank" rel="noopener">OpenAPI Generator</a> だと思います。</p>
<p>試した環境は次の通りです。</p>
<pre><code>
% sw_vers
ProductName:	macOS
ProductVersion:	11.6.8
BuildVersion:	20G730
</code></pre>
<p>まずは OpenAPI スキーマを JSON ファイルとしてダウンロードします。</p>
<pre><code>
% curl -o v5.json https://api.example.com/cgi-bin/mt/mt-data-api.cgi/v5/
</code></pre>
<p>次に <a href="https://openapi-generator.tech/docs/installation#docker" target="_blank" rel="noopener">OpenAPI Generator のインストールの Docker の章</a>を参考に実行します。今回は Python でクライアントを作ってみましょう。（プログラミング言語は<a href="https://openapi-generator.tech/docs/generators/" target="_blank" rel="noopener">いろいろ対応</a>しています）</p>
<pre><code>
% docker run --rm \
  -v ${PWD}:/local openapitools/openapi-generator-cli generate \
  -i /local/v5.json \
  -g python \
  -o /local/out/python
</code></pre>
<p>docker image の作成や実際に <code>open-api-cli</code> 生成する間しばらく待つと <code>out/python</code> ディレクトリに作成されます。</p>
<pre><code>
% du -hs out
 16M	out
% find out/python -type f | wc -l
    1352
</code></pre>
<p>とても大量でした......</p>
<p>とりあえず試してみます。</p>
<pre><code>
% cd out/python
% virtualenv -p python3 env
% source env/bin/activate
% pip install -r requirements.txt
</code></pre>
<p>必要なライブラリは pip でインストールしました。</p>
<p><code>out/python/README.md</code> の Getting Started にコードのサンプルがあるのでコピペします。（インデントや構文エラーがあったのでそれは修正しました）</p>
<pre><code>
import time
import openapi_client
from pprint import pprint
from openapi_client.apis.tags import assets_api
from openapi_client.model.asset import Asset
from openapi_client.model.asset_updatable import AssetUpdatable
from openapi_client.model.entry import Entry
from openapi_client.model.error_content import ErrorContent
from openapi_client.model.page import Page

configuration = openapi_client.Configuration(
    host = "https://api.example.com/mt/mt-data-api.cgi/v5"
)

configuration.api_key['mtauth'] = 'YOUR_API_KEY'

with openapi_client.ApiClient(configuration) as api_client:
    # Create an instance of the API class
    api_instance = assets_api.AssetsApi(api_client)
    overwrite_once = 0 # int | If specify \"1\", the API always overwrites an existing file with the uploaded file. This parameter has been available since Movable Type 6.1.2 (optional)
    body = dict(
        auto_rename_if_exists=0,
        auto_rename_non_ascii=0,
        file=open('/path/to/file', 'rb'),
        normalize_orientation=1,
        path="path_example",
        site_id=1,
    ) # {str: (bool, date, datetime, dict, float, int, list, str, none_type)} |  (optional)

    try:
        # Upload a file
        api_response = api_instance.assets_upload_post(overwrite_once=overwrite_once, body=body)
        pprint(api_response)
    except openapi_client.ApiException as e:
        print("Exception when calling AssetsApi-&gt;assets_upload_post: %s\n" % e)
</code></pre>
<p>では実行してみます。</p>
<pre><code>
% python myclient.py
ModuleNotFoundError: No module named 'openapi_client.model.asset_updatable'
</code></pre>
<p>ん？モジュールがない？</p>
<pre><code>
% ls openapi_client/model/asset*
openapi_client/model/asset.py   openapi_client/model/asset.pyi
</code></pre>
<p>grep しても asset_updatable クラスの定義がない......。ということで、Python はあまり相性がよくなさそうですね......。</p>
<p>気を取り直して Perl で試してみました。結論から言うと Perl では無事に実行できました。</p>
<pre><code>
% docker run --rm \
  -v ${PWD}:/local openapitools/openapi-generator-cli generate \
  -i /local/v5.json \
  -g perl \
  -o /local/out/perl
% cd out/perl
% vi cpanfile
% cat cpanfile
requires 'Class::Accessor';
requires 'Class::Data::Inheritable';
requires 'DateTime';
requires 'Log::Any';
requires 'LWP::Protocol::https';
requires 'URI::Query';
% carton install
% vi myclient.pl
% cat myclient.pl
use WWW::OpenAPIClient::AuthenticationApi;
use WWW::OpenAPIClient::AssetsApi;
use Data::Dumper;

my $auth_instance = WWW::OpenAPIClient::AuthenticationApi-&gt;new;
my $auth_obj = $auth_instance-&gt;authentication_post(
    client_id =&gt; 'test',
    password =&gt; 'fjz5mcws',
    username =&gt; 'Melody', 
);
my $access_token = $auth_obj-&gt;access_token;

my $api_instance = WWW::OpenAPIClient::AssetsApi-&gt;new(
    api_key =&gt; {'X-MT-Authorization' =&gt; "MTAuth accessToken=$access_token"},
);

my $overwrite_once = 1;
my $auto_rename_if_exists = 0;
my $auto_rename_non_ascii = 1;
my $file = "movable-type-logo.png";
my $normalize_orientation = 1;
my $path = "path_example";
my $site_id = 1;

eval {
    my $result = $api_instance-&gt;assets_upload_post(overwrite_once =&gt; $overwrite_once, auto_rename_if_exists =&gt; $auto_rename_if_exists, auto_rename_non_ascii =&gt; $auto_rename_non_ascii, file =&gt; $file, normalize_orientation =&gt; $normalize_orientation, path =&gt; $path, site_id =&gt; $site_id);
    print Dumper($result);
};
if ($@) {
    warn "Exception when calling AssetsApi-&gt;assets_upload_post: $@\n";
}
% perl -I lib -I local/lib/perl myclient.pl
</code></pre>
<p>こちらも <code>out/perl/README.md</code> をほぼコピペしています。違いとしては <code>WWW::OpenAPIClient::AuthenticationApi</code> を使ってアクセストークンを取得した点とそのアクセストークンを <code>WWW::OpenAPIClient::AssetsApi-&gt;new</code> の引数に渡したところです。Swagger UI のところでもお伝えしました通り、Movable Type Data API はリクエストヘッダに <code>X-MT-Authorization: MTAuth accessToken=アクセストークン</code> （API によっては sessonId の場合もあります）を渡す必要があります。</p>
<p>クラス名など色々と怪しい部分もありますが、OpenAPI Generator はあくまで雛形作成であって、生成後は自身でカスタマイズしていく方向のようですね。とっかかりとしては便利かもしれません。</p>
<h2>まとめ</h2>
<p>この記事で Movable Type が OpenAPI スキーマに対応したことや OpenAPI スキーマの利用用途について簡単にお話ししました。</p>
<p>Movable Type が OpenAPI スキーマに対応したことで Data API を利用する環境がより身近になったと思います。Movable Type Advent Calendar 2022 の1日目の <span class="entryUser" data-v-a52ecc02="">Yoshiki Kato</span> さんの記事『<a href="https://hyper-text.org/archives/2022/12/creating_jamstack_blog_astrojs_and_mt_data_api.shtml" target="_blank" rel="noopener">Astro.js と Movable Type Data API を使用して Jamstack な Blog を作ってみる | WWW WATCH</a>』でも <a href="https://jamstack.org/" target="_blank" rel="noopener">Jamstack</a> が触れらていましたが、Movable Type Data API が Jamstack をはじめとする様々な API エコノミーの選択肢に入るようになるとうれしいです。もし Movable Type Data API を活用する機会があれば各種ソーシャルネットワークやブログなどでぜひ紹介してくださいね！</p>
<p>Happy coding!</p>
<h2>See Also</h2>
<ul>
<li><a href="https://adventar.org/calendars/7425" target="_blank" rel="noopener"><span>Movable Type Advent Calendar 2022 - Adventar</span></a></li>
<li id="line1"><a href="https://www.sixapart.jp/press_releases/2022/11/16-1100.html" target="_blank" rel="noopener"><span>CMSプラットフォーム Movable Type の次期バージョン「Movable Type 8」を2023年秋にリリース予定 - プレスリリース | シックス・アパート - CMSソフトウェア、サービスを提供</span></a></li>
<li><a href="https://www.movabletype.jp/blog/mt8-overview.html" target="_blank" rel="noopener"><span>2023年秋にリリース予定の Movable Type 8 の概要 - ブログ | CMSプラットフォーム Movable Type ドキュメントサイト</span></a></li>
<li><a href="https://swagger.io/specification/" target="_blank" rel="noopener"><span>OpenAPI Specification</span></a><a href="https://adventar.org/calendars/7425" target="_blank" rel="noopener"><span></span></a></li>
<li><a href="https://www.movabletype.jp/developers/data-api/" target="_blank" rel="noopener"><span>Data API ドキュメント - 開発者ポータル | CMSプラットフォーム Movable Type ドキュメントサイト</span></a><span></span></li>
</ul>]]>
    </content>
</entry>

<entry>
    <title>YAPC::Fukuoka 2017 HAKATA で「Web API の未来」を話してきた - Untitled Folder</title>
    <link rel="alternate" type="text/html" href="https://shigeta.dev/blog/2017/07/yapcfukuoka-2017-hakata-web-api.html" />
    <id>tag:localhost,2017:/shigeta.dev/blog//4.49</id>

    <published>2017-07-06T06:00:00Z</published>
    <updated>2023-12-06T07:08:09Z</updated>

    <summary>YAPC::Fukuoka 2017 HAKATA で「Web API の未来」...</summary>
    <author>
        <name>shigeta</name>
        
    </author>
    
        <category term="events" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://shigeta.dev/blog/">
        <![CDATA[<p><a href="http://yapcjapan.org/2017fukuoka/" title="" target="_blank">YAPC::Fukuoka 2017 HAKATA</a> で<a href="http://yapcjapan.org/2017fukuoka/talks.html#/detail/29" title="" target="_blank">「Web API の未来」</a>と題してトークをしました。</p>
]]>
        <![CDATA[<h3>博多！</h3>

<p>4年ぶり、人生2度目、博多大好き！
どことなく南の方の顔つきのせいかわかりませんが、博多はすごく好きな街です。（よく現地の人に間違われますが生まれも育ちも神奈川県）</p>

<p>トークに採用していただいたので<a href="https://www.sixapart.jp/" title="" target="_blank">会社</a>にお願いして旅費と宿泊費を出してもらいました😁
到着したら湿気がすごくて暑かったですね😣</p>

<h3>前夜祭</h3>

<p>博多駅近くに宿を取ったのですが、Google Map で前夜祭会場のヌーラボさんのオフィスまで距離を見たら歩けそうだったから歩いたです。そしたら途中で通り雨に会うし、何気に距離があるし、電車という選択をすればよかったです😵
YAPC::Japan シリーズになってからはじめての参戦でしたが、前夜祭は YAPC::Asia で見た雰囲気そのもので盛り上がっていましたね。本編がワクワクしてきたのでした。
東京でよくお目にかかるみなさんに簡単なご挨拶だけさせてもらいました。</p>

<p><a href="https://shigeta.dev/blog/assets/IMG_6666.jpg" data-test="popup-now" onclick="window.open(this.href,'popup','width=1280,height=961,scrollbars=yes,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><figure class="mt-figure mt-figure-center"><img src="https://shigeta.dev/blog/assets_c/2023/12/IMG_6666-thumb-320xauto-44.jpg" width="320" height="240" alt="IMG_6666.jpg" class="mt-image-none" style="" /><figcaption>前夜祭のケータリング</figcaption></figure></a></p>

<h3>当日</h3>

<p>LINE Fukuoka オフィスが会場でした。とても開放感のあるオフィスで素晴らしいオフィスでした。コーヒーも振る舞っていただきありがたい限りです。（さすがくしいさん）</p>

<div style="width: 100%; text-align: center">

<a href="https://shigeta.dev/blog/assets/IMG_6669.jpg" data-test="popup-now" onclick="window.open(this.href,'popup','width=1280,height=961,scrollbars=yes,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><figure style="display: inline-block" class="mt-figure mt-figure-left"><img src="https://shigeta.dev/blog/assets_c/2023/12/IMG_6669-thumb-320xauto-49.jpg" width="320" height="240" alt="IMG_6669.jpg" class="mt-image-none" style="" /><figcaption>A会場</figcaption></figure></a>

<a href="https://shigeta.dev/blog/assets/IMG_6670.jpg" data-test="popup-now" onclick="window.open(this.href,'popup','width=1280,height=961,scrollbars=yes,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><figure style="display: inline-block" class="mt-figure mt-figure-left"><img src="https://shigeta.dev/blog/assets_c/2023/12/IMG_6670-thumb-320xauto-47.jpg" width="320" height="240" alt="IMG_6670.jpg" class="mt-image-none" style="" /><figcaption>B会場</figcaption></figure></a>

<a href="https://shigeta.dev/blog/assets/IMG_6676.jpg" data-test="popup-now" onclick="window.open(this.href,'popup','width=1280,height=961,scrollbars=yes,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><figure style="display: inline-block" class="mt-figure mt-figure-center"><img src="https://shigeta.dev/blog/assets_c/2023/12/IMG_6676-thumb-320xauto-46.jpg" width="320" height="240" alt="IMG_6676.jpg" class="mt-image-none" style="" /><figcaption>ノベルティ</figcaption></figure></a>

<a href="https://shigeta.dev/blog/assets/IMG_6668.jpg" data-test="popup-now" onclick="window.open(this.href,'popup','width=1280,height=1281,scrollbars=yes,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><figure style="display: inline-block" class="mt-figure mt-figure-center"><img src="https://shigeta.dev/blog/assets_c/2023/12/IMG_6668-thumb-320xauto-48.jpg" width="320" height="320" alt="IMG_6668.jpg" class="mt-image-none" style="" /><figcaption>パンフレット</figcaption></figure></a>

<br style="clear:both"/>
</div>

<p>当日は自分のトークの準備やお昼などで少し中抜けしましたが次のトークを聞いていました。</p>

<ul>
<li><a href="http://yapcjapan.org/2017fukuoka/timetable.html#/detail/1" title="" target="_blank">2017年夏のPerl (40min) charsbar </a></li>
<li>徳丸さんのトーク</li>
<li><a href="http://yapcjapan.org/2017fukuoka/timetable.html#/detail/14" title="" target="_blank">未来のプログラマー達へ ~Perl入学式卒業生から~ (20min) tomcha_ </a></li>
<li><a href="http://yapcjapan.org/2017fukuoka/timetable.html#/detail/25" title="" target="_blank">未来志向のCPANモジュール開発 - アイデアを生み出し実装する方法 (20min) 木本　裕紀 </a></li>
<li><a href="http://yapcjapan.org/2017fukuoka/timetable.html#/detail/18" title="" target="_blank">The plan of Aniki 2.0 (20min) karupanerura</a> </li>
<li><a href="http://yapcjapan.org/2017fukuoka/timetable.html#/detail/39" title="" target="_blank">サービスディレクターの意思決定を支える技術 (20min) AirReader</a> </li>
<li><a href="http://yapcjapan.org/2017fukuoka/timetable.html#/detail/47" title="" target="_blank">新時代のテストフレームワークTest2 (20min) akiym</a></li>
<li><a href="http://yapcjapan.org/2017fukuoka/timetable.html#/detail/3" title="" target="_blank">スキップしていいテスト、スキップしてはいけないテスト　〜速さと信頼を兼ねたテストコードを構築する術〜 (40min) macopy </a></li>
<li>Sponsor Session</li>
<li>Lightning Talks</li>
<li>Sponsor Session</li>
<li>Keynote</li>
</ul>

<h4>Perl6</h4>

<p>charsbar さんのトークを聞きながら Perl6 の足音が近づいてきた印象がありました。ぼちぼち触ってみようかな。ちょうど私のトークの裏番組が tokuhirom さんの Perl6 の話だったので聞けなかったのは残念。</p>

<h4>テストツール</h4>

<p>終盤でテストのトーク2つを聞きましたが Test2 が気になりますねえ。Perl もちゃんと進化してる感じが出てて「未来」というテーマに合っていましたね。</p>

<h3>自分のトーク「Web API の未来」</h3>

<p>福岡といえば<a href="https://www.avispa.co.jp/" title="" target="_blank">アビスパ福岡</a>ですね！なので前日にアビスパのショップに行ってコンフィットTシャツを買って着ました！</p>

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">14:20からB会場は Takatsugu Shigeta( <a href="https://twitter.com/comewalk">@comewalk</a> ) さんによる「 Web API の未来」です！<a href="https://twitter.com/hashtag/yapcjapan?src=hash">#yapcjapan</a> <a href="https://twitter.com/hashtag/yapcjapanB?src=hash">#yapcjapanB</a> <a href="https://t.co/M4kPNTER4u">pic.twitter.com/M4kPNTER4u</a></p>&mdash; yapcjapan (@yapcjapan) <a href="https://twitter.com/yapcjapan/status/881020490583752704">July 1, 2017</a></blockquote>

<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<script async class="speakerdeck-embed" data-id="c7046ee2dd4141d6aba0247304fa07df" data-ratio="1.33333333333333" src="//speakerdeck.com/assets/embed.js"></script>

<p>GraphQL が次の5年の API の未来を担うのか？いや、GraphQL がスタンダードにはならないかもしれないけれども、クライアントサイドで処理しやすい JSON 形式で好みのデータが簡単に取り出せる API が主流になるのは明らか、というのが言いたいところでした。</p>

<p>ついでに GraphQL の Perl 実装がなかったので自作しました、という話をしようかと思ったらすでに GraphQL という namespace が取られていたので違う名前にしようっかな、というオチもありました。</p>

<p>自分で GraphQL のモジュールを作り始めたころは CPAN に GraphQL のモジュールはありませんでしたのでゴリゴリ書いていたわけです。で、発表直前（3分前！）に「あ、CPAN チェックしておくか」と思って検索したら GraphQL が取られていたという😭</p>

<p>namespace の件は tokuhirom さんや charsbar さんに相談したら、まずはメンテナーに連絡して namespace 譲ってもらえるか確認しつつ、相手が手放さない感じであれば PR 送ってみるとか別名で登録するとかがいいんじゃない？って教えてもらいました。</p>

<p>「そういうのはさっさと作ってあげちゃわないと」って tokuhirom さんに言われてぐうの音も出ないと😅</p>

<p>サーバサイドの DB のスキーマからリソース定義して REST API を用意してそれをクライアントサイドから呼ぶのではなく、クライアントサイドからほしいデータを最小ステップで取りに行く手段を提供する API がこれからの主流ですのでこれから API を公開する予定でしたら REST にとらわれない発想で作るのがいいですよ。それが GraphQL を使うのかどうかはクライアントの実装次第だと思います。</p>

<h3>懇親会</h3>

<p>もつ鍋を囲みながら懇親会でした。100名ほどがいたと思いますが座敷のテーブル席だったのでなかなか移動ができず多くの方と話せなかったのは残念でしたが色々な方と福岡の事情や懐かしい人の話とかできて楽しかったです。
KPI 的には<a href="https://www.sixapart.jp/jobs/" title="" target="_blank">私の勤める会社に興味のある方</a>に声をかけることでしたがこのブログを読んだ方が私に連絡してくださることを心待ちにしております🙏</p>

<h3>二次会</h3>

<p>YAPC::Asia の頃は東京開催でしたので終電を気にしてなかなか二次会に行けなかったですが、今回は宿泊でしたので二次会にもお邪魔しました。LINE のTシャツを着た人たちと話せて楽しかったです😄</p>

<h3>次は沖縄！</h3>

<p>次は沖縄で開催ですね。上司に話をしましたら「またトーク応募してね」ということでしたので沖縄で何か発表できるよう応募したいと思います。</p>

<h3>最後に</h3>

<p>運営のみなさんは大変だったと思いますが参加者の雰囲気などからも YAPC::Fukuoka の開催は成功だったと感じました。地元が半分、地元以外が半分くらいの比率だったと思いますが、地元の比率が上がると地元の活性になると思いますし、参加者の母数が増えればそれもまた活性につながると思います。博多は交通のアクセスもよく、街もきれいだけど、山笠のような伝統的な祭もあり、良いところなのでまた YAPC::Fukuoka が開催されるときにはお邪魔したいです。ありがとうございました！</p>

<h3>おまけ</h3>

<p>会社のブログでも紹介されましたのでお時間があったら読んでみてください。
<a href="https://www.sixapart.jp/pressroom/2017/07/hwsa_20170703.html" title="" target="_blank">YAPC::Fukuoka に参加してきました！の巻 [ほぼ週刊SA]</a></p>
]]>
    </content>
</entry>

<entry>
    <title>Hello 2016 - Untitled Folder</title>
    <link rel="alternate" type="text/html" href="https://shigeta.dev/blog/2016/01/hello-2016.html" />
    <id>tag:localhost,2016:/shigeta.dev/blog//4.47</id>

    <published>2016-01-06T02:22:00Z</published>
    <updated>2023-12-06T02:32:36Z</updated>

    <summary>あけましておめでとうございます！ ...</summary>
    <author>
        <name>shigeta</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://shigeta.dev/blog/">
        <![CDATA[<p>あけましておめでとうございます！</p>
]]>
        <![CDATA[<p>2016年がはじまりました。後厄になります。</p>

<p>2015年は本厄でした。人生の先輩から「本厄は自分じゃなくて周りに来るんだよねー」と聞いていましたが、本当に私の周辺にいろいろとありました。忘れられない一年となりました。</p>

<p>2016年の初詣でおみくじを引き大吉が出ました。今年は良い一年になるといいなあ。ま、今年も例年通り忙しい年になりそうなのは確定なので頑張ります。引き続きよろしくお願いします。</p>
]]>
    </content>
</entry>

<entry>
    <title>Shibuya Perl Mongersテクニカルトーク#17 に行ってきた - Untitled Folder</title>
    <link rel="alternate" type="text/html" href="https://shigeta.dev/blog/2015/06/shibuya-pm-17.html" />
    <id>tag:localhost,2015:/shigeta.dev/blog//4.44</id>

    <published>2015-06-03T07:18:39Z</published>
    <updated>2023-12-06T04:56:19Z</updated>

    <summary>Shibuya Perl Mongersテクニカルトーク#17 にお邪魔してきま...</summary>
    <author>
        <name>shigeta</name>
        
    </author>
    
        <category term="events" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://shigeta.dev/blog/">
        <![CDATA[<p><a href="http://shibuya.pm.org/blosxom/techtalks/201506.html" target="_blank">Shibuya Perl Mongersテクニカルトーク#17</a> にお邪魔してきました。</p>

<p><a href="https://shigeta.dev/blog/assets/IMG_5084.jpg" data-test="popup-now" onclick="window.open(this.href,'popup','width=2448,height=2449,scrollbars=yes,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="https://shigeta.dev/blog/assets_c/2023/12/IMG_5084-thumb-300xauto-39.jpg" width="300" height="300" alt="IMG_5084.jpg" class="mt-image-none" style="" /></a>
<br /></p>
]]>
        <![CDATA[<p><a href="http://shibuya.pm.org/blosxom/techtalks/201107.html" target="_blank">前回</a>から4年が経過したそうです。最近 <a href="http://shibuya.pm.org" target="_blank">shibuya.pm</a> の活動がないなあと思っていたので #17 の開催は楽しみでした。</p>

<h2>濃かった</h2>

<p>改めて Perl って面白いなって思いました。約2時間でしたがあっという間でした。4年経っても shibuya.pm は shibuya.pm でした。
()[()] とか Perl を PHP や javascript にしちゃうとか ppencode とか変態的な感じは shibuya.pm ならではだと思うし、HTTP/2 みたいな最先端の話題も扱うし、ベンチマークから裏付けを取ってたり、趣向が広くて深い。とにかく何かを発見できるし、ハッとさせられる。こんな場所は shibuya.pm だけですね。最高。</p>

<h2>Ingress</h2>

<p>開場の少し前に到着したのでヒカリエを中心に少しずつキャプチャーしていったわけですが、18:30 すぎたあたりからポータルの取り合いが激しかったです。ハチ公は激しいことは知っていましたがあの時間のヒカリエもすごかったす。最後はnipotanさんをはじめ青の人のおかげでP8ができていたのでtranslatorが捗りました。ヒカリエのエージェントのみなさん、ありがとうございました！</p>

<h2>最後に</h2>

<p><a href="http://yapcasia.org/2015/" target="_blank">YAPC::Asia 2015</a> の CFP に応募しようか迷っていましたが shibuya.pm に参加したら応募したくなりました。CFP のギリギリだけれどもサマリーを少しまとめたら応募したいと思います。
開会の挨拶の中で触れていましたが Perl を業務で利用している企業が少なくなっているみたいですけど（<a href="http://sixapart.jp/jobs/" target="_blank">当社</a>はまだ使っていますが）、やっぱり Perl って面白いから使い続けた方がいいよ！</p>

<p>会場をご提供してくれた DeNA さん、shibuya.pm リーダーの竹迫さん、発表者のみなさん、すげー楽しかったです。ありがとうございました！</p>
]]>
    </content>
</entry>

<entry>
    <title>Twitter Flock Tokyo 2015 - Untitled Folder</title>
    <link rel="alternate" type="text/html" href="https://shigeta.dev/blog/2015/05/twitter-flock-tokyo-2015.html" />
    <id>tag:localhost,2015:/shigeta.dev/blog//4.43</id>

    <published>2015-05-20T03:26:19Z</published>
    <updated>2023-12-06T04:49:32Z</updated>

    <summary>少し遅くなりましたが 2015-05-19 に Twitter Flock To...</summary>
    <author>
        <name>shigeta</name>
        
    </author>
    
        <category term="events" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="ja" xml:base="https://shigeta.dev/blog/">
        <![CDATA[<p>少し遅くなりましたが 2015-05-19 に <a href="https://twitterflocktokyo.splashthat.com/" target="blank">Twitter Flock Tokyo 2015</a> に行った話を書きます。</p>

<p><a href="https://shigeta.dev/blog/assets/IMG_5051.jpg" data-test="popup-now" onclick="window.open(this.href,'popup','width=3264,height=2449,scrollbars=yes,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="https://shigeta.dev/blog/assets_c/2023/12/IMG_5051-thumb-300xauto-42.jpg" width="300" height="225" alt="IMG_5051.jpg" class="mt-image-none" style="" /></a>
<br /></p>
]]>
        <![CDATA[<p>会場は<a href="http://www.lapnet.jp/space/lmr/" target="_blank">ラフォーレミュージアム六本木</a>で300名ほど座席がありましたがほぼ満席でした。大盛況でしたね。
受付時のケータリング、休憩時にはコーヒーやクッキー、懇親会時のケータリングと食べ物も豊富で、お土産もTシャツにBluetooth スピーカーをいただきまして、無料のイベントでしたがとても豪華でした。
（ざっと東京のイベントだけでも数百万円の経費がかかっているのではないかと想像しました。Flock は<a href="http://flock.fabric.io/#event-locations" target="_blank">全世界で15都市で開催</a>されているので総額で数千万円はかかっているのではないでしょうか。広告収入強化に向けて <a href="http://www.mopub.com/" target="_blank">MoPub</a> を広く使ってもらうがメインなのだろうなと推測します。）</p>

<p><a href="https://shigeta.dev/blog/assets/IMG_5053.jpg" data-test="popup-now" onclick="window.open(this.href,'popup','width=3264,height=2449,scrollbars=yes,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="https://shigeta.dev/blog/assets_c/2023/12/IMG_5053-thumb-300xauto-40.jpg" width="300" height="225" alt="IMG_5053.jpg" class="mt-image-none" style="" /></a></p>

<p><a href="https://shigeta.dev/blog/assets/IMG_5054.jpg" data-test="popup-now" onclick="window.open(this.href,'popup','width=2448,height=3265,scrollbars=yes,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="https://shigeta.dev/blog/assets_c/2023/12/IMG_5054-thumb-autox400-41.jpg" width="300" height="400" alt="IMG_5054.jpg" class="mt-image-none" style="" /></a></p>

<p><a href="https://get.fabric.io/" target="_blank">Fabric</a> は導入しやすくなっているので MoPub が手軽に利用できる点においては今後広告を出すアプリが増えそうですね。
Fabric には MoPub のほかにも <a href="https://get.fabric.io/digits" target="_blank">Digits</a>、<a href="https://get.fabric.io/crashlytics" target="_blank">Crashlystics</a>、<a href="https://get.fabric.io/native-social" target="_blank">TwitterKit</a> などアプリ開発者にとっては魅力的な機能が満載なので試してみる価値はあると思います。
今回のイベントの内容についてはオープニングスピーチで Dick Costolo や Jack Dorsey がビデオメッセージで登場してイベントに花を添える形でした。Fabric の機能紹介がメインでしたので事前に触れていた自分にとって各プレゼンはぼちぼちの収穫でしたがイベント会場を通じて Twitter 社の本気度を垣間見た気がしました。
素晴らしいイベントにお招きいただきましてありがとうございました！</p>

<blockquote>
13:00 - 14:00 受付<br />
14:00 - 15:00 オープニングスピーチ + デモ + カスタマーサクセスストーリー<br />
15:00 - 15:20 休憩<br />
15:20 - 15:50 Digits: A Better Way to Login<br />
15:50 - 16:20 Crashlytics: Quality First<br />
16:20 - 16:50 TwitterKit: Tap Into the Pulse of the Planet<br />
16:50 - 17:10 休憩<br />
17:10 - 17:40 Using Twitter to Promote Your App and Get Growth<br />
17:40 - 18:10 MoPub: Make Money With Your Apps<br />
18:10 - 19:30 レセプション + 開発チームとの懇親会<br />
<p><small><a href="https://twitterflocktokyo.splashthat.com/" target="_blank">Twitter Flock Tokyo 2015</a></small></p>
</blockquote>
]]>
    </content>
</entry>

<entry>
    <title>2015年もよろしくおねがいします - Untitled Folder</title>
    <link rel="alternate" type="text/html" href="https://shigeta.dev/blog/2015/01/2015.html" />
    <id>tag:localhost,2015:/shigeta.dev/blog//4.42</id>

    <published>2015-01-29T15:54:00Z</published>
    <updated>2023-12-06T02:32:36Z</updated>

    <summary>昨年は本当に忙しくて仕事一筋でした。合間にドラクエやったりしていましたがほぼほぼ...</summary>
    <author>
        <name>shigeta</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://shigeta.dev/blog/">
        <![CDATA[<p>昨年は本当に忙しくて仕事一筋でした。合間にドラクエやったりしていましたがほぼほぼ仕事に明け暮れていました。<a href="https://movabletype.net/">MovableType.net</a> がベータ版が公開されて一安心です。皆さんも是非使ってみてください。</p>

<p>最近は仕事か Ingress かのどちらかですね。よく歩いています。先日 Lv10 になりました。Lv8 まではチュートリアルでそこから Lv10 までは少ししんどかったけど Lv10 から Lv11 は結構しんどそうですね。ゴールドが4枚（実質+2枚だけど）とかどんだけかかるんだって話ですわ。まだ行っていない土地がたくさんあるのでいろいろと足を運びたいと思います。<a href="http://yapcasia.org/2015/">夏はビッグサイトへ</a>行くのが楽しみです。</p>

<p>遅くなりましたがこのブログポストを新年のご挨拶に代えさせていただきます。今年もよろしくお願いします。</p>
]]>
        
    </content>
</entry>

<entry>
    <title>英語キーボードを選ぶ理由 - Untitled Folder</title>
    <link rel="alternate" type="text/html" href="https://shigeta.dev/blog/2015/01/post.html" />
    <id>tag:localhost,2015:/shigeta.dev/blog//4.41</id>

    <published>2015-01-29T15:44:53Z</published>
    <updated>2023-12-06T02:32:36Z</updated>

    <summary>ここ 7 - 8 年は英語キーボードを使っています。この期間のうちで Windo...</summary>
    <author>
        <name>shigeta</name>
        
    </author>
    
    
    <content type="html" xml:lang="ja" xml:base="https://shigeta.dev/blog/">
        <![CDATA[<p>ここ 7 - 8 年は英語キーボードを使っています。この期間のうちで Windows PC や Macbook など何台かのマシンを使ってきたんだけど BTO で英語キーボードにしています。</p>

<p>日本語キーボードって日本語変換キーを中心にコードを書くのに不要なキーがあるから使いづらいとか英語キーボードの方がかっこいいとかいろいろ後付けっぽい理由があったんだけど一つ腑に落ちる結論が見つかった。</p>

<p>リモートホストにログインしたときに OS の言語設定がたいてい英語だから英語キーボードの方が都合がよい。日本語キーボードだと主に記号の位置が違ってしまい入力ミスが増えるからつらい。Perl のワンライナーで何かしようとしたら @（アットマーク）を探すのに結構苦労したり。これは確実に英語キーボードを選ぶ理由の一つだな。</p>

<p>しばらくはこれを英語キーボードを使う理由にしよう。やっぱり英語キーボードだよね。</p>
]]>
        
    </content>
</entry>

</feed>
