OmniAICreator/Qiita-1.07M huggingface dataset:
x10からC++の関数を呼び文字列の配列を引数として渡す方法


[x10からC++の関数を呼ぶ](http://qiita.com/yohm/items/e21c59d9c08443286d37) にある方法でC++の関数を呼ぶことができる。
ただし、ここに記載されているのは引数が以下の３通りについてのみ。

- プリミティブ型(Long, Doubleなど)
- プリミティブ型の配列
- 文字列

ここでは「文字列の配列」を引数とするC++の関数をどのように呼べばよいかを説明する。

# コード

まずコードを示す。

```scala:rail_string.x10
import x10.io.Console;
import x10.compiler.Native;
import x10.compiler.NativeCPPInclude;
import x10.compiler.NativeCPPCompilationUnit;


@NativeCPPInclude("MyCpp.hpp")
@NativeCPPCompilationUnit("MyCpp.cpp")

class Main {

  public static def main( args: Rail[String] ) {
    nativeFunc( args );
  }

  @Native("c++", "nativeFunc( #1 )")
  native static def nativeFunc( argv: Rail[String] ): void;
}
```

```cpp:MyCpp.hpp
#include <x10/lang/Rail.h>
#include <x10/lang/String.h>

void nativeFunc( x10::lang::Rail<x10::lang::String*>* argv );
```

```cpp:MyCpp.cpp
#include <x10/lang/Rail.h>
#include <x10/lang/String.h>

void nativeFunc( x10::lang::Rail<x10::lang::String*>* argv ) {
  
  for( size_t i=0; i < argv->FMGL(size); i++ ) {
    x10::lang::String* x10_str = argv->raw[i];
    std::cerr << x10_str->c_str() << std::endl;
  }
}
```

以上のコードを同じディレクトリに配置し、`x10c++ -d build rail_string.x10` でコンパイルすればよい。
例えば、`./build/a.out foo bar`というコマンドを実行すると、`foo\nbar`と出力される。

# 解説

通常のC++関数呼び出しと同じように `@Native`を付与した関数を呼ぶ。

```
  @Native("c++", "nativeFunc( #1 )")
  native static def nativeFunc( argv: Rail[String] ): void;
```

C++の関数が呼ばれるが、プリミティブ型ではないクラスを引数に渡した場合、それらに対応するx10オブジェクトのポインタが渡される。

具体的には、`Rail[String]`を引数として渡すと、C++側での型は `x10::lang::Rail<x10::lang::String*>*` となる。

ちなみにRail,StringのC++のクラス定義は以下のファイルを見ればよい。
https://github.com/x10-lang/x10/blob/master/x10.runtime/src-cpp/x10/lang/Rail.h
https://github.com/x10-lang/x10/blob/master/x10.runtime/src-cpp/x10/lang/String.h

あとはC++側でこれらのオブジェクトを操作していく。

`x10::lang::Rail`クラスの主要なメソッドは以下の通り

- `argv->FMGL(size)`: size属性を取得する
    - FMGLというのはマクロ。Railに限らずx10の属性にアクセスする時には `FMGL(属性名)` という操作を行えばアクセスできる。
- `raw`: 配列の実体
    - 例えば `argv->raw[0]` とすると、最初の要素にアクセスできる。

`x10::lang::String` クラスの主要なメソッドは以下の通り

- `c_str()`: 文字列のポインタ (const char*) を返す。c++の`std::string#c_str()`と同じ。

これらを使うと文字列の配列を操作して、一般的なC++の文字列の配列にすることができる。

MyCpp.cppで実装をC++で定義する際に

```cpp
#include <x10/lang/Rail.h>
#include <x10/lang/String.h>
```

を忘れるとエラーになる。
ちなみに`x10c++`コマンドでコンパイルすると、`x10/lang`までのパスがincludeパスに含まれるので、自分で明示的にこれらのパスを指定する必要はない。

またこれを応用すれば、x10の標準ライブラリに含まれる別のクラスについても同じようにC++の関数に渡すことができるだろう。
iosの証明書の更新のハマりどころ

#証明書が切れると発生すること

iosの証明書の有効期限は下記のリンクより参照できます。
作成後から1年後に有効期限が切れます
https://developer.apple.com/account/ios/certificate/

・iOSの次回申請ができない
・プッシュ通知が送られなくなる

などの弊害が発生します。
なので、更新は１年に１回発生します。

##実際にやること

実際には新しく証明書を作り直します
こちらのサイトが参考になります
https://i-app-tec.com/ios/apply-application.html

流れとしては、
自分のPCで証明書を作る　> 開発用なら「iOS App Development」製品用なら「App Store and Ad Hoc」を指定します。


### ハマりどころ１（プッシュの設定）
プッシュがある場合、こちらでうまくいきましたが、上記のところで「Apple Push Notification service SSL 」でも良いかもしれませんが、私の場合、 左ペインのIdentifiers > App IDs から対象のNameを選択し、

こちらのPush通知を有効にしてあげることによって、「CertificateSigningRequest.certSigningRequest」を作成し、SSL Certificateに設定します
![スクリーンショット 2017-08-28 14.47.47.png](https://qiita-image-store.s3.amazonaws.com/0/87607/44f445bc-2af0-5be1-b7e7-687bfca65573.png)

また、awsのsns(simple notification service)を使用している場合、こちら側の
設定も証明書の更新が必要になります。
※こんなような更新画面です
<img width="891" alt="スクリーンショット 2017-08-28 15.04.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/87607/bd2fe759-7928-1004-0be1-1b6ddacf31e9.png">


### ハマりどころ２（プロビジョニングファイルの更新
左ペインより、「Provisioning Profiles > ALL」を選択するとこちらも　有効期限切れもしくは、有効ではないと出てくると思います。こちらで先ほど作った証明書を再度選び直してください

### ハマりどころ3（Xcode側の設定
こちらもプロビジョニングファイルが更新しないと、次回以降申請が出せなくなるので更新します。
こちらも有効期限切れ、もしくは、有効ではない状態になっていると思います。
ただし、正しくできていると、ios developerのサイトと勝手に同期されて、プロビジョニングファイルも更新されています。
ハマりどころとして、エラーが消えない場合があります。この場合、一度古いプロビジョニングファイルを削除してしまいましょう(Macであれば、下記に格納されていると思います)、xcodeを開きなおすと、サーバと同期され最新のみ自動で取り込まれます。

```
~/Library/MobileDevice/Provisioning Profile
```

### ハマりどころ4（開発者への配布
証明書を更新することによって、他に開発者がいる場合は、開発できなくなってしまいます。
なので、p12ファイルを配布する必要があります。

こちらのサイトが参考になります
http://mmorley.hatenablog.com/entry/2015/09/07/131745
割と消すWordPressのheadたち

```php
    remove_action('wp_head', 'print_emoji_detection_script', 7);
    remove_action('wp_print_styles', 'print_emoji_styles');
    remove_action('wp_head', 'rsd_link');
    remove_action('wp_head', 'wlwmanifest_link');
    remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 ); //前後の記事リンク
    remove_action( 'wp_head', 'wp_shortlink_wp_head', 10, 0 ); //ショートリンク
    remove_action('wp_head', 'wp_generator');
    add_filter( 'emoji_svg_url', '__return_false' );
    remove_action('wp_head','rest_output_link_wp_head');
    remove_action('wp_head','wp_oembed_add_discovery_links');
    remove_action('wp_head','wp_oembed_add_host_js');
    remove_action('template_redirect', 'rest_output_link_header', 11 );
```
MacのターミナルでEC2にSSHでログインする

基本コンソール内でしか作業は行わないのですが、SSHで接続することがあったので備忘録として記事をまとめます。

#キーペアの作成

まずEC2のインスタンス作成時、キーペアの作成をします。
事前に作成している既存のものを使う場合は、既存のキーペアを選択します。
注意しなければならないのは、このキーペアは紛失すると再発行ができません。
ログインできなくなります！
大切に保管しましょう！！

![キーペアの作成.png](https://qiita-image-store.s3.amazonaws.com/0/174392/a33869b7-234a-509c-d2ef-08c19c9c72fa.png)

#SSHログインに必要なIPの確認

![EC2ログイン.png](https://qiita-image-store.s3.amazonaws.com/0/174392/d605543a-5f48-0e5e-4ece-44094a80eefe.png)

#キーペアの配置

EC2作成時に作成したキーペア(XXX.pem)をダウンロードし、~/.ssh/keysにコピーします。

```
cp コピー元　コピー先
xxxnoMacBook-Air:keys xxx$ cp ~/Desktop/xxx-20170816.pem ./
```

次は権限の設定です。

```
権限は600に設定します。
xxxnoMacBook-Air:keys xxx$ chmod 600 ~/.ssh/keys/xxx-20170816.pem

※設定変更前は644だったのですが、SSHの場合は権限がありすぎる、というかオープンすぎるのも良くないようです。
```

これで事前準備は完了です。

#早速EC2にSSHログイン

```
ssh [ユーザー]@[IP] -i [キーファイルの指定]

xxxnoMacBook-Air:keys xxx$ ssh ec2-user@xx.xx.xx.xx -i  ~/.ssh/keys/xxx-20170816.pem

       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|\___|___|

```
無事ログイン成功です！！

EC2・amazonLinuxの初期ユーザ名は[ec2-user]になっています。

▼以下参考
Amazon Linux　→　[ec2-user]
RHEL　→　[ec2-user] or [root]
Ubuntu →　[ubuntu] or [root]
Centos →　[centos]
Fedora　→　[ec2-user]
SUSE　→　[ec2-user] or [root] 


#おわりに
何と言っても一番大事なことは、キーペアを絶対に無くさないことです！！
無くしてしまうとインスタンスとキーペア合わせて作り直しです。。。。＞＜
password_hash()とpassword_verify()を用いた暗号化と認証の方法について

PHPでログインフォーム付きのWebアプリを開発されている方は多いと思います。
ユーザ情報を管理する際にパスワードを平文で管理しているとセキュリティ上、好ましくないため暗号化しておくべきですが、暗号化の方法は様々です。
[PHPの公式ドキュメント](http://php.net/manual/ja/faq.passwords.php)によれば、`SHA1`や`MD5`による暗号化は不適切であり、最近では`crypt()`や`password_hash()`を用いて暗号化することが好ましいとされています。

`password_hash()`と`password_verify()`を組み合わせればお手軽に暗号化と認証の仕組みを実装できます。

`password_hash()`と`password_verify()`の使い方については様々な解説がありましたが、ユーザアカウント作成時にパスワードを暗号化する手順と、ログイン時にユーザ情報を認証する手順が、流れとして紹介されているものが少ない印象だったため、DBへの情報追加などの一連の手順を踏まえて記述したいと思います。

##ユーザ情報の登録画面

```index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ユーザ情報の登録画面</title>
</head>
<body>

<p>ユーザ情報</p>
<form action="create_user_info.php" method="post">
ID:<input type="text" name="id"><br>
PASS:<input type="text" name="pass">
<input type="submit" value="送信">
</form>

</body>
</html>
```

##ユーザ情報の登録（パスワードの暗号化）
```create_user_info.php
<?php

//パスワードの暗号化
$hash_pass = password_hash($_POST['pass'], PASSWORD_DEFAULT);

// 接続するデータベースの情報
$dsn = 'pgsql:dbname=dbname host=localhost port=5432';
$user = 'user';
$password = 'password';

try {
    // データベースへの接続開始
    $dbh = new PDO($dsn, $user, $password);
    
    // bindParamを利用したSQL文の実行
    $sql = 'INSERT INTO table_name (id, pass) VALUES(:id, :pass);';
    $sth = $dbh->prepare($sql);
    $sth->bindParam(':id', $_POST['id']);
    $sth->bindParam(':pass', $hash_pass);
    $sth->execute();
    
    // データベースへの接続に失敗した場合
} catch (PDOException $e) {
    print('接続失敗:' . $e->getMessage());
    die();
}

?>
```
平文のパスワードを暗号化している`password_hash($_POST['pass'], PASSWORD_DEFAULT);`の箇所ですが、**第一引数には暗号化したい文字列を指定、第二引数ではハッシュアルゴリズムを指定**します。
第二引数として、**PASSWORD_DEFAULT**を設定しておけば、インストールしているPHPのバージョンにおいて最も適切なハッシュアルゴリズムがデフォルトで設定されるようです。

詳しくはPHPの公式ドキュメントの[定義済み定数](http://php.net/manual/ja/password.constants.php)をご確認ください。

##ログイン画面
```pass_check.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ログイン画面</title>
</head>
<body>

<form action="pass_check.php" method="post">
ID:<input type="text" name="id"><br>
PASS:<input type="text" name="pass">
<input type="submit" value="ログイン">
</form>

</body>
</html>
```

##ユーザ情報の認証（暗号化済みの文字列との比較）
```pass_check.php
<?php

// 接続するデータベースの情報
$dsn = 'pgsql:dbname=dbname host=localhost port=5432';
$user = 'user';
$password = 'password';

try {
    // データベースへの接続開始
    $dbh = new PDO($dsn, $user, $password);
    
    // bindParamを利用したSQL文の実行
    $sql = 'SELECT pass FROM table_name WHERE id = :id;';
    $sth = $dbh->prepare($sql);
    $sth->bindParam(':id', $_POST['id']);
    $sth->execute();
    $pass = $sth->fetch();
    
    //認証処理
    if(password_verify($_POST['pass'], $pass['pass'])){
        print '認証成功';
    }else{
        print '認証失敗';
    }
    
    // データベースへの接続に失敗した場合
} catch (PDOException $e) {
    print('接続失敗:' . $e->getMessage());
    die();
}

?>
```
認証処理を行っている``password_verify($_POST['pass'], $pass['pass'])``の箇所ですが、第一引数には認証する文字列を指定、第二引数では暗号化済みの文字列を指定します。
``password_verify``が平文で入力された文字列と暗号化済みの文字列がマッチするかを確かめます。

PHPのコードを理解しようとするよりも、暗号化の仕組みが理解できれば流れもつかみやすいかと思いますので、PHPの公式ドキュメントを読みながら理解を進めると良いかもしれません。

##参考：
安全なパスワードハッシュ
http://php.net/manual/ja/faq.passwords.php
WordPressでimgタグを簡単に挿入する

## TL;DR
自分でビューヘルパーを作るとimgタグを書きやすく、見やすく生成出来るよ。

## imgタグをお手軽に挿入したい
WordPressをやっていっている時に、沢山あるimgタグをベタ書きするなんてやってられませんよね。
こういう時、ビューヘルパーなんかを使って書きやすく、また見やすくするのは当然でしょう。

WordPress上にメディアとしてアップロードされたものは、`get_image_tag();`で簡単に呼び出せますが、記事の画像ではなくサイトの見た目にかかわる画像なども、関数で簡単に呼び出せるようにしておくと良いでしょう。

```php:functions.php
/**
 * イメージタグの生成.
 *
 * @param $file_name
 * @param string $class
 * @param string $alt
 * @param integer $width
 * @param integer $height
 * @return null echo img tag
 */
function the_image($file_name, $class = '', $alt = '', $width = NULL, $height = NULL) {
  $extra_attr = '';

  if ($class) {
    $extra_attr .= ' class="' . esc_attr($class) . '"';
  }
  if ($width) {
    $extra_attr .= ' width="' . esc_attr($width) . '"';
  }
  if ($height) {
    $extra_attr .= ' height="' . esc_attr($height) . '"';
  }
  if ($alt) {
    $extra_attr .= ' alt="' . esc_attr($alt) . '"';
  }

  echo '<img src="' . get_theme_file_uri('/assets/images/' . $file_name) . '" ' . $extra_attr . ' >';
}

```

このような関数を用意しておくと、imgタグを簡単に生成することが可能になります。

```php:functions.php
<?php the_image('my_pic.png', 'profile', 'プロフィール画像', 500, 500); ?>
```

関数にしておくとIDEで引数の説明が出たりするのもいいですね。`get_theme_file_uri('assets/images/*');` のような、地味に書くのが手間な定型句を書かずに済むのもお得です。

このように少し面倒くさいな、と感じるところはガンガンビューヘルパーを作っていくと良いと思います💪
さくらのVPS、CentOS7(x86_64)に、elasticsearchを入れてみた。

rootになる。

●javaのインストール

    yum install java
    java -version

バージョン表示は、下記のように表示される。

    openjdk version "1.8.0_141"
    OpenJDK Runtime Environment (build 1.8.0_141-b16)
    OpenJDK 64-Bit Server VM (build 25.141-b16, mixed mode)


●elasticsearchのインストール

    rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
    vim /etc/yum.repos.d/elasticsearch.repo

新規ファイルとして、下記内容のファイルを作成する。

    [elasticsearch-5.x]
    name=Elasticsearch repository for 5.x packages
    baseurl=https://artifacts.elastic.co/packages/5.x/yum
    gpgcheck=1
    gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
    enabled=1
    autorefresh=1
    type=rpm-md

下記コマンドを実行する。

    yum install elasticsearch

    systemctl enable elasticsearch

    systemctl start elasticsearch


    curl localhost:9200

    [root@tk2-259-39318 ~]# curl localhost:9200
    {
      "name" : "skdoA54",
      "cluster_name" : "elasticsearch",
      "cluster_uuid" : "ERp54wHgQxamJAXrpncmCA",
      "version" : {
        "number" : "5.5.2",
        "build_hash" : "b2f0c09",
        "build_date" : "2017-08-14T12:33:14.154Z",
        "build_snapshot" : false,
        "lucene_version" : "6.6.0"
      },
      "tagline" : "You Know, for Search"
    }

●Kuromojiのインストール

    /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji

-> Installed analysis-kuromoji と表示されたらOK。


    systemctl restart elasticsearch

Failed connect to localhost:9200; 接続を拒否されました
と出るときは、
      
      vi /etc/elasticsearch/elasticsearch.yml
      
      network.host: "localhost"
      http.port: 9200
      
      systemctl restart elasticsearch
AWSから１０００万円の請求が来ないために

# 危険な落とし穴

GitHubは無料枠だと公開設定なので
あげるソースを十分気を付けないといけません。

ミスしてアクセスキーなどを
アップしてしまったらもう大変。

攻撃されればAWSからの請求額が1000万円！！
なんてことも・・・

---

# 気を付けよう

GitHubは本当に気を付けて使いましょう。

アクセスキーのことだけではなく
ロジックを全て見れてしまう訳ですから
攻撃の種にはなります。

危険なファイルは `.gitignore` などを使って
アップ対象外にするなどして
うまく使うことが理想です。

が、いちいちこれは大丈夫かと
気にしながら開発するよりも
非公開設定のGitを用意して、何も気にせず
プラグラムに集中できる方がオススメです。

---

# 非公開Git

GitHubの非公開設定は有料です。

と言っても月1000円程度なので
GitHubを使わせてもらっている身として
支払うのも手です。

どうしても
決済を避けたい。無料で使いたい。という方は
とりあえずBitbucketでもいいと思います。

---

# Bitbucket

無料でもユーザ数5人。
ストレージ1Gまでは使えるので
小規模ならば十分です。

また、友達を紹介すると
ユーザ数は8人まで増やせるみたいです。

リスクを考えながら開発するより
非公開なので安心して
ガンガン全部あげてデプロイしていく方が
開発の進み的にも全然いいでしょう。

ということで、Bitbucketはこちら。
https://ja.atlassian.com/software/bitbucket

---

# 最後に

実際にGitの設定を間違えて
AWSの費用がすごい金額になった話は
良く聞きます。

その金額を支払わなければいけないかどうかは
AWSさんのジャッジなので
AWSのサポートと詰めていく形になります。

色々と心配事を増やさないためにも
最初は非公開設定で
Gitを利用するのが良いでしょう。

最終的にはGitHubに公開していって
FWや便利ツール的に
使ってもらったりできたら嬉しいですよね。

いつかはGitでスターをたくさんもらえるような
人物になりたいものです。
【WebVR】Theta R（RICHO R） の動画をUVCモードでWebVRしてみる【A-Frame】

# はじめに
WebVRのフレームワーク A-Frame を利用してThetaのLive動画をVR対応させます。

# 準備

* Webサーバー（外部を利用する場合はSSLが必要です、たぶん [^1]）
* Thetaなどの全天球カメラ（私は[ThetaR](http://ricohr.ricoh/ja/)で確認）
* VR機器（私はOculus CV1で確認）

[^1]: 映像を取得する getUserMedia が動かないと思います。Localhostなら大丈夫だったかと。

# ソース

[A-Frame](https://aframe.io/) のソースコードを参考にしました。
たったこれだけのソースで、VR対応できるなんて、なんて素敵なのでしょう。

```html:360video.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>360 Video</title>
    <meta name="description" content="360 Video — A-Frame">
    <script src="https://aframe.io/releases/0.6.1/aframe.min.js"></script>

    <script type="text/javascript">
    var constraints = {
        audio: true,
        video: true
    };

    // get user media
    navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

    navigator.getUserMedia(constraints,
        function(stream) {

            var video = document.getElementById("video");
            video.src = URL.createObjectURL(stream);

            console.info("media start");
        },
        function(error) {
            console.error(error);
        }

    );
    </script>
</head>

<body>
    <a-scene>
        <a-assets>
            <video id="video" autoplay loop crossorigin="anonymous"></video>
        </a-assets>
        <a-videosphere src="#video" rotation="0 180 0"></a-videosphere>
    </a-scene>
</body>

</html>
```

# 確認

1. サーバーにソースをアップ
2. OculusをPCに接続
3. ThetaをPCに接続
4. Chromeでアクセス
5. カメラ利用の許可を求められるので、許可 [^2]
6. 映像が映し出されたら画面右下のVRボタン<img width="30" src="https://qiita-image-store.s3.amazonaws.com/0/198489/4a2395c2-a7fe-bb4d-e421-fd44af049827.png">をクリック。
7. Oculusを覗いてみる
8. WoW!

[^2]: カメラを複数繋いでいる場合はURL欄右側のアイコンを<img width="50" alt="" src="https://qiita-image-store.s3.amazonaws.com/0/198489/5399ea2b-db7d-051c-1ea9-ee6440682075.png">から目的のカメラに変更。
Mastodon API で「You are being redirected」とアクセストークンの取得

> Mastodon の API でアクセストークンを取得しようとすると、「You are being redirected」が返ってくる。

## TL; DR <sub><sup><sub><sup>（今北産業）</sup></sub></sup></sub>

1. 初回トークン発行時の「承認画面」に転送されています。
2. テストアプリで、アクセストークンが欲しいだけであれば Mastodon の[設定からアクセス・トークンを発行する](#20170907-%E8%BF%BD%E8%A8%98)のが楽。
3. スクリプトでアクセス・トークンを取得するには「[Access Token Generator for Mastodon API](https://takahashim.github.io/mastodon-access-token/)」（by [@takahashim](http://qiita.com/takahashim) ）の[スクリプト](https://github.com/takahashim/mastodon-access-token/blob/master/index.html)を使うのが手っ取り早い。

### 関連Qiita記事

- [Mastodon APIから「返信」をトゥートする](http://qiita.com/drafts/68ae99c7f98fe309f9bf/edit)
- [Mastodon APIから「未収載」でトゥートする](http://qiita.com/KEINOS/items/27d201afed4ed665cb11)

## TS; DR と 所感

Qiitadon や、その他の Mastodon インスタンスで API を使うための**アクセス・トークンを取得しようとすると「You are being redirected.」の 302 エラーで認証画面（`/auth/sign_in`）にリダイレクトされてしまう**。

以前は PHP 経由でも直接 cURL コマンドを叩いても取得できたのに、`ClientID` と `ClientSecret` までは取得できるものの、トークン取得時に認証画面へのリダイレクトが返されるようになりました。

Qiita／Qiitadon 共に二段階認証は設定しておらず、なんとなくですが、Qiita アカウントと GitHub アカウントと連携してからのような気がします。

> The `/oauth/token` path will attempt to login with the given credentials, and then retrieve the access token for the current user. **If the login failed the response will be a 302 redirect to `/auth/sign_in`**. Otherwise the response will be a JSON object containing the key `access_token`.

本家の情報を見ると認証に失敗しているらしいのですが、もともとメールアドレスとパスワードは変数で渡しているのと念のための内容も確認済みなので、恐らくタイポではない気がします。どうやら「このアプリを許可しますか？」的な、例の画面に転送されているっぽいのです。

「軽くトークンが欲しいだけなのに面倒臭いなぁ」と困っていたら、 @takahashim さんの「[Access Token Generator for Mastodon API](https://takahashim.github.io/mastodon-access-token/)」を使うのが簡単でした。

ソースも GitHub で公開されているので、何を行なっているのかが見れて安心＆勉強になりました。
>[https://github.com/takahashim/mastodon-access-token/blob/master/README.md](https://github.com/takahashim/mastodon-access-token/blob/master/README.md)

### 2017/09/07 追記

Mastodon v1.6.0rc1-16-g4c3dd0b を確認したところ、「設定」-「開発」-「アプリ」から「新規アプリ」ボタン押下で、アプリの登録および OAuth に必要なキー（`Client ID`, `Client Secret`, `Access Token`）が取得できるようになっていました。個人専用のアプリのために、**アクセストークンを取得するだけなら、この画面から発行するのが一番楽**だと思います。（下記図参照）

<img width="100%" alt="スクリーンショット 2017-09-06 0.20.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/78776/54718f1d-f45a-12a8-b44c-6c14207da9bb.png">

## 参考文献

- Testing with cURL | tootsuite @ github<br>https://github.com/tootsuite/documentation/blob/master/Using-the-API/Testing-with-cURL.md
- PHPでMastodonのStreaming APIを受信する。 @ Qiita<br>http://qiita.com/yyano/items/841f79266faf2dc8b6dc
- mastodonのAPIをcurlで試してみた @ Qiita<br>http://qiita.com/znz/items/c924cd4e9d5e50e50058
- ノンプログラマーがMastodon BotをIFTTTとかRSSあたりで作ったドン @ Qiita<br>http://qiita.com/fujii_yuji/items/3507aa9f3d1c6258bb7b
Kernel Network について

## はじめに
kernelのネットワークがどのような仕組みになっているのか、気になったので少し調べてみました。
まだ軽くしか調べられていないが、一旦アウトプット。

## 概要
+ プロセスはソケットを介して通信を行う。
+ ソケットは、ファイルインターフェースを拡張して作られているので、kernelレベルではファイルの利用手順とほぼ同じである

## Kernelのネットワークスタックはどのようになっているのか？
+ 詳細は[Kernel Map](http://www.makelinux.net/kernel_map/)
+ 概略図。[ここから転載](https://ja.osdn.net/projects/linux-kernel-docs/wiki/0.8%E3%80%80%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF)
![kernel_network_stack.png](https://qiita-image-store.s3.amazonaws.com/0/107486/d7fb4dda-6778-bd3c-dcd1-b4b7048a718a.png)


## ソケットインターフェース
+ プロセス間通信が可能。遠隔のプロセスとの通信も可能
+ ソケットバッファによってデータのコーピー処理を頻繁に発生させない仕組みになっている

+ 通信確立までの流れ
  1. サーバ側がクライアントを受け付けるソケットファイルを作成する(socket()を呼び出す)
  2. 受付用ソケットファイルに名前をつける(bind()を呼び出す)
  3. ソケット・キューを作成する(listen()を呼び出す)
  4. ソケット・キューに入っているクライアントからの接続の最初の1つを受け付ける(accept()を呼び出す)
  5. クライアント側ではソケットファイルを作成する(socket()を呼び出す)
  6. クライアント側からサーバへ接続要求を出す(connect()を呼び出す)
  7. サーバ側で、受付用ソケットファイルとは別に、接続用ソケットファイルを作成する。
  8. 結果、read()やwrite()などのシステムコールを呼び出せるようになる
+ 通信切断時は、close()を呼び出し、切断
# 知らないと借金6000万円、フリーランス契約の知識

# 知らないと借金6000万円、フリーランス契約の知識

## 免責事項
法的な内容に関する内容の正確性は保証されません。

## 契約内容、理解してますか？
フリーランスのエンジニアは案件ごとに"契約"を行うが、どのくらいのエンジニアが契約を交わすことの意味やその内容を
理解しているだろうか？多くの人は契約書にほとんど目を通さずにサインをしてしまっているだろう。

しかし契約内容を理解せずに契約を交わしてしまうと、ほんの些細なことから６０００万円の借金を負ってしまうようなことが簡単に起こり得る。実際に私は納期に間に合わず損害倍賞として個人で６０００万円の借金を負った人を知っている。
このような事態を避けるためにも、契約や法律に関する理解を深めることは非常に重要と言える。

今回はこのような事態を避けるために契約を理解するための解説、そして契約書の理解は難しくないということ、そして
エンジニアがどのように契約と向き合えば良いかを説明する。

## 契約は怖い
### 契約は契約者同士の法律
契約は契約者同時の法律のようなものであ。どんなに不利な内容であっても合意すれば、内容そのものが法律に反しない限り、それを履行する義務がある。

### 起こり得ること
例えばエンジニア側が、"納期に間に合わない場合は、それによる損害を全てを負担する"というような契約で、実際に納期に間に合わず、６０００万円の損害が出た場合、エンジニアが個人で６０００万円を負担しなければならない。

※ 特に契約書に記載がなくても損害賠償の請求は可能だが、個人で契約を行う場合はその上限を定めたりするのが妥当だろう。

### 契約企業が外国企業に買収されたら
日本では実際に契約で取り決めた内容よりも、契約者同時の話し合いで物事を調整する文化があり、たとえ契約書に不利な内容が書かれていても相手がそれを行使してこないと考えている人も多いだろう。

しかし海外の企業は契約書に記載されている内容の履行を求めてくる可能性がある。もしエンジニアが国内の企業と契約を交わし、その契約先の企業が外国企業に買収されれば、話し合いではなく契約書の内容を優先して要求を出してくる可能性が高まる。

このような点でも契約を行う際は注意が必要である。


## 契約書
### 契約書は内容の確認書類
日本の法律では、契約を行う際に契約書は必須ではなく、契約内容のお互いの合意が取れれば、契約書がなくても合意が成立する（例外あり）。契約書は合意の内容の証明をしっかり残し、後のトラブルを回避する等の理由から作成される。

### 理解は難しくない
契約書の内容が難しくて読んでも理解できないと考えている人も多いかもしれないが、実際に読んでみると容易に内容ができるものも多い。

## エンジニアが意識すべきこと
### いますぐ確認しよう
もしあなたが現在の契約の内容を確認していない場合は、今すぐ契約書を確認すると良いだろう。もし不利な内容が書かれている場合は早めに契約を終了させる方が良いかもしれない。

### エージェント登録時
エージェント登録時はまず初めに契約書を見せてもらうように依頼しよう。しっかりとしたエージェントならばすぐに提示してもらえるだろう。

### 交渉
企業やエージェントが出してきた契約書をそのまま受け入れなければならないというルールはない。契約書の内容は熟読して受け入れられない項目に関してはしっかり交渉を行おう。

## 請負ではなく委任
フリーランスのソフトウェア開発契約では委任と請負の２種類が主だが、個人では委任契約を選ぶべきだろう。
請負と委任に関しての具体的な説明は省略するが、簡単にチャートにまとめた。

契約種別|仕事の完成責任|個人契約リスク|個人契約のエンジニア向きか
---|---|---|---
委任|なし|低い|YES
請負|あり|高い|NO

ソフトウェア開発では、見積もりや必要技術の予測が困難である。問題が発生した場合、企業ならば人員の割り振りなどで対応できるが個人で対処不能となる可能性が企業と比較して極めて高い。

請負は委任よりリスクが高く、本来なら報酬が高額になるものだが、実際には請負契約で委任程度の報酬が提示されている場合は多い。

これらの理由からフリーランスエンジニアは請負ではなく委任を選択するのが賢明だろう。
Bash on Ubuntu on Windowsからdocker-machineにTLSで接続する(Hyper-V使用)

#Bash on Ubuntu on Windowsでdockerをhttpソケットを開けながらセキュアに利用したい
Bash on Ubuntu on Windows上でdockerを使いたくても現状ではクライアントしか動きません。
そのためdockerのサーバーはBash on Ubuntu on Windowsではなくホストの方で動かす必要があります。
Docker for Windowsにはhttpソケットを開けるオプションが存在します。

![0822.png](https://qiita-image-store.s3.amazonaws.com/0/194293/fad6fc11-79be-ba6b-d23d-bb1993b1e96a.png)
Docker for WindowsのタスクトレイからSettingsを開くとGeneralに、
> - [ ] Expose daemon on tcp:localhost:2375 without TLS

とありますが、この機能は文字通りTLSを使わずに2375を待ち受けるためセキュアではありません。
何らかの理由(例えばファイヤーウォールのルールの設定権がない)から、生のhttpソケットを公開したくない場合があります。
Windowsコンテナの場合はdaemon.jsonを編集することによって、設定を変更することが可能ですが、Linuxコンテナの場合、TLSで待ち受ける機能(待受ポートの設定とかも)が正常に働きません。

 * [Windows 上の Docker エンジン](https://docs.microsoft.com/ja-jp/virtualization/windowscontainers/manage-docker/configure-docker-daemon)

上記のリンクではWindowsコンテナについてMS公式のドキュメントですが、同じことをLinuxコンテナに作用させるとクラッシュします。(Version 17.07.0-ce-rc3-win23 (13024)で確認)
[これ](https://github.com/docker/for-win/issues/225)とか、[これ](https://github.com/docker/for-win/issues/314)を見る限りLinuxコンテナを公開する場合はdocker-machineを使ってね、のような感じみたいです。
そのため、docker-machineを利用してBash on Ubuntu on Windows(BoW)からTLSを使ってhttpソケットにアクセスさせます。

##前提として
Bash on Ubuntu on Windows(BoW)とdocker-machine、Hyper-Vが使えることとします。
BoW上でDockerクライアントを入れておきます。
私の環境では、Docker for Windowsを入れたらdocker-machineも入ったのでそれを利用しています。
docker-machineで使う仮想スイッチは予めHyper-Vの管理コンソールかpowershellで作成しておきます。
このとき仮想スイッチは｢外部ネットワーク｣で、対象となるNICを選択し、｢ □管理オペレーティングシステムに～｣のチェックを入れます。多分内部的にはブリッジのような感じになってます。
作成したスイッチの名前は後で使うので覚えておきます。
私の環境ではうまく動きませんが、動く方は[WindowsNAT](http://www.atmarkit.co.jp/ait/articles/1612/16/news039.html)で構成してもいいと思います。
![0828.png](https://qiita-image-store.s3.amazonaws.com/0/194293/5bc6ad75-1a6b-6dc4-1a1d-dfcf8b34afc8.png)

そして、先ほど作ったスイッチを使うため、引数で先ほどのスイッチを指定してください。
私は｢bridge｣という名前で作成したため、以下のようになります。
Hyper-Vを使用するため、driverでhypervを、マシン名をtestVMにしています。

```
docker-machine create --driver hyperv  --hyperv-virtual-switch 作成したHyper-Vのスイッチ名(私の環境だとbridge) 作成するマシン名
```


管理者権限で起動されたpowershell上で実行すると指定したマシン名で作成されます。
作成が終わったら、同じくpowershell上で以下のコマンドを叩いてください。

```
docker-machine env 作成したマシン名
```

実行するとbashで追加すべき環境変数が表示されます。
そのうち、

 * DOCKER_TLS_VERIFY 
 * DOCKER_HOST 
 * DOCKER_CERT_PATH
 * DOCKER_MACHINE_NAME

をBoWのbashなりzshの環境変数に追加しましょう。私の環境ではzshで読み込んでexportしてます。
この時注意するべきなのが、DOCKER_CERT_PATHは、BoW上では/mnt/c/をつけて、その上で、パスを\から/に書き換えてください。
例:DOCKER_CERT_PATH="/mnt/c/Users/ユーザー名/.docker/machine/machines/testVM/"
BoW上で、

```
docker version
```
を叩いて、server側の情報が表示されたら成功です。
GAMESS > setupまとめ > version:20 Apr 2017(R1)

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GAMESS version:20 Apr 2017(R1)
Intel Math Kernel Library version 12
```

量子化学計算のGAMESS
http://www.msg.ameslab.gov/gamess/index.html

setupに関する整理をしておく。

### Version

GAMESS version:20 Apr 2017(R1)

Intel Math Kernel Library version 12
を使う。

### install.info

configにて以下のようになるように設定した。

```install.info
#!/bin/csh
#   compilation configuration for GAMESS
#   generated on UN1609-01
#   generated at Mon Aug 28 11:29:13 JST 2017
setenv GMS_PATH            /home/y_okada/GAMESS_20Apr2017/gamess
setenv GMS_BUILD_DIR       /home/y_okada/GAMESS_20Apr2017/gamess
#         machine type
setenv GMS_TARGET          linux64
#         FORTRAN compiler setup
setenv GMS_FORTRAN         gfortran
setenv GMS_GFORTRAN_VERNO  4.4
#         mathematical library setup
setenv GMS_MATHLIB         mkl
setenv GMS_MATHLIB_PATH    /opt/intel/mkl/lib/intel64
setenv GMS_MKL_VERNO       12
#         parallel message passing model setup
setenv GMS_DDI_COMM        sockets
#         LIBCCHEM CPU/GPU code interface
setenv GMS_LIBCCHEM        false
#         Intel Xeon Phi build: true/false
setenv GMS_PHI             false
#         Shared memory type: sysv/posix
setenv GMS_SHMTYPE         sysv
#         OpenMP support: true/false
setenv GMS_OPENMP          false
```

### compddi

machines/readme.unix記載通りに実行した。

### compall

machines/readme.unix記載通りに実行した。

### lkedのエラー対処

[GAMESS > setup > Error:undefined reference to `dlopen'](http://qiita.com/7of9/items/ba1fcd477e6fb26d7a5f)

### rungms

以下のように設定をした。

```
set SCR=/backupDev/workGAMESS
set USERSCR=~/workGAMESS
set GMSPATH=~/GAMESS_20Apr2017/gamess
```

その後、runall 00にてexample47まで実施されることを確認した。
Rails ユーザーが Django で簡単なブログエンジンを作ってみた

# 概要

Django を最近勉強し始めたので、簡単なブログエンジンを作ってみた。
[Django チュートリアル](https://docs.djangoproject.com/ja/1.11/intro/tutorial01/)を全面的に参考にした。
このチュートリアルは、わかりやすくてよい。

このブログエンジンでは、ブログエントリの一覧表示・新規作成・編集・削除が可能。ブログエントリが10個を超えるとページネーションする。

# 実装

https://github.com/elm200/blogger-django

![image.png](https://qiita-image-store.s3.amazonaws.com/0/26146/be3d1ca3-2d97-2ec9-5330-79d423e54424.png)

# Rails との比較

Python のフルスタックなウェブフレームワークとして Ruby on Rails と比較されることの多い Django。私は使い始めてまだ10日程度なので大きなことは言えないが、いまのところとても気に入っている。Rails と比べるとタイプ量は多めだが、その分わかりやすい。

Rails は黒魔術的なメタプログラミングによって、わずかなコード量でいろんなことが可能になるが、いちど決められた「レール」を外れると、何をどうしたらいいのかすぐわからなくなる。親切心で導入された Rails の各種 DSL も、何がどこまでできるのかよくわからず、使い込んでくると鬱陶しく感じられる。

その点 Django は「暗黙的より明示的」という Python の哲学に忠実で、こちらがアクションを起こさない限り、余計なことをしないのがよい。Rails ではフレームワークのソースコードを読み込まないと動作が理解できなかったが、Django ではそこまでやらなくても良さそう（少なくとも頻度は減りそう）。

# 今後の課題

- 一覧画面でのカラム別ソート
- コメント欄の作成
GAMESS > setup > Error:undefined reference to `dlopen'

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GAMESS version:20 Apr 2017(R1)
Intel Math Kernel Library version 12
```

量子化学計算のGAMESS
http://www.msg.ameslab.gov/gamess/index.html

Intel Math Kernel Libraryを用いた計算設定をしている。

セットアップにおいて、lked実行時に以下のようなエラーが出る。

```
/opt/intel/mkl/lib/intel64/libmkl_core.a(mkl_memory_patched.o): In function `mm_cleanup_thread_cbk':
mkl_memory.c:(.text+0xa7ef): undefined reference to `dlopen'
mkl_memory.c:(.text+0xa810): undefined reference to `dlsym'
mkl_memory.c:(.text+0xa85e): undefined reference to `dlsym'
mkl_memory.c:(.text+0xa874): undefined reference to `dlsym'
mkl_memory.c:(.text+0xa88a): undefined reference to `dlsym'
mkl_memory.c:(.text+0xa97f): undefined reference to `dlerror'
mkl_memory.c:(.text+0xa9d2): undefined reference to `dlopen'
mkl_memory.c:(.text+0xaa86): undefined reference to `dlopen'
mkl_memory.c:(.text+0xaa9c): undefined reference to `dlerror'
mkl_memory.c:(.text+0xab60): undefined reference to `dlopen'
mkl_memory.c:(.text+0xab68): undefined reference to `dlerror'
mkl_memory.c:(.text+0xab7d): undefined reference to `dlsym'
mkl_memory.c:(.text+0xaba0): undefined reference to `dlopen'
mkl_memory.c:(.text+0xaba8): undefined reference to `dlerror'
mkl_memory.c:(.text+0xabb8): undefined reference to `dlsym'
mkl_memory.c:(.text+0xabd3): undefined reference to `dlerror'
```

https://software.intel.com/en-us/forums/intel-math-kernel-library/topic/621814
によると`-ldl`が必要とのこと。

lkedファイルの543行あたり(case mklのcase 12の場合)において以下がある。

```
          if ($GMS_FORTRAN == gfortran) set iflib=gf
          set MATHLIBS="-Wl,--start-group"
          set MATHLIBS="$MATHLIBS $mpath/libmkl_${iflib}_ilp64.a "
          set MATHLIBS="$MATHLIBS $mpath/libmkl_sequential.a "
          set MATHLIBS="$MATHLIBS $mpath/libmkl_core.a "
          set MATHLIBS="$MATHLIBS -Wl,--end-group"
```

下記のように`-ldl`を追加した。

```
          if ($GMS_FORTRAN == gfortran) set iflib=gf
          set MATHLIBS="-Wl,--start-group"
          set MATHLIBS="$MATHLIBS $mpath/libmkl_${iflib}_ilp64.a "
          set MATHLIBS="$MATHLIBS $mpath/libmkl_sequential.a "
          set MATHLIBS="$MATHLIBS $mpath/libmkl_core.a "
          set MATHLIBS="$MATHLIBS -Wl,--end-group"
          set MATHLIBS="$MATHLIBS -ldl" # added 2017/08/28
```

lkedを実行するとエラーがでなくなり、`games.00.x`が生成された。

```
$lked
...
Linker messages (if any) follow...
 
The linking of GAMESS to binary gamess.00.x was successful.
0.436u 0.156s 0:00.60 96.6%	0+0k 0+90752io 0pf+0w
```
既存のDBを途中からknex.jsでスキーマ管理する



JavaScript 用の SQL Query Builder [knex.js](http://knexjs.org/) は，Rails Migration と同じようなことを node でもやりたいとなった時に非常に便利．
しかし，既に運用中の DB で knex.js を使おうとした時に，knex の DSL では，既存 DB と全く同じスキーマが再現できないケースがある．

# 再現できないケース

- `ON UPDATE CURRENT_TIMESTAMP` が設定できない
- `id int(11) NOT NULL AUTO_INCREMENT` が設定できず `id int(10) unsigned NOT NULL AUTO_INCREMENT` になる
- `float` が `precision`, `scale` なしで設定できず  `float(XXX, XXX)` になる


# knex.schema.row でスキーマを丸コピして対応

[knex.schema.raw](http://knexjs.org/#Schema-raw) で直接スキーマデータを実行すればよい．
`SHOW CREATE TABLE sample_table;` で取得できるスキーマを記述する．

```javascript:create_sample_table
const TABLE_NAME = 'sample_table';

exports.up = function (knex, Promise) {
    return knex.schema.hasTable(TABLE_NAME).then(function (exists) {
        if (!exists) {
            return knex.schema.raw(
                " CREATE TABLE `sample_table` (" +
                "   `id` bigint(20) NOT NULL AUTO_INCREMENT," +
                "   `title` varchar(255) NOT NULL," +
                "   `created_at` datetime NOT NULL," +
                "   `updated_at` datetime NOT NULL," +
                "   PRIMARY KEY (`id`)," +
                " ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;"
            );
        } else {
            return new Error("The table already exists");
        }
    });
};

exports.down = function (knex, Promise) {
    return knex.schema.hasTable(TABLE_NAME).then(function (exists) {
        if (exists) {
            return knex.schema.dropTable(TABLE_NAME);
        }
    });
};
```

# knex実行

既存 DB に対しても `knex migrate:latest` を実行しても問題ない．
実行後，`knex_migrations`, `knex_migrations_lock` が生成されていることを確認する．


# 参考
- http://knexjs.org/
- http://qiita.com/YoshiyukiKato/items/59c9ac742536d706b322
rake db:migrateしようとするとPG::ConnectionBad: could not connect to server: Connection refusedエラーで怒られる（solved）

#background info
`rake db:migrate`を実行しようとすると以下のようなエラーが出てくる:

```
PG::ConnectionBad: could not connect to server: Connection refused
	Is the server running on host "localhost" (::1) and accepting
	TCP/IP connections on port 5432?
could not connect to server: Connection refused
	Is the server running on host "localhost" (127.0.0.1) and accepting
	TCP/IP connections on port 5432?
```

#attempt1: 再インストール

```
$ gem uninstall pg
$ bundle install
```

を試みたが特に変化はなし。

#attempt2: database.ymlの書き換え

```
default: &default
  host: localhost
```

を足すと直るかもしれないときき実行したが特に変化なし。

#attempt3: そもそもpostgresql実行していないのでは？

<a href="https://stackoverflow.com/questions/7975556/how-to-start-postgresql-server-on-mac-os-x" target=_blank>How to start PostgreSQL server on Mac OS X?</a>を参考にしながら`pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start`でマニュアル実行。ちなみにマニュアルストップの方法は`pg_ctl -D /usr/local/var/postgres stop -s -m fast`。

```
$ pg_ctl -D /usr/local/var/postgres status
pg_ctl: server is running (PID: 52599)
/usr/local/Cellar/postgresql/9.6.4/bin/postgres "-D" "/usr/local/var/postgres"
```

動いている！

そこで`rake db:migrate`を実行してみると今度は以下のようなエラーが:

```
rake aborted!
ActiveRecord::NoDatabaseError: FATAL:  database "mynewapp_development" does not exist

PG::ConnectionBad: FATAL:  database "mynewapp_development" does not exist
```

データベースがそもそもないと怒られているみたいなので`rake db:create`を実行してデータベースを作成する。

```
$ rake db:create
Created database 'mynewapp_development'
Created database 'mynewapp_test'

$rake db:migrate
rake db:migrate
== 20170828031040 CreatePosts: migrating ======================================
-- create_table(:posts)
   -> 0.0028s
== 20170828031040 CreatePosts: migrated (0.0028s) =============================
```

参照: <a href="https://stackoverflow.com/questions/38409126/rails-4-change-database-from-sqlite3-to-pgsql" target="_blank">rails 4 change database from sqlite3 to pgsql
</a>

#エラーの原因

単純にpostgresqlが起動していなかったこととデータベースが用意されていなかった。
RaspberryPi2 CentOS7でgcc-4.9.4 のビルドがうまくいかない→できました！

##環境
raspberry pi2 on centos7

```
# cat /etc/redhat-release
CentOS Linux release 7.3.1611 (Core)
Linux version 4.4.26-v7.1.el7 (mockbuild@armv7-02.dev.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-4) (GCC) ) #1 SMP Sat Oct 22 16:14:43 UTC 2016

cpuinfo: ARMv7 Processor rev 5 (v7l)
```

###makeで標準出力の末尾に以下のメッセージが出力される

In file included from /usr/include/features.h:399:0,
                 from /usr/include/stdio.h:27,
                 from ../../../libgcc/../gcc/tsystem.h:87,
                 from ../../../libgcc/libgcc2.c:27:
/usr/include/gnu/stubs.h:7:29: fatal error: gnu/stubs-soft.h: No such file or directory
 # include <gnu/stubs-soft.h>
                             ^
compilation terminated.
make[3]: *** [_muldi3.o] Error 1
make[3]: Leaving directory `/tmp/gcc-4.9.4/build/armv7l-unknown-linux-gnueabihf/libgcc'
make[2]: *** [all-stage1-target-libgcc] Error 2
make[2]: Leaving directory `/tmp/gcc-4.9.4/build'
make[1]: *** [stage1-bubble] Error 2
make[1]: Leaving directory `/tmp/gcc-4.9.4/build'
make: *** [all] Error 2
```

##原因
~~調査中・・・
何かご存じの方いらっしゃいましたら、コメントまでお願いできますでしょうか。~~

##2017/09/25追記
gnu/stubs-soft.hを他のマシンから持ってきたり、glibcをupdateしてみたり、コンパイルオプションに
--mfloat-abi=hardを追加してみましたが、だめでした。
このまま暗礁に乗り上げそうです。

##2018/11/15追記
--disable-multilib --with-float=hard をオプションにつけたところ、正常にビルドすることが出来ました。
実際のコマンド：
`./configure --prefix=/usr/local/gcc-4.9.4 --disable-multilib --with-float=hard`
`make`
`make install`

```
# gcc -v
組み込み spec を使用しています。
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/gcc-4.9.4/libexec/gcc/armv7l-unknown-linux-gnueabihf/4.9.4/lto-wrapper
ターゲット: armv7l-unknown-linux-gnueabihf
configure 設定: ../configure --prefix=/usr/local/gcc-4.9.4 --disable-multilib --with-float=hard
スレッドモデル: posix
gcc バージョン 4.9.4 (GCC)
```

RaspberryPi2でのmakeには丸1日かかりましたので、止めたくないサービスがある場合は留意したほうがよさそうです。

コメントしてくださったみなさま、ありがとうございました。
AWS S3でregionを設定する

# 注意
ここではAWS SDK for Ruby **V2**で開発しています。
V1とは、`AWS::S3`ではなく`Aws::S3`と書いたり若干違うので要注意です。

# AWSのS3でインスタンスを作ると、、、

`Aws::S3::Client`でインスタンスを作っていたときのことです。
以下のように書いていました、、、

```
def s3
  @s3 ||= Aws::S3::Client.new(
      :access_key_id => ENV['AWS_S3_ACCESS_KEY'],
      :secret_access_key => ENV['AWS_S3_SECRET_KEY']
  )
end
```

するとエラーが出ます。
Regionを設定しないと以下のエラーが出ると思います。

```
Aws::Errors::MissingRegionError - missing region; use :region option or export region name to ENV['AWS_REGION']:
```

では、どのようにしたらいいのでしょう？

## Regionの設定の仕方

ここで[AWSのドキュメント](http://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html)をみてみましょう。

<img width="907" alt="スクリーンショット 2017-08-19 2.31.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/153320/bea60d3f-f066-1774-8fa2-a329a1262a32.png">

ここでサービス対象があるところを設定します。
基本的に`Qiita`を読んでいる人は日本で開発していると思うので

```
def s3
  @s3 ||= Aws::S3::Client.new(
      :region => 'ap-northeast-1',
      :access_key_id => ENV['AWS_S3_ACCESS_KEY'],
      :secret_access_key => ENV['AWS_S3_SECRET_KEY']
  )
end
```

となって、エラーがでなくなります。

参考になればいいね！とストックをお願いします。
font-sizeをremとvwを混ぜていい感じにレスポンシブに拡縮してくれるようにする

僕は普段rem指定でフォントサイズを決めてるのですが、RWDの案件などでは横幅がiPadサイズとかになると、文字がとても小さくなり読みにくくなることがある。以下のコードでrem指定のまま、いい感じに拡縮できるようになる。

`$sp_width`はPhotoshopなどのデザインデータの横幅。

```
html {
    font-size: 62.5%; 
}
@media (max-width: 899px) {
    html {
       $sp_width: 320px;
       font-size: 100vw * (10px / #{$sp_width}); 
}
```
Line Waveの100の嫌いなところ

1.開封してWiFi接続したらいきなりソフトウエアアップデート（アプリ側のやってみようのメッセージと異なり、いきなり反応しなくなり焦る）
→アップデートは五分くらいでした。

2.勝手に会話を終了する（こっちはまだ話してんのよ）
3. 朝のアラームすっぽかされた
4. なぜか娘の声にだけ反応しない（音圧弱いから？）
5. 音楽の音量と、対話の音量が同じになってしまう（そこは別々にしないと）
6. なかなか聞き取ってくれなくて、そのたびに、Clova！からやり直し
7. 小声では聞き取ってくれない
→大きな声なら5メートルくらい離れていても動作しました（スペック通り）
8. 電源コードが正々堂々、前面に
9. なぜか横向きで配達（宛名ラベルのせい）
10. とにかく反応が遅い（いいよ、もう自分でスマホで調べるよ）
→3秒くらい、ちょっと間が空きます
11. 呼びかけは、ClovaかJessicaしか選べない
12. 呼びかけは、OK, Clovaとしないと、同じ部屋にいる人が気になってしまう
13→OKを入れることで、操作しているんだなとわかる。（グーグルの宣伝のおかげか）
14.　目覚ましにスヌーズがない
15.　聞き取れないときに、聞き取れませんでしたと言ってから、また待機状態になってしまう
16.　Line Musicの曲を指定して流すことがとても難しい
　　→トンチンカンな反応で勝手に認識終了
17.  テレビドラマのセリフの何かが、ジェシカに聞こえたらしく、夜中にいきなり女の人の声で反応しはじめて、心臓がとまりそうになる。
18. Line連携の呼び名がデフォルトのリストからしか選べないので、自分の名前やニックネームがない人は、登録しようがない。
19.  音量ゼロにすると、ジェシカと読んでも返事が音量ゼロよ。
20. 一息で、ジェシカ、リラックスする音楽を再生して、と言い切るのは結構つらいものがある
21. 滑舌悪いと、うまく操作できない。噛んだら、ジェシカ！からやり直し
22. スピーカーの低音が効きすぎ
23. 筐体が布みたいなので覆われているので、ティッシュ触ったあととかに触ると、細かいホコリがついてしまう。
24. 指示を理解できなかったときの返事が、気を利かせ過ぎで、長たらしくてイライラする
25. 曲を再生できないとき、もっと勉強しなきゃなりませんとか言うのだけど、そもそも曲が提供されていないのか、それとも間違って聞き取ったのかが分からない
26. お客様がいらしていて絶対喋っちゃいけないタイミングで、アップデートが終わりましたと三回絶叫する
27. 先行版を買った人をおちょくるような正式版のキャンペーン価格
28. テレビは電源オンとボリュームのみなので、朝布団の中から操作しようとしても、前夜にFireStickTVやChromeCastを見てたりすると、真っ黒な画面が流れるだけで、あとはリモコン取りに行くと事になる
29. アラームの音量を上げようとすると音がなるので周りを起こしてしまう。
30. アラームを止めるのに何度も声かけが必要
自動更新購読を実装したアプリをApp Storeから削除する際の注意点

この度、自動更新購読を使ったアプリを、ストアから削除することになりました。
かなしいですね。

ところで、実際に自動更新購読を使ったアプリをストアから削除した場合、ユーザー側で既にダウンロード済みのアプリってどうなるんだろうか。
なにかアプリ側で特別な処理がいるんだろうか。
ググってもどうもちゃんとした情報が見つからなかったので、実際にAppleに問い合わせをしてみた。

念の為に書いておくと、この話はあくまで2017年8月28日時点でのAppleからの回答です。
ここ最近自動更新購読のシステムが変わったりしているので、未来永劫ここに書いて有ることが正しいとも限らないです。
少しでも不安に思ったらAppleに問い合わせると良いかと思います。

# アプリのストアの配信状態と、アプリのプロダクトの配信状態はそれぞれ独立
これはAppleのテクニカルサポートにも連絡して確認したが、アプリをストアから取り下げたとしても、アプリの自動更新購読プロダクトをストアから取り下げない限りユーザーは自動更新購読で継続課金をすることができるとのこと。

Appleへの質問とその回答は次の通り。
> Q1. When we remove the app from app store, users who downloaded the app can refresh and verify Auto-Renewable Subscription receipt?
> Response - If all you do is to remove the app from sale, but leave the In-App Purchase auto-renewing subscription items as “Cleared for Sale”, then the existing users will still their credits cards charged for the auto-renewing subscription items. As the auto-renewing subscription items renew, the transactionObserver in the app should continue to detect the renewal purchases and the appStoreReceipt in the app shall be updated to reflect the renewals.

この回答から、自動更新購読プロダクトの配信可能設定がオンになっている限り（Cleared for Sale）、プロダクトは自動更新購読され続けるとのこと。
なので、iTunesConnectのプロダクトの配信可能設定をオフにしないといつまでも自動更新購読され続けてしまう。
配信可能設定はiTunesConnectのプロダクトの設定から変更することができる。

![スクリーンショット 2017-08-28 11.25.01.png](https://qiita-image-store.s3.amazonaws.com/0/69711/986e7c2e-6920-7662-3a41-41954cfca78a.png)

コンテンツをAppleから配信している場合は特に問題はないのだが、コンテンツを自社サーバーから配信している場合は、アプリをストアから削除してコンテンツ配信サーバーも落としちゃうと、ユーザーのアプリ継続課金中なのに使えない、ということになりかねないので気をつけるべし。

# 自動更新購読プロダクトの配信をオフにした場合の挙動
自動更新購読プロダクトの配信をオフにした場合、ユーザーのプロダクトは自動更新が行われなくなり、自動更新に伴う新しい課金も行われなくなるとのこと。
ただし、すでにダウンロード済みのコンテンツについては引き続き利用できなければならないし、サービスを提供している場合は各ユーザーの自動更新購読期間満了まで使用し続けられなくてはならない。

ちなみに、自動更新購読プロダクトの期間は、ユーザーがプロダクトを購入したときから積算するので、ユーザーによっては購読満了日がまちまち。
なので、全てのユーザーの購読期間が満了するには最低でもプロダクトの配信設定をした期間だけ待たなければならない。

# ユーザーの購読期間満了前に自社のコンテンツ配信サーバーを落としちゃった場合
これ結構微妙な話なのでなんとも言えないのだが、Appleに問い合わせた際の話だと、ユーザーから問い合わせがあった時に個別に対応して返金、ということがあるとのこと。
ただ具体的な返金基準等は教えてもらえず、また、ユーザー毎に購読期間満了日を勘案して個別対応で返金額を算出するらしい。
最終的にすべての返金分は、iTunesConnectを通してデベロッパーに請求するそうなので、気をつけようという話。

# 最終的なアプリの取り下げ方。
1. 事前に余裕を持ってユーザーに対してサービス終了の告知をする
2. サービス終了期日にアプリをストアから削除。同時にアプリ内自動更新購読プロダクトの配信設定もオフ
3. 自社サーバーからコンテンツを配信している場合は、自動更新購読プロダクトで設定していた配信期間は最低でも稼働させておく。
4. 配信期間終了をもって自社のコンテンツ配信サーバーを停止
ESLintのコメントでのルール制御

大まかには`.eslintrc`に書いとけばいいが、ファイルや特定の場合によって個別にルールを無効にしたい時がちょこちょこある。その辺をコメントで解決できる方法がいくつかあるのでまとめ。

## ファイル全体

例えばこのコードは`no-unused-vars`というルールの警告を受けるが、

```js
const a = 1;
```

こうすれば回避できる。

```js
/* eslint no-unused-vars: 0 */
const a = 1;
```
注意点として必ず`/* */`で囲む事。また、ルールは`,`で区切って複数指定できます。

`/* eslint ... */`で書いたものは、そのファイル全体で有効になるので、こうすると再度有効になって`a`にも`b`にも警告を受ける。

```js
/* eslint no-unused-vars: 0 */
const a = 1;
/* eslint no-unused-vars: 2 */
const b = 2;
```

> ちなみに設定の数値はそれぞれ、`0="off"` `1="warn"` `2="error"` という意味です。

## 特定の行のあるルールを無効に

以下のルールが使える。これらはルール名を指定しないとすべてを無効にし、指定するばそれだけ無効にする。ルールは`,`で区切って複数指定できます。

### `eslint-disable-next-line <...rule>`

無効にしたい行の**前の行**に書く。以下は`b`だけが警告される。

注意点として必ず`//`記法を使う事。

```js
// eslint-disable-next-line no-unused-vars
const a = 1;
const b = 1;
```

### `eslint-disable-line <...rule>`

無効にしたい行と**同じ行**に書く。以下も`b`だけが警告される。

注意点として必ず`//`記法を使う事。

```js
const a = 1; // eslint-disable-line no-unused-vars
const b = 1;
```

### `eslint-disable <...rule>`と`eslint-enable`

これは行というより範囲だけど。２つの間のルールが無効になる。以下も`b`だけが警告される。

注意点として必ずどちらも`/* */`記法を使う事。

```js
/* eslint-disable no-unused-vars */
const a = 1;
/* eslint-enable no-unused-vars */
const b = 1;
```

`eslint-enable`は指定したルールだけ戻す感じで、何も指定しなければすべて戻すことができる。

```js
/* eslint-disable no-unused-vars, no-unused-expressions */
const a = 1;
() => {};
/* eslint-enable */
const b = 1;
```
Vuex + APIの実装


もし、間違いがあればどんどんご指摘いただきたいですm(__)m

#Vuexの概要図

![Vuex](https://vuex.vuejs.org/ja/images/vuex.png)


データをサーバに送信する際に実行される流れ。

```
1. コンポーネントでイベントが発火
2. コンポーネントがStoreのアクションを呼び出す(dispatch)
3. アクションがAPIへ問合せを行う
4. アクションがリクエストの結果に応じてミューテーションを呼び出す(commit)
5. ミューテーションがstateを書き換える
6. stateが変更された部分のコンポーネントに変更が反映される
```

#アクションとAPIに関して

アクションは、


```
1. 非同期処理（APIへの問い合わせ）
2. ミューテーションを実行
```

コードで見れば、こんなかんじです。

```js:action.js
const actions = {
    [ACTION.GET_ITEMS] ({commit}) {
        ItemsAPI.getAllUnchecked(items => {
            commit(MUTATION.SET_ITEMS, items);
        });
    },
    [ACTION.CREATE_ITEM] ({commit}, content) {
        ItemsAPI.create(content, (item) => {
            commit(MUTATION.ADD_ITEM, item);
        });
    },
    [ACTION.CHECK_ITEM] ({commit}, id) {
        ItemsAPI.check(id, () => {
            // チェックされたアイテムをリストから削除
            commit(MUTATION.REMOVE_ITEM_BY_ID, id);
        });
    },
    [ACTION.DELETE_ITEM] ({commit}, id) {
        ItemsAPI.delete(id, () => {
            commit(MUTATION.REMOVE_ITEM_BY_ID, id);
        });
    }
};
```

それぞれ、アクションを定義し、

1. APIとやりとり
2. ミューテーションにコミット

1の部分のやりとりは以下のようにやってます。


```js:async_api.js
const axios = require('axios');
const API_URI = '/api/items';

export const ItemsAPI = {
    getAllUnchecked(callback) {
        axios.get(API_URI)
            .then((response) => {
                callback(response.data);
            })
            .catch((error) => {
                console.log(error);
            });
    },
    create(content, callback) {
        axios.post(API_URI, {content: content})
            .then((response) => {
                callback(response.data);
            })
            .catch((error) => {
                console.error(error);
            });
    },
    check(id, callback) {
        axios.patch(API_URI + '/' + id, {checked: true})
            .then((response) => {
                callback(response.data);
            })
            .catch((error) => {
                console.error(error);
            });
    },
    delete(id, callback) {
        axios.delete(API_URI + '/' + id)
            .then((response) => {
                callback(response.data);
            })
            .catch((error) => {
                console.error(error);
            });
    }
};

```

APIへ問い合わせて、コールバック関数にデータを渡しています。

※ミューテーションではHTTPリクエスト等の非同期処理を実行してはいけません。
基本的にミューテーションではstateの変更をします。

#参考
https://vuex.vuejs.org/ja/intro.html
http://blog.asial.co.jp/1499?category_id=12
heroku+rails+mysqlでheroku run rake db:createができない。

作ったアプリをherokuで動かしてみようと思って、ハマったのでメモです。

# 環境
```
heroku
clearDB(mysql)
rails5
```
# エラーにハマる。
`heroku run rake db:create`を実行すると以下のエラー。

`Mysql2::Error: Can't connect to local MySQL server through socket '/tmp/mysql.sock' `

データベースへの接続がうまくいっていないのはエラー文から分かりますが、調べてみたところ、このエラーはけっこう原因が色々あるみたいです。
自分の場合は以下の方法で解決しました。

# 解決
こちらのサイトを参考にしながら、環境変数をきちんと`heroku config:set`してあげたら動くようになりました。
[Heroku で Rails4 + MySQL を動かす](http://xyk.hatenablog.com/entry/2014/09/29/184727)

単純にmysqlに接続するための設定が足りていなかっただけです。

環境変数の設定については、こちらが詳しいです。
[環境変数の操作](http://qiita.com/colorrabbit/items/18db3c97734f32ebdfde)

ここで気をつけるのは、`heroku config:set 'DATABASE_PASSWORD'='内容'`という感じで、`DATABASE_PASSWORD`のところも`''`で囲んであげないと以下のエラーが出ます。
`DATABASE_PASSWORD is invalid. Must be in the format FOO=bar.`
# 以上です ！
herokuは初心者でもデプロイまで簡単にできて助かりますね！！
何か間違いなどあればコメントお願いします！
GAMESS > setup > [GAMESS directory]と[GAMESS build directory]を違うものにした場合に、はまる

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GAMESS version:20 Apr 2017(R1)
```

量子化学計算のGAMESS
http://www.msg.ameslab.gov/gamess/index.html

Linux版のセットアップでうまくいかなかった。

./config実行での設定項目に以下がある。

1. GAMESS directory
2. GAMESS build directory

上記については、以下と思っている。
> 1はtar.gzファイルを展開した場所
2はセットアップ後のGAMESSを配置する場所

「1と2を異なるdirectoryに設定」したとする。

### トラブル1

config実行後、install.infoファイルが2の場所に作成される。ビルドするのは1の場所なのでビルド時に「install.infoファイルが見つからない」となる。

install.infoファイルを2の場所から1の場所にコピーしてからsetup作業を続けたらcompddiの実行は成功した。

### トラブル2

次に、compallを実行すると以下のようなエラーとなる。

```
$ ./compall 
Mon Aug 28 11:19:43 JST 2017
Something went wrong with 'config', so that the source code
activation program was not correctly compiled.  Please repeat
the 'config' step, so that tools/actvte.x is created.
```

tools/actvte.xが作成されるのは「2. GAMESS build directory」の方であり、ビルド環境の「1. GAMESS directory」においては見えない、ということになっているようだ。

### 対処

考えられる対応は以下となる。

「1. GAMESS directory」と「2. GAMESS build directory」を同じにする。

google検索などで見つかるGAMESSのセットアップ例では「1. GAMESS directory」と「2. GAMESS build directory」を同じにしているようである。それは上記のようなトラブル回避のためなのかもしれない。
[Slack] 外部から特定のチャンネルに投稿する

Slackにはすでにチケット管理システムや監視ツールと連携するアプリが用意されていますが、Incoming WebHooksというアプリを使うことで、連携アプリが無いツール向けにHTTPSベースの汎用的な外部連携の仕組みを簡単に実現することができます。
# Slack側の設定
```
Slackのチーム設定によってはアプリのインストールに管理者の承認が必要な場合があります。
その場合は管理者に連絡してIncoming WebHooksをインストールしてもらってください。 
```
チーム名をクリックして[Manage apps]を選択します。

![01.select-manage-apps.png](https://qiita-image-store.s3.amazonaws.com/0/171575/516c1a6b-9054-4d7e-9d22-ce494bb23314.png)

画面上部の検索ボックスに[incoming]と入力して候補に挙がった[Incoming Webhooks]を選択します。

![02.search-app.png](https://qiita-image-store.s3.amazonaws.com/0/171575/e9b85a02-3e7b-8d85-38e6-c715595481c1.png)

[Add Configuration]をクリックします。

![03.app.png](https://qiita-image-store.s3.amazonaws.com/0/171575/4534e35b-2f74-8189-12fa-f31ea1cdd2d9.png)

外部から投稿したいチャンネルを選択します。ただし、チャンネルはリクエスト内で指定できるので、ここで選択するのはあくまでもデフォルトのチャンネルです。(後から設定画面で変更できます。プライベートチャンネルも指定できます)
選択後[Add Incoming WebHooks integration]をクリックします。

![04.add.png](https://qiita-image-store.s3.amazonaws.com/0/171575/d72fc1e4-1783-09e3-9162-63e94afe79bb.png)

以下のような画面が表示されればSlack側の設定は完了です。

![05.complete.png](https://qiita-image-store.s3.amazonaws.com/0/171575/fc263428-83b8-40ba-5977-fa1c54d0f0ff.png)

### 参考) Integration Settings (設定)

| 設定名 | 説明 |
|:--|:--|
| Post to Channel | 前の手順で選択した投稿先のデフォルトチャンネルを変更できます。リクエスト内で指定(この設定を上書き)することもできます。 |
| Webhook URL  | 外部からリクエストを送信する先のURLです。Regenerateをクリックすることで再生成することができます。  |
| Descriptive Label  | 一覧で表示されるメモです。  |
| Customize Name | Slack投稿時に表示される名前を設定します。リクエスト内で指定(この設定を上書き)することもできます。 |
| Customize Icon  | Slack投稿時に表示されるアイコンを設定します。リクエスト内で指定(この設定を上書き)することもできます。 |
| Preview Message  | 投稿のプレビューです。 |

# 外部からの投稿
まずはシンプルな内容を投稿してみます。ここではcurlコマンドを使ってリクエストを送信します。
リクエストのBodyで指定するパラメータは[payload]で、payloadの値としてJSON形式で投稿内容を指定します。Payload内で必須となるパラメータは投稿メッセージ本体(text)のみです。

``` sh
$ curl -X POST --data-urlencode 'payload={"text": "テスト投稿です。"}' https://hooks.slack.com/services/*********/*********/************************
```

以下のように投稿されます。投稿先のチャンネルと名前、アイコンは設定ページで指定した値になります。

![06.post1.png](https://qiita-image-store.s3.amazonaws.com/0/171575/c181a877-8935-9655-4bda-833b20c2ce95.png)


次にリクエストを少しカスタマイズしてみます。具体的には、先ほどとは異なるチャンネル(channel)、名前(username)、アイコン(icon_emoji)で投稿してみます。

```sh
$ curl -X POST --data-urlencode 'payload={"channel": "#wh-customize-test", "username": "naokichi-dummy", "text": "投稿先、名前、アイコンを変更してみました。", "icon_emoji": ":ghost:"}' https://hooks.slack.com/services/*********/*********/************************
```

![07.post2.png](https://qiita-image-store.s3.amazonaws.com/0/171575/0e6813a9-a439-8173-880b-87b2194d7943.png)

ここでアイコンは `:ghost:` という名前を指定していますが、これはSlackに登録されているアイコンの名前です。好きなアイコンを使いたい場合は、Slack管理画面からアイコンを登録してその名前を指定します。

これ以外にもリンクを追加したり色を変えたり、他のメッセージを参照するなど投稿をカスタマイズすることができます。詳細は設定画面内の例を参照してください。

# 注意事項
外部に公開するWebhook URLにはアクセス制限をかけることができません。従ってURLが漏洩すると誰でも投稿できますので、URLを公開リポジトリのソースコードには含めないなどWebhook URLの管理にはくれぐれもご注意ください。