OmniAICreator/Qiita-1.07M huggingface dataset:
PythonでPandocのフィルターを書く

# PythonでPandocのフィルターを書く
私は汎用ドキュメントフォーマット変換ツール[pandoc](http://pandoc.org/)を愛用している。Pandocについて詳しくは[日本語版ユーザーズガイド](http://sky-y.github.io/site-pandoc-jp/users-guide/)などを参照されたい。

ところが、場合によっては変換時に微妙にドキュメントに手を加えたいことがある。例えば、マークダウンで書いたドキュメントをHTMLに変換する際リンクのURLを一斉に置換したいかもしれない。
正規表現で変換するのが簡単だが、実はpandocにはフィルター機能が提供されている。フィルターを使えば、パースされたドキュメントのシンタックスツリーを利用できる。フィルターはpandoc本体と同様にHaskellで書くこともできるが、仕組み的には何言語でも書くことができ、Pythonも公式でサポートされている。

- [Scripting with pandoc](http://pandoc.org/scripting.html)
- [https://github.com/jgm/pandocfilters](https://github.com/jgm/pandocfilters)

以下のようにpandocがパースしたドキュメントの構文木をJSONフォーマットに変換し、標準入出力を介してフィルターに渡す仕組みだ(図はマニュアルより)。

```
                         source format
                              ↓
                           (pandoc)
                              ↓
                      JSON-formatted AST
                              ↓
                           (filter)
                              ↓
                      JSON-formatted AST
                              ↓
                           (pandoc)
                              ↓
                        target format
```

これを使えばインテリジェントなフィルターを書くことができる。まず、公式で提供されているpandocfiltersをインストールしよう。

```
pip install pandocfilters
```

これを使って早速ドキュメント中のリンクURLを変更するフィルターを書こう。

```py:convertlink.py
from pandocfilters import toJSONFilter, Link


def myfilter(key, value, format_, meta):
    if key == 'Link':
        value[1][0] = "prefix/" + value[1][0]
        return Link(*value)


if __name__ == "__main__":
    toJSONFilter(myfilter)
```

実行するには、pandoc実行時にfilterオプションを指定する。カレントディレクトリのスクリプトを指定するには、"./convertlink.py"と書かなければならないので気をつけて。

```sample.txt
## sample document
text text text

[link](path/to/otherpage)
```

```shell-session
$ pandoc --filter=./convertlink.py -t markdown sample.txt
sample document
---------------

text text text

[link](prefix/path/to/otherpage)
```


## その他のTips
pandocが使用する構文木(pandoc AST)のサンプルはpandocで出力することができる。jsonを指定するとJSON、nativeを指定するとHaskellフォーマットで確認できる。

```shell-session

$ pandoc -t json sample.txt 
[{"unMeta":{}},[{"t":"Header","c":[2,["sample-document",[],[]],[{"t":"Str","c":"sample"},{"t":"Space","c":[]},{"t":"Str","c":"document"}]]},{"t":"Para","c":[{"t":"Str","c":"text"},{"t":"Space","c":[]},{"t":"Str","c":"text"},{"t":"Space","c":[]},{"t":"Str","c":"text"}]},{"t":"Para","c":[{"t":"Link","c":[[{"t":"Str","c":"link"}],["path/to/otherpage",""]]}]}]]
$ pandoc -t native sample.txt
[Header 2 ("sample-document",[],[]) [Str "sample",Space,Str "document"]
,Para [Str "text",Space,Str "text",Space,Str "text"]
,Para [Link [Str "link"] ("path/to/otherpage","")]]
```

フォーマットの詳細は[Text.Pandoc.Definitionのドキュメント](http://hackage.haskell.org/package/pandoc-types)にある。

またフィルターオプションの指定は以下のコマンドパイプラインと等価なので、デバッグ中はこれを利用できる。

```shell-session

$ pandoc -t json sample.txt | python ./convertlink.py | pandoc -f json -t markdown
```
gnuplotでファイルの一行目をtitleにする

グヌヌプヨッヨで数値計算の結果をアニメーションにする際、
一行目に時間のデータが入っていて、それをタイトルにしたい…したくない？
となった時のメモ。

コマンドラインでheadコマンドをうってその結果をtimeに格納し、
sprintfで適当に整形してtitleにセット。
今回の場合はtimeがsec.で入っているので、hrに直してタイトルにしてます。

```gnuplot
file = (好きなファイル名を入れてね！)
time = system("head -1 " . file)
set title sprintf("%2.2f hrs", time / 3600)
```
EC2(CentOS)上にlaravel開発環境を最速で構築する

PHPの今一番イケてるフレームワーク、laravelをとりあえず動く状態にする方法のメモ。

# ゴール

- laravelが動く状態にする

# 前提条件

- Amazon Linux AMI
- WebサーバとPHPは導入済みとする

webサーバとPHPを導入していない場合は、以下参照。この投稿は以下のもののあと行ったものです。
[EC2にnginx+php(php-fpm socket)環境を最速で構築 - Qiita](http://qiita.com/koni/items/05158e33b4c8aac07b59)

# インストール

## composerの導入

```
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
```

## 必要なモジュールの導入

以下はよくつかわれそうなもののみです。

```
sudo yum -y install php56-mysqlnd php56-devel php56-mbstring php56-mcrypt php56-pdo -y
```

ちなみにlaravelは以下の環境が必須です。
```
PHP >= 5.4
Mcrypt PHP Extension
OpenSSL PHP Extension
Mbstring PHP Extension
Tokenizer PHP Extension
```


## laravelインストーラーの導入

```
composer global require "laravel/installer=~1.1"
chmod +x ~/.composer/vendor/bin/laravel
```

# laravelのディレクトリの作成

コマンド一発でやってくれる

```
composer create-project laravel/laravel hogehoge --prefer-dist
Crafting application...
Generating optimized class loader
Compiling common classes
Application key [xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx] set successfully.
Application ready! Build something amazing.

# ~/.composer/vendor/bin/にPATH通して以下でも可能
$ laravel new hogehoge
```

パーミッションを変更しておきます。

```
chmod 777 hogehoge/storage hogehoge/vendor
```

# Apache/nginxの設定

URLにindex.phpを含まないpretty なURLにする設定のため、以下を追加します。
DocumentRootは、hogehoge/publicになります。

## Apacheの場合

効かない場合は、AllowOverrideの設定をチェック

```hogehoge/public/.htaccess
Options +FollowSymLinks
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
```

## nginx

```/etc/nginx/nginx.conf
location / {
    try_files $uri $uri/ /index.php?$query_string;
}
```

# 表示確認

ルートのURLにアクセスしてみて、以下のようなページが表示されればOKです！

![ss 2015-06-06 18.35.06.png](https://qiita-image-store.s3.amazonaws.com/0/5075/404706e5-62ec-4037-59be-6f1213345c1b.png)




# 参考

http://laravel.com/docs/5.0#install-laravel
puttygenで作成した鍵がGitHubやSSHで利用できない時の対応

SSH用の鍵は、Windows上でPuTTYgenを使ってよく生成しています。
が、先日のこと。ちゃんと正常に生成できたはずなのに、いざGithubに登録しようと思ったら、エラーで弾かれる…。なぜ…。
もしや、SSH用の鍵を生成する際、「SSH1/SSH2」だの「RSA/DAS」だのオプションがあるが、よく分からずデフォルトオプションで生成しちゃってたのが問題？
そういえば過去にもサーバによって使えたり使えなかったりする鍵があったので、これはいい加減に勉強せねば...ってことで、鍵の種類について調査してみました。

いざ調べてみたら、話はそもそもSSHのプロトコルの違いを知ることからだったのです。

# 商用SSH と OpenSSH

* SSH には 商用SSH と OpenSSH の二つの流れがある。

> SSHの発明者(Tatu Ylonen)がある時期に会社（SSH Communications Security）（日本SSH社はここ）を起こして商用SSHを売り出してから、SSHは自由に使えなくなりました。そこで元々の公開されていたSSHをベースに本質は維持しつつ特許に抵触する部分を全部取り払って改良を加えたものがOpenSSHです。ユニックスのFreeBSD用に開発され、他のＯＳにも移植されています。
> 
> 引用元サイト：http://osksn2.hep.sci.osaka-u.ac.jp/~naga/miscellaneous/winssh/winssha-2.html



# SSHプロトコルバージョンによる違い

SSHプロトコルは、バージョン違いにより下記２種類が存在する。

* SSH1
* SSH2

# SSH暗号化方式による違い

SSH暗号化方式にはRSA方式、DSA方式が存在する。
SSHプロトコルバージョンによりサポートしている暗号化方式は異なる。

|SSHプロトコル|サポート暗号化方式|
|:-----------|:------------|
|SSH1|RSA|
|SSH2|RSA, DSA|

※同じRSA方式でもSSH1とSSH2では互換性はない。

# 暗号鍵の記述形式の違い

* SSH1 では統一されている。
* SSH2 では統一されておらず、商用SSHと OpenSSH で違う。加えて、どちらにも互換性のあるPuTTy形式も存在する。
<dl>
<dt>OpenSSH形式</dt>
<dd>OpenSSHのフォーマット。秘密鍵のヘッダーに以下の文字列。  
<code>-----BEGIN RSA PRIVATE KEY-----</code>
</dd>
<dt>SECSH（ssh.com）形式</dt>
<dd>商用SSHのフォーマット。秘密鍵のヘッダーに以下の文字列。  
<code>---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----</code>
</dd>
<dt>PuTTy形式</dt>
<dd>PuTTyのフォーマット。秘密鍵の拡張子はppk(Putty private key）。秘密鍵のヘッダーに以下の文字列。  
<code>PuTTY-User-Key-File-2: ssh-rsa</code>  
PuTTYの使用する形式はPuTTY独自のものだが、OpenSSHや商用SSHと互換性があるように配慮されている。
</dd>

# サービスによって鍵の対応フォーマットが異なる場合がある

> windowsのputtygenで作成した公開鍵をそのままgithubなどのopenssh対応ツールにそのまま使う事ができない。githubの場合はadd keyでエラーになり登録ができない。
そのため一度puttyで作成したキーをssh-keygenで作成したのと同じ状態のopenssh対応版に変更する必要がある。
>
> 引用元サイト：http://to-developer.com/blog/?p=1143

Puttyで生成した鍵は、適宜別フォーマットのものに変換してあげる必要があるってことですね。納得。

# 参考サイト

* http://osksn2.hep.sci.osaka-u.ac.jp/~naga/miscellaneous/winssh/winsshb2.html
* http://d.hatena.ne.jp/machua/20110809/1312899353
WindowsでもOCaml

* [gnupack](http://osdn.jp/projects/gnupack/)を使いました。


* インストールは[apt-cyg](https://github.com/kou1okada/apt-cyg/)から行いました。

1.パッケージを探します。

```
 # apt-cyg find ocaml
................
Searching for installable packages matching ocaml:
emacs-ocaml
ocaml
ocaml-base
ocaml-camlp4
ocaml-compiler-libs
ocaml-gv
```
2.インストールします。

```
# apt-cyg install ocaml
```
3.確認します。

```
# ocaml
        OCaml version 4.01.0
```
ModelのFixtureを任意のテストケースのみ実行する


CakePHPでPHPUnitを使っているときに毎回テストケース実行時にFixtureが実行されると、実行時間が長くなり非効率です。
そこで以下の手順でFixtureを任意のタイミングで実行することが可能です。


##1.autoFixturesプロパティをfalseにする
CakeTestCase::$autoFixturesがtrueになっていると、CakeTestCase::setUpメソッドで毎回Fixtureの読み込みを行うので、これをfalseにします。

```SampleFixture.php
public $autoFixtures = false;
```

##2.Fixtureを読み込みたいタイミングでloadFixturesメソッドを実行
Fixtureを読み込みたいタイミングでテストメソッド内でCakeTestCase::loadFixturesメソッドを実行します。

```SampleFixture.php
function testMethod_任意のタイミングでFixture実行 () {
    $this->loadFixtures('fixtureA', 'fixtureB');
}

```

# 参考
* [テストのテストケースからのフィクスチャの読み込み（ CakePHPの公式サイトより）](http://book.cakephp.org/2.0/ja/development/testing.html#id19)
Node.js gulpでcssをscssに変換

ダウンロードしたwordpressテーマのstyle.cssをscssに変換するために導入してみました。

#gulp-css-scssを使う
わかりやすい名前ですね

#インストール
いつものおまじない


````js
npm install gulp-css-scss
````

#使い方

````
var gulp = require('gulp');
var cssScss = require('gulp-css-scss');
 
gulp.task('css-scss', function() {
  return gulp.src('my-file.css')
    .pipe(cssScss())
    .pipe(gulp.dest('scss'));
});
 
gulp.task('default', ['css-scss']);
````

・・ファイルはできたけど元のcssと変わらないゾ？？
使い方はこれ以外なさそうなのですが・・・
商品テーブルを拡張したテーブルも検索対象にする

- アドオンを作成していることが条件です。「**my_product_extend**」
- 今回の例で利用するテーブル  **cscart_products_ex** ・・・product_idをキーとしてcscart_productsとつながっているテーブル

# init.php
/app/addons/my_product_extend/**init.php**
**/app/functions/fn.catalog.php** で定義されているHOOKポイント「additional_fields_in_search」を利用する。

```php:init.php
fn_register_hooks(
    'additional_fields_in_search'
);
```
※init.phpは、利用するHOOKポイントを宣言します。


# func.php
/app/addons/my_product_extend/**func.php**

```php:func.php

//検索対象追加フィールドを拡張
function fn_my_product_extend_additional_fields_in_search(&$params, &$fields, $sortings, $condition, &$join, $sorting, $group_by, &$tmp, $piece, $having)
{
    $params['pshort'] = 'Y';//ショート説明を含める
    $params['pfull'] = 'Y';//フル説明を含める
    $params['pkeywords'] = 'Y';//METAキーワードを含める
    
    //独自テーブルをJOIN
    if(AREA == 'A'){
        $join .= " LEFT JOIN ?:products_ex AS products_ex ON products_ex.product_id = products.product_id";
    }
    
    ///////////////////以下検索対象とする
    //カタログ番号
    $tmp .= db_quote(" OR products_ex.catelog_no LIKE ?l", '%' . $params['q'] . '%');
    
    //カタログ品名
    $tmp .= db_quote(" OR products_ex.catelog_name LIKE ?l", '%' . $params['q'] . '%');
    
    //メーカー品番
    $tmp .= db_quote(" OR products_ex.maker_item_code LIKE ?l", '%' . $params['q'] . '%');
}
```
※func.phpは、アドオンで利用する関数をまとめて記述します


これだけでショップフロント、管理パネルの検索ロジックを拡張できます。

----

![CS-Cart](http://cs-cart.jp/images/content/features/feature_preview_design_2_ja.png)
CS-CartはPHPとMySQLで書かれたECサイト構築パッケージです。
http://cs-cart.jp/
EC2にnginx+php(php-fpm socket)環境を最速で構築

EC2上インスタンスにnginxとPHP5.6を入れて、PHPの実行環境を最速で作成する方法です。

# ゴール

- Amazon Linux AMIの標準リポジトリのnginxとphp5.6, php-fpm環境を構築します
- ブラウザからPHPスクリプトにアクセスできる状態になります
- nginxとphp-fpm間のやりとりをUnixドメインソケットに変更します
- ドキュメントルートは、`/var/www/default`にします

# EC2 インスタンスを起動

Amazon Linux AMI 2015.03 (HVM), SSD Volume Type でインスタンスを建てる。普通に立てればOK。
最後に外から見えるかみたい人は、Elastic-IPかパブリックIPを振り、セキュリティグループの設定でTCP80番を開けておきます。

# インストール

nginx, php56 , php56-fpmをインストール

```
sudo yum install nginx -y
sudo yum install php56 php56-fpm -y
```

## 設定ファイルの変更

まずはnginxの設定ファイルの変更から。

```diff:/etc/nginx/nginx.conf

+ server_tokens off;

  http {
-   index index.html index.htm;
+   index index.php
      server {
-       root /usr/share/nginx/html; 
+       root /var/www/default;

-       #location ~ \.php$ {
-       #    root           html;
-       #    fastcgi_pass   127.0.0.1:9000;
-       #    fastcgi_index  index.php;
-       #    fastcgi_param  SCRIPT_FILENAME/scripts$fastcgi_script_name;
-       #    include        fastcgi_params;
-       #}
+       location ~ \.php$ {
+       root           /var/www/default;
+       fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
+       fastcgi_index  index.php;
+       fastcgi_param  SCRIPT_FILENAME /var/www/default$fastcgi_script_name;
+       include        fastcgi_params;
+     }
```

次にphp-fpmの設定。

```diff:/etc/php-fpm-5.6.d/www.conf
- user = apache
+ user = nginx

- group = apache
+ group = nginx

-   listen = 127.0.0.1:9000
+   listen =  /var/run/php-fpm/php-fpm.sock

-   ;listen.owner = nobody
-   ;listen.group = nobody
+   listen.owner = nginx  
+   listen.group = nginx
```

## 起動と自動起動設定

nginx, phpをそれぞれ起動します。

```
sudo service nginx start
sudo chkconfig nginx on
sudo chkconfig --list nginx

sudo service php-fpm start
sudo chkconfig php-fpm on
sudo chkconfig --list php-fpm
```

## 表示確認

```
# 適当なファイル名に変更
echo "<?php phpinfo();" >> /var/www/default/hogehogehoge.php
```

ブラウザから以下にアクセスして、phpinfoが表示されればOKです。
このファイルは確認したらすぐに消しましょう。

```
http://[サーバーのIPアドレス]/hogehogehoge.php
```


## 参考

[AmazonLinuxにnginx+PHP5.6+PHP-fpm+PHP-redis環境を作る - Qiita](http://qiita.com/toshihirock/items/77835f83f679423874ea)
drawWithRectでTail Truncationする（ParagraphではなくRectで）

drawInRect などでStringを描画する場合（UILabelなどでもそうだが）、Paragraphが対象の場合は、指定範囲で途中で切れたStringに自動的に...をつけてくれるTail Truncationにするには、下記のようにlineBreakModeにByTruncatingTailを指定したAttributeを作ればいい。

```swift
let style = NSMutableParagraphStyle()
style.lineBreakMode =.ByTruncatingTail
style.alignment = NSTextAlignment.Left
let stringAttrubute = [
    NSParagraphStyleAttributeName: style
]
```
**しかし、Paragraph は Word Wrapping して同時に描画範囲内で Tail Truncation したい場合どうすればいいのだろう。**

例えば、下の図のような感じにしたい。図の文章のあとにまだ文章は続いているが、draw範囲はそれより小さいのだ。
![fig01.png](https://qiita-image-store.s3.amazonaws.com/0/80250/3ab16bf1-ac7c-ec32-e816-9db15f49955f.png)

ちなみに以下のような指定はエラーになる。

```swift
style.lineBreakMode = .ByTruncatingTail | .ByWordWrapping
```

↓結論
drawWithRect のoptionsの指定に TruncatesLastVisibleLine があるからこれを使えばいいと分かったのでのメモ。
NSMutableParagraphStyle は ByWordWrapping にして、drawWithRect でTruncatesLastVisibleLine 指定。

```swift
let style = NSMutableParagraphStyle()
style.lineBreakMode =.ByWordWrapping
style.alignment = NSTextAlignment.Left
let stringAttrubute = [
    NSParagraphStyleAttributeName: style
]
let sampleText = "このStringは、このように...（略）...するようにしたい。途中で改行がはいるのである。\nどうすればいいのだろう？あ、できた！\nそして、まだまだStringは続く....（略）...."
sampleText.drawWithRect(
    CGRectMake(0,0,800,300), 
    options: .UsesLineFragmentOrigin | .TruncatesLastVisibleLine,
    attributes: stringAttrubute  as [NSObject : AnyObject],
    context: nil)
```

ちなみに、Objective-Cでは下記だけでこれができていた（ような気がする）。

````Objective-C
[sampleText drawInRect:CGRectMake(0,0,800,300)
                       withFont: font
                       lineBreakMode:NSLineBreakByTruncatingTail];
```
勉強会会場を借りるときの確認項目10 ＋α

勉強会の会場を借りるときに確認しておくとよい10項目をまとめました。

これらは主な項目であり、勉強会の内容やスタイルによって追加して確認すべき項目もあるでしょう。

# 確認時のポイント

## 1. とにかく全部

とにかく全部、分かりきってると思うことも確認しましょう。

下見してあったとしても設備の入れ替えや突発的な問題で状況が変わっているかもしれません。

## 2. 詳細まで確認

警備上の手続きや社内ルールなど聞いてみなければ分からないことは多いです。

場合によっては事前に準備すべきことが発生したり、当日早めに会場入りする必要があるかもしれません。

## 3. まとめて質問

思いついたことをポツポツと質問するのは、担当者さんの時間を奪い迷惑をかけるだけです。

テキストでもエクセルでもいいのでまとめて確認してまとめて返答できるように質問しましょう。

# 確認事項10 ＋α

# 1. 定員

- 会場の定員数
- 必要であれば机やテーブルの数

# 2. ネット環境の有無

- 来場者向けに提供可能か
- スピーカー&スタッフのみOKか
- 動画配信したい場合は来場者向けと別回線を使えるか

# 3. 電源

- 電源利用可能か
- 何席分くらいあるか

# 4. 入退場方法

- ゲート等への社員立会有無
- 入館証等の発行・着用有無
- エントランス通行可能時間
- 来場者リストの事前提出有無

※イベント告知で的確に案内を出さなければいけないし、場合によってはエントランス係や受付係を増員する必要が出るかもしれないので入念に確認しましょう。

# 4. 参加費徴収の可否

- 勉強会や懇親会が有料の場合は問題ないか
- 会場で現金払いでもOKか

※有料イベントOKでも会場で現金のやりとりはNGという場合もあるので入念に確認しましょう。

# 5. 自動販売機

- 同フロアまたは建物内に利用可能な自販機はあるか
- 同フロア内なのか別の階なのか
- 移動時の社員立会有無

# 6. 喫煙所

- 同フロアまたは建物内/外に利用可能な喫煙所はあるか
- 詳しい位置
- 移動時の社員立会有無

※屋外に喫煙所があって、途中退場できない建物の場合は入館前に済ませるよう案内を出す必要があります。

# 7. 飲食

- 会場内での飲食可否
- 飲み物のみOKか
- 持ち込み禁止で社内自販機利用はOKか
- 途中でのケータリング搬入OKか
- アルコールOKか

※懇親会を会場でする場合などは提供予定の内容を詳細に伝えて問題ないか確認しましょう。「ビール飲みながらワイワイやりましょー！」とか告知しといて後でNGでしたってのはあまりに残念過ぎるので。

# 8. マイク

- マイク使用可否
- 種類と数

※事前に言っておかないと当日「え？マイク使うの？今日扱える人いないよー」なんてことになりかねないのできちんと確認しましょう。

# 9. プロジェクター

- プロジェクターの解像度
- 接続端子の種類
- 借りられるコネクターの種類

# 10. 音声出力

- 登壇者PCからの音声出力可否

※当日になって登壇者が会場スピーカーから音を出したいと言い出すことがたまにあるので一応確認しておきましょう。

# ＋α. 会場説明

- 冒頭に会場説明してもらえるか
- 会場提供企業がどんな会社か簡単な案内をしてもらえるか

※せっかく会場提供してくれる会社さんのことも来場者に知ってもらいましょう。
OS X でパスワードで保護されたzipアーカイブを作る

思ったよりも作らなければならない機会の多い "パスワード付きzipアーカイブ" の作り方の話です。

思ったより作らなければならない機会が多いので、そろそろコンテクストメニューからできる様になって欲しいです。パスワード付きzipの展開はダブルクリックでできるだけでも随分ありがたいんですけどね。

# 作り方

GUI では出来ませんが、 OSX でも CLI なら標準の zip コマンドで、パスワード付きアーカイブを作ることが出来ます。

```shell-session
zip -e -r out.zip src_directory
Enter password:
Verify password:
```

# オプション

* ```-e``` オプションは ```--encrypt``` で、パスワードを設定します
* ```-r``` オプションは ```--recurse-paths``` で、ディレクトリを再帰的に処理します。

# 備考

直接関係無いですが ```-r``` オプションを付けずにディレクトリを圧縮すると、エラーは出ず空のディレクトリがアーカイブされるだけになってしまうので注意が必要です。
オリジナルデザインのツイートボタンから、ツイート完了したイベントを取得する

SNSへの投稿ボタンを設置することはよくあるが、ユーザーがちゃんと投稿してくれたかどうかをどう確認する方法はあるのか。
twitterについて調べてみた結果を報告する。

#twitterのJavaScript APIでコールバックイベント取得する

https://dev.twitter.com/web/javascript/events

```js
window.twttr = (function (d,s,id) {
  var t, js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return; js=d.createElement(s); js.id=id;
  js.src="//platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs);
  return window.twttr || (t = { _e: [], ready: function(f){ t._e.push(f) } });
}(document, "script", "twitter-wjs"));

twttr.ready(function (twttr) {
  twttr.events.bind('tweet',function(){
    //ここにツイート完了時の処理を書く
  });
});
```
これでツイート完了時のイベントを取得して関数を実行することができる。

ただし、公式ウィジェットである[ツイートボタン](https://about.twitter.com/ja/resources/buttons)からのツイートが想定されているようである。
オリジナルデザインのボタンからツイートをさせたい場合でも、ツイート完了のイベント取ることはできるのか。

## window.open()で開いたintentはコールバックイベントを取得できない
キャンペーンサイトなどでは公式のツイートボタンではなく、よくこんな感じボタンを実装すると思う。

```html
<a href="javascript:void(0);" id="tweetBtn">
 <img src="/images/tweet_button.png" alt="オリジナルデザインのツイートボタン">
</a>
<script>
$('#tweetBtn').on('click', function(e){
  e.preventDefault();
  var url = 'https://twitter.com/intent/tweet?text=' + encodeURLComponent('ツイートテスト');
  window.open(url, '_blank');
});
</script>
```
実はこの方法では、ツイート完了時のイベントは取得できない。
公式フォーラム上の投稿で、twitterのスタッフが回答している。
[window.open()からintentのコールバックを取得する方法](https://twittercommunity.com/t/get-web-intent-callback-from-a-window-open-call/20881)

ここはハマりポイントだが、実は単純にブラウザネイティブの``target="_blank"``で新しいウインドウを開いてやった場合は、コールバックイベントを取得できる。

```js
$('#tweetBtn').on('click', function(e){
  var url = 'https://twitter.com/intent/tweet?text=' + encodeURLComponent('ツイートテスト');
  $(this).attr(href, url);
  return true;
});
```

**だが、しかし**

## IEではイベントを取得できない

Chrome, Firefox, Safariでは、上記のやり方でツイート完了後のイベントを取得できた。
しかし、IEではイベント取得できない。公式ウィジェットのツイートボタンでもダメであった。

どういうことだと、先ほどのtwitterの公式ドキュメント（[Scripts:Event](https://dev.twitter.com/web/javascript/events)）を見ると、

> Note that Web Intent events may not function fully in browsers that don’t support the browser postMessage API.
> 訳：Web Intent イベントはpostMessage APIをサポートしていないブラウザでは十全には機能しないおそれがありますのでご注意ください

あれ、IEは8からpostMessageをサポートしているはずだったけど・・・
http://caniuse.com/#feat=x-doc-messaging
どうも、partial supportedすなわち部分的サポートであるらしい。それがためにIntentのイベントも取得できないのかもしれない。
それにしても、11でもまだ正式サポートではないようだ・・・相変わらず何をやっているのか。

# 結論
**IEではツイート完了を確認できない**
したがって、全ユーザーで同じ挙動を期待する場合は使えない。（確実にツイートをした場合にだけ、見返りを提供したいなど）
ただ、参考程度にちゃんとツイート確認しているのか計測したいだけなら、実装してもよいだろう。



###所感
SNSでシェアしてくれたら見返りをあげるという仕組みでもって、より多くのユーザーに広告したいという意図からすると、ユーザーがSNSに投稿したのかを確認したいという要望は理解できる。
ただ、正直なところ、報酬で釣って拡散を期待するサプライヤーも報酬欲しさに広告を撒き散らすユーザーも、私はどちらも好きではない。自分が本当に素敵だと感じるモノを、見返りなどなくてもシェアしたいと思うのモノを、シェアすればいい。
売りたい者とタダで欲しい者、内発性ではなく実利に駆動された者たちが跋扈するソーシャルはつまらない。
AtomでローカルのPackageをインストールする方法

# こんなときに必要になります
例えば、自作のPackageをUpdateするために、ローカルで開発中のものをインストールしたいとき。

# 方法
`apm link hoge`
hogeはインストールしたいPackageのディレクトリへのパスを指定してください。

同名のpackageがすでにインストールされている場合は、先にそちらをアンインストールする必要があります。

# よくわかってないこと
`apm link`には`--dev`というオプションがあり、開発中はそっちを使ったほうがよさそうな雰囲気。けど、同名のpackageがdevでない方にインストールされている場合、いい感じにdevの方を優先実行する仕組みがあるのかよくわかんない。

dev modeだといけるっぽい？
https://discuss.atom.io/t/load-developing-package/2554
Ethereum Dapp フレームワーク Embark のインストールと使い方

以下に移行しました<br><a href="http://block-chain.jp/tech/ethereum-dapp-embark/" title="Ethereum Dapp フレームワーク Embark のインストールと使い方">Ethereum Dapp フレームワーク Embark のインストールと使い方</a>
Rust Iterator Cheat Sheet

https://danielkeep.github.io/itercheat_baked.html

>  This summarises the iterator-related methods defined by the following Rust libraries:
>
> - Std: the Rust standard library. Methods are defined on the [`std::iter::Iterator`](http://doc.rust-lang.org/std/iter/trait.Iterator.html) trait.
> - IT: the [`itertools`](https://crates.io/crates/itertools) library. Methods are defined on the [`itertools::Itertools`](https://bluss.github.io/rust-itertools/doc/itertools/trait.Itertools.html) trait.
vagrant up周りで失敗して解決したまとめ



### vagrant upした時にでたログその1

```

...
GuestAdditions versions on your host (4.3.26) and guest (4.3.6) do not match.
...
yum install kernel-devel-2.6.32-431.3.1.el6.x86_64

Building the main Guest Additions module[FAILED]
(Look at /var/log/vboxadd-install.log to find out what went wrong)
...

```

### kernel-develをインストールしたりアップデートする

参考記事

[Vagrantでフォルダがmountできないエラーが出たときの対応](http://qiita.com/kazu69/items/812b236e84fee1db3900)

[Vagrant で CentOS 6.5 を使っていたら Guest Additions の更新に失敗してハマった](http://qiita.com/a-suenami/items/3b04151ce6e7d5b72a3e)

---

### その2

```
Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant /vagrant
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant /vagrant

The error output from the last command was:

/sbin/mount.vboxsf: mounting failed with the error: No such device
```

### GuestAdditionsをインストールしたり再ビルドしたりする

参考記事

[Failed to mount folders in Linux guest. This is usually because the "vboxsf" file system is not available.を直す方法](http://qiita.com/DQNEO/items/2375dd8002a831268cb5)
数値をうずまき状に配置する


以下のように、数値をうずまき状に並べるプログラムです。

```
25 10 11 12 13
24  9  2  3 14
23  8  1  4 15
22  7  6  5 16
21 20 19 18 17
```

## 作成方針

1 を中央に配置して、そのまわりをぐるっと 1 周して数値を配置するようにしました。

```
はじめに中央に 1 を配置します。

1

↓ 次に、1 の上に 1 歩進みます。

2
1

↓ 時計回りにぐるっと 1 周します。

2 3
1

↓ 下に進む

2 3
1 4
  5

↓ 左に進む

  2 3
  1 4
7 6 5

↓ 上に進む

9 2 3
8 1 4
7 6 5
```

上記のステップを、指定のサイズ分まで繰り返します。

## プログラム

Python スクリプトです。

```python:spiral.py
# coding: utf-8

import itertools

# うずまき状に数値を配置する
#
# 例)
# 10 11 12 13
#  9  2  3 14
#  8  1  4 15
#  7  6  5

def spiral(n):
    N = (-1,  0)
    E = ( 0,  1)
    S = ( 1,  0)
    W = ( 0, -1)

    def advance(p, d):
        return p[0] + d[0], p[1] + d[1]

    path = [(0, 0)]
    for size in itertools.count(3, 2):
        if len(path) >= n: break

        p = path[-1]
        p = advance(path[-1], N) # 上に 1 歩進む
        path.append(p)

        # 時計まわりにぐるっと 1 周する
        for d in [E, S, W, N]:
            step = size-2 if d == E else size-1
            for _ in range(step):
                p = advance(p, d)
                path.append(p)

    display(path[:n])

def display(path):
    m = { path[i] : i+1 for i in range(len(path)) }
    rs = [p[0] for p in m]
    cs = [p[1] for p in m]

    minrow, maxrow = min(rs), max(rs)
    mincol, maxcol = min(cs), max(cs)
    fmt = '%%%ds' % len(str(len(path)))
    for r in range(minrow, maxrow+1):
        for c in range(mincol, maxcol+1):
            if c > mincol:
                print(' ', end='')
            x = m[r, c] if (r, c) in m else ' '
            print(fmt % x, end='')
        print()

def main():
    while True:
        s = input("size> ")
        spiral(int(s))

if __name__ == '__main__':
    main()

```

## 実行結果

実行結果です。`size>` はプロンプトです。数値を指定すると、その数だけうずまき状に配置します。

```
size> 9
9 2 3
8 1 4
7 6 5
size> 25
25 10 11 12 13
24  9  2  3 14
23  8  1  4 15
22  7  6  5 16
21 20 19 18 17
size> 38
26 27 28 29 30 31
25 10 11 12 13 32
24  9  2  3 14 33
23  8  1  4 15 34
22  7  6  5 16 35
21 20 19 18 17 36
            38 37
```

## 環境

- OS X 10.10.3
- Python 3.4.0

## 追記

@trsqxyz さんが書き直してくださいました。

- https://gist.github.com/trsqxyz/7809b6ca667f120b9838
Raspberry Pi で Dartを動かす

DartをRaspberry Pi用にビルドしていきます。

### 1 必要な物をもってくる

DartのビルドにはDartSDKのコードとRaspberry Piのクロスコンパイル用ツールが必要です。

```bash
mkdir dart4raspi
cd dart4raspi

#gclientのインストール
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=`pwd`/depot_tools:"$PATH"

#Dart SDKを持ってくる
gclient config https://github.com/dart-lang/sdk.git
gclient sync

#Raspberry Piのtoolsを持ってくる
git clone https://github.com/raspberrypi/tools.git
```

### 2 Dartをビルド

```bash
cd sdk
#build開始
./tools/build.py -m release -a arm \
 --toolchain=../tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian(-x64)/bin/arm-linux-gnueabihf \
  create_sdk
```

-x64 オプションは64bitのマシンでビルドする場合付けてください。

時間がかかりますので、気長に待ちましょう。ついでに自分の環境用のdart-sdkもビルドしてくれます。
ちなみに僕の場合、マシンのスペックの問題もあるのでしょうが二時間ほどかかりました。

### 3 sdkをRaspberry Piに送る

```bash
scp -r out/ReleaseXARM/dart-sdk pi@[raspberry pi ip address]:./dart-sdk
```

### 4 パスを通す

```bash
# on raspberry Pi
export PATH=`pwd`/dart-sdk/bin:"$PATH"
```

これでraspberry piでDartが使えるようになります。

ちなみに、Raspberry PiにあるGPIOを使うためには管理者権限で実行しなければいけないため、symlinksを貼っておいたほうが何かと便利だと思います。

```bash
sudo ln -s /path/to/your/dart-sdk/bin/* /usr/bin/
```

ちなみにエミュレーターを使うこともできます。その他の詳しい方法などが知りたい方は下のリンクを参照してください。

### 参考

---

[Building Dart SDK for Raspberry Pi · dart-lang/sdk Wiki](https://github.com/dart-lang/sdk/wiki/Building-Dart-SDK-for-Raspberry-Pi)
robeでRailsの補完が働かない


環境: emacs, auto-complete, robe

## 結論 事前にinf-rubyを実行しない

導入の際に参考にしたページでは

* M-x inf-ruby
* M-x robe-start

の順でrobeを実行していた。

単純にM-x robe-startだけを実行するとenvirionmentを聞かれて、そのままRailsとプロジェクト内要素の補完ができた。
SSLのkey/certificationが正しいPairか調べる(verifyする）

Nginx にSSLを設定していて、以下のようなエラーにぶつかった。

```
SSL_CTX_use_PrivateKey_file(" ... /www.example.com.key") failed
   (SSL: error:0B080074:x509 certificate routines:
    X509_check_private_key:key values mismatch)
```

Private keyで、Certification(証明書）が読み込めない様子。
CertificationとKeyの一致をNginxの設定と切り離して検証するために、OpenSSLコマンドを使って検証する方法.

(ネットで検索しただけです)


a. まず、Keyを検証

```
$openssl rsa -in /key/path/name.key -modulus -noout | openssl md5
(stdin)= 値1
```

b. Certificationを検証

```
openssl x509 -in /crt/path/name.crt -modulus -noout | openssl md5
(stdin)= 値2
```

値１ と　値2 が一致していれば、オッケ一です。


参照
https://support.f5.com/kb/en-us/solutions/public/6000/700/sol6746.html
Android SDK を Intellij で動かしてみる

日々の開発は Intellij IDEA を使っているので、Android Studioを使うのではなく、IntellijでAndroidの開発を行おうと思ったので、SDKを入れてみた。

---

それぞれのバージョン

* OS: MAC OS Yosemite
* Intellij IDEA: ver.14  
* Android Sdk: android-sdk_r24.2 2015/6/6 時点の最新<br>
  [Download Android Studio and SDK Tools | Android Developers](https://developer.android.com/sdk/index.html#Other)

1. Android SDKをダウンロード
---
 以下のリンクから、Android SDK だけを　OS を選んでDownloadする。
 Downloadしたら、開封して、適当な箇所においておく。
[Download Android Studio and SDK Tools | Android Developers](https://developer.android.com/sdk/index.html#Other)
![スクリーンショット 2015-06-06 11.57.43.png](https://qiita-image-store.s3.amazonaws.com/0/34345/c00bb038-4466-7219-ae71-198fc56c0f50.png)

2. Intellij IDEA にSDKを登録する
---
 Intellijの *Default Project Structure* -> *Platform Settings* -> *SDKs* を選択する。
新規SDKを登録するので **+ボタンを押す** 。
 ![スクリーンショット 2015-06-06 12.00.43.png](https://qiita-image-store.s3.amazonaws.com/0/34345/399e272c-1812-2eaf-4f17-f8a2ae06158f.png)

すると、SDKの種類を聞かれるので *Android SDK* を選択する。
![スクリーンショット 2015-06-06 12.04.14.png](https://qiita-image-store.s3.amazonaws.com/0/34345/8f28d68a-c1a8-a63f-d906-027674a6fe4c.png)

追加すると、 *Create New Android SDK* とでるので Build targetを *Android 5.1.1* を選択する。
![スクリーンショット 2015-06-06 12.09.13.png](https://qiita-image-store.s3.amazonaws.com/0/34345/1a1153b2-d8b3-aabb-8dda-5c3b83d8a51f.png)
ここでは、別に *Google APIs* を選択しても問題はない。
Google APIs には Android API が含まれている。Google Mapとか使う予定がなければ、Android APIでいいんじゃないかな（?）

選択すると、自動的に追加されるので、*Apply* を押して *OK* を選択する。
次に追加するSDKのデータの場所を聞かれるので、1.で開封したディレクトリを選択する。

この時に*Android SDK Manager*が起動して、いろいろなもののインストールを促されるので、従うがままインストールをする。

3. 新規プロジェクトを作ってみる。
---
あとは、Intellijでいつもどおり新規プロジェクトを作成すれば良い。
1. *Create New Project*を選択する。
2. 次に作成するModuleを聞かれるので、*Application Module*を選択する。
 ![スクリーンショット 2015-06-06 12.20.28.png](https://qiita-image-store.s3.amazonaws.com/0/34345/c2ce7d1b-6487-19df-1fb0-3be05769ec45.png)
3. あとは、ディレクトリとか、Applicaiton nameとかを選択して*Finish*を押す。
4. Projectのひな形が作成される。



4. 作成してできたら基本的にOKなはず！
---
問題なくBuildできるかを確認してみる。
1. BuildするModuleを登録するので、*Edit Configureations* を選択する。
![スクリーンショット 2015-06-06 12.24.40.png](https://qiita-image-store.s3.amazonaws.com/0/34345/8d10ad90-d48b-8826-8dd8-2c623acd6ab8.png)

2. 右上の**+ボタン**から*Android Application*を選択する。
![スクリーンショット 2015-06-06 12.24.57.png](https://qiita-image-store.s3.amazonaws.com/0/34345/005aa13c-c338-2cd8-cef4-ac749449b80e.png)

3. 新しく設定ができるので、**Name**を適当につけて、**Module**を今回作成したプロジェクトを選択する。選択したら、ApplyしてOKを押せば設定が完了する。
![スクリーンショット 2015-06-06 12.25.18.png](https://qiita-image-store.s3.amazonaws.com/0/34345/90c24284-f1c9-98f6-ac3b-a3b2219f4cfc.png)

4. あとは、Runを実行させて、Emulaterなどの選択を求められたら、Buildは問題なく実行されているはず！Android Emulaterなり、Genymotionを使ったりして、表示させて完了！
![スクリーンショット 2015-06-06 12.33.26.png](https://qiita-image-store.s3.amazonaws.com/0/34345/fad04872-9a04-a6a5-47d3-ef918a6ffa0e.png)

以上になります。
おつかれしたー。
プロの力が身につく iPhone/iPad アプリケーション開発の教科書 (Swift対応版)


この参考書は、プログラミングの経験はあるが、アプリ開発は未経験という人をターゲットとしているということですが、むしろ少しはアプリ開発の経験がある人が、
* テーブルビューやコレクションビューをきちんと使えるようにする
* イベント処理をしっかり理解する
* UserDefaultだけでなくデータ処理をもっと使えるようになる
* マルチスレッドなどを使えるようになる

といった一歩さらに理解を深めるのに適しているように思います。特に In-App Purchase を少しながらでも説明した少ない参考書です。（少なくともSwift での In-App Purchase を解説したものははじめてだと思います）

最初にObjective-C とSwift を対比しながら文法を説明してありますが、これはとてもわかりやすく、特にSwift の特徴を知る上で役に立ちます。またそれほどのページ数をさいているわけでは内ですが、的確にポイントを説明されています。
それぞれの単元でサンプルをベースにして説明されていますが、単にサンプルを説明するだけでなく、たとえばイベントの処理の順序やメソッドの呼び出しのプロセスなどを図示してあり、動作をきちんと理解するのに役立ちます。若干図示に偏りすぎて説明不足なところもありますが、むしろ多少プログラミングガイドやレファレンスを読んでいるとこの図で理解が明確になります。

一方でターゲットをiPhoe アプリ未経験者にしているため、サンプルの説明ではXCode でのStoryboard の設定の図示にページを多く割いていてくどい感じです。書籍としての販売を考えるとどうしてもアプリ開発未経験者をターゲットにしたいところでしょうが、説明されている内容はアプリ未経験だと少し難しい内容が多いので、できればターゲットをアプリ経験者としてstoryboard の設定などはず１つで済ませて、より深くあるいは多くの技術を解説して欲しいと感じました。

それでもあまりに初心者に的を絞ったSwift の参考書が多い中で、「詳解 Swift」や「開発のプロが教えるSwift標準ガイドブック」と並んでSwift での開発を進める上でとても役に立つ１冊だと感じました。

![IMG_0281.jpg](https://qiita-image-store.s3.amazonaws.com/0/60473/a8df2e02-f624-e3b0-5264-9272ae7a0b90.jpeg "IMG_0281.jpg")
Swiftで無料iOS/Android/.NET開発ができる新IDE Fireと新SwiftコンパイラSilver

SwiftとKotlinについて調べていて、Youそんなに似てるんなら相互コンパイラや変換環境作っちゃいなよ（俺が作るとは言ってない）、と思ってそんなの作ってる人いないか探してたら、表題のようなものを見つけてしまいました。

Swiftを、Java（JVM）や.NETの上で動くようにコンパイルする無料コンパイラ、Silver
http://elementscompiler.com/elements/silver/

Silverで無料開発Android/iOS/.NET開発できる他、有料だとc#/Oxygenでの開発もできるIDE、Fire
http://elementscompiler.com/elements/fire/

まだβ版で、2015後半での正式版公開を目指しているようですが、とりあえず今でも最低限のものは動くようです。

![iOS、Android両方のプロジェクトを含んだソリューション](https://qiita-image-store.s3.amazonaws.com/0/10108/8a3795fe-c667-9b84-6418-c4ac609d1403.png)
iOS、Android両方のプロジェクトを含んだソリューション

![iOSでの実行結果](https://qiita-image-store.s3.amazonaws.com/0/10108/15daad57-2b23-82bc-9b4a-db75d656d9eb.png)
iOSでの実行結果、デバグコンソール

![Androidでの実行結果](https://qiita-image-store.s3.amazonaws.com/0/10108/9703787a-176a-357f-d261-37a8a34d30d4.png)
Androidでの実行結果、デバグコンソール。なんかiOSと違う表示、不安をそそるエラー表示っぽいのが嫌な感じ

とりあえず実行してみて思ったのは、コンパイルが速い！
最低限のビューだけのアプリですし、最終コンパイルはiOS SDKやAndroid SDK使ってるわけですから、それより速いわけは原理的にないのですが、それでも一瞬という印象を受けます。
Xamarinの遅いコンパイルに慣れた身には、すごいと感じました。

が、その他のところはやはりまだまだβクオリティのようです。

* 「最近開いたファイル」が、メニューには出てくるけどスプラッシュスクリーンには出てこない
* 単独プラットフォーム(例：iOS)で作ったソリューションに別プラットフォーム(例：Android)を追加しても、一度ソリューションを閉じないと追加側がコンパイルできない
* マルチプラットフォームソリューションにすると、今現在デバグしているデバイスが画面上に出てこない
* 実機を繋いでも、数分レベルでデバイスリストに上がってこない

などなど、ちょっと触っただけでもアラが目立ちます。
とはいえ、βとして出しているものなので、その辺はレポートを上げていけば、直っていくのでしょう。
XIB/Storyboardや、Androidのデザインxml等はXcodeやAndroid Studioのエディタを積極的に借りていくスタイルのようです。

また、Silverのコンパイルの方も、Apple標準Swiftとの差がこちらに挙げられています。
http://docs.elementscompiler.com/Silver/DifferencesAndLimitations/
現時点でのバグとしての仕様差の他、Silverはマルチプラットフォームを目指しているために、JVMや.NET仕様の側による形で、今後も埋まらない差としての仕様差も挙げられています。
この辺は将来Swiftのライブラリ資産が溜まってきた時に地味に影響してきそうですが、.NET/XamarinでもiOSではAOTであるが故の取り込めない仕様差などがあるわけなので、まあ許容範囲なのかなと思います。

今を時めく言語のSwiftを使って、マルチプラットフォームを実現しようという野心的なプロジェクト、かつSwiftは無料なので、軽くウォッチしておけば、将来化ける可能性もあるかもしれません。

追記：
標準Swiftと差がある仕様だけでなく、上方互換としての機能があるのにも気づきました。
http://docs.elementscompiler.com/Silver/LanguageExtensions/
読んでみると、c#で便利なawait/async系や、マルチキャストイベント、クロスプラットフォーム開発に便利なPartialクラス、等の仕様が加えられているようです。
そのうち、LINQ相当の機能なども、付け加えられるのかもしれません。

追記2：
Swift2やSwiftのOSS化について、対応を[RemObjectsに聞いてみました](http://talk.remobjects.com/t/apple-open-sources-swift-impact-on-silver/6340)。
結果、

* Swift2には対応するよ。というかもう作業始めてるよ
* SwiftのOSS化は、こちらのコンパイラに対するインパクト自体は少ないと思うけど、AppleのSwiftライブラリとの連携などには活かされそう

ということのようです。
Node.jsでFTPを使う

Node.js始めて10日目

Webpackで作成したjsファイルをレンタルサーバーにアップロードしたいと思います。
今回はftpモジュールを使います。

#インストール
いつものおまじない

````
npm install ftp
````

#接続

````js
var Client = require('ftp');
var c = new Client();
c.connect({
    host:"ftp.hoge.com",
    port:21,//portが21の場合は省略可能
    user:"youraccount",
    password:"yourpassword"
})

c.on('ready',function(){
    console.log("ok");
})

c.on('error',function(err){
    console.log(err);
})

c.on('greeting',function(message){
    console.log(message);
})
結果：
成功の場合：FTP server ready
失敗の場合：{ [Error: Login incorrect.] code: 530 }　等。
````

connectメソッドに接続情報をjson形式で渡してあげればOK。
接続成功、失敗についてはイベントで拾う

#FTPコマンドを送る
例えばファイル一覧を取得する例

````js
var Client = require('ftp');
var c = new Client();
c.on('ready', function() {
  c.list(function(err, list) {
    if (err) throw err;
    console.dir(list);
    c.end();
  });
});

c.connect({/*接続情報*/});
````
結果は下記のようにJSON形式で返ってきます

````js
{   type: 'd',
    name: 'web',
    target: undefined,
    sticky: false,
    rights: { user: 'rwx', group: 'rx', other: 'rx' },
    acl: false,
    owner: 'your account',
    group: 'your account group',
    size: 4096,
    date: Tue Feb 03 2015 19:21:00 GMT+0900 (東京 (標準時)) 
} 
````

#リモートディレクトリの階層を移動する

````js
c.on('ready',function(){
  c.cwd('hoge',function(err, currentDir) {
    if (err) throw err;
    c.list(function(err,list){
        console.dir(list);
    })
  });
})

````
ディレクトリ、hogeに移動して、そのディレクトリのリストを表示する例です。
第二引数、`currentDir`は、単にそのディレクトリ名を返すようですが、接続先ftpサーバー次第なようです。私が試したサーバーでは何も返さない(undefined)でした。

#ファイルをダウンロードする
ダウンロードしたデータがstreamで返ってきますので、それをfsで書き込みしてあげるだけです。

````js
var fs = require("fs");

c.get('test.txt', function(err, stream) {
  if (err) throw err;
  stream.once('close', function() { c.end(); });
  stream.pipe(fs.createWriteStream('test.txt'));
});
````
これでカレントディレクトリに指定したファイルがダウンロードされます。
ここでいうカレントディレクトリは、このjsファイルをコマンドラインから実行(`node test`)したときの
カレントディレクトリです

#ファイルをアップロードする

````js

c.on('ready',function(){
  c.put('test.js', 'test.js', function(err)  {
    if (err) throw err;
    c.end();
  });
})

c.connect({/*接続情報*/});

````
これでカレントディレクトリにあるファイルがアップロードされます。
ここでいうカレントディレクトリは、このjsファイルをコマンドラインから実行(`node test`)したときの
カレントディレクトリです


その他のFTPコマンドもだいたい使用できると思います。試してませんんが、セキュアな接続もできるようです。
詳細については[本家ドキュメント(英語）](https://www.npmjs.com/package/ftp)を参照ください。

アップロードするファイルが決まっているのであれば、一つjsファイルを作っておいて
コマンド叩けばアップロードされますから、便利かな。特にwindowsユーザは。
Swift Arrayの拡張


```
/// Array拡張メソッド
extension Array {
    
    /// 指定されたオブジェクトのインデックスを取得
    ///
    /// :param: obj
    /// :returns: みつかった場合インデックス, みつからない場合はnil
    func indexOfObject<T: Equatable>(obj: T) -> Int? {
        if self.count > 0 {
            for (i, objectToCompare) in enumerate(self) {
                let to = objectToCompare as! T
                if obj == to {
                    return i
                }
            }
        }
        
        return nil
    }
    
    /// 指定されたオブジェクトを削除
    ///
    /// :param: obj 削除するオブジェクト
    /// :returns: 指定されたオブジェクトを削除した配列
    mutating func removeObject<T: Equatable>(obj: T) -> Array {
        self = self.filter({$0 as? T != obj})
        return self;
    }
    
}

```
Rails i18n エラーメッセージ 日本語化

良いものを見つけたのでメモ。

```
  errors:
      messages:
        inclusion: "は一覧にありません。"
        exclusion: "は予約されています。"
        invalid: "が不正な値です。"
        confirmation: "が一致しません。"
        accepted: "を承諾してください。"
        empty: "が記入されていません。"
        blank: "が記入されていません。"
        too_long: "は{{count}}文字以内で記入してください。"
        too_short: "は{{count}}文字以上で記入してください。"
        wrong_length: "は{{count}}文字で記入してください。"
        taken: "はすでに使用されています。"
        not_a_number: "は数値で入力してください。"
        greater_than: "は{{count}}より大きい値を指定してください。"
        greater_than_or_equal_to: "は{{count}}以上の値を指定してください。"
        equal_to: "は{{count}}を指定してください。"
        less_than: "は{{count}}より小さい値を指定してください。"
        less_than_or_equal_to: "は{{count}}以下の値を指定してください。"
        odd: "は奇数を指定してください。"
        even: "は偶数を指定してください。"
        # Append your own errors here or at the model/attributes scope.

      models:
        # Overrides default messages

      attributes:
        # Overrides model and default messages.
```

参考
http://www.oiax.jp/rails/asagao_2/error_messages_i18n_1.html
一対一だったのに、一対多に修正があってspecが真っ赤…な時に

http://blog.thefrontiergroup.com.au/2014/12/using-factorygirl-easily-create-complex-data-sets-rails/
こちらを発見し嬉しかった。

`transient`を使うと一時的な引数を作れるので、これに指定をすれば、あとは`after(:create)`などでうまいことできるということだ。ほー。

```rb
FactoryGirl.define do
  factory :book do
    transient do
      read_by nil
      wishlisted_by nil
      # nil is a sensible default, we don't want our factories creating
      # extra data unnecessarily. It slows your test suite down
    end
 
    after(:create) do |book, factory|
      if factory.read_by
        FactoryGirl.create(:user_read_book, book: book, user: factory.read_by)
      end
      if factory.wishlisted_by
        FactoryGirl.create(:wishlist_book, book: book, user: factory.wishlisted_by)
      end
    end
  end
end
```

自分のところは `transient` が通らなくて `ignore` で代用。

https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md
django-compressorでTypeScriptを使う

## 前提

テンプレートはこんな感じ[^1]

```django
{% load compress %}
{% compress js %}
<script type="text/typescript">
class Greeter {
    constructor(public greeting: string) { }
    greet() {
        return "<h1>" + this.greeting + "</h1>";
    }
};
var greeter = new Greeter("Hello, world!");
var str = greeter.greet();
document.body.innerHTML = str;
</script>
{% endcompress %}
```

# ダメだったやりかた

```settings.py
COMPRESS_PRECOMPILED = ('text/typescript', 'tsc --out {outfile} {infile}')
```

エラーが出る

```
error TS6053: File '/tmp/tmpxxt3rmzl.ts' not found.
```

## 理由

tscは拡張子に`.ts`または`.d.ts`しか使用できない。[^2]

# 解決方法

tscをラップしたスクリプトを作ってそれを指定する。

```settings.py
COMPRESS_PRECOMPILED = ('text/typescript', '/path/to/my-tsc {infile} {outfile}')
```

```sh:my-tsc
#!/bin/sh

cp $1 $1.ts
tsc $1 --out $2
rm $1.ts
```

# 参考

- https://github.com/django-compressor/django-compressor/issues/619


[^1]: TypeScriptのコードは[公式のサンプル](https://github.com/Microsoft/TypeScriptSamples/blob/e3959001d3066097cf610d729f9b33e9b49a2634/greeter/greeter.ts)

[^2]: https://github.com/Microsoft/TypeScript/blob/ed7b07dce1e66e56fdc9ca9a8b1f818a9ab92080/src/compiler/core.ts#L705
UIWebViewでタップ動作を拾う方法


```
// UIGestureRecognizerDelegate を指定
class MyViewController: UIViewController, UIGestureRecognizerDelegate

    override func viewDidLoad() {
        super.viewDidLoad()

            let tapGesture = UITapGestureRecognizer(target: self, action: "didTapWebView:")
            tapGesture.numberOfTapsRequired = 1
            tapGesture.delegate = self
            self.webView.addGestureRecognizer(tapGesture)
    }
    
    func gestureRecognizer(
        gestureRecognizer: UIGestureRecognizer, 
        shouldRecognizeSimultaneouslyWithGestureRecognizer
        otherGestureRecognizer: UIGestureRecognizer
    ) -> Bool {
        return true
    }
    
    func didTapWebView(recognizer: UITapGestureRecognizer) {
        println("didTapWebView")
    }

```
Chromeのsvgの中のtextのフォントのコントロールがきかないです


font-family:monospace
と
white-space:pre
に頑張って欲しいのですが、SafariはできるのにChromeがだめです。

![スクリーンショット 2015-06-06 10.50.57.png](https://qiita-image-store.s3.amazonaws.com/0/16626/9b20a59d-379d-0d0a-8ec6-bf1975cc6275.png "スクリーンショット 2015-06-06 10.50.57.png")


https://jsfiddle.net/xk29co5s/4/

```
<svg viewBox="0 0 400 400" style="width:400px">
    <line x1="0" y1="0" x2="400" y2="0" stroke="black" />
    <line x1="0" y1="0" x2="0" y2="400" stroke="black" />

    <g transform="translate(0, 10)">
        <text x="0" y="10">0123456789</text>
        <text x="0" y="30">abcdefghijklmn</text>
    </g>
    <g transform="translate(0, 60)">
        <text x="0" y="10" style="font-family:monospace;">0123456789</text>
        <text x="0" y="30" style="font-family:monospace;">abcdefghijklmn</text>
    </g>
    <g transform="translate(0,110)">
        <text x="0" y="10" font-family="monospace">0123456789</text>
        <text x="0" y="30" font-family="monospace">abcdefghijklmn</text>
    </g>
    <g transform="translate(0,160)">
        <text x="0" y="10" font-family="monospace" white-space="pre">0123456789x</text>
        <text x="0" y="30" font-family="monospace" white-space="pre">01  45  89x</text>
        <text x="0" y="50" font-family="monospace" white-space="pre">  23  67  x</text>
        <text x="0" y="70" font-family="monospace" white-space="pre">          x</text>
    </g>
    <g transform="translate(0,260)">
        <text x="0" y="10" font-family="monospace" style="white-space:pre;">0123456789x</text>
        <text x="0" y="30" font-family="monospace" style="white-space:pre;">01  45  89x</text>
        <text x="0" y="50" font-family="monospace" style="white-space:pre;">  23  67  x</text>
        <text x="0" y="70" font-family="monospace" style="white-space:pre;">          x</text>
    </g>
</svg>

<svg viewBox="0 0 400 800" style="width:400px">
    <line x1="0" y1="0" x2="400" y2="0" stroke="black" />
    <line x1="0" y1="0" x2="0" y2="400" stroke="black" />
    <style>
      text {
        font-family:monospace;
        white-space:pre;          
      }
    </style>
    <g transform="translate(0,10)">
        <text x="0" y="10">abcdefghijklmn</text>
        <text x="0" y="30">0123456789x</text>
        <text x="0" y="50">01  45  89x</text>
        <text x="0" y="70">  23  67  x</text>
        <text x="0" y="90">          x</text>
    </g>
</svg>


```
C++ Makefile 別ディレクトリにオブジェクト出力


####フォルダ構成
```
example
|-- bin
|   `-- example    <- (TARGET) 実行ファイル
|-- include
|   `-- main.h
`-- source
    |-- main.cpp
    |-- makefile
    `-- obj        <- (OBJDIR) 中間ファイル生成先ディレクトリ
        |-- main.d <- (DEPENDS) 依存関係ファイル
        `-- main.o <- (OBJECTS) オブジェクトファイル
```  

####makefile
```
COMPILER = g++
CFLAGS   = -g -Wall -O2
LDFLAGS  =
LIBS     =
INCLUDE  = -I../include
TARGET   = ../bin/example
OBJDIR   = ./obj
SOURCES  = $(wildcard *.cpp)
OBJECTS  = $(addprefix $(OBJDIR)/, $(SOURCES:.cpp=.o))
 
 $(TARGET): $(OBJECTS) $(LIBS)
	$(COMPILER) -o $@ $^ $(LDFLAGS)

$(OBJDIR)/%.o: %.cpp
	@[ -d $(OBJDIR) ]
	$(COMPILER) $(CFLAGS) $(INCLUDE) -o $@ -c $<

all: clean $(TARGET)

clean:
	rm -f $(OBJECTS) $(TARGET)
```
####ポイント
>$(OBJDIR)/%.o: %.cpp 
>@[ -d $(OBJDIR) ]
>$(COMPILER) $(CFLAGS) $(INCLUDE) -o $@ -c $<

1行目 .cpp -> obj/.o に変換して出力するというサフィックスルール
2行目 obj/以下に出力するファイルパス(ファイル名？)を@に設定
3行目 コンパイル

コンパイル時にobj/を含んだファイル名を指定していなくてsrc以下にオブジェクトが出力されてしまって暫くはまった。。。

####参考URL
[シンプルで応用の効くmakefileとその解説](http://urin.github.io/posts/2013/simple-makefile-for-clang/)
Vagrant1.7.2とCentOS7.1がものすごく相性わるい件

Vagrant1.7.2でCentOS7.1 (`chef/centos-7.1`) を使ったらエラーが出まくるという現象に遭遇しました。

# 症状
* vagrant upしたときに、多種多用なエラーが出る
* エラーは出たり出なかったりする。70%くらいの確率で発生する(感覚値)。
* vagrant reloadすると直る

# どんなエラーか？
主に下記2点に絡むものです。

* プライベートネットワークでのIPアドレス割り当て
* vboxsfのマウント失敗

## ネットワーク絡みのエラー

その１

````
The following SSH command responded with a non-zero exit status. 
Vagrant assumes that this means the command failed! 

sed -e '/^#VAGRANT-BEGIN/,/^#VAGRANT-END/ d' /etc/sysconfig/network-scripts/ifcfg-enp0s8 
```

その2

```
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

/sbin/ifdown

Stdout from the command:



Stderr from the command:

usage: ifdown <configuration>
```

その3

```
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

cat /tmp/vagrant-ifcfg- > /etc/sysconfig/network-scripts/ifcfg-

Stdout from the command:



Stderr from the command:

cat: /tmp/vagrant-ifcfg-: No such file or directory
```

## vboxsfがらみ

/vagrantのマウント失敗

```
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

chown `id -u vagrant`:`id -g vagrant` /vagrant

Stdout from the command:



Stderr from the command:

chown: cannot access ‘/vagrant’: No such file or directory
```

"vboxsf" file system is not available

```
localapp: /tmp/vagrant-cache => /Users/DQNEO/.vagrant.d/cache/chef/centos-7.1
Failed to mount folders in Linux guest. This is usually because
the "vboxsf" file system is not available. Please verify that
the guest additions are properly installed in the guest and
can work properly. The command attempted was:

mount -t vboxsf -o uid=`id -u vagrant`,gid=`getent group vagrant | cut -d: -f3` vagrant-cache /tmp/vagrant-cache
mount -t vboxsf -o uid=`id -u vagrant`,gid=`id -g vagrant` vagrant-cache /tmp/vagrant-cache

The error output from the last command was:

/sbin/mount.vboxsf: mounting failed with the error: No such file or directory
```

# CentOS7.0を使えばエラー出なくなった。

どうやら、CentOS7.0 -> CentOS7.1 でNetworkManagerに関して大きな仕様変更があったようです。
ネットワークエラーはそれが原因っぽい。
(vboxsfのエラーと関係あるかは不明)

`chef/centos-7.0`を使うようにしてみたら、嘘のように挙動が安定しました。
しばらくこれで運用してみようと思います。


# 関連Issue

https://github.com/mitchellh/vagrant/issues/5661
https://github.com/mitchellh/vagrant/pull/5709

上記(#5709) のパッチを手動であててみても解決しませんでした。
技術英語 > even up > to even up the spacing of the cards

http://stackoverflow.com/questions/30023515/need-to-design-8-boxes-in-two-rows

> . I have added some padding and margin to <font color=red>even up</font> the spacing of the cards, the nth-child rule is used to apply that to the correct card.
answered May 27 at 14:28 by matthewelsom

evenというと「偶数」という意味でよく使われるが、even upで「均等にする」という意味にもなる。

関連するフレーズとして以下のようなものがある
- evenly distributed : 均等に分布した
- get even : おあいこ
SWI-Prologでスペルミスを推測してくれた話


（対象OS：Windows8、Windows8.1　※Windows7は試していない）

M.Hiroiさんの[お気楽 Prolog プログラミング入門](http://www.geocities.jp/m_hiroi/prolog/)のサンプルを試している中で、筆者が述語名のスペルミスをした時に、SWI-Prologが推測してメッセージを出してくれたので紹介。


手順は以下の通り。

まず、SWI-Prologは以下の手順でインストール。

```ps1:powershell
#PowerShellを管理者にて実行しておく

#chocolateyのインストール
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1'))

#SWI-Prologのインストール
choco install swi-prolog
```



次に、以下の内容をファイルに保存し、ダブルクリックで起動。

```prolog:family.pl
/* 男性 */
male(taro).
male(ichiro).
male(jiro).
male(saburo).

/* 女性 */
female(hanako).
female(tomoko).
female(sachiko).
female(youko).

/* 父親 */
father_of(taro, ichiro).
father_of(taro, jiro).
father_of(taro, tomoko).
father_of(ichiro, saburo).
father_of(ichiro, youko).

/* 母親 */
mother_of(hanako, ichiro).
mother_of(hanako, jiro).
mother_of(hanako, tomoko).
mother_of(sachiko, saburo).
mother_of(sachiko, youko).

parents_of(X,Y):- father_of(X,Y).
parents_of(X,Y):- mother_of(X,Y).

son_of(X,Y) :- parents_of(Y,X),male(X).
```

下のような画面が立ち上がった。
![20150606_swiprolog2.png](https://qiita-image-store.s3.amazonaws.com/0/49502/e1c7294a-6c39-880f-4923-82dc274c03ec.png)

次に、質問を入力したのだが、ここで筆者がスペルミス。
（"son_of"を"san_of"と間違えた）

```prolog
1 ?- san_of(X,hanako).
```

すると、

```prolog
Correct to : "son_of(X,hanako)"?
Please answer 'y' or 'n'?
```

「son_of(X,hanako)に訂正しますか？y(yes)かn(no)か答えて下さい」と怒られた。もちろん答えはyes。

結果、無事スペルミスも訂正されて、答えが導き出された。
![20150606_swiprolog.png](https://qiita-image-store.s3.amazonaws.com/0/49502/aa51fff0-e148-fbbf-886c-1cbb332c06bd.png)


もちろん、noと答えた場合は、エラー。
![20150606_swiprolog3.png](https://qiita-image-store.s3.amazonaws.com/0/49502/5a088da1-1e1e-1838-a7e2-8ebfa2db8275.png)

「san_ofなんてありませんよ。son_ofならありますけどね」だそうで。嫌味な奴だ（笑）

それはともかく、スペルミスのような初歩的なミスに起因する不具合は、ハマる時はかなりハマるので、こういう推測機能が標準で入っているのは嬉しい。
ElectronでjQueryがundefinedになる


ElectronでjQueryがundefinedになる。

```html:index.html
<body>
	<script src="lib/jquery.min.js"></script>
	<script>
		jQuery('#hoge'); // jQuery is not defined
	</script>
</body>
```

## 原因

electronのissueがあった。

[jQuery isn't set globally because "module" is defined · Issue #254 · atom/electron](https://github.com/atom/electron/issues/254)

Electronではブラウザ側のJS実行時に`module.exports`が存在するので、jQueryがcommonJSでロードされたと勘違いして、windowに$とjQueryを定義しないというのが原因。（[この辺りにif文が](https://github.com/jquery/jquery/blob/66e1b6b8d49812239b5712d65922ff94c60f7b02/src/intro.js#L17-L35)）

## 解決策

### requireでロードする

```html
<!--<script src="lib/jquery.js"></script>-->
<script>
window.jQuery = window.$ = require('./lib/jquery');
</script>
```

上記のようにrequireでロードしてwindow.$, window.jQueryに代入する。

### 'node-integration': false

http://electron.atom.io/docs/faq/#i-can-not-use-jqueryrequirejsmeteorangularjs-in-electron

メインプロセス側JSでBrowserWindowをインスタンス化する時のオプションに`'node-integration': false`を追加する。

```js:main-process.js
// In the main process.
const {BrowserWindow} = require('electron')
let win = new BrowserWindow({
  webPreferences: {
    nodeIntegration: false
  }
})
win.show()
```

そうすると、ブラウザ側に`module.exports`が定義されなくなるので、ブラウザ側JSを修正する必要がない。


基本的にはBrowserifyやWebpackなどを使ってCommonJSで開発して、アプリのWebViewみたいにElectron外のWebページを表示させたい場合は`node-integration`オプションを使って制御するのがよさそう。