OmniAICreator/Qiita-1.07M huggingface dataset:
Gatsby + Netlify + WordPressでHeadless CMS化してみた。

WordPressの表示速度を改善するために、フロントエンドで静的サイトジェネレーターを使う事にした。
英語では「Static site generator」。
使用したジェネレーターはReactベースで爆速の表示速度が魅力的な、Gatsby。
ワックスやジェルとかでお世話になった整髪料ブランドではない。
ほぼ自分用メモ。

#使用技術
Gatsby
https://www.gatsbyjs.org/
Best of JavaScript (https://bestofjs.org/tags/ssg/) ではNext.jsに次ぐ人気。
コミュニティも拡大しており、これからを担う主要な静的サイトジェネレーターになっていくと思われる。

gatsby-starter-wordpress
https://www.gatsbyjs.org/starters/GatsbyCentral/gatsby-starter-wordpress/
GatsbyのWordPress用のテンプレート。
gatsby-source-wordpress（https://www.gatsbyjs.org/packages/gatsby-source-wordpress/）
をベースに作られている。
gatsby.configで色々設定するだけ。簡単。
テンプレートからではなく、一からサイトを作りたい場合は、gatsby-source-wordpressを既存のプロジェクトにnpm installして色々設定した方が良い。

Netlify
https://www.netlify.com/
クライアント側はNetlifyでホスティング。
Webhookを使って、後述のJAMstack Deploymentsで自動デプロイ。

JAMstack Deployments
https://github.com/crgeary/wp-jamstack-deployments
WordPressのプラグイン。これを入れて、NetlifyのBuildhooksで出たAPIキーを管理画面に入力するだけ。
あとはNetlify側で自動ビルド。

#環境構築
Netlifyと連携取るために、まずはGithubアカウントを作成する。
アカウントを作れたら、Netlifyに行き、Netlifyのアカウントを作成。
あとは適当にGithubでリポジトリ作って、Netlifyでリポジトリ選ぶだけ。
Settings->Built & deployで Build hooksがあるので、そこでAPIキー生成しておく。
WordPressサイトも用意しておく。

#Gatsbyの設定
https://www.gatsbyjs.org/docs/quick-start

```
npm install -g gatsby-cli
```

でグローバルにインストール。
あとは、リポジトリ保存してるディレクトリで

```
gatsby new リポジトリ名 https://github.com/gatsbyjs/gatsby-starter-wordpress
```

と叩いて、スターターをインストール。

グローバルにgatsby-cliをインストールしたくない（グローバル環境汚染したくない）場合は、
npxを使うと良い。私は基本npxを使っている。

```
npx gatsby new リポジトリ名 https://github.com/gatsbyjs/gatsby-starter-wordpress
```

インストールできたら、gatsby.configを開いて、
baseUrl, protocol, hostingWPCOM, useACF, verboseOutputを入力。
baseUrlにWordPressをインストールしてるUrlを入力。※http://〜以降の部分。
protocolにはhttpかhttpsかを入力。
hostingWPCOMはWP.comにホスティングしているならtrue、
useACFはAdvanced Custom Fieldsを使っているならtrueにする。
verboseOutputはビルドするときのメッセージを表示するかの設定。
エラーメッセージとかを細かく表示して確認したいなら、true。
別に何も表示しなくて良いのなら、falseで構わない。

ここまで出来たら、コミットしてプッシュしておく。

#WordPressの設定
上述のJAMstack Deploymentsをローカルに落として、インストール。
インストールしたら右上にメニュー出てくるので、クリックして、先ほど生成したAPIキーを入力。
で、投稿とか固定ページとか、更新したらビルド＆デプロイして欲しいページをチェックする。
ちなみに投稿と固定ページにチェック入れた。
あとは投稿増やしたりしたら、自動的にビルドされて、フロントエンドが更新される。
終わり。

#最後に
はじめは、Gatsbyでwordpress用のstarterがある！と喜んだが、
それだけでは、毎回毎回、手動でデプロイしなければいけない事に気付き、一気に萎えた。
だが、前述のJAMstack Deploymentsがあったお陰で、自動ビルド＆デプロイ出来、
WordPressのHeadlessCMS化を本格的にできるようになった。プラグイン作者に感謝。

以下の記事も似たような事が書かれているので、参考に。
https://qiita.com/yahsan2/items/39eb9e3e19f72257084c
FlagShihTzuで無限に増えるboolean型カラムを一つのカラムで管理する

# 無限に増えるboolean型カラム
例えば、「◯◯の通知を受け取る・受け取らない」とか、何とかフラグみたいなものを保持しようとすると、boolean型カラムで管理することになると思います。
これだと、通知のバリエーションとか、何とかフラグが増える度にmigrationが必要になってしまいだんだん辛くなってきます。。:sweat:

```ruby:schema.rb
ActiveRecord::Schema.define(version: 2019_03_08_205817) do

  create_table "users", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "name"
    t.string "email"
    t.boolean "admin", default: false, null: false
    t.boolean "hoge_notification_receivable", default: false, null: false
    t.boolean "fuga_notification_receivable", default: false, null: false
    t.boolean "piyo_notification_receivable", default: false, null: false
    # ...
    # これではbooleanで管理したいものが増える度にmigrationが必要になってしまう・・
  end

end

```

# migration不要でboolean値のバリエーション増加に対応する
その辛み、[FlagShihTzu](https://github.com/pboling/flag_shih_tzu)で解消できます！:innocent:

テーブルに integer型の `flags` カラムを追加し、

```ruby:
change_table :users do |t|
  add_column :users, :flags, :integer, default: 0, null: false
end
```

modelに `FlagShihTzu` をincludeして管理したいboolean値を定義するだけでOKです！

```ruby:user.rb

class User < ActiveRecord::Base
  include FlagShihTzu   # FlagShihTzu をinclude

  # has_flagsでbooleanで管理したい値を定義する
  has_flags(
      1 => :admin,
      2 => :hoge_notification_receivable,
      3 => :fuga_notification_receivable,
      4 => :piyo_notification_receivable,
      # 何とかフラグが増えたらここに定義追加するだけでOK！
    )

  # 各フラグの初期値設定は after_initialize でやると良い
  after_initialize :assign_default_flags, if: :new_record?

  def assign_default_flags
    assign_attributes(
      admin: false,
      hoge_notification_receivable: true,
      fuga_notification_receivable: true,
      piyo_notification_receivable: true,
    )
  end
end

# 使う側は特に意識せずそのまま使える
user.admin # => true
user.hoge_notification_receivable # => false
```

導入手順や詳細は[FlagShihTzu](https://github.com/pboling/flag_shih_tzu)を参照してください。:grin:
WinActor PDFファイルの結合処理

さて、本日はWinActorを用いて複数のPDFファイルを１つにまとめる処理を作ってみました。

ここで、２つ問題が発生。

# 1回の [ファイルを開くダイアログ] で全てのファイルを設定しようとした場合
こちらはWinActorの仕様の問題(明記されているかは不明)で、変数に設定できる文字列の長さに上限があり、途中でファイル名が途切れてしまう。
# 1回の [ファイルを開くダイアログ] で1つのファイルを設定しようとした場合
こちらはAcrobatの仕様で、[Ctrl]+[Shift]+Iが連続で効かない。
(画像マッチングを使えばましなんでしょうが、画像マッチングはそれはそれで問題が発生するので)
1. [Ctrl]+[Shift]+I で [ファイルを開くダイアログ]を開く
2. 追加したいファイルを追加する
3. [開く]ボタンを押す。
ここで、元の画面に戻った時に [結合]のボタンにフォーカスが当たります。
この[結合]ボタンにフォーカスが当たっている時に[Ctrl]+[Shift]+Iをしても、[ファイルを開くダイアログ]が表示されない。

私のとった対策は、[Ctrl]+[Shift]+Iの前に[Tab]入れてます。
もちろん、この[Tab]のせいで、[結合]ボタンにフォーカスが当たる時もあるので、適当に繰り返すことにしました。
Reactで複数のinput(入力フィールドがある)をmapしたときにはまったこと

## 冒頭　inputって一個だけやないんやで！！

はい、いきなりですみません。
私はReactをかじり出して１年ぐらいのペーペーで、某会社に所属しながらそこのプロジェクトでは一向にReactを触る機会がないので、自分で仕事をとってReactを勉強しています。

さて本題です、

Reactでinputって一つだけだとonChangeできるけど、

mapを使って複数のコンポーネントに紐づくinputの一つ一つにonChange設定するときどうするの?

っていうのが今回のはまった箇所です。


## 解決策　※ハッカーズバーで助言をいただきなんとかたどり着きました

```javascript
//親
import React, { Component } from "react";
import Items from "./Items";
class Form extends Component {
  state = {
    members: [
      {
        id: 1,
        name: "1111",
        description: "ああああ",
        value: "テキスト1"
      },
      {
        id: 2,
        name: "いいいい",
        description: "2222",
        value: "テキスト2"
      },
      {
        id: 3,
        name: "うううう",
        description: "3333",
        value: "テキスト3"
      }
    ]
  };

　//handleChangeイベントを発火させて引数を受け取る
  handleChange = member => {
    this.setState({
      members: this.state.members.map(e => (e.id === member.id ? member : e))
    });
    console.log(this.state.members);
  };

  render() {
    const { members } = this.state;
    return (
      <div>
        {members.map(member => {
          return (
           //ItemsコンポーネントにonChangeのhandleChangeを渡す
            <Items 
              key={member.id}
              member={member}
              onChange={this.handleChange}
            />
          );
        })}
      </div>
    );
  }
}

export default Form;



```

```javascript
import React, { Component } from "react";

class Items extends Component {

  //handleChangeをここで呼び出す
  handleChange = event => {
    const { member, onChange } = this.props;
    onChange({
      ...member,
      value: event.target.value
    });
  };

  render() {
    const { member } = this.props;
    return (
      <div>
        {member.id}
        //このクラスで定義しているhandleChangeを実行する
        <input value={member.value} onChange={this.handleChange} />
      </div>
    );
  }
}

export default Items;
```
これで結果的にinputの一つ一つにチェンジイベントが使えるようになった。

## サンプル
<iframe src="https://codesandbox.io/embed/jl8vo53l7w?fontsize=14" style="width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;" sandbox="allow-modals allow-forms allow-popups allow-scripts allow-same-origin"></iframe>


https://codesandbox.io/embed/jl8vo53l7w?fontsize=14


## まとめ
まだまだ勉強不足と共に「配列」を操作することが難しいと感じている
Reactをやると色々と勉強になると同時に学習せねばーーという気持ちになるので、がんばります。

もっといけてる書き方があればぜひ教えてください。
その利用価値の有無は置いといて、Windows Subsystem for Linux の Ubuntu 上で Headless LibreOffice を使って PDF を生成することはできる

タイトルの長さですでにうっとりとしてしまいますが、WSL の Ubuntu でも普通に Headless LibreOffice を使って PDF を生成することはできるというお話。

ただ、母艦の Windows 上でも当然できることなので、そこに価値があるのか？と言われると・・・。

### 1. 日本語フォント入れる
Ubuntu だと IPA ゴシック系入れときゃ、とりあえず OK なのかな。

```
sudo apt install fonts-ipa*
```

### 2. LibreOffice 入れる

```
sudo apt install libreoffice
```

### 3. 実行してみる
ちなみに、わたしの実行環境は、[Windows Subsystem for Linux の Ubuntu 18.04 LTS で俗に言う「今さら聞けない・・・」を調べやすくしてみる](https://qiita.com/comeon_babuu/items/5bb8862ccfc3d0e67966) で $LANG を ja_JP.UTF-8 にしてあるものなので、新規インストールほやほやの c.UTF-8 で動くのかどうかは分からず。

```test.txt
今日は何の日
明日は明日の風が吹く
```

```
libreoffice --headless --convert-to pdf --outdir $HOME test.txt
```

<img width="1037" alt="出来上がった PDF" src="https://qiita-image-store.s3.amazonaws.com/0/371960/7f5e6763-eb42-c351-d070-06ce1a39bd6b.png">


まあ、お遊びということで。
【Swift】UIScrollViewとLoadView()と非同期処理


忘備録です。
UIScrollViewがLoadView()とviewDidLoad()でViewControllerを再読込した時にスクロールしてくれなくなったので、動くようにするにはどうしたらいいのか躓いたので解決方法をメモしておきます。

# 前提
- swift4.2,xcode10
- UIScrollViewを画面に配置、その中にUIViewを置く
- そのUIViewの中に部品をコードで生成して入れる
- TableViewで選択された内容でScrollViewやボタンの内容が変更
- 内容が変わるのでUIViewControllerを読み込み直す（本の内容を同じViewController内でページを変えていくイメージ）
- UIViewControllerを読み込み直すやり方はLoadView()とviewDidLoad()のコールで行う

# やったこと
- viewDidLoad()でデータを読み込む
- その内容に従ってUIScrollView内のViewにLabelや画像を貼り付けていく
- その内容によって変わる高さを計算してviewDidLayoutSubviews()で中のViewのheightとUIScrollViewのContentSizeを設定する

# 結果
- 初回の内容は問題なく表示され、スクロールが出来る。
- が、UITableViewでリストを選んでLoadView()とviewDidLoad()をコールしたところ、ScrollViewの外に設置してあったUITableViewは問題ないがUIScrollViewがスクロールしなくなった

# 対策
- viewDidLayoutSubviews()で非同期処理としてContentSizeの更新を走らせる

```swift:
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        let contentWidth = ScrollView.bounds.width
        // 非同期処理にてUIの更新
        DispatchQueue.main.async {
            // offset - 内部のコンテンツのトータルのHeightをインスタンス変数にしてあります 
            // Viewの高さ
            self.View.frame.size.height = self.offset
            self.ScrollView.contentSize = CGSize(width: contentWidth, height: self.offset)
        }
    }


```

これでなんとか動いてくれました。
Draw.io をnode.jsで動かす

# はじめに。

Draw.io をnode.jsで動かす方法を述べる。

なんでnode.jsかって？

インストールしたくないし、ぱっと動かしてつかって、いらなくなったらぽいっと捨てたいからや。

# インストール

```bash
#!/bin/bash

git clone --recursive https://github.com/jgraph/drawio-desktop.git

pushd drawio-desktop
  npm install
  pushd drawio
    npm install
  popd
popd
```

# 起動

```bash
#!/bin/bash

pushd drawio-desktop
NODE_ENV=development
npm start
popd
```

# 動作確認

![Screenshot from 2019-03-08 21-23-11.png](https://qiita-image-store.s3.amazonaws.com/0/114392/1aa3c664-7be4-401a-e479-5793e8166710.png)
Cocos2D-X - UnicodeEncodeError: 'cp950' codec can't encode character u'\u7f16'


>2019-07-18 Updated
>Version :　3.17.2

# Build Error
```
Traceback (most recent call last):
  File "D:\Downloads\cocos2d-js\tools\cocos2d-console\bin\/cocos.py", line 1081, in <module>
    run_plugin(command, argv, plugins)
  File "D:\Downloads\cocos2d-js\tools\cocos2d-console\bin\/cocos.py", line 970, in run_plugin
    plugin.run(argv, dependencies_objects)
  File "D:\Downloads\cocos2d-js\tools\cocos2d-console\plugins\plugin_compile\project_compile.py", line 1508, in run
    self.parse_args(argv)
  File "D:\Downloads\cocos2d-js\tools\cocos2d-console\bin\cocos.py", line 615, in parse_args
    self._add_custom_options(parser)
  File "D:\Downloads\cocos2d-js\tools\cocos2d-console\plugins\plugin_compile\project_compile.py", line 74, in _add_custom_options
    help=MultiLanguage.get_string('COMPILE_ARG_BUILD_TYPE'))
  File "D:\Downloads\cocos2d-js\tools\cocos2d-console\bin\MultiLanguage.py", line 52, in get_string
    fmt = cls.get_instance().get_current_string(key)
  File "D:\Downloads\cocos2d-js\tools\cocos2d-console\bin\MultiLanguage.py", line 158, in get_current_string
    ret = ret.encode(self.encoding)
UnicodeEncodeError: 'cp950' codec can't encode character u'\u7f16' in position 84: illegal multibyte sequence
```

# Solution
Find the file ***string.json*** in the subfolder ***tools\cocos2d-console\bin*** whithin [cocos2d-x-3.17.2.zip](https://cocos2d-x.org/filedown/cocos2d-x-3.17.2) unzip folder and delete ***"zh"*** and ***"zh-tr"*** json part.
WinActor ウィンドウ識別を使ったシナリオの安定動作

WinActorを用いた業務自動化シナリオにおいては特にウィンドウの起動待ちや特定のウィンドウに対しての操作（値の設定、取得、ボタン操作など）が多いと思いますが、下記の記事にもある通り、 *ウィンドウ識別のクリア* を入れないとうまく動作しないことが発生します。
私も下記の記事を参考にしたところ、今まで発生していたエラーがピタリと止まりました。
だからと言って、こまめに全箇所に入れるのも ~~手間~~ 処理時間の無駄になるので、どんなタイミングで入れるべきかを考察してみた。
キャッシュの内容と実際のウィンドウに違いが生じた時
ということは、処理の手前でもいいですが、処理時間を考えるとウィンドウが新たに作られた時にウィンドウ識別をクリアすればいいのではないでしょうか？

[【WinActor】ブラウザの画面遷移時の初期処理](https://qiita.com/irohamaru/items/493ef71f0e62f4ec9f9d)
C# gRPC RpcException をスローしたときにメソッド呼び出しが終わらなくなる


サービス側の処理で RpcException をスローすることがありますが、クライアント側から呼び出したメソッドが終了しないケースを発見しました。一見何の問題もないように見えてしまうため、注意が必要です。

gRPC のバージョンは 1.16.0 ですが、他のバージョンでも発生するかもしれません。

### サービスの実装

RpcException のトレーラーに格納する内容をいったん ServerCallContext に格納し、ServerCallContext の ResponseTrailers プロパティ経由で RpcException に格納します。

```c#:RpcExceptionをスローするサービスメソッド(1)
public override Task<Response> GetData(Request request, ServerCallContext context)
{
    // ServerCallContext にトレーラーを格納し、
    context.ResponseTrailers.Add("result", "1");

    // ServerCallContext からトレーラーを取得して例外に格納する。
    throw new RpcException(
        new Status(StatusCode.Unauthenticated, "Unauthenticated.")
        , context.ResponseTrailers
    );
}
```

ちなみに ServerCallContext.ResponseTrailers を使わなければこの現象は発生しません。通常はこちらのように実装すると思います。

```c#:RpcExceptionをスローするサービスメソッド(2)
public override Task<Response> GetData(Request request, ServerCallContext context)
{
    // Metadata にトレーラーを格納し、
    Metadata trailers = new Metadata();
    trailers.Add("result", "1");

    // Metadata を例外に格納する。
    throw new RpcException(
        new Status(StatusCode.Unauthenticated, "Unauthenticated.")
        , trailers
    );
}
```

### クライアントの実装

メソッドの呼び出しが終わらず、ブロックされたままになります。

```c#:上記のサービスメソッド(1)を呼び出す
try
{
    // このメソッド呼び出しが終わらない。
    Response response = await rpcClient.GetData(new Request());
}
catch (Exception ex)
{
    // 切断されたりするまで例外はキャッチされない。
    Debug.WriteLine(ex.ToString());
}
```
[Ruby on Rails]ActiveRecord::Base の getter/setter

```app/models/application_record.rb
ApplicationRecord < ActiveRecord::Base
```



```vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.1/lib/active_record.rb
35 module ActiveRecord
     ...
38   autoload :Base
```

```vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.1/lib/active_record/base.rb
277   class Base
        ...
310     include AttributeMethods
```

```vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.1/lib/active_record/attribute_methods.rb
395    def [](attr_name)
396      read_attribute(attr_name) { |n| missing_attribute(n, caller) }
397    end

       ...

409    def []=(attr_name, value)
410      write_attribute(attr_name, value)
411    end
```

```vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.1/lib/active_record/attribute_methods/read.rb
54      def read_attribute(attr_name, &block)
          name = if self.class.attribute_alias?(attr_name)
            self.class.attribute_alias(attr_name).to_s
          else
            attr_name.to_s
          end

          primary_key = self.class.primary_key
          name = primary_key if name == "id".freeze && primary_key
          sync_with_transaction_state if name == primary_key
          _read_attribute(name, &block)
65      end
```

```vendor/bundle/ruby/2.5.0/gems/activerecord-5.2.1/lib/active_record/attribute_methods/write.rb
35      def write_attribute(attr_name, value)
          name = if self.class.attribute_alias?(attr_name)
            self.class.attribute_alias(attr_name).to_s
          else
            attr_name.to_s
          end

          primary_key = self.class.primary_key
          name = primary_key if name == "id".freeze && primary_key
          sync_with_transaction_state if name == primary_key
          _write_attribute(name, value)
46      end
```
Elastic Stack 気になるIssues&Pullreqs

つらつらとelasticのgithubを眺めていて、気になったやつらです。
早く実装されないかな〜楽しみ〜

## Elasticsearch
- [Snapshot lifecycle 
management](https://github.com/elastic/elasticsearch/issues/38461)

## Kibana
- [New Visualize Editor - Mission 
Statement](https://github.com/elastic/kibana/issues/31933)
- [Kibana App roadmap for New Platform 
migration](https://github.com/elastic/kibana/issues/31968)
- [Kibana Actions roadmap](https://github.com/elastic/kibana/issues/32371)
- [\[Maps\] embeddable phase 
1](https://github.com/elastic/kibana/issues/31137)
- [\[Maps\] embeddable phase 
2](https://github.com/elastic/kibana/issues/31178)
- [Alerting Service](https://github.com/elastic/kibana/issues/24214)
- [[Localization] Support for Japanese Language](https://github.com/elastic/kibana/issues/32800)

## Logsash

## Beats
- [Add script processor](https://github.com/elastic/beats/pull/10850)
関数宣言 関数式 アロー関数 の使い方

最近この3つの関数について学び、１日かけてようやく最低限の理解はできたので、自分用メモとして書きます。
間違っている場合は、ご指摘をくださると嬉しいです。

#関数宣言
関数宣言とは、以下の書き方を指します。
関数宣言した関数を使いたい場合は、関数名();とすればOKです。今回の場合は、sample();とすればOKということです。

```javascript:sample
function sample(){
 console.log('sample');
}
```

#関数式
関数式とは、以下の書き方を指します。関数式は、変数に関数を代入するという書き方をします。なので、このsampleを使いたい場合は、変数名();とすればOKです。今回の場合は、sample()となります。

**{}の後に;をつけ忘れないようにしましょう。**
；がなくても動いてしまいますが、関数式は変数に関数を代入するような書き方なので、一般的に；は書くべきだそうです。

```javascript:sample
const sample = function(){
 console.log('sample');
};
```
(追記)
ありがたい事に補足をいただいたので、ここにもメモとして残します。
関数式は上のような書き方もできますが、以下のように関数名を書いた書き方もできるようです。

```javascript
const sample = function sample1(){
 console.log('sample');
};

```
この場合は、
* 関数外から呼び出す場合は変数名();でないと呼び出せません。
* 関数名();は関数内でないと使えないようです。

じゃあ関数内で関数を呼び出すときってどんなとき？
→再帰関数を使うするとき


#アロー関数
アロー関数は、以下の書き方を指します。
この関数は、関数式を省略して書けるというメリットがあります。
・・・正確にいうと、他に大きなメリットがあるのですが(this問題とか）今は省略します。
上の関数式の「function()」の部分が「() =>」に変わった書き方と解釈してOKです。
アロー関数は関数式と同じく、使いたいときは変数名();でOKです。
また、こちらも**;忘れにはお気をつけて。**

```javascript:sample
const sample = () => {
 console.log('sample');
};
cocos2dxでcppからJavaのコードを実行

# 環境
cocos2dx 3.17 (JavaScript)
Android

# 問題
cocos2dxのAndroidでネイティブといえばJavaでコードを書くが、使用するライブラリによってはcppを触らなくてはならない。
js -> java -> cpp という流れ。
逆にネイティブからjsの関数を実行するしくみについて、java -> js はあるが、cpp -> js をしたい。
古いcocos2djsでは`ScriptingCore::evalString(code)`を使用していた。
しかしcocos2dxをアップデートしていたら、これがcrashする。

## crash例
https://github.com/cocos2d/cocos2d-x/issues/17718
https://github.com/cocos2d/cocos2d-x/issues/13807

いろいろ調べると、JniHelperを使うといいようだ。

# 呼び出し例
http://developer.wonderpla.net/entry/blog/engineer/cocos2d-x_jni2/

以下のように実装して、cpp -> java ( -> javascript)が実現できた。

# 実装

```cpp
#include "platform/android/jni/JniHelper.h"

void executeJavaScript()
{
    cocos2d::JniMethodInfo t;

    if (cocos2d::JniHelper::getStaticMethodInfo(t,
                                       "jp/example/java",       // Javaのクラス
                                       "executeJs",             // Javaのメソッド名（static）
                                       "(Ljava/lang/String;)V"  // 引数
    )) {

        // jstring - C++ representation of Java String
        // JSのメソッド名を文字列で書いて変換
        jstring stringArg = t.env->NewStringUTF("javascriptMethod('arg')");

        // call the method, with arguments
        t.env->CallStaticVoidMethod(t.classID, t.methodID, stringArg);
    }
}
```
javascriptを書いて逮捕されるには - How to get arrested

## TL;DR
近頃、巷ではjavascriptを自分のページに設置するだけで逮捕・家宅捜査されたり、ブラクラへのリンクを張っただけで補導されたりしたという噂をよく聞く。そこで、逆にどうしたら逮捕されることができるのかこれらの出来事から考えてみた。

## CoinHiveで逮捕されたのはナゼか？
CoinHiveで逮捕されたのは何故だろうか。恐らく<del>警察の早とちり</del>イヤなプログラムだから逮捕されたのだろう。どこら辺がイヤなプログラムなのか？

1. 見えない(見えないものは怖い)
2. よく知らない(知らないものは怖い)
3. パソコンが遅くなる(遅くなるとイライラする)

ほら、イヤなプログラムでしょ？<del>まぁ、CoinHiveは恐らくトレンドマイクロが煽ったせいというのも大きいとは思われるが。</del>

## 中２女子ブラクラ補導事件
中２女子ブラクラ補導事件というのは私が勝手にそう呼んでいるだけだが、２年生の女子中学生が掲示板にブラクラへのリンクを張っただけで補導されたという事件があった。
<del>恐らく警察は彼女がそのプログラムを作ったものと勘違いしての所業だと思われるがそこは置いておく。</del>
さて、このプログラムは下に示すような極めて簡単なプログラムで、ブラウザによっては途中で実行を止めてしまうようなものもある。

````javascript
while(1) {
  alert("閉じても無駄だよ！");
}
```

よしんば彼女が作ったとしてこの程度のプログラムで補導されるのは<del>頭がおかしい</del>常識的に考えてあり得ないが、補導されたのは事実である。なぜ警察は補導したのだろうか？

1. 警告ダイアログが鬱陶しくてイライラするから
2. 対処法を知らないと無限に時間をとられるから

など、やはりこちらも心情的な面が強く押し出されているように感じられる。

## 結論 - How to get arrested with javascript
結論としては、次のことが言えると思う。

1. それっぽく見えるから逮捕した  
  → それっぽく見せる (ex. 見えない場所で動かす、無限ループ etc.)
2. 現実的に逮捕できるから逮捕した  
  → 下の「より逮捕される確率を上げるために」に詳しく書いた

恐らく全てはこの2点に集約されるものと思われる。

## より逮捕される確率を上げるために
1. 海外プロバイダではなく、国内プロバイダを必ず使う。
  * 日本の警察ごときが海外のプロバイダにまで「最低でも英語で」発信者情報開示請求を出せる訳がないと思われるため。
2. トレンドマイクロに敵視される
  * 警察のサイバー犯罪対策はほとんど民間のサイバーセキュリティ企業の言いなり
  * むしろこれが難しいまである
3. できるだけ不快な思いをさせるようにする。
  * 不快だし逮捕しても誰も文句言わないよね？
  * 下手なことをすると冗談ではすまなくなるのでほどほどに。

というわけで[ブラクラ](javascript:(x=_=>(alert("閉じても無駄！"),x()))())を埋め込んでみる。<del>押すと警告メッセージの無限ループが始まるので注意しよう。</del>**下の追記[^1]をみてください。**

一応念のため書いておく。
上記のブラクラ実行リンクについて

1. 上記のリンクはブラクラを体験してみたい諸兄のために用意したものであり、リンクをクリックしたことによるいかなる損害も当方は一切関知しない。
2. 無限ループ警告ダイアログはプログラム意図した動作であり、実行したユーザーはこの事を知っているものと見なす。
3. 上記リンクをクリックするという行為をもってこれらの条項に同意したと見なす。

これで補導されたら面白すぎるので、ネタにします。

----
[^1]: 追記<br />スクリプトリンクは動作しないみたい。どういうコードか見たい人は[ここから](https://qiita.com/frodo821/items/8b5af10b95162d5d297d.md)みると良いかも。
Raspberry Pi 3 を イーサネットコンバータにする

Raspberry Pi 3 Model B+ ( ラズベリーパイ ) を使用したイーサネットコンバータ構築

- Raspberry Pi の wlan0 無線 ( wi-fi ) [ 192.168.1.x ]
- Raspberry Pi の eth0 有線LAN [ 192.168.2.x ]

上記環境で有線LANに接続したしたNASからインターネットができる状態にしました。
テレビ等のネット環境が必要な機器で利用すると便利です。



# 1.eth0 側のセグメント設定
```
$ sudo nano /etc/dhcpcd.conf
```
```/etc/dhcpcd.conf
interface eth0
static ip_address=192.168.2.1/24
```




- 設定を反映して確認

```
$ sudo systemctl restart dhcpcd.service
$ ip address show eth0
```

- Raspberry Pi が eth0 を優先してしまいLAN接続した際にRaspberry Piがネットに繋がらなくなる場合は下記の設定も追加

```/etc/dhcpcd.conf
interface eth0
static ip_address=192.168.2.1/24
static routers=0.0.0.0 ( 追加 )
static domain_name_servers=0.0.0.0 ( 追加 )
```


# 2.ブリッジ設定

```
$ sudo nano /etc/rc.local
```
```/etc/rc.local

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE

exit 0 の上に追加
```
- 再起動してもろもろ設定を反映

```
$ reboot
```


# 3.NAS(接続端末)のIPを固定しておく

固定IPを設定して Raspberry Pi と有線LAN接続

[ 今回設定した内容 ]

- IPアドレス 192.168.2.100
- サブネット 255.255.255.0
- GATEWAY 192.168.2.1
- DNS 192.168.1.1

# 4.Raspberry Piからの動作確認

```
$ ping 192.168.2.1 ( eth0 )
$ ping 192.168.2.100 ( NAS )
$ ping 192.168.1.1 ( ルーター )
$ ping www.google.co.jp
```
これが全て通ればOK

# 5.NASからの動作確認

```
$ ping 192.168.2.1 ( eth0 )
$ ping 192.168.1.1 ( ルーター )
$ ping www.google.co.jp
```
これが全て通ればOK

# 6.wi-fiの接続が切れたとき対策

・[Raspberry PiでWi-Fi切断時、自動的に再接続されるようにする方法](https://qiita.com/gzock/items/0b3d925c16079561abc4)

こちらの記事を参考に設定を行いました

# 参考

・[Raspberry Piでイーサネットコンバータを作る](http://www.soramimi.jp/raspberrypi/etherconv/)
・[ラズパイを無線LANイーサネットコンバータ化する方法](https://qiita.com/winuim/items/8c39aa92f7c905e55b92)
・[raspberrypi3で手っ取り早くイーサネットコンバータを作る](https://blog.vongole-pasta.xyz/?p=1584)
・[ラズパイで有線LANをTCP接続機器に、WI-FIをインターネットに接続する](http://altenergy-system.com/archives/4092)
・[RaspberryPi3のWifiが繋がらない or 繋がらなくなった時](https://yuki-sato.com/wordpress/2016/09/06/raspberrypi3%E3%81%AEwifi%E3%81%8C%E7%B9%8B%E3%81%8C%E3%82%89%E3%81%AA%E3%81%84-or-%E7%B9%8B%E3%81%8C%E3%82%89%E3%81%AA%E3%81%8F%E3%81%AA%E3%81%A3%E3%81%9F%E6%99%82/)
JavaScriptでPromise.race() を使ってタイムアウト処理を書く

## 目的
JavaScriptにおいて、長いリクエストがタイムアウトした場合の処理を実装するのには
様々な書き方があると思うが、
その中でもasync, awaitを使った非同期処理におけるタイムアウト処理の実装に苦労したので
まとめておく。
実装が雑で申し訳ないが、誰かの役に立てば。

## 参考資料
- [Promise.race() - 複数のPromise関数を実行し、最初の結果を得る](https://lab.syncer.jp/Web/JavaScript/Reference/Global_Object/Promise/race/)
- [【JavaScript】ちゃんと理解しておきたいPromiseの勘所など](https://kde.hateblo.jp/entry/2018/11/01/042432)

## サンプルコード
### 共通部分
```js
async function main_request() {
  return new Promise((resolve) => {
    // あえてタイムアウト時間より長い処理にする
    setTimeout(() => {
      resolve("ok");
    }, 5000);
  });
}

async function exec_request() {
  var response = await promise_test(3000)
  console.log(response)
}
```

### Promise.race()を使わない実装
return部分で何を返しているかがわかりにくい

```js
async function promise_test(ms) {
    return new Promise(async function (resolve) {
        setTimeout(() => {
            // タイムアウト
            resolve('timeout');
        }, ms);
        var response = await main_request()
        resolve(response)
    });
}

exec_request() //output: timeout
```

### Promise.race()を使った実装
 return部分で何を返しているかが明確

```js
async function promise_test(ms) {
  var timeout = (ms) => new Promise(function (resolve) {
    setTimeout(function () {
      // タイムアウト
      resolve("timeout");
    }, ms);
  });

  return Promise.race([
    timeout(ms),
    main_request()
  ])
}

exec_request() //output: timeout
```

## 注釈
async, awaitは不慣れで、無駄な箇所があるかもしれません。
よりよい書き方があったら教えてください！
blueqatハンズオン準備

# blueqatのインストール

## ローカルのpythonを利用する場合
### blueqatのインストール
```python
$ pip install blueqat
```

### pythonの起動

```bash
$ python
```
## ローカルもしくはGoogle Colaboratoryのjupyter notebookを利用する場合

```python
! pip install blueqat
```
# ハンズオン
以下の2つのハンズオンをやりますので、コードが動くかどうか、確認しておいて下さい。

## 重ね合わせ回路

```python
from blueqat import Circuit
Circuit().h[0].m[:].run(shots=100)
```
## 量子もつれ回路

```python
from blueqat import Circuit

Circuit().h[0].cx[0,1].m[:].run(shots=100)
```

# 備考
## pythonのインストール手順
pythonは3.6以上をインストールしておいて下さい。
pythonのインストール手順は以下のサイトにあります(3.7.2が最新)。

https://www.python.jp/install/install.html

ご利用のプラットフォームに応じた手順を実行下さい。

### jupyter notebookのインストール手順

jupyter notebookをインストールする手順は以下にあります。
https://jupyter.org/install

### Google Colaboratory

Googleアカウントでログインした状態で以下のURLにアクセスするとjupyter notebookが利用できます。

https://colab.research.google.com
【CSS】ボーダーをヌルッと動かす方法。

#ボーダーをヌルッと動かしましょう。
今回はCSSのアニメーションを使用しボーダーをヌルッと動かしてみます。

##コード

```index.html
<h1 class="test">Test</h1>
```
```style.css
.test{
    overflow: hidden;
}

.test::after{
    border-bottom: 2px solid #000;
    content: "";
    position: relative;
    display: block;
    width: 0%;
    animation: up 2s infinite ease-in-out;
    -webkit-animation: up 2s infinite ease-in-out;
}

@keyframes up {
    0% { width: 0%;}
    50% { width: 100%; left: 0px;}
    100% { left: 100%; width: 100%; opacity: 0.2;}
}

@-webkit-keyframes up {
    0% { width: 0%;}
    50% { width: 100%; left: 0px;}
    100% { left: 100%; width: 100%; opacity: 0.2;}
}
```

たったこれだけです。

##考え方
まず**::after**で文字の下にボーダーをつけましょう。
これが::beforeなら文字の上にボーダが付きます。

そして、afterの中にconntent: "";と書くことにより空白を作ります。
この空白がないとボーダー君は何を基準にボーダーになれば良いのか分からないので、表示されません。

この時点ではwidth: 0;にしておきましょう。
fadeInさせる時display; none:にするじゃないですか？
あのような意味合いです。

その次にアニメーションですね！
animation: 〇〇(好きな名前) 2s infinite ease-in-out;
こちらの意味としましては
・**一回の処理に2秒用います**
・**無限に繰り返します**
・**始まりと終わりだけゆっくり動きます**
と言った具合です。

-webkit-これはベンダープレフィックスと言ってブラウザの違いによる表示の不具合を防ぐためのものですね。
・-webkit-   Chrome, Safari 5
・-moz-   Firefox 9
・-o-   Opera 12
・-ms-   IE
※今は-webkit-だけでもいいらしいです。[そのベンダープレフィックス、いつまでつけてるの？](https://qiita.com/amamamaou/items/42197e443134478befaf)

そして、@keyframesでアニメーションにどんな処理をさせるかを追記していきます。

```style.css
@keyframes up {
    0% { width: 0%;}
    50% { width: 100%; left: 0px;}
    100% { left: 100%; width: 100%; opacity: 0.2;}
}
```
0%,50%,100%となってるのは時間を%で表しています。
なので、今回は2秒と設定しているのでその間にこちらの処理を行います。

50%の時点でwidth: 100%にしてleftの登場です。
今回のキモはこのleftの処理とoverflow: hidden;です。

そして100%になるとleft: 100%;にしています。
このleftの処理とoverflow: hidden;を合わせることによって端にたどり着いた瞬間に短くなって、消えていくように見せています。
気になる方はoverflow: hidden;をのけてみてください。
理屈がわかると思います。

では、またの投稿をお楽しみに。
ReactiveなLINQで点滅動作を表現したい

ランプで状態表示などするときは点滅って言うパターンが用意されることが多いです。

これをReactiveなLINQで表現したい！！

点滅動作とは
**一定期間ごとにON/OFFを繰り返す**
と言うことでしょうか。

Observableで簡単に書けそうだなと思ったんですがちょっと失敗しましたのでメモ。

IntervalかTimerを使ってCountで発生回数を数えれば・・・。
と思ってましたがこれは間違い

```C#:失敗
Observable.Interval(TimeSpan.FromMilliseconds(1000))
	.Count()
	.Select(count => count % 2 == 0);
```

Countはシーケンスが終わるまで動きませんので、
IntervalではいつまでたってもCountから先に流れません(汗


これもメソッドの意味をちゃんと分かってなかったのですが、
TimerやIntervalは発生回数を引数に渡してくれるので↓で十分なのでした。

```C#:ちゃんと動く
Observable.Interval(TimeSpan.FromMilliseconds(1000))
	.Select(count => count % 2 == 0);//trueから開始
	
//Observable.Interval(TimeSpan.FromMilliseconds(1000))
//	.Select(count => count % 2 == 1);//falseから開始
```

気になるのはこのCountがOverflowするとどうなるのか・・・？

ドキュメントが見つからず、ソースを確認

https://github.com/dotnet/reactive/blob/master/Rx.NET/Source/src/System.Reactive/Linq/Observable/Timer.cs

Intervalの中身はTimerでした。
ここが該当箇所でしょうか？？

```C#:該当箇所?
private void Tick()
{
    var count = _index;
    _index = unchecked(count + 1);

    ForwardOnNext(count);
}

```

これだとオーバーフローして負の数になりそうな・・・・？

ただ指定できる最小単位が1msですので、オーバーフローするには最低でも292471208.67･･･年必要と言うことになります。
え？2.9億年て事？
確かにそこまでいけば気にしなくてもいいか(笑

##追記
0bit目だけで判断できるのでこれでも可

```C#:ビット判定
Observable.Interval(TimeSpan.FromMilliseconds(1000))
	.Select(count => (count & 1) == 0);//trueから開始
```

ところでこういうことは2進数での負の数の表現を知らないと分からない話なんだと気付きました。
知らないといけないのは確かですが、人間はもっと上位層だけに意識を集中したいものです。
ReactのClass ComponentでReact-Reduxに繋ぐ

React-Reduxの説明されているページなどでは大体例としてFunctional Componentでしか説明されていなくて
Class Componentでどうやって繋ぐのかという具体例がほとんど見当たらなかった
慣れてる人から見れば他愛もない問題なのかも知れないけれど個人的にはちょっと苦戦したので執筆

Class Componentじゃなきゃコンポーネントマウント・アンマウント時になどのタイミングで呼ばれるライフサイクルメソッドを定義する場合に不便だったり(認識誤りかも知れないけれど)、元のコンポーネントをClass Componentとして定義しててそれをReact-Reduxに繋ぎたい場合だったりなどなど
→【追記】ver16.8で追加されたReact Hooksを使えばFunctional Componentでも同等の事ができそう

##準備
今回Functional ComponentからClass Componentへ書き換えるというアプローチを行い書き換え元として
[connected-react-router](https://github.com/supasate/connected-react-router)のexamples/basicを利用する
これをダウンロードして普通に起動する場合
コマンドプロンプトやターミナルなどでexamples/basicへ行き
npm install で依存関係を解決し
npm start でサーバーを起動
ブラウザから http://localhost:8080 へアクセスすると以下の様な画面が表示される
![img1.png](https://qiita-image-store.s3.amazonaws.com/0/314532/521aef13-47b5-0eaf-9f06-18657e03ae2f.png)
この中でCounterの部分でReduxを使用していて
![img2.png](https://qiita-image-store.s3.amazonaws.com/0/314532/acadb43c-219f-3329-efab-d4dfa99f53a7.png)
ここで[+]ボタンを押すとカウントアップされ
![img3.png](https://qiita-image-store.s3.amazonaws.com/0/314532/84c5b57c-9291-c242-62dc-a5a1a59c0492.png)
このカウントアップされた値はストアに格納されているのでReact Router経由の他の画面のに移動して
![img1.png](https://qiita-image-store.s3.amazonaws.com/0/314532/521aef13-47b5-0eaf-9f06-18657e03ae2f.png)
戻ってきても値が保持されている
![img3.png](https://qiita-image-store.s3.amazonaws.com/0/314532/84c5b57c-9291-c242-62dc-a5a1a59c0492.png)
この動作をReduxでの保存の動作の指針とした

##実際の書き換え
今回書き換えはこのCounterのComponentが定義されているexamples/basic/src/components/Counter.jsファイルに対して行う

散々試行錯誤した結果書き換えが必要な個所はこれだけだった

```diff:examples/basic/src/components/Counter.js
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { increment, decrement } from '../actions/counter'

-const Counter = (props) => (
-  <div>
-    Counter: {props.count}
-    <button onClick={props.increment}>+</button>
-    <button onClick={props.decrement}>-</button>
-  </div>
-)
+class Counter extends React.Component {
+  constructor(props) {
+    super(props);
+  }
+  render(){
+    return (
+      <div>
+        Counter: {this.props.count}
+        <button onClick={this.props.increment}>+</button>
+        <button onClick={this.props.decrement}>-</button>
+      </div>
+    );
+  }
+}

Counter.propTypes = {
  count: PropTypes.number,
  increment: PropTypes.func.isRequired,
  decrement: PropTypes.func.isRequired,
}

const mapStateToProps = state => ({
  count: state.count,
})

const mapDispatchToProps = dispatch => ({
  increment: () => dispatch(increment()),
  decrement: () => dispatch(decrement()),
})

export default connect(mapStateToProps, mapDispatchToProps)(Counter)
```

主な変更点としては
本体JSXはrender()の戻り値に指定
アロー関数の引数はpropsはconstructor()からsuper()に渡す
superに渡されたpropsはclass内ではthis.propsとなる
自作パッケージをpushしてgo getするのが面倒くさい


# 自作パッケージをpushしてgo getするのが面倒くさい

3/9追記しました

## ~~急募~~
~~ちゃんとした開発方法が記されたわかりやすいドキュメント~~

## 問題
そもそも開発方法としてどうしたらいいのかわからないけど、とりあえず誰でもgo getして使えるようにgithubのリポジトリからインポートするようにしています。

    import "github.com/~~~"

こんな感じに開発していると、このインポートしているパッケージを変更したときにまたpushしないといけません。
ちょっとした変更でも。

    git add .
    git commit -m 'ちょっとした変更'
    git push origin master

というか、動くかどうかもわからないコードでマスターが汚れます。

## 3/9追記 解決方法
コメントで@spiegel-im-spiegelさんに教えていただきました。
`GOPATH`には複数のパスを設定できるようです。`go get`を使用した場合は最初に指定したパスが使われます。そのため、2番目以降に開発用のディレクトリを指定すると良さそうです。

例えば、`GOPATH`に`$HOME/go-dev`というパスを指定し、`$HOME/go-dev/src/github.com/ophum/test`というディレクトリを作成し、このディレクトリで開発を行うようにすると良さそうです。

## ~~暫定的な解決方法(?)~~

~~`go get`すると`$GOPATH`で指定されたディレクトリにリモートからクローンするようです。例えば、githubのophumというユーザのtestというリポジトリを`go get`した場合`$GOPATH/src/github.com/ophum/test`というパスでクローンされます。また、このディレクトリの中にはリポジトリの内容と同じものが入っています。(クローンなので)~~
  
~~同じものが入っています。~~  
  
~~ということで、例えばローカルのリポジトリのパスが以下のような場合~~
    
    $HOME/test

~~このパスのリンクを`$GOPATH/src/github.com/ophum/`に貼ってあげます。~~

    ln -s $HOME/test $GOPATH/src/github.com/ophum/test

~~そうすることで、$HOME/testを変更した場合リモートにpushすることなく、このパッケージをインポートしているパッケージで`go run`することができました。~~

## ~~急募~~
~~ちゃんとした開発方法が記されたわかりやすいドキュメント~~
DjangoのViewでデータを追加する時　Error:save() missing 1 required positional argument: 'self'

DjangoのViewでデータを追加する時、例えばフォームから入力してデータを追加するのではなく、
View上でDjangoモデルに直接データを追加したい時がある。

これをやろうとした時に
少し詰まったのでメモしておく。

下のコードにあるように、FavoriteというDjangoモデルにuserとfavoriteのフィールドがあり、
そこにLikeしたユーザとその投稿の記事を紐づけたい時、初めはFav=Favoriteとしていた為、
エラーが生じていた。修正案としてFav=Favorite()としてインスタンスを引き渡すと無事に解決出来た。

```ruby:qiita.rb
def like(request):
    Fav = Favorite()
    Fav.user = request.user
    Fav.favorite = post
    Fav.save()
```

また、こちらの記事にも
同じような事が記載されている。
https://stackoverflow.com/questions/46907511/typeerror-save-missing-1-required-positional-argument-self
Jupyter LabをDockerで環境構築する

## 概要
Jupyter LabのDockerでの環境構築方法

## 関連記事
- [jupyter(ipython notebook) + matplotlib + vagrantでグラフ描画](https://qiita.com/Esfahan/items/bbb2e9d593faa8b45861)

## 環境
- jupyterlab 0.35.4


## Dockerイメージの作成
### Dockerイメージをpull

```shell-session
$ sudo docker pull jupyter/datascience-notebook
```

### Dockerfileを作成

```Dockerfile
FROM jupyter/datascience-notebook

RUN pip install --upgrade pip
RUN pip install jupyterlab
RUN jupyter serverextension enable --py jupyterlab
```

### build

```shell-session
$ sudo docker build -t jupyterlab:latest ./
```

## jupyterlabのパスワードを設定
以下のコマンドで、jupyterlabにブラウザでアクセスする際のパスワードを設定する。

```shell-session
$ sudo docker run --rm -it \
  jupyter/datascience-notebook /bin/bash -c \
  "python -c 'from notebook.auth import passwd;print(passwd())'"

# パスワードを入力
Enter password:
Verify password:
# ハッシュ化されたパスワード
sha1:xxxxxxxxxxxxxxxxxxxxxxxx
```

jupyter-notebook4.3からセキュリティが厳しくなったらしい
https://jupyter-notebook.readthedocs.io/en/latest/security.html#server-security

### ハッシュ化されたパスワードを付与してjupyterlabを起動する
`--NotebookApp.password`オプションに、ハッシュ化されたパスワードをセットする。

```bash
sudo docker run  \
    --rm \
    -e TZ=Asia/Tokyo \
    -p 8888:8888 \
    --name jupyterlab \
    -v $(pwd)/code:/code \
    jupyterlab:latest \
    start.sh jupyter lab --NotebookApp.password="sha1:xxxxxxxxxxxxxxxxxxxxxxxx"
```

### ブラウザでアクセス
http://localhost:8888
ブラウザでアクセスし、先程設定したパスワードを入力する。

Notebookでpython3を実行してみる

![Screen Shot 2019-03-08 at 18.04.54.png](https://qiita-image-store.s3.amazonaws.com/0/105936/e80eaf24-c042-2e03-cb84-2fe2d24a3367.png)

pythonを実行

![Screen Shot 2019-03-08 at 18.05.25.png](https://qiita-image-store.s3.amazonaws.com/0/105936/69f99363-c504-0efa-d9f9-d9aade19a1a6.png)


## pythonファイルを実行する場合
pythonファイルを実行する場合は、`%run`を使う。

```
%run -i {ファイル名}
```

また、`cd`とか`ls`とかいったシェルコマンドも使える。

![Screen Shot 2019-03-08 at 18.16.28.png](https://qiita-image-store.s3.amazonaws.com/0/105936/9fa5fefb-fd45-6754-f474-b28a267fc74b.png)



## 参考
- [Jupyter Notebookの後継？Jupyter Labをつかってみた](http://kzkohashi.hatenablog.com/entry/2018/07/27/073124)
Raspberry Pi 3 に NAS をマウントさせる

Raspberry Pi 3 Model B+ ( ラズベリーパイ ) を使用したNASのマウント

# 環境
- Raspberry Pi 3 Model B+
- DroboFS ( NAS )
- NAS の ipを固定(任意) [ 192.168.2.100 ]


# 1. cifs-utilsのインストール

```
$ sudo apt-get install cifs-utils
```

# 2.マウント用ディレクトリの作成

```
$ sudo mkdir /mnt/nas
$ chmod 777 /mnt/nas
```

# 3.マウント

```
$ sudo mount -t cifs //192.168.2.100/Public /mnt/nas cifs username=pi,password=,file_mode=0777,dir_mode=0777,iocharset=utf8,defaults,vers=1.0
```
"mount error(112): Host is down"が表示される場合はvers を 2.0 or 3.0 等に変更して再度マウント
私の環境の場合NASが古い関係でvers=1.0のパラメーターが無いとマウントできませんでした。

匿名でアクセスさせたかったのでpassword=を空で指定しています。



# 4.起動時に自動的にマウントさせる

### 1. 設定を追加

```
$ sudo nano /etc/fstab
```


```php:/etc/fstab
//192.168.2.100/Public /mnt/nas cifs username=pi,password=,file_mode=0777,dir_mode=0777,iocharset=utf8,defaults 0 0
```


# 5.手動での動作確認

```
$ sudo mount -a
$ df
/mnt/nas にマウントされていることを確認
```

これでエラーが表示されずマウントできていることが確認できたら起動時に自動マウントされるようになります。

# 6.ネットワークサービス起動後にマウントするように設定

通信可能な状態になってからNASのマウントを行わないと失敗するの下記設定を行います。

```
$ sudo raspi-config
```
![img2-5.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/8ba12a86-719f-04bd-eb6b-dd3abca63378.jpeg)
「3 Boot Options」を選択

![88.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/05ac30a5-e9c1-744e-d412-e8d0cb1696e2.jpeg)
「B2 Wait For Network at Boot」を選択

# 7.再起動
```
$ reboot
```
```
$ df
/mnt/nas にマウントされていることを確認
```


# 7.補足説明 ( マウントの解除 ) 
手順上必要はありませんがエラー時、設定変更時に再度マウントする時等に使用します。

```
$ sudo umount /mnt/nas
```
# 参考

・[Linux上でWindows共有フォルダをマウントする時に"mount error(112): Host is down"エラーが発生](https://qiita.com/Ahijo0523/items/2e0f43d1de21793202a0)
・[ラズパイZeroで自宅のNASをマウントする](https://www.mana-cat.com/entry/2017/05/02/164244)
・[Raspberry PiにNASをマウントする。](https://qiita.com/wbh/items/90288f44b62a36d24f0a)
・[Raspberry Pi で Linkstation を自動マウントする](https://blog.withachristianwife.com/2018/01/25/auto-mount-linkstation-with-raspberry-pi/)
・[Raspberry Pi (Wheezy)でWindowsの共有フォルダへのアクセス](https://blog.goo.ne.jp/sabotenboy_london/e/c6411a6baac033d8487eb402313a791e)
・[Raspberry piにNASをマウントした時の覚書](https://qiita.com/NoTASK/items/8521d237bcacf75a37ba)
gitで履歴を保持したままブランチ名を変更する方法

masterと別のブランチ (以下ではdevelopとする) が枝分かれしてしまったけど、
developをmasterに置き換えたい時ってあると思います。

例えば、github pagesだとmasterブランチの内容がデプロイされるので、
developブランチなどの開発用ブランチを切っておいて、ビルドしたものをmasterで管理するのが一般的だと思います。でも気が変わって、masterで開発用コードを管理したいと思うかもしれません。 (github pageからnetlifyに移行するときとか)

# 解決策1: ブランチをリネームする

もとのmasterの履歴が消えてしまってもいいなら、
以下のように、developブランチをmasterに名前変更するのが一番手っ取り早いです。

```bash
git branch -m master old-master
git branch -m develop master
git push -f origin master # force pushでコンフリクトを避ける
```

# 解決策2: マージ戦略 (`ours`)を使う

もし、masterの情報を消さずに履歴に残しておきたいのであれば、`git merge`の`--strategy`オプションでマージ戦略を`ours`にすればよいです。
この戦略を使うことによって、マージする際にマージ元の履歴は残しつつ、マージの結果は現在のブランチの内容で上書きされた状態になります。

```bash
git checkout develop
git merge --strategy ours master
git checkout master
git merge develop
```

上のコマンドを実行するとコミットログは以下のようになります。
左側のパスがdevelop、右側がmasterのパスとなっているのですが、
実行後のmasterはdevelopがもともと指していたコミット (`add netlify CMS setting`)と同じになっていることが (`diff`)で確認できました。

```
*   d39f112 (HEAD -> master, origin/master) Merge branch 'master' into develop
|\
| * b5d22c9 Updates
| * 81d260f Updates
| * 6b4e277 Updates
* | 4a2b0e8 Add netlify CMS setting
* | 18454da Add article
* | c2a7dc1 Add gh-pages
|/
* 4352875 Add styled-component and change layout
* 62c0b88 Make date atom component
```
MongoDB Atlasに接続する

MongoDBのDBaaS(Database as a Service)であるMongoDB AtlasにCLI(**PowerShell**)およびGUIビューアの**MongoDB Compass**で接続する方法。
筆者の環境はwindows8.1。

##手順
[MongoDB Atlas](https://www.mongodb.com/cloud/atlas)の登録やClusterの作成等は既に終わっているものとする。
**Clusters**->**Overview**にある**CONNECT**ボタンを押す。
<img src=https://qiita-image-store.s3.amazonaws.com/0/296108/61aa42f2-144c-06b0-2db9-c40852e5678b.png>


次の画面が表示される
<img src=https://qiita-image-store.s3.amazonaws.com/0/296108/82db4313-5c40-b9a6-a8a6-26309e231790.png>
 
* 一番上**Mongo Shell**はコマンドプロンプト等CLIを使う
* 真ん中はmongoDBのドライバ(ライブラリ)を使って自作アプリケーションから接続する方法
* 一番下はビューアである**MongoDB Compass**から接続する方法

###CLIで接続する

2019/3/8現在、CLIを選んだときとCompassを選んだときに、(最新のツールを選んでいれば)、表示されるコマンドが同一なので、compassの画面で説明する。
<img src=https://qiita-image-store.s3.amazonaws.com/0/296108/1caa0628-0272-03a6-4be0-7f18bf6d15ac.png>

CLIに入力するコマンドが表示されるので、**Copy**ボタンを押す。
大体次のようなコマンドになっているはず。

```language:PowerShell
mongo "mongodb+srv://something-something.mongodb.net/something"     --username example

```
実行するとパスワード入力を求められ、接続できる。
>MongoDB shell version v4.0.6
Enter password:
connecting to: mongodb://**something-shard-00-00-something.mongodb.net**.:27017, ...

###Compassで接続する
Compassを立ち上げて新規の接続を設定する。
<img src=https://qiita-image-store.s3.amazonaws.com/0/296108/de85280f-6089-d480-9508-3f2d2f85ada6.png>

* 注意するのが、**Hostname**で、コマンドに記載されているホスト名＋ドメイン名(一つ上の画像で青いブロック：something-something.mongodb.net)を書いても接続できない。
CLIで接続したときに表示される接続先(ここでは**something-shard-00-00-something.mongodb.net**)で接続できた。
* 既に別の端末が接続している場合は**Read Preference**を**Secondary**等に変更する


後は画像の丸を付けた個所（**Authentication(Username, Password), SSL**）を設定して**CONNECT**ボタンを押す。
Raspberry Pi 3 でファイル共有 ( samba )

Raspberry Pi 3 Model B+ ( ラズベリーパイ ) を使用したファイル共有 ( samba ) 環境構築

# 環境
- Raspberry Pi 3 Model B+
- Raspberry Pi の ipを固定(任意) [ 192.168.1.110 ]

# 1.sambaインストール

```
$ sudo apt-get install samba
```


# 2.設定

```
$ sudo nano /etc/samba/smb.conf
```

```/etc/samba/smb.conf
[Public]
   comment = RaspberryPi3
   path = /mnt/nas
   guest ok = yes
   read only = no
   browsable = yes
   force user = pi
```
上記設定を追加
pathについては共有したいディレクトリを設定


# 3.設定を反映させるために再起動

```
$ sudo service smbd restart
```

これで \\192.168.1.110\Public で他のパソコン等からも接続が可能になりました。
![img99.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/7197bc88-a4ca-7d34-af09-1782facbc7bd.jpeg)

# 参考
・[Raspberry Pi 3 Model B+ に samba をインストールする](https://qiita.com/bu_itamochi/items/d413d24d68f144949c57)
GNU Parallelでプログラムを実行する時に"dyld: Library not loaded"とエラーが出る

# 何が起こったか
CERNのROOTを使ったプログラムをGNU Parallelで実行したかったが、以下のようなエラーで実行できなかった。詳細は省くけど、実行ファイルはanalysisというもので、引数として数字を読み込むとそれに対応したデータの解析をしてくれるもの。

```
$ ./analysis 1000
```

これならば問題なく動く。これを以下のようにするとエラーが出る。

```
$ seq 1000 1010 | paralle ./analysis
dyld: Library not loaded: @rpath/libCore.so
  Referenced from: /....././analysis
  Reason: image not found
dyld: Library not loaded: @rpath/libCore.so
  Referenced from: /....././analysis
  Reason: image not found
dyld: Library not loaded: @rpath/libCore.so
  Referenced from: /....././analysis
  Reason: image not found
(以下同じエラー)
```

# 解決策
解決方法はここに書いてあった。
https://root-forum.cern.ch/t/rpath-madness-on-os-x/23654
乱暴にまとめると、MacOSXの10.10以降はDYLD_LIBRARY_PATHはある条件下では無視されるらしい。ちなみに、正しくROOTをインストールした状態だと（thisroot.shを動かすと）DYLD_LIBRARY_PATHは設定されているので、そのPATH内に目的のlibCore.soは存在している。
諦めて、プログラム本体をコンパイルする際にライブラリがある場所を明示的に書く必要があるらしい。C++のコンパイルオプションに以下の行を入れる。

```
-Wl,-rpath,<root-installation-prefix>/lib
```

# よくわかっていないこと
すごく簡単なShell Scriptを書いてみる。

```sh:tmp.sh
#!/bin/bash
./analysis 1000
./analysis 1001
```

これを実行すると動かない。今はzshを使っているんだけど、bashにすると動く（こともある）。基本的にスクリプトから呼び出すのがダメなようにも見えるけど、このShellScriptが動くがParallelではダメな場合もあったりする。それとbashやtcsh、zshと変えてみると動いたり動かなかったり。ちゃんと全部組み合わせを調べてはいない。
【React Native】Error: ENOENT: no such file or directory, uv_cwdが出たときにまずすること

何回やっても忘れてしまうので......

1.

```bash
$ react-native run-android
```
を実行したターミナルでCtrl+C

2.

```bash
$ react-native run-android
```
を再実行！

これでエラーがまだ出るときは公式やstack over flowを見ましょう
jsでブラウザバックボタンを無効にする

# はじめに

たまにブラウザの戻るボタン押したらアラートが出て戻れないようになっているサイトありますよね。
あれをjQueryで実装する機会があり、
色々検索してやろうとしたんですが、なかなかできない or コード量が多く…
何とか試行錯誤して簡潔にブラウザのバックボタンを無効にできたので、実装方法をまとめました。


# ソースコード

コードは短め。jQuery使ってます。

```javascript:js
$(function(){
 history.pushState(null, null, null); //ブラウザバック無効化
 //ブラウザバックボタン押下時
 $(window).on("popstate", function (event) {
   history.pushState(null, null, null);
   window.alert('前のページに戻る場合、前に戻るボタンから戻ってください。');
 });
});
```

## 解説

### history.pushState(null, null, null);
まずこの記述で、偽の履歴を追加しています。
なのでこの記述だけで、ブラウザバックボタン1回は阻止できそう。
しかし、2回押されると戻ってしまいます。
そのため、戻るボタンを感知して毎回これを追加していく必要がありそう。

参考サイト：[ブラウザの履歴を操作する](https://developer.mozilla.org/ja/docs/Web/Guide/DOM/Manipulating_the_browser_history)

### 戻るボタンを押されたときにイベント発火する方法

```javascript
$(window).on("popstate", function (event) {
//ここに処理を記述
});
```

>引用　https://developer.mozilla.org/ja/docs/Web/API/WindowEventHandlers/onpopstate
>popstate イベントは、戻るボタンをクリックしたり (又は JavaScript で history.back() を呼び出したり)、
>同じ文書で2つの履歴項目間を移動したりするように、ブラウザーのアクションを実行することのみがトリガーになります。

このイベントをうまく使って戻るボタン押下を感知。そんでもう一回偽の履歴を追加して、アラート表示。
ここはモーダルにできればモーダルの方が良いですね（　＾ω＾）

# 応用編

### 特定のページだけ適用する


例えば、サイトに30くらいページがあるとして、
その中の5つのページにこのブラウザバック無効を適用したいとなると、5つのページからこのjsファイルを呼び出すのはちょっと大変ですよね。

その場合、共通で呼び出しているヘッダーなどにjsファイルを呼び出し、
jsの中で特定のページにだけ適用させるようにします。

その方法はこんな感じでいけます。

```javascript:js
$(function(){

//URLファイル名取得
var path = window.location.pathname.split('/');
path = path[path.length-1].split('.html')[0];

//ブラウザバック対象ページ
var pathTarget = ['page_backdisable','page_backdisable1'];

if(pathTarget.indexOf(path) >= 0){
	//pathTargetに入っているページだけ実行される
	//上記ソースコードを書く
}

});
```

この場合、page_backdisable.htmlとpage_backdisable1.htmlのページのみブラウザバック無効化が適用されます。

URLファイル名取得の方法はサイトによると思います。
pathで現在いるページのファイル名を取得して、pathTargetに適用したいファイル名を記述しておきます。
pathTarget.indexOf(path)で比較し、
一致していたら0以上、一致していなかったら-1が返ってきます。


# おわりに
一応Chrome、IE、Firefox、Safariらへんは試してちゃんと確認できました。
また、もっと良い書き方あったら是非コメントしてください！
Amazon Linux 2 の PHP7.2 で ElastiCache の Redis を使う方法


Amazon Linux 2 の PHP7.2 で、冗長化構成とかして、セッションを ElastiCache の Redis に保存して使う場合に php-pecl-redis をインストールする方法。

# 2019/6/3 更新

祝、Amazon Extra の PHP にも redis が入っていることを確認しました！
良かった。良かった。

もう remi レポジトリを追加しなくて良いです。

```
$ sudo amazon-linux-extras install php7.2
$ sudo yum install --enablerepo=amzn2extra-php7.2 php-pecl-redis 
$ sudo systemctl restart php-fpm

$ sudo vi /etc/php.d/50-redis.ini
session.save_handler = redis
session.save_path = "[ElastiCacheのエンドポイント]"
```

## Remi レポジトリ削除方法

yum のインストールし直しをしても良いかもです。

```
$ sudo yum remove php-pecl-redis
$ sudo vi /etc/yum.repos.d/
```

# 2019/3 時点の情報

他のブログ記事だと、素の Apache や PHP7.2 での方法しか書いてなかった。
Epel のレポジトリだと古いバージョンの PHP しかできないみたいなので、
Remi のレポジトリを使う。

```
$ sudo yum install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
$ sudo yum install --enablerepo=remi-php72 php-pecl-redis 
$ sudo systemctl restart php-fpm

$ sudo vi /etc/php.d/50-redis.ini
session.save_handler = redis
session.save_path = "[ElastiCacheのエンドポイント]"
```

concrete5 CMS のみで利用する場合は `/etc/php.d/50-redis.ini` の編集は不要です。

Redis 自体は、サーバー上で動かさないのでインストールしないです。


この記事は、 [concrete5](https://concrete5-japan.org) CMS が Version 8.5.0 で Redis に標準対応して、月間1000万PVのサイトで、ElastiCache の Redis でキャッシュやセッションを保持させて冗長化させているんだけれど、Amazon Linux でしか試したことがなかったので、Amazon Linux 2 で可能かどうか検証したために作成しました。

## 参考

https://blog.offline-net.com/2018/12/30/ama

## 他参考記事

[concrete5 (8.5.0 以降) で Redis を使う方法](https://qiita.com/katzueno/items/0f172a2d5bc65fc9acb2)
徳丸本を久々に読んでXSS、SQLインジェクション、CSRFなどの盲点を復習した

# 概要
「安全なWebアプリケーションの作り方」という包括的にWeb技術のセキュリティが書かれた本があるのですが、それを久々に読んで盲点だったなーと思うことをまとめました。

- アプリケーションレイヤーで対策できること
- サーバー・インフラレイヤーで対策できること

に分けてまとめていきます。

# アプリケーションレイヤーで対策できること
## XSS対策の盲点
### セッションIDのCookieにHttpOnlyを付与しよう
基本は``htmlspecialchars``ですが、それ以外に盲点になりそうな対策として、クッキーに``HttpOnly``属性を付与するというのがあります。

セッションIDの``Cookie``に``HttpOnly``を付与することで、万が一XSS脆弱性があってもセッションIDが盗まれることがなくなります。

``HttpOnly``というのは、``JavaScript``などのHttp以外の読み取りに対するOnlyなんですね。

### URLを動的に生成する部分ではURLとして正しいかどうかのチェックをしよう
滅多にはないと思いますが、動的に生成されるURLが画像に対する``href``とか``src``だった場合、``javascript:HOGEHOGE``という形式の文字列がそこに入ると任意の``JavaScript``を実行できてしまいます。

なので、そういった出力パタメータには``http(s)``から始まっているかどうかのチェッカーを挟みましょう。

とはいえあるかな・・・だいたいURLはサーバー側で生成している気がする。が。

CGMなどでユーザーにHTMLタグの入力を許可する場合は表示していい要素だけ逃してエスケープしよう

[https://github.com/paquettg/php-html-parser](https://github.com/paquettg/php-html-parser)
こういうライブラリを使って、HTMLの内容をパースして個別でタグに包んであげる、という感じでしょうかね。その際に中身をエスケープすれば無事で済みそうです。

## SQLインジェクション対策の盲点
もちろん静的プレースホルダー利用一択なのはわかった上で。さらにやったほうがいいこと。

### アプリケーションを操作するアカウントのデータベースの権限を適切に設定する
これはうっかりしそう。
アプリケーション側から利用するデータベースユーザーが例えばTableの削除権限を持っている必要はありませんし。

データベース消されるとかが一番ひどいので、こういった根っこの対策はやっておいて損は無さそう。

例えばこのページに権限の一覧が書かれているようなので参考までに。
[権限の種類と設定されている権限の確認](https://www.dbonline.jp/mysql/user/index5.html)

## CSRF対策の盲点
何度見ても``CSRF``はどういう脆弱性なのか説明が難しいですね。

ざっくりいうと、僕が作ったサイトからTwitterのパスワード変更画面にリクエストを飛ばして、それをTwitterが承認したらやばいよねってやつです。
偽サイトをいくらでも作れてしまいます。

なので、``CSRF``対策とは、**あるリクエストが本物のユーザーによる当サイトからのアクセスであることを証明する手段**ということになります。

### まずはCSRF対策が必要なページを探そう
全ページに上記の対策をしたら大げさだし、そもそも自然流入してくる人たちまで弾かれちゃうのでやめましょう。

### トークンで対策しよう
トークン埋め込みが一般的だけど・・・
``JWT``が一昔前に流行りましたね。
[JWT（JSON Web Token）でCSRF脆弱性を回避できるワケを調べてみた話](https://qiita.com/mejileben/items/ae7b346f0fc4a59101b5)

このQiita見たら多分思い出せる。手前味噌ですが。

# サーバー・インフラレイヤーで対策できること
## Webサーバーそのものの対策
### 脆弱性情報をRSSで監視しよう
こういうのちゃんとキャッチアップしないとなぁ。。。
https://jvn.jp/rss/

### ポートスキャンを掛けて不要なポートが空いていないかを確認しよう
``SSH``は特定のIPからしか許可しないようにしましょう。

[CloudWatch LogsでSSHへの不正アクセスを検知し、通知を受ける。](https://qiita.com/ukiuni@github/items/8f0c45037e3a28238290)

上記の記事のように検知する仕組みを作るのもいいなと思います。

### SSHサーバーのパスワード認証を辞めて公開鍵認証のみにしよう
総当たり攻撃を仕掛けられる可能性があるので、パスワード認証はそもそも避けておくべきです。

### サーバー自体の見直しをしよう
Linuxサーバーのセキュリティに関してはこの記事がとてもわかり易くてよかったです。

[そこそこセキュアなlinuxサーバーを作る](https://qiita.com/cocuh/items/e7c305ccffb6841d109)

## まとめ
Webセキュリティは壊滅的なリスクを回避するためのスキルであるがゆえに、どうしても経営層とか企画レイヤーから甘く見られてしまう背景もあると思っていて、意識的にエンジニアサイドが身につけていかないと、と個人的には危機感を持って学んでいきたいなーと思っています。

おすすめのサイト、書籍などありましたら是非コメントやTwitterにて教えていただければ幸いです！！