OmniAICreator/Qiita-1.07M huggingface dataset:
プログラミング初心者がkotlinでチャットアプリを作りたい話【１日目】

VISだったり、ローカルの開発環境だったり環境構築って難しいと思います。実際難しい。
今日は、Kotlinを公式ドキュメントなどで頑張って調べながら、Hello,Worldまで行きたいと思います。

##Vagrantfileの設定
Vagrantのboxはbento/centos-7.1を使おうと思っています。

Vagrantfileの書き換え設定は、Foward-portのみでVagrantfileによると、localhost:8080(または、自分の選択した番号）
に接続すると、このVagrantのサーバーにアクセスできるようです（私の英語の理解があっていればですが）

##前提ファイルのインストール〜kotlinインストール
```
$sudo yum install unzip zip
$curl -s "https://get.sdkman.io" | bash
$source "$HOME/.sdkman/bin/sdkman-init.sh"
$sdk install kotlin
```
SDKMAN!はサクサクとインストールを進めることができました。 rbenvツールはPATHを通さなければいけない分インストールの手間はSDKMAN!のほうが簡単なのかもしれませんね。

##Hello,World!
Hello,worldする前に、上記では＄kotlin　から始まるコマンドを打つことができません。
理由としては、kotlinはJavaを使って動かしているため、Javaをインストールすることが必要です。これは、SDKMAN！で可能ですよ（べんり！）
Javaはkotlinに比べたら少し体感インストールに時間がかかりました。
```
＄sdk install java  
```
をすることで、利用が可能になります。

```hello.kt
fun main(args: Array<String>) {
    println("Hello, World!")
}
```
ターミナルでこのように書き、(私は、共有フォルダーの設定に失敗することが最近度々あるので、vimをインストールし、

```
$ kotlinc hello.kt -include-runtime -d hello.jar
```
とコマンドを打つことで、.jarのファイルに変換されます。

その他のコマンドに関しては、

```
$kotlinc -help
```
を参照するとコマンドの一行解説が書いてありますよ。（-を忘れないように）

###参考文献
- [SDKMAN!](http://sdkman.io/index.html)
- [Kotlinコマンドライン・コンパイラの使用](https://kotlinlang.org/docs/tutorials/command-line.html)
PWA で SS リーダーアプリ作った



# アプリについて
成果物: https://ssconnect.elzup.org/ (モバイル対応のみ)
リポジトリ: https://github.com/elzup/ssconnect

![icon-60@3x.png](https://qiita-image-store.s3.amazonaws.com/0/40717/ec1bebb4-035a-81c2-4b82-652981a4c941.png)

<div style="display: flex;">
<img src="https://qiita-image-store.s3.amazonaws.com/0/40717/dcdf27aa-e100-2f47-2924-5a8389481200.gif" />
<img  src="https://qiita-image-store.s3.amazonaws.com/0/40717/12279a02-8aaf-c528-98f7-34bb075f9f98.gif" />
</div>


リーダーと呼びましたが、いわばアンテナアプリ側です。複数のSSまとめサイトの SS リンクリストを表示します。


このアプリの一つ目の特徴は検索です。作品タグ + キャラ名で絞り込み、検索クエリをタブ化して保存できます。
もう一つの特徴は複数のサイトをあつかっていながらSSの重複がないことです。タイトルをある程度正規化して集約しています。

データは Rails で実装した API からとってきています。記事データは SS アンテナサイトの RSS を収集しています。SSをRSSで非SSRです。
実はこのアプリのコアはサーバーサイドで、収集やタグ整理、管理の自動化に力を入れています。

## PWA
React Native で作っていた個人開発アプリを PWA に移行しました。(1から)

作っているものが Native である必要がないこと、アプリストア管理やリリース準備などの手間を感じていたこと、デバッグ環境が軽くなりそうなことなどがきっかけです。(小さい個人開発しかして無いので狭い視点かもしれません)。もちろん PWA にはもっとたくさんメリットがあると思います。


### デプロイまでした感想
GitHub Pages と create-react-app を使っているのでその時点で結構パフォーマンスが満たされている
感じがします。
manifest.json など最低限の設定でスプラッシュ画面がつく体験が良かった。
やはり Web 開発なので View の開発が断然楽で体に良かった。

今後
Audits などで PWA しっかり最適化して記事を上げたいと思います。
まだ触っていませんが、PWA でも store の migration などは必要になって来ると思います。
PC 対応は自分に需要がないので後回しです。


# 使っているもの
## Redux
必須。

## FlowType
型は必須。

## s2s
https://github.com/akameco/s2s

Action の Type 書いた瞬間に Redux 構成と reducer, action, Flow 型づけ、テストなどなどを一瞬で作ってくれるので神。自分は必須。

## styled-components
必須。

https://www.styled-components.com/

綺麗に整理して使ってないけど最近は Component ファイル内に雑に生やして使っている。
https://github.com/SSconnect/ssconnect/blob/master/src/components/StoryCell/index.js

擬似クラスや keyframe も書きやすい。

## redux-persists
必須。

2行くらいで Store 永続化出来る。after REHYDRATE で Action 呼ぶ機能が欲しい。

## material-ui
http://www.material-ui.com/#/
コンポーネント群ライブラリ。特にこだわりなく適当に選んだ。

# デバッグ系

## Redux DevTool Extension
必須
![Developer_Tools_-_http___localhost_3000__and_index_js_—_components_StoryCell_—____ghq_github_com_SSConnect_ssconnect_and_Tomato_One.png](https://qiita-image-store.s3.amazonaws.com/0/40717/1d986689-b2dc-8f4d-e53f-627af87e71ee.png)

## StoryBook

![Storybook_and_Document2.png](https://qiita-image-store.s3.amazonaws.com/0/40717/d09f22cd-bd56-2571-6b89-d7043023ef35.png)

横幅 full のコンポーネントのための Wrap が欲しい。


# デプロイとか
## react-create-app
開発のための script (react-scripts)が付いている。
service worker や manifest.json など一通りデフォルトでつくので良い。
```react-scripts reject``` があるのがやっぱり好き。


## gh-pages
今回は GitHub Pages に上げている。gh-pages は dist 用のブランチ管理して push してくれる。
なので gh-pages コマンドで一発。

---

ごく普通のものだけですがこの辺で以上です。

React Native はつまづくところ多かったり開発が安定しなかったのでしばらく 書かないかなと思います。
Redux + Flow の現在の構成がしっくり来すぎてコード書くのが楽しい時期です。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Redux はー<br>まだガンには効かないが<br>そのうち効くようになる</p>&mdash; えるざっぷ (@_elzup_) <a href="https://twitter.com/_elzup_/status/925864190933217280?ref_src=twsrc%5Etfw">2017年11月1日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
F/L というオレオレ言語の製作を通じて思ったこと・感じたこと

# はじめに
この文書では、[F/L というオリジナル言語](https://github.com/iigura/FL)の設計・実装を通じて思ったことや感じたことのうち、プログラミングもしくはプログラムをする人＝プログラマに関するものをまとめたものです。

もう少し技術よりの部分は別の記事「[メイキングオブ・プログラミング言語 F/L](https://qiita.com/iigura/items/756e07bafdd5dd361657)」にまとめてありますので、そちらもご覧になっていただければ幸いです。

# 楽しかったところ
* 自分の言語による世界（オレオレ言語ワールド）が徐々に広がっていく様子を実感できたこと
* 開発を通じて、記述言語である Lua について色々学ぶことができた
* F/L は Forth をベースとする言語でしたので、Forth 系言語について勉強するきっかけになった

# 辛かったところ
* 説明のための文章を書かなければならないところ
* ダウンロードできる環境を準備すること（ファイルの清書や github の準備など）
* Lua でソースコードレベルデバッギングできなかったところ（print 文を武器に念力デバッグしたところ）

# 全体としての評価
全体的には、どちらかと言えば楽しい部分が多いように感じました。総合的な評価としては「楽しかった」と思います。

言語設計という行為（＝実装や言語のデザイン）は、「学ぶものが多い」と実感しました。既に多くの人が語っているようにも思いますが、少々辛くてもオレオレ言語は作ってみるべきだと私も思いました。

## コーディングにおける学び
言語のデザインに関しては、その言語の思想というか、その言語らしさとは何か？等に答えていかなければなりません。これは「（現在構築中の）世界を、どのように見るか」ということに他ならず、「どのような世界を実現したいのか」ということだと思います。

今回の F/L は Forth を基としていますが、このような状況です。全く新しい言語を作る場合は、非常にエキサイティングな体験になるのではないかと想像します。

実務的なシステムやアプリケーションを作っているときよりも、より純粋に「（今作っているシステムにとって）ふさわしいプログラムとは何か？」という問題に対峙できる気がしました。

## 文書作成の機会として
新しく生まれた言語に関する入門書やリファレンスは、その言語の開発者が作成しなければなりません（他に書いてくれる人がいないので…）。結果として、文章作成に迫られるという状況が生まれます。私も（本当に）最低限の文書しか作成できていませんが、それでも、その言語に関する解説なりリファレンスを書くという行為は良い文章修行になると感じました。

# 表現としての言語設計・言語製作
絵画や写真、小説など、今この瞬間にも多くの芸術作品が制作されていることかと思います。これらの中にプログラミング言語も入るのではないでしょうか。少なくとも、ソースコードというテキストにより、ひとつの世界を表現するものとして「オレオレ言語」は捉えることが可能ですし、かなり複合的な芸術なのではないかと思う次第です。

# その他
言語処理系については、既存の言語について実装を試みた・実装した経験があります（C に関してはフェードアウト、RIB についてはそこそこ上手く行っている状況）。これらはすでに誰かが確定した文法を持つものについての処理系となります。一方、オリジナル言語を設計する場合、文法とその意味ならびに実装を行わなければなりません。

他の人がどのようにして言語をデザインし、言語処理系を作成しているのか、それをもう少し知りたくなりました。まつもとゆきひろさんの本「言語のしくみ」をざっと読んだ程度ですが、このようなテキストをもっと読んでみたいです。何かオススメのものがありましたら教えて下さい。
言語作成の習作：プログラミング言語 F/L

# はじめに
F/L は Lua で記述された Forth 系プログラミング言語です。オリジナルの Forth とは異なり、浮動小数点値や文字列、無名ワードブロックなどを値として取り扱うことができます。

#インストール方法
Github https://github.com/iigura/FL よりファイル一式をダウンロードして下さい。これらのファイルは lua で書かれた言語処理系のソースコード（拡張子 .lua）と F/L のプログラム（拡張子 .fls）から構成されています。全てテキストファイルです。

#起動方法と終了方法
FL.lua があるディレクトリで lua FL.lua として下さい。EOF を入力（mac のターミナル等では Ctrl-D 押下）で終了します。

#使い方
Forth における . と dup などは同様に使用できますので、 5 dup * . と入力しリターンキーを押すと 5 の 2 乗である 25 が表示されます。詳しくは「[F/L でのプログラミング](https://qiita.com/iigura/items/fe7a69e53cb8b1fd2d7a) 」をご覧ください。

#関連文書
* （簡易な）プログラミングガイド：[F/L でのプログラミング](https://qiita.com/iigura/items/fe7a69e53cb8b1fd2d7a) 
* 辞書ごとのリファレンス：[F/L のワード一覧](https://qiita.com/iigura/items/d8413b256012c8f828bd)
* その他（雑記）：[メイキングオブ・プログラミング言語 F/L](https://qiita.com/iigura/items/756e07bafdd5dd361657)
初めてMacを使ったときにインストールしたApp

はじめてMacを開発用として使うにあたり、インストールしたAppを記録します。

# Google日本語入力
まずは日本語入力から。以下サイトからダウンロードする。
https://www.google.co.jp/ime/

# Firefox
インターネットブラウザ。Safariはあまり使わない。
以下サイトからダウンロード。
https://www.mozilla.org/ja/firefox/

# Thunderbird
メーラ。デフォルトのメールアプリはあまり使わない。
以下サイトからダウンロード。
https://www.mozilla.org/ja/thunderbird/

# Visual Studio Code
エディタ。Vimも使うがパッケージ管理に疲れたのでこちらを使う。
以下サイトからダウンロード。
https://www.microsoft.com/ja-jp/dev/products/code-vs.aspx

# Dropbox
これも個人的に使用するためインストール。
以下サイトからダウンロード。
https://www.dropbox.com/ja/downloading

# Homebrew
macOS用パッケージマネージャ。
https://brew.sh/index_ja.html

Terminalを起動して以下コマンドを入力することでインストールする。途中、Enterキーの入力と管理者パスワードを入力する必要がある。

```bash
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

# Git
Homebrewでインストールする。

```bash
$ brew install git
```
# Ruby(rbenv)
macOSにはデフォルトでrubyがインストールされているが、rubyのバージョンを管理したり切り替えたりするケースも想定されるのでrbenvをインストールする。

```bash
$ brew install rbenv
$ rbenv install -l
(インストール可能なバージョンが表示される)
$ rbenv install 2.4.2
```
`~/.bash_profile`に以下を記述する。ファイルが無ければ作成する。

```bash
export PATH=/usr/local/bin:$PATH
if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi
```

使用するrubyのバージョンを設定する。

```bash
$ rbenv global 2.4.2
```

# Terminalを使いやすくする
デフォルトのターミナルはいろいろと使いづらいことがわかってきたのでここらでカスタマイズする。

まず、シェルをbashからzshに変更する。

```bash
$ chsh -s /bin/zsh
```

次にテーマを変更する。以下記事のものが良さそうなので使わせていただく。手順も記事を参照。

http://cocopon.me/blog/?p=4862

# プログラミング用フォントRictyをインストール

```
$ brew tap sanemat/font
$ brew install Caskroom/cask/xquartz
$ brew install ricty
$ cp -f /usr/local/Cellar/ricty/3.2.2/share/fonts/Ricty*.ttf ~/Library/Fonts/
$ fc-cache -vf
```

# TweetDeck
以下URLからダウンロード・インストール

https://itunes.apple.com/jp/app/tweetdeck-by-twitter/id485812721?mt=12

# Evernote
以下URLからダウンロード・インストール

https://itunes.apple.com/jp/app/evernote-%E3%81%82%E3%82%89%E3%82%86%E3%82%8B%E6%83%85%E5%A0%B1%E3%82%92%E3%81%BE%E3%81%A8%E3%82%81%E3%81%A6%E8%A8%98%E6%86%B6/id406056744?mt=12

# Slack
以下URLからダウンロード・インストール

https://itunes.apple.com/jp/app/slack/id803453959?mt=12

# iTerm2をインストール
Terminalに不便を感じる頃なのでiTerm2に乗り換える。
以下URLからダウンロード・インストール

http://www.iterm2.com/#/section/home

# pecoをインストール
そろそろTerminalでいろいろ遊びたくなる頃なので。

```bash
$ brew install peco
```
Gedit for Mac install

#GeditをMacで使いたい人に
Geditは、Ubuntuで標準なのでそこで初めて出会った人も多いかと思います。
(AtomやEclipseに比べて)非常に軽いのでオススメ。
##初心者向けに
Linuxは、（パッケージ管理ツールの）コマンドでインストールする
Debian系ならaptやapt-get
Red-Hat系ならyumや最近は、yumの後継のdef

Macは、基本brewというコマンドでインストールすることが多い。
brew コマンドは、Homebrewというやつ。

こちらを参考にすると良い。
「Home-brew macOS用パッケージマネージャ」
https://brew.sh/index_ja.html
#Gedit Macのinstall方法
とりあえずグーグル先生曰くこれでインストール
$ brew install gedit
すると、warningが出てきました。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
Warning: Building python from source:
  The bottle needs the Apple Command Line Tools to be installed.
  You can install them, if desired, with:
    xcode-select --install
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
しかし、警告レベルなので無視してたら
最後の方でエラーはきます。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
Error: An unexpected error occurred during the `brew link` step
The formula built, but is not symlinked into /usr/local
Permission denied @ dir_s_mkdir - /usr/local/Frameworks
Error: Permission denied @ dir_s_mkdir - /usr/local/Frameworks
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
なのでとりあえず、警告の指示通り
$ xcode-select --install
してみます。
すると、xcodeがgui上でアップデートしますか？
と聞いてくるのでアップデートする。

再び
\$ brew install gedit
しかし、エラー文は、変わらない...
ここでちゃんとエラー文を読む...笑
Permission deniedのエラー
これは、許可がなくて拒否されているってこと。
エラー文でグーグル先生に聞いたところ
\$ sudo chown -R \$USER /usr/local
※コマンドchownは、所有権の変更
※オプション-Rは、ディレクトリ内全て処理してくれる
すればいいよだってさ。
実行してみると、なんかエラーはく。
chown: /usr/local: Operation not permitted
とりあえず
\$ls -la
してみると
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
drwxr-xr-x   15 root  wheel   480 11  2 04:04 .
drwxr-xr-x@  10 root  wheel   320 11  2 04:38 ..
~~~
drwxrwxr-x   17 username  admin   544 10 26 21:38 Homebrew
drwxrwxr-x  156 username  admin  4992 11  2 04:56 bin
~~~~
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
てな感じになっていておそらく、admin adminから変わったのかな
そこでもう一度、今度こそという願いを込めて実行
$ brew install gedit
通りました。

##感想
言いたいこととしては、geditってUbuntuで標準で使われているくらいだし
軽いとか聞いたことあるし、軽いし、インストール簡単だと思ってた。
しかし実際は、
依存関係が半端ないし、usr/localの下にファイル作ろうとするから
許可の申請必要で初心者すぎる私には、少しだけ辛かった。

ということで、無事にインストールできたので魅力だけでも伝えます。
###魅力
・一瞬で立ち上がり、コマンドのカラーなども標準で入っていて
　デフォルトのインストールでカラーを変更したりできます。

・プラグインが豊富でターミナルを出したりもできるし
　ビルドなどもショートカットを登録して
　ビルド、実行ができるそうです。
　IDEのように使えるということですね。
【Tensorflow】KerasをUbuntu16.04にinstallする

## 1. はじめに
- ディープラーニング用のマシンを複数組んだので、マニュアル代わりに

## 2. 要件
- tensorflow-gpuをインストール**のみ！！**

## 3. 各種インストール
### (1) cudaのインストール
1. https://developer.nvidia.com/cuda-80-ga2-download-archive からinstallerをインストール（cuda-8.0をインストールする）
2. 以下のコマンドでcudaのインストール  

```
$ sudo dpkg -i cuda-repo-ubuntu1604_8.0(tabで補完)
$ sudo apt-get update
$ sudo apt-get install cuda
```

3.　パスを追加する

```bash
# 以下を.bashrc or .bash_profile or .zshrcなどに追加する
# ----------
export PATH=/usr/local/cuda-8.0/bin:${PATH}
export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64:${LD_LIBRARY_PATH}
# ----------

# 追加後、設定ファイルの再読み込み
$ source ~/.bashrc
```

4.　動作確認

```bash
$ nvcc -V
# 出力例）Cuda compilation tools, release 8.0, V8.0.61
```

### (2) tensorflow-gpuのインストール
- 基本的にgoogleの[document](https://www.tensorflow.org/install/install_linux#InstallingVirtualenv)に従って行えばOK
macpro で openbsd




1) fedora導入前に a6 領域を確保しておきます

　　また　Fedora-Workstation-Live-i386-26-1.5.iso　を　DVDにやいておきます。

以下全部　windows PC でやりました。
そして　できあがったハードディスクを　macproにくっつけるだけです
その心は　openbsdをfedoraのgrubで起動します。


2)install fedora
  
3)fedoraを起動して
/boot/grub/grub.cfg　を編集します

menuentry '-------------openbsd' {
set root='hd0,msdos4'
chainloader +1
}


4)install62.fs をddでやいたUSBメモリで起動して
openbsdをいれます。

これで　winなPCでの作業はおわりです。
あと　macpro につけると　grubでfedora か　openbsdかの
選択ができます。

X　例えば　lumina をたちあげるには
nvideaでは無理で　ATI (=AMD)のradeon が必要です。

以上OS-Xは全く使いませんでした。
ちなみに自分のMACPROは　２００６年のです。
【nohup】ssh先でセッションが切れてもプロセスをkillされない方法

### 1. はじめに
- 実行時間が長い以下のようなスクリプトをssh先で動かしたい方のために書いています
    - データ分析
    - ディープラーニングのデータセット作成、学習

### 2. バックグラウンドでスクリプトを動かす
簡単に使いたい人↓

```shell-session
 $ nohup (コマンド) &
```
使用例↓

```shell-session
例.1） 単純に
 $ nohup test_script.py &
例.2） 引数がある場合
 $ nohup test_script.py 10 &
```

### 3. 別セッションで実行状況を確認する場合
- バックグラウンドで実行しているため、標準出力に実行状況を表示するような記述になっていても**表示されません**
- 『nohup』はデフォルトで『nohup』を動かしたディレクトリに、ログを出力します

そこで、実行状況を確認する方法として**『tail -f nohup.out』**が有効です

```shell-session
利用例）

1. バックグラウンドで処理を実行

$ nohup test_script.py &

2. session kill
$ (ctrl + d)

3. 再度 ssh
$ ssh user@host

4. 作業ディレクトリへ移動
$ cd (nohupを実行したディレクトリ)

5. ログの出力
$ tail -f nohup.out
```
--- 

追記.1 python コマンドに`-u`をつけると毎秒printを監視してくれます
socket.io ~2.0 にリバースプロキシを通す方法

# 構成
```127.0.0.1:3000``` で socket.io v2系 のサーバーが LISTEN していると仮定。

## Apache 2.4.27
必要なモジュールは以下の通り。
* mod_proxy
* mod_rewrite
* mod_proxy_wstunnel
バックエンドへの通信は http://, ws:// で行い、TLSはリバースプロキシで落とす。

```apache
# ......
# 必ず VirtualHost の中に記述すること
<VirtualHost _default_:443>
# ......
# リライトを有効化
RewriteEngine on 
# パスが /socket.io/ で始まり、クエリに transport=websocket が含まれているとき、
RewriteCond "%{REQUEST_URI}" "^/socket.io/" [NC]
RewriteCond "%{QUERY_STRING}" "transport=websocket" [NC]
# パスを保持したまま WebSocket プロトコルでローカルホストにプロキシを通す。
RewriteRule "/(.*)" "ws://127.0.0.1:3000/$1" [P,L]
# もちろんフォワードプロキシは無効化
ProxyRequests off
# それ以外のリクエストのうち /socket.io/ で始まるものは、localhost に通す。
ProxyPass "/socket.io/" "http://127.0.0.1:3000/socket.io/"
ProxyPassReverse "/socket.io/" "http://127.0.0.1:3000/socket.io/"
# ......
</VirtualHost>
# ......
```

### 補足
transport=websocket がクエリに含まれているとき、
socket.io は WebSocket へのプロトコルアップグレードを要求している。
従って、この時だけ WebSocket のプロトコルとして転送する。
それ以外のときは、フォールバックの可能性等もあるため http で転送。
Qiita にこれ以外の設定もあるが、フォールバックしか動いていない可能性が高いので要注意。


## Nginx 1.13.3
詳細な情報は以下にあるため、そちらを参照すると良い。
https://www.nginx.com/blog/nginx-nodejs-websockets-socketio/
Apacheの場合と違って、ほとんど何も考えずに流してあげれば動いてくれる。

```nginx
# Upstream の設定。
# 流したい先をここに記述する。
upstream websocket {
    server localhost:3000;
}
# ......
server {
    # ......
    location /socket.io/ {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://websocket;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;  # どのプロトコルにアップグレードするかを残す
        proxy_set_header Connection "upgrade";   # とりあえずプロトコルをアップグレードすることにする
    }
    # ......
}
```

# 動作確認法
Chrome の Developer Tools などを活用して確認できる。
1. Network のタブを選択
2. 種類は All or WS
3. Type が websocket になっているものを選択
4. Frames のタブを選択
以上の手順で、実際に送られている WebSocket のフレームを確認することが出来る。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/63615/e13ad09b-c8b4-f072-2cb2-7c63584a2714.png)
HHVMとHackを触ってみる

## 概要
リリースしてからずっと興味を持っていたが、今まで触っていませんでした。
PHP7のリリースによって、HHVMとパフォーマンスに差がないことから世間的には興味が薄れつつありますが、敢えてこのタイミングでHHVMとHackを触ってみます。

## はじめに
### Hack言語
2014年にFacebookにより開発されたプログラミング言語です。オープンソースとして公開されており、同社が開発したPHP実行環境のHHVM で動作します。

### HHVM(HipHop Virtual Machine) 
PHPやHackを実行する仮想マシンです。JITコンパイルで中間言語に変換した後、コンパイルして実行する方式です。

## CentOS7にHHVMをインストール
ubuntuへのインストールが推奨されていますが、自分は業務でCentOSをよく使っているので、今回はCentOSにインストールします。
[本家Github](https://github.com/facebook/hhvm/wiki/Prebuilt-Packages-on-Centos-7.x)にインストール方法が載っているので、そちらを参照して進めます。

### 手順
まずはCentOSを更新

```
yum update -y
```

EPELリポジトリ更新

```
rpm -Uvh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-9.noarch.rpm
```

依存関係のあるライブラリ更新

```
yum install cpp gcc-c++ cmake git psmisc {binutils,boost,jemalloc,numactl}-devel \
{ImageMagick,sqlite,tbb,bzip2,openldap,readline,elfutils-libelf,gmp,lz4,pcre}-devel \
lib{xslt,event,yaml,vpx,png,zip,icu,mcrypt,memcached,cap,dwarf}-devel \
{unixODBC,expat,mariadb}-devel lib{edit,curl,xml2,xslt}-devel \
glog-devel oniguruma-devel ocaml gperf enca libjpeg-turbo-devel openssl-devel \
mariadb mariadb-server make libc-client -y
```

HHVMインストール

```
rpm -Uvh http://mirrors.linuxeye.com/hhvm-repo/7/x86_64/hhvm-3.15.3-1.el7.centos.x86_64.rpm
```

バージョン確認

```
$ hhvm --version
```

バージョンが正しく表示されれば、導入完了です。

## 初めてHHVMでHackを動かそうとして躓いた事

インストール後の動作検証として、世界に挨拶しようと下記コードが記載されたhello.hhを動かそうとした所、エラーが発生しました。

```php:hello.hh
<?hh
echo "hellow hack\n";
```


```
$ hhvm hello.hh

Fatal error: hello.hh appears to be a Hack file, but you do not appear to be running the Hack typechecker. See the documentation at http://docs.hhvm.com/hack/typechecker/setup for information on getting it running. You can also set `-d hhvm.hack.lang.look_for_typechecker=0` to disable this check (not recommended).
```

指定されたドキュメントを確認した所、最初に .hhconfig を作成してから実行する必要が有ると記載されていました。
そのため、 .hhconfig を空で作成して再実行します。

```
$ hhvm hello.hh
hellow hack
```

無事に実行できました。
これで環境が整ったので今後も時間をみつけてHHVMとHackを触ってみようと思います。

最後まで読んで頂きありがとうございました。
日記アプリのMVP化工程記録・4

# 始める前に「やれます！」って言わないほうが良い

見積もる前に出来ますとか、言うべきではないっていう教訓ですね。エンジニアなら。
> 次の記事が投稿される時にはもちろん解決策を提示する予定です。

[前回の記事](https://qiita.com/poin-settia/items/c9e5cd2df5648b41b43c)の〆にそんな事を書きましたが、動作しない原因を突き止めると共に一旦RxJavaでの実装を取りやめました。

# なぜ、上手く動作しなかったのか

RepositoryでRealmを操作する際、emitterがnullになるという事は検索結果が出力出来ていないという事です。
よくよくエラーを見ると、

```
RealmResults<Person> results = mRealmHelper.findAll();
```
でExceptionを吐いていました。内容は
> Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.

端的にいえば別スレッドで作成されたRealmResultsは渡せない、という事です。
・・・そうでした、RealmResultsはスレッド間で受け渡しができないんでした。

# じゃあどうするのか
本日のコミットは[こちら](https://github.com/poin-settia/Diary/commit/b40d71fa850a97b08f70b9036c720364c47b264e)になります。(日替わりメニューか)

コミットコメントにも書きましたが、Rxでの実装をやめて同期でRealmを操作するように修正しました。
非同期処理でもRealmResultsをImmutableに変換する、など色んな手法が存在するのですが、今回の目的はあくまでも**MVP化**です。それを忘れてはいけません。

リアクティブな実装は今後導入予定のRetroFit通信で、好きなだけ非同期通信を学べば良いと思うのです。ここは涙を飲んでMVP化を優先させる事にしました。

# つまりどうなったのか
[前回の記事](https://qiita.com/poin-settia/items/c9e5cd2df5648b41b43c)で書いたとおり
> ★リスト初期表示イベント・Presenter

における一連の機能をModel/View/Presenterに分離させました。

```java:View
mPresenter.initList();
```
からイベントがスタートして

```java:Presenter
RealmList<Person> personList = mRepository.getFirstList();
```
Presenter →　Repository　へとRealmDBの検索の要求。
Repository → Presenter　へと結果の返却。

```java:Presenter
if (personList.size() != 0) mView.showList(personList);
```
Presenterは結果から次の動作を判断し、リストデータが存在する時にだけ
Viewへと表示の要求を行います。

```java:View
showList(RealmList<Person> personList)
```
最終的にView(Fragment)でリストを描画すれば
> ★リスト初期表示イベント・Presenter

は動作の完了となります。
基本的なMVPの流れは非Rxでなくても変わりません。個々の役割が明確になっている点がMVP化の利点です。

# 次回は
だなんて毎回フラグを立ててきましたが、今回のような流れにそってFragmentの機能をどんどん分離させていくだけだと思います。

残念ながらRxの導入は見送りましたが、MVPアーキテクチャへの改造という当初の目標は変わりません。
早くMVP化を完了させて新機能の拡充に入りたいものです。
Kotlin学習メモ(開発に役立つ特徴)

#**主な変数の定義**

#valとvar

 - val→再代入で不可
 - var→再代入可能

##例
```kotlin
val a: String = "foo"
a = "bar" // エラーになる
var b: String = "foo"
b = "bar" // エラーにならない
```

**出来るだけvalを使い、必要な場合のみvarを使うのがベターらしい**

---

#nullable

nullを**代入できる変数**と**できない変数**は、別の型として区別される。
例えば、String型であれば最後に?をつけてString?型として宣言しない限り、
nullを代入することはできません。

##例
```kotlin
val a: String = null // エラーになる
val b: String? = null // エラーにならない
```

このように、意図しないnullの代入はコンパイル時にエラーとなるため、
ぬるぽを防ぐ効果があります。

---
#値を返すif式

Kotlinのifはif文としてだけでなくif式としても使える為、
値を返すことが出来ます。
このため簡潔に書ける場面が多くて便利です。

##例(Javaだとこうなる)
```java
String a;
if(b) {
  a = "foo";
} else {
  a = "bar";
}
```
---
##例(Kotlinならこのように書ける)
```kotlin
val a = if(b) "foo" else "bar"
```
---


#名前付き引数、デフォルト引数

Kotlinでは、引数に名前をつけたり、デフォルト値を与えることができるため、
オーバーロード（多重定義、引数や戻り値が異なる同一名称のメソッドを複数定義すること）
を使わずに済む。

##例
```kotlin
// middleNameにはデフォルト値を設定
fun fullName(firstName: String, middleName: String = "", lastName: String)

// 必要な引数のみ指定して渡すことができる
val name = fullName(firstName = "Jun", lastName = "Ikeda")
```
jQueryのajaxでバイナリのデータを取得する


## jQueryの`$.ajax()`でバイナリをGETすると、`parsererror`が返ってくるんだが...？
- `$.ajax()`はバイナリをテキスト扱いしてしまうため
- ググってみると、jQueryを諦めて潔く`XMLHttpRequest`を書いて解決してる例が多い。。
    - [Henry Algusさんのブログ](http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/)を参照して「`$.ajax`で取得する方法はある！」と紹介しつつも、「`$.ajaxTransport`で長い記述したくない！」と`XMLHttpRequest`で済ませちゃう例が多数。。
        - そもそも、このブログでは何を言っているの？

## BinaryTransport
- 結論を言うと、**これが`$.ajax`でバイナリを取得する方法である。**
    - この関数を読み込ませるだけで、`$.ajax`でバイナリをGETできる！（jQuery`$.ajax`の拡張）
    - Henry AlgusさんがGitHubで公開している https://github.com/henrya/js-jquery/tree/master/BinaryTransport
        - npmもある！ https://www.npmjs.com/package/jquery-binarytransport

## 使い方
### Blobで取得
```js
$.ajax({
	url: "image.png",
	type: "GET",
	dataType: 'binary',
	responseType:'blob',
	processData: false,
	success: function(result){
	}
});
```

### ArrayBufferで取得
```js
$.ajax({
	url: "image.png",
	type: "GET",
	dataType: 'binary',
	responseType:'arraybuffer',
	processData: false,
	success: function(result){
	}
});
```

これでコードがスッキリ！
障害やエラー、接続不能時の問い合わせ。その時のヒアリングシート例


問い合わせをする際や、逆に受ける際のテンプレートとして使ってください。

|質問|補足|
|:-----------------|:-----------------|
|どこからどこに対するアクセスでしょうか？<br>どこ経由でしょうか？|できればサーバー単位、IP単位など|
|前まで問題なかったでしょうか？<br>いつから問題が発生しましたか？|最近どこかに何か修正や変更があったのかも？<br>ほとんどの障害は何かが変わったことが起因となります|
|常にその問題が発生していますか？|発生したりしなかったりの場合は、原因がまた異なります|
|再現方法はありますか？|再現できると解決に近くなります|
|正常な動きだとどうなりますか？|事実確認1|
|今回の動きはどうなっていますか？|事実確認2|
|今までに何を確認しましたか？|アプリ同士がつながらない？何かコマンドがつながらない？<br>同じ作業を省くため、できるだけ詳細に事実をお願いします。|
|ログやレスポンスは見ましたか？|ヒントになります|
|エラーのスクリーンショット/ログを見せてください|実物があるとコミュニケーションロスが減ります|
|他にもなにかが起きてますか？|ヒントになります|
|ご自身の考えるきっかけ|ヒントになります|
|逆に、問題ない部分はどこでしょうか|違いが重要。逆に重要|
|症状が大きくなったり小さくなったりするときはありますか？|ヒントになります|
|今、何か応急処置をしていますか？|ヒントになります|
|お困り度、ユーザー影響など|優先度に影響します|
|対応方法に対する要望|あれば。|

上記のような点を考慮した報告があると調査がスムーズになるでしょう。
Angularで初回ロード中画面を設定する

小ネタです。
Angluarで作ったSPAの初回ロード時のロード中画面を設定する方法です。

# 前提
今回紹介する内容は、以下のバージョンのangluar-cliで作成したAngularのプロジェクトで確認しています。

```
$ ng -v
...
@angular/cli: 1.4.9
node: 8.8.1
os: darwin x64
```

# 手順

## ひとまず文字だけ表示する

方法は至って簡単で、src/index.htmlの`<app-root>`内に表示させたい文字を入力するだけです。
AppComponentはangluar-cliで作成したAngluarアプリのブートストラップ(エントリーポイント)となっており、AppComponentの内容が完全に読み込まれるまでの間、ココに入力した文字ロード中画面として画面に表示されます。

```html:index.html
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>AngularTest</title>
  <base href="/">

  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root>Loading...</app-root>   <!-- ココ -->
</body>
</html>
```

angular-cliで作成したAngluar 2系のサンプルなどを見ると、`app-root`内に`Loading...`の文字が入っているのを見かけますが、現在最新のangluar-cliを使って作成したプロジェクトでは`app-root`内には何も記述されていない状態でindex.htmlが生成されるようです。

## 表示
![スクリーンショット 2017-11-02 0.40.41.png](https://qiita-image-store.s3.amazonaws.com/0/79414/1e34eea4-1dbb-0d66-accd-e1ed15ffeeb7.png)


## CSSでちょっといい感じにスタイリングする

`app-root`内にstyleタグを使ってを記述していきます。
[How TO - CSS Loader](https://www.w3schools.com/howto/howto_css_loader.asp) を参考に円状のローダーを作成しました。

```html:index.html
...
  <app-root> 
    <style>
    app-root {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      height: 100vh;
      color: gray;
    }
    .loader {
      border: 16px solid #f3f3f3;
      border-top: 16px solid #4055ae;
      border-radius: 50%;
      width: 120px;
      height: 120px;
      animation: spin 2s linear infinite;
    }
    @keyframes spin {
      0% { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
    .loader-text {
      display: block;
      margin-top: 1em;
    }
    </style>
    <div class="loader"></div>
    <span class="loader-text">Loading...</span>
  </app-root>
...
```

## 表示
![スクリーンショット 2017-11-02 0.40.52.png](https://qiita-image-store.s3.amazonaws.com/0/79414/7efc775b-83f9-98d5-d35f-9ffe23adb922.png)


# その他

レイアウトの確認や、デバッグ時にはChromeデベロッパーツールで擬似的に回線速度を落としリソースの読み込みタイミングを遅らせるなどするとスムーズです。 
参考: [Chromeデベロッパーツールで実機の回線速度を再現してコーディング](https://qiita.com/umi_kappa/items/fb9dcb10e7e1e4a05450)
Ubuntu 14.04でElecom WDC-150SU2Mを認識させる

デスクトップのubuntuでwifi子機を使いたかったので、
この記事を元にドライバーをインストール
http://www.cntsv.jp/blog/archives/1500

この通りではいかなかったのはBIOSのWindows UEFI modeをoffらないといけないところ。


```
$ pwd
/home/ubuntu
$ cd rtl8188eu/
$ make all
$ sudo make install
$ ls -l 8188eu.ko（makeが成功したことを確認する）
$ sudo insmod 8188eu.ko
$ lsmod | grep 8188（モジュールの追加が成功したことを確認する）
8188eu 671710 0
$ iwconfig
```

あとは上の通りにやれば認識されて、右上にwifi一覧が出た。
wifiが使えるようになった。


#参考
http://www.cntsv.jp/blog/archives/1500
http://www.taillook.tech/entry/2016/11/02/115214
https://freesoft.tvbok.com/tips/lga2011/asus_secure_boot.html
C言語のポインタを理解したい！＃２

前回の内容はこちら→[C言語のポインタを理解したい！＃１](https://qiita.com/PotyaExe/items/a1d954e7cf50cefaf68d)

こんにちは。最近まぜそばにハマってきたぽちゃです。今回はポインタを使った配列、関数の扱い方について書きたいと思います。
前回から言っていますが僕も完全に理解したわけではないので、参考になるかならないかレベルですがよろしくお願いします<(_ _)>

#そもそも配列とは
配列とは何か復習しましょう！
配列は**同じ型のデータをもったかたまり**のことです。
宣言方法は'データ型名　配列名[要素数]
例えば
`int a [5]`
と宣言した場合はint型のデータが５個あるということになります。その際[]に入れる数字のことを**要素数**といいます。
まとめると
`データ型名　配列名[要素数]`となります。
#ポインタで配列を扱いますか。
ここからはポインタと配列を絡めて話を勧めていきます。
ポインタで配列を扱う時に注意が必要なのが、**ポインタが配列 (の先頭) を指す**のです。
どういうことかわからないと思うので一つサンプルプログラムを用意しました

```C:sample
#include <stdio.h>
int main (void){
char potya[10]="potya";
char *p1;

p1=potya;

printf("%c",*p1);
printf("%c"*(p1+1));
printf("%c"*(p1+2));
printf("%c"*(p1+3));
printf("%c"*(p1+4));
return 0;
}
```
```:出力結果
potya
```
では説明していきます。
p1=potyaという意味ですが、**これはポインタの値設定**になります。
p1にpotya[0]のアドレスを渡しているのです。

**え？見ればわかるって？その後のpotya[1]とかはどうやって入力するんだって？**
では次にこの図をみてください
![teisyutu1.jpg](https://qiita-image-store.s3.amazonaws.com/0/196752/9c8e5bcf-8029-0633-1973-f8d3c750b285.jpeg)
汚いのはごめんなさい。マウスパッドで書いたので許して...
potya[0]が*p1ということにするとpotya[1]は*(p1+1）になるという形です。
ちなみに*(p1+1)というのは[ポインタp1の指すアドレス+1の中身]という意味です。
よって、**ポインタが配列（の先頭）を知ってさえいれば配列の中身なんてすぐわかる**のです。
これでポインタを使った配列の扱い方はOK！

#関数って数学やん
確かに数学でも関数という言葉がでてくるけど、意味が違います
数学は
>数学における関数とは、かつては、ある変数に依存して決まる値あるいはその対応を表す式の事であった。この言葉はライプニッツによって導入された。その後定義が一般化されて行き、現代的には数の集合に値をとる写像の一種であると理解される

[wikipedia参照](https://ja.wikipedia.org/wiki/%E9%96%A2%E6%95%B0_(%E6%95%B0%E5%AD%A6))


しかし、プログラムでの関数では
> サブルーチン（英: subroutine）は、コンピュータプログラミングにおいて、プログラム中で意味や内容がまとまっている作業をひとつの手続きとしたものである。繰り返し利用されるルーチン作業をモジュールとしてまとめたもので、呼び出す側の「主」となるもの（メインルーチン）と対比して「サブルーチン」と呼ばれる。サブプログラム (subprogram) と呼ばれることもある。また、「サブ」をつけずに「ルーチン」と呼ぶこともある。

> [中略]

> サブルーチンを、結果として値を返すものと、処理だけを行い値を返さないものに分類することがある。その場合、前者を関数（英: function）、後者を手続き（英: procedure）と呼んで区別する。プログラミング言語の仕様としてC言語のようにどちらかの呼び方のみを採るものと、Pascalのように両者を区別するものがある。

という意味となっています。[wikipedia参照](https://ja.wikipedia.org/wiki/%E3%82%B5%E3%83%96%E3%83%AB%E3%83%BC%E3%83%81%E3%83%B3)

そこの違いです。

では関数を使ってみましょう。
関数の書式は
>戻り値の型 関数名(引数)
{
  処理
}

となっています。
例としてはこうです。

```C:sample2
#include <stdio.h>
void print();

int main(void){
     print();
     printf("@PotyaExe\n");
     return 0;
}
void print(){
     printf("Twitterアカウントは\n");
}

```


```:出力結果
Twitterアカウントは
@PotyExe
```

こういう感じになります。
#関数でポインタを扱います
これも前回の復習です。
ポインタは**アドレスを記憶する変数**と書きましたね？
ポインタは読み込んだり書き込んだ
これは利用するしかない！！
それを使ってサンプルプログラムを作ってみたいと思います。

```C:sample3
#include <stdio.h>

void checkfunc(int*,int);

int main(void){
    int check;

    checkfunc(&check,100);
    printf("%d\n",check);
    return 0;
}
void checkfunc(int *suuji,int add){
    *suuji=add+10;
}
```

```:出力結果
110
```
まず、checkfuncの自作関数にcheckのアドレス、100を送ります。
そしたらsuujiにcheckのアドレス、addに100を受け取ります。
そして計算をして110をポインタsuujiの参照先に上書きします。
これによってcheck=110となります。

まあ簡単。
図にするとこう
![teisyutu2.jpg](https://qiita-image-store.s3.amazonaws.com/0/196752/5569cb90-5c26-af76-b0df-c8cde0066a8a.jpeg)

これが限界です。すいません。

これで関数でポインタも扱えますね!

#まとめ
**ポインタは配列の先頭さえわかれば良い**
**ポインタを使って関数間で値を渡し合える。**
これでまたレベルアップしましたね！

最後まで見ていただきありがとうございました！
ポインタはややこしいので最初のうちは図を書いて覚えることをおすすめします。
それでは！次回で会いましょう

何か質問があれば[Twitter](https://twitter.com/PotyaExe?lang=ja)まで
applescriptで下書きメールを保存する

メールを作成した後、送信せずにしばらく待つとメールが下書きに保存される。明示的に下書きに保存する方法は見つからなかった。

```applescript
set theToAddress to "xxxx@aaaa.com"
set theSubject to "メールタイトル"
set theBody to "メール本文"

tell application "Mail"
	-- メール作成
	set newMessage to make new outgoing message with properties {subject:theSubject, content:theBody}

	tell newMessage
		--受取人の指定
		make new to recipient at end of to recipients with properties {address:theToAddress}
		
		--メール送信しない
		--send
	end tell
end tell
```
【BAT】フォルダの更新日時を維持してコピーする

# はじめに
エクスプローラーでフォルダをコピーすると更新日時がフォルダ作成日時に変わります。中身のファイル自体の更新日時はそのままです。
テスト用に3日以前のフォルダが削除されるか確認するために過去日時のフォルダを作成したかった。

# robocopyを使用
エクスプローラーを使わないで、Windows7 に標準で付属している「robocopy」コマンドを使用することでフォルダの更新日時を維持してコピーすることができる。

``` bat
robocopy [コピー元] [コピー先] /E /DCOPY:T 
```

オプションについて
/E 空のディレクトリを含むサブディレクトリをコピーします。
/DCOPY:T ディレクトリのタイムスタンプコピーします。 

# フォルダコピーについて
フォルダ自体をコピーしたつもりが中身のファイルだけがコピーされてしまい、フォルダコピーってどうやるのか、思わず悩んでしまったので備忘録として残しておく。

コピー元に「hoge」フォルダだけを指定すると、中身だけがコピーされてしまう。

``` bat
robocopy C:\AAA\hoge D:\BBB\ /E /DCOPY:T 
```

「hoge」フォルダ自体もコピーするには、コピー先にフォルダを指定する必要がある。

``` bat
robocopy C:\AAA\hoge D:\BBB\hoge /E /DCOPY:T 
```
ちなみにコピー先のフォルダ指定はコピー元と同じである必要はないでの別の名前にしてもよい。

xcopyでも同様にコピー先にフォルダを指定する必要がある。
但し、xcopyではフォルダの更新日時を維持してコピーすることは出来ない。

``` bat
echo d | xcopy C:\AAA\hoge D:\BBB\hoge /E
```

# 最後に
一般的にフォルダをコピーしても更新日時が維持されるばかりと思ってのに出来なかったんですね。案外、気にしないと分からないもんだ。

# 参照
* [ネットワーク間コピー時、フォルダのタイムスタンプ維持方法](http://www.flatcorp.jp/blog/memo/348.html)
* [robocopyでフォルダ自体のコピーは可能ですか](https://oshiete.goo.ne.jp/qa/8624424.html)
* [XCOPYで指定したフォルダとファイルをコピーしたい](https://oshiete.goo.ne.jp/qa/4722506.html)
LinuxKitでスタティックIPアドレスを設定

## 結論

onbootで`linuxkit/ip`コンテナを使いましょう。

## StaticIPの設定方法

詳細は以下のIssueを参照。

- [How to setup a static IP for a LinuxKit VM instance](https://github.com/linuxkit/linuxkit/issues/2516)

このIssueには実際に動かせるサンプルyamlが載っていませんので作成してみました。

サンプルでは以下のように指定しています。

- IPアドレス: 192.0.2.101
- デフォルトゲートウェイ: 192.0.2.1
- ネームサーバ:
  - 8.8.8.8
  - 8.8.4.4


```yaml:static_ip_example.yml
kernel:
  image: linuxkit/kernel:4.9.59
  cmdline: "console=tty0 console=ttyS0 console=ttyAMA0"
init:
  - linuxkit/init:42a92119e1ca10380e0d33e26c0cbcf85b9b3558
  - linuxkit/runc:817fdc592eac6cb7804fa1721a43a7f6e23fb50f
  - linuxkit/containerd:82be2bbb7cf83bab161ffe2a64624ba1107725ff
  - linuxkit/ca-certificates:af4880e78edc28743f7c5e262678c67c6add4c26
onboot:
  - name: sysctl
    image: linuxkit/sysctl:a9ad57ed738a31ea9380cd73236866c312b35489
  - name: rngd1
    image: linuxkit/rngd:842e5e8ece7934f0cab9fd0027b595ff3471e5b9
    command: ["/sbin/rngd", "-1"]
  - name: ip
    image: linuxkit/ip:54971b6664cb7b52912e909a8f6a45e5a5c94506
    command: ["ip", "-b", "/root/ip-command"]
    binds:
      - /root/ip-command:/root/ip-command
  - name: resolv
    image: alpine:3.6
    command: ["/bin/sh", "-c", "cat /root/resolv.conf > /etc/resolv.conf" ]
    binds:
      - /root/resolv.conf:/root/resolv.conf
      - /etc/resolv.conf:/etc/resolv.conf
services:
  - name: getty
    image: linuxkit/getty:626ccc8e1766c40447f29a790d3a7cfff126f2a2
    env:
     - INSECURE=true
  - name: rngd
    image: linuxkit/rngd:842e5e8ece7934f0cab9fd0027b595ff3471e5b9
  - name: sshd
    image: linuxkit/sshd:f55ec010619e19178d5daecb4e595e84ecbf7d67
files:
  - path: root/.ssh/authorized_keys
    source: id_rsa.pub
    mode: "0600"
    optional: true
  - path: root/ip-command
    contents: |
      addr add 192.0.2.101/24 dev eth0
      link set eth0 up
      route add default via 192.0.2.1 dev eth0
  - path: root/resolv.conf
    contents: |
      nameserver 8.8.8.8
      nameserver 8.8.4.4
      search localdomain
trust:
  org:
    - linuxkit
```

`files`セクションでipコマンドで実行する内容が記載されているファイルをアップロードし、それをonbootに記述した`linuxkit/ip`コンテナで実行しています。

今回はyaml中にIPアドレスを直書きしてますが、`linuxkit/metadata`コンテナで各クラウド上のメタデータサービスを利用するということも可能ですので色々運用に合わせて工夫が必要そうです。

以上です。
MapDで全世界のtweet分析してみた

# MapDとは
https://www.mapd.com/
地図データを扱うことに長けたデータベース製品であり、データを可視化し分析するためのVisual Analytics Platformを持つ
データベースの検索から地図上への表示までがとても高速なのが売り
MapD公式Webページにデモが用意されているので、今回はそれを使ってデータ分析してみる

# デモを触ってみる
https://www.mapd.com/demos/tweetmap/
上記のURLにアクセスすると、全世界のTweetmapというデモページが開かれる
4か月ぐらい前から現在までのツイートが世界地図上にマッピングされているようである
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201287/0cf5ae19-63c2-b919-72e8-1a0672be8f97.png)
データは6時間おきに更新されている模様(未調査)
地図の右下を見ると、391,745,448件のツイートが表示されていることがわかる
少しロードは重いが、見た目は綺麗
日本はツイート大国のようだ

# デモ画面の使い方説明
データを絞り込む方法として、エリア指定、日時範囲指定、ハッシュタグ指定の3種類を紹介する

## エリア指定絞り込み
表示されている地図の範囲が、そのままデータを取得するエリアの指定になる
すなわち、地図をズームインしたりズームアウトしたり、移動したりした際、表示されている範囲のツイートだけが地図上にプロットされ、下のグラフと右のバーに表示される

## 日時範囲指定絞り込み
地図の下にあるギザギザのグラフは、横軸が時間軸で、縦軸が6時間当たりのツイート数を表している
グラフ両端の青い棒は横にスクロールさせることが可能で、〇月〇日から△月△日までのツイートを絞り込むことができる

## ハッシュタグ指定絞り込み
画面右のペインは、使用されたハッシュタグがその回数が高い順に並べられている棒グラフである
クリックするとそのハッシュタグがつけられているツイートだけを絞り込むことができる

# データ分析
## 小ネタ①
私は初めてこのデモデータ見たとき、アメリカ、ヨーロッパ、日本がよくツイートしてるなーと思ってました
しかしよく見るとフィンランドもたくさんのツイートが散らばってるなぁと思ったわけです
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201287/9a4a189c-483a-4544-3a04-6aa219b953ff.png)
さすがIT先進国フィンランド！
どんなツイートしてるのか適当にクリックしてみよう！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201287/cd35e394-6700-d459-06f6-0d04ab3ea9dc.png)
1261858…
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201287/6c86f776-5fc2-8712-a4dc-2516a64b3ab7.png)
1309337はフィンランド語でmiljoonakolme…
あー勉強になるなぁ
って、BOTやん！！！！！

このままだとフィンランドはいつか一面紫色で覆われちゃうんじゃないかな！

以上
きちんとしたデータ分析はまた今度やります！
ndarrayとSeriesとDataFrameそれぞれにpandas.get_dummiesを適用してみたら

# 背景

pythonで回帰とかまわそうとすると，カテゴリデータの取扱に困る．
そこでpandas.get_dummies（）という便利なメソッドがあるが，少し癖がある．

# 結論

結論からいうと，DataFrameに変換して，かつカテゴリデータは文字列型にした状態でget_dummiesにかけておけば間違いがない．

# 結果

<dl>
<dt>ndarray,Series</dt>
<dd>get_dummiesにかけると，データが数値だろうが文字列だろうがダミー変数に変換してくれる．<br>
ただし，Series.nameがカラム名に反映されないため，いくつかのカテゴリデータをダミー変数にした系列をconcatなどで結合する場合に列名が被る．</dd>
<dt>DataFrame</dt>
<dd>数値データまたは数値データに準ずるboolなどはget_dummiesでダミー変数に変換してもらえない．<br>
文字列であればダミー変数に変換され，またカラム名は元の「カラム名_値」の形式となるため他の系列との重複を気にせずconcatしてしまえる．</dd></dl>

# 確認

コード
----

```python:get_dummies_test.py
import numpy as np
import pandas

# 0〜3のサイズ20の乱数列
rawdata = np.random.uniform(0, 4, size=5).astype(int)

# Series
ser  = pandas.Series(rawdata, name='rand')

nd_dummy   = pandas.get_dummies(rawdata, drop_first=True)
ser_dummy  = pandas.get_dummies(ser, drop_first=True)
df_dummy   = pandas.get_dummies(ser.to_frame(), drop_first=True)
str_dummy  = pandas.get_dummies(ser.astype(str).to_frame(), drop_first=True)

print('ndarray\n', nd_dummy)
print('\nSeries\n',ser_dummy)
print('\nDataFrame(int)\n',df_dummy)
print('\nDataFrame(str)\n',str_dummy)
```

出力
----

<pre>
ndarray
    1  2  3
0  0  0  0
1  0  1  0
2  0  0  0
3  0  0  1
4  1  0  0

Series
    1  2  3
0  0  0  0
1  0  1  0
2  0  0  0
3  0  0  1
4  1  0  0

DataFrame(int)
    rand
0     0
1     2
2     0
3     3
4     1

DataFrame(str)
    rand_1  rand_2  rand_3
0       0       0       0
1       0       1       0
2       0       0       0
3       0       0       1
4       1       0       0
</pre>
rails newの手順を毎回忘れるので記録

# はじめに
`rails new`する時、頻度が低いため毎回手順を忘れます。
なので手順を自分なりにまとめました。
(rubyとかmysqlとかは一通り揃っている前提です)
※ `rails new`する機会が有るたびに更新予定

# 全体の流れ
## githubのレポジトリと連携しておく
いつもやるので。

```
mkdir fuga
cd fuga
git init
git remote add origin https://github.com/hoge/fuga.git
```

## railsを導入
```
bundle init
vim Gemfile
  →railsを追加
(
  もしくは
  echo "gem 'rails'" >> Gemfile
)

bundle install --path vendor/bundle --jobs=4
```
--pathでインストール先を設定（アプリ毎に分けたい場合）
--jobsは並列処理してくれて速くなるらしい


## rails new
```
bundle exec rails new . -B -d mysql --skip-turbolinks --skip-test
```
-Bはbundleをスキップ（Gemfile編集後に実行したいので）
-d mysqlでDBをmysqlに
--skip-turbolinks文字通り
--skip-test文字通り

## Gemfile編集
```
vim Gemfile
  →slimを入れたりする
bundle
```
git_source云々は放置で良いらしい
[Rails 5.0.1 で rails new するとできる Gemfile の git_source ブロックの意味](https://qiita.com/kymmt90/items/0ab4027fb5c42857d759)

## その他
```
vim .gitignore
  →/vendor/bundle を追記
(
  もしくは
  echo "/vendor/bundle" >> .gitignore
)
```


# トラブルシューティング
※随時更新予定
phpでサイズの大きいファイルを操作する

巨大なログファイル(500MBくらい)をphpだけで処理しようとしたら苦戦しまくったのでまとめました。

やりたい事 : `ログファイルの最終行の内容を取得する`

失敗すると : `Allowed memory size of 536870912 bytes exhausted (tried to allocate 688430032 bytes)`

こうなります。。。 

#最初に完成形

```.php:php
    $file_handle = fopen($file, "r");
    fseek($file_handle, -2000, SEEK_END); //ファイルポインタを終端から2000バイト前に設定

    ob_start();
    fpassthru($file_handle); //ファイルポインタの位置からファイルの終端まで出力する
    $re = ob_get_clean();
    fclose($file_handle);

    $lines = explode(PHP_EOL, $re, -1);
    echo $lines[count($lines)-1];
```

エラー対応とかは省いています。必要最低限だとこうなりました。
ファイルのポインタを終端から2000バイト前にずらしたあとに、そこから終端までを出力。
その内容をバッファリングして、配列を最後にexplodeしてます。

#失敗例

##file — ファイル全体を読み込んで配列に格納する

```.php
    $lines = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
    echo $lines[count($lines)-1];
```
全体を読み込むので重くて駄目でした。

##fgets — ファイルポインタから 1 行取得する

```.php
    $file_handle = fopen($file, "a+"); //ファイルポインタをファイルの終端に設定
    $re = fgets($file_handle);
```
```.php
    fseek($file_handle, -2000, SEEK_END); //ファイルポインタを終端から2000バイト前に設定
    $re = fgets($file_handle);
```

ファイルポインタの位置を変えても結局、そこから1行単位でしか取得できないのでこちらも駄目でした。

##SplFileObject::current — ファイルの現在の行を取得する

```.php
    $splFileObject = new SplFileObject($file);
    $splFileObject->fseek($splFileObject, -1, SEEK_END); //ファイルポインタを終端から１バイトに設定    
    #$splFileObject->seek(ファイルの行数); //phpのみでファイルの行数が取得できればいけそう。
    echo $splFileObject->current();
```

かなりいけそうだと思いましたがこれも駄目でした。
ファイルの行数をphpのみで取得する方法(fopen,feof,whileとか使うの以外で)が分からず、諦めました。

#まとめ

サイズの大きいファイルをphpで扱うときはポインタをうまく操作して
任意の場所だけ読むようにしないと遅くて処理が落ちる。

ファイルの行数をphpで取得する方法は`exec('wc -l '.$file);` とかがいいのでしょうか。
どなたか分かる方いましたら教えてほしいです。
MAMPのPHP7.1.1にMongoDBのドライバーを導入する方法

もう結構前のことですけれども、調べてみてもなかなか見つからずに苦労したので、書いてみようと思います。

OS : macOS Sierra(10.12.3)
MAMP : 4.1.1
PHP : 7.1.1
MongoDB : 3.2.9

まず、基本的にPHPの以前のバージョンだと以下のサイトの方法で大体できそうです。↓
[MongoDBをMAMP環境のPHPで利用する](http://d.hatena.ne.jp/zebevogue/20120630/1341020573)

ですが、私の環境だと、途中で以下のような表示が出てうまくいきません。

    $ ./pecl -c ../conf/pear.conf install mongo
    WARNING: "pecl/mongo" is deprecated in favor of "channel:///mongodb"
    pecl/mongo requires PHP (version >= 5.3.0, version <= 5.99.99), installed version is 7.1.1
    No valid packages found
    install failed

バージョンが5.3.0から5.99.99までしかダメだということですかね。

そこで、stackoverflowで質問してみたところ以下のような回答を得ました。感謝！
[MAMPのPHP7.1.1にMongoDBのドライバーを導入する方法](https://ja.stackoverflow.com/questions/35095/mamp%E3%81%AEphp7-1-1%E3%81%ABmongodb%E3%81%AE%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90%E3%83%BC%E3%82%92%E5%B0%8E%E5%85%A5%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)

正直リンク先を見て頂ければもう解決するのですが、一応ここにも簡単に書いておこうと思います。
詳しくはリンク先をご参照ください。

・PHP7.1用のmongo.soのインストール

    brew tap homebrew/php
    brew install php71-mongodb
・php.iniへの設定書き込み
インストールの最後に出てくるパスをphp.ini(私の環境では/Applications/MAMP/bin/php/php7.1.1/conf/php.ini)に書き込む

    extension=/usr/local/Cellar/php71-mongodb/1.2.9/mongodb.so

以上です。

MAMPのphpinfoを見てみると、mongodbが読み込まれているのが確認できると思います。

![スクリーンショット 2017-11-01 23.07.14.png](https://qiita-image-store.s3.amazonaws.com/0/183878/c058c9e7-b874-d960-6634-d7326072ca59.png)

もし何か間違ったりしていたらコメントで指摘頂ければと思います。
railsにおけるオブジェクトについて

オブジェクトとは、とても簡単に言うと、関連する変数（値）とメソッド（動作）をまとめて、そのまとまりに名前を付けたものです。
関連する変数やメソッドは1つのオブジェクト内で宣言してまとめてしまうことで、管理しやすくするのがオブジェクト指向です。
ソースコードの見やすさや複数のソースコードファイルがあるときの管理のしやすさを考えると、関係のある変数やメソッドはまとめておく方が好ましく、それを実現できる仕組みとしてオブジェクトが用意されている。

また、オブジェクトを直訳すると物体になる。

そして、オブジェクト指向プログラミング言語とは、積極的にオブジェクトという概念を導入したプログラミング言語ということになる。
snake caseでjsonを出力する

気がついたらできるようになっていた

[Custom Naming Strategies](
https://www.playframework.com/documentation/2.6.x/ScalaJsonAutomated#Custom-Naming-Strategies)

```scala
      case class User(firstName: String, lastName: String)

      implicit val config = JsonConfiguration(JsonNaming.SnakeCase)
      implicit val userWrites: OWrites[User] = Json.writes[User]
      val user = User("Taro", "Yamada")

      println(Json.toJson(user).toString)
```

実行結果
```
    {"first_name":"Taro","last_name":"Yamada"}
```
ちょっとずつ読むドメイン駆動設計 第三部 より深い洞察へ向かうリファクタリング 第九章 暗黙的な概念を明示的にする3 ぎこちない点・矛盾する点を調べる

[前々回](https://qiita.com/YasuhiroKimesawa/items/809ac929026daef0b768)より

暗黙的な概念を導き出すためのヒントはどこにあるか。
>
1. [チームの言語に耳を傾ける](https://qiita.com/YasuhiroKimesawa/items/620feebc26b047c39264)
2. 設計のぎこちない点・エキスパートの発言で矛盾すると思われる点を詳細に調べる
3. ドメインに関する文献を読む
4. 大量の実験をする

続きです

## 設計のぎこちない点を精査する

設計のなかで最もぎこちない部分。
たとえば、

- **手続き型に書いてしまって説明しにくい複雑な処理**が行われているところ
- 新しい要求が出てくるたびに**複雑さが増している**ところ
- 処理はオブジェクトで行われてるが、**ぎこちない**ものがある
- **何か足りない**とわかっていても、モデルの解決策が浮かばない

こういうところを、掘り下げて考えなければならない。
会話やドキュメントに現れないところです。

積極的にドメインエキスパートをその調査に参加させて、会話を開始していきます。

## 矛盾について熟考する

同一人物からもたらされた情報であっても、注意して分析すれば論理的に整合しないこともある。これは、深いモデルへの大きな手がかりになり得ます。

用語のバリエーションにすぎないものや、誤解である場合もありますが、矛盾していると思われるのであれば、見落としがあるかもしれません。

また、新しい要件を実現するときに矛盾が起こることもありますよね。
この要件を満たそうとすると、既存のあのサービスはどうするか・・・とか。
例えば、新しい割引サービスを実施しようとしますが、既存の他の割引はどうするか・・・などなど。。。

このような矛盾は、熟考することで、現実に適用できるかもしれません。

また、すべての矛盾に折り合いをつけることが現実的でなく、望ましくないこともあるかもしれません。このテーマについては、１４章で改めてとのことです。

明日に続きます。
railsで使うメソッドについて

メソッドは処理をひとまとまりに部品化するものである。

メソッドを使って処理を部品化することで再利用可能になる。

メソッドには、定義と呼び出しがあります。定義とは、メソッドを作ることです。呼び出しとは、メソッドを使うことです。

一度メソッドを定義しておくと、何度でも再利用できます。

メソッドの利点は、再利用できることと、その処理に名前をつけられることがあります。
【Python】lambdaで再帰

lambda式の中で再帰がしたい。できるだけ短く書きたい。

# できるのか

参考文献:

- [Python : lambdaの中でも再帰できた](https://qiita.com/ttatsf/items/46eba555fce3d45156f2)
- [Pythonでのワンライナー](https://qiita.com/gyu-don/items/1c200d4e9fc6e22d3c7b#%E5%86%8D%E5%B8%B0)

自分自身を引数で受け取る関数を使えばいいらしい。なるほど。

```py
>>> gcd = lambda *x: (lambda f: f(f, *x))(lambda f, x, y: f(f, y, x % y) if y else x)
>>> gcd(24, 9)  # 最大公約数
3
```

PEP8準拠での文字数は、本体 (`lambda f, x, y: ...`) の文字数 + 33文字。

# 短くなるのか

キーワード引数を使ったら、`lambda`が1つ減って短くなった。(本体 + 25文字)

```py
>>> gcd = lambda *x, f=(lambda f, x, y: f(f, y, x % y) if y else x): f(f, *x)
>>> gcd(24, 9)
3
```

追記: キーワード引数のカッコは省略できた。(本体 + 23文字)

```py
>>> gcd = lambda *x, f=lambda f, x, y: f(f, y, x % y) if y else x: f(f, *x)
>>> gcd(24, 9)
3
```

# おわりに

Pythonのキーワード引数はトリッキーな使い方ができて面白いですね。
もっと短くなる書き方があれば教えてください。
IPv6対応メールサーバ(Postfix)構築失敗　一部の送信元からメール受信できない

イントラネットでメールサーバーを構築したのですが、一部送信元からのメール受信ができず困っています。
目的は、レンタルサーバーのメール容量が小さいことに不満があり、IPv6を使って、自前サーバーを構築を試みました。
しかし、メールサーバーの構築に苦労しています。

【環境（バージョン等）】
　・OS：CentOS7　7.4.1708
　・Postfix:2.10.1
　・dovecot:2.2.10

　・DNS機能は独自ドメインを取得した「お名前ドットコム」のDNSサーバーを利用しました。
　　もちろん、自営サーバーには、AAAAレコードで記載しています。
　　これにより、Webサーバーとデータベースサーバーは外部から接続できています。
　　したがって、IPv6の名前解決に問題は無いと思います。

【事象（困っていること）】
　テキストやWebの情報に沿って、メールサーバーをインストール（Postfix,Dovecot)しました。
　しかし、Webメールを使って試験したところ、一部の送信元からのメールが受信できないのです。
　受信できる送信元もあることから致命的では無いと思うのですが、この違いの理由がわかりません。
　何らかのアドバイスをいただければ助かります。

　［メール受信が成功した送信元］
　　Ｇｍａｉｌ、Ｏｕｔｌｏｏｋ．ｃｏｍ、プロバイダ系（スターキャット、コミュファ光）など
　　　　⇒　/var/log/maillogに着信処理記録が残っています。
　［メール受信が失敗した送信元］
　　ロリポップ、Ｙａｈｏｏ　Ｍａｉｌ、Ｅｘｃｉｔｅなど
　　　　⇒　/var/log/maillogにも、まったく記録が残りません。

【仮説（初歩的見解）】
　受信できない送信元では、IPv6とIPv4のデュアルスタックになっていないのか？
　でも、今時IPv6に対応していないとは思えないので、何かしら特別な設定が必要なのでしょうか？

以上、よろしくお願いします。
githubのissueについて

1. githubのプロジェクト画面でcodeの隣にあるissuesを選択する。
2. New Issueボタンを押す
3. ユーザーにどんなメリットがあるのかを記述する。（製作者目線ではなくユーザー目線で）
4. コメントには誰がいつ閲覧しても分かりやすいように記述する。
5. Assigneesは誰が直すべき担当者を決める。
6. Labelsはissueがどんな作業かを記述する。
7. 以上が決まったら、Submit new issueのボタンを押す。
Windows 仮想メモリ(ページファイル)

#仮想メモリ
　Linuxと同じと思っていたらはまった件
　デフォルトだと動的に変わってしまう。監視設定などで困る。
　初期サイズ、最大サイズを決めてしまうこと。

　Azure環境であれば、Dドライブ(一時領域)がに設定するのが良い。

　また、確保するサイズはダンプを取らないのであれば、カーネル領域分を確保すれば良い。

#SQL Serverの場合
　確保したメモリを基本確保しない。そのためメモリをどんどん使い仮想メモリにアウトすることが多い。
　SQL Serverの設定で制限をかけておくほうがよい。
　日次で再起動可能であれば、それでも良いかも。
Indexes の代わりをする php スクリプト

[Indexes の代わりをする php スクリプト \- hadacchi blog](https://www.hadacchi.com/wp_blog/?p=2061)より転記

自分で管理しているサーバでは不要だが，会社のサーバなど管理者権限がなく，でもディレクトリ内のファイル一覧を見たいパスで，Indexesオプションの代わりをしてくれるphpスクリプトを作ってみた．
自分のブラウザ環境で，nginxのファイル一覧画面を参考に作ったものなので，多少のフォーマット変更は各人でヨロ．

```php:index.php
<html>
<head><title>Index of <?php
if($_SERVER['SCRIPT_NAME']==$_SERVER['REQUEST_URI']) {
    if(dirname($_SERVER['REQUEST_URI'])=='/')  print '/';
    else print dirname($_SERVER['REQUEST_URI']).'/';
} else {
    print $_SERVER['REQUEST_URI'];
}
?></title></head>
<body bgcolor="white">
<h1>Index of /</h1><hr><pre>&lt;?php
foreach (scandir('.') as $val) {
    if ($val=='.') continue;
    elseif ($val=='..') print "&lt;a href=\"../\">../</a>\n";
    else {
        print "&lt;a href=\"$val\">$val</a>";
        for ($i=51-strlen($val);$i>0;--$i) print ' ';
        $st=stat($val);
        print date('d-M-Y H:i',$st[9]);
        for ($i=20-strlen("$st[7]");$i>0;--$i) print ' ';
        print $st[7]."\n";
    }
}
?>
</pre><hr></body>
</html>
```
Redmine APIでPOST/PUTリクエストメソッドを送信できない時の(強引な)対処方法

[Redmine](http://www.redmine.org/)が好き過ぎて[Redmineを題材にしたファンタジー小説書いてる](https://github.com/8novels/redmine-fantasy)8amjpです。

## Redmine API

さて、Redmineは素晴らしいツールなんですが、画面がちょっと無機質で、初心者には取っ付きにくい……という印象があります。
そこで私は、もう少し取っ付きやすい画面を提供するため、[Angular](https://angular.io/)を使って[Redmine API](http://www.redmine.org/projects/redmine/wiki/Rest_api)経由でチケットの情報にアクセスするWebクライアントアプリを作ろうと考えました。
このRedmine API、とっても便利なんですよ。AngularのHTTPモジュールからGETメソッドでアクセスすれば、チケットの情報をJSONやXMLの形式で自由自在に取得できます。
さらには、POSTメソッドやPUTメソッドを使えば、チケットの作成や更新も簡単に……

……できないんですよ。
Redmine APIに、Chrome等のWebブラウザからPOST/PUTメソッドでリクエストを送信すると、必ずエラーになります。
えー。これじゃ読み取り専用じゃないですか。なんで？

## なぜエラーになるのか

勉強してみましたよ。もう。

* [HTTP アクセス制御 (CORS) - HTTP | MDN](https://developer.mozilla.org/ja/docs/Web/HTTP/HTTP_access_control)

えーと、Redmine APIにアクセスする時など、別ドメインへのリクエストは、セキュリティ上の理由で厳しいルールが課せられます。
そのルールを規定したのが[Cross-Origin Resource Sharing](https://www.w3.org/TR/cors/)、略して**CORS**と呼ばれるものです。
で、「シンプルではない」リクエスト（PUT等）の送信時は、安全性を確認するため、事前にOPTIONSメソッドでリクエストを送信し、正常な応答があれば続けてPUTメソッドを送信します。
これをプリフライトリクエストといって…………

と、頭の痛くなるような（でもセキュリティ上とても大事な）ルールに縛られながら、リクエストを送るわけなんですが。ここで大問題が発生です。

まず、ChromeやFirefoxといった主要なWebブラウザは、必ずプリフライトリクエストを送信します。仕様です。簡単にはオフにできません。
で、Redmine APIでは、このプリフライトリクエストに応答する術がありません。必ず404エラーを返します。
結果、POSTもPUTもできません。

**どうせえっちゅうんだよーー！！**
**インターネットに公開されたサーバーでならわかるけどよー！　イントラの内部でくらい自由にやらせてくれよーー！！**
**畜生めー！！　ちくしょうめーーー！！！**

## 解決方法

というわけで、Apacheにこの怒りをぶつけてやりましょう。
`/apps/redmine/conf/`ディレクトリにある`httpd-app.conf`の末尾に、下記を追記します。

```
Header always set Access-Control-Allow-Origin "*" 
Header always set Access-Control-Allow-Methods "OPTIONS, PUT" 
Header always set Access-Control-Max-Age "60" 
Header always set Access-Control-Allow-Headers "Content-Type, X-Redmine-API-Key" 
RewriteEngine On 
RewriteCond %{REQUEST_METHOD} OPTIONS 
RewriteRule ^(.*)$ $1 [R=200,L] 
```

これでPOSTもPUTも送信し放題。いやー、嬉しくて何度POST/PUTしたことやら。

詳しいことはさっきのMDNのページに書いてありますが、一応さらりと解説しておきますね。

1行目は、どのドメインからのアクセスを許可するかを指定します。
ワイルドカードを指定すればすべてのアクセスを受け付けますが、セキュリティの事を考えるとちゃんと指定すべきです。わかっちゃいるけど。
2行目は、どのメソッドを許可するかを指定します。GET/HEAD/POSTメソッドは既に許可されてるっぽいので、OPTIONSとPUTメソッドを追加で指定します。
3行目は、プリフライトリクエストの有効期間です。とりあえず60秒にしました。深い根拠はありません。
4行目は、どのリクエストヘッダを許可するかを指定します。Redmine APIでは「Content-Type」と「X-Redmine-API-Key」ヘッダは必須なので、それを指定しています。
5-7行目は、OPTIONSメソッドのリクエストがあったらオウム返しにステータスコード200を返します。ゆるゆる門番。

これで、長らく頭を悩ませていた<ruby>問題<rt>Issue</rt></ruby>が、力技とは言えやっと<ruby>解決<rt>Resolved</rt></ruby>になりました。良かった良かった。
ま、解決できたのは、本家Redmineサイトのフォーラム内の[この記事](http://www.redmine.org/boards/2/topics/52964)のおかげなんですけどね。ありがとうございます。

## おわりに

「わざわざこんな事しなくても、こうすれば簡単にPOST/PUTできるよー」などという情報を御存知でしたらぜひ教えてください。
Railsでfogを使用してamazonS3にファイルアップロードする時の権限設定

# はじめに

[Ruby on Rails Tutorial 13.4.4](https://railstutorial.jp/chapters/user_microposts?version=5.1#sec-image_upload_in_production)ではfogを使用してAmazonS3にファイルをアップロードする必要があります。AmazonS3にファイルをアップロードするためにはIAMユーザーとＳ３ bucketの間に権限設定を行う必要があるのですが、単純にググるとIAMにAmazon S3 Full Accessを設定するように説明しているサイトが引っかかることが多いです。

もちろんチュートリアルなのでこれで動作確認はできますし、初めて利用するAWSとしては十分なのかもしれません。ただ、本番運用を想定すると、無闇にIAMに対してFullAccessは設定したくないですよね。できればbucketを限定した必要十分な権限設定としたいところです。

# インラインポリシー設定方法

IAMに以下の2つのインラインポリシーを設定すると、fogによるファイルアップロードやダウンロード、削除を行うことができました。ちなみに、〜Aclの権限を設定していなくて結構時間がかかってしまいました・・・fogはアップロードしたあとに、オブジェクトの権限を設定したりしているのでしょう。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "****",
            "Effect": "Allow",
            "Action": [
                "s3:GetBucketLocation",
                "s3:ListAllMyBuckets"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket"
            ]
        }
    ]
}
```

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "****",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket/*"
            ]
        }
    ]
}
```