OmniAICreator/Qiita-1.07M huggingface dataset:
KotlinでRxAndroid1.0を使う

- KotlinでRxAndroidを使ってみたという話。RxAndroidを追加してViewObservableやWidgetObservableを試そうとしたものの、そんなクラスはいないと言われる。。。

## 公式に書いてあった
https://github.com/ReactiveX/RxAndroid/wiki#moved

```
WidgetObservable and ViewObservable have been rolled into (and improved in) RxBinding.
```

- ということで前のバージョンではRxAndroid本体に含まれていたもののいくつかはExtension化したらしい。Schedulerは本体に含まれているので非同期回りのハンドリングで使いたいだけなら本体だけで足りそう。

## 試してみる
### Extensionを追加
- build.gradleのdependenciesに追加。Kotlin向けのは最後に`-kotlin`をつけてねと書いてあるので従う。

```groovy:build.grade
dependencies {
    ext.rx_android_kotlin_version = '0.3.0'
中略
    compile 'io.reactivex:rxandroid:1.0.1'
    compile 'io.reactivex:rxjava:1.0.14'
    compile "com.jakewharton.rxbinding:rxbinding-kotlin:$rx_android_kotlin_version"
    compile "com.jakewharton.rxbinding:rxbinding-support-v4-kotlin:$rx_android_kotlin_version"
    compile "com.jakewharton.rxbinding:rxbinding-appcompat-v7-kotlin:$rx_android_kotlin_version"
}
```
### 実装
- EditTextの入力欄が4つあって、全部何かしら入力されたらSubmitボタンを有効にするというシチュエーションで作ります。

```kotlin:RxSampleFragment.kt
package me.rei_m.kotlinsample.fragments

import android.os.Bundle
import android.support.v7.widget.AppCompatButton
import android.support.v7.widget.AppCompatEditText
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

import com.jakewharton.rxbinding.widget.RxTextView

import rx.Observable

import me.rei_m.kotlinsample.R

public class RxSampleFragment : AbstractFragment() {

    companion object {
        fun newInstance(): RxSampleFragment {
            return RxSampleFragment()
        }
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {

        val view = inflater.inflate(R.layout.fragment_rx_sample, container, false)

        // 各入力欄のObservableを取得
        val orderName = RxTextView.textChanges(view.findViewById(R.id.edit_order_name) as AppCompatEditText)
        val orderPostalCode = RxTextView.textChanges(view.findViewById(R.id.edit_order_postal_code) as AppCompatEditText)
        val orderAddressFirst = RxTextView.textChanges(view.findViewById(R.id.edit_order_address_first) as AppCompatEditText)
        val orderAddressSecond = RxTextView.textChanges(view.findViewById(R.id.edit_order_address_second) as AppCompatEditText)

        // Buttonを取得
        val submitButton = view.findViewById(R.id.button_rx_submit) as AppCompatButton
        submitButton.isEnabled = false

        // ObservableをcombineLatestに食わして各項目のどれかに変更があった場合はStreamが流れるようにする
        // 引数の最後のAction1で流れてきた値をチェックしてすべて入力済ならtrueを流す
        Observable.combineLatest(orderName,
                orderPostalCode,
                orderAddressFirst,
                orderAddressSecond,
                { v1, v2, v3, v4 -> (0 < v1.length && 0 < v2.length && 0 < v3.length && 0 < v4.length)
        }).subscribe({isValid ->
            // 従いボタンの有効/無効を切り替える
            submitButton.isEnabled = isValid
        })

        return view
    }
}
```

- Kotlinいまのところいい感じです。
- コードはこちらに https://github.com/rei-m/kotlin_sample
【メモ】正規表現でn桁以内の数字列のみ検索する

不定形の文字列中の数字部分を抽出してちょっと計算したいんだけど、
1000桁みたいなint型やdouble型に変換したらややこしくなるレベルの桁数が出てきたら
面倒くさくなるからそれは除いて検索しようってなったときにちょっとハマったからメモ。
\d{1,5}とかやっても1234567890とかが出てきたら12345と67890で分かれてマッチしちゃうし
どうしようって思ってたところ、

```php:search_number.php
$number_text =
'999999999999999999
19
18782
999999999999999999999
18782
777
999999999999999999999999
37564
1hoge22bar333foo4444fuga55555piyo666666bora7777777toto88888888';
$pattern = '/(?<!\d)\d{1,5}(?!\d)/';
preg_match_all($pattern, $number_text, $result);
var_dump($result);
//結果↓
// array(1) {
// [0]=>
// array(10) {
// [0]=>
// string(2) "19"
// [1]=>
// string(5) "18782"
// [2]=>
// string(5) "18782"
// [3]=>
// string(3) "777"
// [4]=>
// string(5) "37564"
// [5]=>
// string(1) "1"
// [6]=>
// string(2) "22"
// [7]=>
// string(3) "333"
// [8]=>
// string(4) "4444"
// [9]=>
// string(5) "55555"
// }
// }
```
どうやらこれで行けたっぽい
### 簡単な解説
```php:正規表現
'/(?<!\d)\d{1,5}(?!\d)/'
```
\d{1,5} = 1文字以上5文字以内の半角数字
(?<!\d) = 直前が半角数字でない
(?!\d) = 直後が半角数字でない
否定先読みとか否定後読みとかのアレですね。
進捗を取りながらファイルをダウンロードする

__＿人人人人人人人人人人＿__
__＞　進捗どうですか！？　＜__
__￣Y^Y^Y^Y^Y^Y^Y^Y^￣__

僕はダメです。

進捗、大事ですよね。毎日進捗に追われる日々。

ダウンロードでも進捗は大事です。小さなファイルを落とすぐらいならすぐに終わって問題ないのですが大きなファイル、例えばLinuxのディストリのisoファイルなんかはギガバイト級だったりするので自分で作ったプログラムで軽々しくダウンロードするといつ終わるのか分からなくてドキドキします。ルータのランプを眺めてダウンロードが行われていることを予想したりします。

そういうわけで進捗をとりながらダウンロードするhaskellのプログラムを書きます。

主に使うパッケージはみんな大好きhttp-conduitさんとstmさん。

まずは進捗を入れるためのデータ型から。並行処理ができるようにSTMを使って実装します。

```hs
type URL = String

data Progress = Progress {
  url :: URL
, size :: (TVar Integer)
, total :: (TVar Integer)
, cancel :: (TVar Bool)
}

newProgress :: URL -> IO Progress
newProgress u = Progress u <$> newTVarIO 0 <*> newTVarIO 0 <*> newTVarIO False

packProgress :: Progress -> IO (URL, Integer, Integer, Bool)
packProgress pg = atomically $ do
  s <- readTVar . size $ pg
  t <- readTVar . total $ pg
  c <- readTVar . cancel $ pg
  return (url pg, s, t, c)
```

packProgressではreadTVarIOで実装した方がパフォーマンスが上がるかもしれませんが、```s,t,c```の間で齟齬が生じる可能性があるのでatomically内でまとめて処理します。進捗を見たいだけならあまり気にしなくてもいいでしょうが。

今回はpackProgressの結果はタプルにしていますが、新しくデータ型を作ってアプリカティブスタイルにしたいですね。

続いてダウンロードする部分。

```hs
import qualified Data.ByteString as B (length)
import qualified Data.ByteString.Char8 as B (unpack)
```

残りのimportは適当にhackage見てください。

```hs
download :: Progress -> IO ()
download pg = do
  req <- parseUrl . url $ pg
  man <- newManager tlsManagerSettings
  runResourceT $ do
    res <- http req man
    let cl = maybe 0 (read . B.unpack) . lookup hContentLength . responseHeaders $ res
    liftIO . atomically . flip writeTVar cl . total $ pg
    responseBody res $=+ updateProgress pg $$+- sinkNull

updateProgress pg = await >>= maybe (return ()) go
  where
    update len = atomically . flip modifyTVar (+ len) . size $ pg
    go chunk = do
      let len = B.length chunk
      liftIO . update . toInteger $ len
      flag <- liftIO . readTVarIO . cancel $ pg
      if flag then return () else do { yield chunk; updateProgress pg }
```

末尾再帰最適化とかよくわからないです。

コンソールに出力したい時は```let len = B.length chunk```の次辺りで```liftIO $ packProgress pg >>= print```とかすればいいんじゃないでしょうか。

sinkNullに流し込んでいるのでファイルへ保存はしていません。
保存したい場合はsinkFileなりsinkHandleにしてください(conduit-extraにあります)。

依存パッケージは

* base
* bytestring
* transformers
* conduit
* http-conduit
* resourcet
* http-types
* stm

辺り。stackのlts-3.6で書きました。

これを使えばダウンロードの
__＿人人人人人人人人人＿__
__＞　進捗大丈夫です　＜__
__￣Y^Y^Y^Y^Y^Y^Y^￣__
メタプログラミングの考えをRubyで使用するときのパターン

# メタプログラミングとは
「コードを記述するコードを記述すること」と一般的には呼ばれている。

rubyのメソッドである「find」「find_each」「find_in_batches」も抽象化して考えることができる（メタプログラミングかどうか実際のところ、調査不足でわからないが）

# どういうときに使用するのか
そもそも・・メタプログラミングすると動的にプログラムを実行することができる。プログラムの一部をパラメーター化することでコードの重複を取り除くこともできる。うまく使えばリーダブルにもなる。がしかし、使い方によっては理解しにくくなったり、メンテナンスしにくくなったりする。

処理を1箇所に局所化できるか、、、言いかえると、
「メタプログラミングでやっていることの詳細を知らなくても使えるくらい抽象化できるか」


# どうやって使用していくのか
主に２パターンだと考えてよい

パターン１「モンキーパッチ」
既存のクラスを拡張し上書きすること

```
class Fixnum
  def +(v)
    self - v
  end
  def *(v)
    self / v
  end
end
puts 42 + 42
puts 42 * 42
```


パターン２「動的なメソッド定義」
似たような処理を持つメソッド群を、まとめて定義すること
(具体例でコードを出します)

## そのときに気をつけるべきポイントは
パターン１
全ての文字列が保持しても問題のない汎用的な機能か見極めることが大事
→意図していない挙動になりバグにつながる

パターン２
method_missing
「未定義メソッドに対しても好きな処理を加えられる」
→バグが起こりやすい、起こっても特定しにくい
→唯一性を考えてメソッドを作成する必要がある

# 実際の例
パターン１に関してはあまり実行する機会がなさそうなので今回はパターン2のみ
扱います。

```
<% if request.path=~ /^\/top/ %>
  <%# ITエンジニア %>
  <% if @login_user.exp_job_types == "10" %>
    <% job = engineer %>
  <%# デザイナー %>
  <% else @login_user.exp_job_types == "20" %>
    <% job = designer %>
  <% end %>
<% end %>
```


```
  #経験職種（大分類）
  def experienced_job?(login_user,type)
    login_user.exp_job_types.present? && login_user.exp_job_types == number
  end
```

```
@login_user.experienced_job?(@login_user,JobType::IT_ENGINEER)
```

rubyは引数でどうこうする言語ではない。
つまり今回experienced_parent_job_engineer?とかexperienced_parent_job_creative_web?とかってメソッドがそれぞれ別個で存在するように作っているのはRuby的には違和感がない。。が・・・今後もこの形のメソッドを作成する可能性は十二分にあることはなんとなくわかる。また同じメソッドがいくつもあるのには違和感がある→メタプログラミングだっ！

```
  　def experienced_job?(number)
      exp_job_types.present? && exp_job_types == number
    end

    def method_missing(method_name,*args)
      #正規表現でメソッド呼びだし
      method_name.to_s.match(/^experienced_parent_job_(\w+)\?$/) do|ms|
        super unless JobType.const_defined?("#{ms[1].upcase}")
        return experienced_job?(eval"JobType::" + ms[1].upcase)
      end
      super
    end
```

# おまけ(マッチした複数の文字列を取得)

よく見かけるのは正規表現オブジェクトのパターンにマッチした文字列を取得するというもの。ただ1つのパターンをいくつかに分割し、それぞれの部分にマッチした文字列を取得することも可能であり、このパターンのものがメタプログラミングのときにはよく目につく。

```
def method_missing(method_name, *args)
    if /^(.+)_with_save(\!?)$/.match(method_name)
      if defined? $1
        send($1,*args)
        if $2.blank?
          return self.save
        else
          return self.save!
        end
      end
    end
・
・
・
・
end
```
マッチすると括弧の数だけ変数「\$1」や変数「\$2」に部分文字列が代入されていきます。順番はパターンの中でマッチ箇所が現れた順となります。
ActiveRecordに特定条件の時だけ有効になるwhere文を追加する

# 導入

controllerとかで稀によくある特定条件の場合だけ条件式を追加する処理が見た目悪くてなんとかしたかった。
※ 検索とかそんな時に比較的よく見かける

（例）検索条件に"今日"が入ってきた時には「作成日が今日」を検索する

```rb
@items = User.where(public_flag: true)
@items = @items.where(created_at: Date.today) if params[:filter] == "今日"
```

（例）名前が入力されたらその名前のユーザを返す。入力が空なら全件返す

```rb
@items = params[:name].present? ? User.where(name: params[:name]) : User.all 
```

# 何とかする

rails4から ``` where.not(id: 1) ``` みたいな書き方で1行でいい感じに完結する書き方を模索

## where.if の実装

where.if(true/false, query) で 第1引数に booleanを渡してtrueならqueryを実行、falseなら不採用を実現する。

```irb
User.where.if(false, id: 1).to_sql
=> "SELECT `users`.* FROM `users`"
User.where.if(true, id: 1).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1"
```

### 拡張

```ruby
ActiveRecord::QueryMethods::WhereChain.include(Module.new do
  def if(condition, opts, *rest)
    return @scope unless condition
    @scope.where_values += @scope.send(:build_where, opts, rest)
    @scope
  end
end)
```

 ## 書き直す

（例）検索条件に"今日"が入ってきた時には「作成日が今日」を検索する

```ruby
@items = User.where(public_flag: true).where.if(params[:filter] == "今日", created_at: Date.today) 
```

（例）名前が入力されたらその名前のユーザを返す。入力が空なら全件返す

```ruby
@items = User.where.if(params[:name].present?, name: params[:name]) 
```

## 参考
Rails 4.2 で Arel を使って OR クエリを構築する
http://qiita.com/QUANON/items/d6772127ffc0e7b78759
chshできない環境でログインシェルを変更する（したように見せかける）

# デフォルトのログインシェルがsh系の場合

~/.profile に

```bash
exec zsh
```

とか書く


# デフォルトのログインシェルがcsh系の場合

~/.login に

```bash
exec zsh
```

とか書く
[tvOS]UITextViewをSiri Remoteでスクロールする


```swift
textView.panGestureRecognizer.allowedTouchTypes = [NSNumber(integer: UITouchType.Indirect.rawValue)]
```

panGestureRecognizerのallowedTouchTypesにIndirectを指定すれば良い。
allowed`Touch`Typeなので注意（pressじゃないよ

また、必要に応じて`userInteractionEnabled`と`selectable`を有効にしておくと良い。

確実にスクロールさせたい時は`preferredFocusedView`をオーバーライドさせる。
Optional bindingに関して

#Start Developing iOS Apps. optional bindingに関して

##Optional Binding構文
```
オプショナル型は、下記のようにif文の条件で使用することができます。
値が空(nil)の場合はfalse、それ以外はtrueを返します。

嬉しい点 => nilチェックとアンラッピングができるから嬉しい
```

```
unwrap

値が空(nil)ではない事を表す。
アンラップはラップ（包装）の反対で、オプションという包装紙に包まれた変数の包装を解くイメージです。

アンラッピング 方法1

変数 = オプショナル型 <= unwrap、値が空ではない状態にする事

アンラッピング 方法2

オプショナル型の変数名の後ろに「!」マークをつける

var price: Int?
price = 300
let priceWithTax = calculateTax(price!) <=ココ

```
```
var price: Int? = 100
if let p = price {
    print("価格：\(p)円")
} else {
    print("価格：未定")
}
var price: Int? = 100

if var p = price {
    p -= 10
    print("割引価格：\(p)円")
}
```

参考URL
http://tea-leaves.jp/swift/content/%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%8A%E3%83%AB%E5%9E%8B

http://ai-future.hatenablog.jp/entry/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E6%9C%AA%E7%B5%8C%E9%A8%93IT%E6%A5%AD%E7%95%8C%E4%BC%81%E6%A5%AD%E4%BC%9A%E7%A4%BE%E5%B0%B1%E8%81%B7%E8%BB%A2%E8%81%B7
JavaScriptとGroovyでマイナンバーのチェックデジットを計算する


まだ手元には届いてないけど、マイナンバー制度始まりましたね。とある業務で、マイナンバーのチェックデジットを計算するロジックを書いたので記録。

業務で必要だったのはJavaScript。で、なんとなく書きたくなって書いたのがGroovy。間違えてたら、大変なのでご指摘いただけるとうれしいです。

ちなみに、個人用のマイナンバーは12桁の1桁目がチェックデジット。法人用マイナンバーは13桁の13桁目がチェックデジット。

個人用マイナンバーのチェックデジットは、法律で以下のように定義されている。

```
第五条 　令第八条の総務省令で定める算式は、次に掲げる算式とする。
算式
　１１―（ｎ＝１（シグマ）１１（Ｐｎ×Ｑｎ））を１１で除した余り）
　ただし、（ｎ＝１（シグマ）１１（Ｐｎ×Ｑｎ））を１１で除した余り≦１の場合は、０とする。
算式の符号
　Ｐｎ　個人番号を構成する検査用数字以外の十一桁の番号の最下位の桁を１桁目としたときのｎ桁目の数字
　Ｑｎ　１≦ｎ≦６のとき　ｎ＋１　７≦ｎ≦１１のとき　ｎ―５ 
```

## JavaScript版
これをJavaScriptで書くと、こんな感じ。

```JavaScript
function calcCheckdigit(myno) {
  var divisor = 11;
  var sigma = 11;
  var sum = 0;
  var pn = 0, qn = 0;

  for (var n = 1; n <= sigma; n++) {
    pn = parseInt(myno.substr(sigma - n, 1));
    qn = (n >= 1 && n <= 6) ? n + 1 : n - 5;
    sum += pn * qn;
  }

  return (sum % sigma <= 1) ? 0 : divisor - (sum % divisor);
}
```

マイナンバー **123456789018** のチェックデジットが正しいかは、こんな感じで求める。

```JavaScript
var myno = "123456789018";
var checkDigit = calcCheckdigit(myno);

(checkDigit.toString() === (myno.substring(myno.length - 1, myno.length)));
```
## Groovy版
続いて、あまり需要のなさそうなGroovyで書いた場合。

```Groovy
def myno = "123456789018"

def divisor = 11
def sigma = 11
def sum = 0
def pn = 0, qn = 0

(1..sigma).each { n ->
	pn = myno[sigma - n] as int
	qn = (n >= 1 && n <= 6) ? n + 1 : n - 5
	sum += pn * qn
}

def checkDigit = (sum % sigma <= 1) ? 0 : divisor - (sum % divisor)

println(checkDigit)
assert(checkDigit as String == myno[myno.length() - 1])
```

## 法人番号をJavaScriptで
法人番号のチェックデジットは、JavaScriptでしか書いてない。
インターフェースが個人番号と違うのは、自覚してます…。

```JavaScript
function isCorporateCheckdigit(myno) {
  var divisor = 9;
  var sigma = 12;
  var sum = 0;
  var pn = 0, qn = 0;

  for (var n = 1; n <= sigma; n++) {
    pn = parseInt(myno.substr(myno.length - n, 1));
    qn = (n % 2 == 1) ? 1 : 2;
    sum += pn * qn;
  }

  var checkDigit = divisor - (sum % divisor);

  console.log(checkDigit);
  return (checkDigit.toString() === (myno.substring(0, 1)));
}
```
Amazon Linux AMI php56で、idn_to_asciiが使えなかった。

# 1. やったこと
yumで、php56-intlをインストールしました。

```
$ sudo yum install php56-intl
```
よくあるpunycode変換サイトの様に融通がきかないので、parse_urlしてhostのところだけ変換する様に使う。
iOSアプリでwavからflacへの変換を行う

# はじめに

iOSでは標準でflacファイルをサポートしていません。
外部ライブラリを用いて、wavからflacへ変換する手順をまとめたので共有します。

環境はXcode7.1、iOS9、Objective-cです。

[FLACとは](https://ja.wikipedia.org/wiki/FLAC)

# ライブラリ取得

ライブラリを2つダウンロードします。

[IDZPrecompiledFLAC](https://github.com/iosdevzone/IDZPrecompiledFLAC)
[IDZPrecompiledOgg](https://github.com/iosdevzone/IDZPrecompiledOgg)

arm64対応でビルドしてあって非常にありがたい！

# プロジェクトに追加

以下2点に注意。

・Link Binary With Librariesから追加
Build Phasesから追加します。

・bitcodeサポートをNOに変更
Build SettingsのEnable BitcodeをNOに設定。

# wav to flac 変換処理

こちらから2ファイルダウンロードしプロジェクトに追加します。

[wav_to_flac](https://github.com/jhurt/wav_to_flac)
1. wav_to_flac.h
2. wav_to_flac.c

.cファイルのinclude箇所を少し修正。
「FLACiOS/」から「FLAC/」に変えます。

```c:wav_to_flac.c
#include "FLAC/metadata.h"
#include "FLAC/stream_encoder.h"
```


ここからはObjective-c。

任意の.mファイルにて呼び出し。
今回はbundleに含めたwavファイルをflacに変換しdocuments直下に出力しています。

```objc:ヘッダをincludeする
#include "wav_to_flac.h"
```

```objc:変換処理呼び出し

- (void)convertSample
{
    NSString *documentsDirPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
    NSString *flacFileWithoutExtension = [documentsDirPath stringByAppendingPathComponent:@"flac_001"];
    
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *waveFile = [bundle pathForResource:@"001" ofType:@"wav"];
    
    int interval_seconds = 30;
    char** flac_files = (char**) malloc(sizeof(char*) * 1024);
    
    int conversionResult = convertWavToFlac([waveFile UTF8String], [flacFileWithoutExtension UTF8String], interval_seconds, flac_files);
    
    NSLog(@"%d", conversionResult);
}
```

# おわりに

あまり需要がないかもですが、私にとっては必要な情報でした。

手順をまとめると簡単そうに見えますね。
あんなに苦労したのに(笑)
[tvOS]UIBarItemの通常色は変えられない

多分バグかな…

```swift
item.setTitleTextAttributes([NSForegroundColorAttributeName:theme.barTintColor], forState: UIControlState.Normal)
            item.setTitleTextAttributes([NSForegroundColorAttributeName:theme.barTintColor], forState: UIControlState.Highlighted)
            item.setTitleTextAttributes([NSForegroundColorAttributeName:theme.barTintColor], forState: UIControlState.Disabled)
            item.setTitleTextAttributes([NSForegroundColorAttributeName:theme.barTintColor], forState: UIControlState.Selected)
            item.setTitleTextAttributes([NSForegroundColorAttributeName:theme.barTintColor], forState: UIControlState.Focused)
            item.setTitleTextAttributes([NSForegroundColorAttributeName:theme.barTintColor], forState: UIControlState.Application)
            item.setTitleTextAttributes([NSForegroundColorAttributeName:theme.barTintColor], forState: UIControlState.Reserved)
```

Stateはどれを指定しても選択中のタブの色として指定される。
Javascriptでデバイス判定


モバイル判定

```js
if (/mobi/i.test(window.navigator.userAgent)) {
// モバイルの場合
}
```

これもあり

```js
if (window.navigator.userAgent.toLowerCase().indexOf('mobi') != -1){
// モバイルの場合
}
```

タッチスクリーン搭載デバイス（タブレットを含む）判定
 
```js
if ('ontouchstart' in document.documentElement){
// タッチスクリーン搭載デバイスの場合
}
```
Ubuntu - apt-getでインストールされるパッケージの確認方法

 apt-getでインストールされるパッケージの確認方法を調査したのでメモ

#### 確認コマンド
```
apt-cache policy <パッケージ名>
```

今度からはパッケージインストール手順はこんな感じにする予定
```
apt-get update
apt-cache policy <パッケージ名>
apt-get install <パッケージ名>
```

インストールする前に何をインストールするかを確認するのは大切

#### ※参考
http://makaaso.hatenablog.com/entry/2015/10/13/163421
MySQL - csvデータをデータベースに格納する方法

mysqlにcsv形式のデータを格納する方法を調査した時のメモ

[例]ローカルにあるcsvファイル先頭１行読み飛ばして格納するコマンドサンプル

#### 1.「LOAD DATA文」を使用する方法

```
LOAD DATA LOCAL INFILE '<CSV_FILE>'
INTO TABLE <TABLE_NAME>
FIELDS TERMINATED BY ","
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
;
```

#### 2.「mysqlimport」を使用する方法

```
mysqlimport -u<USER> -p --fields-terminated-by="," --fileds-enclosed-by='"' --lines-terminated-by"\n" --ignore-lines=1 --local <DB> <CSV_FILE>
```

「mysqlimport」の場合、格納するテーブルはcsvファイル名に依存しているようなので、「LOAD DATA」のほうが柔軟性が良さそう

#### ※参考
http://makaaso.hatenablog.com/entry/2015/10/26/191816
MariaDB - Ubuntu14.04にapt-getでMariaDB Serverをインストールする方法

MariaDB Serverをインストールした時のメモ

#### 環境
* OS: Ubuntu14.04

#### インストールコマンド
```
sudo apt-get install software-properties-common
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
sudo add-apt-repository 'deb http://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/repo/10.1/ubuntu trusty main'
sudo apt-get update
sudo apt-get install mariadb-server
```

#### ※参考
http://makaaso.hatenablog.com/entry/2015/10/26/134217
Linux - n日前・n分前のファイルを削除する方法

今更ながらfindコマンドでn日前・n分前のファイルを削除する方法をメモ

#### 1.findコマンドのフォーマット

```
find [path..] [expression]
```

#### 2.日時を指定するオプション

* -atime +n  
        最終アクセス日時がn日以前のfile(or directory)を検索

* -atime -n  
        最終アクセス日時がn日以降のfile(or directory)を検索

* -ctime +n  
        最終変更日時がn日以前のfile(or directory)を検索

※「+」はn日以前、「-」はn日以降、ない場合はn日前  
※「-amin」「-cmin」「-mmin」だとn分前を指定できる

#### 3.アクション指定するオプション

```
--exec [command] {} \;
```

* 30日以前のファイルを表示

```
find ./ -mtime 30 -exec ls -l {} \;
```

* 30日以前のファイルを削除

```
find ./ -mtime 30 -exec rm -f {} \;
```

#### 参考
http://makaaso.hatenablog.com/entry/2015/10/26/134312
Percona - Ubuntu14.04にapt-getでPercona Serverをインストールする方法

 Percona Serverをインストールした時のメモ

#### 環境
* OS: Ubuntu14.04

#### インストールコマンド
```
sudo su -
sudo apt-key adv --keyserver keys.gnupg.net --recv-keys 1C4CBDCDCD2EFD2A
echo "deb http://repo.percona.com/apt "$(lsb_release -sc)" main" | sudo tee /etc/apt/sources.list.d/percona.list
echo "deb-src http://repo.percona.com/apt "$(lsb_release -sc)" main" | sudo tee -a /etc/apt/sources.list.d/percona.list
apt-get update
apt-cache policy percona-server-server-5.6
apt-get install percona-server-server-5.6 percona-server-client-5.6
```

#### ※参考
https://www.percona.com/doc/percona-server/5.6/installation/apt_repo.html
Redis - 設定をオンラインで変更する方法

 Redisの設定をオンラインで変更する方法を調査したのでメモ

#### 設定の確認

```
$ redis-cli CONFIG GET save
1) "save"
2) "900 1 300 10 60 10000"
```

#### 設定の変更

```
$ redis-cli CONFIG GET save ""
OK
```

#### ※参考
http://makaaso.hatenablog.com/entry/2015/10/07/105904
Titanium + CryptoJSでデータを暗号化

Titaniumでデータを安全に保存する場合、iOSならKeychainを使う手がありますが、クロスプラットフォームでの開発で双方向暗号化をうまく実装する方法は提供されていません。

もっとも、そんなものはクロスプラットフォームの開発を前提にする以上は誰も提供していませんが。

JavaやObj-Cで書いたモジュールを使うという手もありますが、プラットフォーム間での動作の違いがあると面倒なので、できればJSで解決したいものです。

そこで、[Forge](https://github.com/digitalbazaar/forge)や[CryptoJS](https://code.google.com/p/crypto-js/)といったものが候補に上がってくるかと思います。

Forgeはcrypto-jsの開発が停滞したため作者がこっちの方がいいよと推薦しているプロジェクトで、ブラウザとNode.jsのどちらでも動作するようになっています。

しかし、残念なことにTitaniumではNodeのモジュールはそのまま動作させることができませんでした。相互依存しているutil.jsに互換性がないのが痛いですね。またマルチバイト文字列でAESを扱う際に面倒なことが多そうなので諦めました。BrowserifyをもじったTitaniumifyプロジェクトもあるそうなので、そちらの未来に期待しましょう。

そこで、今回はCryptoJSを使って、AESを利用した双方向暗号を使ってみましょう。NSAに覗かれないように別のがいいといった声なき声を平気で無視できるのが非対話式ドキュメントの便利なところですね。

CryptoJSの場合、AESならaes.jsを単体で組み込んでしまえば動作するようになっています。ただ、CommonJSの形式で使うには少し工夫が必要です。

まずはminifyされたバージョンを取得してます。
http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js

こちらのファイルをapp/assets/直下（またはapp/lib/直下）に設置します。そして、ファイルの一番下に以下の行を追記します。

```js
module.exports = CryptoJS;
```

これでCommonJS形式で使えるようになりました。

```js
var CryptoJS = require('aes');
var str = "桃、桃、桃";
var enc = CryptoJS.AES.encrypt(str, "Secret Passphrase");
Ti.API.info(enc.toString());
var dec = CryptoJS.AES.decrypt(enc.toString(), "Secret Passphrase");
Ti.API.info(dec.toString(CryptoJS.enc.Utf8));
```

エンコードされたオブジェクトencをtoStringするとbase64エンコードされた文字列が、デコードされたオブジェクトをtoString()したら「桃、桃、桃」と出力されましたね。実行するたびにsaltの値が変化するので、base64の結果は毎度違ったものになるはずです（じゃないと推測されちゃいますよね）。


enc.toString()の結果をどこかに保存しておけば、上のやり方でいつでもデコードできます。
[tvOS]UIPageControlの背景を剥がす

tvOSのUIPageControlには背景ブラーが付いており、必要ない場合は剥がす必要があります。

<img width="298" alt="スクリーンショット 2015-10-26 18.47.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/24979/a59f3384-28b7-3c16-76c2-29cf424aec9e.png">


```swift
        for v in pageControl.subviews {
            if let subView = v as? UIVisualEffectView {
                subView.removeFromSuperview()
            }
        }
```

正体はUIVisualEffectViewなので、探してremoveFromSuperviewでイナフ

<img width="267" alt="スクリーンショット 2015-10-26 18.47.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/24979/e8d32475-57fd-632b-f66f-178145291687.png">
特定の拡張子を持つすべてのファイルをジェネレート


指定ディレクトリ以下のすべてのファイルをなめて、希望の拡張子を持つファイルのファイルパスのみをジェネレータ的に返す。`os.walk` を使うとできる。

よく使う操作だとは思いつつすぐ書き方を忘れるのでメモも兼ねて今後のために関数化しておく。Python2系でも3系でも使える。


```python
import os


def walk_files_with(extension, directory='.'):
    """Generate paths of all files that has specific extension in a directory. 

    Arguments:
    extension -- [str] File extension without dot to find out
    directory -- [str] Path to target directory

    Return:
    filepath -- [str] Path to file found
    """
    for root, dirnames, filenames in os.walk(directory):
        for filename in filenames:
            if filename.lower().endswith('.' + extension):
                yield os.path.join(root, filename)
```

実際にはこんな感じで使う。

```python
for filepath in walk_files_with('csv', './data/'):
    print(filepath)
```


Python 3.4 以上なら `pathlib` 使ったほうがスマートかもねー。
Plist.fileに関して

ATS関連のために「plist.file」を学習

##App Transport Security

```
App Transport Security(ATS)はiOS9.0 or OS X 10.11以上で有効な機能であり、アプリとウェブサービスとの間の安全な接続のために利用する機能です。

ATSが有効な場合、HTTPでの通信はできません。
またAppleが推奨する必要条件を満たさない接続は強制的に接続失敗になります。

例えば、推奨の要件を満たさないWebページをWKWebViewで開こうとした場合ページのロードは失敗します。

Info.plistに特定のキーと値を追加すれば、ATSを無効にしたり一部の動作を変更したりする事が出来る。
```

#plistとは?
```
plistはproperty list(プロパティーリスト)の略となる。
・.plistファイルは主にAppleソフトウェアで扱われます。
```


#ATSに対処する方法(暫定)
```
info.plistに次の内容を記述する。

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>
```
メール開封数確認

# メール開封数確認
## imgタグによるビーコンを仕込む
というやり方が一般的なようです。

http://waterlow2013.hatenablog.com/entry/2015/03/01/075321

数はユニークにしたいので、URLにIDを仕込んで同一IDの場合には二重にカウントをしないような処理を入れればOK

## 注意
正確な開封数は取得できない。
メールをテキスト形式で開かれたり、そもそも画像を開かないような設定をされている場合にはURLへのアクセスが行われないため取得することができない。

# みなさんどうしてるんですかね？
二段階認証(TOTP)メモ

# TOTP
二段階認証のアプリは色々あるらしいが(IIJ Smartkey、Authy、Google Authenticator等)、どうやら TOTPというワンタイムパスワードの規格があり、それに沿っている模様。

*RFC6238 Time-based One-time Password Algorithm (TOTP)の仕組みのメモ*
http://qiita.com/shrkw/items/426a7f1a59f42e0bd523

そのうち使うかもしれないのでメモ。

# QRコード(URIフォーマット)
多くの二段階認証アプリはQRコードで登録するが、実際のURIは以下のようになっている。
```
otpauth://totp/Example:hoge@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Example
```

- **otpauth://totp/[LABEL]?[Parameters]** という形式。
- **[LABEL]** は 発行者(Example) と アカウント名を:で区切ったものを記述。
- **secret**は任意のパラメータをBase32でエンコードしたもの。
- **issuer**は**[LABEL]**と同一の発行者を指定。IIJ SmartKeyの場合、必須らしい。
- **[Parameters]** には 任意で**algorithm**や**digits**が指定できる。

詳細はこちら。
*google-authenticator Key Uri Format*
https://github.com/google/google-authenticator/wiki/Key-Uri-Format
*IIJ SmartKey URIフォーマット*
https://www1.auth.iij.jp/smartkey/uri_v1.html

# ワンタイムパスコード生成(PHP)
パスコードを実際にどのように生成しているか、の処理。
あらかじめ与えられた*secret*とUNIX Time で6桁の数字が確定する。
以下を参考に（ほぼ転載気味）。
*Google TOTP Two-factor Authentication for PHP*
https://www.idontplaydarts.com/2011/07/google-totp-two-factor-authentication-for-php/

```php
<?php
// Base32でバイナリ変換
function base32_decode($b32) {
  $lut = array("A" => 0,       "B" => 1,
               "C" => 2,       "D" => 3,
               "E" => 4,       "F" => 5,
               "G" => 6,       "H" => 7,
               "I" => 8,       "J" => 9,
               "K" => 10,      "L" => 11,
               "M" => 12,      "N" => 13,
               "O" => 14,      "P" => 15,
               "Q" => 16,      "R" => 17,
               "S" => 18,      "T" => 19,
               "U" => 20,      "V" => 21,
               "W" => 22,      "X" => 23,
               "Y" => 24,      "Z" => 25,
               "2" => 26,      "3" => 27,
               "4" => 28,      "5" => 29,
               "6" => 30,      "7" => 31
  );

  $b32    = strtoupper($b32);
  $l      = strlen($b32);
  $n      = 0;
  $j      = 0;
  $binary = "";

  for ($i = 0; $i < $l; $i++) {

       $n = $n << 5;
       $n = $n + $lut[$b32[$i]];       
       $j = $j + 5;

       if ($j >= 8) {
           $j = $j - 8;
           $binary .= chr(($n & (0xFF << $j)) >> $j);
       }
  }

  return $binary;
}

// google-authenticator のサンプルキー
$sample_secret = 'JBSWY3DPEHPK3PXP';
$binary_key = base32_decode($sample_secret);

// 30秒単位
$timestamp = floor(microtime(true) / 30);

$binary_timestamp = pack('N*',0) . pack('N*', $timestamp);

$hash = hash_hmac ('sha1', $binary_timestamp, $binary_key, true);

// RFC4226 6桁に切り詰める
$offset = ord($hash[19]) & 0xf;
$OTP = (
   ((ord($hash[$offset+0]) & 0x7f) << 24 ) |
    ((ord($hash[$offset+1]) & 0xff) << 16 ) |
    ((ord($hash[$offset+2]) & 0xff) << 8 ) |
    (ord($hash[$offset+3]) & 0xff)
   ) % pow(10, 6);

// 数字を出力
printf("%06d",$OTP);
```

# 参考
*Googleの2段階認証で使われているOTPの仕様が気になった*
http://d.hatena.ne.jp/ritou/20111225/1324822654
*Base32*
https://ja.wikipedia.org/wiki/%E4%B8%89%E5%8D%81%E4%BA%8C%E9%80%B2%E6%B3%95
Groovyの型指定と実行速度

# はじめに
以前下記のブログで各種JVM言語で実行速度を比較している記事を見つけました。
[【Java 3兄弟で】Groovy, Scala, Clojure【フィボナッチ】](http://www.mixp.net/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E8%A8%80%E8%AA%9E/290)
自分の環境でもGroovyで同じく検証すると記事よりかなり速かったので、よく比べてみると自分のソースでは型指定をintとして書いていました。
そのことをブログのコメントで書くと管理人の方も比較してくださり同じく速度に違いが出ることが確認できました。

一般的にGroovyの入門記事などと読むとGroovyは基本ラッパー型しか使わずに、数値計算などもGroovy側でよしなに変換してくれるから気にしなくていいといったことしか書かれていないため今まで考えたこともありませんでした。
そこでGroovyで型指定した時にどういった挙動になるか調べてみました。

# やったこと
## テストコード
次のようなコードを書いてみました。

```groovy
def num0 = 0
Integer num1 = 1
int num2 = 2

println "Integer: ${Integer.class}"
println "int: ${int.class}"

println()

println "num0: ${num0.class}"
println "num1: ${num1.class}"
println "num2: ${num2.class}"
```

defとIntegerとintで変数を宣言し、それぞれ整数リテラルで初期化しました。
その後Integer、intそれぞれのクラス名と変数のクラス名を取得してみました。

## 実行結果
結果は次のように出力されました。

```
Integer: class java.lang.Integer
int: int

num0: class java.lang.Integer
num1: class java.lang.Integer
num2: class java.lang.Integer

```

Javaではintはクラスではないので2行目はエラーになると思ったのですが「int」と表示されました。
Groovyではクラスのように見えるようです。

変数のクラス名はすべてIntegerになっています。3個目はintになるのかなと思いましたがこれもIntegerです。Groovyでは整数リテラルはIntegerになるためでしょうか

## テストコード2
次に書きのようなコードを試しました。

```groovy
def num0 = null
Integer num1 = null
int num2 = null
```

intがクラスのように見えるのならこのコードは受け付けるように思えます。

## 実行結果
```
Exception thrown

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'null' with class 'null' to class 'int'. Try 'java.lang.Integer' instead

	at ConsoleScript23.run(ConsoleScript23:3)
```

キャストできない例外を吐いて、intじゃnull使えないからInteger使えと怒られてしまいました。
やはり内部的には普通にプリミティブintのようです。
ちなみに下記のように記述すると2行目でNullPointerExceptionが出てきます。

```groovy
Integer num1 = null
int num2 = num1
```

# 速度比較
参考ブログと同様にフィボナッチ数列を最適化無しでintとInteger版2つ作って速度を比較してみました。

```groovy
int fib1(int num) {
    if(num <2) return num
    fib1(num-1) + fib1(num-2)
}

Integer fib2(Integer num) {
    if(num <2) return num
    fib2(num-1) + fib2(num-2)
}

def before,after

before = System.currentTimeMillis()
println fib1(39)
after = System.currentTimeMillis()

println "${after-before}ms"

before = System.currentTimeMillis()
println fib2(39)
after = System.currentTimeMillis()

println "${after-before}ms"
```

```
63245986
1600ms
63245986
8357ms
```

5倍くらい違います。
やっぱりintにしたほうが速いようです。

## 結論
このようにGroovyにおいてもintとIntegerの挙動は異なり、場合によってはintで宣言したほうが速度が改善されることがわかりました。
しかしプリミティブ型を使用するとJavaと同様にnullが使用できず、紛れ込んでしまった時例外が発生するので注意が必要です。
また再帰のような例ですと、前回説明したメモ化のようなテクニックを使用したほうが安全でしょう。
参考：[メモ化により再帰を高速化する](http://qiita.com/ligun/items/cce80651ec90d099cb63)
そもそも計算に速度を求める用途でGroovyが向いているとも思えません。
どうしても一部分で速度を求めたい以外でGroovyらしいコーディングから外れるのはやめたほうがいいでしょう。

## ちなみにScalaは
Scalaは殆ど触ったことがなく、Groovyと比較で調べてみた程度なのですがコンパイル型なのもあり速いようです。
特にScalaはプリミティブ型がなくすべてオブジェクト型なのにJavaと遜色なく使えると聞いて、なんでなんだろうと思って調べてみました。
どうもScalaはコード上ではオブジェクトとして表現されていても、コンパイル時に最適化できるときは積極的にプリミティブに変換しているようです。
なのでフィボナッチ数列のような例だと速く処理できて、かつプログラマはそれを意識しなくて良いのです。
なかなかいい機能ですね(その代償なのかコンパイル速度は遅いらしいですが)

## 最後に
あまり言語機能に詳しくはないため間違いや誤解などあるかもしれません。
何かご指摘等ありましたらコメントお願いします。
[Xamarin.Forms] Navigation ナビゲーションバーの非表示、右上にボタン追加

画面遷移で良く使うNavigationですが、
よく使いそうな機能をメモしておきます。

```
// ナビゲーションバーを非表示にする（thisはPageオブジェクト）
NavigationPage.SetHasNavigationBar(this, false);
```

```
// ナビゲーションバーの右上にボタンを追加する。
ToolbarItems.Add(new ToolbarItem("Name", "icon.png", async () =>
{
    // 何か処理を記述
}));
```
ubuntuにVirtualBox Guest Additionsをx11無しで入れる手順

パッケージから入れようとするとどうにもx11関連のパッケージも入ってしまうので、ソースから入れます。

* まずは iso を[このへん](http://download.virtualbox.org/virtualbox/) からDL
* `mkdir /mnt/vbox` して `mount <path to iso> -o loop /mnt/vbox`
* apt-get install build-essential
* /mnt/vbox/VBoxLinuxAdditions.run --nox11

あとはしばらく待つのみ。X11環境がないからそれっぽいのは動かないよ、というような警告が出ますが、インストールは完了します。使う気がないので良いでしょう。
Apache FOP 1.1 + Maven でエラーが発生した場合の対応


- Apache FOP - https://xmlgraphics.apache.org/fop/

Maven利用時に Apache FOP 1.1 を依存関係に記載するとエラーになった。

```xml
<dependency>
    <groupId>org.apache.xmlgraphics</groupId>
    <artifactId>fop</artifactId>
    <version>1.1</version>
</dependency>
```

↓

```
- Missing artifact org.apache.avalon.framework:avalon-framework-impl:jar:4.2.0
- Missing artifact org.apache.avalon.framework:avalon-framework-api:jar:4.2.0
```

Maven Central Repositoryで管理されてるpom.xmlの状態が不正？
とりあえずエラーとなる依存モジュールをexcludeして、
個別でdependencyに記述することでエラーを回避。

```xml
<dependency>
    <groupId>org.apache.xmlgraphics</groupId>
    <artifactId>fop</artifactId>
    <version>1.1</version>
    <exclusions>
        <exclusion>
            <groupId>org.apache.avalon.framework</groupId>
            <artifactId>avalon-framework-api</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.apache.avalon.framework</groupId>
            <artifactId>avalon-framework-impl</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>avalon-framework</groupId>
    <artifactId>avalon-framework-api</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>avalon-framework</groupId>
    <artifactId>avalon-framework-impl</artifactId>
    <version>4.2.0</version>
</dependency>
```
CSRF 対策のバグの対策

* 2.13.4 
    * [脆弱性](http://www.ec-cube.net/info/weakness/weakness.php?id=63)
    * [TRANSACTION_ID が NULL === NULL で正常となる] (https://github.com/EC-CUBE/eccube-2_13/issues/67)


```diff
    public function isValidToken($is_unset = false)
    {
        // token の妥当性チェック
-        $ret = $_REQUEST[TRANSACTION_ID_NAME] === $_SESSION[TRANSACTION_ID_NAME];
+        $ret = $_REQUEST[TRANSACTION_ID_NAME] === $_SESSION[TRANSACTION_ID_NAME] 
+               && isset($_REQUEST[TRANSACTION_ID_NAME]);

        if ($is_unset || $ret === false) {
            SC_Helper_Session_Ex::destroyToken();
        }

        return $ret;
    }
```
踏み台サーバ越しにあるRedisにRedis Desktop Managerでつなぎにいく


# 背景

前回はMySQLでしたが今回は、Redis Desktop Managerです。
RedisをGUIでいじれるのないかなーと探していて以前見つけたのがこのツールです。
もちろんコマンドで叩いててもいいですがGUIのほうが早かったり直感的だったりします。

気に入っている点としては、以下の点です。

* データベースごとのキーの数がすぐわかる
* キーの値にクリックのみでアクセスできる
* キーと値の消去もクリックのみで出来る
* JSONで値が入っていても整形して出してくれる
* TTLなどの値も表示されている

![gui_1.png](https://qiita-image-store.s3.amazonaws.com/0/30079/3c9e341a-5b1e-a102-8d77-cb107250694f.png)

![gui_2.png](https://qiita-image-store.s3.amazonaws.com/0/30079/299478b0-6b57-9584-bad5-9d16522c68a2.png)

ローカルにあるRedisは簡単につなげるのですが、その時に困るのが、踏み台など経由した先にあるRedisにつなぐ場合です。
この場合、後述するように設定すると繋げれるようになります。

# 環境

![server.png](https://qiita-image-store.s3.amazonaws.com/0/30079/ddc3e9ba-d096-4b8a-197c-77d05c597368.png)

ローカルのMacからAppサーバであるApp001に、踏み台を経由して以下のコマンドで、つなぎに行けることを前提としています。
なおapp001はApp001のホスト名です。

    ssh app001

上記のようにつなぐには~/.ssh/configに以下のような設定をします。
fumidai_proxyが踏み台のホスト名です(図ではHost: fumidaiのこと)

    Host fumidai_proxy
        HostName fumidai
        User user_name
        IdentityFile ~/.ssh/id_rsa
        
    Host app001
        User user_name
        IdentityFile ~/.ssh/id_rsa
        ProxyCommand ssh fumidai_proxy -W %h:%p

# Redis Desktop Managerの設定

## バージョン

最新バージョンは、0.8.1ですが、SSHトンネリングがうまく使えないのと、UIがバグっている場合があるので、__0.7.6__を使用します。
なお、過去のリリースは以下から取得できます。

[https://github.com/uglide/RedisDesktopManager/releases](https://github.com/uglide/RedisDesktopManager/releases)

## 設定手順

前回のMySQLのときはSSHを経由しての設定ができたのですが、今回はできないのでSSHのポートフォワードを使います。
以下のようにコマンドを叩きます。

    ssh -fNL 50011:redis:6379 app001

説明は以下です。

![rdm_3.png](https://qiita-image-store.s3.amazonaws.com/0/30079/935d561a-4aeb-da7a-9b65-6bf04621de6e.png)

SSHポートフォワードが設定できたらRedis Desktop Managerを開き以下のように設定し、接続するとつながります。

<img width="1073" alt="rdm_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/30079/03ae8d21-3640-45f3-28e2-0449a08dc304.png">

# 結び

いちいちSSHのポートフォワードを設定しなければいけないところが面倒いのですが、何かいい方法があったりするのかしら。
CentOS6にremiでPHP56がインストールされずPHP533のままになる問題

#概要
CentOS6のデフォルトPHPバージョンが5.3.3で古いから新しいバージョン（5.6）を入れたい。
先人たちの教えに従って、epel,remiリポジトリを追加。
`sudo yum --enablerepo=remi-php56 install php`
としてもBaseリポジトリを参照して5.3.3からアップデートされないので困った。

#対処

`sudo yum --disablerepo=* --enablerepo=remi-php56 install php`
としてみたところインストールできた。

#原因？
おそらく*.repoファイルのプライオリティが問題かと思われる（間違っていたらご指摘ください）
そのため一旦すべてのリポジトリ設定ファイルをDisableとしたのちremi-php56のみEnableとしたところインストールできた。
POP3sをつかった、Remineのチケットを登録

# メールでRedmineにチケットを登録したいが、IMAPが使えないメールサーバなのです
IMAPができなくて、POP3sでメールを取り込んでいます。
Remineにメールでチケットを登録したくなったのでcronを仕込んだ。
redmine:email:receive_pop3 と、ssl=1のオプションを使うとうまくいく。

匿名ユーザで使いたかったので「allow_anonymous=1 unknown_user=accept no_permission_check=1」も追加しています。

```
bundle exec rake -f /var/lib/redmine/Rakefile redmine:email:receive_pop3 RAILS_ENV="production" port=995 ssl=1 host=[pop3サーバ] username=[pop3のユーザ] password=[パスワード] project=[登録したいプロジェクトの識別子] allow_anonymous=1 unknown_user=accept no_permission_check=1
```

これをcronで10分間隔で実行しています。
Zabbixなどの監視ツールからメールを出して自動登録などが可能となってちょっとハッピー

# 環境
Redmine version は 2.6.0.stable です
C#でJSONを扱うライブラリ「Json.NET」を使ってみました

**<font color="red">2020/1/16追記</font>**
この記事を投稿してから5年が経過しましたが、
.NET Core 3.0から [System.Text.Json](https://www.nuget.org/packages/System.Text.Json) が追加されました。
使用感はわかりませんが、Microsoft公式なのでこちらもご検討ください。


Json.NET
http://www.newtonsoft.com/json

C#.NETでJSONのパースを行うライブラリとして、
Json.NETを使ってみましたがとても便利です。

NuGetで導入できます。

## シリアライズ

メソッドSerializeObject()を使う。

シリアライズ対象クラス(UserModel)

```cs
[JsonObject("user")]
public class UserModel
{
    [JsonProperty("id")]
    public int UserID { get; set; }
    [JsonProperty("name")]
    public string Username { get; set; }
}

```

シリアライズ処理

```cs
var data = new UserModel();
data.UserID = 100;
data.Username = "太郎";

string json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
```

結果

```json
{
  "id": 100,
  "name": "太郎"
}
``` 

## デシリアライズ
メソッドDeserializeObject<T>()またはDeserializeObject()を使う。

```cs
UserModel model1 = JsonConvert.DeserializeObject<UserModel>(jsonstring);
object model2 = JsonConvert.DeserializeObject(jsonstring);
```

サンプルでは単純なモデルクラスだが、
階層構造を持ったJSONでも問題なくデシリアライズ可能。
JSON配列もListなどにパースしてくれる。

## 便利なオプション機能
### 既定値（DefaultValue、DefaultValueHandling）
既定値を設定するにはSystem.ComponentModel名前空間のDefaultValue属性を利用する。

```cs
[JsonObject("user")]
public class UserModel
{
    [JsonProperty("id")]
    public int UserID { get; set; }
    [JsonProperty("name")]
    [DefaultValue("demo")]
    public string Username { get; set; }
}
```

次に、列挙体DefaultValueHandlingでシリアライズ（デシリアライズ時）の既定値の取り扱い方法を制御します。

DefaultValueHandling

|設定値|動作|
|:--|:--|
|Include|シリアライズ時に既定値の項目をJSONに含める（既定の動作）。|
|Ignore|シリアライズ時に既定値の項目をJSONに含めない。|
|Populate|デシリアライズ時にJSON文字列中に要素が存在しない場合でも既定値を設定する。|
|IgnoreAndPopulate|IgnoreとPopulateの同時指定。|

利用方法
プロパティ単位に指定するかシリアライズ（デシリアライズ）時にオプションで指定します。

```cs
// プロパティで指定
[JsonProperty("name", DefaultValueHandling = DefaultValueHandling.Ignore)]
public string Username { get; set; }

// シリアライズ時に指定
string json = Newtonsoft.Json.JsonConvert.SerializeObject(model, Formatting.Indented, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore});

// デシリアライズ時に指定
UserModel model = JsonConvert.DeserializeObject<UserModel>(jsonstring, new JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Populate });
```

以上
[JAWS-UG CLI] Lambda:#7 エイリアスの削除



前提条件
========


Lambdaへの権限
--------------

Lambdaに対してフル権限があること。


AWS CLI
-------

以下のバージョンで動作確認済

* AWS CLI 1.9.0

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.9.0 Python/2.7.5 Darwin/13.4.0 botocore/1.3.0
```


0. 準備
=======


変数の確認
----------

プロファイルが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```

```text:結果(例):
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       administrator-prjz-mbp13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region                ap-northeast-1        env    AWS_DEFAULT_REGION
```

プロファイルが想定のものになっていることを確認します。


1. 事前作業
===========


1.1. Lambda関数名の決定
-----------------------

```bash:コマンド:
aws lambda list-functions \
        --query 'Functions[].FunctionName'
```

```json:結果(例):
      [
        "HelloWorld"
      ]
```

```bash:変数の設定:
LAMBDA_FUNC_NAME='HelloWorld'
```


1.2. エイリアスの確認
---------------------

```bash:コマンド:
aws lambda list-aliases \
        --function-name ${LAMBDA_FUNC_NAME}
```

```json:結果(例):
      {
        "Aliases": [
          {
              "AliasArn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:HelloWorld:product",
              "FunctionVersion": "2",
              "Name": "product",
              "Description": "Released version on product env."
          }
        ]
      }
```

```bash:変数の設定:
LAMBDA_ALIAS_NAME='product'
```

```bash:コマンド:
aws lambda get-alias \
        --function-name ${LAMBDA_FUNC_NAME} \
        --name ${LAMBDA_ALIAS_NAME}
```

```json:結果(例):
      {
        "AliasArn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:HelloWorld:product",
        "FunctionVersion": "2",
        "Name": "product",
        "Description": "Released version on product env."
      }
```


2. エイリアスの削除
===================


```bash:変数の確認:
cat << ETX

        LAMBDA_FUNC_NAME:  ${LAMBDA_FUNC_NAME}
        LAMBDA_ALIAS_NAME: ${LAMBDA_ALIAS_NAME}

ETX
```

```bash:コマンド:
aws lambda delete-alias \
        --function-name ${LAMBDA_FUNC_NAME} \
        --name ${LAMBDA_ALIAS_NAME}
```

```text:結果(例):
      (戻り値なし)
```


3. エイリアスの確認
===================

```bash:コマンド:
aws lambda get-alias \
        --function-name ${LAMBDA_FUNC_NAME} \
        --name ${LAMBDA_ALIAS_NAME}
```

```text:結果(例):
      A client error (ResourceNotFoundException) occurred when calling the GetAlias operation: Cannot find alias arn: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:HelloWorld:product
```


完了
====
[JAWS-UG CLI] Lambda:#4 エイリアスの作成



前提条件
========


Lambdaへの権限
--------------

Lambdaに対してフル権限があること。


AWS CLI
-------

以下のバージョンで動作確認済

* AWS CLI 1.9.0

```bash:コマンド:
aws --version
```

```text:結果(例):
      aws-cli/1.9.0 Python/2.7.5 Darwin/13.4.0 botocore/1.3.0
```


0. 準備
=======


変数の確認
----------

プロファイルが想定のものになっていることを確認します。

```bash:変数の確認:
aws configure list
```

```text:結果(例):
            Name                    Value             Type    Location
            ----                    -----             ----    --------
         profile       administrator-prjz-mbp13        env    AWS_DEFAULT_PROFILE
      access_key     ****************XXXX shared-credentials-file
      secret_key     ****************XXXX shared-credentials-file
          region                ap-northeast-1        env    AWS_DEFAULT_REGION
```

プロファイルが想定のものになっていることを確認します。


1. 事前作業
===========


1.1. Lambda関数名の決定
-----------------------

```bash:コマンド:
aws lambda list-functions \
        --query 'Functions[].FunctionName'
```

```json:結果(例):
      [
        "HelloWorld"
      ]
```

```bash:変数の設定:
LAMBDA_FUNC_NAME='HelloWorld'
```


2. エイリアスの作成
===================

```bash:変数の設定:
LAMBDA_ALIAS_NAME='product'
LAMBDA_FUNC_VERS='1'
LAMBDA_ALIAS_DESC='Released version on product env.'
```

```bash:変数の確認:
cat << ETX

        LAMBDA_FUNC_NAME:   ${LAMBDA_FUNC_NAME}
        LAMBDA_ALIAS_NAME:  ${LAMBDA_ALIAS_NAME}
        LAMBDA_FUNC_VERS:   ${LAMBDA_FUNC_VERS}
        LAMBDA_ALIAS_DESC: "${LAMBDA_ALIAS_DESC}"

ETX
```

```bash:コマンド:
aws lambda create-alias \
        --function-name ${LAMBDA_FUNC_NAME} \
        --name ${LAMBDA_ALIAS_NAME} \
        --function-version ${LAMBDA_FUNC_VERS} \
        --description "${LAMBDA_ALIAS_DESC}"
```

```json:結果(例):
      {
        "AliasArn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:HelloWorld:product",
        "FunctionVersion": "1",
        "Name": "product",
        "Description": "Released version on product env."
      }
```


3. エイリアスの確認
===================

```bash:コマンド:
aws lambda list-aliases \
        --function-name ${LAMBDA_FUNC_NAME}
```

```json:結果(例):
      {
        "Aliases": [
          {
              "AliasArn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:HelloWorld:product",
              "FunctionVersion": "1",
              "Name": "product",
              "Description": "Released version on product env."
          }
        ]
      }
```

```bash:コマンド:
aws lambda get-alias \
        --function-name ${LAMBDA_FUNC_NAME} \
        --name ${LAMBDA_ALIAS_NAME}
```

```json:結果(例):
      {
        "AliasArn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:HelloWorld:product",
        "FunctionVersion": "1",
        "Name": "product",
        "Description": "Released version on product env."
      }
```


完了
====
最強の環境切り替えツール2015

最強の環境切り替えツール2015
============================

様々な事情から、同一のマシンに複数の環境が混在することはよくある。Rubyを使っていてもあるプロジェクトは2.1系だが、あるプロジェクトは1.8系じゃないと動かないみたいなパターンだ。また、プロジェクトごとに環境変数を設定したり、書式設定をしたりすることもある。そういった環境の混在をうまくさばくためのツールを導入しよう。

* direnv
* anyenv
* editorconfig

異論・反論・ほかに導入すべきツールなどがあれば是非ともコメントしてほしい。

# direnv

[direnv](http://direnv.net/) はディレクトリ単位で環境変数を切り替えることができる。よく使われる用途としてはパスワードを安全に保持する、言語の環境を整えるなどである。

## インストール

Macでのインストールならば簡単だ。

```
$ brew install direnv
```

ソースからインストールする場合にはGolangが必要になる。

```
git clone https://github.com/direnv/direnv
cd direnv
make install
```

実行バイナリをインストールするだけではインストールは完了しない。direnvは仕組み上シェルのcdコマンドを乗っ取る形なので、シェル上でインストールするためのコマンドを実行する必要がある

```
eval "$(direnv hook bash)"
```

bash の場合は、上記コマンドを ~/.bashrc に記述する。ほかにもtcsh, zsh, fish などにも対応している。詳細は[公式](http://direnv.net/)を見てほしい。

## gitで無視したい

direnv では設定ファイル `.envrc` を各ディレクトリに作成するため、gitには`.envrc`を無視するように設定したい。

```
vi `git config --get core.excludesfile`
```

このファイルに`.envrc`を追加するといいだろう。

## 使い方

```
$ cd ~/hoge
$ echo 'export PASSWORD="password"' > .envrc
$ direnv allow .
```

こうしておけば、~/hoge のディレクトリに移動した場合のみ、環境変数にPASSWORDが設定される。もちろんPATH環境変数をいじることも可能だ。

### 秘密情報を環境変数で受け渡しすること

たとえばウェブアプリを作ったりする場合、DBの接続情報などを設定ファイル(と、称したDSL, ソース, YAML, JSON, ini)などを置くケースは多い。ただ、これには問題があってVCSで管理下におくべきかどうか、ファイルが混ざる危険、インストールが面倒になったりなどの問題がある。

そこで設定情報は環境変数に切り離そう。direnvを使わずに環境変数を設定する方法もあるし、PaaSなどでは秘密情報を環境変数に設定できるものもよくある。

あるいはちょっとしたスクリプトを書くときに、ついついスクリプトに直接パスワードを書いてしまう人はいないだろうか？パスワードを環境変数に分離する癖をつけておけば事故の可能性は減る。

# anyenv

direnvが汎用的な環境切り替えツールだとしたら、[anyenv](https://github.com/riywo/anyenv)は言語の環境切り替えに特化したツールだ。anyenv自体には言語の切り替え能力はなく、実際に切り替えをする個別のツールを管理するためのツールなのだ。

```
$ anyenv install ndenv
$ ndenv install v4.0.0
$ ndenv global v4.0.0
```

最初の`anyenv install ndenv`で、Nodeを切り替えできる`ndenv`をインストールする。次の`ndenv install v4.0.0`でnode 4.0.0をインストールし、`ndenv global v4.0.0`でグローバルで使うNodeを4.0.0に設定する。

direnvでも言語の切り替えはやろうと思えばできるが多少面倒だしできることはanyenvの方が多いのでdirenvを使ってる人でもanyenvがおすすめだ。

[公式](https://github.com/riywo/anyenv)などを確認してほしいが、R言語, Crystal, Erlang, Elixir, Haskell, D言語, Java, Lua, Node, PHP, Perl, Python, Ruby, Go, Scala(sbt/scala) などに対応している。

## インストール

```
$ git clone https://github.com/riywo/anyenv ~/.anyenv
$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.your_profile
$ echo 'eval "$(anyenv init -)"' >> ~/.your_profile
$ exec $SHELL -l
$ mkdir -p $(anyenv root)/plugins
$ git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update
$ git clone https://github.com/znz/anyenv-git.git $(anyenv root)/plugins/anyenv-git
```

your_profileは、bashユーザーならbash_profileなどと読み替えてほしい。

# EditorConfig

プロジェクトでインデントについてもめることはないだろうか？[EditorConfig](http://editorconfig.org/)を使えば、たとえばプロジェクトごとにインデントなどのルールを統一することができる。

EditorConfigは、.editorconfigという設定ファイルの書式とファイルの扱いに関する規定(プロトコル)と、各種エディタの実装の二つによって成り立っている。よくある使われ方は`~/.editorconfig`に全体的な設定を記述しておき、個別のプロジェクトごとに`.editorconfig`を設定するパターンだ。

## インストール

EditorConfig対応のエディタを使うか、プラグインなどを導入すればいい。[公式](http://editorconfig.org/#download)にアクセスすると、たとえばIntelliJ IDEA ならばプラグインを入れるまでもなく対応しているとわかるし、SublimeTextならばプラグインが存在していることがわかる。
c++ builder XE4, 10.2 Tokyo > ショートカットを作成する

```txt:動作確認
C++ Builder XE4
Rad Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)
```

ショートカットを作成したい。

[参考 @ プログラミングは道連れ](http://park6.wakwak.com/~wmasa/prog/srclib/0008.htm)

上記を参考に以下の実装。

```cpp
//---------------------------------------------------------------------------
bool __fastcall TForm1::CreateShortcutLink(String srcFile, String dstDir, String shortcutBaseName)
{

	IShellLink *pShellLink = NULL;
	IPersistFile *pPersistFile = NULL;
	String shortcutPath;

	if (FileExists(srcFile) == false) {
		OutputDebugString(L"27");
		return false;
	}

	CoInitialize(NULL);

	bool res;

	HRESULT hRes = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pShellLink );
	if (SUCCEEDED(hRes)) {
		hRes = pShellLink->QueryInterface(IID_IPersistFile, (void**)&pPersistFile);

		pShellLink->SetPath(srcFile.c_str());
		pShellLink->SetWorkingDirectory(dstDir.c_str());

		if (shortcutBaseName.Length() > 0) {
			shortcutPath = IncludeTrailingPathDelimiter(dstDir) + shortcutBaseName + L".lnk";
		} else {
			shortcutPath = IncludeTrailingPathDelimiter(dstDir) + ExtractFileName(srcFile) + L" - Shortcut.lnk";
		}

		if (pPersistFile->Save(shortcutPath.c_str(), /* fRemember=*/false) != S_OK) {
			OutputDebugString(L"52");

			res = false;
		} else {
			res = true;
		}
	}

	pPersistFile->Release();
	pShellLink->Release();
	CoUninitialize();

	return res;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	String srcFile = L"D:\\WORK\\151026_shortcut\\dat.txt";
	String dstDir = L"D:\\WORK\\151026_shortcut";
	String shortcutName = L"";

	CreateShortcutLink(srcFile, dstDir, shortcutName);
}
//---------------------------------------------------------------------------
```

`dat.txt - Shortcut`というショートカットが作成できる。