OmniAICreator/Qiita-1.07M huggingface dataset:
wordpress使用時に参考にしたサイトとプラグイン

# はじめに
wordpressは高機能で使ってて非常に楽しいのですが、なにぶんカスタマイズ性が高すぎてよくわかんなくなってしまいます。そのため、自分の頭の整理も込めて、参考させていただいたwebページをまとめています。

※ 間違いなどありましたらコメント欄にて指摘していただけるとありがたいです。m(_ _)m
適宜、追加と加筆修正を行なっていく予定です。

# 参考にしたもの一覧

## 基本
- http://www.nsthink.com/wordpress/
    - wpの基本的な構成を学ぶことができる。
    - wpの各種ファイルの意味がわかる。
    - まずはこれをしっかりと読むことで、独自のPHPをかく時や複雑なカスタマイズをするときに迷うことが少なくなる。

## スタイル
- https://www.akaeho.net/wordpress-edit-css/
    - wpの追加CSSの使い方がわかる。
    - 後述するJetpackを導入すると利用可能
    - 追加CSSは一度書けば全ての固定ページと投稿ページにも反映されるのが利点。
    - しかし、追加CSSで記述したスタイルは一つのファイルとしては保存されないため、管理がしにくいのが難点。
    - そのため、要所のスタイリングには、後述する外部CSSファイルのインポート方法を学んだ方がいいかもしれない。
    - 追加CSSを用いる場合はChromeを使うべき。
- http://design-spice.com/2011/10/14/wordpress-cs/
    - ひとつのページにのみ外部CSSを読み込ませる方法。
    - ブラウザのページ編集画面からカスタムフィールドにてCSSを設定できるようになるため、わかりやすい。
    - 記述したコードを読むと、functions.phpのいじり方が少しわかる。
    - functions.phpを直接触るため、バックアップは必ず取っておく。

## プラグイン
- [All-in-One WP Migration](https://ja.wordpress.org/plugins/all-in-one-wp-migration/)
    - これひとつでwpを別のサーバーに移動することが楽になった。
    - 移動先のwpと移動下のwpにも真っ先に導入しておきたいプラグイン。
    - [使い方](https://netaone.com/wp/all-in-one-wp-migration/)
    - 後述するJetpackは元どおりに反映されなかった。
- [Jetpack by WordPress.com](https://ja.wordpress.org/plugins/jetpack/)
    - アクセス解析のような機能や、その他たくさんの機能が盛り込まれているプラグイン。
    - しかし今回はウィジェットの公開設定の機能を主に使った。
    - 特定のページにのみウィジェットを表示させるなどの設定ができる。
    - 前述した追加CSSのように、webの解説ページによっては、これが入っている前提で話が進むものもある。そのため、真っ先に導入したいプラグインのひとつ。
- [Contact Form 7](https://ja.wordpress.org/plugins/contact-form-7/)
    - メールフォームを作成する時に便利なプラグイン。
    - これがあれば一瞬でフォームが完成する。
    - 製作者が日本人のようなので、日本語の解説が多めでありがたい。
    - [公式のリファレンス](https://contactform7.com/ja/docs/)、[初心者向けの解説](https://ferret-plus.com/8560)
- [Custom Post Type UI](https://ja.wordpress.org/plugins/custom-post-type-ui/)
    - カスタム投稿タイプを簡単に実装できるプラグイン
    - これで記事の投稿と管理がしやすくなった。
    - [解説](https://techacademy.jp/magazine/4532)
- [List category posts](https://ja.wordpress.org/plugins/list-category-posts/)
    - 特定のカテゴリーやカスタム投稿を一覧で表示する。
    - 上記のCustom Post Type UIと同時に使用すると相性がいい。
    - 機能が多すぎるので、まずは[このサイト](https://www.nishi2002.com/19595.html)で軽く触れた後に、[公式のリファレンス](https://wordpress.org/plugins/list-category-posts/#other_notes)を読むといいと思う。
- [Simple Calendar – Google Calendar Plugin](https://ja.wordpress.org/plugins/google-calendar-events/)
    - Googleカレンダーを固定ページやサイドバーとして表示できるプラグイン。
    - 初めから用意されているデザインがとてもかっこいい。
    - プラグインを使用ために必要なGoogleカレンダー側の設定がとても面倒。
    - 参考のページを見つけてもほとんどが昔のページデザインのもの。
    - [使い方](http://tech.pjin.jp/blog/2016/04/07/carendar-for-wordpress/)（これも昔のGoogleのデザインなので、参考程度に。）
- [Shortcodes Ultimate](https://ja.wordpress.org/plugins/shortcodes-ultimate/)
    - 簡単にショートコードを生成できるプラグイン。
    - 特にページ内にアニメーションを導入したい時に活躍した。
    - [アニメーションの使い方](https://crescita.tokyo/wordpress-animation/)
- [WP-Members Membership Plugin](https://ja.wordpress.org/plugins/wp-members/)
    - 会員制のページを作る時に利用。
    - カスタマイズ次第で一部のページを会員向けにしたりすることが可能。
    - [使い方](https://techacademy.jp/magazine/6669)

# 最後に
[Tech Academy](https://techacademy.jp/magazine/6669)さんは何か新しく使い方を学びたい時に、要点を短時間で学習できるため、非常にお世話になっています。ありがとうございます。
デフォルトのNamesプロパティに注意

##現象
↓ここを見て追試してみた。
[[EXCEL]名前定義にはブックとシートの指定があって取り出し方によって値が変わることがある。](https://qiita.com/tomikiya/items/7f18d5f68152d78774af)
素朴にNamesと書くだけの場合ThisWorkbook.Namesを見ているようだ。
当たり前だが、ワークシート指定する場合はWorksheet.Namesを見る。
ところがThisWorkbook.NamesはWorksheets(1).Namesに重複する名前定義があれば上書きされてしまうらしい。
なんちゅう子だ、もしかしたら既知の手遅れな不具合なのかもしれないがorz

###補足
極端なテストケース：ワークシートを1枚にして、1個セルを選んでブックの名前定義"color"を付け、もう1個セルを選んでシートの名前定義"color"を「名前の管理」メニューから新規作成する。テストプログラムを実行すると常にシートの名前定義が使われる。

##対策
- ブックとシートで名前の重複を避ける
- 逐一Worksheet指定する
- Worksheets(1)にシートの名前定義をしていないシートを割り当てる

##テストプログラム
```vb:test.xlsm
Sub TriggerObject_Click()
  On Error GoTo Err:
  Caption = "Plain Names "
  MsgBox Caption & Names("color").RefersTo
  Caption = "Application "
  MsgBox Caption & Application.Names("color").RefersTo
  Caption = "ThisWorkbook "
  MsgBox Caption & ThisWorkbook.Names("color").RefersTo
  Caption = "Worksheets(1) "
  MsgBox Caption & Worksheets(1).Names("color").RefersTo
  Caption = "ActiveSheet "
  MsgBox Caption & ActiveSheet.Names("color").RefersTo
  Exit Sub
Err:
  MsgBox Caption & "No Name"
  Resume Next
End Sub
```
機能追加しても手数を増やさないでよね



プログラムをリリースした後、機能を追加することはよくあります。
機能追加するとどうしてもプログラムは大きく複雑になり、場合によってはユーザーの操作も増えてしまいます。
ここでは、**手数**という観点で、ユーザーを困らせない考え方を紹介します。

##**手数**

ユーザーが何かの目的で機器やソフトウェアを操作する場合に、ユーザーが操作する数を**`手数`**とここでは呼ぶことにします。（**`ステップ数`**と呼ぶと意味が異なり混乱するのでやめます）

**手数**は、プログラムに機能を追加するとどうしても増やさざるを得ない状況に直面します。
その場合、プログラムの改修のしやすさの視点で追加してしまわず、

```bash
最小の手数を増やさない
```

ということを考えてみましょう。
**”一番シンプルな操作をするケースでの手数を増やさないでよね"**ということです。
ポイントは **最小の** です。機能を追加しても、その追加機能を使わないユーザーにとっては、**手数**が増えてほしくないわけです。

#**券売機の例**

例えば、電車の券売機で切符を買う場合の**手数**を考えます。一番シンプルなケースとして、現金で大人1人分の切符を購入することにします。
その場合の手順は、

```
1. お金を入れる
2. 行き先ボタンを押す
3. 切符を受け取る（お釣りがあればお釣りも）
```

となるので、手数は**３**となります。

最近の券売機は、

- 大人1人と子供1人のまとめ買い
- 回数券を購入する機能
- 電子マネーにチャージする機能

等々、機能がどんどんと増えていますが、一番シンプルに購入するケースでは、

```
1. お金を入れる
2. 行き先ボタンを押す
3. 切符を受け取る（お釣りがあればお釣りも）
```

を崩さずに維持すべきです。これが

```
1. 画面の「切符を買う」「チャージする」の2つのボタンから、「切符を買う」のボタンを押す
2. お金を入れる
3. 行き先ボタンを押す
4. 切符を受け取る（お釣りがあればお釣りも）
```

のように手数が増えてしまうと、ユーザーの手間が増えて残念です。

##**携帯電話の例**
**手数**という点では、電話機は優秀です。
黒電話も、コードレス電話も、携帯電話も、電話を掛けるときの手数は**２**です。

```
1. 受話器を上げる
2. 電話番号を押す
```

```
1. 充電器から電話機を持ち上げる
2. 電話番号を押す
```

```
1. 携帯電話の通話ボタンを押す
2. 電話番号を押す　（1と2は逆でも可）
```

スマホの登場で電話の機能がアプリとなったため、手数が１増えましたが、これはやむを得ない増加と言えます。原則、増やさないように考えた結果かどうかが大事です。

```
1. 電話アプリを起動する
2. 電話番号を押す
3. 発信ボタンを押す
```

##**プログラムの良い改修と悪い改修**
###**良い改修**
- 見た目や動作を変えない（新機能に気づいてもらえなくてもよい！ぐらいの気持ちで）
- バージョンアップ後の初回起動時のみ、新機能をさりげなくアピール（最小の操作を邪魔しない程度に留める）
- 見た目を少しだけ変える（最小の操作に影響が無い範囲で！）
- 逆に最小の手数を減らせるか考えてみる（分かりにくくならないように注意が必要）

###**悪い改修**

- 「従来の機能」と「追加機能」を選択させるダイアログを最初に強制表示する
- 従来の機能を別の場所に移動する（従来の手順が分からなくなる）
- バージョンアップ後の初回起動時のみ、追加機能のチュートリアルを強制的に開始する

###**悪い改修に陥らないために**
開発者にしてはユーザーに新しい機能を使って欲しいと考える気持ちはよく分かりますが、下手に新機能をアピールすると、ユーザーの反感を買い、そのプログラムが搭載されたパッケージ・製品そのものも嫌いになってしまいます。
ユーザーの手数が増加するのは極力避けて、ユーザーを困らせないようにしましょう。

###参考
[複雑さと前提条件が増えすぎるとメンテナンス不能になる。](http://qiita.com/nonbiri15/items/db4ec3077837f691535b)
unityでunityeditor その３

#概要

unityでunityeditorやってみた。
fbxからanimationclipをコピーしてみた。

#環境

unity 5.2.5f1

#サンプルコード

```
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;

public class test4 : EditorWindow
{
    public string Text
    {
        get;
        set;
    }
    const int width = 400;
    const int height = 300;
    [MenuItem("test/test4")]
    public static test4 Init()
    {
        var window = EditorWindow.GetWindow<test4>("test4") as test4;
        return window;
    }
    void OnGUI()
    {
        EditorGUI.TextArea(new Rect(0, 0, test4.width, test4.height - 30), this.Text);
        if (GUI.Button(new Rect(0, height - 30, test4.width, 30), "OK"))
        {
            foreach (var clip in Resources.FindObjectsOfTypeAll<AnimationClip>())
            {
                if (clip != null)
                {
                    var path = AssetDatabase.GetAssetPath(clip);
                    var directory = Path.GetDirectoryName(path);
                    if (directory != "Assets/ohi/")
                    {
                        this.Text += path;
                        this.Text += "\n";
                        var clone = new AnimationClip();
                        var events = AnimationUtility.GetAnimationEvents(clip);
                        var srcClipInfo = AnimationUtility.GetAnimationClipSettings(clip);
                        AnimationUtility.SetAnimationEvents(clone, events);
                        AnimationUtility.SetAnimationClipSettings(clone, srcClipInfo);
                        foreach (var n in AnimationUtility.GetAllCurves(clip, true))
                        {
                            clone.SetCurve(relativePath: n.path, type: n.type, propertyName: n.propertyName, curve: n.curve);
                        }
                        var outputPath = "Assets/ohi/" + clip.name + ".anim";
                        AssetDatabase.CreateAsset(clone, outputPath);
                    }
                }
            }
            this.Text += "ok";
        }
    }
}

```

以上。
unityでunityeditor その２

#概要

unityでunityeditorやってみた。
animationclipをコピーしてみた。


#環境

unity 5.2.5f1

#サンプルコード

```
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;

public class test3 : EditorWindow
{
    public string Text
    {
        get;
        set;
    }
    const int width = 400;
    const int height = 300;
    [MenuItem("test/test3")]
    public static test3 Init()
    {
        var window = EditorWindow.GetWindow<test3>("test3") as test3;
        return window;
    }
    void OnGUI()
    {
        EditorGUI.TextArea(new Rect(0, 0, test3.width, test3.height - 30), this.Text);
        if (GUI.Button(new Rect(0, height - 30, test3.width, 30), "OK"))
        {
            foreach (var clip in Selection.objects.OfType<AnimationClip>())
            {
                if (clip != null)
                {
                    var path = AssetDatabase.GetAssetPath(clip);
                    var directory = Path.GetDirectoryName(path);
                    if (directory != "Assets/ohi/")
                    {
                        this.Text += path;
                        this.Text += "\n";
                        var clone = new AnimationClip();
                        var events = AnimationUtility.GetAnimationEvents(clip);
                        var srcClipInfo = AnimationUtility.GetAnimationClipSettings(clip);
                        AnimationUtility.SetAnimationEvents(clone, events);
                        AnimationUtility.SetAnimationClipSettings(clone, srcClipInfo);
                        foreach (var n in AnimationUtility.GetAllCurves(clip, true))
                        {
                            clone.SetCurve(relativePath: n.path, type: n.type, propertyName: n.propertyName, curve: n.curve);
                        }
                        var outputPath = "Assets/ohi/" + clip.name + ".anim";
                        AssetDatabase.CreateAsset(clone, outputPath);
                    }
                }
            }
            this.Text += "ok";
        }
    }
}


```

以上。
ActsAsTaggableOnのタグをチェックボックスで複数選択して検索 w/ Ransack

#ActsAsTaggableOnのタグをチェックボックスで複数選択してRansackで検索（主にViewだけ）
```ruby:comments_controller.rb
  ...

  def search
    @tags = ActsAsTaggableOn::Tag.all
    @q = Comment.ransack(params[:q])
  end
  
  ...
```
Viewはラベルをクリックでも選択できるように

```haml:_search_form.html.haml
= search_form_for(@q, url:result_path) do |f|
  .form-group
    - @tags.each do |t|
      = f.check_box :tags_id_in, { multiple: true, :checked => t.id, include_hidden: false }, t.id
      %label.badge.badge-primary{:for => "q_tags_id_in_#{t.id}"}= t.name

  .form-group
    = f.submit "Search", class: "btn btn-lg btn-primary"

```

```sass:search_form.sass
input[type="checkbox"]
    display: none
    &:checked + .badge-primary
      font-weight: bold
      font-size: 2rem
      background-color: #dc3545
```
チェックボックス本体は`display: none`で隠しておく。
あとはお好みでスタイル当てればOK
JavaScript からクリップボードを扱える Async Clipboard API がそろそろ見えてきました

OS のクリップボードを JavaScript から扱える Async Clipboard API が Chrome M66 からデフォルトで使えるようになります。

## これまでの クリップボード
### 昔
Flash 等の技術を用いてクリップボードにアクセスしていました。
https://github.com/zeroclipboard/zeroclipboard
### 現状
IE に追従する形で他のブラウザにも `document.execCommand` が実装されました。
https://developers.google.com/web/updates/2015/04/cut-and-copy-commands

この API は Selection API と組み合わせることでテキストのコピーやペーストが可能になるというものでした。
ブラウザ間の差異や扱いにくさがあり、それを吸収するためのライブラリが生まれていました。
https://github.com/lgarron/clipboard-polyfill
https://github.com/zenorocha/clipboard.js

## Async Clipboard API
Async Clipboard API は Promise ベースでクリップボードのコピーやペーストが行える API です。
Chrome の M62 からフラグで使えており、 M66 からはデフォルトで使えるようになります。

現時点ではテキストのみの対応であり、画像等他のフォーマットは扱えません。

パーミッションについては[こちら](https://developers.google.com/web/updates/2018/03/clipboardapi#security_and_permissions)の記事が参考になります。

### 動作するサンプル
https://js-5pu4rc.stackblitz.io/
Chrome の `Version 67.0.3361.0 (Official Build) canary (64-bit)` でのみ動作確認しています。

### 実装
https://stackblitz.com/edit/js-5pu4rc
本来ボタンのクリックは不要ですが動作がわかりやすいので使用しています。

### 注意点
現状の Chrome の実装ではユーザジェスチャ（ボタンのクリック等）は不要ですが、タブがアクティブでないと動作に失敗してしまいます。

Chrome Developer Tools でサクッと試そうとしたところ、タブがアクティブになっておらず Promise が reject してしまい動作確認に手間取りました。その場合は[この issue](https://github.com/w3c/clipboard-apis/issues/66#issuecomment-365724979) で示されている通り、タブに切り替える時間を設けクリック等で切替える一手間が必要になります。

Async Clipboard API のより詳しい説明は[こちら](https://github.com/w3c/clipboard-apis/blob/master/explainer.adoc)
IntelliJ IDEA で Angular や React のデバッグをする

# はじめに

* IntellJ IDEA で Angular や React など npm で開発サーバーを起動する JavaScript アプリケーションのデバッグを行う手順をまとめた。
* 開発サーバー設定については Angular は Angular CLI で、 React は create-react-app で作成したアプリケーションのデフォルト設定を想定して記載している。

# 環境

* macOS
* IntelliJ IDEA ULTIMATE 2017.2

# 手順

## Chrome プラグインのインストール

* [JetBrains IDE Support](https://chrome.google.com/webstore/detail/jetbrains-ide-support/hmhgeddbohgjknpmjagkdomcpobmllji) をインストールする

## IntelliJ IDEA プラグインのインストール

* メニューの "Preferences" で "Plugins" を開く
* "NodeJS" プラグインをインストール

## npm 実行設定の追加

* メニューの "Run" > "Edit Configurations" を開く
* "+" 押下で "npm" を選択
* Name を "npm start" とし、Command を "start" として "OK"
* メニューの "Run" > "Run" で作成した "npm start" を実行
* 以上の手順は Angular, React 共通

## デバッグ設定の追加

* メニューの "Run" > "Edit Configurations" を開く
* "+" 押下で "JavaScript Debug" を選択
* 接続先の URL を入力して "OK"
  * Angular なら Name を "localhost:4200" とし、URL を "http://localhost:4200" とする
  * React なら Name を "localhost:3000" とし、URL を "http://localhost:3000" とする
* メニューの "Run" > "Debug" で作成したデバッグ設定を選択して実行
  * 前記の "npm start" 実行中に行う
* ブラウザで対象の URL が開かれて Chrome プラグイン経由でデバッグ情報が IDEA に引き渡される
  * コードにブレークポイントを設定して正常にデバッガが利用できることを確認する。

# 参考 URL

* https://blog.jetbrains.com/webstorm/2017/01/debugging-angular-apps/
* https://blog.jetbrains.com/webstorm/2017/01/debugging-react-apps/
[Azure] WebAppsのWebジョブから起動したバッチファイルでdateを扱う場合、mm/dd/yyyy形式になるので注意

タイトルがほぼ情報の全てですが、バッチファイル内で現在日時を取得し、それを引数としてプログラム実行することがあります。

```bat:前月(YYYYMM)を引数としてプログラム起動
rem ---現在年月の取得---
set dt=%date:~-10%
set yy=%dt:~0,4%
set mm=%dt:~5,2%

rem ---前月を計算---
set /a mm=%mm%-1
if %mm%==00 (
    set mm=12
    set /a yy=%yy%-1)

rem ---mmを0埋めして引数とする---
set mm=0%mm%
set mm=%mm:~-2%
set PREVIOUS_MONTH=%yy%%mm%

node myprocess.js %PREVIOUS_MONTH%
```

これをAzure WebAppsのWebジョブとして実行した場合、dateの結果がmm/dd/yyyy形式になるため、正常に起動しません。上記の実行結果は・・・

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/201f5c51-66ab-69d1-5ff3-e5ebc87b3db2.png)

mm/dd/yyyy形式から日付を取得するため、バッチファイルを少し修正します。変更点は 3, 4行目(yyとmmの取得位置)です。

```bat:前月(YYYYMM)を引数としてプログラム起動(改)
rem ---現在年月の取得---
set dt=%date:~-10%
set yy=%dt:~6,10%
set mm=%dt:~0,2%

rem ---前月を計算---
set /a mm=%mm%-1
if %mm%==00 (
    set mm=12
    set /a yy=%yy%-1)

rem ---mmを0埋めして引数とする---
set mm=0%mm%
set mm=%mm:~-2%
set PREVIOUS_MONTH=%yy%%mm%

node myprocess.js %PREVIOUS_MONTH%
```

動かしてみると、今度は無事実行できました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/8d8501d6-be21-25cc-2a8e-f0786bc05539.png)


WebAppsはアプリケーション設定で（WEBSITE_TIME_ZONE：Tokyo Standard TImeを設定することにより）タイムゾーンを変更できますが、日付と時刻の形式は今のところ変更できないようです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/9d439f41-4511-8d02-3367-8693d42edf47.png)

また、[こちらの記事](https://qiita.com/minorufujimoto/items/78f9da9fbff69d304cf4) にあるような地域設定に依存しないバッチへの修正は、wmicコマンドがWebAppsのユーザ権限で実行できないため、修正することができませんでした。

```powershell
D:\home>wmic os get LocalDateTime
Access is denied.
```

できれば実行されるプログラムの方で日付計算するよう変更した方がいいと思いますが、既存のバッチをWebジョブにそのまま移設したい場合は、dateの処理に注意する必要があります。
シンボリックリンク

# シンボリックリンクについて
シンボリックリンクとその周辺用語についてまとめた。
windows使ってる人はショートカットから、UNIX系はシンボリックリンク、MacOSX系はエイリアスから入ればいいと思うー。

## 経緯
昔、ハッカソンで使用していたリポジトリを見ていたら `ln -s xxx`という業務で見かけないコマンドを見つけた。
`list`を示す`ls`かと一瞬思ったが、調べてみると，`ln`コマンドはリンクの作成を行うとのことだった。
よくよく考えてみると、メイン機はwindowsなので、リンクがなにかよくわかっていない。環境設定パス？それともショートカットみたいなもの？？シンボリックリンクってなに？ハードリンクもあるの？
そういえばエイリアスって言葉もあったなぁ。って疑問が次々と生まれてきた。
まずは、用語についてそれぞれ調べる。

## 用語
- リンク
- シンボリックリンク
- ハードリンク
- エイリアス(Mac OSX)
- ショートカット(win)

### リンク
そもそもリンクとは参照のこと。

### シンボリックリンク
Windowsでいうところのショートカットのようなもの。
対象ファイルまでのパスを含んだただの小さなファイル。
存在しないファイルへのシンボリックリンクも作成することができる。

ハードリンク(あるいは単にリンク)が持つ、同一ファイルシステム内でしか使用できないという欠点を解決するために導入された。(らしい)
[参照](http://www.wdic.org/w/TECH/%E3%82%B7%E3%83%B3%E3%83%9C%E3%83%AA%E3%83%83%E3%82%AF%E3%83%AA%E3%83%B3%E3%82%AF)

### ハードリンク
ハードリンクは「ファイルに別名を付けるリンク」。
そのため、ハードリンクを削除する事で実体ファイルを削除できる。実態を共有しているため削除には注意が必要。

### シンボリックリンクとハードリンクの違い
実態ファイルを削除できるか

### ショートカット(win)
シンボリックリンクの劣化版(らしい)

### ショートカットとリンクのちがい
>ショートカットは単に宛先が書かれたファイルに過ぎないが、シンボリックリンクは宛先のファイルやディレクトリ(フォルダー)と同じ扱いをすることが可能

この比較はよくわからないが、実際にコマンドラインからの操作を行うと理解できる。
>コマンドラインからも実フォルダや実ドライブと同じ取り扱いが可能となる

### エイリアス
エイリアスはMac OS Xでのシンボリックリンクの呼称。エイリアスを削除しても本体には何も影響しない。
エイリアスはほかのOSよりも進んでおり、リンク先ファイル（オリジナルと呼ぶ）を移動したりファイル名が変更しても自動的に追従する。(エイリアスレコードと呼ばれる、ファイル固有の参照情報を保存)
ただし、UNIXでエイリアスというと、コマンドをを別名で登録する機能のことなる。

## command

```
# win
mklink /s(soft) /h(hard)
```

```
# UNIX・Mac OSX
ln -s(soft=symbolic) -h(hard)
```




### 参考
[ソフトリンク](https://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%95%E3%83%88%E3%83%AA%E3%83%B3%E3%82%AF)
[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](http://wa3.i-3-i.info/index.html)
【MATLAB】MEXでc, c++コンパイラを指定する方法【ubuntu】

# はじめに
ubuntu 16.04 & matlab R2017bにおいて，
MEXファイルを作る際に少し手間取ったのでメモ

# 問題
```matlab
mex hogehoge.cpp
```
を実行した際に，「gcc version '5.4.0'を使用しています。gcc のこのバージョンはサポートされていません」という警告が出る．
また，作成されたMEXファイルを実行した際に，
「'path/hogehoge.mexa64' で必要とされるシンボル'xxxxxxxxx' がありません。」
というエラーが発生し，実行されない．

# 原因
システムにインストールされているコンパイラ(gcc, g++)のバージョンに
matlabが対応していなかった．

# 解決策
matlabが対応しているコンパイラ (本稿執筆時はgcc-4.9, g++-4.9) をインストールし，
それらを指定してmexを実行する．

# 手順
1. gcc, g++のインストール

    ```sh
    $ sudo apt-get install gcc-4.9 g++-4.9
    ```

2. インストールした g++ (Cの場合はgcc) のパスを指定してmexを実行

    ```matlab
    mex -v GCC=/usr/bin/g++-4.9 hogehoge.cpp
    ```
GNU tar > --exclude-tag > タグファイルを持つディレクトリは圧縮しない | タグファイルは圧縮する || --exclude-tag-allと--exclude-tag-underの違いは未消化

```txt:動作環境
CentOS 6.8 (64bit)
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
tar (GNU tar) 1.23
```


## --exclude-tag

### man @ explainshell.com

https://explainshell.com/explain?cmd=tar+--exclude-tag
> 
```
--exclude-tag=FILE
      exclude contents of directories containing FILE, except
```

explainshell.comのバグのためか、説明が途中で切れている。

「exclude contents of directories containing FILE, except for FILE itself」

### 使用例

以下のファイルがあるとする。

```bash
$ ls DIR01/
doko01.txt  zun01.txt
```

exclude-tag用のファイルを作成する。

```bash
$ touch DIR01/exclude_tag
```

タグを元にtarしてみる。

```bash
$ tar cvzf assortment.tgz DIR01/ --exclude-tag=exclude_tag
DIR01/
tar: DIR01/: contains a cache directory tag exclude_tag; contents not dumped
DIR01/exclude_tag
```

tarファイルを確認すると以下となる。

```bash
$ tar tvzf assortment.tgz 
drwxrwxr-x xxx/xxx   0 2018-03-05 17:55 DIR01/
-rw-rw-r-- xxx/xxx   0 2018-03-05 17:55 DIR01/exclude_tag
```

### 用途 (推測)

- 特定のディレクトリは圧縮対象外にしたい
- 一方で、圧縮対象外にした情報はtar.gzの中に残しておきたい
    - tagファイルは圧縮する

### オプション

以下はman tarの情報。

```
       --exclude-tag=FILE
              exclude contents of directories containing FILE, except for FILE
              itself

       --exclude-tag-all=FILE exclude directories containing FILE

       --exclude-tag-under=FILE
              exclude everything under directories containing FILE
```

`--exclude-tag-all`と`--exclude-tag-under`の違いは未消化。
RubyでTwitterのアカウント間の関係を取得する

# はじめに
Twitterのフォロワーのみに閲覧を制限したコンテンツの作成を行えるアプリの開発時に必要となったので調査しました。

# gemのインストール

```bash
gem install twitter
```

# ソースコード
ユーザーAとユーザーBのスクリーンネームを引数とし、ユーザーAがユーザーBをフォローしていればtrue、していなければfalseを返す関数です。

```ruby
def auth(A_screen_name,B_screen_name)
  require 'twitter'
  client = Twitter::REST::Client.new do |config|
    config.consumer_key        = TWITTER_API_KEY
    config.consumer_secret     = TWITTER_API_SECRET
    config.access_token        = OAUTH_TOKEN
    config.access_token_secret = OAUTH_SECRET
  end

  result = client.friendship(A_screen_name,B_screen_name)
  return result.source.following?
end
```
TWITTER_API_KEY,TWITTER_API_SECRETにはTwitterから取得したAPIキーを入力してください。
セキュリティの観点から環境変数に設定したものを参照する形にするべきです。
OAUTH_TOKEN,OAUTH_SECRETにはTwitterとのOAuth認証によって発行されたものを入力してください。
# 解説

client.friendshipメソッドはユーザー間の関係性を返します。 

```ruby
result = client.friendship(A,B)
```

上記のとき、result.source.following?はAがBをfollowしてる時にtrueになり、result.source.followed_by?はBがAをfollowしてる時にtrueになります。これでアカウント間の関係を取得することが出来ます。

# 詳細
[こちら](https://5hyn3.github.io/posts/make-content-published-only-on-twitter-followers-with-rails/)のブログに本記事の内容を応用した、Twitterのフォロワーのみに閲覧を制限したコンテンツの作成を行えるアプリの開発についての記事を書きました。

# 参考
[Qiita - OmniAuthで認証した後に、tweetしたりfollowしたりする](https://qiita.com/hilotter/items/dfcf287c8c6704128ddd)
3/3 モブプログラミングを実践してみよう!! 〜アジャイルモンスターのモブプロ入門〜　に参加した

先日（3/3）、表題のセミナー
https://devlove-kansai.doorkeeper.jp/events/70480
に参加してきたのでざっとまとめる。
及部さんのスライド
https://speakerdeck.com/takaking22/mobupuroguraminguwoyarou-aziyairumonsutafalsemobupuroru-men-number-koberb

### やったこと 
自販機プログラムの製作
言語：Python
開発環境：
　最初replt.it https://repl.it/ 
　すぐにcyber-dojo http://cyber-dojo.org/ にかえる
中間で 5人中2人 メンバ入替

###わかったこと
想像以上にハードワーク。50分で10分休憩くらいのペースでやるくらいじゃないとキツイ。
Web上のIDE環境が使えることがわかった。すぐに開発・テストができるので便利。
組み込み系ではまず環境を整えるので一苦労なので雲泥の差。

Python の言語仕様ははじめてだったけど、わかった気になった。
実のところ、コードを書いたのは hogehoge年だったのは内緒。
TDDでプログラミングをすすめたが、最後まとめの説明するのがとても楽だった。
この点はTDDの（隠れた）利点じゃないかなと再認識。

モブワークと役割分担ワークの違い
製造ラインっぽくいうと段取り替えが頻繁にかわるならモブ、
同じものをテンプレート的につくるなら役割分担の方がいいじゃないかと。
人から人への段取り替え（引継ぎ）や、作るものがころころ変わるならモブの方が賢い。

ペアプログラミングとの違い
モブワークだとメンバ全員が全体にかかわっている点。
ペアプログラミングだと、全体にかかわっていないので、別途結合テスト、基本設計・ポリシーレビューなど統合に必要な作業がどうしてもでてくる。

モブワークでの工夫：やったー！
やったー！は、ライブの盛り上げみたいなもの、テーマに集中するために（マインドフルネス状態になるために）役立ちそう。

###セミナーでのふりかえり写真
![agya.jpg](https://qiita-image-store.s3.amazonaws.com/0/242026/96cc8494-89e7-a2a1-4670-2e78e33b5ab9.jpeg)


###つぎやること
社内（組み込み開発環境）でやるには、こんな段取りかな。
1. 声かける。3～5人で１チーム、2チームは欲しい
2. ちょっと大きめ会議室確保、ディスプレイ チーム当たり1台。
3. 最初は2時間。どんなに欲張っても4時間か。
4. 資料目次
    1. モブプログラミングの簡単な説明、進め方
    2. お題　これは自販機でええか
    3. 開発環境指定　これは cyber-dojo がいいな
    4. 開発言語はお任せ
    5. 最初のターン 40min で到達する状態
    6. 人を入替
    7. 次のターン 40min で到達する状態
    8. ふりかえり　やったこと・わかったこと
       （ミリオタなので(^^;;;）AARっぽくやりたい　「何があったか」「みんなで何故そう決めたのか」「もっとよい決定をするには」
    9. ふりかえり　次やること　組み込みWebSystemでやるには相談
    10. まとめ

####謝辞
話し手の及部 敬雄さん、
スタッフの中村 洋さん、Akiさん、
TAM Coworkingさん、会場提供ありがとうございました！

###参考リンク
[TDD(テスト駆動開発)+モブプログラミングを社内でやってみた話](http://engineer.crowdworks.jp/entry/2018/04/06/190000)
systemdで環境変数を設定した際、起動後に（念の為）確認したい場合

## TL;DR

```sh
# リンク先例
tr '\0' '\n' < /proc/<pid-of-daemon>/environ

# pgrep利用（1プロセスのみ特定可能な場合）
tr '\0' '\n' < /proc/$(pgrep -f <process-name>)/environ

# systemctl show利用（複数プロセス起動するものでMainPIDが取得したい場合）
tr '\0' '\n' < /proc/$(systemctl show <unit-name> -p ExecMainPID | cut -d= -f2)/environ 
```

## 参考例発見

```sh
tr '\0' '\n' < /proc/<pid-of-daemon>/environ
```

[Bug 1193453 – "systemctl show" doesn't show environment variables defined when EnvironmentFile is used][link]

なかなか検索がヒットしなかった中、上記を発見。
つまり、起動後じゃないと見れないから確認するコマンド（systemctl xxx）はないみたい。
ちなみに`systemctl show-environment`はちょっと違う。

ちなみに`'\0'`はNull


## `pgrep`で少し楽に

毎回systemctl statusとかしてpid確認するのも面倒なので下記でも良さそう。

```sh
tr '\0' '\n' < /proc/$(pgrep -f <process-name>)/environ
```


## `pgrep`でpid複数になっちゃうような場合

複数プロセスあるよ、とかだったら下記かなと思うけど、長い。。。

```sh
tr '\0' '\n' < /proc/$(systemctl show <unit-name> -p ExecMainPID | cut -d= -f2)/environ 
```



[link]: https://bugzilla.redhat.com/show_bug.cgi?id=1193453
paramiko+scpで共有サーバにファイル転送する

※2018年3月8日追記
scpだとディレクトリが転送できないことがわかりましたので修正いたしました！

#経緯
python歴1ヶ月の初心者です。間違っていたらコメントで訂正をお願いいたします。

いつもはTeratermを使ってscpコマンドでファイルを共有サーバに転送していたけれど、これを自動的に行う必要がでてきたので、実装に至りました。

今回はpythonのライブラリであるparamikoを使いssh接続を行いscpでファイルを転送するところまでの実装です。
（今後はファイルを自動取得するスクリプトをマージして実装を行う予定です）
実装については以下の記事とGithubを参考に行いました。

『Paramiko + scp 導入 ~ SSH接続 ~ SCPでファイル転送』
https://qiita.com/int_main_void/items/1cdec761b745010629d5
『scp.py』
https://github.com/jbardin/scp.py
#環境
Python 3.6.4
Anaconda 4.3.34
paramiko 2.4.0 
(conda forgeでインストールすると2.3.1がインストールされました)
※with構文を使っているので、勝手にopen, closeの処理をしています。使わない場合は`scp.close()`をお忘れずに。

#やってみた
1. paramikoのインストール
anaconda上で`pip install paramiko`

2. ssh接続

```python:ssh-transport.py
import paramiko
with paramiko.SSHClient() as ssh:
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname='XXX.XXX.XXX.XXX', port=22, username='username', password='password')
```
たったこれだけでssh接続。teratermいちいち開いてられませんね。
※with構文を使っているので、勝手にopen, closeの処理をしています。使わない場合は`scp.close()`をお忘れずに。

3. scp client作成

```python:ssh-transport1.py
import scp
with scp.SCPclient(ssh.get_transport()) as scp:
        scp.put('filename', '/upload/to/remote/directory/')
        scp.get('/upload/to/remote/directory/')
```
scpもこれだけでOKみたいです。
4. マージ

```python:ssh-transport.py
import paramiko
import scp

with paramiko.SSHClient() as ssh:
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname='XXX.XXX.XXX.XX', port=22, username='username', password='password')
with scp.SCPclient(ssh.get_transport()) as scp:
        scp.put('filename', '/upload/to/remote/directory/')
        scp.get('/upload/to/remote/directory/')
```

これでファイル転送ができると思います。

#今後の発展
今回は純粋に「scpでファイル転送」なので、これだけ短いプログラムでしたが、現在書いている「別サーバからファイル自動取得するスクリプト」とをマージさせたいと思います。
Railsにおけるfrontvalidationの書き方

インターン先で学んだことのメモ書き

app/views/users/edit.html.slim

```edit.html.slim
= simple_form_for @user, html: {class: 'edit-user-form'} do |f|
 = f.input :email
 = f.button :submit, "Update", class: 'btn btn-primary'

javascript:
 Users.edit.init();
```

app/javascripts/application/users.coffee

```users.coffee
edit =
 els:
   form: ".edit-user-form:
   init: ->
    @validateForm()
　　　　　　validateForm: ->
     $(@els.form).required
```

formにvalidationをかけたいclass名を書く

```
javascript:
 Users.edit.init();
```
と書くことで、
Usersディレクトリ内のeditの中のinit();を探して走らせてくれる。
vimでcamelCaseな文字列をchain-caseに置換する

# まずは結論から

```text:置換対象のテキスト
longLongLongString
```

```vim:vim
:s/\v\C([a-z])([A-Z])/\1-\L\2/g
```

```text:置換後のテキスト
long-long-long-string
```

# vim特有のメタ文字について

```
\v -> very magic
```

素のvimの正規表現はPerl/Rubyなどの一般的な正規表現などとは異なり、正規表現のメタ文字をバックスラッシュでエスケープしなければなりません。
very magicモードにすると、メタ文字のエスケープが免除され、一般的な正規表現のように書ける。
(筆者はeregex.vim使う派)

```
\C -> case sensitive
```

ignorecaseしている場合でも大文字小文字を区別する。

```
\L -> lower case
```

マッチした文字列を小文字に変換
Mac暗号化起動ディスクを外付けHDDにコピーして起動

MacBookAirの内蔵SSDの空き容量が少なくなりアプリ開発環境の整備も困難になりました。

今は、新しいMacを買うことも出来ないので、外付けのハードディスクから起動できるようにしようと試みています。

ググってディスクユーティリティで、復元の方法でコビーする方法を知りました。

確かに起動することは、出来ます。
でも、ログインパスワードを入力しても、ログイン出来ないのです。

私のMacBookAirのキーボード壊れているので、USB接続のキーボード使っています。
キーボード対応していないのかとも思いました。
でも、パスワードが違うというメッセージも　出ません。

更にググったら、暗号化されているディスクを外付けHDDにコピーして起動する記事を見つけました。

Macのリカバリーアシスタントをダウンロードして起動しましたが、復元したいディスクが壊れているか起動できないという内容のエラーが出てしまい使うことができませんでした。
lionのバージョンの起動ディスクを作るツールです。
今の私のMacのOSのバージョンは、High Sierraです。
リカバリーアシスタントが対応していたのかなと、勝手に想像しています。

これまで試した結果、暗号化されている起動ディスクをコピーして外付けHDDから起動はでいないと思いました。

その為、今、暗号化を解除しています。
１日以上必要と出ましたので、終わるのを待っている状態です。
内蔵SSDは、120GBです。
暗号化解除に１日以上かかるので、暗号化は、慎重に検討した方が良いと思います。

外付けHDDにバックアップしたものに、暗号化されると良いと思います。

外付けHDDから起動できたら、新しく記事を投稿したいと思います。

2018/03/08追記します。
MacでAPFSでフォーマットされた暗号化ディスクをバックアップする際は、同じフォーマットようにAPFSでフォーマットしたパーテーションでないとバックアップできないようです。
しかも、recoveryのパーテーションも、必要です。
Bitbucket Pilelines/Deployments入門

# はじめに
Amazon S3とCloudFrontを使用してスタティックなWebコンテンツを配信・運用しているんですが、
「~~AWSのコンソールポチポチするのストレス~~更新時の運用を楽にしたいんじゃ！」というディレクターやデザイナーの要望に答えるためにBitbucket Pipelinesを使用して自動化してみました。
スタティックなファイルのデプロイなので、PipelinesとしてもDeploymentsとしても入門レベルの内容だと思います。

# 前提
+ S3+CloudFrontでコンテンツ配信できる環境が整っていること
+ BitBucketのGitリポジトリがあること

# 手順
## 1. IAMユーザの作成
Bitbucket Pipelinesがデプロイに使用するIAMユーザを作成します。
IAMには`S3のオブジェクトを更新するのに必要`な権限と、`CloudFrontのInvalidationリクエストができる`権限が必要です。
ポリシーそのものは適宜作成してください。

ユーザを作成したら、アクセスキーの生成をしてキーペアを取得してください。

## 2. BitBucketの設定
### 2.1 Pipelinesの有効化
リポジトリの左メニューより　`設定` > PIPELINES `Setting` > `Enable Pipelines`を有効にします。

### 2.2 環境変数の設定
リポジトリの左メニューより　`設定` > PIPELINES `Environment variables`に進み、以下の環境変数を定義します。

|Variable name|Value|Secured|
|---|---|---|
|AWS_ACCESS_KEY_ID|手順1で取得したACCESS_KEY_ID|:heavy_check_mark:|
|AWS_SECRET_ACCESS_KEY|手順1で取得したSECRET_ACCESS_KEY|:heavy_check_mark:|
|CONTENTS_BUCKET|デプロイ先のバケット名||
|DISTRIBUTION_ID|CloudFront distributionのID||

なんらかの理由でS3のバケットが変更になったり、CloudFrontのDistributionが変わったりした場合でもGitのコミットなしで変更できるようにキーペア以外も環境変数で定義してみました。

### 2.3 Pipelineの定義

以下のファイルをリポジトリ直下にコミットします。

```bitbucket-pipelines.yml
image: python:3.6.4

pipelines:
  branches:
    master:
      - step:
          name: Print Message
          caches:
            - pip
          script:
            - echo "Deploy process to production environment started"
      - step:
          name: Deploy to Production(push to S3 and cache invalidation)
          deployment: production
          trigger: manual
          caches:
            - pip
          script:
            # Install
            - pip install awscli
            # Push to S3
            - aws s3 sync . s3://${CONTENTS_BUCKET}
              --delete
              --exclude '.git/*'
              --exclude '.gitignore'
              --exclude 'README.md'
              --exclude 'bitbucket-pipelines.yml'
            # Requesting cache invalidation
            - aws cloudfront create-invalidation --distribution-id ${DISTRIBUTION_ID} --path '/*'
```

この内容の場合、リモートリポジトリ(Bitbucket)のmasterブランチにマージされるとPipelineが走り出します。
`trigger: manual`は最初の`step`には記述できないようなので、`echo`でメッセージを出力するだけのstepを記述し、2つめの`step`に処理を記載しています。

これでデプロイはPipelinesの画面からボタンを押すだけでできるようになり、また、Deploymentsの画面からどのコミットがデプロイされているのかを追えるようになるので便利です。
kotlin の khttp の使い方 (Post)

ソースのダウンロード方法はこちら
[kotlin の khttp の使い方 (Get)](https://qiita.com/ekzemplaro/items/d9369d2d7fac98bc01cb)

```kotlin:http_post.kt
// ------------------------------------------------------------------
/*
	http_post.kt

					Mar/04/2018
*/
// ------------------------------------------------------------------
import khttp.post

fun main(args: Array<out String>) {
	println("*** 開始 ***")

	val payload = mapOf("user" to "jiro", "password" to "123456")
	val url : String = "http://httpbin.org/post"
	val rr = post(url,data=payload)
	println(rr)
	println(rr.statusCode)
	println(rr.text)

	println("*** 終了 ***")
}

// ------------------------------------------------------------------
```

```text:Makefile
JAR=../../jar
ORG_JSON=$(JAR)/org.json.jar
http_post.jar: http_post.kt
	kotlinc -cp $(ORG_JSON) http_post.kt \
		khttp/KHttp.kt \
		khttp/responses/Response.kt \
		khttp/responses/GenericResponse.kt \
		khttp/requests/Request.kt \
		khttp/requests/GenericRequest.kt \
		khttp/structures/cookie/Cookie.kt \
		khttp/structures/cookie/CookieJar.kt \
		khttp/structures/files/FileLike.kt \
		khttp/structures/authorization/Authorization.kt \
		khttp/structures/parameters/Parameters.kt \
		khttp/structures/maps/CaseInsensitiveMap.kt \
		khttp/structures/maps/CaseInsensitiveMutableMap.kt \
		khttp/extensions/Extensions.kt \
		-include-runtime -d http_post.jar
clean:
	rm -rf http_post.jar
```

実行コマンド

```bash
java -jar http_post.jar
```
kotlin の khttp の使い方 (Get)

khttp のソースのダウンロード

```bash
git clone https://github.com/jkcclemens/khttp.git
```

org.json.jar のダウンロードはこちら
[Download org.json.jar](http://www.java2s.com/Code/Jar/o/Downloadorgjsonjar.htm)

```kotlin:http_get.kt
// ------------------------------------------------------------------
/*
	http_get.kt

					Mar/04/2018
*/
// ------------------------------------------------------------------
import khttp.get

fun main(args: Array<out String>) {
	println("*** 開始 ***")

	val url : String = "http://httpbin.org/get"
	val rr = get(url)
	println(rr)
	println(rr.statusCode)
	println(rr.text)

	println("*** 終了 ***")
}

// ------------------------------------------------------------------
```

```text:Makefile
JAR=../../jar
ORG_JSON=$(JAR)/org.json.jar
http_get.jar: http_get.kt
	kotlinc -cp $(ORG_JSON) http_get.kt \
		khttp/KHttp.kt \
		khttp/responses/Response.kt \
		khttp/responses/GenericResponse.kt \
		khttp/requests/Request.kt \
		khttp/requests/GenericRequest.kt \
		khttp/structures/cookie/Cookie.kt \
		khttp/structures/cookie/CookieJar.kt \
		khttp/structures/files/FileLike.kt \
		khttp/structures/authorization/Authorization.kt \
		khttp/structures/parameters/Parameters.kt \
		khttp/structures/maps/CaseInsensitiveMap.kt \
		khttp/structures/maps/CaseInsensitiveMutableMap.kt \
		khttp/extensions/Extensions.kt \
		-include-runtime -d http_get.jar
clean:
	rm -rf http_get.jar
```

実行コマンド

```bash
java -jar http_get.jar
```
Angularで作るER DIAGRAM TOOL - 第十一回　リレーションシップモーダルの作成と開く処理

まずは、前回、ModelのH2にエンドポイントを追加して、
コネクションを作成するようにしたのですが、
コネクションを作成せずに、モーダルを開くように変更します。



##（１）リレーションシップモーダルの作成

/src/app/modal-relation/modal-relation.component.ts
https://github.com/dog-ears/er-diagram-tool/commit/7295efacc56aa0c29f524bb4cffdddd817c591d3#diff-646411b438809058dd2679d246b8906b

・source_modelが接続元Model、target_modelが接続先Modelです。
・source_model_display_schema、target_model_display_schemaは、どのカラムの内容で表示するかです。

（例）
category has many booksの場合、
source_model_display_schemaにタイトルを選ぶと、カテゴリを選ぶ際にカテゴリタイトルをプルダウンで選べます。

one-to-manyの場合は、target_model_display_schemaは不要となります。

・relation_typeによって、dataService.addOneToManyRelation()または、dataService.addManyToManyRelation()（いずれも未実装）を呼び出します。



/src/app/modal-relation/modal-relation.component.html
https://github.com/dog-ears/er-diagram-tool/commit/7295efacc56aa0c29f524bb4cffdddd817c591d3#diff-01be9d6214e34da40775ab3244149f02



/src/app/service/data.service.ts
https://github.com/dog-ears/er-diagram-tool/commit/7295efacc56aa0c29f524bb4cffdddd817c591d3#diff-ae990bb302f27e60323deb45d6746b17

・とりあえず、addOneToManyRelation()、addManyToManyRelation()を空実装しておく



/src/app/app.module.ts
https://github.com/dog-ears/er-diagram-tool/commit/7295efacc56aa0c29f524bb4cffdddd817c591d3#diff-fc6b22833aeaf77f8440c4970ade705e

・ModalRelationComponentのimportおよび登録



##（２）Model - H2 エンドポイントのドロップ後の処理を変更

まずは、コネクション作成部分をモーダル呼出しに修正します。

/src/app/service/jsPlumb.service.ts
https://github.com/dog-ears/er-diagram-tool/commit/8600c7eea9846a3dcb940fd049814789ce8d09f3#diff-da7afb11f9169e78d9b5cfea7afcc510

・BsModalService、BsModalRef、ModalRelationComponentのimport。
・BsModalServiceのDI
・メンバ変数BsModalRefの追加
・addEndpointにオプション追加

beforeDrop: (params)=> {} --- エンドポイントをドロップした直後に発生。このタイミングでモーダルを開き、
return falseすることにより、その後の処理（コネクションの作成）をキャンセルします。

・モーダルに渡すデータは、SourceModelとTargetModel。beforeDropのparamから、SourceModelエレメントと、TargetModelエレメントのIDを取得できるので、
エレメントのID名からモデルを取得する機能を、dataクラスに実装します。



/src/app/class/data.ts
https://github.com/dog-ears/er-diagram-tool/commit/8600c7eea9846a3dcb940fd049814789ce8d09f3#diff-ba726bfa70586322bd593dddb7beaf87

・getModelByElementH2Id()を実装



これで、model-h2のendPointをドラッグ・ドロップすることで、リレーションモーダルが開くようになりました。
※リレーションモーダルから先はまだ未実装。



リレーションモーダルの先を実装する前に、一つ残っているバグがあります。
モデルを削除したとき、endPointが残り続けます。

![cap11.jpg](https://qiita-image-store.s3.amazonaws.com/0/103767/a55bad39-e95b-3884-1e66-ce37c6b7d9e4.jpeg)



##（３）Model削除時に、そのModelについていたendPointを削除する機能を実装

/src/app/model/model.component.ts
https://github.com/dog-ears/er-diagram-tool/commit/c7b772c2ec27c703829e99463e28028ab5118d44#diff-14ac3c6b037418c538e10e3c5571bbbe

・削除時（ngOnDestroy()）にjsPlumbService.destroyModel()（未実装）を実行


/src/app/service/jsPlumb.service.ts
https://github.com/dog-ears/er-diagram-tool/commit/c7b772c2ec27c703829e99463e28028ab5118d44#diff-da7afb11f9169e78d9b5cfea7afcc510

・destroyModel()を実装



これで、モデル削除時に自動でendPointが削除されるようになりました。

次回は、one-to-manyのリレーション作成を実装していこうと思います。
3DES-CBCの復号（Padding なし)

##前提
- PHP7
- 送信側はShift-JIS、受信側はUTF-8
- 送信側は下記の流れで暗号化して送信してくる。(某決済代行サイト)　
    1. 3DES-CBC（Padding なし）にエンコード
    1. BASE64にエンコード
    1. 送信！！！ 

##コード
```php:decode.php
public function do($str){
        $iv = '初期化ベクトル';
        $password = '秘密キー';
        $method = 'des-ede3-cbc'; //3DES-CBCの設定(DES-CBCの場合、des-cbc)
        $decodeTarget = base64_decode($str)
        $result =  openssl_decrypt(
                           $decodeTarget, //①
                           $method,　　　　　　　　　　　　　　//②
                           $password,     //③
                           OPENSSL_NO_PADDING, //④
                           $iv //⑤
                           );

   return mb_convert_encoding($result, 'UTF-8','Shift_JIS');
//TRIMするならtrim($result)
}
```
###解説
```php:
        openssl_decrypt(
                '①:復号対象',
                '②:暗号メソッド',
                '③:秘密キー',
                '④:オプション',
                '⑤:初期化ベクトル'
                );
```
[phpマニュアル：openssl_decrypt](http://php.net/manual/ja/function.openssl-decrypt.php)
「②:暗号メソッド」：openssl_get_cipher_methods()にて利用できるメソッドは確認可能[^1]
「④:オプション」：マニュアルには下記の様に書かれており、 
OPENSSL_RAW_DATA：行データ、
OPENSSL_ZERO_PADDING：Paddingなし
という認識。(0も指定可能みたい[^2])

>OPENSSL_RAW_DATA あるいは OPENSSL_ZERO_PADDING のいずれか。

##雑記
mcryptで書かれているコードは見つけたが、PHP7では非推奨のため使えない。(PHP7.2より前なら使用可能[^3])
ということで、opensslでと探したが無くて苦労しました；；

記載内容に間違いがあれば、ご指摘いただけると幸いです。


---

[^1]: [phpマニュアル：openssl_get_cipher_methods](http://php.net/manual/ja/function.openssl-get-cipher-methods.php)
[^2]: [phpマニュアル：「User Contributed Notes」 Hernanibus氏](http://php.net/manual/ja/function.openssl-decrypt.php#119577)
[^3]: [phpマニュアル：mcrypt_decrypt](http://php.net/manual/ja/function.mcrypt-decrypt.php)
AWS SQS Get/Put コンポーネントを使ってみて

#AWS SQSPutコンポーネントの特徴
AWSの[Amazon Simple Queue Service (SQS)](https://aws.amazon.com/jp/sqs/)へメッセージを保存するコンポーネントで、指定するのはメッセージを入れるキュー（URL）のみ。
メッセージは入力ストリームが使用されて、入力ストリームをBase64エンコードしたものになる。

#AWS SQSGetコンポーネントの特徴
AWS SQSPutコンポーネントが保存したメッセージを[SQS](https://aws.amazon.com/jp/sqs/)から取得するコンポーネント。
[SQS](https://aws.amazon.com/jp/sqs/)から見て１回も受信されたことのない未読のメッセージのみを取得することができる。
取得したメッセージは他（別サーバーで動作しているASTERIA WARPのフローなど）が取得できない期間を秒で指定できる（可視性タイムアウト値を指定できる）。
取得したメッセージをフローで正常に処理した後に削除することができる。

#使ってみる
- まず、メッセージをキューへ保存する。

テキストストリームの値をキューへ保存してみる。

![flow1.PNG](https://qiita-image-store.s3.amazonaws.com/0/180278/b619f3e1-8d81-5575-b88f-df4bfb8001f6.png)

コネクションが設定されたAWS SQS Get/Putコンポーネントをダブルクリックするとキューのリストから使用するキューを選択することができます。

![dialog.png](https://qiita-image-store.s3.amazonaws.com/0/180278/860aa3b8-56f1-2b27-b62b-b38c87a4c860.png)

特に考えることなく[SQS](https://aws.amazon.com/jp/sqs/)のキューへメッセージを保存することができました。

![base64.PNG](https://qiita-image-store.s3.amazonaws.com/0/180278/e078bd7e-d921-a448-8e95-23b627a302fc.png)


- メッセージを取得してみる。

Startコンポーネントでフローをトランザクション化しています。

![flow2.PNG](https://qiita-image-store.s3.amazonaws.com/0/180278/7657610c-fb6d-a384-a7cd-8c9bc64b4df2.png)

[SQS](https://aws.amazon.com/jp/sqs/)から取得したメッセージは、６０秒以内にサブフローが処理をする予定にしています。
（プロパティ：メッセージ可視タイムアウト（秒）へ「60」を設定）

正常に処理が終了した場合、取得したメッセージは[SQS](https://aws.amazon.com/jp/sqs/)から削除されますが、サブフローでの処理でExceptionが発生した場合は[SQS](https://aws.amazon.com/jp/sqs/)のメッセージを削除せずに６０秒後に他のフローが処理できるようにしています。
（プロパティ：コミット時の処理へ「メッセージを削除」を設定）

![prop.PNG](https://qiita-image-store.s3.amazonaws.com/0/180278/650bf413-1d55-4cf9-bd0f-67ddc662cd0c.png)

キューからのメッセージ取得も簡単にできました。

#気になる点
- Base64

AWS SQS Putコンポーネントがメッセージをキューへ保存するとメッセージはBase64されているので、AWSのコンソールで表示されるメッセージの詳細もBase64のままで内容は一見わからない。

AWS SQS Putコンポーネントが保存したメッセージはAWS SQS Getコンポーネントが取得するならばよいが、他のシステムが取得する場合を考えると使いづらい。

Base64されていないメッセージをAWS SQS Getコンポーネントで取得すると「java.lang.NullPointerException」が発生する場合があるようです。これはバグとして報告しておきます。このバグが修正されればキューへ「デッドレターキュー設定」を行うことで、間違って他のシステムがメッセージを保存しても処理を継続することが可能になります。

- メッセージ属性未対応

[メッセージ属性](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-attributes.html)をコンポーネントのカテゴリープロパティなどで設定できれば速度と効率を向上できそうです。
何かのメモ

kvm上からVirsh listで表示されるインスタンス全てのdumpxmlを表示したいとき。

以下は名前とTAP情報を出してます。（雑ですが。）

```
virsh list  | grep instance | awk '{print $1;}' | xargs -L1 virsh dumpxml | egrep 'nova:name|tap'

```

egrep 'hogehoge'のところで、必要なところをピックアップすれば、舐めることができる。
エンコードについてわかったこと

この前、Windows-31Jからutf-8にエンコードして渡そうとしたんだけど
Windows-31J内でutf-8にエンコードすると
文字の幾つかが「�」みたいになってしまった。

これはつまり文字をエンコードするのは受け取り側で対応しよう。ってことだと思う！
Windows-31J内でutf-8にエンコードすると
utf-8化した文字がWindows-31J内で表示できなくて、
文字が壊れてしまうってことだと理解した。

まぁ、そことに気がつくまでにエンコーダーを幾つか試した際に、
Windows-31Jをutf-8にエンコードできるライブラリーが少ない事が発覚した。
Windows-31Jだけでなく、より多くの文字コードをエンコードしたい場合は
下記のライブラリーが良いかもしれない。
https://github.com/inexorabletash/text-encoding
minikubeとdocker for macの共存

minikubeとdocker for macを
同時に使う場合は
環境変数によって、docker imageの向き先が変わる。



## Docker環境変数確認

環境変数が出ている場合はminikube

```
$ env | grep DOCKER
DOCKER_TLS_VERIFY=1
DOCKER_HOST=tcp://192.168.0.1
DOCKER_CERT_PATH=/Users/user_name/.minikube/certs
DOCKER_API_VERSION=1.23
```

ない場合は docker for mac

```
$ env | grep DOCKER

```



## docker for mac に切り替える


環境変数を削除すればい。

```
unset DOCKER_TLS_VERIFY
unset DOCKER_HOST
unset DOCKER_CERT_PATH
unset DOCKER_API_VERSION
```

https://docs.docker.com/docker-for-mac/docker-toolbox/#setting-up-to-run-docker-for-mac

## minikubeに切り替える。


```
eval $(minikube docker-env)
```
STM32のタイマー 機能比較

比較的安価に購入できる STM32 ボード。cortex-M が載ってます。

タイマーが多数内蔵されていますけど、機能のバリエーションがあります。
どれを使えばいいんじゃい！どう違うんじゃい！　と言うのを自分のためにまとめました。
データシート（reference manual)の章の頭を持ってきました。細部には差があるのかもしれません。

もしかして、公式に機能比較があったりする？
STM32F303 から持ってきましたが、TIMx の x を気にすればいいようです。
（日本語が不自由ですみません。　例：STM32F103 の TIM2 は 303 の TIM2 と（ほぼ？）同じ。）

| TIMx → |(ソート用)| 1 | 8 | 20 | 2 | 3 | 4 | 6 | 7 | 15 | 16 | 17 | note |
|-----|------|---|---|----|---|---|---|---|---|---|---|---|---|
|↓機能|0|adv|adv|adv|gen|gen|gen|bas|bas|gen|gen|gen| adv :advanced-control, bas:basic, gen:general-purpose|
|• 16-bit up, down, up/down auto-reload counter.|1|v|v|v|v3|v|v||||||v3: 32bit support|
|• 16-bit auto-reload upcounter|1.2|||||||v|v|v|v|v||
|• 16-bit programmable prescaler allowing dividing (also “on the fly”) the counter clock frequency either by any factor between 1 and 65536.|2|v|v|v|v|v|v|v|v|v|v|v||
|Up to N independent channels for:|3|6|6|6|4|4|4|||2|2|2||
|– Input Capture (but channels 5 and 6)|3.1|v|v|v|v|v|v|||v|v|v||
|– Output Compare|3.2|v|v|v|v|v|v|||v|v|v||
|– PWM generation (Edge and Center-aligned Mode)|3.3|v|v|v|v|v|v|||v|v2|v2|v2: not support for center- mode|
|– One-pulse mode output|3.4|v|v|v|v|v|v|||v|v|v||
|• Complementary outputs with programmable dead-time|8|v|v|v||||||v1|v|v|v1:for ch1 only|
|• Synchronization circuit to control the timer with external signals and to interconnect several timers together.|9|v|v|v||||||v||||
|• Synchronization circuit to control the timer with external signals and to interconnect several timers.|10||||v|v|v|||||||
|• Repetition counter to update the timer registers only after a given number of cycles of the counter|11|v|v|v||||||v|v|v||
|• 2 break inputs to put the timer’s output signals in a safe user selectable configuration.|14|v|v|v||||||||||
|• Interrupt/DMA generation on the following events:|15|v|v|v||||||v||||
|– Update: counter overflow/underflow, counter initialization (by software or internal/external trigger)|15.1|v|v|v|v|v|v|||v||||
|– Update: counter overflow|15.11|v|v|v|v|v|v|v|v|v|v|v||
|– Trigger event (counter start, stop, initialization or count by internal/external trigger)|15.2|v|v|v|v|v|v|||v|v|v||
|– Input capture|15.3|v|v|v|v|v|v|||v|v|v||
|– Output compare|15.4|v|v|v|v|v|v|||v|v|v||
|– Break input (interrupt request)|15.5|||||||||v||||
|– Break input|15.7||||||||||v|v||
|• Supports incremental (quadrature) encoder and Hall-sensor circuitry for positioning purposes|21|v|v|v|v|v|v|||||||
|• Trigger input for external clock or cycle-by-cycle current management|22|v|v|v|v|v|v|||||||
|• Break input to put the timer’s output signals in the reset state or a known state|37|||||||||v|v|v||
|• Synchronization circuit to trigger the DAC|66|||||||v|v|||||

あ、公式に似たのがありました　→　AN4013 (http://www.st.com/content/st_com/en/search.html#q=AN4013-t=resources-page=1)
Node-RED Alexa Home Skill Bridge のデバイス検出設定でハマった件

#経緯
※3/6追記
どうやらサービス自体が実行した当時不通だった模様。
同環境で正常にデバイス検出できたことを確認済。
また困ったときに見る備忘録のような感じで残しておきます。

僕がNode-RED Alexa Home Skill Bridgeの設定をする中で思わぬところにハマってしまったが
参考にさせていただいたサイト等でハマりそうな様子が**全く**見受けられないため
僕しかハマらないだろうメモで申し訳ないですが記述しておく。

#参考サイト

http://dolls.orz.hm/?p=13447
https://www.masamedia.top/archives/3377.html


#改めて手順
１．[Node-RED Alexa Home Skill Bridge](https://alexa-node-red.bm.hardill.me.uk/)にアクセスしてログイン
　　アカウントなければRegisterで作成


<img width="500" alt="2018-03-06_232600.png" src="https://qiita-image-store.s3.amazonaws.com/0/242059/1f367283-aeb8-d05a-084c-2e8d01503999.png">




２．Devicesタブでデバイスを登録する。
<img width=500" alt="2018-03-06_232747.png" src="https://qiita-image-store.s3.amazonaws.com/0/242059/58ff28ba-d67d-253f-78e9-917eea14b977.png">





３．AlexaアプリでNode Redスキルを有効にする。

<img width="500" alt="2018-03-06_232942.png" src="https://qiita-image-store.s3.amazonaws.com/0/242059/bf580ce4-c1c4-425a-29cf-66f53ff40da2.png">



４．認証が求められるので、１でアクセスしてログインしたアカウントで認証する。
<img width="500" alt="2018-03-06_233135.png" src="https://qiita-image-store.s3.amazonaws.com/0/242059/27f6043c-5b22-57de-62b6-36c90bcc3829.png">



５．デバイスが探され、２で登録したデバイスが見える。
<img width="500" alt="2018-03-06_233354.png" src="https://qiita-image-store.s3.amazonaws.com/0/242059/151c04f3-fcf9-05b8-eca3-4a82460d121c.png">




**・・・はずなのだが、
何回繰り返しても２で設定したデバイスが見えない現象が発生した。**

#現象環境
自宅Wi-fi環境に接続している

・PC
・iphoneX
・ラズパイ
・Amazon Echo

PCかiphoneXでAlexaアプリに同Wi-fiで接続してみてデバイスを探すを試みても検出しない。

#結果どうしたか
何回も試行して疲れ果てて外に出て
**家のWi-fiから離れて4G環境のiphoneXでデバイスを探すを試した**結果、
なんと一発でデバイスを検知した。
どうやら同じネットワーク？がマズかったらしい？
~~こんなん気づくかボケ~~

#まとめ
**デバイスの検出はiphoneXの4G環境でやろう、僕！！（極論）**

ネットワーク設定等を見直して、ダメなら別ネットワークから攻めるというやり方です、ハイ
gistにfetchで書き込む

### headerのAuthorization部を変えれば、basicとoauth token を切り替えられる。

```js
  ...
  ,auth ="Basic " + btoa(u+":"+p)
  //,auth ="token a04f631c476b4b54e131XXXXXXXXXXXXXXXXXXX"
  ;//get token is https://github.com/settings/tokens
```
### fetchの基本型
catchは復旧してresolveに戻さない限り呼び出し側が実装する。

```js
 let url=...
 ,option={method:'POST',mode:'cors',headers:{...}/*,body:{...}*/ }
 ;//method: 'HEAD' 'POST' 'PATCH' 'DELETE' 'GET' //mode: 'cors' 'no-cors'
 return fetch(url,option).then(res=>res.text()) /*|res.json()|res.ok...*/ 
```

### 新規でgistを作ってアップロードする。
```js
let up=(str)=>{
  if(str.length==0) return Promise.reject('data is 0')
  ;
  let u =window.prompt('u?'),p=window.prompt('p?')
  if(!u || !p ) return Promise.reject('cancel')
  ;
  let filename = str.slice(0,20),content=str,desc =new Date().toISOString()
  ,auth ="Basic " + btoa(u+":"+p)
  //,auth ="token a04f631c476b4b54e131XXXXXXXXXXXXXXXXXXX"
  ;//get token is https://github.com/settings/tokens
  return fetch("https://api.github.com/gists",{
    method:"POST"
    ,mode:"cors"
    ,headers:{
      "Authorization":auth
      ,'Accept': 'application/json'
      ,'Content-Type': 'application/json'
    }
    ,body:JSON.stringify({
      public: false
      ,description: desc
      ,files:{
        [filename]:{content: content}
      }
    })
  })
  ;
  ;//
}
```

### 最小のuiで
```html
<button onclick="upgist()">upgist</button><br>
<textarea></textarea><br>
<pre></pre>
```
```js
function upgist(){
  const data=fn.q('textarea').value
  ,show =(d=>{fn.q('pre').textContent = JSON.stringify(d,null,2);return d})
  Promise.resolve(data)
    .then(up)
    .then(fn.log)
    .then(res=>res.json())
    .then(show)
    .catch(show)
  ;
}
```

### 全部
```html
<button onclick="upgist()">upgist</button><br>
<textarea></textarea><br>
<pre></pre>
```
```js
let fn={}
fn.q =(d=>document.querySelector(d))
fn.log=(d)=>{console.log(d);return d}
;
let up=(str)=>{
  if(str.length==0) return Promise.reject('data is 0')
  ;
  let u =window.prompt('u?'),p=window.prompt('p?')
  if(!u || !p ) return Promise.reject('cancel')
  ;
  let filename = str.slice(0,20),content=str,desc =new Date().toISOString()
  ,auth ="Basic " + btoa(u+":"+p)
  //,auth ="token a04f631c476b4b54e131XXXXXXXXXXXXXXXXXXX"
  ;//get token is https://github.com/settings/tokens
  return fetch("https://api.github.com/gists",{
    method:"POST"
    ,mode:"cors"
    ,headers:{
      "Authorization":auth
      ,'Accept': 'application/json'
      ,'Content-Type': 'application/json'
    }
    ,body:JSON.stringify({
      public: false
      ,description: desc
      ,files:{
        [filename]:{content: content}
      }
    })
  })
  ;
  ;//
}
;
function upgist(){
  const data=fn.q('textarea').value
  ,show =(d=>{fn.q('pre').textContent = JSON.stringify(d,null,2);return d})
  Promise.resolve(data)
    .then(up)
    .then(fn.log)
    .then(res=>res.json())
    .then(show)
    .catch(show)
  ;
}

```
OmiseGo SDKのコンポーネント

# OmiseGo SDKのコンポーネント

下記を参考。
https://github.com/omisego/ewallet/blob/develop/docs/design/components.md

eWalletは、Elixirアプリケーションで下記のサブアプリケーションを含んでいる。

- **ewallet_api**: HTTP-RPCエンドポイントを通してWWWにつながるゲートウェイ。
 これらのエンドポイントは、eWalletとやりとりするために使われる。Swagger仕様書に詳細が書かれている。
 
- **admin_api** : HTTP-RPCエンドポイントを通してWWWにつながるゲートウェイ。システムを管理するために使われる。Swagger仕様書に詳細が書かれている。

- **ewallet**: (鋳造プロセス、価値の移動、など)のビジネスロジックを含むサブアプリケーション

- **ewallet_db**: すべてのデータベースのスキーマとマイグレーションを含むサブアプリケーション

- **local_ledger**: ビジネスロジックを含むサブアプリケーション

- **local_ledger_db**: すべてのデータベースのスキーマとマイグレーションを含むサブアプリケーション

- **url_dispatcher**: HTTPリクエストを適切なサブアプリケーションに割り振るサブアプリケーション

## 計画されているサブアプリケーション

- **admin_panel**: eWalletを管理するためのReactフロントエンド

- **request_logger**:eWalletをデバッグできるログシステム

- **blockchain_gateway**: Blockchainへのインターフェイス