OmniAICreator/Qiita-1.07M huggingface dataset:
paiza POH joshibato #_poh


今回、解き応えのある問題ではなかったので、多言語展開はなしです。

## A (rio)
普通のシミュレーション。結果以外は小数計算であることに注意。

```rb:paizapoh6a.rb
#!/usr/bin/ruby
x=y=0.0
gets.to_i.times{
	t,s=gets.split.map(&:to_i)
	if t==1
		x+=s
	elsif t==2
		y+=s
	else
		x,y=x-s*x/(x+y),y-s*y/(x+y)
	end
}
p (100*y/(x+y)).to_i
```

## B (kirishima)
問題文からするとシミュレーションで解くべきな気がするけど、私は満足できないので、 **ダイクストラ** で解いた。


```cpp:paizapoh6b.cpp
#include <queue>
#include <cstdio>
#define INF 99999999
using namespace std;

typedef int Weight;
struct Edge {
  int src, dst;
  Weight weight;
  Edge(int src, int dst, Weight weight) :
    src(src), dst(dst), weight(weight) { }
};
bool operator < (const Edge &e, const Edge &f) {
  return e.weight != f.weight ? e.weight > f.weight : // !!INVERSE!!
    e.src != f.src ? e.src < f.src : e.dst < f.dst;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

void shortestPath(const Graph &g, int s,
    vector<Weight> &dist, vector<int> &prev) {
  int n = g.size();
  dist.assign(n, INF); dist[s] = 0;
  prev.assign(n, -1);
  priority_queue<Edge> Q; // "e < f" <=> "e.weight > f.weight"
  for (Q.push(Edge(-2, s, 0)); !Q.empty(); ) {
    Edge e = Q.top(); Q.pop();
    if (prev[e.dst] != -1) continue;
    prev[e.dst] = e.src;
    for(auto &f:g[e.dst]) {
      if (dist[f.dst] > e.weight+f.weight) {
        dist[f.dst] = e.weight+f.weight;
        Q.push(Edge(f.src, f.dst, e.weight+f.weight));
      }
    }
  }
}

int main(){
	int N,Q;
	scanf("%d",&N);
	vector<int>v(N);
	for(int i=0;i<N;i++)scanf("%d",&v[i]);
	Graph g(N);
	for(int i=0;i<N;i++){
		int nxt=i+v[i];
		if(nxt==i||nxt<0||nxt>=N)continue;
		g[nxt].push_back(Edge(nxt,i,1));
	}
	vector<Weight> dist;
	vector<int> prev;
	shortestPath(g,N-1,dist,prev);
	for(scanf("%d",&Q);Q--;){
		int x;
		scanf("%d",&x);
		puts(x<0||x>=N||dist[x]==INF?"No":"Yes");
	}
}
```

## C (tsubame)
簡単すぎませんか。これ、もしかして、つばめがDランク、リオがCランク、霧島がBランク相当の問題だったんだろうか。

```rb:paizapoh6c.rb
#!/usr/bin/ruby
n=gets.to_i
p n+n/10+n%10
```

## D (matsue-ruby)
私は松江に行く予定はありませんが…
キーを昇順で取っておけば速く解けるのではないかと。
計算量はならしでO(LN)だと思われます。
最大0.09秒なので、Ruby 2.0環境では最速ではないかと？

```rb:paizapoh6d.rb
#!/usr/bin/ruby
h=Hash.new{|h,k|h[k]=[]}
gets.to_i.times{
	s=gets.strip
	h[[s,s.reverse].min]<< s
}
min_self_palindrome=nil
result1=[]
result2=[]
a=h.sort
a.each{|k,v|
	v.sort!
	i=0
	while i<v.size/2 && (v[i]!=v[v.size-i-1]||v[i]==v[i].reverse)
		result1<< v[i]
		result2<< v[v.size-i-1]
		i+=1
	end
	if i<=v.size-i-1 && v[i]==v[i].reverse
		min_self_palindrome=(min_self_palindrome&&[v[i],min_self_palindrome].min)||v[i]
	end
}
puts result1.join+(min_self_palindrome||'')+result2.reverse.join
```

## 最終コード

10/7になりました。提出期間は10/6までなので、最終コードを公開します。Ruby(空白コメント等除いて268)です。
テストケースの穴は使っていないはず。

```rb:paizapoh6d_final.rb
#!/usr/bin/ruby
#y => min_self_palindrome

h=Hash.new{|h,k|h[k]=[]}
gets;$<.sort.each{|e|s=e.chop;h[[s,s.reverse].min]<< s}
y=nil;r=[];u=[]
h.each{|k,v|l=v.size-1;i=0
(r<<v[i];u<<v[l-i];i+=1)while i<-~l/2&&v[i]==v[l-i].reverse
y=(y&&[v[i],y].min)||v[i]if i<=l-i&&v[i]==v[i].reverse}
$><<r*''+(y||'')+u.reverse*''
```
無効な日付について

#v12まで

■無効な日付をDATE型変数に代入できる。
<pre>
C_DATE($dtTemp)
$dtTemp:=!2015/09/31!
</pre>

■文字列から日付に変換しても普通に処理できてしまう。
<pre>
C_DATE($dtTemp)
$dtTemp:=Date("2015/09/31")
</pre>

■ただし、文字列に変換するとブランクとなる。
<pre>
C_STRING(80;$strTemp)
$strTemp:=String(Date("2015/09/31"))
//この場合、$strTemp=""となる。
</pre>

■+0をすると有効な日付に変わる
<pre>
C_DATE($dtTemp)
$dtTemp:=!2015/09/31!+0
//この場合、!2015/10/01!となる。
</pre>

#v13以降

■無効な日付は入力時点で、ブランク日付となる。
<pre>
C_DATE($dtTemp)
$dtTemp:=!0000/00/00! //!2015/09/31!と入力してもブランク日付となる
</pre>

■文字列から日付に変換すると、ブランク日付となる。
<pre>
C_DATE($dtTemp)
$dtTemp:=Date("2015/09/31")
//$dtTemp = !0000/00/00!
</pre>
Swiftのメソッドの種類





#メソッドの種類
- クラスメソッド
- インスタンスメソッド
- イニシャライザ(init)


#クラスメソッド

**クラスメソッドのお約束**
1. クラスメソッドの定義はfuncの前に`class`が付く
2. クラスメソッドの呼び出しは、クラス名.クラスメソッド名

```クラスメソッド

class Human {
    
	#1. クラスメソッドの定義はfuncの前に`class`が付く    
    class func helloClass() {
        println("hello class")
    }
    
}

#2. クラスメソッドの呼び出しは、クラス名.クラスメソッド名
Human.helloClass()  //=> "hello class"

```

『クラスメソッドは、クラスが使うメソッドだから``クラス名.クラスメソッド名``と記述する』



#インスタンスメソッド

**インスンタンスメソッドのお約束**
1. インスタンスメソッドの定義は`func`のみ
2. インスタンスメソッドの呼び出しは、インスタンス.インスタンス名

```インスンタンスメソッド
class Human {
    
    #1. インスタンスメソッドの定義は`func`のみ
    func helloInstance() {
        println("hello instance")
    }
    
}

let human = Human()

#2. インスタンスメソッドの呼び出しは、インスタンス.インスタンス名
human.helloInstance()  //=> "hello instanse"
```

『インスタンスメソッドは、インスタンスが使うメソッドだから``インスタンス名.インスタンスメソッド名``と記述する』


#イニシャライザ(init)

**initのお約束**
1. initメソッドは``init()``と定義
2. initメソッドはインスタンスを生成時に自動で呼び出される
3. initに引数を設定した場合、インスタンス生成時に引数を渡す


###引数無しのパターン
```init引数なし
class Human {
    
    # 1. initメソッドは``init()``と定義
    init() {
        println("init Hunma")
    }
    
}

# 2. initメソッドはインスタンスを生成時に自動で呼び出される
let human = Human()  //=> "init Human"
```


###引数ありのパターン

```init引数あり
class Human {
    
    #1. initメソッドは``init()``と定義
    init(name: String) {
        println("init Hunma is \(name)")
    }
    
}

#3. initに引数を設定した場合、インスタンス生成時に引数を渡す
let human = Human(name: "keita")  //=> "init Human is keita"
```
Nginxでaioディレクティブを使用するには


Nginxでaioディレクティブを使用するには、コンパイル時のオプション--with-file-aioを有効にしなければならない

```sh
# ./configure --with-file-aio
# make
# make install
```

[HttpCoreModule]でaioを見つけたが有効にできず、ググっても見つけられずに困った

# 今後
https://www.nginx.com/blog/thread-pools-boost-performance-9x/
タイトルしか読んでないが、9倍になるらしいので調査。


[HttpCoreModule]:http://nginx.org/en/docs/http/ngx_http_core_module.html
Zabbixで監視対象ホストを追加（Windows）

忘備録

【前提条件】
Zabbixは既にインストール済とします。

監視対象ホストを追加します。例として Windows Server 2012 R2 を対象に追加します。
対象の Windows でファイアウォールを有効にしている場合は、ポート 10050 を受信許可しておく必要があります。

監視対象の Windows ホストで以下のサイトから Windows 用のバイナリファイルをダウンロードしてください。
⇒ http://www.zabbix.com/jp/download.php

ダウンロード完了後、ZIP ファイルを展開し、生成されたフォルダを開くと以下のように「bin」と「conf」フォルダがあります。 ここから「conf」フォルダ直下の「zabbix_agentd.win.conf」と、「bin\win64」直下の 3つの exe ファイルを Zabbix Agent を配置する任意のフォルダにコピーします。

![image](https://qiita-image-store.s3.amazonaws.com/0/55845/481354c4-2ea5-31fe-7431-27635f217bca.png)

ここでは例として「C:\Program Files\Zabbix_Agent」というフォルダを新規作成し、そこへ以下のように上記 4ファイルを格納して進めます。
![image](https://qiita-image-store.s3.amazonaws.com/0/55845/6fdb8a29-802e-c1f0-bd32-96c4ba889a1f.png)

Zabbix Agent の設定ファイル「zabbix_agentd.win.conf」をテキストエディタで開き、以下のように必要なパラメーターを変更します。
<pre>
# 14行目：ログファイルの格納場所を指定
LogFile=C:\Program Files\Zabbix_Agent\zabbix_agentd.log
# 74行目：Zabbix サーバーを指定
Server=10.0.0.30
# 115行目：Zabbix サーバーを指定
ServerActive=10.0.0.30
# 126行目：自身のホスト名を指定
Hostname=fd3s.server.world
</pre>

コマンドプロンプトを管理者権限で起動し、以下のようにコマンドを入力してインストールします。「～ successfully」と表示されればインストール成功です。
> cd C:\Program Files\Zabbix_Agent 
> zabbix_agentd.exe --config "C:\Program Files\Zabbix_Agent\zabbix_agentd.win.conf" --install

![image](https://qiita-image-store.s3.amazonaws.com/0/55845/f1964039-c25a-91b9-b464-2d81846c24cf.png)

サービスの管理画面を開くと「Zabbix Agent」が追加されています。「開始」をクリックして起動してください。正常に起動できれば Agent 側の設定は完了です。
![image](https://qiita-image-store.s3.amazonaws.com/0/55845/0d9c49dd-2d33-9f53-2294-2eeb3915b415.png)

Zabbix の管理サイトにログインし、「設定」-「ホスト」タブに移動し、「ホストの作成」ボタンをクリックします。
![image](https://qiita-image-store.s3.amazonaws.com/0/55845/b16a4f9d-c0c6-3b87-b02b-696f098d005c.png)

ホストタブを選択します。ホスト名は、他のサーバと重複しないような名前を設定します。ホスト名に使える文字は、アルファベットの大文字小文字と半角数字、記号はアンダースコアとハイフンが使えるようです。表示名には使える文字の制限がありませんので、分かりやすい名前を付けておきます。所属グループは必須です。最後に監視対象サーバのIPアドレスを入力します。
![image](https://qiita-image-store.s3.amazonaws.com/0/55845/79821fa9-3179-2df9-86a7-3dc8ba909564.png)

必要な項目を入力したら「テンプレート」タブに移動し「選択」ボタンをクリックします。
![image](https://qiita-image-store.s3.amazonaws.com/0/55845/d64469c1-d96f-147f-290c-8239c300fbd2.png)

「Template OS Windows」を選択し「選択」ボタンをクリックします。
![image](https://qiita-image-store.s3.amazonaws.com/0/55845/900b205a-c572-f034-15a3-a6b2c06f9f43.png)
「追加」リンクをクリックします。
![image](https://qiita-image-store.s3.amazonaws.com/0/55845/f5996ce2-0fc6-ab7b-e10c-61b90b820980.png)

テンプレートとのリンクに、先ほど選択したテンプレートが表示されていることを確認し「更新」をクリックすれば、ホストの作成の完了です。
![image](https://qiita-image-store.s3.amazonaws.com/0/55845/7cb0294f-e3d3-c42f-187f-13377701dffa.png)

監視対象ホストが追加されました。
![image](https://qiita-image-store.s3.amazonaws.com/0/55845/8e7df628-872f-b521-2342-c115414e940f.png)

しばらく時間が経つと、追加した対象ホストのデータが表示されるようになります。
![image](https://qiita-image-store.s3.amazonaws.com/0/55845/f38ea802-ff69-bfba-5921-d04fa4c36094.png)
C# 備忘録 コールバックについて

#コールバック 
処理をまとめるときに便利なC#の機能

##何かを実行する
```
//定義 
System.Action callback = () =>
{
    Debug.Log("もふもふ");
};

//実行 もふもふが表示される
callback();
``` 

引数を渡したいときは型パラメータを指定

```
//定義
System.Action<int> callback = (n) =>
{
    for (int i = 0; i < n; i++)
    {
        Debug.Log("もふもふ");
    }
};

//実行 もふもふが10個表示される
callback(10);
``` 


##何かを実行して値を返す
値を返したいときはSystem.Funcを使う

```
//定義
System.Func<string> callback = () =>
{
    return "もふもふ";
};

//実行 もふもふが表示される
Debug.Log(callback());
``` 

引数を渡したいときは型パラメータを複数指定

```
//定義
System.Func<int,string> callback = (n) =>
{
    if(n%2==0)
    {
        return "偶数";
    }
    else
    {
        return "奇数";
    }
};

//実行 奇数が表示される
Debug.Log(callback(3));
```
Kotlinのsafe call演算子とUnitの話

# Safe-call演算子
Kotlin書く人でSafe-call演算子`?.`を使わない人は少ないんじゃないかと思います。
それだけ当たり前に使う演算子なのですが、先日軽くはまったところがあるので、紹介します。

```kotlin
class A {
 fun foo():Unit = Unit
 fun bar():Int = 0
}
```
こんなクラスがあったとします。
それをこんな風に使います。

```kotlin
 val a : A? = null
 a?.foo()
 a?.bar()
```
まあ、思った通りに動きます。```a==null```なので、foo()もbar()も実行されません。

では、これならどうでしょう？

```kotlin
 val a : A? = null
 a?.foo() ?:hoge()
 a?.bar() ?:huga()
```
hoge(),huga()が両方とも実行されて欲しい、というケースです。

これ、なぜかIDE上では```a?.foo()```のところに警告が出ます。```Elvis Operator (?:) always returns the left operand of non-nullable type Kotlin.Unit```
どうやら、foo()はUnitを返すので、```a?.foo()```もUnitになり```null```にはならない、よってエルビスの右辺は実行されないよ、と警告されているようです。
警告を信じている限り、hoge()は実行されないように思われます。
bar()の方はIntを返すので、```a?.bar()```がInt?と解釈されるので問題ない、ということのようです。

では、実行してみましょう。

```
=========: HOGE
=========: HUGA
```
あれ？

hoge()が実行されてますね。

どうも、コンパイラとエラーチェッカーの間に齟齬があるようです。

# まとめ

```kotlin
nullable?.let { doit() } ?: instead()
```
こんな風に```?.let { }```を交えた構文を

```kotlin
if ( nullable != null ){
  doit()
}else{
  instead()
}
```
の代わりとして、手癖で覚えてたらIDEに警告されて悩んだ、という話でした。

個人的には、警告の解釈の方が筋が通ってるように思えるんですが、
動いてる方が正しいとも言えるわけで……難しい。

いまのところ、警告を無視するしか無さそうです。
显示打印的行数的代码



    #ifdef DEBUG
    #define NSLog(FORMAT, ...) fprintf(stderr,"%s:%d  \t%s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
    #else
    #define NSLog(FORMAT, ...) nil
    #endif
    
#设置导航栏背景图片
    
    //stretchableImageWithLeftCapWidth:5 topCapHeight:10
    // 从 5 ，10 的位置拉升
    UIImage * naviImage = [[UIImage imageNamed:@"navigationbar"]stretchableImageWithLeftCapWidth:5 topCapHeight:10];
    
    
    
##是图片不拉升
        photoImageView.contentMode = UIViewContentModeScaleAspectFit;
    
    
## //把图片保存到相册里
        UIImageWriteToSavedPhotosAlbum(imageView.image, nil, nil, nil);

    
## //直接打开网址  下载AppStor
   
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:_dataDict[@"itunesUrl"]]];
##//请求超时的时间设置
 
    AFHTTPRequestOperationManager * manager = [AFHTTPRequestOperationManager manager];
    //5秒 超时时间
    manager.requestSerializer.timeoutInterval = 5;
    
##//更改状态栏    UIStatusBarStyleLightContent 字体改为白色
     -(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
    }
#pragma mark -- 手势 --
//点击消失显示

    -(void)tapAction:(UITapGestureRecognizer *)tap{
    

    //    _topImageView.hidden = !_topImageView.hidden;
    
    if (_topImageView.hidden == YES) {
        _topImageView.hidden = NO;
        _bottomOpImageView.hidden = NO;
        [UIView animateWithDuration:0.5 animations:^{
            //
            _topImageView.alpha = 1;
            _bottomOpImageView.alpha = 1;
        } completion:^(BOOL finished) {
            //
        }];
        
    }else{
        [UIView animateWithDuration:0.5 animations:^{
            //
            _topImageView.alpha = 0;
            _bottomOpImageView.alpha = 0;
        } completion:^(BOOL finished) {
            //
            _topImageView.hidden = YES;
            _bottomOpImageView.hidden = YES;
        }];
    }
    }
    
    

#第三方库
            
##第三方库UMSocial_Sdk_4.2
###分享东西
    //UMSocialSns
        [UMSocialSnsService presentSnsIconSheetView:self appKey:@"55bf7d1ee0f55a3ccc002b2c" shareText:@"今天去优衣库看了看" shareImage:[UIImage imageNamed:@"Defaultretein1@2x"]shareToSnsNames:@[UMShareToSina,UMShareToQQ,UMShareToLWTimeline] delegate:self];


##第三方库MBProgressHUD
加载等待提示
   // MBP
   
    MBProgressHUDManager * hudManager = [[MBProgressHUDManager alloc]initWithView:self.view];
    [hudManager showIndeterminateWithMessage:@"正在加载"];
    //成功
     [hudManager showMessage:@"数据加载完成" duration:1];
    //失败
      [hudManager hide];


##第三方库KVNProgress
加载等待提示

    [KVNProgress showWithStatus :@"正在加载"];
    
    
    [KVNProgress showSuccessWithStatus:@"OK"];
    
     [KVNProgress showErrorWithStatus:@"请检查你的网络"];
Spring Session のストレージとして MongoDB を使う

[Spring Session](http://projects.spring.io/spring-session/) はセッションのストレージとして Redis をサポートしていますが、他の DB は現時点ではサポートされていません。そこで、MongoDB をストレージとして使うための拡張を作成してみました。

## Spring Session とは

簡単に言えば、サーブレットコンテナに依存しないセッションのクラスタリングなんかができるようになります。フィルタ(springSessionRepositoryFilter)を使用して、サーブレットコンテナの Session 処理を横取りするような実装になっています (仕組みの詳細は [How HttpSession Integration Works](http://docs.spring.io/spring-session/docs/1.0.2.RELEASE/reference/html5/#httpsession-how) を参照)

日本語の情報が少ないのですが、[Spring-Sessionを使ってみた](http://qiita.com/uich/items/cd5d63c12f1d342fc65c) あたりが参考になります。

## 使い方

リポジトリは[こちら](https://github.com/tmurakam/spring-session-mongodb)にあります。
使い方は [USAGE.ja](https://github.com/tmurakam/spring-session-mongodb/blob/master/USAGE.ja.md) に書いてあるので、そちらを見ればわかると思います。

基本的に、やることは以下の３つです。

1. pom.xml や build.gradle に dependency を追加する。
2. MongoDB 接続設定用の Java Config を書く。
3. XMLで設定する場合は、Spring の bean 設定(XML)を追加して、web.xml にフィルタの設定をする。

## 実装について

MongoDB 以外の DB (MySQL とか)を使いたい、ということもあると思うので、実装の詳細について解説します。
やらないといけないことは以下の通りです。

### ExpiringSession を継承してセッションクラスを作る。

これがデータベースに保存されるべきエンティティになります。
spring-session-mongodb では [MongoSession](https://github.com/tmurakam/spring-session-mongodb/blob/master/spring-session-mongodb/src/main/java/org/tmurakam/spring/session/data/mongodb/MongoSession.java) クラスが該当します。

### SessionRepository を実装したリポジトリクラスを作る。

いわゆる DAO。実際にデータベースにセッションクラスを読み書きするための実装です。
spring-session-mongodb では [MongoSessionRepository](https://github.com/tmurakam/spring-session-mongodb/blob/master/spring-session-mongodb/src/main/java/org/tmurakam/spring/session/data/mongodb/MongoSessionRepository.java) が該当します。これは Spring Data MongoDB を使用してデータベースを読み書きするようになっています。

実装上注意すべき点がいくつかあります。

* getSession() をしたときに必ず lastAccessedTime を更新しないといけません。
* セッション属性は型が不定 (Object型)なので、シリアライズ・デシリアライズ処理を自前で書かなければなりません。
* 古くなったセッションを自動破棄する処理はないので、自前で実装する必要があります。flushExpiredSessions() に実装しているので、参考にしてください。
 
### sessionRepositoryFilter を生成するための Configuration クラスを作成する。

spring-session-mongodb では [MongoSessionConfiguration](https://github.com/tmurakam/spring-session-mongodb/blob/master/spring-session-mongodb/src/main/java/org/tmurakam/spring/session/data/mongodb/MongoSessionConfiguration.java) が該当します。

@Bean アノテーションをつけるメソッド名は springSessionRepositoryFilter にします。変えてもいいですが、当然 web.xml に記述する名前をあわせる必要があります。
zshだとgit reset HEAD^とか、とにかく「^」が使えない。そんなとき。


# 解決法
## zsh-git-escape-magicを使う。
@quenhuluさんからのご紹介です。導入も簡単でとても便利です。ありがとうございます！
> zsh-git-escape-magic を使うと ^ などが自動でエスケープされます。
https://github.com/knu/zsh-git-escape-magic

## その他
### エスケープする。
#### バックスラッシュ

```zsh
% git reset HEAD^
# => zsh: no matches found: HEAD^
```
```zsh
# お好きなものを
% git reset HEAD\^
% git reset --soft HEAD\^
% git reset --hard HEAD\^
% git reset HEAD\^\^
% git reset HEAD\^\^\^
# ・・・
```
#### クォート
@hage@githubさんからのご紹介です。キャレット（`^`）が多い時に見やすくて有効ですね、ありがとうございます！
>エスケープする方法の他にクオートする方法があります。
% git reset 'HEAD^'

#### `HEAD`は`@`に置き換えれる
こちらも@hage@githubさんからのご紹介です。`git 1.8.5`より`HEAD`のエイリアスとして`@`が使えるようになったようです。タイプ数が3も減るのは素晴らしいですね。ありがとうございます！
>それとどのバージョンからか忘れましたが、HEADのエイリアスとして@が用意されました。以下の二つは同じ意味です。
% git reset 'HEAD^'
% git reset '@^'

### こんな方法も。
[zsh の exntended_glob と HEAD^^^ を共存させる。 - 冬通りに消え行く制服ガールは✖夢物語にリアルを求めない。 - subtech](http://subtech.g.hatena.ne.jp/cho45/20080617/1213629154)

# 原因
便利な`extended_glob`オプションが原因。
`setopt extended_glob` のようにextended_globオプションをセットしていると起きてしまう。
`extended_glob`において`^`はパターン否定。
他にもいろいろあるです。


```zsh:例）拡張子がtxtでないものをls
% ls
# => tororo.txt  tororo_dir/ totoro.txt  totoro_dir/
#     ~/lsls

% ls ^*.txt
# => tororo_dir:
#    
#    totoro_dir:
#     ~/lsls
```
iTunesで聴いている曲をSlackに通知するアプリをswiftで書いた

[iTunesで聴いている曲をSlackに通知するアプリをElectronで作った](http://qiita.com/uiureo/items/12ddb011d071d09fe180) という素敵な記事をみつけ、そういえば最近似たようなやつを作ったなぁと思って記事にしてみました。

ただの紹介記事だと面白くないので、どうやって Apple Music に対応したのかをついでに記そうと思います。

![SlackMood.png](https://qiita-image-store.s3.amazonaws.com/0/53253/7bd860e7-5df3-5188-ba0d-2963ca69690b.png)

https://github.com/ayasuda/SlackMood

もっとも簡単に作るなら Apple Script が便利です。私もつい最近までは、単純に再生中の曲を slack に流すだけでよかったので、 ruby + osascript コマンドで実装していました。

## Apple Script で iTunes の情報を取る

だいたいこんなコードで再生中の曲自体は取れます。

OSX をお使いの方は「アプリケーション - その他 - スクリプトエディタ」などで次のファイルを作成してみてください。

```getTrack.scpt
tell application "iTunes"
  set trackName to name of current track
  set trackArtist to artist of current track
  return trackName & " - " & trackArtist
end tell
```

ファイルを作成・保存したら、スクリプトエディタで直接実行してもいいですし、コンソールから

> $ osascript path/to/getTrack.scpt

してもよいです。

標準出力に、再生中の曲が表示されたのがわかるかと思いますので、あとは [slackcat](https://github.com/rlister/slackcat) するなり、直接 `curl` あたりで post するなり自由にできます。

しかし、この方法で **Apple Music の情報は取れません** 。

## Apple Script で取り扱える情報について

Apple Script で取り扱える情報を調べるにはスクリプトエディタの「用語説明」を使います。

![how_to_get.png](https://qiita-image-store.s3.amazonaws.com/0/53253/df4197c8-2c20-ab4e-5ac4-224b4767ce7d.png)

「ファイル - 用語説明を開く」をクリックすることで、Apple Script でアクセス可能なアプリケーションのリファレンスを開くことができます。

![dictionary.png](https://qiita-image-store.s3.amazonaws.com/0/53253/56cbe24b-939b-90a5-e2ed-c9aacae25e89.png)

この中から iTunes を選ぶと次のようなリファレンスが提示されます。

![itunes_refs.png](https://qiita-image-store.s3.amazonaws.com/0/53253/76ecb20f-82c0-6a13-065d-6f1eb7285005.png)

この中を調べても、やっぱり **Apple Music の情報は取れなさそうだ** とわかります。 

## それでも Apple Music の再生情報を取りたい！

なぜ Apple Music の曲情報が取れないかというと、アクセス権がないから（一応ネットワーク上の情報なので。マイミュージックに追加をすると、ローカルからのアクセス権がつくので、AppleScript などでアクセスできるようになります）なのですが、それでも、slack に投稿するために曲情報、欲しいですよね？

そこで、別のアプローチを試します。

そう、通知センターです。

![notification.png](https://qiita-image-store.s3.amazonaws.com/0/53253/9eab929d-ba8b-1767-93b0-3b17e8248dbd.png)

こんな風に再生情報が表示できる以上、何らかの方法を使えば同じだけの情報は取れるはずです！

結論から言えば、 `NSDistributedNotificationCenter.defaultCenter` に "com.apple.iTunes.playerInfo" のオブザーバを登録することで **Apple Music の音楽も曲情報が取得できます** 

NSNotificationCenter はプロセス間通信を非常にやりやすくしたもので、アプリケーションは任意のメッセージを Listen できますし、通知センターに任意のメッセージを送信できます。

詳細は
http://www15.plala.or.jp/NovemberKou/programming/columnHome/column/whatIsNotification.html
などが詳しいかと思います。

## 感想

そもそも swift を使うつもりは全然なかったのですが、一番簡単に NotificationCenter のオブザーバを用意する方法がこれだったので、仕方なく Cocoa アプリケーションとして実装されています。
Electron は大変よくできていると思うので、 Electron での通知センターのオブザーバー実装に皆さんも挑戦してみてはいかがでしょうか？

また、SlackMood の実装はものすごく簡単です。

任意のメッセージを受け取って、決めうちの slack api に post するだけにすぎません。

Listen するメッセージの切り替えや、post先の切り替えは、ソースコードを書き換えるだけですぐに実現できるかと思いますので、ぜひ適当に fork して、あなただけの mood message publisher を作ってみてください！
Android端末内のRealmデータ確認


# 1. ADB Shellで確認する方法
## adb コマンド確認及び設定
ターミナルから現在繋がっている端末を確認する

``` shell
$ adb devices
```

以下のようなエラーが出た場合

``` shell
bash: adb: command not found
```
Android StudioのPreferenceからAndroid SDK Loactionをコピーする
![スクリーンショット 2015-09-01 15.29.09.png](https://qiita-image-store.s3.amazonaws.com/0/28329/5d28ef0c-158c-5ad1-7c89-ca848e4b507c.png)

以下のようにPATHにSDK Locationを追加します。

```shell
vi ~/.bash_profile 
```

~/.bash_profile中にAndroid SDK Path追加します。

```
export PATH=$PATH:/Users/{your name}/Library/Android/sdk/platform-tools
eval "$(rbenv init -)"
```

bash_profileを再度読み込む

```shell
$ source ~/.bash_profile 
```


## Realmファイル確認

```shell
$ adb shell
shell@XXX:/                   $ run-as com.test // your package name
shell@XXX:/data/data/com.test $ ls files        // realmデータ位置やファイル名確認
```

## Realmファイルコピー

run-as してcatをしたらPermission deniedになりますので必ず下の順番でコピーする

```shell
$ adb shell
shell@XXX:/                   $ cd /data/data/com.test/files
shell@XXX:/data/data/com.test $ cat default.realm > /sdcard/default.realm      
shell@XXX:/data/data/com.test $ exit  

$ adb pull /sdcard/default.realm /Users/{your name}/Desktop/
```
## Realmデータ確認
Realm Browserアプリケーションをインストールしてコピーしたファイルを実行したら中身がみれる。


# 2. Stetho利用する方法
Stethoとは？chrome からAndroidストレージが見れるライブラリ(facebook製)
http://facebook.github.io/stetho/

それをrealm に対応したライブラリ
https://github.com/uPhyca/stetho-realm


#　感想
2番目で色々確認できるのでオススメ。
Facebookに感謝と時間がある時にfacebook open projectをゆっくりみたいな。
Carrierwaveで画像を複数アップロードする

## 今回すること
画像アップロード用のgemであるcarrierwaveを使い、あるモデル(今回はprotorypeモデル)にネストさせた形で画像(thumbnail)を複数アップロードします。

## 使用するファイル
- gemfile
- thumbnail_uploader.rb
- prototypes_controller.rb
- prototype.rb
- thumbnail.rb
- prototype/new.html.haml

## やり方

####1 まずcarrierwaveをインストールします

```gemfile
gem 'carrierwave'`
```

`bundle install`

####2 アップローダーを作成します
`rails g uploader thumbnail`
=> thumbnail_uploaderが作成される。

####3 アソシエーションを定義する
`rails g migration AddPrototypeRefToThumbnail prototype: references` 
=> `rake db:migrate`

```ruby:prototype.rb
		has_many: thumbnails
```

```ruby:thumbnail.rb
		belongs_to: prototype
```

#### 4 アップローダーを指定

```ruby:thumbnail.rb
	mount_uploader :image, ThumbnailUploader
```
※ここのimageはthumbnailsテーブルのカラム名です。
#### 5 accepts_nested_attributes_forによる入れ子フォームの作成

```ruby:prototype.rb
accepts_nested_attributes_for :thumbnails
```
これによってプロトタイプにネストされたサムネイルを投稿できるようになります。

#### 6 コントローラーの編集

```ruby:prototypes_controller.rb
def new
	@prototype = Prototype.new(create_params)
	3.times { @prototype.thumbnails.build }
end
```
> @prototype.thumbnails.build

これによってプロトタイプに紐付いているサムネイルをビルドします。これによって入れ子のモデル(thumbnail)を表示させる **fields_for** が表示できます。今回は画像を3枚投稿するので、

> 3.times

としています。

```ruby:prototypes_controller.rb
private
def create_params
params.require(:prototype).permit(thumbnails_attributes: [:image])
```
サムネイルをフォームから投稿するためにストロングパラメータを指定します。
**fields_for**は **[引数に与えた名前]_attributes** というname属性でフォームを作成するので、今回は `thumbnails_attributes`とします。
さらに`[:image]`でカラムの指定をしています。

#### 7 フォームの作成

　fields_forを使って画像投稿フォームを@prototypeにネストさせます。

```ruby:prototypes/new.html.haml
=form_for(@prototype) do |f|
	= f.fields_for :thumbnails do |thumbnail|
    	= thumbnail.file_field :image
	= f.submit "投稿する"
```

これで画像を複数投稿できるようになりました！

## 参考

http://www.workabroad.jp/tech/1118
(carrierwave)

http://ruby-rails.hatenadiary.com/entry/20141208/1418018874
(accepts_nested_attributes_for)
You are not logged in. Please login and try again エラー発生時に確認するポイント(備忘録)

facebook loginのインポートは完了した！
しかし、動作させると"You are not logged in. Please login and try again"
というエラーが発生してしまった時に確認するポイントを備忘録として残します。

#環境
OS Mac OS X 10.10.5
Android studio 1.3.1
facebook android sdk 3.23.1

#確認するポイント
・facebook developersサイト内で、Androidプラットフォームが追加されているか
・Google Play Package Nameが正しく設定されているか

#手順
1.facebook developersサイトを開く
2.SettingsのBasicタブを選択
3.画像のように、Androidのプラットフォームが追加されていない場合はAdd Platformから追加
![スクリーンショット 2015-09-01 15.18.49.png](https://qiita-image-store.s3.amazonaws.com/0/74445/b8e19457-fa42-48ed-06a9-7a6544074081.png)

4.Google Play Package Nameを設定(com.XXXXXXX.XXXXXXX)


※その他の項目については、空欄
Registratorでコンテナ内のAddress/Portを登録する

コンテナ構成の変更に伴うロードバランサ(例えばnginx)設定の変更にconsul, consul-template, registrator を使っておりますが、なかなか快適です。

一点だけ不満だったのが、Registrator をデフォルトの設定で起動すると、serviceのAddress/Portがコンテナ内ではなくホストネットワーク用のものが生成されるため、ロードバランサ自体をコンテナとして運用している場合にうまいこと consul-template を作るのが難しいことでした。

**例）** `.ID`のパターンから正規表現でホスト名を抜き出すという汚い事をやっていた

```nginx
upstream hogehoge_web {
  {{range service "hogehoge_web"}}server {{.ID | regexReplaceAll "^.*?:(.*?):.*?$" "$1"}}:3000 max_fails=3 fail_timeout=10 weight=1;
  {{else}}server 127.0.0.1:65535; # force a 502{{end}}
}
```

こんなおかしな設計のはずがないと思い、[Registratorのソース](https://github.com/gliderlabs/registrator/blob/master/registrator.go)を確認したところ、きちんと `--internal=true` というオプションが用意されており、これをつけて起動すればコンテナ側で利用できるAddress/Portを登録してくれるようです。

**docker-compose.ymlの記述例)**

```yaml
consul:
  image: gliderlabs/consul-server
  command: "-bootstrap"
  ports:
    - 8300:8300
    - 8400:8400
    - 8500:8500
    - 8600:8600/udp
registrator:
  image: gliderlabs/registrator:latest
  command: --internal=true --ttl=120 --ttl-refresh=30 consul://consul:8500
  volumes:
    - /var/run/docker.sock:/tmp/docker.sock
  links:
    - consul
```

Registratorを`--internal=true`で使う場合、`net: host`になっていると内向きと外向きの両方のサービスが二重に登録されてしまって気持ちが悪いので、ブリッジにしています。

これで以下のように素直な記述ができます。

```nginx
upstream hogehoge_web {
  {{range service "hogehoge_web"}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=10 weight=1;
  {{else}}server 127.0.0.1:65535; # force a 502{{end}}
}
```

素晴らしい。
libbz2を使ってpbzip2で圧縮したファイルを伸張する

# pbzip2で圧縮したファイルを伸張する
以前作成したプログラム(bzip2で圧縮したファイルの伸張はできる)で、pbzpi2(Parallel BZIP2)で圧縮したファイルの伸張が行えなかったので対応させた。
そのときのテストプログラム。

```cpp:bz2test.cpp
#include <stdio.h>
#include <stdlib.h>

#include <bzlib.h>

int main(int argc, char const* argv[])
{
    FILE *fp = fopen(argv[1], "rb");
    if (fp == NULL) return 1;
    int bzerror;
    char unused[BZ_MAX_UNUSED];
    int unusedLen = 0;
    BZFILE* bz2in = BZ2_bzReadOpen(&bzerror, fp, 0, 0, unused, unusedLen);
    if (bzerror != BZ_OK) return 2;

    bzerror = BZ_OK;
    int length = 512;
    void* buffer = malloc(length);
    while (true) {
        if (bzerror == BZ_STREAM_END && feof(fp)) {
            break;
        }
        uint n = BZ2_bzRead(&bzerror, bz2in, buffer, length);
        if (bzerror != BZ_OK && bzerror != BZ_STREAM_END) {
            return 3;
        }
        if (bzerror == BZ_STREAM_END && !feof(fp)) {
            void* unusedTemp = NULL;
            BZ2_bzReadGetUnused(&bzerror, bz2in, &unusedTemp, &unusedLen);
            if (bzerror != BZ_OK) {
                return 4;
            }
            for (int i=0; i<unusedLen; i++) {
                unused[i] = ((char*)unusedTemp)[i];
            }
            BZ2_bzReadClose(&bzerror, bz2in);
            if (bzerror != BZ_OK) {
                return 5;
            }
            bz2in = BZ2_bzReadOpen(&bzerror, fp, 0, 0, unused, unusedLen);
            if (bzerror != BZ_OK) {
                return 6;
            }
            uint n2 = BZ2_bzRead(&bzerror, bz2in, (char*)buffer + n, length - n);
            if (bzerror == BZ_DATA_ERROR_MAGIC || bzerror == BZ_DATA_ERROR) {
                return 7;
            }
            if (bzerror != BZ_OK) {
                return 8;
            }
        }
    }

    free(buffer);
    return 0;
}
```

## 環境
CentOS6.5
bzip2 Version 1.0.5
Parallel BZIP2 v1.1.6
## コンパイル
`g++ bz2test.cpp -lbz2`

# bzip2とpbzip2の違い
bzip2はシングルストリームであるがpbzip2はマルチストリーム。
こんなイメージ。

```text:bzip2
[----------------------bzip2----------------------]
```
```text:pbzip2
[--bzip2--|--bzip2--|--bzip2--|--bzip2--|--bzip2--]
```
pbzip2はbzip2で圧縮したデータが連続して格納されているため、bzip2として伸張しても途中までしか伸張したことにならない。
ストリームが終了(BZ_STREAM_END)したら、再度オープンして次のストリーム(1つのbzip2圧縮データ)を伸張する必要がある。
そのときに直前のストリームで伸張しきれていないデータを保持(BZ2_bzReadGetUnused)しておく。
ヤフオクAPI落札者一覧(myWinnerList)の取得でエラー「該当するオークションがありません。/code7202」

ヤフオクAPIをつかって落札情報を取得。
効率的に管理したいと思っていますが落札者一覧でエラー7202がでて問題を特定できません。

#①落札者一覧の取得でエラー「code7202」

##１．YConnectで接続し（tokenを保存）
##２．マイ・オークション表示（出品終了分）
https://auctions.yahooapis.jp/AuctionWebService/V2/myCloseList?output=xml&list=sold
１で得たTokenを使用して、落札された一覧を取得は成功しています。
ただしこの情報だけでは、「/Result/Winner」に落札者の
e-mailが入っておらず連絡が取れないので合わせて落札者一覧を取得

##３．マイ・オークション表示（落札者一覧）
１で得たTokenを使用して、下記を実行しましたがエラーになりました。
CODE:7202が意味するエラーの内容が検索しても探せず投稿させて頂きました。
IDは上記２で取得したIDでページにアクセスし存在する事は確認できています。
[ERROR]
	Message:該当するオークションがありません。
	Detail:Array()
	Code:7202
[PHP]
`
	$url = "https://auctions.yahooapis.jp/AuctionWebService/V1/myWinnerList?auctionid=".$id;
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Bearer ' . $access_token));
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
	$response = curl_exec($curl);
	$xml = simplexml_load_string($response);
`
#②user_idとYahoo! JAPAN IDですが
UserInfoAPIで得られるuser_id「26文字の固定長」のみユーザ識別に使えるとあるのですが、myCloseListには「Winner/Idとして」Yahoo! JAPAN IDが入ります。これでは照合できないと思うのですがmyWinnerListにて取得した場合は「/Bidder/Idとして」Yahoo! JAPAN IDとあります。
ここは結局照合不可能という事でしょうか？
タスクランナーを使わずにnpm+webpackのみでWebアプリ開発



# はじめに
タスクランナーを使わずにnpm+webpackのみでWebアプリを開発するためのシードプロジェクトを作成しました．
フロントエンド開発のツールが多く煩雑なので，できるだけシンプルにしたいというのがモチベーションです．
テストまわりは未対応で，順次追加していく予定です．

[2015/9/7]
画像ファイル（png, jpg）をビルドできるようにしました．


# シードプロジェクトの内容

## ソース

[https://github.com/nihsuy/webapp-seed-project](https://github.com/nihsuy/webapp-seed-project)

## プロジェクト構成

> ├── src : ソースファイル
> │　　├── index.html
> │　　├── images
> │　　│ 　　└── logo.png
> │　　├── scripts
> │　　│ 　　└── app.js
> │　　└── styles
> │　　　　　└── app.scss
> ├── package.json : npm設定ファイル
> └── webpack.config.js : webpack設定ファイル

## 使い方

> npm install
> npm run start

プロジェクトのルートで npm run すると，コマンドの一覧が表示されます．

* npm run start: 開発用Webサーバを起動
* npm run build: ビルド
* npm run clean: クリーン

## 利用するツール

### パッケージ管理:　npm

開発環境のパッケージ管理を主目的とするnpmとブラウザで動作するライブラリ管理を主目的とするbowerがありますが，両方をnpmで管理します．

> npmに統一する場合の問題点が[npm とフロントエンドのパッケージ管理の未来](http://havelog.ayumusato.com/develop/others/e630-npm_meets_frontend.html)に書かれています．

### ビルド:　webpack

タスクランナー（Gruntやgulp）と依存モジュールの結合ツール（Browserifyやwebpack）を組み合わせて使うことが多いですが， webpackのみを使います．

各種データ形式を読み込むためにwebpackのローダーを使います．

* **babel-loader**: ES6の読み込み
* **css-loader**, **style-loader**: CSSの読み込み
* **sass-loader**: Sassの読み込み
* **file-loader**: 画像ファイルなどの静的ファイルの読み込み

ビルド設定は webpack.config.js に書きます．

コンソールで webpack を実行すると，ビルドが走ります．
-p オプションを付与すると，出力されるファイルが最適化されます．


### 開発用Webサーバ，変更監視，自動リロード:　webpack-dev-server

コンソールで webpack-dev-server --content-base build を実行すると，開発用Webサーバが http://localhost:8080 で起動します．
--hot --inline オプションを付与すると，ファイルの変更監視，自動ビルド，自動リロードが走るようになります．
-d オプションを付与すると，デバッグ用のソースマップが出力されます．

ビルドされたデータはメモリに保持されファイル出力されません．ファイル出力する場合は別途ビルドする必要があります．
IPython Notebook上で文字列の表示


IPython Notebook上で以下のコードを実行すると，文字列がそのまま表示され，改行されません．

```python
msg = 'test\ntest\ntest\n'
msg
>>> 'test\ntest\ntest\n'
```

## 解決策
以下の様にprint()すると改行して表示されます．

```python
msg = 'test\ntest\ntest\n'
print(msg)
>>> test
>>> test
>>> test
```

ちなみに，自分はsklearnのclassification_report()関数を使って分類の結果を表示しようとしているときに，この問題？に陥りました．

こういう基本的なことはチュートリアルなどに載っていないし，なんて検索したら出てくるのかも分からず，15分ほど時間を無駄にしました．．．
UIViewの一部だけ角丸にする

参考: [how to set cornerRadius for only top-left and top-right corner of a UIView?](http://stackoverflow.com/questions/10167266/how-to-set-cornerradius-for-only-top-left-and-top-right-corner-of-a-uiview)


# Problem

UIViewの左上と右上だけ角丸にしたい。上記の参考資料を見て試したが、左上は角丸になったが右上は角丸にならなかった。

# Solution

ポイントはlayoutSubviews()をオーバーライドして、その中で角丸にする処理を実装すること。
layoutSubview()以外で角丸処理をすると、右上が角丸にならなかったり、マージンが崩れたりする。


## CustomView.swiftを作成する

```swift
class CustomView: UIView {
  var corners: UIRectCorner = [.TopLeft, .TopRight, .BottomLeft, .BottomRight]
  var radius: CGFloat = 0
  
  func roundCorners(corners:UIRectCorner, radius: CGFloat) {
    self.corners = corners
    self.radius = radius
  }
  
  override func layoutSubviews() {
    super.layoutSubviews()
    let maskPath = UIBezierPath(roundedRect: self.bounds,
      byRoundingCorners: self.corners,
      cornerRadii: CGSize(width: self.radius, height: self.radius))
    
    let maskLayer = CAShapeLayer()
    maskLayer.frame = self.bounds
    maskLayer.path = maskPath.CGPath
    
    self.layer.mask = maskLayer
  }
}
```

## 使用方法

```swift
class ViewController: UIViewController {
  @IBOutlet weak var titleView: CustomView!
  
  override func viewDidLoad() {
    super.viewDidLoad()
    // 上部のみ角丸にする
    titleView.roundCorners([.TopLeft, .TopRight], radius: 10.0)
  }
}
```
Mail_mimeDecode で base64 デコードできないメールがあった

PEAR ライブラリの [Mail_mimeDecode-1.5.5](https://pear.php.net/package/Mail_mimeDecode) にガッカリなバグがあったので共有。

ユーザーからの画像付きメールを受信して、その画像を取り出して記録する処理を書いていたのですが、特定のユーザーからのメールだけいつも処理に失敗していました。`Mail_mimeDecode::decode()` の引数に生メールを渡し、以下のようにオプションを指定すれば、base64 デコード済みの body が取得できるはずなのですが、そのユーザーからのメールだけは画像が base64 文字列のまま値を返されていました。

```php
private function __encodeToMailObject($rawMail) {
	$Decoder = new Mail_mimeDecode();
	return $Decoder->decode([
		'include_bodies' => true,
		'decode_bodies' => true,
		'decode_headers' => true,
	]);
}

// 戻り値は base64 デコードされた形になるはずなのに、
// 特定のメールだけ base64 エンコードされたまま返ってしまう
```

原因は `Mail_mimeDecode::_decodeBody()` でした。このメソッド内部では、メールヘッダーの `Content-Transfer-Encoding` の文字列を見て、どんなデコードをするかを判断します。が、この条件判断文がケースセンシティブに作られており、全部小文字で *base64* と書かれていなければ base64 decode はされないという仕様でした。

```php
// pear/mail_mime-decode/Mail/mimeDecode.php

function _decodeBody($input, $encoding = '7bit')
{
    switch ($encoding) {
        case '7bit':
            return $input;
            break;

        case 'quoted-printable':
            return $this->_quotedPrintableDecode($input);
            break;

        case 'base64':
            // 引数 $encoding が `base64` (小文字) じゃないと入れない
            return base64_decode($input);
            break;

        default:
            return $input;
```

問題のメールは `Content-Transfer-Encoding: Base64` と書かれていたため、body 部が一切デコードされずスルーされていました。

ひとまず以下のように大文字小文字を無視するように修正して解決しました。

```php
function _decodeBody($input, $encoding = '7bit')
{
    //switch ($encoding) {
    switch (strtolower($encoding)) {
```


ちなみにこのライブラリにプルリクを出したかったのですが、2010年12月以来更新が無いので無理そうです。そもそも PHP はメール送信ライブラリは山ほどあっても、受信ライブラリが少ない気がします。PHP でメール受信処理なんて誰もやらないということなのでしょうか…。


2015-09-09 追記
----
[PHP: Diff of /pear/packages/Mail_mimeDecode/trunk/Mail/mimeDecode.php](http://svn.php.net/viewvc/pear/packages/Mail_mimeDecode/trunk/Mail/mimeDecode.php?r1=305006&r2=337165)

[本家PEAR](https://pear.php.net/package/Mail_mimeDecode/download/) では2010年12月の version 1.5.5 から更新が止まっていますが、svn.php.net を見るとつい最近も作者本人によってコミットがされていました。この記事の問題も修正されているようですし、PHP7 対応までされているようなので、むしろそっちのソースを使ったほうがよさそう。

なんで PEAR に反映しないんでしょうね…？
RubyMineでのRubyの設定

いまのところこれ
`JS`とくらべて設定できることが少ない。

![Screen Shot 2015-09-01 at 2.18.04 PM.png](https://qiita-image-store.s3.amazonaws.com/0/27895/0a4aac37-adea-6a34-d9dd-5a621dfba54b.png)
Joda-timeにおけるInterval, Duration, Periodの違いについて

Joda-timeで時間間隔を表現するのにどのクラスを使うべきなのかと考えて調べてみたのでメモ。

cf: http://stackoverflow.com/questions/2653567/joda-time-whats-the-difference-between-period-interval-and-duration

## Interval

- 「時刻Aから時刻Bまでの間」
- 両端の時間が指定された時間軸の中で固定の範囲
- `contains(ReadableInstant instant)`によってある時刻がその範囲に含まれるか検出できる

## Duration

- 「ミリ秒で表現される時間の長さ」
- `Interval#toDuration`で作ったりできる

## Period

- 「時間単位(年、週、分など）で構成される時間の長さ」
- `Duration`とは違い、例えば「1年間」で表現される`Period`は計算時にうるう年をまたぐかどうかなどが考慮される

例: 2016年1月1日 -> 2017年1月1日では2月29日をまたぐため1年間の日数は366日

```
scala> import org.joda.time._

scala> val d = new LocalDate(2016,1,1)
d: org.joda.time.LocalDate = 2016-01-01

scala> val p = Period.years(1).withWeeks(5).withDays(10)
p: org.joda.time.Period = P1Y5W10D

scala> d.plus(p)
res1: org.joda.time.LocalDate = 2017-02-15

scala> d.plusYears(1)
res2: org.joda.time.LocalDate = 2017-01-01 // 一つの時間単位について計算するだけならこちらのメソッドでも可

scala> p.toDurationFrom(d.toDateTimeAtCurrentTime)
res21: org.joda.time.Duration = PT35510400S // 2016-01-01を基準にした時のDuration

scala> p.toDurationFrom(d.plusYears(1).toDateTimeAtCurrentTime)
res22: org.joda.time.Duration = PT35424000S // 2017-01-01を基準にした時のDuration
```

補足：Periodの比較は面倒

```
scala> val p2 = new Period(d, d.plus(p))
p2: org.joda.time.Period = P1Y1M2W  // 2つの日付から差分を取る

scala> p.equals(p2)
res3: Boolean = false // 時間表現が異なるため同じとみなされない

scala> val p3 = new Period(d, d.plus(p), PeriodType.yearWeekDay)
p3: org.joda.time.Period = P1Y6W3D // 差分の計算方法を年週日にする

scala> p.equals(p3)
res4: Boolean = false // でもやっぱり合わない

scala> p.normalizedStandard.equals(p3)
res17: Boolean = false // 同じP1Y6W3Dになっても一致したとみなされない

scala> p.normalizedStandard.minus(p3).equals(Period.ZERO)
res19: Boolean = true // やっと一致判定した
```

一致判定は割にあわないですね…。
論理削除 Casual Talks #1 参加メモ（後半のみ）

[論理削除 Casual Talks #1 : ATND](https://atnd.org/events/68902)

後半からうしろのほうでみてたので感想を書きます。発表内容と自分の感想、メモがごっちゃになってるのでご注意ください。

まともなまとめは、[#ronsakucasual DBの論理削除についてひたすら共有する 論理削除 Casual Talks #1 にいってきたまとめ](http://blog.mogmet.com/ronsakucasual-1/)を参照ください。

### 20:30 - 20:50	@misoobu	論理削除と、そこでのElasticsearch活用（仮）

    履歴テーブル

肥大化する -> パーテーション分ける
外部キー制約使いにくい

    削除ログ

そもそもログはRDBにいらない？
そのシステムに本当に必要なものはなんなのか

    Elasticsearch

JSONでINSERTできるのでMongoDB的に使える

#### QA

    Q. Railsのpapertrail, Auditは検討した？

用途が違うので、という答えだったような。

### 20:50 - 21:10	moro	「論理削除を避ける(仮)」

    絶版ステータス

Railsのscope使うとキレイだけど、default_scopeは違う。一時の楽のためにあとでツラくなりやすい。

    論理削除を入れると、どこまでやるのかがあいまいになる
    全部のテーブルに入れる？
    JOINするときツライ

論理削除は伝染する

	データの終わりを考えよう

データ、ドメインのライフサイクルを考えよう

### 21:10 - 21:30	gyugyu	ホスティングの話＋論理削除と言う前に（仮題）

データが外部リソースと連携する場合の話。とても興味深い。

	ユーザーは論理削除という言葉を使わない

開発者は内部事情を語りすぎる。もっとドメインをみつめて、開発者事情での変な言葉を使わないように、使わなくてすむようにしたほうが、幸せになれる。

論理削除の話を聞きに来て、DDDが出てくると思わなかった。これもひとつの飛び道具だった。

## 全体の感想

どの発表も入口は論理削除でしたが、出口はデータモデル、ドメイン設計をまじめに取り組もう、ユーザーの言葉に寄り添ったシステムを作ろう、というしごく真っ当なものでした。別に論理削除を完全否定はしていなくて、思考停止して論理削除を取り入れると不幸になるよ、というアンチパターンの話なんですね。

論理削除の周辺の話題として、データのアーカイブどうするというのと、オペミスにどう対策するかという話もあるけど、そちらはRDBMSのひとたちがすでに考えてきてることだと思うので、商用DB使うというのもひとつの解なのかもしれない。
【CEDEC2015メモ】いまどきのゲーム制作環境


いまどきのゲーム制作環境
エディター群とそのバックエンド、開発スタッフ間のコミュニケーションの具体的な方法解説
http://cedec.cesa.or.jp/2015/session/ENG/3250.html

興味深いところのみ抜粋。

## アセット共有
アセット共有で一番やっかいな問題は競合。

解決手段として以下が挙げられる。

* ロック 
* ファイル分割
* マージ

#### △ ロック
競合は避けられるが、ロック中は他の作業者の作業を止める可能性がある。


#### △ ファイル分割
ある程度の細分化は効果はある。しかし根本的な解決にならない。

#### ◯ マージ
最終的にはやはりマージするしかない。

## アセットマージ

ここでは自社でマージツールを作っているとのこと。
アセット自体も自社フォーマット。

アセットはマージしやすいXMLかJSONで作成。
マージする際は構文に気をつける事。

#### マージツール

ファイルでは無く操作リストをマージする。

| 元ファイル|自分が編集したファイル|他人が編集したファイル|マージ後のファイル|
|:-:|:-:|:-:|:-:|
| base|mine |thier|result|

競合が発生した場合はは以下のフローでマージ。

* baseにmineの操作リストを反映
* baseにthierの操作リストを反映

##  コンフリクト

ユーザに選択させるのは難しいのでルール化する。
例えば、先出し優先など。
そうすればユーザは混乱しない。

#### バグでは無くまじマージを疑え
ユーザは自分がコミットしたものがおかしいとまずバグを疑ってくる。
エンジニアの工数を取らせないためにもまずマージを疑え。

## テレメトリ

テレメトリとは遠隔測定法。
例えば、配布したアプリやツールの情報を測定したりすること。

#### ログをサーバに保存する。
NASにテキストとして保存するのは問題がある。

* アクセスが限定される
* 可読性が悪い
* ログはフォーマットがそれぞれ異なる場合がある

#### データベースに保存

RESTfulAPIでJSONを送信しMongoDBに保存する。
ビューワを作成し可読性を高める。

送信する例
・クラッシュレポート
・データ収集

## 安定した環境の提供

安定した環境を提供しないとにどうなる？
A. 問題が発生して開発が止まる

#### CI（継続的インテグレーション）の導入

ツールはJenkinsを使用。

CIで以下を保証する。

* 起動
* 終了
* メモリリーク発見

#### 配布

起動時にバージョンチェックして古いバージョンはプレイさせない。

## ネイティブキャッシュ

ネイティブキャシュとは・・・
>高速にアクセス出来るキャッシュを作成し、オーバーヘッドを軽減する。

ローカル環境でネイティブキャシュを作成するのは時間がかかり、
時間を浪費してしまう。

ファイルが更新された際にコミットをJenkinsにHookし、
更新されたファイルのネイティブキャシュを作成する。
HardMailCheck 始めました

# HardMailCheck つくりました。

SMTP接続してメールアドレスの存在確認をするライブラリを作りました。  

- github: https://github.com/fantasista21jp/hard_mail_check
- packagist: https://packagist.org/packages/fantasista21jp/hard_mail_check

### 注意点

100％完璧にメールアドレスが存在するもののみを通すという思想で作ってるので、ここでエラーと判定されたけど、実は存在するといったメールアドレスもありえます。
なので、  
『SESなどのバウンスメールの比率に対しシビアな対応をされるメールサービスを使用する時、メールアドレスの精査をしたい！』  
そんな時に使って下さい。  

また、smtpサーバによっては、短期間に何度も存在しないメールアドレスをチェックすると、一定期間接続をブロックされてしまうこともあります。
※有名どころでは、 docomo ですね。『421 Service not available』エラーを返すようになります。  
メールアドレスが存在しないのではなく、ブロックされたリストも取得できるようにしているので、そこはうまい具合に使って下さい。

## サンプルコード

```
<?php

require 'vendor/autoload.php';

$fromEmail = 'shimada@fusic.co.jp';
$checkEmailList = [
    'hoge@docomo.ne.jp',
    'hoge.shimada@gmail.com',
    'hogehoge.shimada@gmail.com',
    'hoge@fusic.co.jp',
    'hoge@aaaaaa',
    'fantasista21jp@docomo.ne.jp',
    'fantasista21jp@docomos.ne.jp',
    'hoge..hoge..hoge@docomo.ne.jp',
];

$hardMailCheck = new \HardMailCheck\HardMailCheck();
$hardMailCheck->setEmailList($checkEmailList);
try {
    $hardMailCheck->checkEmailList($fromEmail);

// 個々のメールアドレスのチェックで引っかかった時
} catch (\HardMailCheck\Exceptions\EmailListNotValidException $e) {
    var_dump($e);
    var_dump($hardMailCheck->getErrorEmailList()); // メールアドレスが存在しない（っぽい）リスト（smtpブロック含む）
    var_dump($hardMailCheck->getBlockEmailList()); // smtpサーバでブロックされたリスト

// 設定値がミスってる時はこっちに入る
} catch (\HardMailCheck\Exceptions\HardMailCheckException $e) {
    var_dump($e);
}

```

### お願い

telnet(fsockopen)で接続してる辺りの処理がかなり雑になってます。
なんかいい方法あったら教えて下さいな。
RecyclerViewのItemDecorationをViewTypeで指定できるライブラリ(RecyclerItemDecoration)を作ってみた。


[RecyclerItemDecoration](https://github.com/magiepooh/RecyclerItemDecoration)

## RecyclerView

AndroidのサポートライブラリではAPILevel7以降で`RecyclerView`をサポートしています。
`ListView`では標準で行間の区切り線が描画されていましたが、`RecyclerView`では描画されません。
`RecyclerView`では区切り線が専用のクラスに切りだされ、開発者がより柔軟に実装することが可能になりましたが、区切り線を表示する場合は自分で実装する必要があります。

シンプルな`RecyclerView`の区切り線の実装方法についてはこちらを参考にしてください。
http://wasabeef.jp/recyclerview-itemdecoration/

## ViewType

`RecyclerView`で様々なレイアウトを実現しようとした時に`ViewType`を使用すると思います。`ViewType`でレイアウトするXMLリソースやBindするモデルが変えることができます。

## RecyclerViewのViewTypeだけで区切り線を描画するRecyclerItemDecoration

ViewTypeで位置を指定して区切り線を描画するライブラリを作ってみました。
ライブラリはこちら→[RecyclerItemDecoration](https://github.com/magiepooh/RecyclerItemDecoration)

### 何が出来るか
positionを指定して多様な区切りを実現するライブラリは存在していたのですが、`ViewType`で指定するライブラリはなかったため作ってみました。↓のようなことができます。

![demo-vertical](https://raw.githubusercontent.com/magiepooh/RecyclerItemDecoration/master/art/demo_vertical.gif "demo-vertical") ![demo-horizontal](https://raw.githubusercontent.com/magiepooh/RecyclerItemDecoration/master/art/demo_horizontal.gif "demo-horizontal")

このスクショでは様々なViewTypeが実装されたRecylerViewにそれぞれ異なる区切り線が表示されています。

### 使い方

ライブラリの使い方は以下のようになります。

```
RecyclerView.ItemDecoration decoration = ItemDecorations.vertical(this)
        .first(R.drawable.shape_decoration_green_h_16)
        .type(DemoViewType.LANDSCAPE_ITEM.ordinal(), R.drawable.shape_decoration_gray_h_12_padding)
        .type(DemoViewType.LANDSCAPE_TILE.ordinal(), R.drawable.shape_decoration_cornflower_lilac_h_8)
        .type(DemoViewType.LANDSCAPE_DESCRIPTION.ordinal(), R.drawable.shape_decoration_red_h_8)
        .last(R.drawable.shape_decoration_flush_orange_h_16)
        .create();

recyclerView.addItemDecoration(decoration);
```

区切り線を表示したい`ViewType`と区切り線のDraweableリソース(もしくはDrawableオブジェクト)を引数に指定するだけです。先頭と最後の区切り線については`first()`, `last()`で指定することができます。

### Gradle

このライブラリはjCenterに公開しているため、AndroidStudioを使っている場合は`build.gradle`に以下の様に記述するとライブラリを使用できます。

```
compile 'com.github.magiepooh:recycler-itemdecoration:1.1.0@aar'
```

### Support
このライブラリでサポートしているLayoutManagerは以下のものになります。

- LinearLayoutManager(Vertical)
- LinearLayoutManager(Horizontal)
- LinearLayoutManager(Horizontal+Reverse)

### RecyclerItemDecorationの利点
PositionではなくViewTypeで区切り線を指定すると、１行１行の順番や数が変わっても区切り線の実装部分には何も変更が起ません。
例えば、「４個表示しているものを８個にしてほしい」「表示位置を変えて欲しい」という要望があった場合にPositionで指定しているとその条件を書き換える必要がでてきます。(←サービス運用中の経験談ｗ)

このライブラリではそこは考慮せずに使用することができます。

## まとめ
PositionではなくViewTypeで区切り線を表示するRecyclerItemDecorationを作ってみました。
使っていただけたら嬉しいですm(_ _)m
CentOS 6.5にRundeckをinstall

## 環境
CentOS 6.5  
Rundeck 2.5.3  


## VM Setting
Rundeckを動かすVMをvagrantで構築

```
vagrant init centos_6_5
```
出来たVagrantファイルに以下を追記

```
config.vm.network "forwarded_port", guest: 4440, host: 4447
config.vm.network :forwarded_port, id: "ssh", guest: 22, host: 2227
config.vm.network "private_network", ip: "192.168.33.17"
```
上記はそれぞれVirtualBox上で複数のVMを立ち上げるため

再立ち上げ

```
vagrant up
```

## Rundeck　install前の準備

SSHでログイン後  
自分のboxにはwgetが入っていないのでwget install

```
$ sudo yum -y install wget
```

Oracle JDK install  
(自分の好みでOpenJDKではなくOracle JDK。たぶんOpenJDKでも動くと思う。)  

```
$ wget --no-check-certificate --no-cookies - --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u60-b27/jdk-8u60-linux-x64.rpm
$ sudo rpm -ivh jdk-8u60-linux-x64.rpm 
```

## Rundeck　install

以下を参照しながらRundeck install  
[Rundeck Downloads](http://rundeck.org/downloads.html)

```
sudo rpm -Uvh http://repo.rundeck.org/latest.rpm
sudo yum -y install rundeck
```

## Rundeck　install後の起動・確認

Rundeck起動

```
$ sudo service rundeckd start
$ sudo chkconfig rundeckd on
```

このままではログイン画面からの遷移がlocalhostに飛ばされうまくいかない。ので設定をいじる。  
/etc/rundeck/rundeck-config.properties の設定を変更する
``` gralils.serverURL ``` の値をRundeckのサーバーIP or ホスト名にしないとログイン画面からまともに遷移できない。

```
$ sudo vi /etc/rundeck/rundeck-config.properties
 
#loglevel.default is the default log level for jobs: ERROR,WARN,INFO,VERBOSE,DEBUG
loglevel.default=INFO
rdeck.base=/var/lib/rundeck
 
#rss.enabled if set to true enables RSS feeds that are public (non-authenticated)
rss.enabled=false
# change hostname here
grails.serverURL=http://<RundeckサーバのIP or ホスト名>:4440
dataSource.dbCreate = update
dataSource.url = jdbc:h2:file:/var/lib/rundeck/data/rundeckdb;MVCC=true;TRACE_LEVEL_FILE=4
```

host側から
http://192.168.33.17:4440/
にアクセスするとログイン画面が表示される。  
デフォルトの管理者でLoginしてみる

|id|password|
|:--|:-------|
|admin|admin|

以下の画面が表示されたら成功
![Rundeck_login.PNG](https://qiita-image-store.s3.amazonaws.com/0/18012/3827d112-ebcc-3fd2-0e6b-042b919b02bb.png)
チェックボックスの同時選択できる数を制限してみる

自作jQueryプラグイン第二弾
https://github.com/uchikoba/jquery.checkboxSelectableLimitter

jQuery本体は別途読み込んでください。

```:Sample
<input type="checkbox" class="chk" value="1">チェック１
<input type="checkbox" class="chk" value="2">チェック２
<input type="checkbox" class="chk" value="3">チェック３
<input type="checkbox" class="chk" value="4">チェック４
<input type="checkbox" class="chk" value="5">チェック５

<script type="text/javascript" src="jquery.checkboxSelectableLimitter.js"></script>
<script type="text/javascript"><!--
$(document).ready(function () {
  $('.chk').checkboxSelectableLimitter({
    limit : 3,
    callback : showLimit
  });
});
function showLimit() {
  // 残り個数を表示するような処理
}
// --></script>
```
Node.jsでフォームからアップロードされたファイルを保存する

*hiroqn@github 氏より、以下のソースは間違いです。
やはりリクエストボディの解釈が必要ですので入力しないでください。*

掲題の処理をする必要があったので少し調べてみたのですが、これだけでいけるようです。

```js
var fs = require('fs');
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/html'});
  if (req.method === 'GET') {
    res.end('<form method="post" enctype="multipart/form-data"><input type="file" name="file"><input type="submit"></form>');
  } else if (req.method === 'POST') {
    var out = fs.createWriteStream('save.jpg');
    req.pipe(out);
    res.end('end.');
  }
}).listen(3000);
```

`localhost:3000`にアクセスしてフォームからファイルをアップロードすると`save.jpg`という名前で保存されます。

最初は[busboy](https://github.com/mscdex/busboy)などでリクエストボディを解釈して保存する必要があるのかなと思っていたのですが、なぜパイプを繋ぐだけで保存できるのか、実はよく分かっていません。