OmniAICreator/Qiita-1.07M huggingface dataset:
Hugoでアカデミックなポートフォリオサイト兼ブログをつくってみた


修士以降の学生で研究に取り組んでいると、自分のプロジェクトやpublicationをまとめたシンプルなウェブページが欲しくなってくる。Wordpressやstrikinglyみたいなサービスが出ているが、オリジナルのWebページを作りたいときには制約が多かったり、機能が多すぎたりすることがある。

HugoはGo言語で記述された、 __スゴイハヤイ静的ウェブジェネレータである。__ 記事やプロジェクトなどを __Markdown記法__ で記述することで投稿したり更新したりできるため、普段mdでノート取ってる方やQiitaの諸兄・諸姉には非常に使い勝手のいいWebジェネレータであると思う。

今回は `Academic` テーマをベースにオリジナルページを作成してみた。

ウェブサイトはこちら : [web](https://jotaros.github.io)


## 使い方（初めての人へ）

https://gohugo.io/getting-started/quick-start/
チュートリアルはここから

- brewでインストール

```sh
brew install hugo
```

- プロジェクトを生成

```sh
hugo new site yourSiteName
```


- テーマを導入

```sh
cd yourSiteName
git init
git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke

echo 'theme = "ananke"' >> config.toml
```


ここでは、yourSiteNameプロジェクト内のthemeフォルダに、submoduleとしてテーマプロジェクトを追加している。
テーマプロジェクト内は基本的には生成したプロジェクトと同様の構造となっており、exampleもあるので改造しやすい。
プロジェクトを追加したときに生成されるconfig.tomlを書き換えてテーマをアクティブにする必要がある。



- 記事を投稿

```sh
hugo new posts/my-first-post.md
```

config.tomlに以下の文言を追加して、

```toml
baseURL = "https://example.org/"
languageCode = "en-us"
title = "My New Hugo Site"
theme = "ananke"
```

- サイトを生成（ビルド）

```sh
hugo server -D
```


[localhost:1337](localhost:1337)にアクセスすると、生成されたウェブサイトが見れる。たったこれだけでWEBサイトが完成してしまう。


## Academicテーマの改造

インストールは、git submoduleで[Academicテーマ](https://themes.gohugo.io/theme/academic/)を`themes`フォルダに追加すればよい。exampleSiteの投稿（content）ツリーはこのようになっている。

```
├── exampleSite
│   ├── config.toml
│   ├── content
│   │   ├── home
│   │   │   ├── about.md
│   │   │   ├── contact.md
│   │   │   ├── hero.md
│   │   │   ├── posts.md
│   │   │   ├── projects.md
│   │   │   ├── publications.md
│   │   │   ├── publications_selected.md
│   │   │   ├── tags.md
│   │   │   ├── talks.md
│   │   │   └── teaching.md
│   │   ├── post
│   │   │   ├── _index.md
│   │   │   ├── faq.md
│   │   │   ├── getting-started.md
│   │   │   ├── managing-content.md
│   │   │   ├── migrate-from-jekyll.md
│   │   │   ├── widgets.md
│   │   │   └── writing-markdown-latex.md
│   │   ├── project
│   │   │   ├── deep-learning.md
│   │   │   └── example-external-project.md
│   │   ├── publication
│   │   │   ├── _index.md
│   │   │   ├── clothing-search.md
│   │   │   └── person-re-identification.md
│   │   ├── tags
│   │   │   └── academic
│   │   │       └── _index.md
│   │   └── talk
│   │       ├── _index.md
│   │       └── example-talk.md
```

トップページに現れるプロフィール画像や文言などもすべてmd記法で記述することが可能。

### cssでカスタマイズ

元のデザインも十分に良いのだが、自分風にカスタマイズしたい場合は、

1. (theme側ではなく)自分のプロジェクトの `static` フォルダに、 `custom.css` という名前でcssファイルを作成
2. 主に `partials/widjets` などの要素・クラスを見ながら、custom.cssを書きかえ
3. 必要に応じてテンプレートを書き換え（上級者向き）、削除などをする（talkしたことなければ消したりなど）。


このあたりの細かい作業が（Hugo初めてだったので）Hard-Codedになってしまったのは大いに反省なのだが、上に書いてあるフォルダ内のデータをいじれさえすれば、Academicのpostパターンを崩すことなくオリジナルのポートフォリオサイトが作成できる。

作成したウェブサイトがこちら：[web](https://jotaros.github.io)



## まとめ


- HugoはスゴイハヤイstaticWebジェネレータ
- mdで書けるため、普段qiitaにおられる諸兄・諸姉におすすめ
- Academicは研究者・学生向けのテンプレートとして有能
- 他のテンプレートエンジンと同様、partialsをいじってcssを書き換えるなどして簡易にオリジナルデザインに変更できる。
Djangoでは常にカスタムUserを使用すべき

カスタマイズUserを作成するために、公式ドキュメントに書かれてあったことを全体的にまとめてみた。

# カスタムUserとは
DjangoではデフォルトのUserモデルが存在し、Adminサイトなどでもそれが使用されている。
デフォルトではユーザー名でユーザーを管理しているが、サービスによってはemail、もしくはそれ以外のunique属性などで管理する場合もあるだろう。
その場合、デフォルトのままでは認証方法が違ったり、必要な要素が足りなかったりする。
そういう時は、すでにあるUserの内容をカスタマイズする必要がある。

# カスタムUserを使う場合の注意点
カスタムUserを使うには、migrationsの`init(0001)`時点でカスタムUserを使うことを含めなければならない。
特に他のmodelからUserを参照している場合などには、途中から参照を変える事ができない。
すでに`migrate`している場合は、DBを初期化して`makemigrations`し直すのが楽。


# 常にカスタムUserを使用すべき
プロジェクトの開始時にはデフォルトUserで問題なかった場合でも、プロジェクトの途中からUserに新しい情報を追加したくなる場合もある。
であれば最初からカスタムUserを使用しておけばいいという話。
タイトルでも、常にカスタムUserを使用すべき、と書いてあるがここで言うカスタムUserとは***何もカスタムしていないカスタムUser***のことである。
とりあえずいつでもカスタムできるように、カスタム用の継承をしたクラスをデフォルトで使用するように変更しておくが、実際にカスタムはしなくてもいいという話だ。

# カスタムしていないカスタムUserの作成方法
```myapp/models.py
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass
```
`AbstractUser`を継承することによって、デフォルトUserに要素を追加することができる

```myapp/admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

admin.site.register(User, UserAdmin)
```
自作UserをAdminに設定

```myproject/settings.py
AUTH_USER_MODEL = 'myapp.User'
```
自作Userを認証用のUserモデルとして設定

---
もっと全体的な事が知りたければ、[公式Djangoドキュメント][公式Django]を読むと良い。

- 参考
  - [公式Djangoドキュメント][公式Django]


[公式Django]: https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#substituting-a-custom-user-model
クマとアレクサとわたし

スマートスピーカーIFTTT 大喜利 アドベントカレンダー20日目です。

IFTTT使おうとしつつ時間がなく、「Echo Dot」と「ヒミツのクマちゃん」を持って12/16-17に開催されたNT加賀 http://kaga-iotac.org/ntkaga2017/ へ行って来ました。



「ヒミツのクマちゃん」はタカラトミーが発売した「会話ができるぬいぐるみ」です。
<a href="https://www.amazon.co.jp/%E3%82%BF%E3%82%AB%E3%83%A9%E3%83%88%E3%83%9F%E3%83%BC%E3%82%A2%E3%83%BC%E3%83%84-%E3%83%92%E3%83%9F%E3%83%84%E3%81%AE%E3%82%AF%E3%83%9E%E3%81%A1%E3%82%83%E3%82%93-%E3%83%81%E3%83%A7%E3%82%B3%E3%83%96%E3%83%A9%E3%82%A6%E3%83%B3-%E3%81%AC%E3%81%84%E3%81%90%E3%82%8B%E3%81%BF-%E5%BA%A7%E9%AB%9823cm/dp/B00VUXWOK0/ref=as_li_ss_il?ie=UTF8&linkCode=li1&tag=tomorrow56-22&linkId=f4212038ab093f47b0eb323b75666f22" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=B00VUXWOK0&Format=_SL110_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=tomorrow56-22" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=tomorrow56-22&l=li1&o=9&a=B00VUXWOK0" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
http://www.takaratomy-arts.co.jp/specials/himikuma/

その「ヒミツ」の内容にAmazonのレビューがプチ炎上しました。
一部で有名な「おじいちゃんのうそつき」事件
![おじいちゃんのうそつき.JPG](https://qiita-image-store.s3.amazonaws.com/0/120903/43448c95-bf06-faa5-68e1-87c3e89729ec.jpeg)

そして、月日は流れてAmazon Echoの登場により真の力を発揮する時が来ました。
NT加賀では1人出展だったので、「アレクサ+クマちゃん」に席を外す時に留守番してもらったのですが、子供にも大人にも人気でした。自分の本来の展示よりも子供が喜んでいて微妙でしたが...

会場の動画はこちら。
https://youtu.be/NDoLRvReUsg

もうちょっとわかりやすい動画も追加しました。
http://nico.ms/sm32464727

いやー、クマちゃんに時代がやっと追い付いた、というかスマートスピーカーのフロントエンドとしてマジでよいです。そして、NT加賀で他にこれをやっている人がいなくて意外だった。
(ベタなネタすぎたという事もあります)

一応、そのあとIFTTTを使おうとしているのですがトリガのパスフレーズの認識がうまく行かなくて苦戦しています。
通知は出来るかとお試しにランダム再生している曲名をLineで通知させているのですが、これはうまくいっているのでのせておきます。個人的には地味に便利。

![songname.JPG](https://qiita-image-store.s3.amazonaws.com/0/120903/3a70cd27-7ea0-9550-aa03-dabaa512f248.jpeg)

では、この辺で。

明日21は登録なし。22日は ForexRobotics さんです。
OpenShiftOnline3 サインアップ〜利用開始

OpenShiftOnline3を使ってみます。実際にサインアップするところから始めてみます。
[OpenShift概要](https://qiita.com/miawak2017/items/)
#登録ページにアクセス
 https://www.openshift.com/devpreview/register.html ![login_page.png](https://qiita-image-store.s3.amazonaws.com/0/222266/e74f2730-6797-7acb-8c28-65455fa53560.png)
"Sign Up for OpenShftOnline" をクリック

#サインアップ(新規登録)
![accountmake.png](https://qiita-image-store.s3.amazonaws.com/0/222266/5af52f98-822a-f7fa-e7e8-bc55125a4c27.png)
"REGISTER”をクリック

#必要事項の記入
![Register for OpenShift Online.png](https://qiita-image-store.s3.amazonaws.com/0/222266/224d92ef-1b72-daa8-52a9-9161d123f722.png)
必要事項を入力し"CREATE MY ACCOUNT"をクリック
入力したメールアドレス宛に登録メールが届くのでメール本文内の"Link to e-mail address verification"をクリック

#プラン選択
![selectaplan.png](https://qiita-image-store.s3.amazonaws.com/0/222266/e6c50045-254a-4d8a-8a95-f171aeffb473.png)
ここでは"FREE"をクリック

#希望するクラスター/地域選択
『OpenShift Online Starter Planは、お好みのクラスタ/地域で[プロビジョニング](http://sp.e-words.jp/w/プロビジョニング.html)されます。容量が利用できない場合、アカウントはキューに入れられ、容量が利用可能になるとプロビジョニングされます。完了すると、電子メールが配信されます。』
![SELECTREGION.png](https://qiita-image-store.s3.amazonaws.com/0/222266/1c0263d5-77f4-4dc2-c5c4-152084a8c5ee.png)
どれか選びクリック

#選択内容確認
![Confirm.png](https://qiita-image-store.s3.amazonaws.com/0/222266/d2e6d770-bd17-afdb-1246-c1507415082d.png)
"私はロボットではありません"にチェックを入れ"Confirm Subscription"をクリック

#プロビジョニング待ち
![AcriveSubscriptions.png](https://qiita-image-store.s3.amazonaws.com/0/222266/320cb0b5-3a9f-289f-9d0c-fe5126db5a9d.png)
キューイングされプロビジョニングのため待機
しばらくして完了メールが届くのでメール本文記載のURLにアクセスする

#プロビジョニング完了（GettingStartedページ）
![gettingstated.png](https://qiita-image-store.s3.amazonaws.com/0/222266/d25aadc8-2570-020b-1b7b-ee3117fb52fb.png)


[プロビジョニング](http://sp.e-words.jp/w/プロビジョニング.html)にはわりと時間がかかっていました。。
クラスタ/地域により変わってくるのかもしれません。
[次回](https://qiita.com/miawak2017/items/8734c16af4df85c991d2)はNode.js環境を構築していきます。
GASでBitcoinのレートを取得してスプレッドシートに貯める話

#はじめに
流行りに乗っかってみようと、少し前に仮想通貨を始めたんですが、APIで売買できるということに最近気づきまして、せっかくエンジニアやってるわけなので、自前のシステムで売買をしてやろうと思った次第です。
そこで、まずはデータだけでも貯めておこうと思ったんですが、詳細が固まってない状態でサーバ立てて、プログラム作って、というのも色々無駄な気がして、手軽さを重視した作りにしました。

※APIは一般公開されているものなので口座作らなくても使えます
※Coincheck以外でもAPIを公開してるところはあるので、Coincheckである必要はないです

#ポイント
Googleのアカウントさえあればできるので色々と敷居が低いのでお手軽です。

#処理概要
GASを使って以下の処理を毎分実行する
・CoincheckのAPIをたたいて、Bitcoinのレートを取得する
・取得したデータをスプレッドシートに書き出す

APIの詳細についてはこちら
https://coincheck.com/ja/documents/exchange/api

#手順
1. スプレッドシートを作成し、「rate」というシートを作る
2. 「ツール」の「スクリプトエディタ」をクリック
3. コードを記述
4. 三角のボタンを押して実行してみる
5. 時計?のボタンで1分毎に実行するように設定する

以上です。
あとはこのデータを使ってどういうトレードのロジックを作るかですね。
そのへんもまた記事にする、かもしれないです。

こんな感じ
![スクリーンショット 2017-12-20 0.44.07.png](https://qiita-image-store.s3.amazonaws.com/0/38124/91428003-9946-b60d-ae09-7afcaac1b886.png)


#ソース

```js:test.gs
function myFunction() { 
  // coincheckの価格取得API  
  var url = 'https://coincheck.com/api/exchange/orders/rate?order_type=buy&pair=btc_jpy&amount=1';
  
  var option = {
    'method' : 'get',
    'muteHttpExceptions' : true,
  };
  
  // リクエスト投げる
  var response = UrlFetchApp.fetch(url,option); 
  var json = response.getContentText();
  var data = JSON.parse(json);
  
  // こういうのが返ってくる
  // {"success":true,"rate":"2103746.04407","amount":"1.0","price":"2103746.04407146"}
  
  if (data.success) {
    // スプレッドシートの「rate」シートの最終行を取得
    var ss = SpreadsheetApp.getActiveSpreadsheet();
    var sheet = ss.getSheetByName("rate");   
    var last = sheet.getLastRow();
    
    // 現在時刻とレートを書き出す
    sheet.getRange(last + 1, 2).setValue(new Date());
    sheet.getRange(last + 1, 3).setValue(data.rate);    
    
  // 失敗した場合
  } else {
    Logger.log(data);
  }
}
```
Nyquistより先に作ったセパレート５ｘ６キーボード

Ergodoxを手に入れたものの、実は自作キーボードだと半額以下で作れるとの情報をもとにを色々調べているうちに、レツプリにたどり着いたのですが、
当時、唯一レツプリのPCBを取り扱ってたSwitchTopは在庫切れだった為、代わりに5x6のMacroPadというPCBを２枚買って見ました。
（その後すぐに、縁あってレツプリの第１回グループバイに参加することができましたが）

Redditで情報を探しても、MacroPadのPCBでLet'sSplitと同じ様なセパレートタイプにするのは難しいなどの情報が書かれていたのでダメ元くらいの気持ちでいました。

以下が実際に入手したMacroPadPCBです。

<img width="768" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/28408/f8743ef3-dfd9-0985-d2d5-4fd34be83005.png">

また、Let'sSplitとは違いセパレートキーボードとして設計されていない為、ProMicroの位置は左右対称とはなりません。
また、シリアルケーブルを接続するTRRSジャックを取り付けるスルーホールもありません。

次に、基板を確認しながら浮き出ている配線とProMicroのスルーホールの位置を丁寧に追っていきました。
これは基盤データが見つからなかったので、仕方ありませんがのちのちTRRSジャックの設置方法のアイデアにつながります。

<img width="768" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/28408/f945d318-f8c5-b2b4-443c-edfca5e268bd.png">

パターンを追った結果、使わないTeensy用スルーホールの１，２，３番ピンはどの配線とも繋がっていないことがわかり、このスルーホールをTRRSジャック基板の固定用スルーホールにすることにしました。
（※片側、且つ３穴なのでTRRSケーブルを指すときに丁寧にしないとメイン基板からハンダごと外れます。）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/28408/8bbdcada-a935-e43d-7251-8a15e57063fe.png)

また、もう一つの課題であるケースについては強度とコスト、加工のしやすさを考えアクリル板にし、トッププレートとボトムプレートで挟み込むサンドイッチタイプにしました。

PCBにスイッチを直接マウントする方法の場合はPCBに直接衝撃が伝わるので不具合発生の軽減の対策にもなるかなと考えています。（多くのキーボード製品もトッププレート採用が多いので。）

また加工業者に頼むとコストがかかるので、
ダイソーの３００円ルータと、アクリルカッターで加工することにしました。

まず、レツプリのケースデータを加工し印刷してアクリル板に貼り付けます。
さすがに６０個の穴を加工していられないので、
列で切り出してはめてみると意外と強度が保てそうなのでこのまま進めました。

<img width="768" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/28408/08c4750f-166d-7762-8e83-dda09490ab2a.png">

列加工は完成まで早いのですが、PCBとのズレ幅が大きく
スイッチが少し浮き気味だったりしました。
親指も結構痛くなるので１列/日が限界ｗ
１列１時間くらいかな

<img width="768" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/28408/a6f77002-dace-3753-b51d-5980e98ee61a.png">

それでも調子に乗ってしまった私は修羅道へ走ってしまいました。

１穴３０分なので、合計１５時間！！

<img width="768" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/28408/e620804d-1f7e-8101-fbb5-d73b315f77de.png">

ついに完成！！
と思いきや

<img width="768" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/28408/8eba3f98-795e-3919-cf1e-31feb74961c5.png">

さらにJoysticの穴まであけてオリジナルキーボードが完成しました。
ジョイスティックなしの場合はQMKのファームウェアで動作します。

Joystick付きはArduinoライブラリを組み合わせオリジナルファームウェアで実装していますが、ダブルタップなどの機能を実装中なので、完成したら公開しようと思います。

<img width="768" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/28408/1a8c91aa-8f89-494f-33bf-b719c42a7a6a.png">

おしまい！
centos7 に docker と docker-compose 入れる

忘れないように、自分のdockerでの環境構築をまとめておく

コマンドの説明（なぜこうしてるか）などは気が向いた時に書き足すかも

```
# すでに入ってるものをアンインストール
sudo yum remove docker docker-common docker-selinux docker-engine
# 依存関係のインストール
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# レポジトリ追加
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# インストール
sudo yum install docker-ce
# 起動
sudo systemctl start docker
# 自動起動
sudo systemctl enable docker

# dockerグループがなければ作る
sudo groupadd docker
# 現行ユーザをdockerグループに所属させる
sudo gpasswd -a $USER docker
# dockerデーモンを再起動する
sudo systemctl restart docker
# exitして再ログインすると反映される。
exit

# docker-composeインストール
sudo curl -L https://github.com/docker/compose/releases/download/1.18.0/docker-compose-`uname -s`-`uname -m` -o /usr/bin/docker-compose
# 権限付与
sudo chmod +x /usr/bin/docker-compose

# bash_completion インストール
sudo yum install -y bash-completion

# docker-compose bash-completion インストール
sudo curl -L https://raw.githubusercontent.com/docker/compose/1.18.0/contrib/completion/bash/docker-compose -o /etc/bash_completion.d/docker-compose
```


# Refs
* https://docs.docker.com/engine/installation/linux/docker-ce/centos/#upgrade-docker-ce
* https://docs.docker.com/compose/install/
* https://qiita.com/DQNEO/items/da5df074c48b012152ee
blurでalertを使うと、IEで挙動が変になる問題

formのテキストボックス等で入力チェックを行い、おかしかったらalertを上げるという方法は昔ながらのシステムだとよくある。
サクッと書くとこんな感じ。

```html:html
<input name="hoge" type="text">
```

```javascript:javascript
$("input[name='hoge']").blur(function(){
	alert("あらーと");
});
```

ただこれIEだと良く分からない挙動になる。
(真下にあるウインドウが手前に持ってこられる？？？良く分からない。)
https://jsfiddle.net/u93pamo0/3/

これを回避するにはblurではなくfocusoutを使う。
※focusoutとblurは微妙に違うので注意が必要。
http://www.jquerystudy.info/reference/events/blur.html

Chromeでもalertが無限ループする事があるらしい。
そもそもalertで何か出すってやるべきじゃないのだろうか。
PeerCast プログラミング配信 Advent Calendar 2017 19日目

左手負傷につきもげAIについての雑談配信してみた
[もげRPGサーバー](https://github.com/fusuya/mogeRPGserver)用のAIの大雑把な作り方の順序を考えた


もげAI作るためには
１，使用するプログラミング言語でのjsonの使い方を調べる
２，ランダムで動くプログラムを作ってみる（テスト）
３，階段をめざして動くプログラムを作る（経路探索）
４，バトル時の攻撃コマンドを使い分ける（どの敵を先に倒すかなど）
５，マップ移動中にハンマーを使うかどうか判断　（経路探索＋α）
６，宝箱を取りに行くのか行かないのか判断（経路探索＋α）
７，ボス戦のバトルプログラム

重要：４、５、６　あと回復薬を使うタイミング



あと視聴者からバグ報告や要望が届いた

バトル中も階層を表示
アイテム持ち替えた時のステータスがマイナスになるときがある（修正よてい）
１００階のwallない問題
指定したステータスから始められるオプションとかほしい


配信コメントに”雑談”ってつけると視聴者がいつもより3人位増えた気がする。
PHPで指定ディレクトリのファイル名取得

# ファイル名取得
* Pythonだとlistdir関数を使って指定ディレクトリのファイル名を取得できるのですが，自分はPHPでファイル名取得することのほうが多いので，一応メモ書きで．

# コード
* scandir 関数を使います．

```php

$dir = ""; //ディレクトリの指定
$files = scandir($dir);

```

* これで$filesに配列として，ファイル名が代入されます．
    * これだとディレクトリ内の " . " と " .. " が含まれる．

なので for文とかで確認したいときは ↓

```php
for($i=2;$i<count($files);$i++){ //$i = 2から始める
    echo $files[$i];
}
```
[cocoa]関東swift勉強会2018-01のご案内

# ■関東swift勉強会2018-01 ご案内
iOS/macOSのプログラミングの勉強会です。 Swift/UIKit /AppKit/Objective-Cの技術的な話題を取り上げます。

## 日時：
2019/01/19(金) 19:30-22:00
## 会場：
池袋コワーキングスペース OpenOffice FOREST http://co-forest.com
3階の受付で、swift勉強会又はcocoa勉強会ですとお伝えください。人数によって会場の席が変わる時があります。
## 集合：
現地
## 座席代：
夜間ドロップイン 一人1,000円（各自でお支払いください)
## 申込：
https://cocoa-kanto.connpass.com/event/75006/
## 発表：
募集中です。conpassのアンケート機能で適当に発表内容を書いてもらえば、こちらで以下に追加します。

* 「アウトライプロセッサ進捗会議」(macOS/Swift) 成田
* 「Developer's Tech Lab」(その他)　 質問コーナーです。iOS/macOSのプログラミングの質問に答えます。

## Cocoa勉強会 関東について：
以下のFacebookグループから、ご参加下さい。
https://www.facebook.com/groups/cocoa.kanto/

# 関連情報
<a href="https://cocoa-kanto.connpass.com">Cocoa勉強会 BUKURO.swift (connpass)</a><br />
<a href="https://atnd.org/groups/cocoa-study">Cocoa勉強会 BUKURO.swift (ATND)</a><br />
<a href="http://cocoa-study.peatix.com">Cocoa勉強会 BUKURO.swift (Peatix)</a><br />

# 【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk>note</a><br />
<a href="https://qiita.com/m_yukio>Qiita</a><br />
AWS AppSync (Preview)を試してみた

## AppSyncのプレビュー申請が通ったので早速試してみました
![0.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/5c84ef3c-e86b-759e-983d-f07576b50472.png)
---
## AWS AppSyncとは
> AWS AppSync では、ウェブアプリケーションやモバイルアプリケーション内のデータがリアルタイムで自動的に更新されます。また、オフラインユーザーが再接続するとすぐにデータが更新されます。AppSync により、応答性に優れた協働的なユーザーエクスペリエンスを実現できる、共同のモバイルアプリケーションやウェブアプリケーションを簡単に構築できます。

> AWS AppSync を使用すると、iOS、Android、JavaScript、React Native でネイティブなモバイルアプリケーションやウェブアプリケーションを構築できます。AWS AppSync コンソールにアクセスし、シンプルなコードステートメントでアプリケーションのデータを指定して、使用を開始してください。アプリケーションのデータの保存、処理、取得に必要なものすべては、AppSync で管理されます。

[AWS AppSync](https://aws.amazon.com/jp/appsync/)


## APIの作成
### 1. APIの作成
勢いよく「Create API」ボタンを押します。
![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/7d5243fd-9ae4-4200-29ee-860be3fa3944.png)
  
### 2. APIの命名
ここではmyAppSyncとしておきます。
![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/74d4a412-d7ee-6f2f-15a7-80377a3bd130.png)

### 3. スキーマの選択
カスタムスキーマとサンプルスキーマを選択できます。
今回はあらかじめ用意されているサンプルスキーマを使いました。
DynamoDBのテーブルとアクセスに必要なIAM roleを自動生成してくれました。

![3.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/eeea0721-9b51-80e4-8dc2-4dd55433679d.png)

### 4. スキーマの確認
スキーマが表示されますので、一番下の「Create」ボタンを押します。

![5.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/a3f7072f-3806-835f-1acc-e862ad4eeb68.png)

これでAPIが作成されました！早い！

## APIの確認
APIが作成されると、サンプルをGithubからクローンできます。
また、スキーマのダウンロードが可能です。

![6.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/14eb8423-7cd7-68da-142b-e89defc4a0c0.png)

### 1. URL・API KEYの確認
作成したAPI「myAppSync」のトップページでURLやAPIキーを確認できます
![7.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/4a8bf902-6902-d3e5-4925-1d8cfe8d4a6f.png)

### 2. DynamoDBの確認
DynamoDBのテーブルが自動生成されているのを確認する事が出来ました！
![8.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/358f8b1f-c5a0-169c-da3b-472ae0382413.png)

Read Capacity、Write Capacity共に「5」になっているので、テスト用途であれば小さめにしておきましょう。
![9.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/8b0d3dcd-fd9b-7615-6ce9-06080f38629f.png)

今回は「1」にしておきました。
![10.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/0eb7e51b-baf2-5b8e-8239-8e3e6c836386.png)

### 3. クエリーのテスト
AppSyncではクエリーのテストが出来るようになっています。
早速サンプルのイベントテーブルへデータを追加します。
![11.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/7681be2b-7757-ec4c-a4d0-1ea2dd167e2e.png)

無事にデータが入りました！
![12.PNG](https://qiita-image-store.s3.amazonaws.com/0/33070/9d6bffe0-cadb-27d9-9005-f9b1eab561ca.png)

## 所感
* GraphQLサーバーを数分で利用できるようになるのはとても便利で、apollo-serverをコンテナで立てるよりも楽だなという印象を受けました。
* AWSの対応しているデータソースに繋ぐのであればとても便利なサービスです。
* データソースはDynamoDB、Elasticsearch service、Lambdaの３つと制限はありますが、IAM roleを自動生成してくれるのはありがたいです。
* スキーマは自分で準備する必要があるのでGraphQLの知識は必須です。
* 今後はもう少し時間を作ってモバイルデバイスからのオフライン、オンライン時の動きを確かめたいと思います。

参考
[Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/introducing-amazon-appsync/)
Decoratorの役割とDraperについて

#本記事の内容
- Decoratorとはなにか
- Draperとはなにか
- Decoratorの利便性
- なぜモデルではだめなのか
- なぜヘルパーではだめなのか
- なぜモジュールではだめなのか
- まとめ

#Decoratorとはなにか
ソフトウェアのデザインパターンの一つです。
既存のオブジェクトを新しいDecoratorオブジェクトでラップすることで既存の関数やクラスの中身を直接触ることなく、その外側から機能を追加したり書き換えたりする。また、既存のクラスを拡張する際にクラスの継承の代替手段として用いられます。
Decoratorというデザインパターンを導入することで、ビューファイルにロジックを記述しないといったことができます。

#Draperとはなにか
DraperはRailsのプレゼンテーション層の役割を担うgemです。
プレゼンテーション層とはviewとモデルの中間に位置し、モデルやビューに実装されやすい表示ロジック/フォーマットを記述する役割を担います。

Draperの導入はこちらを参考にしてください
https://github.com/drapergem/draper

#Decoratorの利便性
具体的にDecoratorのデザインパターンを導入することでどういった利便性があるのでしょうか。

```
# Draper導入前
<dt>Twitter:</dt>
<dd>
<% if @user.twitter_name.present? %>
  <%= @user.twitter_name %>
<% else %>
  None given
<% end %>
</dd>


# Draper導入後
<dt>Twitter:</dt>
<dd><%= @user.twitter %></dd>
</dd>
```

上記のようにプレゼンテーション層にtweetというメソッドを用意することで、viewのロジックを減らすことができます。

どのようにしてプレゼンテーション層を作成していくのでしょうか。
ここではuserモデルがすでに存在することを前提に進めて行きます。
*例なので動かない可能性があります、役割だけご確認ください*

まずuserのデコレータクラスを作成します。このクラスにモデルの拡張したいメソッドを記述していきます。

```
rails generate decorator User
```

今回用意するtweetメソッドでは、もしuserにtweet_nameが存在する場合はtweet_nameを表示し、存在しない場合は"None given"というものを返すものです。

```
class UserDecorator < ApplicationDecorator
  delegate_all

  def tweet
    if working_hours.present?
      twitter_name
    else
      return "None given"
    end
  end
end
```

delegate_allとは、UserモデルのメソッドをUserDecoratorクラスでも使用できるようにするための記述です。これがあることによってuser.nameなどuserモデルが所有するインスタンスメソッドがUserDecoratorクラスのオブジェクトにも使用することが可能となります。

これが最初に記述した「既存のオブジェクトを新しいDecoratorオブジェクトでラップすることで既存の関数やクラスの中身を直接触ることなく、その外側から機能を追加したり書き換えたりする。」という部分になります。

#なぜモデルではだめなのか
何でもモデルに記載しておくと、すぐにモデルは肥大化してしまいます。
モデルにはDBにアクセスするような処理のみを記載することで肥大化を防ぎましょう。特に今回のようなビューロジックはモデルには書かないほうがいいと言えるでしょう。

#なぜhelperではだめなのか
helperもDecoratorもビューを書きやすくするための仕組みという点では共通しています。
しかしこの2つの役割の違いは
helperは**モデルから独立し直接関係していない描画ロジックを実装するのに用います。**
それに対して
Decoratorは**特定のモデルにがっつり関連した描画ロジックを実装するのに用いる**
というものです。

やろうと思えばDecoratorで行う作業をhelperでも実現することは可能なのですが、それではそれぞれの責務から外れてしまいます。

>例えば、数値を3桁ずつに分けてカンマを付けるような「数値」にしか関連していないロジックはヘルパーに実装します。1000を1,000にするような関数です。

またhelperのメソッドはよくコントローラ単位、ビュー単位のローカル関数であると誤解されるのですが、グローバル空間で定義されるためアプリケーション内でのメソッド名の重複に気をつける必要があります。特にチーム開発を行う場合はヘルパーを書いているときはかぶらないように特に注意する必要があります。

#なぜモジュールではだめなのか
モジュールで拡張用のメソッドを定義してモデルのクラスにインクルードすれば同じことを再現できそうです。しかし結局これもモデルに記載しているのとあまり変わり有りません。
もし1人で開発している場合であれば、モジュールがviewのロジックで...、モデルにはDBのアクセスして...、というルールのもとで実装できるかもしれませんが、共同開発の場合にはそのルールを共有していない場合、モデルにビューロジックが溢れ出すこととなりやすいからです。

#まとめ
Decoratorを利用して、モデル、ヘルパーそれぞれの役割を明確にしてあげることで、よりわかりやすいコードをかくことができます。Decoratorをつかうことでviewが驚く程すっきりしました、是非使ってみてください〜。

#参考文献
http://ruby-rails.hatenadiary.com/entry/20150415/1429031791
Rails,Rubyでシェルを実行したい！

#Railsでシェルが使えるか気になったので調べてみました

##具体的な使い方

system記法

```
system('ls')
lsコマンドが実行されます
```

%記法

```
%x( "echo 'hello world'" )
hello worldが出力されます
```

バッククォート記法

```
`echo 'こんにちは'`
こんにちはが出力されます
```

##シェルスクリプトも実行できる
試しにブラウザからRSpecのテストを実行できるか試してみました

```ruby:hoge_controller.rb
system("bash app/controllers/test.sh")
```


```shell:test.sh
bundle exec rspec
```

```
ブラウザからテストが実行できました
  hogehoge
  hogehoge


2 examples, 0 failures
```


###:zap:使い方によっては開発の幅が広がりそうです:zap:
Laravel 5.5 composerでのインストール

#composerのインストール
```ターミナル
composer global require "laravel/installer"
```

#PATHを通す
```ターミナル
vi ~/.bashrc

export PATH="$PATH:$HOME/.composer/vendor/bin"
#:wqで保存

source ~/.bashrc # 反映させる
```
# laravelのインストール
```ターミナル
cd DirectoryName
larabel new ProjectName
```
分散コンテナストレージのLonghornを試そうとしたけど上手くいかなかった話

Dockerを使うとアプリのポータビリティは上がるのですが、クラウド以外の環境だとストレージどうしよう問題も併せて付きまといます。
調べてみるとRancherのLonghornとかを使えば分散コンテナストレージが作れるようなので、Nutanixみたいなハイパーコンバージドが自前で作れるのでは？？？　と思いITアドベントカレンダーネタとしてチャレンジしてみました。

が、上手くいかずorz
とりあえず、上手くいかなかったところまで書いてみました。

k8sの準備
--------------

Longhornはk8sが必要になってきます。そういえばRancher2.0はk8sベースだし同じ会社だから上手くいくんじゃね？　と試してみたもののベータのせいか、私のdocker-toolbox環境ではRancher2.0はエラーが出まくり早くも暗雲が。

いったん、あきらめてGKEを使うことにしました。GKEの準備は下記で。

```bash
$ gcloud components install kubectl
$ gcloud container clusters create "cluster-1" --image-type "UBUNTU" 
$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user="<your mail address>"
clusterrolebinding "cluster-admin-binding" created
```

image-typeは[rancher/longhorn](https://github.com/rancher/longhorn)を参考にデフォルトではなくUbuntuで作成。
ロール作成権限が必要なので`create clusterrolebinding`も行います。

Longhornのデプロイ
-------------

続いてLonghornのデプロイ。`rancher/longhorn`からYAMLを取得して実行

```bash
$ git clone https://github.com/rancher/longhorn.git
$ cd longhorn
$ kubectl create -f deploy\example.yaml
clusterrolebinding "longhorn-bind" created
clusterrole "longhorn-role" created
serviceaccount "longhorn-service-account" created
daemonset "longhorn-manager" created
service "longhorn-backend" created
deployment "longhorn-ui" created
service "longhorn-frontend" created
daemonset "longhorn-driver" created
```

エントリポイントを確認してlonghorn-uiにつないでみます。

```bash
kubectl get svc
NAME                TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)        AGE
kubernetes          ClusterIP      10.31.240.1     <none>          443/TCP        8m
longhorn-backend    ClusterIP      10.31.246.205   <none>          9500/TCP       2m
longhorn-frontend   LoadBalancer   10.31.250.26    xxx.xxx.xxx.xxx 80:32039/TCP   2m
```

上記の場合、ブラウザで下記にアクセス

```
http://xxx.xxx.xxx.xxx/dashboard
```

![2017-12-19.png](https://qiita-image-store.s3.amazonaws.com/0/54904/7cb4ef0d-fc84-5c4a-dd80-34d2ef519c0f.png)

ここまでは割と順調でした。

Longhornを使うコンテナの作成
------------

つづいてLonghornを使うコンテナの作成

```yaml
  volumes:
  - name: vol
    flexVolume:
      driver: "rancher.io/longhorn"
      fsType: "ext4"
      options:
        size: "2G"
        numberOfReplicas: "2"
        staleReplicaTimeout: "20"
        fromBackup: ""
```

こんな感じで指定するっぽい。flex Volumeが実は良くわかってませんがオプション内容的に実行時に動的に領域を作る機能と推測。
`example.yaml`が既に出来上がったっぽいもののようなのでデプロイしてみました。

```bash
$ kubectl create -f examples\example.yaml
pod "volume-test" created
```

一見成功ですがk8sのUI側で下記のエラーが

```bash
Unable to mount volumes for pod "volume-test_default(fc0bd9e1-e4c1-11e7-bf33-42010a800176)": timeout expired waiting for volumes to attach/mount for pod "default"/"volume-test". list of unattached/unmounted volumes=[voll]
```

どうやら領域のアタッチに失敗した模様。先に手動で作成が必要なのかと思いlonghorn-ui側でストレージを作ってみましたがやはりうまくいかず...
何となく初歩的なことに躓いてるきはするものの、今回はここで時間切れとなりましたorz

まとめ
----------

今回はLonghornを試してみようと思ったのですが結果上手くいかずです。k8sの勉強も足らないのでリベンジですね。。。
ただ、分散コンテナストレージがうまくいくと、コンテナの運用がかなり捗りそうなので、パフォーマンス測定とかも含めて再チャレンジはしてみたいです。

それでは、Happy Hacking!

参考
-----

- https://github.com/rancher/longhorn
- https://www.slideshare.net/ShannonWilliams14/introducing-project-longhorn-april-2016-rancher-online-meetup
プログラミングの勉強の進め方について

#勉強の進め方について。
2017年の12月1日から某プログラミングスクールに入門した。
理由はIT系の会社へ異業種転職したいためだ。
Web系への転職を考えているため、言語はRuby、Rails等を勉強中である。
スクールの受講期間は6ヵ月間のスケジュールとなっている。
これを書いている今日(12/19)で入門して19/182日目（17.12.01～18.05.31の期間が182日）だが、既にカリキュラムの39.77%が終わった。
因みに、自分は会社員としてフルタイムで働きながら勉強している。
なぜこれだけハイペースで勉強が進められるのか。
理由は３つある。

#勉強がはかどる理由
１．カリキュラムの数と受講期間の日数を把握して勉強計画を立てている
２．可能な限り前倒しで勉強を進めている
３．質問できる環境がある。共に学ぶ仲間がいる

###１．カリキュラムの数と受講期間の日数を把握して勉強計画を立てている
受講期間が6ヵ月間と長丁場で且つ、カリキュラム数も多いため、1日あたりこなすべきカリキュラムの数を把握することが重要である。
全カリキュラム数÷6ヵ月間の日数で計算している。

###２．可能な限り前倒しで勉強を進めている。
始めたての頃は要領も分からないため、個々のカリキュラムの難易度に関係なくあまり進まなかったが、勉強に慣れてきてからは進めるペースを上げている。
自分は、勉強の早い人とそうでない人の違いは「簡単な課題の時にどれだけ進めているか」だと思う。
難しい課題に取り組むときは誰でも時間がかかる。そのため1日3個ずつと決めていても、スケジュール通りに進まない時もある。
が、、簡単な課題であれば3個と言わず4個、5個（或いはそれ以上）できると考える。
いつもより多くやることで1日にこなせる数の上限を上げることができる。新たな実績ができる。
それで、最初の時点での目標3個でも昨日は5個できたから今日も5個進めよう。と考えている。
もちろん、カリキュラムの内容によって5個まで進まない場合もある。
5個進まなかったとしても気にする必要はない。（遅れているわけではないのだから）
今日の課題は簡単だったからすぐ終わった。ということで目標通りの数だけこなすから、早い人とそうでない人とで差が生まれると考えている。（理由の一つとして）

###３．質問できる環境がある。共に学ぶ仲間がいる。
これは自分にとっては大きなメリットとなっている。
というのも、スクールに通い始める以前は趣味でプログラミングをやっていたためプログラミング仲間も、教えてくれる人も身近にいなかったためである。
自分で調べても分からないときに質問できることで、問題解決までの時間が大幅に短縮された。
また、共に学ぶ仲間がいることでモチベーション向上にもなっている。
Google OAuth 2.0 は危険なのか

# OAuth 2.0 は危険！？

`oauth セキュリティ`ってググるとまぁひどく書かれてて、認可用だから認証には使うなよっていろんな人が言ってた。
あれ？　じゃあ我らが偉大なる devise と omniauth-google-oauth2 の黄金コンビって実はクソだったの？　と私は途方にくれてしまった。

# じゃあどうすればいいんだよ

認証には OpenID Connect 使えと言われた。
しかし `rails openid` `devise openid` ってググっても見つかるのはメンテナンスされてなさそうな gem ばかり。
そんな🍌！
と思って検索しても情報が全くない。
だいたいそもそも omniauth-google-oauth2 の readme にはしっかりと認証って書かれてるわけで、まさか嘘ついてるの？
っと思ったその時。あるサイトを見つけた。

# 答え

https://developers.google.com/identity/protocols/OpenIDConnect

URL から分かる通り公式。

<img width="660" alt="スクリーンショット 2017-12-19 23.41.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/188872/0c3a402d-1a0c-81b7-ee28-84459c1500e2.png">

あれ？　落ち着いて翻訳してみる。

<img width="654" alt="スクリーンショット 2017-12-19 23.41.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/188872/41bd278d-b855-da2a-7fae-4c7063738344.png">

……

<img width="451" alt="スクリーンショット 2017-12-19 23.41.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/188872/06ee8075-e5d7-9614-b791-62302c131ed1.png">

あっはい。
すみませんでした今度から公式ドキュメントちゃんと見ます。

# 結論

Google OAuth 2.0 は認証に使える！
多分な。
※ google 以外は知らない。
kubeconfig管理の俺的プラクティス

## 前提

複数クラウドのkubernetesを利用する場合、 認証情報等が個々のymlファイルに別れてしまうため、
`kubectl`コマンドを使う場合には kubeconfigファイルを指定してコマンド打つという方法が1つ。

```
kubectl get pod --context=hoge_context --kubeconfig=/Users/dev44nobu/.kube/hoge.yml 
kubectl get pod --context=foo_context --kubeconfig=/Users/dev44nobu/.kube/foo.yml
```

(☝︎ ՞ਊ ՞)☝︎ < めんどくセー

## 俺的プラクティス

環境変数`KUBECONFIG` に複数ファイルのパス通してやると勝手にマージされるらしいので、 
適当なディレクトリにymlファイルをまとめて格納、`.bash_profile`等で以下のコマンドを実行してやるのがジャスティスな気がする。

```
export KUBECONFIG="$KUBECONFIG:`ls $HOME/.kube/*.yml | tr '\n' ':'`"
```

これで`kubectl`コマンド利用時に冗長なconfigファイルの指定することから解放されます(°▽°)

```
kubectl get pod --context=hoge_context
kubectl get pod --context=foo_context 
```

## 追記1

[stern](https://github.com/wercker/stern) を利用している場合は、 以下のPRが取り込まれている 1.6.0を利用しないとエラーになります

https://github.com/wercker/stern/pull/58


## 参考リンク
https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/#append-homekubeconfig-to-your-kubeconfig-environment-variable
dpktを使ってPCAPファイルを連結してみた

FUJITSU Advent Calendar 2017 part2 の20日目の記事です。
 (注意）この記事は個人の見解であり、所属する会社、組織を代表するものではありません。

#前提
常にファイルが追加され続けるPCAPファイルを一つの連続したファイルとして読み込ませたい。

例えばtsharkの -b オプションを指定した場合など、
複数のPCAPファイルが常に生成され続ける状態で、
先頭のファイルから連続してPCAPのデータを処理したい場合を考える。
(要はPCAPファイルの区切りで処理を中断させたくない)

#解決方法
Pythonのdpktモジュールを用いて
入力にファイル名一覧のファイル、出力にPCAPファイルとするプログラムを作成した。
下記の dpkt_merge_pcap.py に相当する
https://github.com/t-umeno/dpkt_merge_pcap
https://github.com/t-umeno/dpkt_merge_pcap/blob/master/dpkt_merge_pcap.py

#使い方
```
pip install dpkt
./dpkt_merge_pcap.py [-l input_pcap_file_list] [-o output_pcap_file]
```
要は-l PCAPファイル名一覧のファイル -o PCAPファイル出力先 を指定する。
オプションを指定しないと標準入力からファイル名一覧を読み込み、
標準出力にPCAPファイルを出力する。

#解説
```
#!/usr/bin/python

import getopt, sys
import dpkt,socket

```
dpkt等の必要なモジュールを取り込む。

```

def usage():
    print "dpkt_merge_pcap [-l input_pcap_file_list] [-o output_pcap_file]"

```
-h オプション指定時やオプション誤り時に使用方法(usage)を表示する。

```
def main():
    input_pcap_file_list="/dev/stdin"
    output_pcap_file="/dev/stdout"
```
main()関数を開始し、
PCAPファイル名一覧のファイル名のデフォルト値を標準入力とし、
PCAPを出力するファイル名のデフォルト値を標準出力とする。

```

    try:
        opts, args = getopt.getopt(sys.argv[1:], "hl:o:", ["help", "input_pcap_file_list=", "output_pcap_file="])
    except getopt.GetoptError as err:
        # print help information and exit:
        usage()
        sys.exit(2)

```
-h オプション、-l input_pcap_file_listオプション、-o output_pcap_file以外の
オプションが指定されていれば、usageを表示し異常終了する。

```
    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit(0)
        elif o in ("-l", "--input_pcap_file_list"):
             input_pcap_file_list = a
        elif o in ("-o", "--output_pcap_file"):
             output_pcap_file = a
        else:
            assert False, "unhandled option"

```
-h オプションが指定されていれば、usageを表示し正常終了する。
-l input_pcap_file_list オプションが指定されていれば、
PCAPファイル名一覧のファイルを input_pcap_file_list で指定したファイルとする。
-o output_pcap_file オプションが指定されていれば、
PCAPの出力先を output_pcap_file で指定したファイルとする。

```
    output_pcap = open(output_pcap_file,'wb')
```
PCAPの出力先に指定したファイルを書き込み目的で開く。

```
    pcw = dpkt.pcap.Writer(output_pcap)
```
dpktモジュールにPCAPの出力先を指定する。

```
    f = open(input_pcap_file_list)
```
PCAPファイル名一覧のファイルを開く。

```
    line = f.readline()
    line = line.rstrip()
```
PCAPファイル名一覧のファイルから1行読み込み、
読み込んだ1行の右端の空白や開業を削除する。

```
    if len(line) > 0:
        input_pcap = open(line,'rb')
        pcr = dpkt.pcap.Reader(input_pcap)
        for ts,buf in pcr:
            pcw.writepkt(buf,ts)
        input_pcap.close
```
①PCAPファイル名一覧のファイルから読み込んだ1行の長さが0でなければ、
読み込んだ1行に記載されたPCAPファイルを開いて読み込み、
読み込んだPCAPをPCAP出力先に指定したファイルに出力する。
読み込んだ1行に記載されたPCAPファイルを最後まで読み込んだら
読み込んだ1行に記載されたPCAPファイルを閉じる。
※PCAP出力先のファイルを閉じないことに注意する。

```
    while line:
        line = f.readline()
        line = line.rstrip()
        if len(line) == 0:
            continue
        input_pcap = open(line,'rb')
        pcr = dpkt.pcap.Reader(input_pcap)
        for ts,buf in pcr:
            pcw.writepkt(buf,ts)
        input_pcap.close
```
①をPCAPファイル名一覧の行数だけ繰り返す。

```
    f.close        
    output_pcap.close
```
PCAPファイル名一覧のファイルとPCAP出力先のファイルを閉じる。

```    
if __name__ == '__main__':
    main()
```
main()関数を呼び出す。
静的サイトジェネレータPelicanの動的サイト生成

静的サイトジェネレータPelicanを使ったサイト生成を効率的に行うパッケージ[Takuhai](https://github.com/daizutabi/takuhai)を作成しました．Pelicanでは，記事を更新したら`pelican content`を実行してサイトを生成します．ブラウザ上で確認したいときには，`python -m pelican.server`を実行します．この2段階のステップが結構面倒なことが[Takuhai](https://github.com/daizutabi/takuhai)を作成した動機です．

Takuhaiは，Pelicanプロジェクト内の記事ファイルが更新されたら次のことを実行します：

+ 記事をビルドしてHTMLファイルを生成します．
+ ローカルのHTTPサーバを立ち上げて，生成した記事をブラウザで表示します．
+ 記事が更新されたら，その都度ビルドして，ブラウザのページを自動でリロードします．

本パッケージを作成するにあたって，次の記事を参考にしました：

+ [Using LiveReload with Pelican](https://merlijn.vandeen.nl/2015/pelican-livereload.html)
+ [LiveReload with Pelican](http://tech.agilitynerd.com/livereload-with-pelican.html)

これらの記事が提供する機能に加えて，Takuhaiでは以下の改善を加えています：

+ [PyPI](https://pypi.org)および[Anaconda Cloud](https://anaconda.org)からのインストール．
+ 実行コマンド`takuhai`の実装．
+ ホスト名やポート番号の指定．
+ ブラウザの自動起動．
+ 相対URLと絶対URLの選択．

特に有用と考えている「相対URLと絶対URLの選択」について説明します．Takuhaiの実行コマンド`takuhai`はデフォルトで相対URLでサイトをビルドします．これは`pelicanconf.py`の設定を上書きします．

Pelicanドキュメントの[URL settings](http://docs.getpelican.com/en/stable/settings.html#url-settings)によれば，絶対URLが望ましい選択とされています．しかし，これではローカルHTTPサーバを立ち上げても，リンク先が外部サイトになってしまいます．望ましい動作とは言えないでしょう．

Takuhaiでは，`pelicanconf.py`の設定を上書きすることで，ローカルHTTPサーバの場合に限って相対URLを使うことができます．`pelicanconf.py`の`RELATIVE_URLS`は常に`False`にしておきましょう．開発用に`takuhai content`としたときには相対URLを使い，公開用に`pelican content`としたときには絶対URLを使います．公開前には忘れずに`pelican content`を実行しましょう．

Takuhaiのインストールは簡単です．

```bash
> pip install takuhai
```

condaパッケージも用意しています．

```bash
> conda install -c daizutabi -c conda-forge takuhai
```

インストールができたら，いつも実行している


```bash
> pelican content
```

の代わりに


```bash
> takuhai content
```

を実行してみましょう．`http://localhost:8000`にアクセスすると記事が表示されます．記事ファイルを更新すると，ブラウザのページが自動でリロードされ，最新の内容に変更されることが確認できます．

なお，Takuhaiパッケージを公開する手順については，[「Pythonパッケージの作り方」](https://iroha.daizutabi.net/)で紹介しています．本記事と合わせて参考にしていただければ幸いです．
Netbeansの初期設定(JavaEE向け)

# はじめに

JavaEEの開発するときに、IDEの選択肢としてNetbeansがあがってきます。Glassfishを使う場合なら、使っている人も多いのでは。初期に設定しておきたいものをまとめておきました。

## UTF-8

http://blog.cototoco.net/work/201311/160/

glassfish側も設定
http://etc9.hatenablog.com/entry/20130309/1362812169

## コーディングスタイル

https://github.com/markiewb/eclipsecodeformatter_for_netbeans

https://github.com/google/styleguide/blob/gh-pages/eclipse-java-google-style.xml



## ライセンスヘッダー

ソースのヘッダに、ライセンスの条文をデフォルトでつける機能です。

### 新規作成時

http://stackoverflow.com/questions/38484105/how-to-set-project-license-header-in-a-netbeans-module

https://netbeans.org/gplv2.html

### 既存の変更
ライセンスの条文が変わったり、プロジェクトの途中からいれられるように、既存ファイルに対して変更するためのプラグインがあります。
http://plugins.netbeans.org/plugin/17960/license-changer

----

## JavaEE 参考リンク

* https://www.slideshare.net/agetsuma/cdi20-javadaytokyo-jdt20164c
* http://stackoverflow.com/questions/37082364/a-summary-of-all-java-ee-specifications
* http://enterprisegeeks.hatenablog.com/entry/2015/09/18/120844
パソコンを持たずに「RustのLT会！ Rust入門者の集い #4」に登壇してきました！

RustのLT会！ Rust入門者の集い #4というイベントに登壇してきました。パソコン無しで！

[イベントサイト](https://rust.connpass.com/event/72649/)

## イベントの趣旨

Rustの初心者向けLT会です。前回は初心者向けと言いながらレベルが高すぎて12,3人途中で帰ったというイベントです。私は前回は参加していませんが今回は初心者でも楽しめたのでご報告します！

### パソコンを持たずに参加してきた

パソコンが使えなくなりまして……。それでも登壇したかったのでiPadでの参戦です。iPadでのプレゼンは難易度が高いのであまりおすすめできません。

## 発表内容

Rustの型推論の話をしてきました。昔書いた記事：[Rustの型推論がどこまで強力なのか試してみた](https://qiita.com/aimof/items/c00b911ef5fb8cfed149)がベースです。

[配列とスライスとVecの挙動の違いについて調べてみた](https://qiita.com/rchaser53/items/030b6a6444032b892a27)という人や、[RustでAPIを叩くCLIを作る](https://speakerdeck.com/khigashiguchi/rustdeapiwokou-kucliwozuo-ru-at-rustfalselthui-rustru-men-zhe-falseji-i-number-4)という人など、Rust初心者ってレベル高いなと思わせる（それでも前回より初心者向けらしい）発表が続く中、始めたばかりの頃に個人的に検証した内容を元にした発表で大丈夫だろうか、となかなか心配でした。iPadだし。

### クイズ形式

[発表資料](https://www.slideshare.net/AitoShiroshita/rustrustlt20171218)

今回はクイズ形式にしてみました。iPadでの発表する覚悟を決めたあといきの電車で急遽思いついての変更です。（終業時間とイベント開始時間が同じだから実はイベント中に作っていたような……。まあ、今回は発表しながらスライド作った人がいるのでセーフ）

そこそこ喜ばれたネタがありまして、

「会社紹介。Qiitaオーガナイゼーションにおける投稿記事の二番目がRustの会社に務めています」
「おおー」
「（Rust記事を書いたのは）全部一人です」
「（笑）」

余談ですが、__Vimに負けました__。

結果的にクイズ形式はなかなか食いつきが良かったです。Rust特有の型推論の話を扱ったのもなかなか楽しんでもらえたようでなにより。一番受けがよかったクイズは、最後に持ってきたこれ。

```rust
fn main() {
    let a: i8 = 1;
    let b: i8 = 257;
    println!("{}", a == b);
}
```

true, false, Errorどれだ！？

「trueになります」
「これWarnでますよね？」
「でます」

### まとめ

Rust楽しいと再確認。コミュニティも楽しんできました。

お世話になった皆様ありがとうございました！
hexoとやらを試してみた

#hexo
https://hexo.io/:embed:cite

githubのアカウントあれば誰でもブログを公開できるとのことです
ということで試してみました

##まずはリポジトリ作成
[username].github.io
というリポジトリを作成

##hexoの準備
公式通りに
hexoをグローバルにインストール

```
# npm install hexo-cli -g
```

以下のコマンドでディレクトリを作成します

```
# hexo init blog
```

作成されたディレクトリに移動して、モジュールをインストールします

```
# cd blog
# npm install
```

インストールできたら、以下のコマンドで起動します

```
# hexo server
```

http://localhost:4000/ にアクセスすると雛形ができてます
簡単ですね

##githubで公開

作成されたディレクトリ配下にある<font color="DeepPink">_config.yml</font>を弄ります
<font color="DeepPink">_config.yml</font>ではサイトのタイトル等を変更することができます

```_config.yml
deploy:
  type: git
  repo: https://github.com/[username]/[username].github.io.git
  branch: master
```

編集したら、以下のコマンドでデプロイ

```
hexo deploy -g
```

エラーがでました。
どうやら、<font color="DeepPink">hexo-deployer-git</font>というモジュールをインストールしないといけないようです。ってことでインストール

```
npm install hexo-deployer-git --save
```

改めてデプロイ

```
hexo deploy -g
```

[https:\[username\].github.io/](https:username.github.io/)にアクセスすると先程[http://localhost:4000/](http://localhost:4000/)でみたページにアクセス出来ます
**※ちなみに反映にそれなりに時間が掛かります**

##テーマの導入
https://hexo.io/themes/index.html:embed:cite

こちらのサイトから気に入ったプラグインcloneします

例えば、こちらなら
https://github.com/mkkhedawat/clexy:embed:cite
**README**にあるようにコマンドを実行します

```
# git clone https://github.com/mkkhedawat/clexy themes/clexy
# git clone https://github.com/mkkhedawat/clexy themes/clexy
# yarn remove hexo-renderer-ejs
# yarn add hexo-renderer-jade
# yarn add hexo-prism-plugin
```

<font color="DeepPink">_config.yml</font>を編集

```_config.yml
prism_plugin:
  mode: 'preprocess'    # realtime/preprocess
  theme: 'default'
  line_number: false    # default false
theme: clexy
```

デプロイ

```
hexo deploy -g
```

##記事の投稿
以下のコマンドを実行

```
# hexo new post 新規ページ
```

<font color="DeepPink">source/post/新規ページ.md</font>が作成されているので弄ってpushすれば記事が投稿できます

以上です。

ところで、hexoってなんて読むんですかね・・・？
[Ionic]画像をピンチ、パンのジェスチャーで拡大、縮小させる

この記事は[Ionic Advent Calendar 2017](https://qiita.com/advent-calendar/2017/ionic)の17日目です。

---



ピンチやパンと言ったジェスチャーで画像をズームする方法がわからなかったところ、調べたらIonic Forumに欲しい機能に合致する回答がありました。Ioni Forumに深く感謝して記事を書きます。
[Ionic Forum - Zoom on image in Ionic?](https://forum.ionicframework.com/t/zoom-on-image-in-ionic/45910/27)

# やりたいこと & デモ

こんかんじのズーム。

![zoom-pan.gif](https://qiita-image-store.s3.amazonaws.com/0/165335/bc8a43e3-42f1-8622-b972-3346abdbcb7c.gif)

[Demo](https://ionic-my-sandbox.firebaseapp.com/#/zoom-image)
[ソースコード](https://github.com/scrpgil/ionic-my-sandbox)

# なぜデフォルトだとできないのか？

そもそもこの操作はSafariやChromeといったブラウザならできるのにWebViewを使用しているIonicではできません。
それはviewportの設定で動作しないように設定されているからです。

````index.html
  <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
````

たとえば、これを以下のように変更すれば、ピンチ操作はできるようになりますが、ページ全体が拡大されるので、なんだかなーといった感じです。

````index.html
  <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=2.0, user-scalable=yes">
````

※Ionic DevAppで確かめたらiOSでしか動作しませんでした。

Forumに乗っていた方法だとズバリ画像のみ拡大・縮小が行えるのでよりアプリっぽい感じがします。

# 実装

リンク先がソースコードになります（Forumの内容の転載ですが・・・）
[ソースコード](https://github.com/scrpgil/ionic-my-sandbox/blob/master/src/directives/zoom-pan/zoom-pan.ts)

Hammer.jsを使ってジェスチャーの内容を監視して、pinchやpanedなどの操作の際に、CSSを書き換えて拡大、縮小、移動を行っている様子。

Hammer.jsなんてどこでインストールしたんだ？と思ったけど、ionic-angularのgestureコンポーネント内のhammer.tsがそれに当たるみたい。これってhammer.jsをTypeScriptで実装したんだろうか？凄い。

[ionic-team/ionic/src/gesture/hammer.ts](https://github.com/ionic-team/ionic/blob/master/src/gestures/hammer.ts)

# まとめ

私自身、「ここの画像を拡大したい」と言われた時に「あれ、どうやればいいんだ」と途方にくれた経験があります。
本記事の回答が記載されたのは今年の7月であり、タイムリーな時期に回答があったおかげで何を逃れました。
やはり何か困ったことがあったらIonic Forumを見ることをおすすめします。その時に回答がなくても定期的に覗いてみたほうがよいです。

ちなみに、Direciveなので基本的に拡大・縮小ボタンを作るとか、動的にズーム、ムーブなどの処理をすることはできません。でも、Importに引数を増やしてngOnChangeとかで色々やればできるようになります。その方法はいずれ書く・・・。

# 他の方法

Ionic2-zoom-areaというcomponentも存在します。参考までに・・・。
[DEMO](https://ionic-my-sandbox.firebaseapp.com/#/ionic2-zoom-area)
[ソースコード](https://github.com/leonardosalles/ionic2-zoom-area)
FLACファイルからアルバムアートを取り出す方法

FLACファイルにはCUEシートやアルバムアートを埋め込むことができるが、対応していないプレイヤー向けにそれらを取り出したい時がある。

## FLACエンコーダーの準備
[FLAC公式サイト](https://xiph.org/flac/)から最新のエンコーダー(v1.3.2)をダウンロードし、適当な場所に展開する。
ここでは`C:\Programs\flac-1.3.2-win`に展開したものとする。


## アルバムアートを取り出す
```bat:Cmd
rem 64bitOS向け
cd C:\Programs\flac-1.3.2-win\win64
metaflac.exe --export-picture-to={画像ファイル.jpg} {FLACファイル}
```
画像ファイルは形式が何で格納されているかわからないため、JPEGで表示できなければPNGに変えてみたりすること。
[IrfanView](http://www.irfanview.net/)を使うと、拡張子が間違っていれば自動で修正してくれるのでおすすめ。

## 参考
https://xiph.org/flac/documentation_tools_metaflac.html
globalに置いたdelegateでメモリリークした、その対策



タイトルの通りの状況です。
singletonなりDontDestroyOnLoadを適用したオブジェクトにアタッチされたクラスなりに
デリゲートをメンバ変数として定義。
外部から関数を登録（+＝）したものの解除（-＝）を忘れてしまった。

[http://ufcpp.net/study/csharp/MiscEventSubscribe.html](http://ufcpp.net/study/csharp/MiscEventSubscribe.html)
こちらでも問題が指摘されていますが
この場合、受け取り側がいつまでも解放されなくなります。
例えばCharacterManager.DispatchSignalデリゲートにEnemy.SendSignal関数を登録。
Enemy死んだのでGameObjectごと削除。
CharacterManager.DispatchSignalデリゲートから登録解除を忘れているとEnemyクラスは解放されません。
もしEnemyがmeshやtextureの参照を持っているならいつまでも解放されません。

さらに間違って無名関数を登録してしまったら解除不能になります。
メモリリークの温床ですね。

#対策
デリゲートを使わずUniRXを使います
関数を登録したらIDisposableが返るので無名関数を登録しても大丈夫です

[https://github.com/ufcpp/UfcppSample/blob/master/Chapters/Resource/WeakReference/WeakEvent/WeakEventExtensions.FinalizeDiposable.cs]
(https://github.com/ufcpp/UfcppSample/blob/master/Chapters/Resource/WeakReference/WeakEvent/WeakEventExtensions.FinalizeDiposable.cs)

さらに上記リンクで使われているデストラクタによるDispose忘れの検出を仕込みます
Unityなら~FinalizeDisposable()のところにDebug.LogErrorを仕込めばよいでしょう

ついでに#ifを使ってRelease時はreturn observable.Subscribe(onNext);とすれば
newのコストを減らせるでしょう

#雑感
そもそもグローバルにデリゲートを置くな、というのはあります
長寿命のオブジェクトが短寿命のオブジェクトの参照を持つのはメモリリークの危険性があります
そのことを踏まえてなるべくメモリリークを自動検出できる仕組みを実装していきたいです
JavaScriptで全角を2、半角を1で数える（半角カタカナ対応）

同種のものはたくさんあるのですが、半角カタカナを2と数えるものが多かったため
1と数えるよう変更したものです。

```js
var charcount = function (str) {
	len = 0;
	str = str.split("");
	for (i=0;i<str.length;i++) {
		if (str[i].match(/[ｱ-ﾝﾞﾟ]+/)){
			// 半角カタカナ
			len++;
		} else {
			esc = escape(str[i]);
			if (esc.match(/^\%u/)){
				// 全角
				len+=2;
			} else {
				// 半角英数
				len++;
			}
		}
	}
	
	return len;
}
```
Vue.js日本語サイトを支える仕組み

このエントリは[Vue.js #4 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/vue4)の20日目です。

### :point_up: はじめに
Vue.js の良いところを聞くと、日本語サイト:flag_jp:が充実しているといった点がよく挙げられます。
私も2017年2月から[Vue.js 日本語サイト](https://jp.vuejs.org/)のメンテナに加わり[^1]、継続的にドキュメントの翻訳などをしてきたので、嬉しく感じます:blush:

今エントリでは自分がメンテナになってから、
フロー改善について取り組んできたことを紹介していきます:sparkles:

### :bulb: 気付き
- lintのエラーがちらほらあるな？
- これ本当に人間がやらなきゃいけない更新？

### :eyes: lintのエラーがちらほらあるな？
`npm run lint`することで、lintエラー[^1]に引っかからないか確認できるのですが、
それが強制されておらず、ユーザー任せとなってしまっていたので、mergeのタイミングでlintエラーに気付くということがありました。

そのため、

- `precommit`でlintを強制
- pull request作成時にtopicブランチでもCircle CIでlintを行う

ように改善しました。

### :eyes: これ本当に人間がやらなきゃいけない更新？
本家の更新を見ていると、CSSのスタイル変更など翻訳とは関係ない更新も多くあることに気付きました。
こういった更新はcherry-pickして取り込んでいたのですが、このへんを自動化できないかな？と思うようになりました。

そこで、作ったのがche-tsumiです。[^2]
https://github.com/re-fort/che-tsumi

che-tsumiでは、
<img width="600" alt="vue-translation.png" src="https://qiita-image-store.s3.amazonaws.com/0/98379/855b2da5-77f2-2a8b-ee73-24a4ad690632.png">
1. 本家ドキュメントの更新を検知
2. 日本語サイトのGitHub repoにissueをたてる
3. cherry-pickしてみて、conflictが発生しないかチェック
4. conflictが発生しなければ、pushしてpull requestを作成する

といったようなことをやってくれます。
実際に投げられているissue/pull requestはこんな感じです。

<img width="782" alt="Screen Shot 0029-12-19 at 2.02.32 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/98379/a6a7e58c-fbe9-9ef8-5d75-5f4b86a3afc3.png">

<img width="772" alt="Screen Shot 0029-12-19 at 1.52.35 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/98379/1c5927d3-5a72-63b3-7336-db7a77325422.png">

che-tsumiを導入したことにより、conflictが発生しない更新は、
pull requestをマージするだけでよくなり、人間の負荷が軽減しました。

また、翻訳文をみていると、このドキュメントはどこまで最新の内容が反映されているんだろう？と思うことがありますが、
本家との差分はissueで確認できる[^3]ため、より見る方にとって親切になったと思いますし、より貢献しやすくなったかなーと思います！

### <img width="25" src="https://qiita-image-store.s3.amazonaws.com/0/98379/f61ee904-afdd-a32e-24e3-7ce74cfce6b7.png"> 所感
今年は[Vue.js サーバサイドレンダリングガイド](https://ssr.vuejs.org/ja/)や[electron-vue](https://simulatedgreg.gitbooks.io/electron-vue/content/ja/)[^4]などの翻訳などもやっていたりしました。
しかし、翻訳がない状態から翻訳するのと、差分を定期的にメンテしていくのは、また別の熱意が必要だなーというのを強く感じました。

以上です:yum:

[^1]: スタイルガイドとして、JTF日本語標準スタイルガイドをカスタマイズしたものを使用しています
[^2]: cherry-pickと茶摘みをかけています
[^3]: この運用をしているのはVue.jsのドキュメントだけであり、vue-routerなどの周辺ツールは現状あてはまりません
[^4]: ひとりでやったのでめちゃ大変だった
Azure Media Services の字幕あれこれ

こんにちは。Azure サポートの土屋です。
Azure Media Services では動画を配信するだけでなくエンコードしたり解析処理をしたりする機能もあります。その中で、字幕を作成する機能について紹介します。

#1. 字幕について
[Azure Media Indexer によるメディア ファイルのインデックス作成](
https://docs.microsoft.com/ja-jp/azure/media-services/media-services-index-content) に紹介されているようにアップロード済みの動画をポータルからまたは SDK を使用して作成が出来ます。

内部では Azure Video Indexer を使用しているためサポート状況および品質は Azure Video Indexer の状況に依存致しまして、Azure Media Indexer 2 (Preview) は日本語にも対応しております。

#2. ツールを使って作成 
ポータルからだと日本語に対応している Azure Media Indexer 2 が選択出来ないので Azure Media Services の便利ツール [Azure Media Services Explorer](http://aka.ms/amse) を使用します。こちらはソースコードも公開されてますので Media SDK のサンプルとしても利用できます。このツールが公開されてから SDK の使い方に関するお問い合わせが著しく減少した便利ツールです。

アダプティブ化する前の単一の MP4 ファイルを選択して Azure Media Indexer 2 を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/c9321e37-13d1-a8c9-108d-379892bfda71.png)

言語設定で言語を設定、インデックス作成オプションから TTML、SAMI、WebVTT の希望する形式を設定してインデックス作成を押せばいいだけ。簡単！結果はアセットとして Azure Media Services 上に保存されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/8bf5b55f-915b-1d5f-3b11-548ad3b95b1a.png)

複数の形式を同時に作成しても公開前にプライマリ設定を変更することで任意の形式を利用できますが、今回は説明を簡単にするために WebVTT を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/b8ed4841-d757-4f7e-eeee-9733cd55aa76.png)

# 3. 字幕を公開
公開方法として字幕もストリーミングとして公開する方法と、ストレージから公開する方法があります。しかし、ストレージから公開すると Blob ストレージの URL になるためストリーミングの URL とクロスドメインになります。なので、ストリーミングとして公開することをオススメします。

公開は作成した VTT ファイルのアセットを選択してロケーターを作成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215266/7d6c019b-b6a4-b149-e35f-6c5632827823.png)

ロケーターのタイプとしてストリーミングロケーターと SAS ロケーター (ストレージからの公開) の選択が可能ですがストリーミングロケーターを選択します。

そうすると以下のような字幕の URL が取得されます。

```
https://*.streaming.mediaservices.windows.net/*/*.vtt
```
作成された字幕の URL をポータルですと [Azure Portal を使用したオン デマンド コンテンツ配信の概要](https://docs.microsoft.com/ja-jp/azure/media-services/media-services-portal-vod-get-started) にある手順で公開されたストリーミング URL と一緒に使用します。こちらの公開も Azure Media Explorer を使用すると便利です。

# 4. Azure Media Player に設定
Azure Media Player は動的に対象のクライアントで利用可能なテクノロジーを選択して再生してくれる無償のプレーヤーです。使い方は、[Announcing Azure Media Player](https://azure.microsoft.com/ja-jp/blog/announcing-azure-media-player/) を参照して下さい。Azure CDN 上にホストされているので、バージョンを指定してダウンロードして使用します。

サンプルでもあるように以下のように source でストリーミング URL を manifest まで指定して使用します。ここに "captions" として作成された VTT ファイルの URL を設定するば字幕として表示されます。

```
<source src="https://*.streaming.mediaservices.windows.net/*/*.ism/manifest" type="application/vnd.ms-sstr+xml" />
<track label="Japanese" kind="captions" src="https://*.streaming.mediaservices.windows.net/*/*.vtt" srclang="ja" default></track>
```

もちろん複数言語の字幕の設定も可能で、OS の言語設定により使用する言語が選択されます。簡単なので是非使ってみて下さい。