OmniAICreator/Qiita-1.07M huggingface dataset:
Redmineの新規チケット起票時に選択したトラッカーによってプライベートチケットON/OFFする方法【View customizes Plugin】

# やりたいこと
新規チケット起票時にトラッカーによってプライベートチケットのデフォルトON/OFFを行いたい。

```:例
・トラッカーが「申請」の場合はデフォルトでプライベートチケットにチェックがついている。
・トラッカーが「問い合わせ」の場合はデフォルトでプライベートチケットにチェックがついていない。
こんなことできないだろうか？
```

# 動作環境

Redmine3.4.3
View Customize plugin 1.1.4	

# やり方
Redmineのプラグイン「view customize plugin」を利用します。

下記の設定をview customizeで設定します。
今回は上の例のように「申請」と「問い合わせ」のトラッカーが存在して、
「申請」を選択するとプライベートチケットにチェックが付くようにします。
Code文中にある「// トラッカー名毎に処理を分ける」より下を追加していくことで
複数のトラッカーで処理を変更することが可能です。

- Path pattern

```
/projects/{プロジェクトID}/issues/new
```

- Type

```
JavaScript
```
- Code

```
$(function() {
  var trackerChanged = false;  // トラッカー変更有無

  // トラッカー変更イベントによりフラグの状態制御
  $(document).on('change', '#issue_tracker_id', function() {
    trackerChanged = true;
  });

  // デフォルトのreplaceIssueFormWithを置き換え
  var _replaceIssueFormWith = replaceIssueFormWith;
  replaceIssueFormWith = function(html){

    _replaceIssueFormWith(html);
    // トラッカー変更時にデフォルト設定処理を実行
    if (trackerChanged) {
      setDefalutStatus();
    }

    trackerChanged = false;
  };

  // トラッカーのデフォルト設定処理
  var setDefalutStatus = function() {
    // トラッカー名毎に処理を分ける
    switch($('#issue_tracker_id option:selected').text()) {
      case "申請":
        $("#issue_is_private").prop('checked',true);
        break;
      default:
        $("#issue_is_private").prop('checked',false);
        break;
    }
  }

  // 初回表示処理にもデフォルト値設定処理を実行
  setDefalutStatus();
});
```

# 参考サイト
[Enjoy*Study:Redmineでトラッカー毎にデフォルトステータスを変える(View customize plugin)](http://blog.enjoyxstudy.com/entry/2015/02/17/000000)
[新規チケットをデフォルトでプライベートにしたい。](https://groups.google.com/forum/#!topic/redmine-users-ja/-IkusNfVTO0)
unicorn-worker-killer の設定例

#### Gemfile
`gem 'unicorn-worker-killer'` を追記して `bundle install`

#### 設定例

```config.ru
require 'unicorn/worker_killer'
use Unicorn::WorkerKiller::MaxRequests, 3072, 4096, true #ワーカーが処理したリクエストの数に基づいて、Unicornワーカーを自動的に再起動します。 trueオプションでunicorn.stderr.logにログを出力します。
use Unicorn::WorkerKiller::Oom, (192*(1024**2)), (256*(1024**2)) # メモリサイズに基づいてUnicornワーカーを自動的に再起動します。


require ::File.expand_path('../config/environment', __FILE__) # この記述の上に書くこと！
run Rails.application

```

#### こんなログが出ます
```
INFO -- : #<Unicorn::HttpServer:0x0055ad705e4c78>: worker (pid: 3057) has 1 left before being killed
WARN -- : #<Unicorn::HttpServer:0x0055ad705e4c78>: worker (pid: 3057) exceeds max number of requests (limit: 10)
WARN -- : Unicorn::WorkerKiller send SIGQUIT (pid: 3057) alive: 213 sec (trial 1)
INFO -- : reaped #<Process::Status: pid 3057 exit 0> worker=3
INFO -- : worker=3 ready
```

#### 参考
https://github.com/kzk/unicorn-worker-killer
WEBフロントエンド技術の定番をざっくり


#はじめに

##WEBフロントエンドテクノロジ
WEBフロントエンドの世界は流行り廃りが早くカオスです。
そのうえで、幾つかの技術を組み合わせてプロジェクトにあたるのが通常です。
次に示すのは、定番となっている組み合わせの一種です。

- Node.js & npm (js開発環境)
- webpack (js開発環境)
- Vue.js (フロントエンドフレームワーク)


それでは次から、それぞれについて解説をしていきたいと思います。

#Node.js & npm

##Node.jsとは
Node.jsはjs実行環境です。
こいつがいるおかげでjsは「ブラウザの挙動をちょっといじる」ための言語から、
「なんでもガッツリ開発できる言語」へと化けます。
次に説明するnpmはNode.js上で動きます。

##npmとは
jsのパッケージ管理システムです。
npmには大量のモジュールが登録されており、
npmのコマンドを使用することで手軽にこれらを自分のプロジェクトに導入することができます。
現代的なjs開発では必須です。

後述するwebpackやVue.jsも基本的にはこのnpmを使ってプロジェクトに取り入れていきます。

##参考リンク
- [Node.js](https://nodejs.org/ja/) 
- [npm](https://www.npmjs.com/)
- [npm とか bower とか一体何なんだよ！Javascript 界隈の文脈を理解しよう - Qiita](https://qiita.com/megane42/items/2ab6ffd866c3f2fda066)

#webpack

##webpackとは
jsはhtmlに直接ちょろっと書くもの。これは過去の話です。
今では大量のjsファイルが複雑な依存関係を構成するのが当たり前になってしまいました。
これら大量のjsファイル全てをひとつずつhtmlに読み込むのは現実的ではありません。
そこで

**「全てのjsファイルを単一のjsファイルにまとめなおしたうえで取り込む」**

というやり方がとられます。
このような「jsをまとめる」ことを実現するツールをモジュールバンドラーなどと呼びます。（その名の通り、モジュールをバンドルしますから）

実はwebpackはjsだけでなく画像やcssもバンドルが可能で、
それが人気となっている理由のひとつでもあります

##リンク
- [webpack](https://webpack.js.org/)
- [webpack 入門 （v3系 対応） - Qiita](https://qiita.com/soarflat/items/28bf799f7e0335b68186)
- [webpack で始めるイマドキのフロントエンド開発 - Qiita](https://qiita.com/yosisa/items/61cfd3ede598e194813b)


#Vue.js

##Vue.jsとは
jsによるWEBフロントエンドフレームワークです。
後発ながら今もっとも勢いがあります。

##何ができるの?
表示内容を動的に操作できます。
同様の目的をもったフレームワークとして

- Angular
- React

などなど。

##学び方

Vue.jsはコアメンバーに日本人がいる関係で日本語ドキュメントが充実しています。
**公式ドキュメントを読めばほとんどのことはできます。**
**Vue.jsは公式ドキュメントが最強です。**

##リンク
- [Vue.js](https://jp.vuejs.org/)
SPSS Modelerを複数ウインドウで起動する

SPSS Modelerで複数のストリームを開くとストリームのリストにたまっていき、ここをクリックすることでキャンバスに表示するストリームを切り替えます。オレンジでハイライトされているストリームが表示しているストリームです。
これは実行中のストリームを開いていても切り替えることが可能です。実行中のストリームはストリーム名が緑で表示されます。実行が終われば黒になるので、あるストリームを実行しながら他のストリームの編集作業していても、実行していたストリームの終了を確認することができます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/223763/02a9b005-11d7-2fc3-4ce7-7801e90c8a4d.png)


しかし、
・複数のModeler Serverに接続したい場合
・似たストリームを比較したい場合
には複数ウインドウで起動したいことがあります。
その方法がマニュアルに載っています。
つまり -noshareのオプションをつけて起動するという方法です。

IBM Knowledge Center - 複数の IBM SPSS Modeler セッションの起動
https://www.ibm.com/support/knowledgecenter/ja/SS3RA7_18.1.0/modeler_mainhelp_client_ddita/clementine/start_multiple_client_sessions.html

![image.png](https://qiita-image-store.s3.amazonaws.com/0/223763/68976233-aedd-d4d9-3359-dd457112e51d.png)

このように二つのウインドウで起動ができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/223763/8ef32fdd-d654-ef29-4d49-e9f50eda7289.png)

ただ、ウインドウ間でノードのコピーはできませんでした。

なお、マニュアル上の.str拡張子ファイルの関連付けについては古いWindowsXPでの関連付け方法ですので、お使いのバージョンにあわせて読み替えて設定が必要です。

## windows 10での利用方法（2022/6/15追加）
スタートメニューのショートカット変更がスタートメニューから行えなくなっていますので、ショートカットで実現するのが簡単です。
デスクトップなどでショートカットを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1713f55d-7ded-b414-94c6-86a6d639ac92.png)

項目の場所に以下を入れます。
"C:\Program Files\IBM\SPSS\Modeler\18.3\bin\modelerclient.exe" -noshare

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/599cb796-fd16-b346-c531-386aead8d42e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/deb922a8-d551-f39f-7419-644f7e7f477b.png)

このショートカットを実行すると二つのウインドウで起動ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/3ddbf3a5-6644-6405-5f97-29bd05a36299.png)
Parcel実行時にCannot read property 'replace' of undefinedが出た時

# 自分用メモです

# Parcel実行時にCannot read property 'replace' of undefinedが出た時
package.json
に
```
  "name": "hogehoge",
```
が無いときに出るようなので入れておく
(手動でpackage.json作ったときにはまった)

※index.htmlでjs呼び出しがなければnameなくても動く
azure-cli2.0コマンドtips（az webappsより）

# azure-cli2.0コマンドtips

azure-cli(azコマンド）の自分のよく使うコマンドなどをtips的にまとめていきます（順次更新、追加）。  

## webapps診断ログのアプリケーションログ（ファイルシステム）をOnにする

webappsのログストリームでログを見るためには「診断ログ」の「アプリケーションログ（ファイルシステム）」を"On"設定にしておく必要があるのですが、この項目はOn設定にしても１２時間後に自動的にOffになってしまいます。（理由は調べてない。なにかパフォーマンス低下を招くとか、ストレージを食いつぶすからとかいろいろ理由は思いつくけど）  
GUIから変更してもいいのですが、何度もやるのは面倒なのでazure-cliで開発中や開発機についてはOnにしておきたい。  
以下のコマンドでOnにできます。  

```bash:コマンド入力
$ az webapp log config --resource-group test01 --name test01-server --application-logging true --level verbose
```
levelについては必要に応じて変えてください（当然、resouce-groupとかnameはダミー値です）。
Mac OSにおけるFinderとTerminalの連携

# Terminalで作業中のディレクトリをFinderで開く
Terminalで作業しているディレクトリをFinderで開きたいときは
`open .`
と入力すれば実現されます．

# Finderで作業中のディレクトリをTerminalで開く 
時にFinderで作業していたディレクトリを直ぐにTerminalで開きたい時があります．
一番上にあるFinderウインドウで開いているディレクトリにTerminalで即座に移動できる様なスクリプトを作成しました．

applescript と tcsh のスクリプト組み合わせて実現しています．

```applescript:findercd.applescript(2018/01/10修正)
try
    tell application "Finder" to set currentDir to (target of front Finder window) as text
on error
    return "~"
end try
```


```tcsh:findercd.sh
#!/bin/tcsh
set finderdirectory = `osascript ~/bin/findercd.applescript| sed -e "s/Macintosh HD//" | sed -e "s/:/\//g" `
cd "$finderdirectory"
```

.cshrcにエイリアスを張る必要があります．sourceとする事でcpがスクリプトを抜けても保存されるようになっています．

```tcsh:.cshrc
#!/bin/tcsh
alias findercd 'source ~/bin/findercd.sh'
```

# 残された課題
+ スクリプトが2つのファイルになっている
+ ~~Finderウインドウが開いていないときにapplescriptがエラーになる．~~
    + ~~エラーが出たときの処理~~
    + Finderウインドウが開いていない時には，ホームディレクトリへ移動するように修正した．

# 参考リンク
+ https://stackoverflow.com/questions/12129989/getting-finders-current-directory-in-applescript-stored-as-application
+ https://qiita.com/Yuhsak/items/a1f154f14e5ff871b6d2
    + 後から見つけましたがこちらの方が使いやすそうです．
+ https://qiita.com/mattak/items/bd159863be10b0ae81d8
+ http://www.script-factory.net/software/terminal/fcd/index.html
【Xamarin】「XamlParseException: No embeddedresources found」の原因と対処法

# はじめに

Xamarinは全然初心者です。本業はPHPer。

社内の施策として、業務外でチームを組んでXamarin.Formsでアプリ開発をしていました。
いかんせんC#を書くのもままならないような初心者(※)ですので、頻繁にシミュレーターを実行して、どういう状態なのかを確認して、少し直してはまた実行…を繰り返していました。
※PHPとノリが違い過ぎて戸惑ってます。。

そうすると、たまに`「Xamarin.Forms.Xaml.XamlParseException: No embeddedresources found」`というエラーに遭遇して、iOSやAndroidのシミュレーターが止まることがありました。
あまりに原因不明なこのエラーなのですが、何回も出くわすうちに原因や、エラーが出た時の対処法が分かってきたので、備忘録として記しておきます。

# 実行環境

* macOS 10.13 High Sierra
* Visual Studio For Mac

# そもそもコレは何なのか

`「Xamarin.Forms.Xaml.XamlParseException: No embeddedresources found」`

このエラー、検索してもロクな記述を見かけないのです。
数少ない記述としては、以下のStackoverflowがありますが。。。
[xamarin - No embedded resource found - Stack Overflow](https://stackoverflow.com/questions/27896528/no-embedded-resource-found)

> It's a bug. For some reason its status is RESOLVED FIXED, but it doesn't seem fixed at all. On XS on mac anyway.

「それはバグです。解決済みステータスになってるけど、全部は直りきってないみたいね！とにかくMacのXamarin Studioではね。」(超意訳)

**バグで片付けないでくださいよー！**
しかもMac版Xamarin Studioだと顕著な様子。
当方 **Visual Studio For Mac** なんですが。。Xamarin Studioのリブランド版ともっぱらの噂の。

> just make an edit to that one generated file, save it, and build again. A bit faster than rebuilding everything.

> Of course this means every time you change a .xaml file, you have to build twice.

「編集して、保存して、再度ビルドしてね。もちろんこれはあなたがXAMLファイルを毎回毎回変更することを意味するよ！ 2回ビルドしてね！」 (適当意訳)

…つまるところ、バグだからとりあえず変更与えて再度ビルドして、どうにかしろ、ということなようです。
それではラチがあきません。

# 原因ぽいもの

何回も出くわすうちにパターンが分かってきました。
どうもコイツは、 **最後まで描写されなかったページがあると発生率が高い** っぽいです。
おまけに **Mac** の場合。
私はiOSシミュレーターで多発していました。
Androidは未確認ですが、Xamarin.Formsのエラーなので、恐らく同様であると思われます。

## どういうことか

「最後まで描写されなかった」というのは、「ブレークポイントで一旦止めて、そのまま **最後まで実行しないでデバッガーを停止する** 」ことや、「 **途中で例外が発生するなどして、最後まで実行されなかった** 」ことを指します。

…よくやりますよね、変数の中身確認するためだけにデバッガー動かして、確認出来たら、プログラムが途中だろうがそこで止めちゃうの。
私みたいな初心者は特に。
コレがXamarinではハマりどころになるっぽいです。

何でこれでエラーになるのかは正直分かりません。
ただ、私の環境ではコレやった後、高確率でこのエラーに出くわしました。

前者のパターンの場合は、コードがどっかおかしいのかと思いきや、ソリューション閉じてもう一度開けば何事も無かったかのように動くので、コードの問題ではありません。

# 対処法

## 対処法その1
先述のStackoverflowにもあったように、適当に編集加えて、再度ビルドすること。
しかしこちらでやる限り、それでもこのエラーが出ることが多いです。

## 対処法その2
一度ソリューションを閉じて、開き直すこと。
これは言うまでもなく、毎回そうするのはダルいです。

## 対処法その3
一度 **ソリューションをクリーン** してから、再度ビルドすること。
PCLの場合は、PCLをクリーンでも大丈夫です。
これだったら大体解決することが多いと分かったので、これで行うことが多いです。

# おわりに

Visual Studio For MacでXamarinやってる方は少なからずいるはずなので、もう少し情報があっても良さそうなものなのですが、もしかして環境によるのか…？
ともあれ、同じ現象に悩まされている方の手がかりになれば幸いです。
…主に、未来の自分ですが。
3ヶ月前のElasticsearchのログを自動で削除

Elasticsearchのログを以前は手作業で定期的に削除していたが
スクリプトにしてcronで自動実行するように変更

ログの名前を
`item名-日付`としている(例.item1-2017.01.10)ため
`item名-(90日前の日付)`をcurlコマンドで削除

```
#!/bin/bash

items=(
    "item1"
    "item2"
    "item3"
    "item4"
    "item5"
    "item6"
)

DATE=`date +"%Y.%m.%d" --date="90 days ago"`

for item in "${items[@]}" ; do
    INDEX=$item-$DATE
    echo $INDEX
    curl -XDELETE http://localhost:9200/$INDEX
    echo -e "\n"
done
```

これで90日前のログを自動で削除する
React.js HelloWorldで理解するJSXの書き方(初歩的)

React.js の勉強をはじめました。

Hello World を書いてみます。
Reactは同時にJSXも使われるようですが、JSXがあると理解するのが難しいので、はじめはJSX無しで書いてみました。

# JSX無しで作ったReact.js Hello World

```html:hw01.html
<!DOCTYPE html>
<html>
  <head>
    <script src="https://fb.me/react-15.2.0.js"></script>
    <script src="https://fb.me/react-dom-15.2.0.js"></script>
  </head>
  <body>
    <div id="app01"></div>
    <div id="app02"></div>

    <script>
      const HelloWorld = React.createClass({
        render: function() {
          return React.DOM.div({},
            'Hello World ' +
            this.props.name);
        }
      });

      const hwElement = React.createElement(HelloWorld, {name: '01'});
      ReactDOM.render(hwElement,
        document.getElementById('app01'));

      const hwFactory = React.createFactory(HelloWorld);
      ReactDOM.render(hwFactory({name: '02'}),
        document.getElementById('app02'));

    </script>

  </body>
</html>
```

出力結果のHTML要素は、このようになります

```html
<body>
    <div id="app01"><div data-reactroot="">Hello World 01</div></div>
    <div id="app02"><div data-reactroot="">Hello World 02</div></div>
```

# JSXありで作ったReact.js Hello World

```html:hw02.js
<!DOCTYPE html>
<html>
  <head>
    <script src="https://fb.me/react-15.2.0.js"></script>
    <script src="https://fb.me/react-dom-15.2.0.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js"></script>
  </head>
  <body>
    <div id="app01"></div>
    <div id="app02"></div>

    <script type="text/babel">
      const HelloWorld = React.createClass({
        render: function() {
          return <div>Hello World {this.props.name}</div>;
        }
      });

      const hwElement = <HelloWorld name="01" />;
      ReactDOM.render(hwElement,
        document.getElementById('app01'));

      ReactDOM.render(<HelloWorld name="02" />,
        document.getElementById('app02'));
    </script>


  </body>
</html>
```
babel-core をCDN(webでリンクするscriptのやり方) でリンクして script タグに text/babel をつけることで、script内をJSXとして解釈してくれます。

JavaScript 内にHTMLタグが含まれているのは奇妙な感じですね。

# 参考
[Sy] npmを使わずにReactの開発環境を構築する方法（CDNで配信されているReactとbabel-coreを利用） | Syntax Error.
https://utano.jp/entry/2016/07/react-js-load-from-cdn/

FN1608001 | React: まずは動かしてみる | HTML5 : テクニカルノート
http://www.fumiononaka.com/Business/html5/FN1608001.html

# 追記

サンプルが React 15.2 の例で、16.0 以降に対応していなかったので、新しい記事を書きました。

React16 CDN でHelloWorld JSXありなし両方 - Qiita
https://qiita.com/standard-software/items/0cdbcdb2a6d6355c946b
Karabiner elements 設定例

Sierra で karabiner が動かなくなったので、Karabiner elements に移行しました。
左利き用の下記設定です。

- shift+delete to command+v
- fn+delete to command+c

```~/.config/karabiner/assets/complex_modifications/123456789.json
{
  "title": "Lefty Key",
  "rules": [
    {
      "description": "Change shift+delete to command+v",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "delete_or_backspace",
            "modifiers": { "mandatory": [ "right_shift" ] }
          },
          "to": [
            {
              "key_code": "v",
               "modifiers": ["right_command"]
            }
          ]
        }
      ]
    },
        {
      "description": "Change fn+delete to command+c",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "delete_or_backspace",
            "modifiers": { "mandatory": [ "fn" ] }
          },
          "to": [
            {
              "key_code": "c",
               "modifiers": ["right_command"]
            }
          ]
        }
      ]
    }
  ]
}
```
HttpClientでmultipart/form-dataでのファイル送信で日本語のファイル名が文字化けする


#使用環境
C#
.NET 4.0 (NugetでMicrosoft.Net.Httpをインストール済み)
※たぶん4.5以降も同じです。

#やりたかったこと
WebApiをコンソールアプリから呼び出したかったんです。
でもWebClientクラスでは1回のPOST送信で複数ファイル送れないじゃない！

HttpClientならできる？でも.NET4.5以降のものだしなぁ・・・

と思ったらNugetで配信されてた（Microsoftさんありがとう！）

#ファイル送信ソース
[こちらさん](https://qiita.com/volpe28v/items/b86e0bc9db8e42688cc3)の記事を参考にしながら下記を記述

```C#:Program.cs
using (var httpClient = new HttpClient())
using (var multipart = new MultipartFormDataContent())
{
    var finfo = new FileInfo(filePath); // ここは指定のファイルをどうぞ

    var fileContent = new StreamContent(File.OpenRead(finfo.FullName));
    fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
    {
        Name = "file1", // ここは任意の名前で
        FileName = finfo.Name
    }

    multipart.Add(fileContent);

    // 送信
    var postAsyncTask = httpClient.PostAsync(reqestUrl, multipart);
    postAsyncTask.Wait(); // async/awaitは.NET4.0だから使えない...
    var responseMessage = postAsyncTask.Result;
}
```

ちなみに今回は"サンプルファイル.xlsx"というファイル名のファイルを送信している。

##すると受け取り先で...
**ファイル名が文字化け！**
↓こんな感じ
=?utf-8?B?44K144Oz44OX44Or44OV44Kh44Kk44OrLnhsc3g=?=

#対策
いろいろと調べると、勝手にHttpClientくんがファイル名とかを含んだContentDispositionをエンコードしちゃうらしい。
おそらくBase64でエンコードされる。

そこでStack Overflowくんの[この記事](https://stackoverflow.com/questions/21928982/how-to-disable-base64-encoded-filenames-in-httpclient-multipartformdatacontent)を参考にして、対策をおこなう。

```Program.cs
using (var httpClient = new HttpClient())
using (var multipart = new MultipartFormDataContent())
{
    var finfo = new FileInfo(filePath); // ここは指定のファイルをどうぞ

    // 手動でエンコードを行う。
    string headerValue = string.Format("form-data; name=\"{0}\"; filename=\"{1}\"", "file1", finfo.Name);
    byte[] headerValueByteArray = Encoding.UTF8.GetBytes(headerValue);
    var encodingHeaderValue = new StringBuilder();
    foreach (byte b in headerValueByteArray)
    {
        encodingHeaderValue.Append((char)b);
    }

    fileContent.Headers.Add("Content-Disposition", encodingHeaderValue.ToString());

    multipart.Add(fileContent);

    // 送信
    var postAsyncTask = httpClient.PostAsync(reqestUrl, multipart);
    postAsyncTask.Wait(); // async/awaitは.NET4.0だから使えない...
    var responseMessage = postAsyncTask.Result;
}
```

自分のつたない英語力では「こんな感じで先にエンコードしてやるんやで」
ぐらいのニュアンスしかつかめなかったが、とりあえずこれで文字化けしなかったのでよしとする。

#結論
HttpClientくんが余計なことをしてるので、こんな感じでやってあげよう。
もしかしたらNugetでHttpClientやWebClientの不便な部分を埋めると多分ヒットすると思う。（自分はむり）

先人の方たちの記事に感謝
[メモ] React(+Redux) を書くときに注意した方がいいこと

# この記事は
完全にメモです。

# 内容
### Q. 例えば Header コンポーネントを作るとして、そこに配置するボタンの情報については props で渡す？それとも Header コンポーネント側にべた書き？
べた書きで良い。なぜなら、そのアプリケーションにおいて Header コンポーネントを何度も使いまわすことは考えづらいからだ。
"そのアプリケーションにおいて"再利用するかどうか、が判断材料となる。

### Q. Rails APIモード + React とかで書いていると、どうしても React にロジックを書くことが増えてしまって困るのだが、どうすればいい？ Rails 側に M と C の役割を担わせ、フロントエンド側はあくまで V に徹するものかと思っていたのだが。。
まず、その構成ならば Rails 側はただの API サーバなので、フロントエンド側にロジックが存在することはしょうがない(?)
ただし、React はあくまでも View。
なので、Redux などを導入して、logic はそこに移すべし。
Redux を導入するのは state 管理を用意にするため、とよく言われるが、state をいじるという行為がまさに logic に当たる。
API 呼び出しだけなら問題ないこともあるが、それに付随する受け取ったデータの加工とかは呼び出し元によって違うことが多いので、コールバックにしといたほうがコンポーネント性が高まる。

### Q. localStorage って使っていいの？ state との使い分けは？
永続化したい情報は localStorage に保存してよい。
例えば、ログイン情報など。state に保存してもリロードしたら消えてしまうので。

ただし、localStorage を触るところは(トップレベルに近い)特定のコンポーネントに限定した方がいい。
具体的には、onClick() などでコールバックとして localStorage に設定するようにして、その関数を props として渡すことになる。
API 呼び出しとかも同様の方法を取るべし。

### React 導入してしばらく経ってから、あとから Redux を入れるは大変？
きれいな React を書けていればいるほど、それだけ Redux の導入は容易。
やってみよう。
[WordPress] タグアーカイブのパーマリンクをタグIDにする

# やりたいこと
タグのスラッグ使わないで　`http://example.com/tag/{$term_ID}/` の形にする。
デフォルトだと意識してタグのスラッグを編集しない限りタグの名前が自動でスラッグになるので、2バイトだと `/tag/%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89/` となってちょっと、、、という場合に。
投稿タグのフィードやページ送りもバッチリOK。

なお、カテゴリーアーカイブのパーマリンクをカテゴリーIDにしたい場合は以下の記事参照。

* [カテゴリーのパーマリンクをカテゴリーIDにするよ](http://www.warna.info/archives/2758/)


# ソースコード

はいどーん。

```php
<?php
function numeric_term_link( $url, $term, $taxonomy ) {
    global $wp_rewrite;

	// post_tag only
	if ( $taxonomy == 'post_tag' ) {
		if ( $wp_rewrite->using_permalinks() ) {
			$permastruct = $wp_rewrite->get_extra_permastruct( 'post_tag' );
			$permastruct = str_replace( '%post_tag%', $term->term_id, $permastruct );
			$url = home_url( user_trailingslashit( $permastruct, 'tag' ) );
		}
	}
	return $url;
}
add_filter( 'term_link', 'numeric_term_link', 10, 3 );

function add_tag_id_to_qvar( $vars ) {
	$vars[] = 'tag_id';
	return $vars;
}
add_filter( 'query_vars', 'add_tag_id_to_qvar' );

function numeric_tag_rewrite_rules( $rules ) {
	$custom_rules = array();
	foreach ( $rules as $regex => $rewrite ) {
		$regex = str_replace( '/(.+?)/', '/([0-9]{1,})/', $regex );
		$rewrite = str_replace( '?tag=', '?tag_id=', $rewrite );
		$custom_rules[$regex] = $rewrite;
	}
	return $custom_rules;
}
add_filter( 'post_tag_rewrite_rules', 'numeric_tag_rewrite_rules' );
```

1. `term_link` のフィルターフックで `numeric_term_link()` を実行し、投稿タグアーカイブへのリンクをスラッグらタグIDになるよう変更。なおこれはURLのみを変更するのでこれだけでは片手落ち。
2. リライトルールでタグIDを使えるように `query_vars` のフィルターフックで `tag_id`を追加しておく。
3. リライトルールにフックは色々あるけど、`post_tag_rewrite_rules` で投稿タグのリライトルールに限定して改変。
4. **最後に管理画面の「パーマリンク設定」を変更せずに更新すること**

現場からは以上です。
chinachuの保存先を外付けHDDにする。

chinachuの録画データの保存先を、外付けHDDにするには、所有者変更が必要でした。
基本なのかも知れませんが、私は知らなかったため備忘録的に残します。

なお、外付けHDDの接続〜マウントは以下を参照。
http://sooch.hatenablog.com/entry/2017/03/26/061032

##フォルダ作成
```
$ cd /mnt/hdd1
$ sudo mkdir recorded
```

##所有者変更
###現状の設定
```
#デフォルトの保存先
$ ls -al ~/chinachu/
drwxr-xr-x 2 pi   video 4096 Dec 30 12:55 recorded

#今回作成した保存先
$ ls -al /mnt/hdd1
drwxr-xr-x 2 root root  4096 Dec 30 13:10 recorded
```

###変更
```
$ sudo chown pi recorded
$ sudo chown :video recorded
```

###確認
デフォルトと所有者設定が同じになっていればOK

```
$ ls -al
drwxr-xr-x 2 pi   video  4096 Dec 30 13:10 recorded
```

##保存先を外付けに変更
ブラウザでChinachuを開き、設定画面で以下のように変更します。
`"recordedDir" : "./recorded/",`
→`"recordedDir" : "/mnt/hdd1/recorded/",`

これで保存先の変更は完了。

##あとがき
なお、設定変更後録画をしたら、ダウンロードやストリーミング視聴がグレーアウトしていました。
私はブラウザのキャッシュのクリアをすることで解決しました。
PHPでのセキュリティ(のメモ)

###(1) SQLインジェクション対策
SQL は prepare() を使って記述する。
ここで、変数は「?」を使う。「.」等で変数を接続してはいけない。

```php
$user_id = "1234";
$kind = "test";
$sql = "SELECT id, data FROM table_name WHERE id=? AND kind=?";
$stmt = $pdo->prepare($sql);
$stmt->bindParam( 1, $user_id, PDO::PARAM_STR);  // 1つめの ? に 1234
$stmt->bindParam( 2, $kind, PDO::PARAM_STR);     // 2つめの ? に test
$stmt->execute();
```

---

###(2) XSS対策
変数を画面に表示する場合は htmlspecialchars() を使う。

```php
echo '<h1>idは'.htmlspecialchars($user_id).'です。</h1>';
```

---

###(3) スクリプトインジェクション対策
ユーザーが画面から入力する文字列などは、HTMLタグや PHPタグを取り除くと安心。

```php
$comment = strip_tags($_POST["comment"])
```

---

###(4) CSRF対策
ログイン後に、session_regenerate_id を実行する。

```php
session_regenerate_id(true);
```

ログアウト後に、session_destroy を実行する。

```php
// セッションクリア
session_destroy();
```

---

###(5) CSRF対策 その2
遷移元画面でユーザーが情報を選択し、OKボタンをクリックして、
遷移先画面でSQLでデータを更新(INSERT,UPDATE、DELETE)する。
選択情報は、GETデータで選択内容を引き継ぐ。
という場合、ユーザがログインセッションを保持している状態で、悪意のあるページが遷移先画面のURLをたたかせると意図しないSQLが発行される。
(ぼくはまちちゃん！ 的な問題)
このため、遷移元画面から遷移先画面へはトークンを連携するなどして、正しい遷移元である確認をする。

遷移元

```php
// ランダムな8桁の数字でトークンを作る
$token = random_int( 10000000, 99999999 );
// セッションにトークンを入れる
$_SESSION["TOKEN"] = $token;

// URLにもトークンを入れる
echo '<a href="next.php?token='.$token.'">次のページ</a>';
```

遷移先

```php
// セッションとURLのトークンが一致しなかったら処理しない
if( $_SESSION["TOKEN"] != $_GET["token"] ) {
  die("トークンが一致しません。");
}
```

---

###(6) クリックジャッキング対策
.htaccessファイルに下記の命令を記述する。

```apache
Header set X-FRAME-OPTIONS "DENY"
```

または、PHPでHTMLを書く前に、header()をコールする。

```html+php
<?php
  // クリックジャッキング対策
  header('X-FRAME-OPTIONS: DENY');
?>
<!doctype html>
<html>
…
```

クリックジャッキング対策ができているか確認。
下記のような感じで、適当なファイル(hoge.html)を作る。
「http://…/index.php」の部分にテストしたいURLを入れる。
なにもしていないと画面が表示されるが、クリックジャッキング対策をすると、空白になる。

```html
<html>
  <iframe src="http://…/index.php" width="800" height="1000">
  </iframe>
</html>
```
MacにNode.jsの開発環境を構築する

Node.jsの管理はnodebrewが楽なのでnodebrewを使いましょう。
nodebrewはhomebrewでインストールします。

###Homebrewのインストール
[homebrewのインストール（公式）](https://brew.sh/index_ja.html)

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

###nodebrewのインストール
:one: インストール可能なバージョンを確認する

```
$ nodebrew ls-remote
```

:two: インストール

今回はv8を入れたいと思います。
以下で8の最新を入れます

```
$ nodebrew install-binary v8
Installed successfully
```

:three: インストールできてるか確認

```
$ nodebrew ls
v8.11.2

current: none
```

:three: 使うバージョンを指定する

```
$ nodebrew use v8
use v8.11.2
```

:two: インストールが終わったら環境変数の設定をする。

```
$ vi .bash_profile
```
　`.bash_profile`に以下を書き込む。

```
export PATH=$PATH:$HOME/.nodebrew/current/bin
```
　　`.bash_profile`再読み込み

```
$ source .bash_profile
```

###Node.jsのインストール
環境変数を設定したらnodebrewが使えるようになるので、早速Node.jsをインストールしましょう。

バージョンは安定版（stable）のインストールがおすすめです。

```
$ nodebrew install-binary stable
```
`nodebrew use`で、使うバージョンを切り替えます。

```
$ nodebrew use stable
```
Docker for MacでPHP-FPMがエラー(9000 failed: port is already allocated)

## 概要
今まで、vagrantでCentOSを起動し、dockerを使っていたが、
Docker for Macが便利そうなので使ってみたら、PHPが起動しなかったので、
調べた結果をメモに残しておく。

## エラー内容
どうも9000ポートが使われていると怒られたみたい。

```
ERROR: for php  Cannot start service php: driver failed programming external connectivity on endpoint php (ec901c1c728298639448dc8ea1f049f1b3d2bbadc3618a6562535afc8d9cc86a): Error starting userland proxy: Bind for 0.0.0.0:9000 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.
```

### 誰が9000ポート使っているか？
下記コマンドで調べられるようなので実行してみると...

```bash
$ lsof -i :9000
COMMAND   PID     USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
idea    14197  sono  799u  IPv4 0x833fd9533585d4d1      0t0  TCP *:cslistener (LISTEN)
```

どうやら、IntelliJさんが使ってそう・・・
IntelliJの設定を確認して見るとPHPがデバッグで９０００ポートを使っていた。

<font color=red>Preferences -> Languages & Frameworks -> PHP -> Debug</font>

Xdebugの項目の「Debug port:9000」がどうも原因のようなので、<font color=red>9001</font>に変更する。

## 参考サイト
* [IntelliJ IDEA13 PHP開発環境設定メモ](http://nocono.net/post/2013/29/)
* [Macで使っているPortを調べる方法](https://qiita.com/cozycozy/items/972f3e2866b2dfb0f297)
（弁護士向け）あるディレクトリ以下のファイルの更新日を一覧化し，Excelでフィルターをかけつつ数え上げる。

労働時間の立証等で，PC内部のファイル更新日を一覧化して証拠化したい場面があろうかと思います。
ファイル一覧をうまいことExcelで読み込める形にしたあと，Excelでうまいこと数え上げると，有効な証拠になり得るかと思います。
#ファイル名＆更新日一覧の書き出し
##全ファイル探索関数の定義
[Pythonで再帰的にファイル・ディレクトリを探して出力する - Qiita](https://qiita.com/suin/items/cdef17e447ceeff6e79d)
を参考に（というか関数を丸パクリ）して，find_all_files関数を作ります。
（丸パクリするだけなのでコード略）

##ファイル名（パス付き），更新日，更新時刻　をタブ区切りで書き出す。
ファイル名にカンマが含まれている場合の処理が面倒なので，CSV（カンマ区切り）ではなくTSV（タブ区切り）で書き出しましょう。
もっとも，ファイルの書き出しのためわざわざTSVファイルの入出力を書くのは意外と手間がかかります。
（エクセルがShift-JISで読み込もうとするため。）
単純にprintで標準入出力に表示させて，適当なエディタ（例：CotEditor）にコピペして，文字コードをShift-JISにして拡張子.tsvで保存するのが吉。

```python3:sample.py
import os, time
 # 前記の関数パクリ部分略
dateformat = '%Y-%m-%d\t%H:%M:%S'
for file in find_all_files("./"): # パクったyieldで回す
    print(os.path.relpath(file) +"\t"+ time.strftime(dateFormat, time.localtime(os.path.getmtime(file))))
```
#Excelで開いて色々付け足す。
上記の過程を経て作成された.tsvファイルをExcelで開きます。
【ファイルパス，日付，時刻】の３列からなるファイルになっています。
##曜日列を付け足す
好きな行（私は時刻の右）に曜日列を作ります。
`=TEXT(B1,"AAA")`で，日付データから曜日文字列を出すようにします。
日付そのものではなく曜日文字情報にすることで，曜日でのフィルター（例えば休日労働の抽出）ができるようになります。
##見出し行を付け足す
見出し文字列はお好みで。私の場合，「ファイル名（パス），最終更新日，最終更新時刻，曜日」。
##フィルター済みファイル総数を表示する行を追加する。
先頭に空行を挿入し，`=SUBTOTAL(3,A3:A●)`（※●は最終行）なセルを作ります。
##日付の個数を数える。
###２行目に空行を挿入する（表示用）
あとで使います。
###ダミー列を２列作る。
右端（※印刷範囲指定で容易に除外できるため）に`dummy1`,`dummy2`の列を作ります。
`dummy1`列（手順通りならE列）は，「フィルターされた時は空欄」のセルにします。
`=IF(SUBTOTAL(3,A4), B4, "")` ※既に総数表示行・日付数表示行・見出し行を追加したので，4行目開始。

`dummy2`列（手順通りならF列）は，「同じ行のdummy1が存在するものであって，日付が同じものの逆数」のセルにします。これにより，同じ日付のF列を足し上げると1になることから，F列を足し上げることで日付の個数をカウントできるわけですね。
`=1/COUNTIF(E$4:E$●, E4)`（※●は最終行）

###dummy2列を足し上げて表示する
既に作成済みの２行目の任意のセルに，`=SUBTOTAL(9, $F$4:$F$●)`（※●は最終行）を入力。


あとは印刷範囲やフィルターや印刷タイトル行等をお好みで設定。
Enjoy!
![スクリーンショット 2018-01-10 14.03.34.png](https://qiita-image-store.s3.amazonaws.com/0/192970/17c97459-b800-6289-8335-5f65ccc26ef8.png)

#その他の参考
-[エクセルでフィルターをかけたセルを重複を除いて都度計算でカウントする方法 - Qiita](https://qiita.com/Ping/items/46548f7f3e03e7bda014)
PythonでFTPからダウンロード

#概要
・FTPサーバ機能を有するデータロガーより自動でデータをダウンロードしたい。

#試行錯誤
・ダウンロード対象はその日毎のcsvファイル一式
・wgetコマンドをFTPサーバへ向けるがうまくダウンロードしない。
・このコマンドはHTMLサーバ向け？
・そこでPythonに任せた

#コード
```python3
from ftplib import *
import io
import sys
import os

ftp = FTP('192.168.***.***')
ftp.login('user', 'password')
ftp.cwd('/CF/ENR1/Log/') #サーバの対象フォルダ
ftemp = ftp.nlst('.') 
for file in ftemp:
    files = file[len('/CF/ENR1/Log/')-7:] #パス名./を削除
    print(file)
    with open('../data/ENR1/' + file, 'wb') as f: #ローカルパス
        ftp.retrbinary('RETR %s' % file, f.write)
ftp.quit()

#本当は何度も同じコマンドを発行しない？
ftp = FTP('192.168.***.***')
ftp.login('user', 'password')
ftp.cwd('/CF/SENSOR/Log/')
ftemp = ftp.nlst('.')
for file in ftemp:
    files = file[len('/CF/SENSOR/Log/')-7:]
    print(file)
    with open('../data/SENSOR/' + file, 'wb') as f:
        ftp.retrbinary('RETR %s' % file, f.write)
ftp.quit()
```

#終わりに
・cron使えば勝手にダウンロードしてくれる。
・ローカル側にファイルが既にあるか確認はしていない。
・コードはもっと簡単にできるはず。
・いろんなコメントお待ちします。
Swiftで最速でTwitterシェア機能を実装する


urlスキーマを使って実装してみた。

1. info.plistに以下を設定する

![image.png](https://qiita-image-store.s3.amazonaws.com/0/51402/c8123e44-6f7c-7fab-9c50-1ccc2c82bba3.png)

2. コードを書く

```swift
let text = "シンプルに月齢がわかるカレンダーアプリ https://itunes.apple.com/us/app/月齢カレンダー/id1330557522?l=ja&ls=1&mt=8"
                        .addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
var url = URL(string: "twitter://post?message=\(text)")!
if UIApplication.shared.canOpenURL(url) {
    UIApplication.shared.open(url)
} else {
    url = URL(string: "https://twitter.com/intent/tweet?text=\(text)")!
    UIApplication.shared.open(url)
}
```

urlスキーマで開けない場合はsafariを使うようにした

こちらのアプリにもうすぐ実装予定

https://itunes.apple.com/us/app/月齢カレンダー/id1330557522?l=ja&ls=1&mt=8
【webpack】(2018年1月現時点で)ES2015 (ES6)のままminifyする方法

---
**※この記事は2018年1月に書いた記事です。**

[【webpack】(2018年2月25日現時点で)ES2015 (ES6)のままminifyする方法](https://qiita.com/ota-meshi/items/8d30743fd72f8389628c)を新しく書いたのでこちらを参照したほうが幸せになれると思います。
こちらの結論は、[webpack](https://webpack.js.org/)`v4.0.0`使えということになります。  

残念ながら[webpack](https://webpack.js.org/)`v4.0.0`には出来ないという方はこの記事を読み進めてください。

---
<br>


去年も[【webpack】(現時点で)ES2015 (ES6)のままminifyする方法](https://qiita.com/ota-meshi/items/e60fa3778c0e53ac6a56)という記事を書きましたが、
最近はまた違う方法で出来るので記事を書きます。
（[前回](https://qiita.com/ota-meshi/items/e60fa3778c0e53ac6a56)よりは公式っぽいツールを使います。）



# 初めに[webpack](https://www.npmjs.com/package/webpack)標準のminifyツール

[前回記事](https://qiita.com/ota-meshi/items/e60fa3778c0e53ac6a56)にもう少し詳細を書きましたが、
[webpack](https://www.npmjs.com/package/webpack)でminifyする場合、通常は[webpack](https://www.npmjs.com/package/webpack)の中の`webpack.optimize.UglifyJsPlugin`を利用しますね。
ただしこの場合ES5でjavascriptを記述するか、ES5へのトランスパイルが必須になります。

（現在[webpack](https://www.npmjs.com/package/webpack)は`v3.10.0`）

# [uglifyjs-webpack-plugin](https://www.npmjs.com/package/uglifyjs-webpack-plugin)  
[uglifyjs-webpack-plugin](https://www.npmjs.com/package/uglifyjs-webpack-plugin)は[webpack](https://www.npmjs.com/package/webpack)の`webpack.optimize.UglifyJsPlugin`の実態です。

[リンク先](https://www.npmjs.com/package/uglifyjs-webpack-plugin)のドキュメント見ると、ES6に対応している風です。
早速試してみました。

## [uglifyjs-webpack-plugin](https://www.npmjs.com/package/uglifyjs-webpack-plugin)のインストール
[webpack](https://www.npmjs.com/package/webpack) `v3.10.0`の依存関係にある[uglifyjs-webpack-plugin](https://www.npmjs.com/package/uglifyjs-webpack-plugin)は`v0.4.6`と古い様子なので、個別にインストールします。

```bash
npm i -D uglifyjs-webpack-plugin
```

私がインストールしたときのバージョンは`v1.1.6`でした。

## `webpack.optimize.UglifyJsPlugin`にES6のOptionをつけてみる（失敗）

https://www.npmjs.com/package/uglifyjs-webpack-plugin#uglifyoptions
にあるように`uglifyOptions: {ecma: 6}`とOptionをつけてみます。

```js:webpack.config.js
module.exports = {
  // ・・・
  plugins: [
    new webpack.optimize.UglifyJsPlugin({uglifyOptions: {ecma: 6}}),
  ],
  // ・・・
}
```

としてみました。ただしこれだと失敗します。
[webpack](https://www.npmjs.com/package/webpack) `v3.10.0`の依存関係にある[uglifyjs-webpack-plugin](https://www.npmjs.com/package/uglifyjs-webpack-plugin)は`v0.4.6`と古いので
このコードでは`v0.4.6`の[uglifyjs-webpack-plugin](https://www.npmjs.com/package/uglifyjs-webpack-plugin)が呼ばれていました。

## [uglifyjs-webpack-plugin](https://www.npmjs.com/package/uglifyjs-webpack-plugin)にES6のOptionをつけてみる（成功）
以下のように変更します。

```js:webpack.config.js
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
  // ・・・
  plugins: [
    new UglifyJsPlugin({uglifyOptions: {ecma: 6}}),
  ],
  // ・・・
}
```


めでたく、ES2015 (ES6)のままminifyできましたー:raised_hands:

---

~~[webpack](https://www.npmjs.com/package/webpack)の公式対応はいつなんでしょう？~~
[webpack](https://webpack.js.org/)`v4.0.0`で標準対応されました！！
【WordPress】カスタム投稿タイプの追加方法

# 1.functions.phpに処理を追加

以下の処理を**functions.php**に追加する。この時、投稿タイプの定義も同時に行う
（以下の例は投稿タイプを**news**としています）

```functions.php
add_action( 'init', 'create_post_type' );
function create_post_type() {
	register_post_type( 'news', [ // 投稿タイプ名の定義
		'labels' => [
			'name'          => 'ニュース', // 管理画面上で表示する投稿タイプ名
			'singular_name' => 'news',    // カスタム投稿の識別名
		],
		'public'        => true,  // 投稿タイプをpublicにするか
		'has_archive'   => false, // アーカイブ機能ON/OFF
		'menu_position' => 5,     // 管理画面上での配置場所
        'show_in_rest'  => true,  // 5系から出てきた新エディタ「Gutenberg」を有効にする
	]);
}
```

もっと細かく設定できるようです。
**参考URL**

- [関数リファレンス/register post type - WordPress Codex 日本語版](http://wpdocs.m.osdn.jp/%E9%96%A2%E6%95%B0%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9/register_post_type)
- [Wordpress カスタム投稿でカテゴリを使う場合のfunctions.phpの内容 | FROG-EIGHT](http://frog-eight.com/technical/wordpress-%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E6%8A%95%E7%A8%BF%E3%81%A7%E3%82%AB%E3%83%86%E3%82%B4%E3%83%AA%E3%82%92%E4%BD%BF%E3%81%86%E5%A0%B4%E5%90%88%E3%81%AEfunctions-php%E3%81%AE%E5%86%85/)


# 2.single-[post_type].phpを作成する
上記の例の場合は**single-news.php**となる


# 3.管理画面からカスタム投稿タイプで投稿する
上記の例の場合は**ニュース**で表示されているのでそこから投稿する。
![WS000083.JPG](https://qiita-image-store.s3.amazonaws.com/0/85815/f65b3a3a-3f4d-bc87-0324-b55a88215199.jpeg)


# 4.管理画面からパーマリンクの変更を保存する

![WS000084.JPG](https://qiita-image-store.s3.amazonaws.com/0/85815/56fa1305-cbd1-457d-e05c-41cc1a67ed4f.jpeg)


これを行わないと、おそらく「ページが見つかりません（404エラー）」ページが表示されると思います。
（function.phpに書いた処理内に`flush_rewrite_rules`を追記する、といった記事も見かけたのですが、コストが高く、またこの関数が原因で他のプラグインがおかしくなるとうが起こるみたいでやめた方がいいとのこと。）

**参考URL**

- [いい加減 flush_rewrite_rules を書くのはやめてください！！ – Toro_Unit](https://torounit.com/blog/2015/09/02/2077/)
- [WordPress » パーマリンクの設定がうまく反映されない時の対処法 | MORILOG](http://morilog.com/wordpress/tips/flush_rewrite_rules/)


# 5.投稿した記事の確認
見れるか該当のURLにアクセスして確認する


# 参考URL
- [新たに投稿機能を追加！カスタム投稿タイプとタクソノミーの設定！](http://wp-technique.com/custom-post-type/)
- [Wordpress カスタム投稿タイプの作り方 - Qiita](https://qiita.com/nagasawaaaa/items/9501c0a2e544d85ee78d)
Sympyでsqrt(a**2)をaと表示する方法（a>0）

# はじめに
SympyというPythonの代数計算ライブラリ（http://www.sympy.org/ ）がある。Woflram社のMathematicaと類似の計算を行うことが可能である。

このソフトウェアの関数のなかに、sqrt()という1/2乗を計算する関数があるのだが、素朴にsqrt(a**2)を打ち込むと

```python3
In [1]: import sympy
In [2]: from sympy import *
In [3]: a = symbols("a")
In [4]: sqrt(a**2)
Out[4]: sqrt(a**2)
```

と打ち込むと、根号がとれない。$a$の符号について事前知識があれば、とってほしい。それを行う方法についてのメモである。

# 環境について
* Python
    * Python 3.6.2
* Sympy
    * 1.1.1
      
# Sympyでsqrt(a**2)をaと表示する方法（a>0）
「はじめに」にも書いたように$a$の符号に関する事前知識がないために根号がとれない。ドキュメントを読むと下記のように書いてある。つまり、少なくとも以下の３通りの方法がある。

* 事前にシンボルに符号を指定しておく
* powdenest()を使用して無理やり根号を外す

以下のドキュメント見れば終わりという感じもするが、せっかくなので日本語で書いておく。

> Note that sqrt(x**2) does not simplify to x.

> ```python3
>>> sqrt(x**2)
sqrt(x**2)
```

> This is because the two are not equal to each other in general.
> For example, consider x == -1:

> ```python3
>>> from sympy import Eq
>>> Eq(sqrt(x**2), x).subs(x, -1)
False
```

> This is because sqrt computes the principal square root, so the square may
put the argument in a different branch.  This identity does hold if x is
positive:

> ```python3
>>> y = Symbol('y', positive=True)
>>> sqrt(y**2)
y
```

> You can force this simplification by using the powdenest() function with
the force option set to True:

> ```python3
>>> from sympy import powdenest
>>> sqrt(x**2)
sqrt(x**2)
>>> powdenest(sqrt(x**2), force=True)
x
```

## 事前に符号を指定しておく方法
sqrtの中に入れる記号の符号を事前に指定する方法である。このためには、記号定義を行う際にpositive=Trueとして正とするか、negative=Trueとして負とする。

```python3
In [6]: a = symbols("a", positive=True)
In [7]: sqrt(a**2)
Out[7]: a

In [8]: a = symbols("a", negative=True)
In [9]: sqrt(a**2)
Out[9]: -a
```

たしかに根号がとれる。

## powdenest()を使用する方法
次に少し危険そうな方法として、無理やり外す方法がある。

```python3
In [14]: a = symbols("a")

In [15]: powdenest(sqrt(a**2),force=True)
Out[15]: a
```

確かにあたかも$a>0$であるかのようにとれる。しかし、

```python3
In [19]: powdenest(sqrt(a**2),force=True).subs([(a,-1)])
Out[19]: -1
```

となってしまうので注意が必要である。
LaravelのFakerを日本語化する

Laravelには標準でFakerが含まれていて、ダミーデータを作るのに便利です。
https://laravel.com/docs/5.5/database-testing#writing-factories

Fakerが生成してくれるダミーデータは設定を変える事によって日本語にすることができます。

Fakerの初期化処理は

```php:laravel/framework/src/Illuminate/Database/DatabaseServiceProvider.php
 /**
     * Register the Eloquent factory instance in the container.
     *
     * @return void
     */
    protected function registerEloquentFactory()
    {
        $this->app->singleton(FakerGenerator::class, function ($app) {
            return FakerFactory::create($app['config']->get('app.faker_locale', 'en_US'));
        });

        $this->app->singleton(EloquentFactory::class, function ($app) {
            return EloquentFactory::construct(
                $app->make(FakerGenerator::class), $this->app->databasePath('factories')
            );
        });
    }
```

という風になっており、初期化時のlocaleを設定で変更可能です。

よって設定ファイルに設定を追記します。

```php:config/app.php
'faker_locale' => 'ja_JP',
```

完了です。
spplotのタイトルの字体を変更する

rでspplotをもちいて地図を描写する際タイトルの字体を変更する必要があったのでメモ。

Rstudio Cloudは[こちら](https://rstudio.cloud/project/9128)


##テストデータをダウンロード＆デフォルトで描写
```
library(sp)
library(raster)
alt <- getData('alt', country='JPN')
spplot(alt)
```
<img width="415" alt="Untitled.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/224794/0331f066-2ab6-6ed7-8b38-3b9fd3d98236.jpeg">


##タイトルを追加（デフォルト）
```
spplot(alt, main="altitude")

```

<img width="436" alt="Untitled.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/224794/2fbabc1e-f2b8-bf06-25b0-08c55233f20f.jpeg">

##タイトルを追加（デフォルト字体＋イタリック）
```
spplot(alt, main=list(label=as.expression(bquote( paste("Altitude of ", italic(.("Japan"))))), cex=1))

```

<img width="411" alt="Untitled.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/224794/54eeef02-f78c-deba-1a99-4a12ea708179.jpeg">

##タイトルを追加（ボールド＋イタリック）
```
spplot(alt, main=list(label=as.expression(bquote( paste(bold(.("Altitude of ")), italic(.("Japan"))))), cex=1))

```

<img width="441" alt="Untitled.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/224794/cb444874-7e59-e4a9-3377-d29f97898a46.jpeg">

##タイトルの文字サイズを変更（ボールド＋イタリック）
```
spplot(alt, main=list(label=as.expression(bquote( paste(bold(.("Altitude of ")), italic(.("Japan"))))), cex=2))
```
<img width="404" alt="Untitled.jpeg" src="https://qiita-image-store.s3.amazonaws.com/0/224794/1e445b9b-6d39-8b12-757a-32151c2924fe.jpeg">
Android のアプリ情報を開く (Delphi)

Android のアプリから、アプリ情報の画面を開くことができます。

詳しくはここを見てくださいませ。
https://developer.android.com/reference/android/provider/Settings.html

インテントで、ACTION_APPLICATION_DETAILS_SETTINGS と package: という文字列にアプリのパッケージ名を連結したものを渡すと開きます。
package: の文字列と連結するのは自分自身でも良いし、別のアプリのパッケージ名を指定すれば、そのアプリの設定画面を開くこともできます。

## サンプルコード

```delphi
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Controls.Presentation,
  Androidapi.Jni, Androidapi.JNI.JavaTypes, Androidapi.Helpers, Androidapi.JNIBridge,
  Androidapi.JNI.Util, Androidapi.JNI.GraphicsContentViewText, Androidapi.Jni.Provider,
  Androidapi.Jni.Net, Androidapi.Jni.App
  ;

type
  TForm1 = class(TForm)
    ToolBar1: TToolBar;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { private 宣言 }
  public
    { public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
  Intent: JIntent;  // インテント
  uri: string;      // URI package: + パッケージ名
begin
  // 自分自身のパッケージ名を取得するには TAndroidHelper.Context.getPackageName を使用します
  // IDE のメニューから、プロジェクト|オプションで、バージョン情報を開き、package キーに指定された名前が取得されます
  // デフォルトだと com.embarcadero.プロジェクト名です

  // ACTION_APPLICATION_DETAILS_SETTINGS を使う際には
  // package: の文字列の後に、取得したパッケージ名を連結したものを送る必要があります

  // パッケージ名ですが、デバイスにインストールされているアプリのパッケージ名を指定すると
  // 指定されたアプリのアプリ情報画面を出すことができます

  uri := 'package:' + JStringToString(TAndroidHelper.Context.getPackageName);
  Intent := TJIntent.JavaClass.init(TJSettings.JavaClass.ACTION_APPLICATION_DETAILS_SETTINGS, StrToJURI(uri));

  // startActivity を使ってインテントを飛ばして、アプリ情報の画面を開きます
  TAndroidHelper.Activity.startActivity(Intent);
end;

end.
```

## 実行してみる
![Screenshot_2017-12-27-15-20-14.png](https://qiita-image-store.s3.amazonaws.com/0/164551/f9e29fac-2b2e-3e2c-034c-57bbb60cf06e.png)
画面上のボタンを押すと

![Screenshot_2017-12-27-15-20-20.png](https://qiita-image-store.s3.amazonaws.com/0/164551/11524b13-e881-3cfc-40ba-f0c6b03aad91.png)
アプリ情報の画面が開きました！
Centos7でchromeを使ってお手軽Webスクリーンショット取得

# 概要
Webのスクリーンショット取得でCasperJSを使っていたがCSSで問題発生、キャプチャした画像のデザインがちょっとズレてる。
単純なスクリーンショットで十分だったので他の方法を模索中にchromeのヘッドレス機能を使えばいいことに気が付いたので、そのメモ。

**重要なのはコレ**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/16917/4658861f-89f5-04ac-1f37-6324df847bd7.png)


# 実行コマンド
最初にコマンドからいうと1行で済むお手軽さ。

```bash
google-chrome --headless --disable-gpu --screenshot --window-size=1280,1080 https://www.yahoo.co.jp/
```

# インストール
## chrome
まずはchromeをインストール。yumで設定してインストールいいですが、今回はお手軽に以下で。rootで。

```bash
cd /usr/local/src/
wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
yum localinstall google-chrome-stable_current_x86_64.rpm 
```
## 必要ライブラリ
早速google-chromeを実行するとライブラリがないと怒られた。

```bash
/usr/bin/google-chrome: error while loading shared libraries: libEGL.so.1: cannot open shared object file: No such file or directory
```

以下のライブラリをインストール。

```bash
yum install mesa-libGL mesa-libEGL
```

# 実行コマンド
```bash
google-chrome --headless --disable-gpu --screenshot --window-size=1280,1080 https://www.yahoo.co.jp/
```
※1 **screenshot.png**というファイルができる。
※2 rootで実行する時は、--no-sandbox を追加(rootで実行すること自体どうなのかと、、、)。

# javascriptでの例

```test.js
var childProcess = require('child_process');
var targets = [
    { url: 'https://www.yahoo.co.jp/', file:'yahoo.png' },
    { url: 'https://www.google.com/', file:'google.png' }
];
for (var i = 0; i < targets.length; i++) {
    childProcess.exec('google-chrome --headless --disable-gpu --screenshot=' + targets[i]['file'] + ' --window-size=1280,1080 ' + targets[i]['url']);
}
```

# 参考
・ヘッドレス Chrome ことはじめ
https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja
体力ゲージとダメージ処理※編集中

```PlayerDamage.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class PlayerDamage : MonoBehaviour
{
    public GameObject Explosion;
    public int hp = 5;
    Slider _slider;
    //private Renderer render;
    private bool damaged = false;
    public GameObject slider;

    // Use this for initialization
    void Start()
    {
        _slider=slider.GetComponent<Slider>();
    }

    // Update is called once per frame
    void Update()
    {
        _slider.value = hp;//スライダーとHPの紐づけ
    }


    void OnTriggerEnter(Collider collision)
    {
        //衝突した相手のタグがBall2で体力が0より大きいなら
        if (collision.gameObject.tag == "Ball2" && hp>0)
        {
            StartCoroutine("damage");
        }
        if (hp <= 0)
        {
            Instantiate(Explosion, new Vector3(transform.position.x, transform.position.y, transform.position.z), Quaternion.identity);
            Destroy(this.gameObject);
        }
    }

    IEnumerator damage()
    {
        if (damaged) yield break;
        damaged = true;
        hp -= 1;
        print(hp);
        //whileの中を8回繰り返す
        int count = 8;
        while (count > 0)
        {
            //render.material.color = new Color(1f, 0f, 0f, 0.5f);//ダメージを受けた時に半透明にしたかったら//を消す
            yield return new WaitForSeconds(0.05f);//0.05秒待つ
            //render.material.color = new Color(1f, 0f, 0f, 1f);//ダメージを受けた時に半透明にしたかったら//を消す

            count--;
        }
        damaged = false;
    }
}
```
ffmpeg でyuv420 semi planarの画像データを作成する

動画を扱う機器は、映像の内部フォーマットとしてyuv420 semi planarを採用していることが多いと思います。

開発中にはそのフォーマットのデータを見たり、作成したりする場面があります。最初はこれを imagemagik を使ってやろうとしたのですがいまくいかず。
でもffmpegではうまくいきました。ポイントはそのピクセルフォーマットの名称が "nv12" または "nv21" であること。
nv12とnv21の違いはYUVのうちのUとVの位置が入れ替わっているだけ。
(nv12で試して、赤と青が入れ替わっていたらnv21に変えればいい。)

# nv21フォーマットへの変換の方法
```
ffmpeg -i input.jpg -f rawvideo -pix_fmt nv21 out.raw
```
この画像のサイズは 1920x1080 でした。nv21フォーマットのデータサイズはこの1.5倍になります。
1920 x 1080 x 1.5 = 3110400

```
$ ls -l out.raw 
-rw-rw-r-- 1 koba koba 3110400 Jan 10 12:15 out.raw
```

# nv21フォーマットの画像データを見る方法

```
ffplay -video_size 1920x1080 -f rawvideo -pixel_format nv21 out.raw  
```
画像のサイズは引数で指定してあげる必要があります。
プレイヤーが近づいたら会話するキャラクター※編集中

```TextController.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class TextController : MonoBehaviour
{
    [SerializeField]
    Text uiText;
    [SerializeField]
    [Range(0.001f, 0.3f)]
    float intervalForCharacterDisplay = 0.05f;

    private string currentText = string.Empty;
    private float timeUntilDisplay = 0;
    private float timeElapsed = 1;
    private int currentLine = 0;
    private int lastUpdateCharacter = -1;
    public StartConversation Contact;
    public GameObject Player;


    private string[] scenarios = {
        "あいうえお", //ここにはセリフを入れる。””で囲まれている部分が一回で表示されるセリフ。
        "かきくけこ",
        "さしすせそ",
        "たちつてと"
        };


    // 文字の表示が完了しているかどうか
    public bool IsCompleteDisplayText
    {
        get { return Time.time > timeElapsed + timeUntilDisplay; }
    }

    void Start()
    {
       
    }

    void Update()
    {
        
        if (Contact.contact == false)
        { currentLine = 0; }
        // 文字の表示が完了してるならクリック時に次の行を表示する
        if (IsCompleteDisplayText)
        {
            if (currentLine < scenarios.Length && Input.GetMouseButtonDown(0))
            {
                SetNextLine();
            }
            
        }
        else
        {
            // 完了してないなら文字をすべて表示する
            if (Input.GetMouseButtonDown(0))
            {
                timeUntilDisplay = 0;
            }
        }

        int displayCharacterCount = (int)(Mathf.Clamp01((Time.time - timeElapsed) / timeUntilDisplay) * currentText.Length);
        if (displayCharacterCount != lastUpdateCharacter)
        {
            uiText.text = currentText.Substring(0, displayCharacterCount);
            lastUpdateCharacter = displayCharacterCount;
        }
    }


   public  void SetNextLine()
    {
        currentText = scenarios[currentLine];
        timeUntilDisplay = currentText.Length * intervalForCharacterDisplay;
        timeElapsed = Time.time;
        currentLine++;
        lastUpdateCharacter = -1;
    }
}
```
 
```StartConversation.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityStandardAssets.Characters.ThirdPerson;

public class StartConversation : MonoBehaviour
{
    public GameObject TextController;
    public TextController textcontroller;
    public bool contact;
    public GameObject canvas;
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }


    void OnTriggerEnter(Collider collision)
    {
        if (collision.gameObject.tag == "Ball2")
        {
            contact = true;
            textcontroller.SetNextLine();
            canvas.SetActive(true);
                    }
    }

    void OnTriggerExit(Collider collision){
        contact = false;
        canvas.SetActive(false);
            }      
}
```
EC-CUBE3のインストール by composer

# はじめに
EC-CUBE3を使ってみようと思い、環境構築してみたのですが、
それなりにハマッたので、僕のうまくいった方法をメモしておきます。

## ・うまくいかなかった方法
zipでソースボールをダウンロードしてきて、
"インストールスクリプトを利用" する方法でインストール。

[ソースボールの入手]
https://www.ec-cube.net/download/

[手順]
http://doc.ec-cube.net/quickstart_install

[ダメだった箇所]
"phpのTimeZoneを設定しろ"というエラーがどうしても回避できませんでした。
phpinfoで確認しても、ちゃんと設定されているのだけれど。。。

```
Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone.' in /usr/local/my/data/htdocs/eccube-3.0.15/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php:50
```

## ・うまくいった方法
composerを使った方法だと、すんなり？いけました。

[手順（Webインストーラーを利用）]
http://doc.ec-cube.net/quickstart_install


# 構成
・CentOS7
・Apache-httpd 2.2.31
・Postgresql 9.6.5
・PHP 5.6.31
・EC-CUBE3

# インストール
Apache,Postgresql,PHPは、いったん省略。（時間を見つけて更新します）

## 事前準備
・Postgresql に任意のユーザーとデータベースを作ります。
　"ec-cube"とかでOK。ユーザーはフル権限にします。

## EC-CUBE
・Apacheのdocumentrootに移動します。

```
cd /xxx/htdocs
```

・下記の２コマンドを実行 → "ec-cube"というフォルダにインストールされます。

```
curl -sS https://getcomposer.org/installer | php
php composer.phar create-project ec-cube/ec-cube ec-cube "^3.0"
```

・下記フォルダの権限を変更する。

```
chmod 777 -R ec-cube/app
chmod 777 -R ec-cube/html
```

・http://ｘｘｘｘ/ec-cube/html/install.php を開きます。


あとは画面にしたがって入力していくだけです！
AsyncTaskのジェネリクスについて

Android開発でよく使う（？）AyncTaskクラスのジェネリクスの型に何を指定しればいいのかあまり記述のある記事が少なかったので共有します。



## AsyncTask<Params, Progress, Result>

AsynTaskクラスには３つのジェネリクスの型を指定します。

ざっくり説明するとき下記になります

```java
AsyncTask<Params, Progress, Result>
```

* parames：AsyncTaskクラスに渡す値の型、
主に`doInBackground(vararg p0: ~~~~)`で使う
* Progress：非同期処理が実行されているときに使う引数の型、
主に`onProgressUpdate(vararg values: ~~~)`で使う
* Result：実行結果の型、
主に`onPostExecute(result: ~~~)`で使う

３つの引数でとくに値などを使用しない場合は`Void`で指定します

## 参考

http://d.hatena.ne.jp/Nagise/20120309/1331265123
https://dev.classmethod.jp/smartphone/android/asynctask/