OmniAICreator/Qiita-1.07M huggingface dataset:
Chromeデベロッパーツールで圧縮(minified)されたJavaScriptを読みやすく表示する

以下の内容は、Googleの開発者向けページにある [読みやすい形式への JavaScript の変換](https://developers.google.com/web/tools/chrome-devtools/javascript/pretty-print) ほぼそのままです。

(引用)
> JavaScript を読みやすい形式に変換するには、Chrome DevTools で [Pretty-Print] アイコンをクリックします。 

実際にやってみます。

たとえば[Google Earth](https://www.google.co.jp/intl/ja/earth/)の `app_ja.js` のソースコードは圧縮されているので次のように表示されますが、これだと読める気がしませんね。
![image](https://qiita-image-store.s3.amazonaws.com/0/39561/5e64cbaa-623e-d0d6-0174-ea59f71af6ae.png)

そんなときには、 **Pretty Print** `{}` のアイコンをクリックします。
![image](https://qiita-image-store.s3.amazonaws.com/0/39561/8c976790-89a3-48cb-8b5b-c342fa3e6f37.png)

すると、 `app_ja.js:formatted` というタブの中に、読みやすく整形されたスクリプトが表示されます。
![image](https://qiita-image-store.s3.amazonaws.com/0/39561/c2585c9d-5744-acc1-03cd-e2c381c3577d.png)

ちなみに、デバッグ時のブレイクポイントは`formatted`側に設定すれば良いので、既定のAPIを使うような開発作業も楽になりますね。
Guidelines for writing good articles

Guidelines for writing good articles

<a href="http://www.koreantvshows.com/">korean tv shows</a>

Articles posted to Qiita are displayed in the feed and will be seen by other users. There will also be people who find articles from the search. Let's be conscious of whether your article will be useful to the person who read it.

Even if you write for your own memo, you can make it a much valuable article just by being careful a little. 

Give concrete and concise titles

The title of the article is displayed not only in the page of the article but also in Qiita's feed and Google search results. Let's imagine the contents of the article just by looking at the title.

By attaching concrete titles, people who are looking for specific information will find it easier to find articles.

Example:

"Ruby memo" → "Which one of the scope and inheritance relationship has priority over Ruby's constant search?"
"I am addicted to regular expressions" → "The meaning of multiple line mode differs between Ruby and JavaScript regular expressions"
"OpenSSL Bug" - "Patched OpenSSL Heartbleed Bug in CentOS 6.5"
ログの結果等からグラフを生成する

ログから出力・加工したデータをつかってグラフをプロットする方法です。

# 用意するもの

- GNU awk / GNU coreutils
    - 記事でのデータ生成に使用
- gnuplot
- 「シェルでなんとかしてやる」という気概

# プロットする（ただしターミナル上で）

`terminal`は出力形式です。`dumb`とするとアスキーアートでグラフが描画されます。PNG画像がほしいときは`png`です。

こんなかんじ:

```sh
$ gnuplot -e 'set terminal dumb' \
          -e 'plot sin(x)'
```

![gnuplot_1.png](https://qiita-image-store.s3.amazonaws.com/0/109205/a336b574-4dc6-4fd5-cef4-d7f4af3459b2.png)

# 標準入力からプロット

入力は加工済みとします（ここでは`awk`で生成）。

```sh
$ seq 100 | awk '{print $1, sin($1/10)}' \
    | gnuplot -e 'set terminal png' \
              -e 'plot "<cat" using 1:2 with lines' \
    > gnuplot_2.png
```

![gnuplot_2.png](https://qiita-image-store.s3.amazonaws.com/0/109205/a8dedcfa-b455-3b99-92a7-170ed632f1d6.png)

`plot`の対象に`"<cat"`を指定すると、標準出力をデータとして読み込みます。`using`でプロットに用いるカラムを指定し、今回は線を付けてみました。


# 日付データをX軸に使ってプロット

時系列データは`awk`で生成しました。

```sh
$ date -f <(seq 100 | xargs printf "%d day\n") +"%Y%m%d" \
  | awk '{print($1, rand()*rand())}' | sort \
  | gnuplot -e 'set terminal png' \
            -e 'set xdata time'  # x軸を時系列データにする \
            -e 'set timefmt "%Y%m%d"'  # 読み込み書式を指定 \
            -e 'set format x "%Y%m%d"'  # 出力書式を指定\
            -e 'set xrange ["20170501":"20170701"]'  # 範囲を指定 \
            -e 'plot "<cat" using 1:2 with lines' > gnuplot_3.png
```

![gnuplot_3.png](https://qiita-image-store.s3.amazonaws.com/0/109205/3775d2b6-6e3b-d160-6fc0-0731085c5ef9.png)


# まとめ

データのプロットにはgnuplotを使おう。
PostgreSQLで外部からアクセスを定義する場合の参考サイト

# PostgreSQLで外部からアクセスを定義する場合
下記ファイルを修正するが、設定しているものの意味を知りたかったのでメモ。

vim /var/lib/pgsql/9.4/data/pg_hba.conf

## 日本語マニュアルサイト
https://www.postgresql.jp/document/9.4/html/auth-pg-hba-conf.html
XVim をバージョンアップする

定期的にやってくる、XCode バージョンアップ時、XVim も更新する必要がある。その時のメモ。

## 普通にやる

- git の master 最新を持ってくる
- コンパイル
  - make
- 証明書更新
  - `sudo codesign -f -s XcodeSigner /Applications/Xcode.app`

## 問題が出た場合

大体 issue か PR にあるので見る。

例えば2017年4月19日時点で XCode 8.3.1 で make がこける場合

- それっぽいのを探す
  - https://github.com/XVimProject/XVim/issues/1050
  - develop ブランチならうまくいくとのこと→うまくいった
Node-RED 上の操作で完結する Bluemixの Node-RED パレットへのノードの追加方法

#0. はじめに
タイトルが長くてごめんなさい。

これまで、[BluemixのNode-REDパレットにノードを追加する](http://qiita.com/KenichiSekine/items/b2877c90f59774a27827)の記事を参考にしたり、手元に Cloud Foundry CLI の実行環境が整っていない時は、IBM Bluemix DevOps Services を利用してノードを追加していました。

しかし、既にお気付きの方も多いと思いますが、Node-RED フロー・エディターの画面右上のメニュー内に「処理ノードの追加削除」という項目が追加されています。

![スクリーンショット 2017-04-19 11.50.58.png](https://qiita-image-store.s3.amazonaws.com/0/74185/6bbacc3a-813a-1a42-245c-8b711763b1a4.png)

この項目からの操作により、ノードの追加手順が非常に楽になったので、その手順をご紹介します。

#1. 「処理ノードの追加/削除」の選択
上記画像の要領で画面右上のメニューより「処理ノードの追加削除」を選択。

#2. 「処理ノードを追加」タブの選択
Node-RED フロー・エディターの画面左側に以下の画像の様に既に利用できる状態になっているノードの一覧が表示されます。
![スクリーンショット 2017-04-19 11.56.47.png](https://qiita-image-store.s3.amazonaws.com/0/74185/c25eb026-6ce1-3f64-1b04-42e96b730f2a.png)
「処理ノードを追加」タブを選択します。

#3. 追加ノードの検索とインストール
「処理ノードの追加」タブでは追加するノードの検索ができますので、例として node-red-dashboard ノードを追加します。

![スクリーンショット 2017-04-19 12.36.57.png](https://qiita-image-store.s3.amazonaws.com/0/74185/a9fdd125-bd6c-9e5b-394d-adf963baa3a1.png)

dashboard と入力している間に、入力に一致する名前のノードが絞り込まれます。
![スクリーンショット 2017-04-19 12.38.03.png](https://qiita-image-store.s3.amazonaws.com/0/74185/21b4a9ce-d703-49fe-e982-6912b7b7b0ca.png)

node-red-dashboard として表示されているノードの「処理ノードを追加」ボタンをクリックすると自動的に解決できない依存関係や再起動の必要があるノードもあるので、ノードのドキュメントを読むことを指示するメッセージが表示されます。
![スクリーンショット 2017-04-19 12.44.35.png](https://qiita-image-store.s3.amazonaws.com/0/74185/46025a7f-18fe-38e0-5d02-f5f5d8c95a5f.png)

必要に応じて「Open node information」ボタンからノードのドキュメントを確認後、「Install」ボタンを押すとインストールがおこなわれ、以下のメッセージが表示及びメッセージが非表示となります。
![名称未設定.png](https://qiita-image-store.s3.amazonaws.com/0/74185/922b7e18-ae78-6c54-b5cc-edd28ab1005a.png)
「完了」ボタンをクリックすると「処理ノードの追加削除」の領域が閉じます。

#4. パレット上での追加ノードの確認
ここまでの操作で、Node-RED フロー・エディターの画面左側のパレット上で（それまで存在しなかった場合は、）新たに使用できるノードが追加されています。
![スクリーンショット 2017-04-19 13.18.27.png](https://qiita-image-store.s3.amazonaws.com/0/74185/3a416495-829c-55da-439e-3da4c564d682.png)

これで、色々なノードを簡単に試せますね！
では、また。
PostgreSQL でコメントの無い列を調べる

* 「全テーブルの全カラムにちゃんと列コメントが付いてるか確認して」って言われたとき
* ``pg_xxxx`` だけで見るとコメントが入ってないものが抽出できない

```sql
SELECT
  cols.table_name,
  cols.column_name,
  cmm.column_comment
FROM
  (SELECT
     table_name,
     column_name
   FROM
     information_schema.columns
   ORDER BY
     ordinal_position) cols
  LEFT JOIN
  (SELECT
     psat.relname   AS table_name,
     pa.attname     AS column_name,
     pd.description AS column_comment
   FROM
     pg_stat_all_tables psat
     , pg_description pd
     , pg_attribute pa
   WHERE
     psat.relid = pd.objoid
     AND pd.objsubid <> 0
     AND pd.objoid = pa.attrelid
     AND pd.objsubid = pa.attnum
   ORDER BY
     psat.relname,
     pd.objsubid) cmm 
  ON cmm.table_name = cols.table_name AND cmm.column_name = cols.column_name
WHERE
  cmm.column_comment is NULL
```

もう少しリファクタできそうな気もする。

via [PostgreSQLにてテーブルやカラムの各種情報を取得するSQL (テーブル一覧, カラム一覧, プライマリーキー情報取得, テーブルのコメントを取得, カラムのコメントを取得) - いろいろ備忘録日記](http://devlights.hatenablog.com/entry/20080226/p1)
[Microsoft Translator API]SpeechTranslatorのサンプルを動かす

言語の壁は厚いですよね。
アプリで解決出来たらどれほど素敵なことでしょう。

つい先日マイクロソフトの翻訳APIが強化されたので、これを使えばきっと解決できる！と信じ、
まずはサンプルを動かしてみました。
つまづいたところもあったのでメモとして残します。

##実行イメージ
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Microsoft Translator API SpeechTranslatorのサンプルを確認。 <a href="https://t.co/862qGhLhX7">pic.twitter.com/862qGhLhX7</a></p>&mdash; morio (@morio36) <a href="https://twitter.com/morio36/status/854542876318945286">2017年4月19日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

##流れ
１．Azureの登録
２．サンプルコードのDL&ビルド
３．実行

##１．Azureの登録
下記に従い、アカウント作成～サブスクリプション登録～認証キー取得まで実施してください。
https://www.microsoft.com/ja-jp/translator/getstarted.aspx

##２．サンプルコードのダウンロード＆ビルド
下記のgithubからサンプルコードをダウンロードしてください。
https://github.com/MicrosoftTranslator/SpeechTranslator

下記にslnファイルがあるので、開いてください。
\SpeechTranslator-master\SpeechTranslator.sln

ここで一つつまづいたことがありました。
私の開発環境にはVisual Studio 2017がインストールされているのですが、
「このプロジェクトタイプの基になっているアプリケーションが見つかりませんでした」
というエラーが出てしまい、プロジェクトが開けなかったのです。

![error.PNG](https://qiita-image-store.s3.amazonaws.com/0/114630/8aee1dca-3852-94cb-d8d4-d2e06de39a93.png)

出力されたhtmlファイル内のリンクをクリックすると
WiX Toolsetというツールのダウンロードサイトに飛びました。
（インストーラ関連のツールらしいですが、深追いしてません）

WiX 3.11 RCと、WiX Toolset Visual Studio 2017 Extension（※）をダウンロードし、インストールしました。
※私の環境はVisual Studio 2017のため、Extensionを入れています。

##３．実行
VisualStudioから「開始」を押下して実行すると、下記のような画面が出ます。

![6.png](https://qiita-image-store.s3.amazonaws.com/0/114630/37795b05-7167-4e5e-4112-a70991a95657.png)
（実行するたびに「To Language」のデフォルト選択が変わるのは仕様なのだろうか・・・）

「Settings」→「Account Settings...」を開き、Azureサブスクリプションのキーを貼り付けて「Save」してください。
![7.png](https://qiita-image-store.s3.amazonaws.com/0/114630/cca208ec-4453-17fc-a28b-1188f648baf9.png)

![8.png](https://qiita-image-store.s3.amazonaws.com/0/114630/afd9f7e0-e2ef-3706-464c-47397e956cc7.png)

翻訳元言語、翻訳先言語、声の種類（男女）を選択し、TTSにチェック。
Startを押すとCognitiveサービスに接続され、翻訳可能な状態となります。
![9.png](https://qiita-image-store.s3.amazonaws.com/0/114630/1cd04baa-fc57-872b-1313-71c93766c510.png)


これで翻訳APIをアプリに組み込む下準備ができました。
これからが本番です。
何かアプリを作ったら情報追加致します！
apache2.4での.htaccessを使ったBasic認証

非常に簡単な事のはずなのに探してもサクッとコピペ出来るものが見つけられなかったのでメモ

```
AuthUserFile [htpasswdファイルを置いたフォルダ]/.htpasswd
AuthGroupFile /dev/null
AuthName "Input ID and Password."
AuthType Basic
Require valid-user
<Files ~ "^.(htpasswd|htaccess)$">
        Require all denied
</Files>
```
後、よくあるのは、.htaccessファイルの読み込みを許可する設定をしてないとかですかね。
httpd.confとか、個別confファイル内のDirectory設定内で
AllowOverrideをnoneとかにしてると読まれないので
AuthConfigにしてあげてくださいね。

上の設定をざっくり説明すると
*AuthUserFile
ID、パスワードの記載されたファイル。作り方はhtpasswdとかで検索すればいくらでも出てくると思います。

*AuthGroupFile
ユーザをグループで区切ってアクセス制限したりに使いますが、使ったことないっす。

*AuthName
Basic認証のダイアログに表示される。。。Chromeされない。。。

*AuthType
認証の方式。Basic認証はなにかとセキリティ的に弱いのでしっかり作りたいのであれば調べてみたらいいと思いますが
そんなのApacheでやるなよっとも思う。

*require
パスワードファイル内でアクセスを許可するユーザの羅列。
ここでは全て許可してます。

*それ以下
パスワードファイルとかアクセス制限の方法とか、見えちゃまずいので全部アクセス拒否してます。
Require all denied
この辺が2.2と2.4で大きく違うので注意が必要です。
Codeigniter insertしたidを知りたい場合

$this->db->insert_id()
使用方法

```php:Project_model.php
$this->db->insert('project', $form);
$insert_id = $this->db->insert_id();
return $insert_id;
```
```php:sample.php
if (!$insert_id = $this->Project_model->insert_name($this->form)) {
			$this->_error("登録に失敗しました。");
		}
```
USB・I2C（SMBus）変換モジュール MM-CP2112A

サンハヤトのUSB I2C モジュールの使い方です。
![mmcp2112aa.jpg](https://qiita-image-store.s3.amazonaws.com/0/165672/00cf9061-b553-6ab7-2848-21ca8f7dcb95.jpeg)
[USB・I2C（SMBus）変換モジュール MM-CP2112A](http://www.sunhayato.co.jp/material2/index.php/item?id=1083)

シリコンラボラトリー社のPCアプリを使用することで、USB経由でI2Cデバイスの動作確認が行えます。
I2Cのデバイスを組み込みする際に、事前にセンサーなどの単体で動作を確認するのに使用しています。

サンハヤトさんの公式ページに使い方はありますが、簡単に使い方をメモします。

#1 PCアプリをDLする。
[DLページ](http://jp.silabs.com/products/development-tools/software/interface)

![CP2112A_ソフトウェア.png](https://qiita-image-store.s3.amazonaws.com/0/165672/61872e0d-bfb7-e41d-738f-768783ac85e9.png)
DLページの2112Aのソフトウエアをダウンロードします。

#2 インストールして起動
![CP2112A_ソフトウェア2.png](https://qiita-image-store.s3.amazonaws.com/0/165672/f1f6cea4-89ef-2f94-048b-651c76524b2e.png)

#3 CP2112Aの接続
![CP2112A_ソフトウェア3.png](https://qiita-image-store.s3.amazonaws.com/0/165672/e70b5b92-9507-d982-6da7-ba981c82db2a.png)

PCに接続するとデバイスが現れるのでConnectで接続します。

#4 I2C write
![CP2112A_ソフトウェア4.png](https://qiita-image-store.s3.amazonaws.com/0/165672/0acb14b4-9985-f586-ad85-61990df776b8.png)
[Data Transfer] タグを選択
[Slave Address]を入力
[Data to Write]を入力
[Write Request]を押下
pythonでデータ書き出しの際に「openpyxl.utils.exceptions.IllegalCharacterError」が出たときの対応


pandasを使用してデータをサーバから取得し、openpyxlを使用してデータをExcelなどに書き出す場合に下記のエラーが出る場合がある。
```
openpyxl.utils.exceptions.IllegalCharacterError
```

理由としては取得したデータフレームの中にopenxmlで扱えない不正な文字が含まれている、ということなので下記のように除外するための関数を1回挟めばＯＫ


```python
import pandas as pd
import openpyxl

def illegal_char_remover(data):
    ILLEGAL_CHARACTERS_RE = re.compile(
        r'[\000-\010]|[\013-\014]|[\016-\037]|[\x00-\x1f\x7f-\x9f]|[\uffff]')
    """Remove ILLEGAL CHARACTER."""
    if isinstance(data, str):
        return ILLEGAL_CHARACTERS_RE.sub("", data)
    else:
        return data

#サーバ情報
conn = pyodbc.connect(サーバ情報)
#クエリ実行
df = pd.read_sql(クエリ情報, conn )
#IllegalCharacter除外（ここが追加分）
df = df.applymap(illegal_char_remover)

```
postgresqlでシンプルな文字列結合

# はじめに

PostgreSQLですぐに使える文字列結合を３つ紹介します

- 文字列結合演算子 `str1 || str2`
- concat() `concat(str1, str2 [, ...])`
- concat_ws() `concat_ws(septext, str, str [, ...] ])`

こちらを参考にしました
[PostgreSQL 9.3.2文書 文字列関数と演算子](https://www.postgresql.jp/document/9.3/html/functions-string.html)

## 文字連結演算子
`str1 || str2`
パイプラインで繋ぐだけ、とてもシンプル
整数や真偽値など、非文字列型でも対応してくれる
ただし連結要素にNULLが含まれる場合、結果はNULLとなる。

```SQL
SELECT 
  sei, mei, age, post,
  sei || mei || '(' || age || ')' || post AS outline
FROM 
  members
```

|sei |mei |age |post |outline |
|---|---|---|---|---|
|山田 |太郎 |15|捕手 |山田太郎(15)捕手 |
|里中 |智 |15 |投手 |里中智(15)投手 |
|山田 |サチ子 |6 |(NULL) |(NULL) |
※ 山田サチ子の行にNULLが含まれるため、outlineはNULLとなる

## concat

`concat(str1, str2 [, ...])`
引数（文字列）を結合する、非文字列型でも対応してくれる
結合演算子と違い、NULLの値は無視する

```SQL
SELECT 
  sei, mei, age, post,
  concat(sei, mei, '(', age, ')', post) AS outline
FROM 
  members
```

|sei |mei |age |post |outline |
|---|---|---|---|---|
|山田 |太郎 |15|捕手 |山田太郎(15)捕手 |
|里中 |智 |15 |投手 |里中智(15)投手 |
|山田 |サチ子 |6 |(NULL) |山田サチ子(6) |
※ 山田サチ子の行のNULLは無視されている

## concat_ws

`concat_ws(septext, str, str [, ...] ])`

第一引数を区切り文字として、残りのすべての引数を結合する。
NULLの値は無視する。
スペース区切りした文字列を作りたい時や、
CSVを作りたいときに使えそう ⇒ でもNULLでズレるから向かなそう

```SQL
SELECT 
  concat_ws(',', members.*) AS csvline
FROM 
  members
```

|csvline |
|---|
|山田,太郎,15,捕手  |
|里中,智,15,投手 |
|山田,サチ子,6 |

# おわりに

文字列結合演算子 `||` の存在を知らなかったので、メモ代わりに投稿しました。
ドカベンはよく知りません。
Jetpack のモバイルテーマを無効にしました

WordPress のテーマを作っていたら、モバイルで作った覚えの無いテーマが**表示されて**困りました😅

# 対象読者
設定した記憶がない、下図のようなモバイルテーマが表示される方
<img src="https://qiita-image-store.s3.amazonaws.com/0/1624/95a39ff9-8406-f774-bfa7-c6cb3d14ee08.png" width="30%" />

テーマはフッターに `Proudly powered by WordPress` と書いてあります。

# 切り分け
現在表示している WordPress のテーマソース内を `Proudly powered by WordPress` で grep します。ソース内には該当の文字列は表示されていないことがわかりました。

ソースには無いのでプラグインと考えて、プラグインで関係ありそうなものを調べました。テーマのようなプラグインは無いので、Jetpack が影響しているのかなと考えました。

# Jetpack のモバイルテーマ
Jetpack にはモバイルテーマというものがあるようです。
`Jetpack > 設定` のなかに `Theme enhancements` という項目があります。この中で `Optimize your site for smartphones` を有効にするとモバイルのテーマが有効になります。

<img width="50%" src="https://qiita-image-store.s3.amazonaws.com/0/1624/1a1aea54-7b2f-9678-0c0e-80ba64f4e6a5.png">

今回はモバイルテーマを使用したくなかったので、無効にしました。

# 参考

- https://jetpack.com/support/mobile-theme/

# 感想
Jetpack を有効にしてなんとなくモバイルテーマが表示されるようになってしまった人は最初戸惑うケースではないかと思いました😅

かんそうおしまい(☝ ՞ਊ ՞)
jQueryでNow Loadingからふわっと表示させたい

タイトルからしてふわっとしており恐縮でございます。。。

# 今回のお題

1. ページ読み込み中に「Now Loading...」画像を表示させる
2. 読み込み準備ができたら「Now Loading...」画像を非表示にする
3. その際、表示したいものを「パッ」と出すのではなく「ふわっ」と表示させる


ここで言う「ふわっと」はアニメーションを使ってopacityを徐々に上げて表示する意になります。
ということで、ふわっと感を大事にしてお届けします。


## jQuery
今回はjQueryを使います。

```html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
```

## html
result内に読み込んだ内容を表示させることにします。

```html
<!-- now loading -->
<span class="loading">
    <img src="/img/loading.gif" alt="Now Loading..." />
</span>

<!-- 読み込んで表示したい内容 -->
<div class="result">
</div>
```

## css
resultを透明化、loadingは画像の位置調整をそれぞれしております。

```css
.result {
    opacity: 0;
}
.loading {
    left:50%;
    top:50%; 
    position: fixed;
}
```

## script
loadしたタイミングで1500ミリ秒かけて透明度を下げていくようにします。

```js
$(window).on('load', function() {
  $('.result').css({opacity: '0'}).animate({opacity: '1'}, 1500);
  $('.loading').hide();
});
```

以上、最後までふわふわしたまま終了です。
TLS > [詳細設定] で TLS 1.0、TLS 1.1、TLS 1.2 を有効にして、もう一度 https://xxx-yyy.jp  に接続してみてください。引き続きエラーが発生する場合は、サポートされていないプロトコル、または安全と見なされない RC4 などの暗号スイート ((詳細情報のリンク)) がサイトで使われている可能性があります。サイトの管理者に問い合わせてください。 

```txt:動作環境
Windows 10 Pro (64bit) Anniversary Update適用済
Internet Explorer 11
```

### エラーメッセージ

>このページは表示できません
>
>[詳細設定] で TLS 1.0、TLS 1.1、TLS 1.2 を有効にして、もう一度 https://xxx-yyy.jp  に接続してみてください。引き続きエラーが発生する場合は、サポートされていないプロトコル、または安全と見なされない RC4 などの暗号スイート ((詳細情報のリンク)) がサイトで使われている可能性があります。サイトの管理者に問い合わせてください。 


### エラーの対処

サポート窓口の方に親切に教えていただきました。
情報感謝です。

**対処方法: 証明書を「ローカルユーザ」でインストールする**。

証明書インストール時に以下の選択があった。

1. ローカルユーザ
2. ローカルコンピュータ

他のユーザでも同じシステムが使えるように「ローカルコンピュータ」としてインストールした場合、上記のエラーとなった。

ローカルユーザでインストールすると、IE11にてインターネットオプション > コンテンツ > 証明書 に該当の証明書が表示される。

この状態で問題のサイトに接続すると証明書関連のダイアログが表示され、サイトが表示されるようになった。

TLS1.0などの設定については

- SSL 3.0を使用する: オフ
- TLS1.0を使用する: オン
- TLS1.1の使用: オン
- TLS1.2の使用: オン

Windows 7時は「ローカルコンピュータ」への証明書インストールで問題がなかったという報告もある。Windows 10から変わったのかどうかは未調査。
mastodonのaccess tokenをauthorization_codeで取得する例


はじめに
-------
mastodonのAPIを使用するために必要なaccess tokenの取得について書いた記事です。

oauth2でaccess tokenを取得する方法は[grant_type](https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/709.html)によっていろいろな方法がありますが、よく見かける記事は `grant_type="password"` のものが多かったので `grant_type="authorization_code"`で取得するPythonでの例です。

環境
----

- Python3.6
- 外部ライブラリは[reqeusts](http://docs.python-requests.org/en/master/)パッケージだけ使用

実行結果
-------

```shell-session
$ python mastodon_auth_example.py 
client id:     XXXXXXXXXX...
client secret: YYYYYYYYYY...
open browser  https://mstdn.jp/oauth/authorize?scope=read+write+follow&client_id=XXXXXXXXXXXXXXXXX&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code
input code > ZZZZZZZZZ....
access token : ****************************************************************

```


解説
----

クライアントIDの取得
-----------------

認証済みアプリとして登録するために、クライアントIDを取得する。Twitterではdev.twitter.comでMyAppsで登録したような操作。mastodonではWebインターフェースがないのでREST APIで取得する。

client_id と client_secretが得られる。

```python
res = requests.post('https://mstdn.jp/api/v1/apps',
                    dict(client_name=CLIENT_NAME,
                         redirect_uris="urn:ietf:wg:oauth:2.0:oob",
                         scopes="read write follow")).json()

return res["client_id"], res["client_secret"]
```
redirect_urisは実際にはリダイレクトせずにコンソール上に表示させるためにこのuriを使用するよう。
scopeはこのアプリがユーザーに要求する権限です。アプリが必要とする権限だけ要求すべき。

クライアントIDの発行はアプリごとに作成するため、例ではファイルに保存してそれを再利用する形にしている。

権限承認用URLを作成
-----------------

クライアントIDを使用して権限承認用のURLを生成する。ユーザーはこれをブラウザで開き、（必要ならばログイン後に）アプリが要求する権限を確認した上で承認する。

承認後はアプリが要求するURLへリダイレクトしてアプリ側で認証コードを受け取る流れだが、リダイレクトを受け付けるかたちにするには**サーバプログラムでhttpsでアクセスできなければならない**(Webサービスはそのように作るべき）
ここでは認証コードをブラウザ上で表示してユーザーにコピペしてもらう形式をとる。ブラウザではないデスクトップクライアントなどはこのような形式をとる。

ユーザーがブラウザ上で承認することで認証コードが得られる。

```python
params = urlencode(dict(
    client_id=client_id,
    response_type="code",
    redirect_uri="urn:ietf:wg:oauth:2.0:oob",   # ブラウザ上にcode表示
    scope=SCOPE
))
return 'https://mstdn.jp/oauth/authorize?'+params
```

アクセストークンの取得
-------------------

認証コード、client_id, client_secretの3つを使用してアクセストークンの発行を行う。

```python
res = requests.post('https://mstdn.jp/oauth/token', dict(
    grant_type="authorization_code",
    redirect_uri="urn:ietf:wg:oauth:2.0:oob",
    client_id=client_id,
    client_secret=client_secret,
    code=code
)).json()
return res["access_token"]

```

アクセストークンが得られるのでこれを利用してAPIのAuthorizationヘッダに使用する。

ソースコード
------------

https://github.com/civic/mastodon-auth-example


参考
-----
- [Using the API](https://github.com/tootsuite/documentation/tree/master/Using-the-API)
- [セキュリティトークンとOAuth 2.0](https://www.ipa.go.jp/security/awareness/vendor/programmingv2/contents/709.html)
- [MastodonのAPIをcurlで叩いてみるサンプル](http://qiita.com/shindyu/items/6a1f0c567774516f07da)
- [Mastodon API の叩き方](https://gist.github.com/okapies/eab5c6fc217e914ed0cac6c944384e4d)
ZABBIX3.2でディスカバリ設定、監視設定、メール通知設定

##1. ディスカバリ設定
①[設定]タブ→[ディスカバリ]タブをクリック
②ディスカバリルールで編集したいルールをクリック
　※ルールを新規作成する場合は[ディスカバリルールの作成]をクリック
③ディスカバリルール名を編集
④追加・削除する機器のIPアドレスを編集
⑤[更新]ボタンを押下
![pic1.png](https://qiita-image-store.s3.amazonaws.com/0/171475/5b4906db-5e36-7c70-5cc0-184015dcef4b.png)
![pic2.png](https://qiita-image-store.s3.amazonaws.com/0/171475/dab019d9-781c-d3e3-4530-36f3958f7a52.png)

##2. 監視設定
（１）ホストの追加
①[設定]タブ→[ホスト]タブをクリック
②[ホストの作成]ボタンをクリック
③[ホスト名]を入力
④[所属グループ]にグループ名を登録
⑤エージェントのインターフェース欄に対象ホストのIPアドレスを入力
⑥[テンプレート]タブをクリック
⑦「Template ICMP Ping」を追加
⑧[更新]ボタンをクリック

（２）ホストの削除
①[設定]タブ→[ホスト]タブをクリック
②ホスト一覧から削除したホストをチェックして
　[削除]ボタンをクリック
![pic3.png](https://qiita-image-store.s3.amazonaws.com/0/171475/c5cc069e-f873-9e43-2261-ba2a6c52ed98.png)


##3. メール通知設定
（１）アクションの設定
①[設定]タブ→[アクション]タブをクリック
②「アクションの作成」ボタンを押下
③アクション名および実行条件を選択
④[実行内容]タブをクリック
⑤デフォルトの件名とメッセージを編集
⑥実行内容に「ユーザにメッセージを送信」を選択
⑦[復旧時実行内容]タブをクリック
⑧デフォルトの件名とメッセージを編集
⑨実行内容に「ユーザにメッセージを送信」を選択
⑩[更新]ボタンを押下
※１…作成済の場合は既存のアクション名をクリック
![pic4.png](https://qiita-image-store.s3.amazonaws.com/0/171475/ae901235-aeda-7802-e921-2947e93938ad.png)
![pic5.png](https://qiita-image-store.s3.amazonaws.com/0/171475/27331818-6c9c-4073-6975-624380d6fb2a.png)

（２）メール通知先の設定
①[管理]タブ→[ユーザ]タブをクリック
②[admin]をクリック
③[メディア]タブをクリック
④[追加]もしくは既存の登録先を変更する場合は[変更]または[削除]を押下
⑤[タイプ]で[Email]を選択
⑥送信先にメール通知したい宛先アドレス[例:user1@test.local]を入力
⑦[更新]ボタンを押下
⑧[メディア]ページの[更新]ボタンを押下
![pic6.png](https://qiita-image-store.s3.amazonaws.com/0/171475/95b113ed-1218-17b2-523f-a84ba8fc577e.png)

（３）メール発信元の設定
①[管理]タブ→[メディア]タブをクリック
②[Email]をクリック
③[SMTPサーバー] にアドレス[例:outbound.test.local]を入力
④[SMTP helo]にドメイン[例:test.local]を入力
⑤[送信元メールアドレス]にメール発信したいアドレス[例:admin@test.local]を入力
⑥ [更新]ボタンを押下
![pic7.png](https://qiita-image-store.s3.amazonaws.com/0/171475/1fc09e70-e132-75d9-83ac-a4f93e715f2b.png)

##4. サーバDown/Upによる設定確認
・障害発生時のZABBIXダッシュボード画面
![pic8.png](https://qiita-image-store.s3.amazonaws.com/0/171475/7e0eeb82-1086-5acc-b81f-aff2c4bc0743.png)

・障害復旧時のZABBIXダッシュボード画面
![pic9.png](https://qiita-image-store.s3.amazonaws.com/0/171475/1575095c-4d96-626f-99b6-7995233ef7ce.png)

・障害発生時のメール画面
![pic10.png](https://qiita-image-store.s3.amazonaws.com/0/171475/b36407ef-643f-bacd-0905-2abcef9246b7.png)

・障害復旧時のメール文
![pic11.png](https://qiita-image-store.s3.amazonaws.com/0/171475/4dfc1e37-559f-51b1-32ba-4d0d74a35945.png)
VCのソースセーフに投入するモノ


# 環境
* VS2015
* Git Bash

# 追加するファイル
* .sln
* .vcxproj
* .vcxproj.filters
* ソースコード

# 追加しないファイル
* .sdf
* .suo
* icphフォルダ
* Debugフォルダ
* Releaseフォルダ
* .vcxproj.user
技術書読書会 #4 Infrastructure as Code

# 技術書読書会 #4 Infrastructure as Code

## 読書会とは
新しい発想を得ようと思うならまず参考書をもって誰かに話を聞け。と某自動車メーカの創業者が言っていました。

技術書を最後まで読み切る事は意外と大変です。一人なら無理だけどみんなの力があればできるかも・・・。
そんなことを誰が思たのか、ともあれそんな気持ちに賛同したメンバーが１冊の技術書を読み込むという結構ハードルの高いことにチャレンジをしていきます。

## 技術書読書会の進め方
eXtreme Readingの方式で進めていきます。

### 実施方法
以下の流れで読書をしていきます。

```
1. 0分～5分間で、今回読み進める章/節を発表する
2. 15分～30分間で、読書
3. 5分～10分間で、ディスカッション
4. 1～3を時間分繰り返す
5. まとめ
```

今回の読書会は、所要時間30分で以下の配分で行いました。

```
1. 5分間で、今回読み進める章/節を発表する
2. 15分間、読書
3. 5分間、ディスカッション
4. 10分間、まとめ
```

### 利点
eXtreme Readingの利点です。

- 事前の準備がいらない。
- ディカッションをすることにより理解を深める事ができる。参加者全体の理解度の底上げが期待できる。
- 時間を区切って進行するので、読書の進捗が一定となり本の読み終わり時期を予測することができる
- みんなでやればなんとかなる


## 今回読む書籍
[Infrastructure as Code ―クラウドにおけるサーバ管理の原則とプラクティス](
https://www.amazon.co.jp/Infrastructure-Code-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%B5%E3%83%BC%E3%83%90%E7%AE%A1%E7%90%86%E3%81%AE%E5%8E%9F%E5%89%87%E3%81%A8%E3%83%97%E3%83%A9%E3%82%AF%E3%83%86%E3%82%A3%E3%82%B9-Kief-Morris/dp/4873117968/ref=sr_1_1?ie=UTF8&qid=1491455639&sr=8-1&keywords=Infrastructure+as+Code)

## 参加人数
5人

## 所要時間
30分

## 進捗
2.4.6 - 2.7

## ディスカッション

### 2.4.6 ベアメタルクラウド

飯　用語の確認いいですか？TFTPって何ですか？

```
wikipediaより

Trivial File Transfer Protocol（トリビアル ファイル トランスファー プロトコル、TFTP）は、UDPを用いてコンピュータ間で
ファイルを転送するためのプロトコルである。FTPに比べて軽量・単純なプロトコルである。認証機能が無いためにユーザ名や
パスワードを必要としない。ポート番号69をデフォルトとして使用する。Remote Installation ServicesやPXEなどの
ネットワーク・ブート環境において、ディスクレスマシンがブートする際、BOOTPやDHCPで構成情報を取得した後に、
実際のOSコードをサーバから取得する際に利用される。また、ルータなどの設定の読み取りや書き込みなどにも用いられる。
```

### 2.5.1.2 ホスティングロケーションに関する法的規制
岡　初めて知った。
峯　ヨーロッパは、厳しいんだね。
桑　ヨーロッパも厳しいんだけど各国に情報規制があって、クラウドサービスのサーバーは、立っている国の法律に左右されている。

### 2.5.1.4 独自クラウドを構築するためのトータルコスト
峯　サンクコストは普段生活をしている中で意識している。投資したコスト（時間やお金）だけでなく、今から始めるという意識も持つようにしている
岡　だから、ここでもコストについて現実的な見方ができているかを確認すると書いてあるんですね。

### 2.5.2 クラウドのポータビリティ
岡　ここは、なるほどと思いつつも結構大変だなと！銀の弾丸という感じじゃなかったですよね。
飯　確かにやりたいんですけど、AWSとGCP
飯　これって、クラウド使う意味って出てきますよね
岡　そうそう
飯　2.5.1.3 可変容量の要件でもあったけど、コストが安く済みそうだから使っているみたいなところとか
桑　きちんと要件を切ったうえで判断

### 2.5.1 ポータビリティを実現するためのテクニック
桑　これは、言っていることはわかる。そもそもその機能があるからこのクラウドを選択したって場合もある
峯　ベンダーロック派です。書いてあるけど、時間もかかるし金もかかる。時間はかけたく無し金もかけたくない。
峯　大きくなる見通しが立った段階で、どれだけ早くポータビリティを実現するための戦略を立てられるかかと
飯　サンクコストですよ。
峯　既存サービスをクラウドへ移行するなら、初めから考えるのもありかと
飯　プロダクトのアプリもDocker使っているんだけど、AWS AMIを使えばいいのではという話も出ている

### 2.6 クラウドと仮想化に対するマシンレベルの共感
峯　インスタンスガチャ
桑　インスタンスが立った周りの環境に性能が左右される
峯　Netflixは、[Chaos Monkey](http://www.publickey1.jp/blog/12/chaos_monkeynetflix.html)とか公開してるよ。

## 気づき
* 本日は、8ページ読んだが、区切りの良いところまで進めてみた。個人的にはすっきりした。時間は長めの20分間としたが、読むペースが速くなっているのか。みんな時間を持て余していたように見える。

## まとめ
Skypeは、音が悪い？（お風呂場にいるような感じで聞こえる）ということでうまくいきませんでした。集音マイクがどこかにあるはずなので明日はそちらを試す予定
ROSのカメラ画像処理に関するメモ

## 概要

ROSのカメラ画像処理に関して、いろいろ細かなテクニックがあったので、まとめてみました。

## Depth 画像の Registration

RealSense などの RGBD カメラを利用する場合、RGB画像とDepth画像の座標系を揃えるRegistrationの下処理を行うのが一般的です。

- [depth_image_proc/register](http://wiki.ros.org/depth_image_proc#depth_image_proc.2BAC8-register)
- [rgbd_launch/processing.launch.xml](http://wiki.ros.org/rgbd_launch#processing.launch.xml)
- Realense の場合: [realsense_camera/r200_nodelet_rgbd.launch](http://wiki.ros.org/realsense_camera)

r200_nodelet_rgbd.launch は内部的に rgbd_launch を include していて、rgbd_launch は内部的に image_proc や
 depth_image_proc のノードを利用しています。

### Registration の仕組み

- Depth 画像を Rectify (歪み補正)
- RGB 画像を Rectify (歪み補正)
- Depth 画像を3次元空間にマッピング (deprojection)
- 3次元空間上の点を RGB カメラの座標系にマッピング (projection)

このステップを経ることで、Depth と RGB の各画素で1対1の対応関係が取れるようになります。最終的に得られる Depth 画像の座標系・解像度は、入力の座標系・解像度に関わらず、RGB 画像と同じものになります。

## 画像のフィルタ処理

画像系のトピックのフィルタ処理は、原則として下記の作法に従うのが良い。([image_pipeline](http://wiki.ros.org/image_pipeline)の実装が参考になります)

- Nodelet を使う (zero copy で画像転送できる)
- 通常の Publisher, Subscriber の代わりに image_transport の Publisher, Subscriber, CameraSubscriber を利用する
- できれば、subscriber がいるときだけ処理を行うようにする
    - `image_transport::SubscriberStatusCallback` が利用できる

 このようにすることで、ノード間連携のオーバーヘッドを最小化しつつ、CameraInfo との同期等がスムーズに行なえます。

## PointCloud の Nodelet の負荷

PointCloud 配信の Nodelet を動かすと負荷が大きくなるのでは、と懸念したのですが、 [depth_image_proc/point_cloud_xyzrgb](http://wiki.ros.org/depth_image_proc#depth_image_proc.2BAC8-point_cloud_xyzrgb) は前述の作法にのっとって実装されているので、実は Nodelet を動かしても subscribe しなければ負荷は少ないです。rviz でのデバッグ目的とかでも、気軽に PointCloud の Nodelet を動かしてしまって問題ないです。


## トピック名のルール

[sensor_msgs/CameraInfo](http://docs.ros.org/api/sensor_msgs/html/msg/CameraInfo.html) を見ると、下記のように書かれています。

```
#   image_raw - raw data from the camera driver, possibly Bayer encoded
#   image            - monochrome, distorted
#   image_color      - color, distorted
#   image_rect       - monochrome, rectified
#   image_rect_color - color, rectified
```

自前で Image を配信する場合にも、なるべくこの作法にのっとった方が良さそうです。

## CameraInfo と Image の同期

[rtabmap_ros/data_throttle](http://wiki.ros.org/rtabmap_ros#rtabmap_ros.2BAC8-data_throttle) を利用する際にハマりました。一部の Node は、中で synchronize 処理を行っており、入力の CameraInfo と Image の stamp が合っていないと処理が行われないので注意が必要です。画像のフィルタ処理に image_transport を利用していれば問題ないのですが、そうでない場合にハマります。

## CameraInfo を用いた画像処理

[image_geometry](http://wiki.ros.org/image_geometry) を使うと、CameraInfo を使って簡単に projection や rectify が行えます。

```
from image_geometry import PinholeCameraModel

def get_direction(camera_info, px, py):
    u""" 画像上の座標を入力として、カメラ座標における方向を返す """
    camera_model = PinholeCameraModel()
    camera_model.fromCameraInfo(camera_info)
    vector = camera_model.projectPixelTo3dRay((px, py))
```

例えば、こんな感じ。
OSX の mysql 5.7 で mysqld_multi を使ってレプリケーションする

モチベーションは、ちょっと slave のテストをする必要があったので適当にローカルで試したい、なんだけどまともに mysql の設定をした事がなかったので色々嵌る。


大体 [公式](https://dev.mysql.com/doc/refman/5.7/en/mysqld-multi.html) とかにかいてある事です。

## my.cnf

### 場所

mysql --help に書いてありますが忘れる。
`/etc/my.cnf /etc/mysql/my.cnf /usr/local/etc/my.cnf ~/.my.cnf`

### my.cnf

```
[mysqld_multi]
mysqld     = /usr/local/bin/mysqld_safe
mysqladmin = /usr/local/bin/mysqladmin
user       = multi_admin
password   = password
[mysqld]
[mysqld1]
server-id = 1
socket     = /tmp/mysql.sock
port       = 3306
pid-file   = /usr/local/var/mysql/my.local.pid
datadir    = /usr/local/var/mysql
user       = root
[mysqld2]
server-id = 2
socket     = /tmp/mysql.sock2
port       = 3307
pid-file   = /usr/local/var/mysql2/my.local.pid2
datadir    = /usr/local/var/mysql2
user       = root
```
`mysqld_multi --example` でサンプルが出てくる。

## mysql_install_db

で インストールした。
`/usr/local/var/mysql2` 等に ディレクトリを作成しておく。

`[WARNING] mysql_install_db is deprecated. Please consider switching to mysqld --initialize`
と言われるけど password で嵌ったのでとりえあえず `mysql_install_db` を使って調査してた。


[basedir オプションを指定しないと駄目](
https://yoku0825.blogspot.jp/2014/10/mysql-57-in-mysqlinstalldb.html)なようなので、

```shell-session
 mysql_install_db --defaults-file=/etc/my.cnf --datadir=/usr/local/var/mysql2 --basedir=/usr/local/Cellar/mysql/5.7.18
```
とかで良いのかな。。。バージョン上がったら困るので symlink の方にすべきか。

### 5.7.6 以降の挙動

mysql_install_db で root の password が ~/.mysql_secret に書かれるようになった。嵌る。

slave は mysql port=3307 の方を新しく作ったのですが、めでたくパスワードが分かったのでこちらにも何とかログインできた。

```mysqll:slave
GRANT SHUTDOWN ON *.* TO 'multi_admin'@'localhost' IDENTIFIED BY 'password';
```

で multi_admin ユーザーで shutdown できるようにしておく。

その前に初期 password を変更しないと怒られるので

```mysql:slave
ALTER USER 'root'@'localhost' IDENTIFIED BY 'password';
```
を実行する。

これで `mysqld_multi start/stop` ができるようになるのだけど、[--password オプションで password を渡さないと stop はできない](http://qiita.com/mikeda/items/efbe8c36c0f53e9941b0)ようだ。

## slave の設定

レプリケーション専用のユーザーを作る。
データの更新を防ぐ為にロックをかけておく。

```mysql:master
CREATE USER 'repl'@'localhost' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'localhost';

FLUSH TABLES WITH READ LOCK;
```
dump でスレーブにデータを入れる

```shell-session
mysqldump --all-databases --master-data -u root -p > dbdump.db
// slave に dump データを入れる
mysql -u root -S /tmp/mysql.sock2 -p < dbdump.db 
```
ロックを外す。

```mysql:master
UNLOCK TABLES;
```
slave で マスター構成の設定をして、slave をスタートする。[参考](https://dev.mysql.com/doc/refman/5.7/en/change-master-to.html)

```mysql:slave
CHANGE MASTER TO MASTER_HOST='localhost', MASTER_USER='repl', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=611;

start slave;
```
これで完了。

マスターの変更がスレーブに来ている事を確認できました。

## 参考サイト

[Mac OSXでカジュアルにreplicationしてみる](http://spring-mt.tumblr.com/post/18485897722/mac-osx%E3%81%A7%E3%82%AB%E3%82%B8%E3%83%A5%E3%82%A2%E3%83%AB%E3%81%ABreplication%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)
[Replication](https://dev.mysql.com/doc/refman/5.7/en/replication.html)
【iOS】「これはテストです」的な文言について【アプリ審査】

アプリの審査で、アプリ内に「テスト」という言葉が存在したためにリジェクトされました。

ソリューションセンターにきたメールの内容は、以下の通り。

>　2. 2 Performance: Beta Testing
To resolve this issue, please remove all references to "demo," "trial," "beta," or "test" in your app description, app icon, screenshots, previews, release notes, and binary. If you would like to conduct a beta trial for your app, you may wish to review the TestFlight Beta Testing Guide.


- デモ
- トライアル
- ベータ
- テスト

これらの単語をアプリ内においておくとリジェクトされるよというお話でした。
テスト運用はTestFlightでやれよということですね。
feed実装　フォローしているユーザーの投稿を見る。　フォロー機能続き

ここの記事は、以前書いた記事の続きです。
　以前の記事は、ユーザーをフォローする機能を書きました。
　　http://qiita.com/kitaokeita/items/59b625e0c43a62f5fe6a

今回は、フォロー機能を使って、feed機能を作ってきます

```:rb：環境
rails 5.0
ログイン機能は、deviseで作っている。
```
###フィード実装前の状態

　　　　　　   　deviseで、userモデルを作っている。パスワード以下の項目は省略



|id       |      名前  |   　メールアドレス   |
|:-----------------|------------------:|:------------------:|
| １               |           山田  |       yamada@yahoo.co.jp        |
|  ２           |           佐藤 |       satouu@gmail.com            |
|  ３             |             山本 |       yamamoto@yahoo.co.jp          |

　

本の登録するために、bookモデルを作っている。　内容は、本のタイトルと感想です。


| bookモデル      |        |     
|:-----------------|------------------:|:------------------:
| id            |      本のid       |      
|   title        |           本のタイトル |      
| content           |              本の感想　　
| user_id               |                ユーザーid |



まず最初に、投稿用のcontrollerとviewを作ります。
```
$ rails g controller Page show
```

```ruby:app/controllers/pages_controller.rb
class PagesController < ApplicationController
	 before_action :sign_in_required, only: [:show]

  def show
  	  @feed_items = current_user.feed.paginate(page: params[:page])
  end
end
```


```ruby:app/views/users/show.html.erb
<% if @feed_items.any? %>
  <ol class="books">
    <%= render @feed_items %>
  </ol>
  <%= will_paginate @feed_items %>
<% end %>
```

投稿用に```
_book.html.erbを作る。
```


```ruby:app/views/books/_book.html.erb
  <div class="container">
  <div class="row"> 
    <div class="col-xs-6 col-md-3">
        
           <p><%= book.title %></p>
           <p><%= book.content %></p>
           


    　</div>
           
  </div>
</div>


```

```ruby:app/models/user.rb
def feed
    following_ids = "SELECT following_id FROM relationships
                     WHERE follower_id = :user_id"
    Book.where("user_id IN (#{following_ids})
                     OR user_id = :user_id", user_id: id)
  end

```



参考
　https://railstutorial.jp/　１３章、１４章
UIView の画面キャプチャを png で保存する

View の画面キャプチャをとる方法はググればいくつか出て来るが、 jpg で保存してしまうと画像が劣化してしまう。
なので取得した UIImage を png に変換してから保存すれば綺麗な画像のまま保存できる。

UIView+Ex:

```swift
import UIKit

extension UIView {
    func snapshot() -> UIImage {
        UIGraphicsBeginImageContextWithOptions(bounds.size, true, 0.0)
        let context = UIGraphicsGetCurrentContext()!
        context.setShouldAntialias(false)
        layer.render(in: context)
        let image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        let png = UIImagePNGRepresentation(image)!
        let pngImage = UIImage.init(data: png)!
        return pngImage
    }
}
```


ViewController: 

```swift
    func save() {
        UIImageWriteToSavedPhotosAlbum(view.snapshot(), self, #selector(saved(_: didFinishSavingWithError: contextInfo:)), nil)
    }

    @objc private func saved(_ image: UIImage, didFinishSavingWithError error: NSError!, contextInfo: UnsafeMutableRawPointer) {
        if error != nil {
            print("error")
        } else {
            print("success")
        }
    }
```
nginxにEC-CUBE3を入れてインストーラ(install.php)が動かない場合にやったこと

## 現象

EC-CUBE3をnginxの管理下に展開してインストーラ（install.php）を呼び出すと、リダイレクトを繰り返したとかでブラウザエラーになって先に進まない。

## 原因

インストーラのURLが「/install.php/step1」とかいうキモいURLになってるためで、nginxの該当ドメインのconfで

```
 location / {
        try_files $uri $uri/ /index.php?$query_string;
 }
```

などと、PHP製webアプリにありがちなrewrite処理を書いてると、インストーラの呼び出しがindex.phpに飛ばされて動かない。

## 対策

とりあえずtry_filesの前にこう書いて回避。終わったら消す。

```
 location / {
        rewrite ^/install.php/(.*)$ /install.php?$1 last;
        try_files $uri $uri/ /index.php?$query_string;
 }
```
Tomcat の URL に | などを使っている場合は upgrade に注意すること

Tomcat 8.0.39, 8.5.7, 7.0.73 から、URL に | などが含まれる場合はエラーを吐く仕様になりました。レガシーなアプリケーションの保守に関わっていたりする場合は注意が必要です。

```java
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
	at org.apache.coyote.http11.InternalInputBuffer.parseRequestLine(InternalInputBuffer.java:189)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1000)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:745)
```


関連:
[http://stackoverflow.com/questions/41053653/tomcat-8-is-not-able-to-handle-get-request-with-in-query-parameters](http://stackoverflow.com/questions/41053653/tomcat-8-is-not-able-to-handle-get-request-with-in-query-parameters
)

テストチェック用レポジトリ
[https://github.com/takeo-asai/tomcat-invalid-character](https://github.com/takeo-asai/tomcat-invalid-character
)
elasticsearchでlocalhost以外からのアクセスを許可する方法

elasticsearch.ymlの `network.host` を `0.0.0.0` にすることで他のサーバーからでもアクセス可能になる。

```yaml:elasticsearch.yml
# ---------------------------------- Network -----------------------------------
#
# Set the bind address to a specific IP (IPv4 or IPv6):
#
network.host: 0.0.0.0
http.port: 9200
transport.host: localhost
transport.tcp.port: 9300
```

ログファイルに `node validation exception bootstrap checks failed` というエラーが出て起動できない場合は、`transport.host` と `transport.tcp.port` を上記のように指定する
CloudFormerのちょっとした落とし穴

# はじめに

同じ内容で2回もハマってしまったのでメモ。

CloudFormerで既存のAWS構成をテンプレートに落とした時、CloudFormationの構文エラーになるJSONが吐かれる事があるという話です。

# 本題
文字列の配列でなければならないプロパティーが、単一の文字列になってしまいます。

```json:CloudFormerの出力
{
    "s3policyxxxbucket": {
      "Type": "AWS::S3::BucketPolicy",
      "Properties": {
        "Bucket": {
          "Ref": "s3xxxbucket"
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Id": "Policy-xxx",
          "Statement": [
            {
              "Sid": "xxxxxxxxxxxx",
              "Effect": "Allow",
              "Principal": "*",
              "Action": "s3:GetObject",
              "Resource": "<省略>",
              "Condition": {
                "IpAddress": {
                  "aws:SourceIp": "0.0.0.0/0"
                }
              }
            }
          ]
        }
      }
    }
}
```

上記の```"Action": "s3:GetObject"```が問題で、正しくは```"Action": [ "s3:GetObject" ]```です。

# 最後に
CloudFormerで既存のAWS構成をテンプレートに落とすことが出来るのは便利ですが、それを使う時にはちょっと注意が必要ですね。

それと、CloudFormationのエラー出力がもう少し情報を出してくれれば..と思います。今回も```Invalid Resource ...```ぐらいしか言ってくれなかったので、他の箇所を疑ってしまい、解決するまでに時間を浪費しました。

とは言え、CloudFormerの出力はそのまま使うなと公式にも注意書きしてあった気がするので、よく確認しなかった自分が悪いのですが。
Chrome開発者コンソールに"Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app)."


# 環境
MacBookPro Siera 10.12.3
Chrome 57.0.2987.133
npm 4.2.0
node 7.9.0
firebase": 3.7.4
vue-cli webpackで作った環境

# 現象
firebaseホスティングを使ったWebサイトを作成していて、Chromeの開発者ツール＞コンソールに以下のエラーが出ていた。

```
code: "app/duplicate-app", message: "Firebase: Firebase App named '[DEFAULT]' already exists (app/duplicate-app).", name: "[DEFAULT]", stack: "FirebaseError: Firebase: Firebase App named '[DEFA… [as apply] (http://localhost:8080/app.js:592:14)"}

```

サイトの動作には特に影響はなし。

## 原因
```firebase.initializeApp```が複数回呼ばれているらしい。
でも自分のソースでは１箇所でしか使用していないんだが…。
ああ、キャッシュにでも残って悪さしているのかな？

# 解決方法
キャッシュ消去でエラーメッセージは出なくなった。

### キャッシュ消去手順
1. Chromeで開発者ツール起動
2. 更新ボタン長押し
3. キャッシュの削除とハード再読み込みを押す

消去参考URL
https://superuser.com/questions/220179/how-can-i-do-a-cache-refresh-in-google-chrome?answertab=votes#tab-top
Valet の config の置き場所


Mac OS で軽快なウェブサーバーを構築できる [Valet](https://laravel.com/docs/5.4/valet) の Config 場所を探す必要があったので、探してみました。

Homebrew で普通にインストールされたことを前提にしています。


# Valet 2.18.x の Config の置き場所

ユーザーごとの保存場所が 2.2 ぐらいで移動しました。2.18.10 時点でもかわっていません。

## 大元の保存場所

```
/usr/local/etc/nginx/*
/usr/local/etc/php/*
```

## ユーザーごとの保存場所

```
~/.config/valet/*
```


## Valet 用 Nginx の大元の保存場所

```
/usr/local/etc/nginx/valet/*
```

## ログ保存場所

Nginx アクセスログはデフォルトでは保存されないようになっています。

```
/Users/[ユーザー名]/.config/valet/Log/nginx-error.log
```

# MariaDB & MySQL の置き場所

## Config

```
/usr/local/etc/my.cnf
```

## データ

```
/usr/local/var/mysql
```

# PHP設定の置き場所

```
/usr/local/php/[バージョン]/*
```

# [おまけ] バイナリファイルの置き場所

```
/usr/local/*
/usr/local/Cellar/*
```



# Valet 2.0 以前 の config の置き場所

## ユーザーごとの保存場所

```
~/.valet/Nginx/*
```



# 関連記事

- [Mac のミニマムな Web サーバー Valet 超簡単メモ](http://qiita.com/katzueno/items/49ca8ca2eefbe0a61b63)
- [Laravel/Valet 2.0 のアップグレードでハマったのでメモ](http://qiita.com/katzueno/items/4e7a65bcab18aa2b2f23)



# クレジット

この記事が役に立ったら、「 **CMS は concrete5 が一番**」と頭の中で10回唱えてみてください〜。
proxy下でのpipコマンドの実行(備忘録)


proxy環境のもとでpipコマンド(例えばinstall, search等)を実行しようとしてもエラーが出て実行できない。

既に、いろいろな方が同様の記事を書いているが、そのどれを試してもうまく行かなかったので、私の環境下(iMac OSX Yosemite Python3.6)で動作した方法をメモ。

pipのコマンドには`--proxy=user:pass@proxy:port`でプロキシ設定を行うことができるが、これは動作しなかった。

つぎに、環境変数に直接設定してやる方法

```
export http_proxy="user:pass@proxy:port"
export https_proxy=$http_proxy
export ALL_proxy=$http_proxy

```

を実行してもうまく動作しなかった。

しかし、同様の作業を別のPC(MacbookPro OSX Marvericks Python3.5)で試すと、動作した。

ここでおかしいと思い、Python上でうまくproxyが通っているか、確認した。

```python:commandlineでPythonを呼び出して
import urllib.request
urllib.request.getproxies()
```

上記のコマンドを実行して確認すると、何故か

`{'http':'"user:pass@proxy:port"','https':'"user:pass@proxy:port"','all':'"user:pass@proxy:port"'}
`

となっていた。

ここで`export http_proxy="user:pass@proxy:port"`のダブルクォーテーションを外し、`export http_proxy=user:pass@proxy:port`とすると、pipのコマンドが正常に動作した。



後日同様の作業を実行すると、ダブルクォーテーション込でも正常に動作した。
なぜ？
文字を中央寄せで表示するスクリプト

motdやdotfilesインストールスクリプトのおともにどうぞ。

# 中央寄せ①

```bash
text_center() {
  local columns=$(tput cols)
  local line=
  if [ -p /dev/stdin ]; then
    while IFS= read -r line || [ -n "$line" ]; do
      printf "%*s\n" $(( (${#line} + columns) / 2)) "$line"
    done < /dev/stdin
  else
    line="$@"
    printf "%*s\n" $(( (${#line} + columns) / 2)) "$line"
  fi
}
```

使い方。

```bash
text_center hoge
echo hoge | text_center
```

# 中央寄せ②(figlet用)

もっといい書き方がある気はします…。

```bash
max_length() {
  local length=
  local max_length=0
  local line=
  if [ -p /dev/stdin ]; then
    while IFS= read -r line || [ -n "$line" ]; do
      length=${#line}
      if [ $length -gt $max_length ]; then
        max_length=$length
      fi
    done < /dev/stdin
    echo $max_length
  else
    line="$@"
    echo ${#line}
  fi
}

with_indent() {
  local length="$1"
  local line=
  local indent=
  local i=
  for ((i=0; i < length; i++)); do
    indent="$indent "
  done
  if [ -p /dev/stdin ]; then
    while IFS= read -r line || [ -n "$line" ]; do
      echo "${indent}${line}"
    done < /dev/stdin
  else
    shift
    line="$@"
    echo "${indent}${#line}"
  fi
}

display_center() {
  local columns=$(tput cols)
  local length=$(echo "$@" | max_length)
  echo "$@" | with_indent "$(((columns - length) / 2))"
}
```

使い方。

```bash
cyan="^[[036m"
default="^[[0m"
echo "${cyan}$(display_center "$(hostname | figlet)")${default}"
```
VagrantでRuby on Rails5.Xの開発環境を構築・インストールする

今回は、Vagrantを利用してMacのローカルに仮想マシンを立て、そこにRuby on Railsの開発環境を構築・インストールしていきます。その開発環境で作成したプロジェクトをローカルで動かすところまでの手順をご案内をします。

| 項目       　　　　  |       バージョン　  |
|:-------------------|------------------:|
| macOS              |    Sierra 10.12.4 |
| ruby               |      2.3.4        |
| rails              |      5.0.2        |
| VirtualBox   | 5.1.18 platform packages |
| Vagrant            |1.9.3

#1、事前準備：仮想マシン作成
Vagrantを利用するためには、VirtualBoxが必要になります。そのため、VirtualBoxとVagrantの両方をインストールしていきます。
 
##1-1、VirtualBoxのインストール
<a href="https://www.virtualbox.org/">VirtualBox</a>を各自の環境に合わせてダウンロードします。
今回は、Macを利用しているので、OS Xをダウンロードします。

##1-2、Vagrantのインストール
<a href="https://www.vagrantup.com/">Vagrant</a>を各自の環境に合わせてダウンロードします。
今回は、Macを利用しているので、Mac OS XのUniversal (32 and 64-bit)をダウンロードします。
  
##1-3、仮想マシンの取得
今回は、CentOS7のBoxを選んでBoxListに追加します。

```
$ vagrant box add centos7 https://github.com/tommy-muehle/puppet-vagrant-boxes/releases/download/1.1.0/centos-7.0-x86_64.box
```

なお、追加したBoxは下記コマンドで一覧を確認できます。

```
$ vagrant box list
```

##1-4、仮想マシンの作成・設定
追加したBoxから仮想マシンを作成・設定します。

```
$ vagrant init centos7
```

仮想マシンを作成すると、そのディレクトリに下記ファイルが生成されるので、ローカルで動作させる場合は下記の通り編集します。

```
$ vi Vagrantfile
```

今回の編集箇所は25行目付近です。
下記設定箇所のコメントアウトを外し、下記の通り、guestとhostを3000に設定します。

```ruby:Vagrantfile
 config.vm.network "forwarded_port", guest: 3000, host: 3000
```

この設定により、仮想マシンで作成したプロジェクトを動作させることができます。

#2、ruby on railsの環境構築
ここからは、作成した仮想マシンにログインし、そこでRuby on Railsでプロジェクトを作成するための開発環境を構築・インストールしていきます。

##2-1、仮想マシンにログイン
boxを作成したディレクトリで下記コマンドを実行し、仮想マシンにログインします。

```
$ vagrant ssh
```

##2-2、開発環境構築の準備
作成した仮想マシンにはすでにRubyがインストールされていますが、バージョンが古いので削除をします。その後、yumのパッケージをアップデートします。

```
$ ruby -v
$ sudo yum -y remove ruby
$ sudo yum update
$ sudo systemctl stop firewalld
$ sudo systemctl mask firewalld 
```

AWS EC2（Amazon Linux）の場合、下記パッケージもインストールする必要があります。

```
$ sudo yum install git gcc openssl-devel
```


##2-3、rbenvリポジトリをcloneする
rbenvリポジトリをgitでcloneします。そのため、まずは先にgitをインストールします。

```
$ sudo yum -y install git
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
```

rbenvリポジトリをcoloneしたら、PATHを通し、ターミナル(bash)実行時に rbenv init を実行するように設定します。

```
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ cat ~/.bash_profile
$ source ~/.bash_profile
```

なお、rbenvのバージョンは下記コマンドを実行することで確認できます。

```
$ rbenv --version
```

##2-4、Rubyのインストール
rbenvを利用してRubyをインストールしますが、その際に異なるバージョンのRubyをコンパイルしインストールするためのrbenvのプラグインであるruby-buildを先にインストールします。

```
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
```

インストールできるバージョンが下記コマンドを実行することで一覧で表示されます。今回は、最新のバージョンをインストールします。

```
$ rbenv install -l
$ rbenv install 2.3.4
$ rbenv global 2.3.4
```

##2-5、Railsのインストール

バンドラーをインストール後、Railsをインストールします。
今回は最新バージョンのRailsをインストールします。

```
$ rbenv exec gem install bundler
$ rbenv rehash
$ gem search -r rails | grep "^rails ("
$ gem install rails
```

##2-6、プロジェクトの作成と起動

下記コマンドを実行することで、新しいアプリケーションが作成され、動作します。

http://localhost:3000/
にアクセスするとRuby on Railsのデフォルトのトップページが確認できます。

```
$ rails new cat
$ bundle exec rails server -b 0.0.0.0
```
PHP セッションのシリアライズ方式と他言語からの読み取り

## 1. PHP セッションのシリアライズ形式

PHP セッションのシリアライズ形式には、以下のようなものがあり、`ini_set()` で指定できます。

* php（デフォルト）
* php_serialize
* wddx

http://php.net/manual/ja/session.configuration.php#ini.session.serialize-handler

### 1-1. php と php_serialize

`php` と `php_serialize` が紛らわしいのですが、これらは別ものです。

下記のようなコードで、セッションを保存するとその違いが分かります。

```php
<?php
ini_set('session.serialize_handler', 'php');
//ini_set('session.serialize_handler', 'php_serialize');

class Foo
{
  private $name = 'Mike';
}

session_start();

$_SESSION = [
  'int' => 1,
  'float' => 1.23,
  'bool' => true,
  'string' => 'hoge',
  'array' => [1, 2, 3],
  'object' => new Foo(),
];

var_dump($_SESSION);
```

* php

```
int|i:1;float|d:1.23;bool|b:1;string|s:4:"hoge";array|a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}object|O:3:"Foo":1:{s:9:"Fooname";s:4:"Mike";}
```

* php_serialize

```
a:6:{s:3:"int";i:1;s:5:"float";d:1.23;s:4:"bool";b:1;s:6:"string";s:4:"hoge";s:5:"array";a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}s:6:"object";O:3:"Foo":1:{s:9:"Fooname";s:4:"Mike";}}
````

`php_serialize` は、serialize 関数の出力と同じになります。
http://php.net/serialize

## 2. 他言語からの読み取り

PHP 以外の言語から、PHP セッションを読むには、大きく分けて 3 つの方法が考えられます。

### 2-1. PHP セッションを直接読む

いくつかの言語で、PHP セッションデータを読み書きするライブラリが公開されているので、これらを利用します。ライブラリによって、対応しているシリアライズ形式が異なるので注意する必要があります。

例えば、 golang で、PHP セッションを読み書きする `php_session_decoder` は、`php` を前提としています。
https://github.com/yvasiyarov/php_session_decoder
（なお、このリポジトリには serialize 関数形式が読めるコードも含まれています）

一方、node.js で、PHP の serialize 関数形式のデータを読み書きする `PHP-Serialize` を利用してセッションデータを読むなら、`php_serialize` を指定する必要があります。
https://github.com/steelbrain/php-serialize

連携する際は、利用するライブラリに応じて、PHP セッションのシリアライズハンドラを変えるか、指定されたシリアライズ形式に対応したライブラリを選択することになります。

### 2-2. 汎用シリアライズ形式を利用する

汎用のシリアライズ形式であれば、各言語で実装があるので、PHP でもこれを利用する方法です。

PHP で、冒頭に上げた形式以外を利用するには、独自のセッションハンドラを利用するか、専用の PHP 拡張をインストールすることになります。前者は、実装のやり方次第でどうにでもできるので、ここでは、後者について示します。

汎用のシリアライズ形式といえば、JSON が思い浮かびますが、PHP にはセッションシリアライズについては対応する拡張がありません。[^1]

そこで考えられるのは、 MessagePack です。MessagePack であれば、各言語の実装がありますし、圧縮率や処理効率も期待できます。

MessagePack 拡張
https://github.com/msgpack/msgpack-php

### 2-3. PHP でセッションデータを出力する API を実装
 
別の方法としては、PHP 側でセッションデータを、例えば JSON に変換して出力する API を実装し、これを別システムから読むという方法もあります。

例えば、セッション ID をパラメータとして受け取り、セッションデータを JSON で出力するイメージですね。

```bash
$ curl -X POST -F "session_id=hoge"  http://example.com/api/session2json.php


"json"
```

直接セッションストレージにアクセスするより、オーバーヘッドはありますが、別システム側からは、単に HTTP で JSON を取得するだけなので、実装も簡単です。

もちろん、この API は外部に公開するものではない（してはいけない）ので、内部だけで利用するように注意しましょう。

[^1]: 以前あったような気がしますけど、見つけられませんでした...
rust in docker で cargo build に失敗するときの対処法


こんな感じのエラーが出る

```bash
root@59a819b944e6:/source# cargo build --verbose
    Updating registry `https://github.com/rust-lang/crates.io-index`
error: failed to load source for a dependency on `rand`

Caused by:
  Unable to update registry https://github.com/rust-lang/crates.io-index

Caused by:
  failed to fetch `https://github.com/rust-lang/crates.io-index`

Caused by:
  [16/-17] The SSL certificate is invalid
```

そんなときは

```bash
export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
```

を設定すると解決します
Python / dictionary > setdefault() > 辞書になかったら追加する

@ Introducing Python: Modern Computing in Simple Packages by Bill Lubanovic
(No. 3118 / 12833)
Handle Missing Keys with setdefault() and defaultdict()

> The setdefault() function is like get(), but also assigns an item to the dictionary if the key is missing:

試してみた。

http://ideone.com/N2bmsU

```
away_team = { 'Tuvok': 1, "B'Elanna" : 2 }
print(away_team)
seven = away_team.setdefault("7of9", 3)
print(away_team)
print(seven)
```

```txt:run
{"B'Elanna": 2, 'Tuvok': 1}
{"B'Elanna": 2, 'Tuvok': 1, '7of9': 3}
3
```