OmniAICreator/Qiita-1.07M huggingface dataset:
SparkSQLでクエリ検索してみる。（JSON入力編）


## 環境
* Mac OS X Version 10.9.5
* Scala 2.10.4
* Spark 1.1.0
* Spark SQL 1.1.0
* sbt 0.13.1

## 準備

```tree
/root/to/project/path
   |-- build.sbt
   |-- src
   |    |-- main
   |    |    |-- scala
   |    |    |    |-- Stoppable.scala
   |    |-- test
   |    |    |-- scala
   |    |    |    |-- SparkSQLFromJSONSpec.scala
```

```build.sbt
name := "Spark SQL examples"

version := "0.0.1-SNAPSHOT"

scalaVersion := "2.10.4"

scalacOptions ++= Seq("-Xlint", "-deprecation", "-unchecked", "-feature", "-Xelide-below", "ALL")

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % "1.1.0",
  "org.apache.spark" %% "spark-sql" % "1.1.0",
  "org.specs2" %% "specs2" % "2.4.1"
)
```

## 実装
```src/test/scala/SparkSQLFromJSONSpec.scala
import commons._
                                                                                                                                                                                  
import org.apache.spark._
import org.apache.spark.SparkContext._
import org.apache.spark.sql._

import org.specs2._

class SparkSQLFromJSONSpec extends Specification with Stoppable { def is = s2"""

  SparkSQL From JSON

  From JSON
    read from json                         $readFromJSON

  """

  val json = Seq(
    """{"name":"Yin","address":{"city":"Columbus","state":"Ohio"},"datetime":"2014-08-12 19:07:43"}""",
    """{"name":"Mary","address":{"city":"Manhattan","state":"NewYork"},"datetime":"2014-08-14 19:07:43"}""",
    """{"name":"Mike","address":{"city":"Los Angeles","state":"California"},"datetime":"2014-08-11 19:07:43"}"""
  )
  var retReadFromJSON: Seq[String] = _
  using(new SparkContext("local[1]", "SparkSQLFromJSONSpec", System.getenv("SPARK_HOME"))) { sc =>
    val sqlContext = new SQLContext(sc)
    val rdd = sc.parallelize(json)
    val rddSql = sqlContext.jsonRDD(rdd)
    rddSql.registerTempTable("people")
    val ret = sqlContext.sql(
      "SELECT name, address.city  FROM people WHERE name IN ('Yin', 'Mike') AND datetime < '2014-08-14 00:00:00'")
    retReadFromJSON = ret.collect.map { row =>
      "%s, %s".format(row.getString(0), row.getString(1))
    }
  }
  def readFromJSON = retReadFromJSON must_== Seq(
    "Yin, Columbus",
    "Mike, Los Angeles"
  )
}
```

```src/main/scala/Stoppable.scala
package commons                                                                                                                                                                   

import scala.language.reflectiveCalls

trait Stoppable {
  type T = { def stop(): Unit }
  def using[A <: T, B](resource: A)(f: A => B) = try {
    f(resource)
  } finally {
    resource.stop()
  }
}
```

## 実行

```shell
$ sbt '~test-only SparkSQLFromJSONSpec'
```

## 参考

http://spark.apache.org/docs/1.1.0/sql-programming-guide.html#json-datasets
[XCode]キーボードが立ち上がらなくなったときの対処法

アプリをシミュレータで起動し、キーボードが立ち上がらなくなったときの対処法を記します。

1.Simulator画面を選択する。
2.iOS Simulatorからreset connect and Setting を選択し、再度シミュレータを起動するとキーボードが出現する。

[注意]reset connect and Settingを押すと、全てのシミュレータ内にあるデータが消えます。
SparkSQLでクエリ検索してみる。（テキストファイル入力編）


## 環境
* Mac OS X Version 10.9.5
* Scala 2.10.4
* Spark 1.1.0
* Spark SQL 1.1.0
* sbt 0.13.1

## 準備

```tree
/root/to/project/path
   |-- build.sbt
   |-- src
   |    |-- main
   |    |    |-- scala
   |    |    |    |-- Stoppable.scala
   |    |-- test
   |    |    |-- resources
   |    |    |    |-- people.txt
   |    |    |-- scala
   |    |    |    |-- SparkSQLFromFileSpec.scala
```

```build.sbt
name := "Spark SQL From File examples"

version := "0.0.1-SNAPSHOT"

scalaVersion := "2.10.4"

scalacOptions ++= Seq("-Xlint", "-deprecation", "-unchecked", "-feature", "-Xelide-below", "ALL")

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % "1.1.0",
  "org.apache.spark" %% "spark-sql" % "1.1.0",
  "org.specs2" %% "specs2" % "2.4.1"
)
```

```src/test/resources/people.txt
Michael, 29
Andy, 30
Justin, 19
```

## 実装
```src/test/scala/SparkSQLFromFileSpec.scala
import commons._
                                                                                                                                                                                  
import org.apache.spark._
import org.apache.spark.SparkContext._
import org.apache.spark.sql._

import org.specs2._

// you can use custom classes that implement the Product interface.
case class Person(name: String, age: Int)

class SparkSQLFromFileSpec extends Specification with Stoppable { def is = s2"""

  Spark SQL From File

  FromFile
    read from file                          $readFromFile
  """

  var retReadFromFile: Array[String] = _ 
  using(new SparkContext("local[1]", "SparkSQLFromFileSpec", System.getenv("SPARK_HOME"))) { sc =>
    val sqlContext = new SQLContext(sc)
    import sqlContext.createSchemaRDD

    // Create an RDD of Person objects and register it as a table.
    val people = sc.textFile("src/test/resources/people.txt").map(_.split(",")).map(p => Person(p(0), p(1).trim.toInt))
    people.registerTempTable("people")

    // SQL statements can be run by using the sql methods provided by sqlContext.
    val teenagers = sqlContext.sql("SELECT name, age FROM people WHERE age >= 13 AND age <= 19")

    // The results of SQL queries are SchemaRDDs and support all the normal RDD operations.
    // The columns of a row in the result can be accessed by ordinal.
    retReadFromFile = teenagers.map(t => "%s:%d".format(t(0), t(1))).collect  
  }
  def readFromFile = retReadFromFile must_== Array("Justin:19")
}
```

```src/main/scala/Stoppable.scala
package commons                                                                                                                                                                   

import scala.language.reflectiveCalls

trait Stoppable {
  type T = { def stop(): Unit }
  def using[A <: T, B](resource: A)(f: A => B) = try {
    f(resource)
  } finally {
    resource.stop()
  }
}
```

## 実行

```shell
$ sbt '~test-only SparkSQLFromFileSpec'
```

## 参考

http://spark.apache.org/docs/1.1.0/sql-programming-guide.html#inferring-the-schema-using-reflection
Adobe AIR for iOS ソフトキーボードが出現しない原因

Adobe AIR for iOS でのアプリ開発。
入力可能なダイナミックテキストを置いておけば、フォーカスがあたると自動的にソフトキーボードが出現してくれます。

が、テキスト入力欄にフォーカスが当てられず、入力できないという事態が発生したので、メモ。

解決策としては、

```as3
stage.displayState  = StageDisplayState.FULL_SCREEN;
```

というフルスクリーンにするスクリプトが入っていたことが原因でした。
（Flash Player 向けコンテンツをアプリ化していたため。）
この行をコメントアウトすることで解消しました。
transformプロパティを使って要素を上下中央に配置する

今回は上下中央に配置したいものの高さと幅が決まっていますが、この方法であれば文章などの不規則な高さのものも上下中央に配置可能です。

## HTML

```html
<div class="box>
    <img src="dummy.png alt="" width="24" height="24" class="img" >
</div>
```

## CSS

```css
.box {
   position:relative;
   height:300px;
}
.img {
   position: absolute;
   top: 50%;
   left: 50%;
   -webkit-transform: translate(-50%, -50%);
   transform: translate(-50%, -50%);
}
```

`position`と`top`,`left`で50%ずつ移動させ、要素の表示位置をtransformプロパティで調整するやり方です。
CSS3が使えず、今回のように要素の高さと幅が決まっている場合は、ネガティブマージンなどで調整しましょう。
Foursquare APIメモ

自分用メモです。

# 参考資料

developer.foursquare.com
https://developer.foursquare.com/docs/

Foursquare API プラットフォームおよびデータ使用ポリシー
https://ja.foursquare.com/legal/api/platformpolicy

FOURSQUARE LABS, INC. API およびデータライセンス契約
https://ja.foursquare.com/legal/api/licenseagreement

API 開発者のための Foursquare 商標ガイドライン
https://ja.foursquare.com/legal/api/trademarkusage

リソース
https://ja.foursquare.com/about/logos

[foursquare Api] 使ったときの商標表示って、、、
http://cocoamix.jp/archives/2887

foursquare APIでできること #4sqdevjp
http://qiita.com/koogawa/items/df92ec1c7eb750312b77

foursquare API v2 ドキュメント（日本語訳）
http://tdoc.info/foursquare-API/overview.html

foursquare api その１：概要
http://lxyuma.hatenablog.com/entry/20121222/1356166568

ベニューを検索する
http://syncer.jp/foursquare-venues-search

foursquare APIを使いたい人のための日本語リファレンス。
http://syncer.jp/web/api/foursquare-api/

----

# 概要

* すべてのリクエストはJSONまたはJSONPを返すGETかPOST
* リクエストのパラメータはJSONではなく、HTTPのキーバリュー
* 認証はOAuth2、httpsが必須

# API利用回数制限

一時間ごとにリクエスト数で計られる。
基本的にエンドポイント単位ではないことに注意。

例えば、venues/search で2500リクエスト、venues/explore で2500リクエストである場合、venuesのリクエスト回数制限に達してしまうが、tips/* に対するリクエスト回数は500残っていると言える。

取得したデータはアプリケーション側で可能な限りキャッシュして利用した方が良い。

これでも足りないというのであれば、Foursquare に対してAPI利用回数の増加申請を行う事も可能。
https://developer.foursquare.com/overview/ratelimits

## 回数の確認

HTTPヘッダに記載される。

* X-RateLimit-Remaining
* X-RateLimit-Limit

## venues エンドポイント

* **5000リクエスト毎時間**
* Cliend ID/Client Secret（＝登録アプリケーション）単位で計測

## その他のエンドポイント

* **500リクエスト毎時間**

## OAuthトークン

* **500リクエスト毎時間**
* OAuthトークン（＝ユーザ）単位で計測


# APIリクエスト

## URL

OAuthトークンあり

```
https://api.foursquare.com/v2/ENDPOINT/HOGE
?param1=value1
&oauth_token=OAUTH_TOKEN
&v=YYYYMMDD
&m=foursquare
```

認証無し

```
https://api.foursquare.com/v2/ENDPOINT/HOGE
?param1=value1
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&v=YYYYMMDD
&m=foursquare
```

## バージョニング

`v=YYYYMMDD`

https://developer.foursquare.com/overview/versioning

## レスポンス形式（モード）

* Foursquare 形式 `m=foursquare`
* Swarm 形式 `m=swarm`
 * ただし、v >= 20140806 のとき
 * swarm 形式対応のエンドポイントのみ効果がある

例えば users/USER_ID の場合、swarm 形式に対応している。
https://developer.foursquare.com/docs/users/users

https://developer.foursquare.com/overview/versioning

## 多言語対応

HTTPリクエストヘッダに `Accept-Language` を追加する。または `locale=*` でも可。
日本なら `ja`。

未指定の場合、都市名などの地物情報であれば、その地物が属する国で最も使われる言語表記で返される。

# キャッシュとデータの保存期間

Foursquare から得たデータは、APIのリクエスト回数を抑える為にキャッシュすべきだが、永続的に保管することは許されない。

* スポット情報（Tips, Venues およびその写真など）を更新することなく30日を超えて保存することはできない
* ユーザーの未編集のチェックイン情報を更新する事無く24時間を超えて保存することはできない
* クライアント（アプリケーション、Webサイト）を許可していないユーザーの情報を3時間以上保存することは出来ない
* ユーザーのデータ使用についてユーザーに説明し、同意を得なければ、ユーザーのチェックイン履歴の追跡やそこから得たデータを保持することは出来ない
* いかなる場合もデータを30日を超えて保存することは出来ない

IV. 保存
https://ja.foursquare.com/legal/api/platformpolicy

# OAuth

* https://github.com/koogawa/FoursquareOAuth
* https://github.com/foursquare/foursquare-ios-oauth
* https://github.com/foursquare/foursquare-android-oauth
* http://ssdkfk.wordpress.com/2012/08/27/foursquareの認証、api通信をお手軽にやっちゃう%E3%80%82/
* https://github.com/anoopr/core-data-talk/blob/master/example/Classes/FoursquareAuthViewController.m

手っ取り早くWebViewか？
CentOSにMongoDBをインストールして外部から接続できるようにする



まぁ正確にはScientificLinuxなんですけど。

```
cat /etc/redhat-release
Scientific Linux release 6.5 (Carbon)
```


## インストール

```:/etc/yum.repos.d/mongodb.repo
[mongodb]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/
grpcheck=0
enabled=1
```

```shell
yum install mongodb
```


#### 外部からの接続を許可する

```bash:/etc/mongodb.conf
# コメントアウト
#bind_ip=127.0.0.1 

# Webインターフェースを有効化
httpinterface=true
rest=true
```

#### ファイアウォール設定
ポート27017、28017からの接続を許可します。

```bash:iptables.sh
iptables -A INPUT -p tcp --dport 27017 -j ACCEPT
iptables -A INPUT -p tcp --dport 28017 -j ACCEPT
```

#### 最後にサービス再起動

```
service mongod restart
```


手元のPCから接続確認。

```shell
mongo {サーバーのホスト名}:27017
>
```

OK！


同じく、サーバーの28017ポートにアクセスするとWebインターフェースが表示されます。


## 参考

[mongodbでREST APIを使ってみる - RESTを有効にする、iptables変更、使ってみる、まで](http://tweeeety.hateblo.jp/entry/2014/05/29/183716)
SQLserver の簡易的なバックアップ

SQLserverの簡易的なバックアップ（tsvにエクスポート）

メモ
同じディレクトリにtables.txtを作ってバックアップとりたいテーブル名を1行ずつ書く。
環境に合わせてdbServer dbUser dbPassword dbSchema savePathを設定。

```backup.bat
@echo off
rem 日付時間のフォルダを作成しtables.txtに書いてあるテーブルのバックアップ（tsv形式）で取得
set date_tmp=%date:/=%
set time_tmp=%time: =0%
set yyyy=%date_tmp:~0,4%
set mm=%date_tmp:~4,2%
set dd=%date_tmp:~6,2%
set hh=%time_tmp:~0,2%
set mi=%time_tmp:~3,2%
set datetime=%yyyy%%mm%%dd%%hh%%mi%
set time_tmp=
set date_tmp=
 
set dbServer=
set dbUser=
set dbPassword=
set dbSchema=
set savePath=D:\%datetime%
 
mkdir %savePath%
 
for /f "delims=" %%a in (tables.txt) do (
    echo %%a
bcp %dbSchema%.dbo.%%a out %savePath%\%%a.tsv -w -t \t -S %dbServer% -U %dbUser% -P %dbPassword%
)
pause
EC CUBE で環境毎の設定ファイルの書き換えを不要にする

[1]: #

# [/data/config/config.php][1]

* `$_SERVER["SERVER_NAME"]` で判定を行う

```php:ex.
<?php
define('ECCUBE_INSTALL', 'ON');

if (isset($_SERVER["SERVER_NAME"]) == 0) {
	if (strcmp($_SERVER["SERVER_NAME"], "ec-qube.example.com")) {
		// 本番環境および特定環境での実行

		// URL関連
		define('HTTP_URL', 'http://ec-qube.example.com/');
		define('HTTPS_URL', 'https://ec-qube.example.com/');
		define('ADMIN_DIR', 'admin/');
		define('ADMIN_FORCE_SSL', TRUE);

		// DB 関連
		define('DB_SERVER', 'ec-qube.db.example.com');
		define('DB_TYPE', 'mysql');
		define('DB_USER', 'eccube_db');
		define('DB_PASSWORD', 'eccube_db');
		define('DB_NAME', 'eccube_db');
		define('DB_PORT', '');

		// メール関連
		define('SMTP_HOST', '');
		define('SMTP_PORT', '');
		define('SMTP_USER', '');
		define('SMTP_PASSWORD', '');
		define('MAIL_BACKEND', 'mail');

		// 管理画面操作可能 IP 等
		define('ADMIN_ALLOW_HOSTS', 'a:0:{}');
	} else {
		// テスト環境での実行

		// URL関連
		define('HTTP_URL', 'http://' . $_SERVER["SERVER_NAME"] . '/');
		define('HTTPS_URL', 'http://' . $_SERVER["SERVER_NAME"] . '/');
		define('ADMIN_DIR', 'admin/');
		define('ADMIN_FORCE_SSL', FALSE);

		// DB 関連
		define('DB_SERVER', '127.0.0.1');
		define('DB_TYPE', 'mysql');
		define('DB_USER', 'eccube_db');
		define('DB_PASSWORD', 'eccube_db');
		define('DB_NAME', 'eccube_db');
		define('DB_PORT', '');

		// メール関連
		define('SMTP_HOST', '');
		define('SMTP_PORT', '');
		define('SMTP_USER', '');
		define('SMTP_PASSWORD', '');
		define('MAIL_BACKEND', 'mail');

		// 管理画面操作可能 IP 等
		define('ADMIN_ALLOW_HOSTS', 'a:0:{}');
	}
} else {
	// コマンドラインからの実行
	exit(9);
}
define('ROOT_URLPATH', '/');
define('DOMAIN_NAME', '');

define('AUTH_MAGIC', 'leanialogiapriahauepiaphijiatrusodioslea');
define('PASSWORD_HASH_ALGOS', 'sha256');

```
auth_basic_moduleをUnloadしてもbasic認証設定の抑止にならない

検証環境から本番にもっていくときに認証設定消し忘れてたらえらいことになるよという話。
最近本番用サーバのauth_basic_moduleの読み込みを外しているサーバがあり動作が気になったので調べてみた。
（今思えば単なるパフォーマンスチューニングのためにUnloadしていたのかもしれない）
結果的には読み込みを外してもbasic認証用の構文を書くとダイアログが出力されるということが分かった。
ただ厄介なことに、Unloadした状態だと正しいID/PASSを入れてもページが出ないということ。
以下実験内容

* * *

まず、初期環境として
1. httpd.confの`<Directory "/var/www/html">`内にbasic認証の仕掛けを書く
（↑AllowOverrideで許可すれば.htaccessに書いても同じだと思う）
2. auth_basic_moduleをLoadする設定にする

この状態での動作と２．の条件をOFF（Unload）にした状態での動作の結果を以下に記す。

* 初期状態
basic認証用のダイアログが出て、意図通りの認証が出来る

* 2.がOFFの状態
basic認証用のダイアログが**出て**、正しいID/PASSを入れても再度ダイアログが出る


恐らく、basicのダイアログを出す機構はApache（もしくは他のmodule）内にあって、
auth_basic_moduleはIDとPASSのチェックしかしてないんだろう。
後、たなぼた的にわかったことは、LoadModule行の変更（少なくともauth_basic_module）はreloadでもできたということ。
rubyのrangeオブジェクトのinclude?とcover?の違い


日付の範囲に対して現在日時が含まれているか判定したいとき


```Ruby
october = (Time.new(2014,10,1)..Time.new(2014,10,31))
```

`include?`メソッドを使って判定しようとすると

```Ruby
october.include? Time.now
```

このようなエラーがでる  

```
TypeError: can't iterate from Time
```

`include?`の代わりに`cover?`を使うと判定ができる

```Ruby
october.cover?(Time.now)
```

どちらのメソッドも引数に与えたオブジェクトが範囲内に存在するかを調べるメソッドだがドキュメントをみると

```
cover?(obj) -> bool  

obj が範囲内に含まれている時に真を返します。  

Range#include? と異なり <=> メソッドによる演算により範囲内かどうかを判定します。
```

とある、`include?`は`===`を使用して比較するのに対し`cover?`は`<=>`を使用して比較をする  

つまり、範囲に含まれるオブジェクトによって`include?`と`cover?`の結果がことなる可能性がある  
使う場合はどちらの比較方法が適切か考えて使ったほうがいいかもしれない
ncでMemcachedにアクセスする

## はじめに
memcachedをインストールした後、導通確認をするためにncをつかいましたが、ちょっとした落とし穴がありましたのでメモしておきます。

## 失敗パターン

``` bash

$ nc memcache.xxxxx.cfg.apne1.cache.amazonaws.com 11211
set name 0 100 4
test

CLIENT_ERROR bad data chunk

```

なにをやっても **CLIENT_ERROR bad data chunk**とでます。

## 成功パターン

``` bash

$ nc -C memcache.xxxxx.cfg.apne1.cache.amazonaws.com 11211
set name 0 100 4
test
STORED
get name
VALUE name 0 4
test
END

```

memcachedは改行にCRLF(¥r¥n)を利用しているので-Cオプションをつけて改行コードを変更しなくてはいけないという話でした。

参考：[Memcachedのプロトコル](https://github.com/memcached/memcached/blob/master/doc/protocol.txt)
著作権侵害をせずに利用できる画像をまとめているサイト

* [ブログ用の写真検索さん - Amazonの商品画像を公式加工](http://www.nairegift.com/blogphoto/)
* [商用無料の写真検索さん - フリーの画像素材が6700万点以上](http://www.nairegift.com/freephoto/)

勉強会のスライドに使えるかも


* [著作権侵害をせずに、芸能人の写真を思う存分使える『ブログ用の写真検索さん』が凄い！しかもクリックされれば自分の報酬にもなります。 - SONOTA](http://etc.hateblo.jp/entry/blog-shashin-keisai/)

> Amazonが販促用に用意している画像は、アマゾン・アソシエイトというプログラムを通して他のサイトに掲載しても良いことになっているので、そのルールを活用して『Amazonが保有している画像を合法的に自分のサイトに掲載』してしまうのですね。その証拠に画像URLはAmazonのURLをそのまま使っています。

Amazonのリンクを外してただの画像として使うとまずいみたい
NSDictionaryの高速列挙(for ... in...)で順番を保証する方法

Objective-Cの高速列挙(for ... in ...)は便利ですが、NSDictionaryに対して適用した場合は列挙される順番が保証されません。
順番通りじゃないと困るときの策をメモ。

```objc
// 一旦NSDictionaryのキーを取得
NSArray *keys = [dictionary allKeys];

// sortedArrayUsingComparatorを使ってソート
keys = [keys sortedArrayUsingComparator:^(id o1, id o2) {
    return [o1 compare:o2];
}];

// 順番通りに値を取得
for (id key in keys) {
    [array addObject:[dictionary objectForKey:key]];
}
```

オリジナルのObjectをソートするときはsortedArrayUsingComparatorの中身を変更すれば実装できると思います。
private な特異メソッド (クラスメソッド) を定義するには


*private_class_method* を使う。

```ruby                
class Foo
  def self.method
    3
  end
  private_class_method :method
end
```

```ruby
pry 2.1.1-p76> Foo.method
NoMethodError: private method `method' called for Foo:Class
```

または、特異クラスでプライベートなメソッドを定義。

```ruby                
class Bar
  class <<self
    private
    def method
      3
    end
  end
end
```
電話番号の桁数は10か11桁。9桁はもはや無い

* [総務省｜電気通信番号の利用・指定｜電話番号に関するQ&A](http://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/q_and_a.html)

* [9桁の電話番号 ‐ 通信用語の基礎知識](http://www.wdic.org/w/WDIC/9%E6%A1%81%E3%81%AE%E9%9B%BB%E8%A9%B1%E7%95%AA%E5%8F%B7)

> 電話番号が、頭の0と局番を含め9桁であるもの。現在では一つも残されていない。
> かつて東京(03)と大阪(06)が、9桁の電話番号地域として有名だったが、番号の逼迫に対応するため、次のように一桁増やして10桁化するよう、変更されている。

そういえば自分の田舎も市外局番が変わったことを思い出した。

# 桁数

0から始まり、その後9か10桁となる。

例(全10桁): 0311112222
例(全11桁): 09011112222

```php:
if (preg_match("/\A0[0-9]{9,10}\z/", $tel)) {
    // ok
} else {
    // ng
}
```

## 070が枯渇するので020と060が開放される

* [電子機器通信に専用携帯番号、「020」開放　個人向けには新たに「060」　：日本経済新聞](http://www.nikkei.com/article/DGKKASFS15H6L_V10C15A6MM8000/)

> 総務省は電子機器など機械同士の通信用に「020」で始まる専用の携帯電話番号を開放する。専用番号を割り当てることで、急成長が見込まれる次世代電力計（スマートメーター）などの新ＩＴ（情報技術）革命の成長産業を支える環境を整える。
> 2018年にも既存の「070」は枯渇する見込みで、個人の携帯電話向けにも「060」を開放する計画だ。
> 020と060の合計で約１億7000万の番号が使えるようになる。

これAsteriskで実装するのかな
powershell からのSQLserver接続

参考
http://technet.microsoft.com/ja-jp/magazine/hh855069.aspx
※これをそのままコピペすると実行時エラーとなったため若干修正。

環境
win7(64bit)
PSVersion 2.0
SQLserver 2008R2  

New-Object-TypeNam　→　New-Object -TypeNam　（スペース付与）

```db.ps1
# データ取得用
function Get-DatabaseData {
    [CmdletBinding()]
    param (
        [string]$connectionString,
        [string]$query,
        [switch]$isSQLServer
    )
    if ($isSQLServer) {
        Write-Verbose 'in SQL Server mode'
        $connection = New-Object -TypeName System.Data.SqlClient.SqlConnection
    } else {
        Write-Verbose 'in OleDB mode'
        $connection = New-Object -TypeName System.Data.OleDb.OleDbConnection
    }
    $connection.ConnectionString = $connectionString
    $command = $connection.CreateCommand()
    $command.CommandText = $query
    if ($isSQLServer) {
        $adapter = New-Object -TypeName System.Data.SqlClient.SqlDataAdapter $command
    } else {
        $adapter = New-Object -TypeName System.Data.OleDb.OleDbDataAdapter $command
    }
    $dataset = New-Object -TypeName System.Data.DataSet
    $adapter.Fill($dataset)
    $dataset.Tables[0]
}
# データ操作(deleteなど)用
function Invoke-DatabaseQuery {
    [CmdletBinding()]
    param (
        [string]$connectionString,
        [string]$query,
        [switch]$isSQLServer
    )
    if ($isSQLServer) {
        Write-Verbose 'in SQL Server mode'
        $connection = New-Object -TypeName System.Data.SqlClient.SqlConnection
    } else {
        Write-Verbose 'in OleDB mode'
        $connection = New-Object -TypeName System.Data.OleDb.OleDbConnection
    }
    $connection.ConnectionString = $connectionString
    $command = $connection.CreateCommand()
    $command.CommandText = $query
    $connection.Open()
    $command.ExecuteNonQuery()
    $connection.close()
}

# localhostのデータベース:fugeに接続しselect * from table_nameを実行
Get-DatabaseData –query "select * from table_name" –isSQLServer –connectionString "Data Source=localhost;Initial Catalog=fuge;User Id=hoge;Password=poyo"


 ```
メモ: デプロイ

# 手動でデプロイすることの問題点

* 別に手動で問題ない。
  * やり方を知っている人しかデプロイ出来ないという問題あり。
* 手動に面倒くさくなったらデプロイ方法の改善を考えれば良い
  * 作業漏れの恐れ

# とはいうものの

* 自分しか居ない場合
  * git + scp
    * ある時点から変更されたファイルが何か、後でわかるようにgit使う。
  * 大量の変更の場合は、デプロイ前にディレクトリをバックアップとっておきいつでも戻せるようにしておく。
  * rsyncとsshでローカルコマンド発行

## デプロイツール

* capistrano: ruby (試してないがgemをインストールすることから始まるのでやめた)
  * consul
  * Webistrano (WebUI)
  * [Capistrano勉強会資料（初心者向け:未完成） - Qiita](http://qiita.com/sgtn/items/cdc61e763d6a3a4d8def)
  * [デプロイツール - webistrano+apacheを使ってみる(ec-cubeを使ったサイト用検討) - Qiita](http://qiita.com/bonk@github/items/4696ef4b097b6cf81769)
* Fabric : python (paramikoのインストールに失敗して動かせなかった)
  * [http://qiita.com/pika-shi@github/items/802e9de8cb1401745caa](http://qiita.com/pika-shi@github/items/802e9de8cb1401745caa)
* Ansible : python (centos4には対応してない)


# scpでのデプロイスクリプトの例

```bash:deploy.sh
#!/bin/sh
set -eu
export LANG=C

# 検証環境
STAGING="/home/htdocs"

# 本番環境
#WWWDIR=$STAGING
#WWWDIR="/var/www.20141009"
#WWWDIR="/var/www.20141015"
WWWDIR="/var/www"

#----------------------------------------
file_exists() {
    if [ ! -e $STAGING/${1} ];then
      echo "$STAGING/${1} not found."
      exit 1
    fi
    php -l $STAGING/${1} > /dev/null 2>&1 || return 1
}

echo_scp() {
    echo scp -p "$STAGING/${2}" "apache@web${1}.srv:$WWWDIR/${2}"
}

exec_scp() {
    echo web${1}
    scp -p "$STAGING/${2}" "apache@web${1}.srv:$WWWDIR/${2}"
}

#check_diff() {
#    ssh apache@web{1} "cat ${WWWDIR}/${2}" | diff - $STAGING/${2}
#}

if [ ! `whoami` = "apache" ];then
    echo "apacheユーザで実行してください。"
    echo "例) (cd `pwd` && sudo -u apache sh $0)"
    exit 1
fi
#----------------------------------------

# ここにデプロイしたいファイル一覧を列挙
for file in  \
  model/select.php \
  includes/search.php
do
  file_exists $file
  #check_diff 10 $file
  echo_scp 10 $file
  echo_scp 09 $file
  echo_scp 08 $file
  echo_scp 07 $file
  echo_scp 06 $file
  echo_scp 05 $file
  echo_scp 04 $file
  echo_scp 03 $file
  echo_scp 02 $file
  echo_scp 01 $file
  #
  echo "press enter to exec.."
  read ENTER
  exec_scp 10 $file
  exec_scp 09 $file
  exec_scp 08 $file
  exec_scp 07 $file
  exec_scp 06 $file
  exec_scp 05 $file
  exec_scp 04 $file
  exec_scp 03 $file
  exec_scp 02 $file
  exec_scp 01 $file
done
```
SwiftでのNSNotificationCenterの片付けはdeinitで

SwiftでNotificationCenterの監視の解除を行おうとした際に、`dealloc`メソッドがないことに気が付き困ってしまいました。

ひとまず[NSObjectのドキュメント](https://developer.apple.com/library/IOs/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/index.html)を見に行くと、Swiftでは`dealloc`がない。
![deallocについて.png](https://qiita-image-store.s3.amazonaws.com/0/45525/868f07f8-a7c5-c772-bc26-c503207bfc37.png)

それも当然で、[SwiftのドキュメントのDeinitializationのページ](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Deinitialization.html)を見てみると、

> A deinitializer is called immediately before a class instance is deallocated. You write deinitializers with the deinit keyword, similar to how intializers are written with the init keyword. 

とあり、Swiftでは`deinit`を記述するとのことです。言語自体が違うんですもんね。

書いてみるとこんな感じ。

```swift
deinit {
    let notificationCenter = NSNotificationCenter.defaultCenter()
    notificationCenter.removeObserver(self, name: "com.hogehoge.someNotification", object: nil)
}
```

ということで、後片付けをお忘れなく。
iTermのタブにカレントディレクトリを表示させる

~/.bash_profile

```bash
PROMPT_COMMAND='echo -ne "\033]0;${PWD/#$HOME/~}\007"'
```

ホームディレクトリは`~`に変換。
タブの末尾は`(bash)`とかになって現在実行中のプロセス名が出るが、これは設定によりけり？
bootstrap3使ってみた

# 準備

```bash:
wget https://github.com/twbs/bootstrap/releases/download/v3.2.0/bootstrap-3.2.0-dist.zip
unzip bootstrap-3.2.0-dist.zip
wget -O bootstrap-3.2.0-dist/js/jquery-2.js http://code.jquery.com/jquery-2.1.1.min.js

mv bootstrap-3.2.0-dist bootstrap3
touch index.html
```

# サンプル

参考

* [CSS - Bootstrap 3 徹底解説！](http://c.hrgrweb.com/bootstrap3/css.html#grid-system)

```html:index.html
<html>
<head>
  <meta charset="utf-8"></meta>
  <link href="bootstrap3/css/bootstrap.min.css" rel="stylesheet" />
  <link href="bootstrap3/css/bootstrap-theme.min.css" rel="stylesheet" />
</head>
<body>

<div class="container">
<div class="row">
  <div class="col-md-6">左</div>
  <div class="col-md-6">右</div>
</div>
</div>

<script src="bootstrap3/js/jquery-2.js" type="text/javascript"></script>
<script src="bootstrap3/js/bootstrap.min.js" type="text/javascript"></script>
</body>
</html>
```
シンプルな Pull to refresh

標準機能をつかって pull to refresh を実装するには、最低限次の４プロセスを踏む。

1. プロパティに`UIRefreshControl`オブジェクトを持つ
1. 該当ビューコントローラの`viewDidLoad`にて初期化し、コンテンツビュー(`self.tableView`)へ登録する
1. 関連づけたアクションの中身を実装する（通常、データソースとビューの更新を行う）
1. アクションが完了した後、インジケータ処理を止める

```objectivec:2.初期化、ターゲットアクションの設定、コンテンツビューへの登録
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(actionName) forControlEvents:UIControlEventValueChanged];
[self.tableView addSubview:self.refreshControl];
```

```objectivec:4.インジケータ処理を止める
if (self.refreshControl) {
    [self.refreshControl endRefreshing];
}
```
「This account is currently not available.」なアカウントで任意のコマンドを実行する


## はじめに

ログインシェルに/sbin/nologinが指定されているユーザの権限で任意のコマンドを実行する方法を記述します。

## 環境

* CentOS 6.4
* sudo 1.8.6p3
* bash 4.1.2

## 任意のコマンドを実行する

今回はapacheユーザを利用して動作を確認します。

```shell
$ getent passwd apache
apache:x:48:48:Apache:/var/www:/sbin/nologin
```

```shell
$ sudo su - apache
This account is currently not available.
```

### 一般ユーザの場合

sudoコマンドを利用します。

```shell
$ sudo -u apache whoami
apache
```

### rootユーザの場合

suコマンド、またはsudoコマンドを利用します。

```shell
# su - apache -s /bin/bash -c whoami
apache

# sudo -u apache whoami
apache
```

## 参考

* [Man page of SUDO](http://linuxjm.sourceforge.jp/html/sudo/man8/sudo.8.html)
* [Man page of su](http://linuxjm.sourceforge.jp/html/gnumaniak/man1/su.1.html)
* [Man page of GETENT](http://linuxjm.sourceforge.jp/html/LDP_man-pages/man1/getent.1.html)
正規表現: 日本人っぽい名前のローマ字にマッチする

せっかく作ったのでメモ。

日本人っぽい苗字や名前、地名のローマ字表記にだいたいマッチする。Sublime Textの正規表現で確認しただけだけど、特別なことはしていないので他でもだいたい動くと思う。

```
^([AEIOUKSTNHMYRWGZDBCFJ][tshy]?[aeiou]?)([kstnhmyrwgzdbcfj]?[tshy]?[aeiou]n?)+$
```

RubyやPerl、PHPなどでは<a href="http://blog.tokumaru.org/2014/03/z.html">脆弱性</a>対策のため以下を使用したほうがいい。

```
\A([AEIOUKSTNHMYRWGZDBCFJ][tshy]?[aeiou]?)([kstnhmyrwgzdbcfj]?[tshy]?[aeiou]n?)+\z
```

```:テストパターン
Tsushima
Yagi
Chikamatsu
Yokoyama
Masamichi
Tanakadate
Aikitsu
Terada
Torahiko
Natsume
Soseki
Lois
Armstrong
Bill
Evans
Oscar
Peterson
Buddy
Rich
Luis
Bellson
```
PDFファイルを一括でVectorのImagesetにするスクリプト

Xcode6からPDF形式でのVector画像をImageAssetに登録できるようになりました。

x1のサイズのベクター画像を用意しておけば各種サイズはXcodeがよしなにしてくれるステキ機能ですが、一括で大量のファイルを登録する方法が分かりませんでした。
ドラッグ＆ドロップすれば登録はできるのだけど、初期値がVectorになってない・・・

というわけで、単純なものではありますが、その登録のお手伝いをするスクリプトを書いてみました。

そもそも、xcassetsは中身は単なるフォルダとファイルなので、そこに同じようにファイルを設置してやればよさそうです。

![スクリーンショット 2014-10-15 6.49.33.png](https://qiita-image-store.s3.amazonaws.com/0/19676/1d64e885-c58e-2d22-252f-7f49f138ab80.png)

```shell-session:makeVectorAssets.sh

#/bin/sh

baseDirName="./Assets"

rm -fr ${baseDirName}

mkdir ${baseDirName}

contentsFilename="Contents.json"

for file in `find . -name "*.pdf" -type f`; do
	dirname=`basename ${file} .pdf`.imageset
	filename=${file}
	filebasename=`basename ${file}`
	mkdir ${baseDirName}/${dirname}
	cp ${filename} ${baseDirName}/${dirname}/${filebasename}
	
	contentsFilepath=${baseDirName}/${dirname}/${contentsFilename}
	
	echo "{"										>> ${contentsFilepath}
	echo "  \"images\" : [" 						>> ${contentsFilepath}
	echo "    {" 									>> ${contentsFilepath}
	echo "      \"idiom\" : \"universal\"," 		>> ${contentsFilepath}
	echo "      \"filename\" : \"${filebasename}\"" >> ${contentsFilepath}
	echo "    }"									>> ${contentsFilepath}
	echo "  ],"										>> ${contentsFilepath}
	echo "  \"info\" : {"							>> ${contentsFilepath}
	echo "    \"version\" : 1,"						>> ${contentsFilepath}
	echo "    \"author\" : \"xcode\""				>> ${contentsFilepath}
	echo "  }"										>> ${contentsFilepath}
	echo "}"										>> ${contentsFilepath}
	
done

```

不慣れなもので美しくありませんが許してください。

これを、pdfファイルがあるフォルダで実行すると、「Assets」というフォルダが作成され、その中にそれぞれのimagesetフォルダが出来ますので、このimagesetフォルダを、プロジェクトの Images.xcassets 以下にコピーしてやれば、Xcodeにも反映されるはずです。

![スクリーンショット 2014-10-15 6.58.02.png](https://qiita-image-store.s3.amazonaws.com/0/19676/f82fbc03-190f-1515-32d1-75cf40512965.png)

改造すれば、すでにx1、x2として作成してある画像リソースも変換することができるかと思います。

簡単ですが、こんなところで。

※実はこんなことしなくてもXcodeに良い機能があったらごめんなさい。
【ネームサーバ設定】ValueDomainのネームサーバからAWSのRoute53を使用するよう変更

**まず、ValueDomainにログインして、
「ネームサーバの変更」をクリックします。**

![000.jpg](https://qiita-image-store.s3.amazonaws.com/0/40418/fd42af1b-e274-6d66-653e-184154b3f919.jpeg)

**次の画面で、変更するドメインを選択。**

**AWSのRoute53で自動生成された、NSレコードの値を下図のように設定する。**

![001.jpg](https://qiita-image-store.s3.amazonaws.com/0/40418/a706c300-34d4-0ca2-ef27-3c09e0401d17.jpeg)


**これで、ValueDomainのネームサーバからAWSのRoute53が使用されるよう変更されます。**
ゲーム実況動画とDeep LearningでHIKAKINとマックスむらい

※いろいろ敬称略です
※この記事はゲーム実況のステマじゃない、Deep Learningへのとりくみです

## ゲーム実況動画

ゲーム実況動画が面白くてずっとみてます。視聴しない日が無いぐらい。HIKAKINとかマックスむらいって知ってます？YouTubeだけで食べてるHIKAKIN（ヒカキン）とか少しは一般人も知っているような・・・小学生の方が知ってるのかもしれないけど。

とにかく、面白い、面白くて時間もつぶれる、最近はコード書いているときのBGMのかわりです。前までは少し前のアニソンだったけど。大黒麻季（字が違う？）とか。今は、HIKAKINとかマックスむらいがメイン。

もし時間があったら、YouTubeとかに動画があるからみてみてください。ステマじゃないよ。

## YouTubeかニコニコ動画か

ゲーム実況動画って数が多い。新人も多いし、新人発掘はたのしい。動画はだいたい5分から30分ぐらいがおおい。ただ、数が多すぎるのは問題。24時間しかないんだ、一日。昔の動画も見直したくなるしね。

### 動画のもりあがるポイント

動画を全部みるのも好きだけど、いいところを抜き出したいっていう欲求もあって、Deep Learningすることにした。ディープラーニングする・・・長いな。ディープラする。ディプラする。とか。

ニコニコだと、コメントがあって、コメントの頻度や内容のパターンで（wwww とか 8888 とか、あ、これは面白くて笑ったり、ぱちぱち拍手するっていみね）動画のもりあがりポイントを知ることができる。簡単だよね。コメントのデータダウンロードして、ぶんせきしたらおしまい。手前10秒ぐらいをffmpegとか使って切り出して、つなげればダイジェスト動画もかんたんにできて楽しい。ffmpeg はUbuntuがいいと思う。CentOSはバージョンによって導入が面倒だから、Ubuntuすいしょう。

YouTubeばかりみてるんですけど、つべだとニコニコみたいに時系列の視聴者からのフィードバックデータを得ることができないから、どうしようかなーって。

HIKAKINもマックスむらいも、口癖とか決め顔というか、そうゆうのがあって、それを狙ってディプラして盛り上がりのポイントを見つけるというのがしゅし。マックスむらいはのけぞってたり、ふせってたりする画面とかも見つけたい。

## Deep Learning

Pythonの実装を使います

### YouTubeのデータ

```
$ sudo apt-get install youtube-dl
```

みたいな感じで、つべのファイルをDLするライブラリというかツールを導入する。ダウンロードしたら、フレームの画像をffmpeg使って抜き出して、音声をビットレートを考慮して抜き出す。

### 学習用データ

マックスむらいのパズドラなら「○○はつどう！」みたいな音声。「はつどう」だけでうまくいくか。HIKAKINなら叫び声というか奇声というか、そういうの音声を学習用データに用意。画像の方は、好きな顔をキャプチャしておく。HIKAKINの変顔とかで学習させることになんか罪の意識を感じてるけど、好きだから仕方ないよね。マックスむらい32歳の顔も別個に学習させる。

### 検索

これで、ディプラしてみどころを抜き出すというか、動画の何秒目、何フレーム目にそれがあるよっていうのが得たい結果。

## けつろん

書いててだんだんめんどくさくなってきたから、ソースもコマンドラインのメモも全然無い内容になっちゃった。

YouTubeにマックスむらいの「○○発動！」だけ集まった動画がアップロードされたら、うまくいったということでこの記事を思い出してもらえたら、これ幸いでございます。
OS バージョン別、ローカライズ対応した言語の適応順

OS バージョンによって挙動が異なるのでメモ。
それぞれ、上から順にローカライズ対応を行った言語が見つかればそれが適応されます。

## iOS 6
1. 設定言語
2. info.plist の設定言語（CFBundleDevelopmentRegion）

## iOS 7
1. 設定言語
2. 一般 > 言語環境 > 言語 の最近設定した言語順
3. info.plist の設定言語（CFBundleDevelopmentRegion）

## iOS 8
1. 設定言語
2. 一般 > 言語と地域 > 使用する言語の優先順位
3. info.plist の設定言語（CFBundleDevelopmentRegion）

※使用する言語の優先順位が未設定の時は未確認。
Node.jsでリクエスト毎にNODE_DEBUGをコントロール

# NODE_DEBUG

DEBUGログを出すモジュールをコントロールするenvです。
`express`や`koa`のデフォルトモジュールでも`NODE_DEBUG=foo`のように設定することでログを出力できるモジュールがいくつか存在する。

`NODE_DEBUG`の値を切り替えて再起動すると、デバッグしたいリクエスト以外のログも出てしまう。

そのため今回、２つのパッケージ`node-custom-console`と`node-debug-switcher`を作り、このデバッグ出力をリクエスト毎に切り替えられるようにした。

# node-custom-console

既存の`console`を置き換えることで`console.log`、`console.warn`のような出力を以下のようにモジュール名付きでフォーマットして出力できる。

```js
var console = require('node-custom-console')('module1');
console.log('foo', 'bar')
// > 2014-10-02T06:15:16.830Z [log] 44999 module1: foo bar

var console = require('node-custom-console')('module2');
console.info('foo', 'bar')
// > 2014-10-02T06:15:16.830Z [info] 44999 module2: foo bar
```

さらに、`NODE_DEBUG=module1:info`のように指定することで、`module1`の`info`レベル以上のログだけ出力できる。

詳細はrepoを参照。
https://github.com/dtaniwaki/node-custom-console

# node-debug-switcher

MiddlewareでCookieを利用して`NODE_DEBUG`をリクエスト毎に置き換える。
以下は`koa`に使用例。

```js
var koa = require('koa');
var switcher = require('node-debug-switcher').cookies.koa;

app = koa();
app.use(switcher('cookie_name'));
```

指定した`cookie_name=module1:info`のようにすると、そのリクエストのみ`NODE_DEBUG=module1:info`で処理できる。

詳細はrepoを参照。
https://github.com/dtaniwaki/node-debug-switcher

# 組み合わせ

`koa`での組み合わせ例。

```js:module1.js
var console = require('node-custom-console')('module1');
module.exports = function*(next) {
  console.log 'foo'
  console.info 'bar'
  yield(next);
};
```

```js:server.js
var koa = require('koa');
var switcher = require('node-debug-switcher').cookies.koa;
var module1 = require('./module1');

app = koa();
app.use(switcher('cookie_name'));
app.use(module1)
app.listen 3000
```

以下のように出力をコントロールできる。

```bash
$ node --harmony ./server.js &

$ curl http://localhost:3000/

$ curl -b 'cookie_name=module1:info' http://localhost:3000/
> 2014-10-02T06:15:16.830Z [info] 44999 module1: bar

$ curl -b 'cookie_name=module1:log' http://localhost:3000/
> 2014-10-02T06:15:16.830Z [log] 44999 module1: foo
> 2014-10-02T06:15:16.830Z [info] 44999 module1: bar
```

# セキュリティ対策

`node-debug-switcher`は`secure`オプションを使うとクッキーの値に暗号化したものを使うことができる。

```js
switcher('cookie_name', secure: true, password: 'pass')
```
VPN経由でRDSへ接続する場合に考えること

今日はやっつけメモ。
VPN経由、特に vyatta などを使って独自に VPN 接続している場合で RDS との接続が切られる、もしくは反応がないことがあったら下記の内容を確認。

前提
---

・RDS は ICMP に応答をしない。
　→ そのため、Path MTU Discovery を利用して MSS 値 を調整することができない。
・通常の AWS VPN では ルータ側で適切にパケットの分割が行われるよう。

---

対応
---

1.クライアントの MTU 調整

現在値確認
$ifconfig eth0 ← 対象インターフェース
eth0 Link encap:Ethernet HWaddr 02:1C:A4:AB:D7:15
inet addr:172.31.**.** Bcast:172.31.1**.** Mask:255.255.240.0
inet6 addr: fe80::1c:a4ff:btaa:d713/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 ← default

MTU の変更
$ifconfig eth0 mtu 1350

変更を確認
$ifconfig eth0


2.VPN ルータ側でパケットを適切に分割
 vyatta のマニュアルなどを確認。

---
Rails のキャッシュについて


# Rails3 まで
- __ページキャシュ（ページ全体をキャッシュ）__

    ページのレンダリング結果を静的な HTMLファイルとしてファイルシステムに保存する機能。HTMLファイルは publicディレクトリ以下に配置され、Webサーバ（Nginxなど）から直接返すことができる。リクエストパラメータ（条件付き GET リクエスト）が付与される場合は避けた方が良い。

- __アクションキャッシュ（アクション単位でキャッシュ）__

    ページキャッシュと同じく、ページ全体をキャッシュする機能。柔軟な制御をしたい場合はアクションキャッシュを用いる。（非ログインユーザのみに対してページキャッシュしたいなど）アクションキャシュは、Webサーバで直接返さず、2回目以降のアクセスでも Rails で処理する。その分負荷がかかるが、柔軟な制御ができる。また、アクションキャシュの保存は設定した Railsのキャッシュストア（ActionController::Base.cache_store）が用いられる。

- __フラグメントキャッシュ（ページの一部をキャシュ）__

    HTMLを部分的にキャッシュする機能。多くのページで共通するHTMLがある場合などに有効的。1度目のレンダリング時にHTML文字列としてキャッシュストアに保存され、2度目以降のレンダリングでは、キャッシュストアに保存されたそのHTMLが使われる。

上記の3つが代表的なキャッシュ機能としてあった。

# Rails4

- フラグメントキャッシュ（ページの一部をキャシュ）

ページキャッシュと、アクションキャシュは廃止され、フラグメントキャシュのみ使える。
Russian Doll Caching、cache_digests、fragmen cache などと呼ばれるものは、Rails3 までのフラグメントキャシュと指し示すものとすべて同じ。

> Rails4 で内部的に使われているgemが、従来のRailsにおける fragment cache を進化させた cache_digests であり、cache_digestsの仕組みに対する愛称が Russian Doll Caching である。

Rails3 までの違いは、複数のフラグメントキャッシュを入れ子にしている場合に、内側のコンテンツの更新に連動して、外側のフラグメントキャッシュのキーが自動的に変更される。（マトリョーシカってそういうことか。）

## キャッシュを使う（Russian Doll Caching）
ビューの中に、下記のように記述する

```rb:
<% cache do -%>
  キャッシュしたい内容
<% end -%
```

内側のモデル（belongs_to で touch: trueオプションを加える）を修正する。
これで、内側のモデルが更新された時に、外側も更新（updated_at）されるようになりキャッシュも更新される。

### キャッシュキー
キャッシュのキーは、デフォルトでキャッシュメソッドが呼び出されたURLから生成される。

```
views/<domain>/<controller>/<action>/<MD5>
```
明示的に指定することもできるけど、デフォルトでモデルのインスタンスをキャッシュのキーに指定されて、キーの中に```updated_at```を含むので、モデルが更新されたらキャッシュも更新されて便利っぽい。

## キャッシュストア
キャッシュストアには、標準（ActiveSupport）でファイルシステム、メモリ、Memcached がある。用途に合わせて使い分ける必要があるが、 スケールアウト（キャッシュの一元化、ヒット率）を考えると多くの場合 Memcached をキャッシュストアとして使うと良さそう。


## アクションキャッシュ、ページキャッシュを使いたいという場合
>
- rails/actionpack-action_caching : https://github.com/rails/actionpack-action_caching
- rails/actionpack-page_caching : https://github.com/rails/actionpack-page_caching

分離された gem を用いることで使うことができる。
（DHH の思想で Rails のコアからは廃止されたので、非推奨？）

ページキャッシュなどは、 __Nginx__ や __Varnish__　などが担う役割とのことなので、次回は Varnish もしくは Nginx を用いてページキャッシュを実現してみようと思うます。


# 引用・参考
以下の書籍、記事から多く引用・参考にさせていただきました。
スライドや図、サンプルコードなどもあってとてもわかりやすいです。
>
- WEB+DB PRESS Vol.70｜技術評論社 : http://gihyo.jp/magazine/wdpress/archive/2012/vol70
- Rails アプリケーションのパフォーマンスについて RubyKaigi 2013 で発表しました - クックパッド開発者ブログ : http://techlife.cookpad.com/entry/2013/06/07/rubykaigi-high-performance-rails/
- Rils4で Russian Doll Caching を楽しむためのまとめ [俺の備忘録] : http://o.inchiki.jp/obbr/201
- [Rails 高速化] ページキャッシュ、N+1対策、SQLチューニング - 酒と泪とRubyとRailsと : http://morizyun.github.io/blog/speed-up-rails-bullet/
- Railsでページキャッシュ( page caching )を使うべきでない理由 - masa_wの日記 : http://masa-w.hatenablog.com/entry/2014/02/21/180614
- 【Rails 高速化】ペパボのフリマアプリ「kiteco（キテコ）」の API を高速化したときのことを詳しく書いてみた - 彼女からは、おいちゃんと呼ばれています : http://blog.inouetakuya.info/entry/2014/02/08/221438
- How key-based cache expiration works by David of Basecamp : https://signalvnoise.com/posts/3113-how-key-based-cache-expiration-works
- ASCIIcasts - “Episode 387 - Cache Digests” : http://ja.asciicasts.com/episodes/387-cache-digests
- Caching Strategies for Rails | Heroku Dev Center : https://devcenter.heroku.com/articles/caching-strategies
angularjsでfacebook loginしてみる(ng-facebook)

## 概要
angularjsのモジュールを用いて、facebook loginをしてみる。

ng-facebookを使ってみる。Facebook SDKをラップしてくれてる。readmeそのまま。
https://github.com/GoDisco/ngFacebook
MITだしそれなりにメンテナンスされてるので多分大丈夫。
※promiseベースなのでpromise嫌いな方は別の何かを

## 事前準備
facebookデベロッパーに登録した後にappを登録。
https://developers.facebook.com/apps
※ webサイトとApp Domainsを登録しておかないと蹴られるので注意
※ oauth2なのでhttpsの体制を

## packageとfacebookSDK読み込み
```
bower install ng-facebook --save

vim app/index.html

-----
//追加
<script src="app/bower_components/ng-facebook/ngFacebook.js"></script>
-----

vim app/scripts/app.js

-----
// moduleの依存に追加
angular.module('facebookTestApp',[
  'ngFacebook'
])
.config( function( $facebookProvider ) {
    // もろもろ設定
  $facebookProvider.setAppId('xxxxxxxxxxxxxx');
  $facebookProvider.setCustomInit({
    version : 'v2.0'
  });
})
.run( function( $rootScope ){
  // facebookのjs読み込みのサンプルをコピペ
  (function(d, s, id) {
    var js, fjs = d.getElementsByTagName(s)[0];
    if (d.getElementById(id)) return;
    js = d.createElement(s);
    js.id = id;
    js.src = "//connect.facebook.net/en_US/sdk.js";
    fjs.parentNode.insertBefore(js, fjs);
  }(document, 'script', 'facebook-jssdk'));
});
```

## クライアントサイドでログイン＆情報取得
```js

  $scope.isLoggedIn = false;
  $scope.login = function() {
    $facebook.login().then( refresh );
  }
  $scope.logout = function() {
    $facebook.logout().then( refresh );
  }

  function refresh() {
    $facebook.api("/me").then( 
      function(response) {
        $scope.welcomeMsg = "Welcome " + response.name;
        $scope.isLoggedIn = true;
      },  
      function(err) {
        $scope.welcomeMsg = "Please log in";
        $scope.isLoggedIn = false;
      }   
    );  
    $facebook.getLoginStatus().then(
      function(response){
        console.log(response);
      },
      function(er){
      }
    );
  }
```
* getLoginStatus
    * https://developers.facebook.com/docs/facebook-login/login-flow-for-web/v2.1#checklogin
* GraphAPI : /me
    * https://developers.facebook.com/docs/graph-api/reference/v2.1/user#fields

### サーバサイドで使ってみる（おまけ）

#### サーバサイドへAccessToken投げてみる

```js
    $facebook.getLoginStatus().then(
      function(response){
        if ( response.status === 'connected' ) { 
          CSRF.get(function(token){ // ※CSRF対策のtokenを取得するサービス
            var data = { 
              _csrf: token,
              FBToken: response.authResponse.accessToken
            }
            $http.post('/api/hoge', data)
            .success(function(response){
              console.log(response);
            }); 
          }); 
        }
      }
    );
```

#### サーバサイドでトークン使う

fbgraph使ってみた
https://github.com/criso/fbgraph

```js
var graph = require('fbgraph');
module.exports = { 
  hoge: function(req, res ) { 
    graph.setAccessToken(req.body.FBToken);
    graph.get('me', function(error, result){
      console.log(result.name);
      // 名前とれるはず。正しく取得できれば正当なtokenと判断でいいのだろうか。
      res.json(result);
    }); 
  }
};
```

## まとめ

* モジュール気持ちい
* 簡単に取得できすぎて、これでいいのか不安
* 間違えてたらごめんなさい。突っ込んで下さい。
Monoで、Secure Socket Layer (SSL) / Transport Layer Security (TLS)通信を行うには

#問題点
Monoを使って、httpsアドレスに、HttpClientクラスで接続を行うとセキュリティエラーが発生します。
MonoのFAQページによると証明書がインストールされていないので、例外が発生しているようです。
http://www.mono-project.com/docs/faq/security/
解決方法は、3通りあるようですが、私は、mozroots.exeツールを使って、ルート証明書をインポートする方法で解決しました。

#mozroots.exeをダウンロード
下記ページの[download mozroots.exe](http://www.2shared.com/file/Zg7H-IBV/mozroots.html)リンクからツールをダウンロードします。
https://code.google.com/p/duplicati/wiki/LinuxHowto
ダウンロードしたツールを使って、ルート証明書をインポートします。

```bash
$mono mozroots.exe --import --sync
```
TravisCIでAnsibleのPlaybookを自動チェックする。


# 概要
[ansible-lint](https://github.com/willthames/ansible-lint)とGithub、[TravisCI](https://travis-ci.org/)を使って、Githubへのpush毎にPlaybookのチェックを行います。  
[ansible-lint](https://github.com/willthames/ansible-lint)を使うことでplaybook中の改善ポイントや不適切なモジュールの使い方などをチェックすることが出来ます。
[TravisCI](https://travis-ci.org/)は継続インテグレーションを行うことができるサービスで、Githubと連携して、リポジトリへのpush毎にビルドやテストなど処理を実行する事ができます。
今回はansible-lintを実行させてみました。

# 事前準備
## Githubへの保存
+ AnsibleのplaybookをGithubにpushします。

## TravisCIの設定
+ [TravisCI](https://travis-ci.org/)のアカウントを作成します(Githubアカウントでログインできます。)
+ TravisCIにログインすると自分のリポジトリを確認できるので、lintしたいリポジトリでスライダーをOFF→ONに移動します。

## TravisCI設定ファイル(.travis.yml)の書き方。
リポジトリのルートディレクトリに以下のような`.travis.yml`を作成してpushします。
この例ではsite.ymlをチェック対象にしています。

```.travis.yml
language: python
python:
  - "2.7"
install:
  - pip install ansible
before_script:
  - pushd ../
  - git clone https://github.com/willthames/ansible-lint.git
  - export PYTHONPATH=$PYTHONPATH:`pwd`/ansible-lint/lib
  - export PATH=$PATH:`pwd`/ansible-lint/bin
script:
  - popd
  - ansible-lint site.yml # change your playbook name
```

# 実行結果の確認
Push後にTravisCIでは`.travis.yml`を自動的に読み込んでlintが実行されます。
結果が表示されることを確認します。  
例えばunarchiveモジュールを使わずにshellモジュールでtarを実行していると以下の警告が表示されます。

```
[ANSIBLE0006] tar used in place of unarchive module
/home/travis/build/volanja/ansible-Redmine/roles/redmine/tasks/main.yml:0
Task/Handler: Extract tar.gz
```


## バッジ
playbookのREADME.mdにTravisCIのバッジを貼っておけば、すぐに結果を確認することもできます。
![volanja_ansible-Redmine.png](https://qiita-image-store.s3.amazonaws.com/0/29901/ffce65da-5599-a9c0-694a-a895ccdf1cb4.png "volanja_ansible-Redmine.png")

lintで警告が出たところを優先的に修正しておきましょう。
requestsを使ったOAuth認証　例題：Flickr


requestsとrequests_oauthlibを使ってFlickrにOAuth認証を簡単に行う
[「requestsを使ってWebAPIをたたく 例題：Flickr」](http://qiita.com/kosystem/items/4879931c48d29eb37714)でFlickrのWebAPIのたたいたが、実際には自分のアカウント内のプライペート写真にアクセスしたいことが多い。
そこでOAuth認証を使いアカウントにアクセス可能にする方法を示す。

##install
PyPiに登録されているのでpipまたはeasy_installを使ってインストール

```bash
$ pip install requests requests_oauthlib
```

##API keyの取得
Flickrのアカウントを持っていない場合は必要に応じて取得する。

下記のアドレスにアクセスしアプリケーションの登録を行いAPI KeyとSECRETを入手する。非商用ならNon-Commercialで登録する。
https://www.flickr.com/services/apps/create/apply/

##OAuth認証

###サンプルコード

FlickrのOAuthの手順については公式サイトに説明がある。今回はFlickrを対象としているが、基本的にOAuth1であれば同じ手順のはず。
[Flickr:User Authentication](https://www.flickr.com/services/api/auth.oauth.html)

```python
import urlparse
import webbrowser

import requests
from requests_oauthlib import OAuth1


API_KEY = 'YOUR_API_KEY'
SECRET_KEY = 'YOUR_SECRET_KEY'

request_url = 'https://www.flickr.com/services/oauth/request_token'
authorize_url = 'https://www.flickr.com/services/oauth/authorize'
access_token_url = 'https://www.flickr.com/services/oauth/access_token'
access_url = 'https://api.flickr.com/services/rest/'
callback_uri = 'oob'


def oauth_requests():
    # Get request token
    auth = OAuth1(API_KEY, SECRET_KEY, callback_uri=callback_uri)
    r = requests.post(request_url, auth=auth)
    request_token = dict(urlparse.parse_qsl(r.text))

    # Getting the User Authorization
    webbrowser.open('%s?oauth_token=%s&perms=delete' % (authorize_url, request_token['oauth_token']))  # ブラウザを開きOAuth認証確認画面を表示 ユーザーが許可するとPINコードが表示される

    oauth_verifier = raw_input("Please input PIN code:")  # 上記PINコードを入力する
    auth = OAuth1(
        API_KEY,
        SECRET_KEY,
        request_token['oauth_token'],
        request_token['oauth_token_secret'],
        verifier=oauth_verifier)
    r = requests.post(access_token_url, auth=auth)

    access_token = dict(urlparse.parse_qsl(r.text))
    return access_token

if __name__ == '__main__':
    print oauth_requests()
```

これによりAccess tokenおよびAccess token secretが取得でき、以後これを用いることでユーザーのアカウントにアクセスすることができるはず。

認証後のAPIの仕様に関してはまた別の機会に…

##参考
- [Flickr公式 User Authentication](https://www.flickr.com/services/api/auth.oauth.html)

- [超便利な Python モジュール requests を使って OAuth 認証し、Zaim と連携する方法](http://d.hatena.ne.jp/wwwcfe/20120511/python_requests_oauth)
boot2dockerでコンテナからホストのディレクトリをマウントする(Mac)

docker runには-vオプションというのがあって、dockerホストのディレクトリをコンテナ内のディレクトリにマウントすることができます。ただboot2dockerを使っている場合、マウントされるのはVirtualBox上で動いているVMのディレクトリになります。私の場合はMacですが、できればコンテナからMacのディレクトリを直接マウントしたくなります。

## 仕組み

VirtualBoxにはGuestAdditionsというものがあって、ゲストOSにインストールすることでパフォーマンスを引き出したり、今回使う共有フォルダ機能を使うことができるようになります。詳しくは下記。

[6.4. VirtualBox Guest Additions のインストール](http://docs.oracle.com/cd/E26217_01/E35194/html/qs-guest-additions.html)

共有フォルダというのは、ホストOSのディレクトリをVirtualBox上のVMから読み書きできるようにするものです。これを使って、

1. 共有フォルダ機能を使って、Mac上のディレクトリをVMからマウントする
2. dockerコンテナからは、1でマウントしたディレクトリをマウントする

という方法をとります。

## 手順

boot2dockerはISOイメージからVMを作成し、それを起動してその上でdockerが動作する仕組みになっています。ISOイメージは~/.boot2docker/boot2docker.isoにあります。このISOイメージにはGuestAdditionsはインストールされていません。インストールもできますが、インストール済みのISOイメージを作っている人がいるので、ありがたく使わせてもらいます。

[boot2docker together with VirtualBox Guest Additions](https://medium.com/boot2docker-lightweight-linux-for-docker/boot2docker-together-with-virtualbox-guest-additions-da1e3ab2465c)

```bash
# ダウンロード
cd ~/.boot2docker
wget http://static.dockerfiles.io/boot2docker-v1.2.0-virtualbox-guest-additions-v4.3.14.iso 

# リネーム
mv boot2docker.iso _boot2docker.iso.orig
mv boot2docker-v1.2.0-virtualbox-guest-additions-v4.3.14.iso boot2docker.iso
```

VMを停止します

```bash
boot2docker stop
```

VMを削除して、ISOイメージから作り直します。__既存のコンテナやイメージは全て消えるので注意してください。__

```bash
boot2docker destroy
boot2docker init
```

VMを起動する前に共有フォルダの設定を行います。-hostpathは、共有したいMac上のディレクトリを指定します。以下のようにすると、Mac上の/UsersがVM上の/Usersにマウントされます。LaunchPadからVirtualBoxを起動して、GUIで設定してもOKです。

```
VBoxManage sharedfolder add boot2docker-vm -name home -hostpath /Users/
```

なお-nameは、homeを指定するとVM上の/Usersに自動的にマウントしてくれますが、それ以外を指定すると手動でマウントする必要があります。これはISOイメージの/etc/mtabに「none /Users vboxsf rw,nodev,relatime 0 0」と書いてあるためです。

さて、VMの設定はこれで終わりです。起動します。

```
boot2docker start
```

/Usersが正しくマウントされているか確認します。boot2docker sshでVMにログインし、/Usersを見てみます。

```
boot2docker ssh
ls -l /Users
```
正しくマウントされていれば、ホスト上にあるファイルが表示されるはずです。

あとはdocker runの-vオプションを指定すれば、コンテナから直接ホスト上のディレクトリが読めるようになります。

```
docker run -v /Users:/mnt/users -i /bin/bash
```
JMeterによる負荷テスト

## EC2によるクラスター

* [お手軽JMeterクラスター 〜 フルボッコ編｜アドカレ2013 : CFn #1 ｜ Developers.IO](http://dev.classmethod.jp/cloud/aws/aws-cfn-advent-calendar-2013-fullbok/ "お手軽JMeterクラスター 〜 フルボッコ編｜アドカレ2013 : CFn #1 ｜ Developers.IO")  
  ものすごく便利！!
* [「JMeter クラスタ使ってフルボッコにしてやんよ」と言えるようになるまで – I'm Sei.](http://im-sei.tumblr.com/post/72864851778/jmeter "「JMeter クラスタ使ってフルボッコにしてやんよ」と言えるようになるまで – I'm Sei.")

## JMeter解説

* [負荷テストあれこれ-JMeter 負荷のかけ方、レポートの見方-｜A Day In The Boy's Life](http://ameblo.jp/itboy/entry-10041857522.html "負荷テストあれこれ-JMeter 負荷のかけ方、レポートの見方-｜A Day In The Boy's Life")  
  「スレッド数」、「Ramp-Up期間」「ループ回数」について解説
カリー化と部分適用（JavaScriptとHaskell）

カリー化と部分適用について簡単に説明します。特定の言語に依存しない概念を説明するのが目的ですが、例としてJavaScriptとHaskellを使用します。

# JavaScript

カリー化と部分適用はよく混同されるので注意が必要です。

* 関数を引数1つずつに分割してネストさせることを**カリー化**と呼びます。
* 一部の引数を固定化して新しい関数を作り出すことを**部分適用**と呼びます。

<table><tr><th></th><th>非カリー化</th><th>カリー化</th></tr><tr><td>関数定義</td><td><pre>
function add(x, y) {
    return x + y;
}
</pre></td><td><pre>
function add(x) {
    return function(y) {
        return x + y;
    };
}
</pre></td></tr><tr><td>使用例</td><td><pre>
&gt; add(1,2)
3
</pre></td><td><pre>
&gt; add(1)(2)
3
</pre></td></tr><tr><td>部分適用</td><td><pre>
function add1(y) {
    return add(1, y);
}
</pre></td><td><pre>
var add1 = add(1);
</pre></td></tr><tr><td>使用例</td><td colspan="2"><pre>
&gt; add1(2)
3
</pre></td></tr></table>

関数がカリー化されていれば、引数が足りないときに中間過程の関数が返って来ます。

```text
> add1 = add(1)
[Function]
> add1.toString()
'function (y){return x+y;}'
```

`add1`の`x`の値は`1`に固定化されているため、部分適用となります。

# Haskell

Haskellの関数はデフォルトでカリー化されており、非カリー化はタプルで表現します。

<table><tr><th></th><th>非カリー化</th><th>カリー化</th></tr><tr><td>関数定義</td><td><pre>
add (x, y) = x + y
</pre></td><td><pre>
add x y = x + y
</pre></td></tr></tr><tr><td>使用例</td><td><pre>
&gt; add (1,2)
3
</pre></td><td><pre>
&gt; add 1 2
3
</pre></td></tr><tr><td>部分適用</td><td><pre>
add1 y = add(1, y)
</pre></td><td><pre>
add1 = add 1
</pre></td></tr><tr><td>使用例</td><td colspan="2"><pre>
&gt; add1 2
3
</pre></td></tr></table>

`add x y = x + y` は `add = \x -> \y -> x + y` の糖衣構文です。

# Q&A

Q. カリー化は何が嬉しいの？ 
A. 部分適用が簡単にできます。

Q. 部分適用なんて使うの？
A. コールバックの特殊化で便利ですが、JavaScriptではあまり使わないかもしれません。

Q. コールバックの特殊化とは？
A. 一部だけ異なるコールバックを大量に用意するのではなく、共通関数に対する部分適用で済ませるということです。

Q. あまり使わないのになぜJavaScriptで説明したの？
A. 馴染みのない言語の縁のない概念というわけではないからです。

※ 投げ槍な解答ですが、実例を通して慣れるしかないと思います。

# 参考

* [カリー化 - Wikipedia](http://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%AA%E3%83%BC%E5%8C%96)

Haskellで説明を書きました。

* [Haskell ラムダ 超入門](http://qiita.com/7shi/items/1345bf32003faff435cb) 2014.11.27