OmniAICreator/Qiita-1.07M huggingface dataset:
【その２】Python で headless-chrome でのスクレイピング（Google Cloud SQL / Google Storage 構築編）

# はじめに
- headless-chrome を GoogleCloudPlatform (GoogleAppEngine) 上で稼働し、Python で WEB スクレイピングをした結果を CloudSQL と CloudStorage に登録することをゴールとします。

- はじめる前に、以下が作業が必要となります
 - [【その１】Python で headless-chrome でのスクレイピング（Docker Hub / Google CONTAINER REGISTER 登録編）](https://qiita.com/kojipon/items/e5686c1412a69905e4bf)

# Google Cloud SQL 構築

- GCP メニューより SQL を選択

<img width="409" alt="スクリーンショット 2017-11-21 14.30.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/44348/6e792915-4812-4cb6-f17d-e65bb444fcc7.png">

- データベースエンジンは「MySQL」を選択し、「次へ」ボタンを押下

<img width="337" alt="スクリーンショット 2017-11-21 14.30.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/44348/b2bed777-3242-b50a-758a-c534844ffa0c.png">

- インスタンスとして「第２世代を選択」ボタンを押下。

<img width="416" alt="スクリーンショット 2017-11-21 14.30.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/44348/de0e7b9f-7e7f-a3e2-403c-77be70eacb5a.png">

- インスタンスIDを入力し、「選択」ボタンを押下。マシンタイプも選択することができます。

<img width="413" alt="スクリーンショット 2017-11-21 14.33.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/44348/b71320a0-efc1-586b-d09c-23c183b36de3.png">

- マシンタイプについて
  - 共有コアマシンだと、Cloud SQL SLA の対象範囲外となるようです（https://cloud.google.com/sql/sla）
  - マシンスペックは以下の通りです。

|カテゴリ|マシン名|CPU|メモリ|
|:----------|:----------|:----------|:----------|
|共有コアマシン|db-f1-micro|1vCPU|614.4 MB|
||db-g1-small|1vCPU|1.7 GB|
|標準マシン|db-n1-standard-1|1vCPU|3.75 GB|
||db-n1-standard-2|2vCPU|7.5 GB|
||db-n1-standard-4|4vCPU|15 GB|
||db-n1-standard-8|8vCPU|30 GB|
||db-n1-standard-16|16vCPU|60 GB| 
||db-n1-standard-32|32vCPU|120 GB| 
||db-n1-standard-64|64vCPU|240 GB| 
|ハイメモリマシン|db-n1-highmem-2|2vCPU|13 GB| 
||db-n1-highmem-4|4vCPU|26 GB| 
||db-n1-highmem-8|8vCPU|52 GB| 
||db-n1-highmem-16|16vCPU|104 GB| 
||db-n1-highmem-32|32vCPU|208 GB| 
||db-n1-highmem-64|64vCPU|416 GB|

# Google Cloud Storage 構築

- GCP メニューより「Storage」の「ブラウザ」を選択

<img width="376" alt="スクリーンショット 2017-11-21 15.45.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/44348/91d2aba6-fe4c-8cfe-87e0-235046b8bc3c.png">

- 「バケットの作成」を押下し「作成」ボタンを押下

<img width="495" alt="スクリーンショット 2017-11-21 15.55.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/44348/c92f5302-b1be-59ee-a457-9942284dcf7f.png">

- 完成

<img width="884" alt="スクリーンショット 2017-11-21 16.09.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/44348/38c2046f-7ffa-d329-ad7c-ebf17bb5cf19.png">
Laravel4までのBladeでエスケープしつつデータ表示は波括弧三重{{{}}}。PhpStormには設定書き換えが必要

# `{{}}`ですべてエスケープされるのは5から

久々にBladeテンプレートを見直して、構文などを忘れたので公式で確認してました。

[Bladeテンプレート 5.1 Laravel]

>注意： Bladeの{{ }}文は自動的にPHPのhtmlentities関数を通し、XSS攻撃を防ぎます。

流石にテンプレート構文の書き方はそうそう変わらないだろうと5のマニュアルを読んでいて、そう言えばコードに

```php
// e()はhtmlentities()のラッパー
{{ e('あぶないchara') }}
```

という記述が散見されていたのを思い出し、そうか(安全側に倒しているけど)無駄だったかと外していったら


```php
{{ 'またまたあぶないchara' }}
```

見事に表示が崩れた。

慌てて調べたら、実装はこうなっていた。

```php
class Blade {
	/**
	 * Rewrites Blade echo statements into PHP echo statements.
	 *
	 * @param  string  $value
	 * @return string
	 */
	protected static function compile_echos($value)
	{
		$value = preg_replace('/\{\{\{(.+?)\}\}\}/', '<?php echo HTML::entities($1); ?>', $value);

		return preg_replace('/\{\{(.+?)\}\}/', '<?php echo $1; ?>', $value);
	}
}
```

ぱっと見、正規表現が見づらいので、ちゃんとエスケープしているなと思ったが、2回置換している不自然さによく見ると2重と3重で処理が分かれていた。

webでも調べなおして5から変わったとのこと。

[Laravel5(Blade)のViewで改行させたいだけなのに少し悩んだ - Qiita]

[Laravelのbladeってやつをまとめてみた]

(便利そうなの増えてる…)

***

直接は関係ないが、5では`e()`にも変更が入った
[Laravel の Blade で {{ と }} に囲まれたものは全てエスケープされるわけじゃない - 頭ん中]

***

ちゃんと今使っているバージョンのドキュメントを、(探すのも非常に辛いですが)探しましょうという真っ当な結論です。

# PHPStormではBladeテンプレート対応

`{{e()}}`と`{{{}}}`では文字数にして1文字の削減。
せっかくある機能を使わないのもなんですし、三重に置き換えようとしました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/62354/75917ef8-7152-1adc-a692-255be8e512cb.png)


そうですよね。サポートするなら5の記法ですよね。
が、一応設定画面でold versionの対応してくれていないか見てみました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/62354/21d76d0f-5b8b-23c0-ed60-966bd0763a8d.png)

ありました。

ネットにもありました。

[Laravel 4 Blade markup and Ide Helper in PhpStorm - Stack Overflow]

私のバージョンが古いのか、Content tagsとEscaped tagsの記述が逆ですね…
Stack Overflowの組み合わせが正しい気がしますが、自信がない…。
Raw Tagsは不明。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/62354/7b81c202-ce07-f9a1-a349-e7b25726c27f.png)


バージョンよる違いがあるかもしれませんので、ひとまず既存の設定の場所のまま古い記法に書き換えます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/62354/4042e6e5-3389-789b-e3e9-715c9ed6d73b.png)

エラーも解消されました。

[Laravel 4 Blade markup and Ide Helper in PhpStorm - Stack Overflow]:https://stackoverflow.com/questions/18638253/laravel-4-blade-markup-and-ide-helper-in-phpstorm

[Laravelのbladeってやつをまとめてみた]:https://ogatism.jp/techs/laravel_blade/

[Laravel の Blade で {{ と }} に囲まれたものは全てエスケープされるわけじゃない - 頭ん中]:http://www.msng.info/archives/2016/01/laravel-blade-braces-dont-always-escape.php

[Laravel5(Blade)のViewで改行させたいだけなのに少し悩んだ - Qiita]:https://qiita.com/noratmt/items/f5dee008ba8138ce6c22


[Bladeテンプレート 5.1 Laravel]:https://readouble.com/laravel/5.1/ja/blade.html#displaying-data
Cocos2d-xで使えるプログラム[plist]

#はじめに
plistは何かの説明は他の方々が書いているのでここでは書かない
何に使えてどう扱うのか書いていく

#使用用途
- セーブデータ
- アイテムやモンスターなどのデータ

主にデータの保存に使う
CSVにするかplistにするかJSONにするかの違い

#使い方-読み込み-
以下のようなplistがあるとする

|playerNo|name  |coin |last      |
|:------:|:-----|----:|----------|
| 1      |708QBT|20   |2017/11/15|
| 2      | SIDE |500  |2017/10/20|
| 3      |RENDER|10000|2017/08/03|

```cpp:Sample.cpp
void Sample::loadPlist(){
    //plistファイルの読み込み
    ValueVector plistData = FileUtils::getInstance()->getValueVectorFromFile("sample.plist");
    
    //plistの行を一行ごとに読み込む
    for (auto itr : plistData){
        ValueMap dic = itr.asValueMap();
        
        int player = dic.at("playerNo").asInt();
        std::string name = dic.at("name").asString();
        int coin = dic.at("coin").asInt();
        std::string last = dic.at("last").asString();
        
    }
}
```

#おまけ

```cpp:Sample.cpp
void Sample::loadPlist(){
    //plistファイルの読み込み
    ValueVector plistData = FileUtils::getInstance()->getValueVectorFromFile("sample.plist");
    
    //Enemyクラスを格納できるvector作成
    //Enemyクラスは自作してください
    std::vector<Enemy*> enemyList;

    //plistの行を一行ごとに読み込む
    for (auto itr : plistData){
        ValueMap dic = itr.asValueMap();
        
        int player = dic.at("playerNo").asInt();
        std::string name = dic.at("name").asString();
        int coin = dic.at("coin").asInt();
        std::string last = dic.at("last").asString();
        
        //一行ごとにEnemyを作る
        Enemy* enemy = Enemy::create(player, name, coin, last);
        this->addChild(enemy);

        //enemyListにenemyを登録
        enemyList.push_back(enemy);
    }

    //enemyListの中身を頭から読み込む
    for (auto itr = enemyList.begin(); itr != enemyList.end(); itr++) {
        Enemy* enemy = (Enemy*)(*itr);
        //enemyを動かすならmove関数作って動かせばいい
       
    }
}
```

ステージごとに敵のデータを一気に読み込んで画面外に待機させ、時間経過とともに動かせばゲームっぽくなる

#使い方-書き込み-
```cpp:Sample.cpp
void Sample::savePlist(){
    //データを保存するために格納するValueVectorを作成
    ValueVector saveData;

    //書き込みたいデータを作成
    ValueMap data1;
    data1["id"] = 1;
    data1["name"] = "tarou";
    data1["age"] = 14;

    saveData.push_back(Value(data1));

    ValueMap data2;
    data2["id"] = 2;
    data2["name"] = "oyaji";
    data2["age"] = 42;

    saveData.push_back(Value(data2));

    //パスを指定して書き込む
    std::string path = FileUtils::getInstance()->getWritablePath() + "save.plist";
    
    if (FileUtils::getInstance()->writeValueVectorToFile(saveData, path)){
        //書込み成功時の処理
    }
}
```

読み込みと書き込みをすればセーブデータとなる
ただ、plistはテキストファイルとして開くことができ、改竄出来る
改竄出来ない、させない工夫が必要である

#次回
そのうち考える
JenkinsでAndroidのSDKをpreview版に更新したいときの対処法

## やりたいこと
- preview版のSDKをJenkinsでビルドしたい
 - 2017/11/21 現在最新のSDKのバージョンは26（Android 8.0）
 - 使いたいSDKは27（Androi 8.1 preview）

## 通常のSDKの更新
SDKの定期的な更新とかは以下のリンクのような感じでやればとくに問題なく使えると思います。
[JenkinsでAndroid SDKを更新する](http://qiita.com/mattak/items/50fb72b586390a137d24)

しかし、preview版のSDKを使いたい場合この方法ではpreview版のSDKに更新することができず

```
 You have not accepted the license agreements of the following SDK components:
  [Android SDK Build-Tools 27].
  Before building your project, you need to accept the license agreements and complete the installation of the missing components using the Android Studio SDK Manager.
  Alternatively, to learn how to transfer the license agreements from one workstation to another, go to http://d.android.com/r/studio-ui/export-licenses.html
```

という感じでビルドに失敗してしまいます。

## 対処法
こういうときは自分のローカル `~/Library/Android/sdk/licenses/` 以下のファイルをJenkinsの同じところにコピーして置き換えてあげる。

そうすることでJenkinsのほうでもビルドできるようになります。
Docker 備忘録

# 用語
|用語|説明|
|:-----------|:------------|
|コンテナ|アプリケーションを実行するためのアプリケーションの仮想空間。コンテナに並び、ホスト型（例：VMWare）・ハイパーバイザー型（例：KVM）のスキームがある|
|Docker|ソフトウェアコンテナ内のアプリケーションのデプロイメントを自動化するオープンソースソフトウェア。([引用：Wikipedia](https://ja.wikipedia.org/wiki/Docker))|
|Kubernetes（クーべネテス）|Docker をクラスタ環境でも使えるようにしてくれるオープンソースソフトウェア|
|Pod|Kubernetes で扱う単位。複数のコンテナからなるグループ|

# docker コマンド
| コマンド       | 説明 |コマンド例|
|:-----------------|:------------------|:------------------|
| docker pull [REPOSITORY]|イメージの取得|docker pull python:3|
| docker images|イメージの一覧出力||
| docker run -it --name [CONTAINER_NAME] [IMAGE_NAME] bash |イメージからコンテナを作成し接続|docker run -it --name python-dev1 python bash|
| docker start [CONTAINER_NAME] |コンテナの起動|docker start python-dev1|
| docker attach [CONTAINER_NAME] |コンテナへの接続|docker attach python-dev1|
| docker container list |コンテナの一覧取得||
| docker container list -a|(停止中のものも含めた)コンテナの一覧取得||
| docker rm [CONTAINER_NAME] |コンテナの削除|docker rm python-dev1|
| docker rm $(docker ps -aq) |コンテナの全削除||
| docker rmi [CONTAINER_NAME] |イメージの削除|docker rm python|
| docker rmi $(docker ps -aq) |イメージの全削除||
Jestが動かないときの対処法

`jest`コマンドが動かなくて、おかしいな〜と思ってたら`watchman`を入れてるのが原因らしく、消したら動いた。

```shell
$ brew uninstall watchman
```

参考：https://github.com/facebook/jest/issues/2219#issuecomment-265296329
受託でやるのに程よいベストなGitのフローを考える

# はじめに
事業会社で取り入れているフローなんかを見ると「細かくてすごいな〜」と思いつつ、受託でやるには現実的に厳しいと思ったり…

しかしながら、フローを疎かにし過ぎると色々なリスクが生じることも…

**「程よい」**のレベル感は人それぞれ・案件によっても違うと思いますが、この投稿では間を取って多くの人が**「まぁこれで事足りるよね」**って言うようなものを作りたいと思ってます。

まずは、筆者がベースとなるフローを考察するので、その後みなさんの意見を取り入れてつつブラッシュアップしていければと考えてます！

# 前提
## リモートリポジトリの場所
- Backlog

フローが大きく変わる訳ではありませんが、一旦はBacklog想定にします。

## 想定されるリスク
- デグレしてしまう
- 最新ファイルの在りかが分からなくなる

よく起こるであろうこの辺りをリスクヘッジ出来るフローにしていこうと思います。

## サーバ環境
- 本番環境
- ステージング環境
- 開発環境

想定されるリスクを回避するために、最低限この３つの環境がある想定にします。

## CMS
導入していない想定にします。

# ルール系
## ブランチ
### master
- 本番公開用のブランチ
- このブランチから本番環境にファイルをアップ
- 基本的には、本番環境とファイルがイコールになっていること

### release
- ステージング公開用のブランチ
- このブランチからステージング環境にファイルをアップ
- 基本的には、ステージング環境とファイルがイコールになっていること

### 作業ブランチ（課題番号_作成者名）
- 作業を行うためのブランチ
- このブランチから開発環境にファイルをアップ
- 基本的には、1チケット1ブランチになっていること

## コミット
ここがいくらでも細かく出来てしまう項目なので、難しいところです…

筆者の個人的な意見としては、コミットの粒度はある程度各自に任せつつ、
メッセージには最低限何をしたか分かるように書いてくれれば良いかな〜と思ってます。

※内容は細かいほど良い

## プルリクエスト
- 詳細：何の作業をしたか分かるように記載し、更新したURLも合わせて記載すること
- 担当者：マージ承認者（レビュアー）を設定すること
- 「ファイル」タブを選択し、作業したファイルに誤りが無いかを確認すること

※マージ承認者は、予め担当者を決めておく

# Gitのフロー
1. masterをプル（最新の状態にする）
2. masterから作業ブランチを作成
3. 作業ブランチにて開発
    - ※ステージング環境・本番環境には勝手にアップしないこと
4. ファイルをプッシュ
5. 作業が完了したものは、作業ブランチ→releaseへのプルリクエストを作成
6. releaseにマージされたものをステージング環境にアップ
7. 公開OKとなったものは、release→masterにプルリクエストを作成
8. masterにマージされたものを本番環境にアップ
9. 最終承認が取れた後、作業ブランチを削除

releaseにマージされたいくつかの作業のうち先に１つだけ公開したい場合などは、作業ブランチ→masterへのプルリクエストを作成を許容とする。

※実際はもっといい方法がないかな〜とモヤモヤしているところ…

## コンフリクトが起きた場合
マージ承認者や先にマージした人と内容を確認しながら解決すること。

## 軽微な対応の場合
ここは決めの問題だが、「一箇所テキストを修正するだけ」といったすごく軽微な対応の場合、マージ承認者を介さず自らマージしてOKといったルールは適宜決めていく。

# まとめ
とりあえずは細かくなりすぎず…かと言って疎かにならないようなフローにまとめてみましたが、まだまだ改善の余地はあるんだろうな〜と思ってます。

ぜひ、みなさんの知恵をお貸しいただけると…！
Redmine > Install > トラブルシュート > チケット作成・編集が遅い


# 新規構築直後のチケット作成・編集が遅い

新規構築後のチケット作成に1分くらいかかる現象が発生

調べたら以下のページでSMTPが原因ではないかとの事
[Redmine のチケット作成が遅かった件: とりあえず](http://fukamit.air-nifty.com/blog/2013/04/r.html)



redmine/htdocs/config/configuration.ymlを見ると確かに、gmailのSMTPになっていました。

```rb
  email_delivery:
    delivery_method: :smtp
    smtp_settings:
      address: smtp.gmail.com
      port: 587
      domain: example.net
      authentication: :login
      user_name: 
      password: 
```

ということで、正しいSMTPサーバーを設定したらチケット作成は速くなりました。
【ruby】p pp puts print　違い。


## 書く前のイメージ・・・

p putsよりなんかいい
pp pをよくしてくれるらしい（使ったことはない）
puts 改行する
print 改行しない

ちょっとひどいですね

## 調べました。

### p
引数のオブジェクトをわかりやすく標準出力に出力。
デバッグ用です

### pp

> オブジェクトなどを見やすく出力するためのライブラリです。
pp ライブラリは、ユーザがあたらしく定義したクラスに対しても見やすい表示をするように作られていますので、Kernel.#pp を使う上で余計な作業をする必要はありません。

https://docs.ruby-lang.org/ja/latest/library/pp.html

pretty printの略とのこと。
pと同じくデバッグ用です

### puts
引数のオブジェクトを文字列に変換し、改行を加えて標準出力に出力。
to_sメソッドで文字列に変換される。


### print
引数のオブジェクトを文字列に変換し、標準出力に出力。
to_sメソッドで文字列に変換される。
改行はされない。

参考
https://ref.xaio.jp/ruby/classes/kernel
https://docs.ruby-lang.org/ja/latest/library/pp.html


## 使ってみました

```
require "pp"

str = "string"
p str
# "string"
pp str
# "string"
print str
# string
puts str
# string

list = [1,"str",[1,2]]
p list
# [1, "str", [1, 2]]
pp list
# [1, "str", [1, 2]]
print "print=>"
# [1, "str", [1, 2]]
print list
# [1, "str", [1, 2]]
puts list
# 1
# str
# 1
# 2

hash = profile = {"last_name" => "tanaka",
           'first_name' => "takuya",
           'addres' => 'Tokyo',
           'old' => 22,
           'height' => 176,
           "weight" => 63}
p hash
# {"last_name"=>"tanaka", "first_name"=>"takuya", "addres"=>"Tokyo", "old"=>22, "height"=>176, "weight"=>63}
pp hash
# {"last_name"=>"tanaka",
 "first_name"=>"takuya",
 "addres"=>"Tokyo",
 "old"=>22,
 "height"=>176,
 "weight"=>63}
print hash
# {"last_name"=>"tanaka", "first_name"=>"takuya", "addres"=>"Tokyo", "old"=>22, "height"=>176, "weight"=>63}
puts hash
# {"last_name"=>"tanaka", "first_name"=>"takuya", "addres"=>"Tokyo", "old"=>22, "height"=>176, "weight"=>63}
```


### 感想

- ppでhashがかなり見やすくなる。巨大なデータを扱うときに使いたい。
- putsはarrayのカッコ記法を消し、要素ごとに改行して出力するため、配列のデバッグには向いていないです。
Spring-security+Jetty+ELBでSSLオフロード(SSL終端)

# やりたいこと

ユーザのブラウザからELBまではhttpsで通信、ELBからアプリケーションサーバまではhttpで通信させる
→ これを[Wikipedia - SSLオフロード](https://ja.wikipedia.org/wiki/SSL%E3%82%AA%E3%83%95%E3%83%AD%E3%83%BC%E3%83%89), [英語版  TLS termination proxy](https://en.wikipedia.org/wiki/TLS_termination_proxy)と言う。Rails, ngnix, ELBでやったことはあったけど、Springではやったことない。そしてできればHttpsを強制させたい。

* Spring-security側の設定については以下のブログポストが詳しい
    * [ELB と Spring Security の RequiresChannelUrl#requiresSecure](https://blog.tagbangers.co.jp/2014/10/19/elb-spring-security-requires-channel-url-requires-secure)

Springのソース改変するのは面倒なのでミドルウェア層で解決する。

## Tomcatでの設定例

以下のブログポストでTomcatでの設定例がある、詳しくはブログポストを見てほしいが基本的にはserver.xmlの記述を書き換えるだけでよい

* [Apache Tomcat with SSL behind Amazon ELB](https://willwarren.com/2014/01/27/running-apache-tomcat-with-ssl-behind-amazon-elb/)

```
  HTTP (80) -----> ELB -----> Tomcat (8080)
HTTPS (443) -----> ELB -----> Tomcat (8080)
```

これで、ELB経由してるブラウザからはHttpsで全部通信してるようになる。

## Jetty9での設定

ここからは自分が調査したところになる、Jettyはバージョンによって内部のクラスが結構変わるので、古いWikiなどを見ると設定が通らないことがある。

最終的にはこの部分をアンコメントすることで、Tomcatと同等の設定ができた。

```
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
  ...
  <!-- Uncomment to enable handling of X-Forwarded- style headers -->
  <Call name="addCustomizer">
    <Arg><New class="org.eclipse.jetty.server.ForwardedRequestCustomizer"/></Arg>
  </Call>
</New>
```

ForwardedRequestCustomizerはロードバランサから送られる`X-Forwarded`のヘッダがついたリクエストを良しなに処理してくれる。
Androidで端末の中の動画を一覧取得する

Android端末内に存在する動画を一覧取得したかったので、やってみました。`Cursor`の操作はKotlinの拡張関数を使うととてもコンパクトに書くことができました。

```kotlin
class VideoData(
        val id: String,
        val data: String,
        val title: String,
        val duration: Long,
        val width: Int,
        val height: Int
)

/**
 * Cursorの各行をそれぞれ特定の型にマッピングする。
 */
fun <T> Cursor.map(callback: Cursor.() -> T): List<T> {

    val result = mutableListOf<T>()

    while (moveToNext()) {
        result += callback()
    }

    return result
}

fun list360Videos(context: Context): List<VideoData> {

    val cursor: Cursor? = MediaStore.Video.query(context.contentResolver,
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
            arrayOf(
                    MediaStore.Video.VideoColumns._ID,
                    MediaStore.Video.VideoColumns.DATA,
                    MediaStore.Video.VideoColumns.TITLE,
                    MediaStore.Video.VideoColumns.DURATION,
                    MediaStore.Video.VideoColumns.WIDTH,
                    MediaStore.Video.VideoColumns.HEIGHT
            ))

    cursor?.use {

        return cursor.map {
            VideoData(
                    id = getString(0),
                    data = getString(1),
                    title = getString(2),
                    duration = getLong(3),
                    width = getInt(4),
                    height = getInt(5))
        }

    }

    return emptyList()
}
```

## 実行例

```kotlin
val result = list360Videos(appContext)
result.forEach {
    println(it.title)
    println(it.data)
}
```

メディアプレイヤーのようなアプリを作る際に役立ちそうです。
Wordpress > kusanagi > 設定


# 設定

さくらのクラウドでサーバー手配
https://kusanagi.tokyo/cloud/kusanagi-for-sakuracloud/


KUSANAGIの初期設定
https://kusanagi.tokyo/document/kusanagi-init/

OS含め最新にアップデート
```shell-session
yum --enablerepo=remi,remi-php56 update -y
```

再起動
```shell-session
reboot
```

reboot後、kusanagiコマンドで進める

```shell-session
kusanagi init 
```

マニュアルに添って進める。

終わったら、プロビジョニング（配置）を行う
■手順書
https://kusanagi.tokyo/document/kusanagi-provision/

■実行画面
![image](https://qiita-image-store.s3.amazonaws.com/0/49910/931c4562-29ed-46aa-6c5e-6290ec3d76a0.png)

```shell-session
kusanagi provision 任意のプロファイル名
```

プロファイル名は何でもいいが、/home/kusanagi/配下にプロファイル名でフォルダが作成される。
remove等で特定するプロファイル名となる。


## SSL リダイレクト
kusanagi ssl --https redirect （プロファイル名）
WordPress URLからwp(wordpressファイルが入った階層)を無くす方法

さくらサーバーやXserverの簡単インストールを使った場合、wordpressのトップページは
example.com/wp/
となります。
この時のトップページを一階層上げる作業をご紹介します。

①【設定】→【一般】から[サイトのアドレス（URL）]から/wpを省く。
![Screenshot(4).jpg](https://qiita-image-store.s3.amazonaws.com/0/142782/44cc6f34-4ca8-9f3b-bd14-9fc0dae323cb.jpeg)


②/wp/index.phpを複製してトップページとしたい階層にコピペでindex.phpを貼り付ける。

③index.phpを下記のように書き換える。

```ruby:index.php
require('/wp-blog-header.php');
```
⬇

```ruby:index.php
require('/wp/wp-blog-header.php');
```

④管理画面の【設定】→【パーマンリンク設定】を更新する。（htaccessが更新される。）
iTunesConnectを英語表示にする方法

- iTunesConnectのWebコンソールを英語表記にしたいことがある
    - 英語と日本語の用語の対応関係を確認したい際など
- ＊アプリやStoreの言語設定を英語にしたいわけではない

例えば、以下のような英語表示された画面が見たい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/25428/cafe7c11-62b1-f7c9-6a3d-3ce116b6a492.png)

## 方法
ブラウザの言語設定を英語にする。

Chromeであれば
https://support.google.com/chrome/answer/173424
の「Chrome ブラウザの言語を変更する」を参照

iTunesConnectのユーザー設定等には表示言語設定はなく、ブラウザの言語設定で対応する
VSS、8193エラー

http://elfhbt.blog33.fc2.com/blog-entry-24.html


```
ボリューム シャドウ コピー サービス エラー: ルーチン RegOpenKeyExW(-2147483646,SYSTEM\CurrentControlSet\Services\VSS\Diag,...) の呼び出し中に予期しないエラーが発生しました。hr = 0x80070005, アクセスが拒否されました。
。 

操作:
   ライターを初期化しています

コンテキスト:
   ライター クラス ID: {e8132975-6f93-4464-a53e-1050253ae220}
   ライター名: System Writer
   ライター インスタンス ID: {9e07e315-ab4c-48b5-b871-948d15cff064}
```

レジストリエディタでHKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\VSS\Diagキーのアクセス権にNETOWORK SERVICE特殊アカウントを追加してフルコントロールアクセス権を付与する。

って書いてあるけどレジストリいじりたくない……
Firefox Quantum (version57)を再起動する

# Firefox Quantum (version57)を再起動する

「とにかく再起動のやり方だけ教えて！」  
って人はちょっと下まで[スキップ](#再起動のやり方)

## Restartアドオンが使えなくなった…！

Firefoxのバージョン57が出たのでアップデートしてみたところ…  

・・・Mozillaが告知していた通り、数々の旧式アドオンが死にました。  
  
その中には[Restartアドオン](https://addons.mozilla.org/ja/firefox/addon/re-start/)も含まれていました。  
これはボタン1つでタブやウィンドウの状態を保ったままFirefoxを終了・起動、つまり再起動するアドオンです。

## 再起動したい理由

「わざわざブラウザをする必要あんの？」って思う人もいるかもしれません。なので、その理由を先に説明しておきます。

- Firefoxはメモリの開放が上手くいってない
- 長時間使うとメモリが溜まって重くなる
- 再起動でメモリ開放ができる

です。もしかするとFirefox Quantumでこの問題が解消されてるかもしれないですが、まあ、ゴミは残るだろうしタブの状態そのままで再起動できたら何かと役立つと思ってます。

## 再起動のやり方

1. Developer Toolbarの表示
   `Shift + F2`
1. `restart`コマンド実行
   ```
   restart
   ```
1. 再起動！！

- ※ 17/11/22 「開発者ツールを表示する」という手順が要らないため消しました。
- Macの場合は・・・

    > Mac の場合，ファンクションキーはそのまま押すと OS 側で割り当てた機能が優先されるので，Shift + F2 だけ押してもダメでした。
アプリ（Firefox）が割り当てた機能を使うために fn キーを併用して fn + Shift + F2 とすればいけました。

[scivola](https://qiita.com/scivola)さん情報提供ありがとうございます！


### restartの補足情報

- `restart --nocache`で閉じる前のタブの情報を読み込まずに再起動します。
- `restart --safemode`でセーフモード（拡張機能や設定が無効な状態）で起動できます。

## その他、Developer Toolbarで使える主なコマンド

1. help
   - 全コマンドを表示
1. addon
   - addon list
      - すべてのアドオンを表示
   - addon enable/disable
      - アドオンの有効化・無効化の切り替え
1. resize
   - resize toggle
      - レスポンシブモードのON/OFF
   - resize to WIDTH HEIGHT
      - レスポンシブモードの縦横サイズを指定
コマンドプロンプトでプログレスバーを再現

# 概要

batとかで処理をすると、裏で動いているのか死んでいるのかわからなくなるときがあって不親切かなと、、、
あとユーザの気持ちになると、プログレスバーがあった方がPCが仕事している事を認識できるので
待ち時間のイライラがちょっと緩和される気がしました。

# 現物

進捗を記録していくテキストファイルを監視し、そのテキストファイルの最終行が書き換わるごとにプログレスバーを表示します。
「Done」という文字列を認識すると終了します。

![test.gif](https://qiita-image-store.s3.amazonaws.com/0/32577/63bcc60a-8539-9f28-0666-de4c81d9eff4.gif)

# 仕組み

プログレスバー本体のバッチファイルやSLEEPについて。

## ファイル構造

ぶっちゃけProgressBar.batが進捗管理用のテキストファイルを開けて、sleep.exeがどっか見える所にあればいいです。
下は一例です。

[OneDrive tool.zip](https://1drv.ms/u/s!Ai50VZiXVnDdhIF50c5wxqjSN1UGQg)

```
c:\tool>tree /F
Folder PATH listing for volume Windows7_OS
Volume serial number is 2E48-0DB5
C:.
│   progress.txt
│
├───ProgressBar
│       ProgressBar.bat
│       ReadMe.txt
│
└───Sleep
        ReadMe.txt
        sleep.exe
```

## スクリプト

プログレスバーのbatファイルは下記です。

```bat:ProgressBar.bat
@echo off

rem 進捗用テキストファイルを%temp%に吐き出すようにして、V_FILEPATHの値を%temp%\%1にすると絶対パスで渡せるためお勧め。
set V_FILEPATH=%1
set V_FL=""
set V_RUNSCRIPT=""
set V_TOOLPATH=""
set V_SLEEPPATH=""
set V_CURRENTDIRECTORY=%cd%

rem 実行パスからsleepパス取得
cd /d %~dp0
cd ../
set V_TOOLPATH=%cd%

rem sleep.exeパス取得
set V_SLEEPPATH=%V_TOOLPATH%\Sleep\sleep.exe
if not exist %V_SLEEPPATH% call :ERR "sleep.exe is not exist"

rem カレントディレクトリへ移動
cd %V_CURRENTDIRECTORY%

rem プログレスバー処理開始
:LOOP
	call :TAIL %1%
	set RUNSCRIPT=%V_FL%
	set /p script="%RUNSCRIPT% | "< nul
	:PROGRESS
		set /p x="#"< nul
		rem ping 1.0.0.0 -w 500 -n 1 > nul
		rem timeout /t 1 > nul
		call %V_SLEEPPATH% -m 500
		
		call :TAIL %1%
		if %RUNSCRIPT% neq %V_FL% goto :LOOPCONTINUE
		if "%V_FL%" == "Done" goto :DONE
	goto :PROGRESS

:LOOPCONTINUE
	echo.
	if "%V_FL%" == "Done" goto :DONE
goto :LOOP


rem サブルーチン：テキストファイル最終行取得　グローバル変数V_FL
:TAIL

for /F "TOKENS=1" %%s in (%V_FILEPATH%) do set V_FL=%%s

exit /b


rem 終了
:DONE

echo.
echo Done.
pause

exit 0


rem エラー
:ERR

cd /d %V_CURRENTDIRECTORY%
echo ERR %~1
pause

exit 0
```

## 使い方

gifアニメの通り、ProgressBar.batの引数に進捗を最終行に吐き出すテキストファイルのパスを渡して起動。

進捗を記録するテキストファイルを用意しておいて、処理開始毎に最終行へ今の処理内容を書き込むような事をすればそれっぽく動けます。
bat, vbsだと下記のような感じ。

```bat:bat
echo "実行中の処理～" >> progress.txt
```

```vbnet:vbs
Set objFso = CreateObject("Scripting.FileSystemObject")
Set objFile = objFso.OpenTextFile("c:\tool\progress.txt", 8, True)

If Err.Number > 0 Then
    WScript.Echo "Open Error"
Else
    objFile.WriteLine & "実行中の処理～"
End If

objFile.Close
Set objFile = Nothing
Set objFso = Nothing
```

## SLEEP.EXE

sleep.exeはWindows Server 2003 Resource Kit Toolsというものを使用しました。
ミリ秒指定でスリープするためだけのexeです。
（exeのインストーラですが7zipやWinRARなら中身を抜き出す事ができます）

スクリプトによくあるping飛ばした時の待機時間を利用したコードもあるのですが、そもそもネット環境が無いようなところだと使えないので、ちゃんとスリープするならこれを使用したほうが良さそうです。

https://www.microsoft.com/en-us/download/details.aspx?id=17657
DB2で[Export...modified by timestampformat = ""]を実行する時エラー

## SQL3016N　
ファイル・タイプのfiletmod パラメーターで、予期しないキーワードkeywordが検出されました。

原因：DB2クライアントのバージョンが低いです。
解決策：DB2クライアントをアップグレードします

## SQL3192N  
filetmod で、ストリング string で始まるユーザー指定のフォーマット keyword が無効です。

原因：文字列で始まる時にエスケープが必要です。
解決策：「"」をエスケープする。⇒　modified by timestampformat = \"x\" .

##SQL3022N  
Action String パラメーターの SELECT 処理中に、SQL エラー sqlcode が発生しました。

原因：2 重引用符で囲まなければなりません。
解決策：db2 "export to .."
※この問題は、Linux上のDB2クライアントでのみ発生します。

##SQL3001C
出力ファイルのオープン中に入出力エラー (理由 = reason) が発生しました。

```
An I/O error (reason = "sqlofopn -2079391743") occurred while opening the output file.
```

原因：Linuxで発生していますが、ユーザー権限が不足しています
解決方法：suと入力し、rootのパスワードを入力してコマンドを入力します。
漢字をひらがな/カタカナに変換する

[以前書いた記事](https://qiita.com/sgr-ksmt/items/1dd6c9381bdd39c6cb64)では、文字列を全角/半角に変換するのを紹介しましたが、今回は「漢字」をひらがなあるいはカタカナに変換する処理を紹介します。
ユーザーが入力した住所の文字列をカタカナに自動的に変換する必要があったので調べつつ実装してみました。

## その前に
Stringには、 `applyingTransform(_:reverse)` という関数があって、ある程度これを使うことで変換ができるのですが、
今回のように漢字をひらがな/カタカナに変換する用途では使えるものがありませんでした。 
`toLatin` あったので、 `toLatin` からの `latinToHiragana` を試しましたがイマイチ...。

```swift
let hiragana = "佐藤"
    .applyingTransform(.toLatin, reverse: false)?
    .applyingTransform(.latinToHiragana, reverse: false)
print(hiragana)
// "ずお̌ て́んぐ"
```


...なので、CoreFoundationを使って変換する処理を実装することにしました。

## 実装

```swift
final class TextConverter {
    private init() {}
    enum JPCharacter {
        case hiragana
        case katakana
        fileprivate var transform: CFString {
            switch self {
            case .hiragana:
                return kCFStringTransformLatinHiragana
            case .katakana:
                return kCFStringTransformLatinKatakana
            }
        }
    }

    static func convert(_ text: String, to jpCharacter: JPCharacter) -> String {
        let input = text.trimmingCharacters(in: .whitespacesAndNewlines)
        var output = ""
        let locale = CFLocaleCreate(kCFAllocatorDefault, CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorDefault, "ja" as CFString))
        let range = CFRangeMake(0, input.utf16.count)
        let tokenizer = CFStringTokenizerCreate(
            kCFAllocatorDefault,
            input as CFString,
            range,
            kCFStringTokenizerUnitWordBoundary,
            locale
        )

        var tokenType = CFStringTokenizerGoToTokenAtIndex(tokenizer, 0)
        while (tokenType.rawValue != 0) {
            if let text = (CFStringTokenizerCopyCurrentTokenAttribute(tokenizer, kCFStringTokenizerAttributeLatinTranscription) as? NSString).map({ $0.mutableCopy() }) {
                CFStringTransform(text as! CFMutableString, nil, jpCharacter.transform, false)
                output.append(text as! String)
            }
            tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)
        }
        return output
    }
}
```

仕組みとしては、トークナイザに文字を食わせて、1つずつトークンを取り出して、latin文字として取り出した後に、`kCFStringTransformLatinHiragana`あるいは`kCFStringTransformLatinKatakana`を使って変換し、文字を連結して最後に返却しています。

また、今回はclassにしましたが、適宜Stringのextensionにしても良いかもしれません。

### (半角)スペースや改行文字の削除
また、最初に入力文字のうち、スペースや改行文字を弾くようにしています。
文字の組み合わせによっては半角スペースがあるとおかしな変換をすることがあったので、事前に弾くことにしました。

```swift
# スペース除外なし
TextConverter.convert("岸本 花子", to: .katakana)
// ア̀ン ベ̌ン ヘゥアー ゼィ
# スペース除外あり
TextConverter.convert("岸本 花子", to: .katakana)
// キシモトハナコ
```


### rangeの扱い
CFRangeを作るときは、`.count`ではなく、`.utf16.ount`を使っています。
これによって絵文字が文字化けするのを防ぎます。（がっつり検証してるわけじゃないので場合によってはやばいかも)

## 実行結果

```swift
let inputs: [String] = [
    "佐藤 太郎",
    "さとうたろう",
    "東京都",
    "渋谷区",
    "😇🎂👨‍👩‍👧"
]

inputs.map { TextConverter.convert($0, to: .katakana) }.forEach {
    print($0)
}
```

```
"サトウタロウ"
"サトウタロウ"
"トウキョウト"
"シブヤク"
"😇🎂👨‍👩‍👧"
```

:clap::clap:
GitHub にチャット機能のようなものが追加された (team discussions)

# GitHub にチャット機能が追加
コレのことです

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Why comment when you can discuss? Now there&#39;s more space to talk through your projects with team discussions. <a href="https://t.co/Nn1Pe2MVzl">https://t.co/Nn1Pe2MVzl</a> <a href="https://t.co/2KurmTXwNM">pic.twitter.com/2KurmTXwNM</a></p>&mdash; GitHub (@github) <a href="https://twitter.com/github/status/932670609208889344?ref_src=twsrc%5Etfw">2017年11月20日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

GitHub の組織アカウントには Team という単位でメンバーをまとめられます。
その Team 単位でチャットのようなことを行う機能(team discussions)が追加されました。

正確な情報は以下の公式サイトを参照してください。

- [Introducing Team discussions · GitHub](https://github.com/blog/2471-introducing-team-discussions)
- [About team discussions - User Documentation - GitHub Help](https://help.github.com/articles/about-team-discussions/)

## 使い方

GitHub の組織アカウントに行くと `Teams` というタブがあります(おそらく、組織アカウントのメンバーじゃないと見れないと思います)。
既に Team があるならいずれかをクリックすれば、Team 固有のページに飛んで、チャットを始めることが出来るでしょう。
Team が無ければ、右上の `New team` をクリックして新しく Team を作ります。

![new-team1.jpg](https://qiita-image-store.s3.amazonaws.com/0/143424/932e1197-830e-a72d-7549-be160fdc07ff.jpeg)

![disscuss.jpg](https://qiita-image-store.s3.amazonaws.com/0/143424/9f3ed21a-20db-15d6-f9ec-53e6cb62de06.jpeg)

## できること
- GFM 記法による所謂チャットを行える
- Issue や PR のような絵文字のリアクション
- ピン止め
- Public/Private なチャット
    - 但し途中で切り替えることはできないみたい
    - ちなみにいずれにしてもチームのメンバーしか閲覧できない
- Issue や PR のように一つのチャットに対し一つの URL が割り当てられる
    - 例: `https://github.com/orgs/{組織名}/teams/{チーム名}/discussions/1` 

逆に、Issue や PR と違い、ラベル付けや Open/Close は無い。
また、検索機能も微妙な気がする(そもそも出来なそう...)。

あと、GitHub API にはまだ対応していないようだが Comming Soon... と書いてあった。

## 何がうれしいのか

[公式ブログ](https://github.com/blog/2471-introducing-team-discussions)の方では、ユニークな URL が手に入るのはうれしいと書いてあった。
確かに、Slack では一連の会話を共有するのは難しい(スレッドを使えば何とか...)。

あと(個人的な意見だが)、無理やり Issue や PR で議論していたモノも、Team Discussions にした方が自然かもしれない。
現に、ぼくが所属している部活は、Slack で重要な会話も流れてしまうことを危惧して、`management` というリポジトリを作って、残しておくべき議論をそのリポジトリの Issue で行っている。
GitHub API や Open/Close が出来るようになれば移行してもいいかもしれない。

なかなか使いどころは難しいが、外に公開しないでかつ、(Slackのように)流れてしまっては困るような議論は、この機能を使うと良いみたいだ。

## おしまい

ブログの最後に、「今後も機能を増やしてくので乞うご期待！」的なことが書いてあった。
なので期待して待っていましょ。
json整形コマンドラインツール"jq"


### インストール

```
brew install jq
```

jqは引数に様々なフィルタをパイプ（|）でつなげた形式で処理を指定します。

jq [オプション] 'フィルタ1 | フィルタ2 | フィルタ3 | ...' [入力ファイル]


とりあえず試す。apiからのjsonファイルを整形
'.'は入力データそのものを表す。

```
curl -s "http://tepco-usage-api.appspot.com/2014/2/3.json"|jq '.'
```

出力

```
[
  {
    "usage": 2849,
    "entryfor": "2014-02-02 15:00:00",
    "usage_updated": "2014-02-02 16:05:05",
    "forecast": 0,
    "forecast_peak_updated": "2012-02-02 23:30:00",
    "hour": 0,
    "capacity": 4756,
    "capacity_updated": "2012-02-02 23:30:00",
    "forecast_peak_usage": 3920,
    "month": 2,
    "forecast_peak_period": 18,
    "capacity_peak_period": 18,
    "year": 2014,
    "saving": false,
    "day": 3
  },
  # 以下略
]
```

配列の取り出し

```
curl -s "http://tepco-usage-api.appspot.com/2014/2/3.json"|jq '.[]'
```

出力

```
{
  "usage": 2849,
  "entryfor": "2014-02-02 15:00:00",
  "usage_updated": "2014-02-02 16:05:05",
  "forecast": 0,
  "forecast_peak_updated": "2012-02-02 23:30:00",
  "hour": 0,
  "capacity": 4756,
  "capacity_updated": "2012-02-02 23:30:00",
  "forecast_peak_usage": 3920,
  "month": 2,
  "forecast_peak_period": 18,
  "capacity_peak_period": 18,
  "year": 2014,
  "saving": false,
  "day": 3
}
{
# 以下略
```


ローカルjsonファイルを整形

(meibo.json)

```
{"name":"john","gender":"m","age":"18"}
{"name":"paul","gender":"m","age":"20"}
{"name":"alice","gender":"f","age":"15"}
{"name":"dabid","gender":"m","age":"17"}
{"name":"jasmin","gender":"f","age":"17"}
```

### jsの引数にファイルを指定

```
$ jq "." meibo.json
[
  {
    "name": "john",
    "gender": "m",
    "age": "18"
  },
  {
    "name": "paul",
    "gender": "m",
    "age": "20"
  },
  {
    "name": "alice",
    "gender": "f",
    "age": "15"
  },
  {
    "name": "dabid",
    "gender": "m",
    "age": "17"
  },
  {
    "name": "jasmin",
    "gender": "f",
    "age": "17"
  }
]
```

### catでjsonファイルを標準出力して、それをパイプでjqコマンド受け取る

(cat コマンド)
ファイルまたは標準入力の内容をそのまま標準出力に出力する。

```
$ cat meibo.json | jq .
[
  {
    "name": "john",
    "gender": "m",
    "age": "18"
  },
  {
    "name": "paul",
    "gender": "m",
    "age": "20"
  },
  {
    "name": "alice",
    "gender": "f",
    "age": "15"
  },
  {
    "name": "dabid",
    "gender": "m",
    "age": "17"
  },
  {
    "name": "jasmin",
    "gender": "f",
    "age": "17"
  }
]
```
Goでモンティ・ホール問題を試してみる

# Goでモンティ・ホール問題を試してみる

software design 2017年12月号にて pythonでモンティ・ホール問題の検証をおこなっている記事があったので、Goで試してみました

[モンティ・ホール問題とは](https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%B3%E3%83%86%E3%82%A3%E3%83%BB%E3%83%9B%E3%83%BC%E3%83%AB%E5%95%8F%E9%A1%8C)


## code

```go
func game(change bool) int {
	choice := rand.Intn(3)
	prize := rand.Intn(3)

	if change {
		var opened int
		for {
			opened = rand.Intn(3)
			if opened != prize && opened != choice {
				break
			}
		}

		orgChoice := choice
		for {
			choice = rand.Intn(3)
			if choice != opened && choice != orgChoice {
				break
			}
		}
	}

	if choice == prize {
		return 1
	}
	return 0
}

func play(count int, change bool) float64 {
	var point int
	for i := 0; i < count; i++ {
		point += game(change)
	}
	return float64(point) / float64(count)
}

func main() {
	fmt.Printf("no change: %f\n", play(100000, false))
	fmt.Printf("change   : %f\n", play(100000, true))
}
```

## 結果

```
no change: 0.333920
change   : 0.665360
```

## 感想
確かに、選択を変更したほうが、当たる確率が高くなっていました。
JSON Lintの利用

https://qiita.com/fake-deli-ca/items/ec5a1e5fda1ff4140316

続き。
JSON Parserがないのに、DynamoDBのよくわからないJSON構造をちゃんと作るのは無理、ってことでJSON Lintを入れる。JSONLintを利用したいが、そのためにはnpmがいる。のために、node.jsをインストールする必要がある。

## 前準備
https://nodejs.org/en/download/package-manager/#enterprise-linux-and-fedora

```
$curl --silent --location https://rpm.nodesource.com/setup_9.x | sudo bash -
$sudo yum install -y gcc-c++ make
$sudo yum install -y nodejs
$npm -v
5.5.1
```
## 実際のLintの利用
`$npm install jsonlint`
でインストール

```
$echo '{"id":{"N": "7"}, "type":{"S": "02"},"num":{"S": "aaa"}}' | jsonlint
{
  "id": {
    "N": "7"
  },
  "type": {
    "S": "02"
  },
  "num": {
    "S": "aaa"
  }
}
```
こんな感じ。
How to fix connection error to JMX - hostname -i

### Symptom

Enabling JMX Remote

    Note: This configuration is needed if you are going to monitor Tomcat remotely. If you are going to monitor it locally, using the same user that Tomcat runs with, then with Java 6 it is not needed at all, and with Java 5 it is as simple as adding -Dcom.sun.management.jmxremote, see Java documentation.
    	

    set CATALINA_OPTS=-Dcom.sun.management.jmxremote
      -Dcom.sun.management.jmxremote.port=%my.jmx.port%
      -Dcom.sun.management.jmxremote.ssl=false
      -Dcom.sun.management.jmxremote.authenticate=false

    	

but cannot connect JMX on Oracle Linux 7.x ...


### How to fix

https://docs.oracle.com/javase/8/docs/technotes/guides/management/faq.html


**I am having problem using JConsole to connect to a JVM running on Linux. Connecting to JVM running on Windows and Solaris works fine.**

This is most likely a configuration problem on the Linux machine or the management properties specified to run the application. Please also see FAQ #a4 about using SSL.

You should check the following:

   Check if the hostname correctly resolves to the host address.

   Run "hostname -i" command. If it reports 127.0.0.1, JConsole would not be able to connect to the JVM running on that Linux machine. To fix this issue, edit /etc/hosts so that the hostname resolves to the host address.
phpから外部のjsに値渡し

phpから外部のjavascriptに値渡し

phpから外部のjavascriptに値を渡す方法を紹介します。
＊JQueryも使います。
ほぼこちらhttps://qiita.com/cither/items/b98cc4e237dcc8f7e51f
の記事の一部を引っ張り出す形になっています、
さっそく中身に入っていきましょうー

```php:index.php
//こいつを渡します
$param = "渡したい変数"

//JSON形式に変換する関数を定義
function json_safe_encode($data){
    return json_encode($data, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT);
}

//JQuery読み込み
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
//外部javascript呼び出し
//ここでid属性を記述して、スクリプトタグに変数を埋め込みます
<script id="script" type="text/javascript" src="./js/script.js"
 data-param='<?php echo json_safe_encode($param);?>'>
</script>
```
json_encode関数に毎回引数指定するのが面倒なので５行目で定義しています。


```js:script.js
//JQuery使って属性を取得する、JSON.parseで扱える形に変換
var $script = $('#script');
var result = JSON.parse($script.attr('data-param');
//確認
console.log(result);
```

読んで字の如くですが、
参考になれば幸いです。


参照記事：
https://qiita.com/cither/items/b98cc4e237dcc8f7e51f
画面コピーを含む操作手順書をあっという間に作る

# はじめに

本職が業務用海外アプリの販社のアプリケーションサポートなので、ユーザーや開発元とのやり取りで不具合が出る操作手順を画面キャプチャして手順書を残すことがよくあります。
たいていはWinshotで特定のフォルダに一旦、画面コピーをとにかく集めてからExcelに張り付けていくことになるのですがまあとにかくめんどくさい。
操作を動画に落とすのもありですが、どうしても冗長だしファイルサイズは過大だしでこれも気に入らない。
ところが、クリップボードにある画像をQiitaの編集画面に張り付けるとPNG画像としてアップロードしてくれるというのを[読んだ](https://qiita.com/Ryosuke0624/items/9e4a81d16469659c657d)ときにピピっと(死語)来た訳です。
さすがにQiitaを作業用に使うわけにもいかないので、[Knowledge](https://github.com/support-project/knowledge)の編集画面にペーストするとQiita同様にPNG画像がアップロードされたので、これを下書き＆画像収集に使用してSphinxで清書できないかと考えた。

1つ目の手順書作成が結構うまくいったので、忘備録もかねて記事にしました。

# 作業環境

 - いつものSurface3 (Win10)
 - Sphinx 1.6.5
  - インストール仕様は以前の[記事](https://qiita.com/cosmos4701141/items/58b14e8a239dba578bbc)を参照
  - Phython 3.6
  - [sphinx-quickstart-plus](https://qiita.com/pashango2/items/512e567b328058d4107a)  を追加
 - Pandoc 2.0.1 
 - ~~画面コピーの取得用に [FreeScreenshotWin version 1.4.7](https://sites.google.com/site/mappityper/)~~
  - ~~Win10の標準機能とコンフリクトするので、Ctrl+Home でアクティブウインドウをクリップボード転送できるように設定した~~
  - あとでよくよく調べたらWin10の標準機能で Alt+PrtScn すればアクティブウインドウをクリップボード転送(しつつOnedriveに保存)してくれる
 - [Knowledge](https://github.com/support-project/knowledge) v1.11.0 を作業検証用なのでSurface3のローカルに導入
  - Apache Tomcat Version 8.5.23
   - JAVA (jdk1.8.0_131)

**2017/12/13 追記**

 - 以下のWebブラウザでクリップボード画像の貼り付けを確認
  - Microsoft Edge
  - Chrome

   

# 作業手順

| #  | 工程名          | 内容                                 |
|:--:|:---------------:|:------------------------------------|
| 0  | 記事作成        | Knowledgeに工程ごとに記事を作成する。画面コピーはアクティブウインドウをコピペして、見出しと注釈を入れながらどんどん貼り付ける　|
| 1  | mdファイル作成   | ソースをコピペして作成                |
| 2  | index.rstファイル作成 | 工程ごとのmdファイル名を並べて記述              |
| 3 | URLリンク修正 | "相対URLを絶対URLに置き換え /knowledge/open.file/download -> http://localhost:8080/knowledge/open.file/download |
| 4 | コードブロック置き換え | Markdownのコードブロックを、eval_rst を使ってreStructureTextの1行x1列のSimpleTableに置き換え |
| 5 | 見出しの整理 | 元の記事のタイトルをH1(#)、記事中の見出しはひとつづつレベルを落とす。(# -> ##,## -> ### とか) ※ 見出しに数字は付記しない(バグる) |
| 6 | Sphinxでmake | make singlehtml|
| 7 | Chrome で表示確認	| 表示の乱れがないか確認する |
| 8 | Chrome で保存 | "リンク先の画像をローカルに保存する その他の操作->ファイルに保存->HTML(完全)  ※ファイル名に空白文字を含まないように注意" |
| 9 | Pandoc変換 | pandoc <ファイル名>.html -o <ファイル名>.docx |
| 10 | 表の修正 | 表の幅を変更する(あるいは無指定にする) |
| 11 | 段落文字の削除 | ¶を削除する |
| 12 | 目次の削除 | リンク先がおかしいので削除する。必要であればWORD内で生成する |
| 13 | 奥付の削除 | 自分的にはいらないので、Indices and tablesを削除 |

# 結果

これで、社内向けにはknowledgeで公開しつつ、外部への提出用にはWordできれいにして出すことができました。
コードブロックをSimpleTableに置き換える操作が面倒ですが、80ページ/4000文字/画面コピー80枚/45個のコードブロックの作業手順書のWORD文書が、操作再生の手間(≒キャプチャの時間)＋半日分ちょっとの作業でできました。
JavaScriptである文字列からとある文字すべてを置換するRegExp関数の使いかた

Javascriptの中の文字列を正しくすべて置き換えるには、RegExp関数を使用します。
でも、レファレンスをみるとちょっと書き方が不親切な気が。
```javascript
/ab+c/i;
new RegExp('ab+c', 'i');
new RegExp(/ab+c/, 'i');
```
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp より引用

ただしくは**たてに並べるのではなく、xxx.push("置換対象","置換後の文字列")の置換対象の部分にRegExpを当てはめる**ことで、このRegExpでの正規表現の文字置き換えを実装することができる。

```javascript
 for(var i = 0; i < array2.length; i++){
        var txtToPush = array2[i].innerText.replace(new RegExp("\n",'g'),"");
//        var txtToPush = .replace('\n','');
        arrayToReturn.push(txtToPush);
      }
```
現在このコンピューターは指定されたディレクトリ インスタンスをホストしていますが、Active Directory Web サービスはこのサービスを提供できません。Active Directory Web サービスはこの操作を定期的に再試行します。

http://kh3467.blog66.fc2.com/blog-entry-222.html

≫解決策
dcpromo.exeを実行することで ADWSサービス（Active Directory Application Mode Service）が自動インストールされることが原因。
管理ツールから運用を行うADWSを使用しない場合、無視して問題ない。

「ADAMとは」
http://technet.microsoft.com/ja-jp/library/cc780837%28WS.10%29.aspx

（参考）
http://social.technet.microsoft.com/Forums/it-IT/winserverDS/thread/62a3f70f-d326-4d52-aee8-42b59a0298b9

との事……
ADWSって何？？？
別名でも呼べるようにしたいという理由でaliasを使うのは間違っているのかもしれない

```ruby
class C
  def a
    1
  end

  alias b a
end

class C2 < C
  def a
    super + 100
  end
end

C2.new.a                        # => 101
C2.new.b                        # => 1
```

`C2.new.b` も 101 になるのを期待していたのでちょっとはまりました。
安易に alias を使ったのが間違いでした。

いろんなライブラリを見ると別名でも呼べるようにしたいという理由で alias や alias_method が多用されている気がしますが、b から a を呼び出すのと `alias b a` は違うことを覚えといた方がよさそうです。

元のメソッドを呼ぶだけのコードを alias に置き換えたりするようなリファクタリングにも注意が必要ですね。
突然railsが動かなくなった話


## エラー内容

$ rails s を実行すると、突然

```
Rails is not currently installed on this system. To get the latest version, simply type:

    $ sudo gem install rails

You can then rerun your "rails" command.
```
とのエラー。

怒られるがまま、
$ sudo gem install rails　を実行しますが同じエラーの繰り返し。。。泣


## 解決方法

```
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
```

この２つを実行するだけで、とりあえず当初のエラーはなくなりrailsサーバは立ち上がりました。

おそらく、node.jsのためのパス指定時に、rubyに関する記述の意味もわからず消去してしまったからだと思われます。


## 状況

このエラーが出る以前に、React.jsを書いてみたいと思ったので、
node.jsのインストールを行いました。（多分これを適当にやってしまったのが原因）
[インストール時の参考にした記事](https://qiita.com/akakuro43/items/600e7e4695588ab2958d)にあるように、パスを指定するために　.bash_profile や .bashrc を編集しました。

この作業前後にrails のバージョンをいじったりもしていないので、
おそらくこの辺りでパスとかがおかしくなっただけかなと予想。rails導入時の手順を調べると、

```
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
```

を実行する手順がある。。。（おそらくこの辺が現状うまくいっていない）


## rbenvとruby-buildについて(参考)
(参考)
[rbenv + ruby-build はどうやって動いているのか](http://takatoshiono.hatenablog.com/entry/2015/01/09/012040)
[rbenv で ruby の環境を整える](https://qiita.com/ringo/items/4351c6aee70ed6f346c8)
[Railsアプリ開発に途中から参加する場合の環境設定](https://qiita.com/yh2020/items/efd888854acf89af5ca7)
[rbenvコマンド備忘録](https://qiita.com/a_ishidaaa/items/8cc14453289dba1413dd)
[gemファイルのインストール場所を調べたりする方法](https://qiita.com/ironsand/items/41aaba896954d56484a4)
[Bundler概要](https://qiita.com/hisonl/items/162f70e612e8e96dba50)
[新しいRubyのバージョンをインストールすると`bundle install`できない](https://qiita.com/opiyo_taku/items/f4459ce4f42e18d08e28)


rbenv(rubyのバージョンを切り替えることできる)と、
ruby-build(Rubyの様々なバージョンをインストールすることができる)は、Rubyのバージョンを管理する際に組み合わせて使います。

よくわからん。。。
設定ファイルの記述の意味をしっかり知って操作すべきと思う一件でした
Freeeの勘定科目の削除を半自動するjsshellスクリプト

# 経緯
Freee APIを使って、勘定科目を登録するアプリケーションを書いていた
編集や削除APIが公開されていないため、ブラウザから手動で消す必要がありました。
（問い合わせたところ、対応する予定は今のところないとのこと）
また、勘定科目の画面はまとめて削除ができない。
確認のたびにひとつひとつ消すの手間だったので、jsshellつかって半自動で消すことにした。

jsshellもう随分と更新がされてないけど、目的は達せられたので良しとする

# コード

一番上に表示されている勘定科目を消す

```javascript
$('div.account-item-tr.clickable:first').trigger('click');
setTimeout(function(){
    $('button.btn.btn-danger:first').trigger('click');
    //確認画面のクリックを残したい場合は以下をコメントアウト
    setTimeout(function(){
        $('button.btn-large.btn-danger:first').trigger('click');
    }, 800);
}, 800);
```

# 使い方
https://secure.freee.co.jp/account_items で検索画面で消したい科目を絞り込む
jshellを開いて上のコードをコピーしてrunを押すと消える。
git のコミット履歴をすべて消す（現時点の状態の1コミットだけにする）

普通はこんなことしない。

が、やんごとなき理由によりやらねばならないときに。

```bash
git checkout --orphan tmp
git commit -m "Initial Commit"
git checkout -B master
git branch -d tmp
```

## 解説

`git checkout --orphan tmp`

orphan オプションによって、独立した（親を共有していない）ブランチを切ることができる。

`git commit -m "Initial Commit"`

独立している `tmp` ブランチにコミット。`tmp` 上ではこれが最初のコミットとなる。

`git checkout -B master`

B オプションで `master` ブランチを上書き。この時点で master ブランチは先程の1コミットログだけが残る。

`git branch -d tmp`

あとしまつ。
CentOS逆引きメモ

必要に迫られたCentOS系の逆引きメモになります。

# yum updateで「[Errno 14] HTTP Error 404 - Not Found他のミラーを試します。」が発生する問題

## 対応方法

```
$ yum clean metadata
$ yum clean all
```

## 参考
* [yumのErrno14 | ハックノート](https://hacknote.jp/archives/21195/)

# 起動

## warning skipping the following r/o file systems /sys/fs/cgroup

原因はまちまちだけど再起動すると`warning skipping the following r/o file systems /sys/fs/cgroup`と表示されて起動プロセス止まったように見える場合が有る、少々待てば再起動する。

# cron

## 登録済みタスクの確認

```
crontab -l
```

## cronのログを確認

```
tail -f /var/log/cron
```

# rsync

## ssh 接続でポート番号を指定する。

```
rsync -avz -e "ssh -p 99999" test@host:/var/test/ /var/test/
```

# その他

## ランダム文字列の生成

```
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 8 | sort | uniq
```
サンプルは16バイト長

# 参考

* [cronの実行ログを確認 - 肉になるメモ](http://kazumeat.hatenablog.com/entry/20090424/1240568463)
* [Centos 7 (selinux disabled) - Warning Skipping the following R O filesystems](https://www.youtube.com/watch?v=0_-1CoyXipo)
C++ Builder > TForm > 「テキストやその他の項目の大きさの変更」 > 中(M)や大(L)の場合にウィンドウサイズが変化する

```txt:動作環境
C++ Builder XE4
```

### 症状

コントロールパネル > ディスプレイ > 画像の解像度
において「テキストやその他の項目の大きさの変更」がある。

そこで設定可能なテキストサイズは以下がある。

- 小 - 100% (既定)(S)
- 中(M) - 125%
- 大(L) - 150%

この設定を「小」から変更した場合、フォームの「width」および「height」プロパティの値も拡大されるようだ。

### テストコード

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	int dpi  = this->PixelsPerInch;
	ShowMessage(IntToStr(dpi));
}
//---------------------------------------------------------------------------
```

上記のコードのそれぞれの実行結果は以下となる。

- 小: 96
- 中: 120
- 大: 144


フォームのサイズ(width, height)をプログラム上で変更するようにした場合、上記を考慮しないと「中」や「大」の設定時にフォームの一部しか表示されなくなる。

解像度の高い画面に対して文字が小さくなる場合、ユーザが上記の設定を「小」から変更する場合がある。そのような場合にフォームが正常に表示されなくなる。

### Windows 10

Windows 10 (Autumn Creators Update適用済み)にて上記のコードを実行してみた。

dual monitorにおいて左側だけを「125%」にした。
結果は「96」だった。
( 設定変更後、サインアウトはしていない。デスクトップアイコンの文字は大きくなった）。

### リンク

https://stackoverflow.com/questions/9373260/detect-windows-font-size-100-125-150

https://stackoverflow.com/questions/2946717/how-do-i-handle-windows-7s-125-or-150-magnification-delphi

二つ目のリンク先でいくつかのリンクが紹介されている。
すごいWebサイト

自分がすごいと思ったWebサイトをただ載せるだけ。（随時更新）

## WebGL
- [WebCamMesh](https://airtightinteractive.com/demos/js/webcammesh/)
- [Playmapscube](http://www.playmapscube.com/)
- [WebGL Bookcase](http://bookcase.chromeexperiments.com/)
- [Materials Skin](http://alteredqualia.com/three/examples/webgl_materials_skin.html)
- [Particles morph](http://oos.moxiecode.com/js_webgl/particles_morph/)
- [Pop Up Card Builder](http://madebyevan.com/webgl-water/)
- [ROME](http://www.ro.me/)

## CSSアニメーション
- [ALCYACONSEIL](http://www.alcyaconseil.info/)
- [TOBIAS AHLIN](http://tobiasahlin.com/spinkit/)
- [CSS3 Hover Effects](http://www.alessioatzeni.com/wp-content/tutorials/html-css/CSS3-Hover-Effects/index.html)
- [3D Thumbnail Hover Effects](https://tympanus.net/Tutorials/3DHoverEffects/index.html)
- [MAGIC ANIMATIONS CSS3](https://www.minimamente.com/example/magic_animations/)

## Pure CSS Modal
- [Pure CSS Modal](http://jorgechavz.github.io/pure-css-modal/)
strtotime() を使った曜日による相対的な日付取得

strtotime() で相対的な曜日による日付取得をしようとすると挙動が少しややこしいので、色々なパターンで相対的な月曜日を取得したときの結果をメモしておきます。

## 検証コード

以下の3日間で検証してみます。

- 2017-11-19 (日曜日)
- 2017-11-20 (月曜日)
- 2017-11-21 (火曜日)

これらの日付に対して以下のパターンで相対的な月曜日を取得してみます。

- `monday last week`
- `last monday`
- `monday this week`
- `monday`
- `next monday`
- `monday next week`

```php
$results = [];

foreach (['2017-11-19', '2017-11-20', '2017-11-21'] as $date) {
    foreach (['monday last week', 'last monday', 'monday this week', 'monday', 'next monday', 'monday next week'] as $rel) {
        $results[$date][$rel] = date('Y-m-d', strtotime($rel, strtotime($date)));
    }
}

var_dump($results);
```
### 検証コードの実行結果

|  | 11月19日 (日) | 11月20日 (月) | 11月21日 (火) |
|------------------|---------------|---------------|---------------|
| monday <b>last week</b> | 11月6日  | 11月13日 | 11月13日 |
| <b>last</b> monday      | 11月13日 | 11月13日 | 11月20日 |
| monday <b>this week</b> | 11月13日 | 11月20日 | 11月20日 |
| monday           | 11月20日 | 11月20日 | 11月27日 |
| <b>next</b> monday      | 11月20日 | 11月27日 | 11月27日 |
| monday <b>next week</b> | 11月20日 | 11月27日 | 11月27日 |

## ポイント

- 月曜日当日に `monday` として取得した場合は今日 (今週の月曜日) が取得される。
- 月曜日当日に `next monday` として取得した場合は7日後 (来週の月曜日) が取得される。
- 月曜日当日に `last monday` として取得した場合は7日前 (先週の月曜日) が取得される。

つまり月曜日当日に実行した場合だけ `last monday` と `next monday` の差が 7日 ではなく 14日 になります。

- `last week` や `next week` をつけるとその日からみた先週や来週の月曜日が取得される。
    - 週は月曜日始まりの日曜日終わり固定。