OmniAICreator/Qiita-1.07M huggingface dataset:
iPhone Safariで動画をインライン再生する方法

##iPhone SafariのVideoタグの制限
iPhone SafariのVideoタグには大きく2つ制限がある。

1. ユーザインタラクション（タップ）なしに再生できない
2. 初期再生時必ずフルスクリーン再生になる

特に2がクセモノで、これのせいでモバイルブラウザに動画広告はほぼ無いし、モバイルブラウザゲームには動画演出がない（MotionJPEGみたいにjpegを数百枚数千枚差し替えるとか涙ぐましいことをしている例はある）。

##制限は超えられる
この制限が超えられないものかと調べてみると、やはり同じようなことを訊いている人が居た。

inline html5 video on iphone - Stack Overflow
http://stackoverflow.com/questions/30855662/inline-html5-video-on-iphone

で、そのベストアンサーが

> It's very rough, but the basic gist is that you "seek" through the video instead of playing it outright. So instead of calling:
> ``` video.play() ```
> 
> You instead set a loop using request animation frame or setInterval, then set the:
> ``` video.currentTime = __FRAME_RATE__```


つまり、

**Playすんな、currentTimeを動かせ！**

##Sample Code
```js:ループ再生
	var video = document.createElement('video');
	video.style.display = 'none';
	document.body.appendChild(video);
	var canvas = document.getElementById('myCanvas');
	var ctx = canvas.getContext("2d");
	var ctime = 0;
	var lastTime;
    var ua = navigator.userAgent;
    if(/(iPhone|iPod)/.test(ua)) { // iPadもVideoはインライン再生可能である
        video.addEventListener('canplay',function(){
            lastTime = Date.now();
            setInterval(function(){
                var curTime = Date.now();
                var diff = Date.now() - lastTime;
                lastTime = curTime;
                ctime += diff/1000;
                video.currentTime = ctime;
                ctx.drawImage(video, 0, 0, 480, 360);
                if(video.duration <= video.currentTime){
                    ctime = 0;
                }
            }, 1000/30);
        },false);
    }else{
        video.addEventListener('canplay',function(){
            video.play();
            video.loop = true;
            setInterval(function(){
                ctx.drawImage(video, 0, 0, 480, 360);
            }, 1000/30);
        },false);
    }
	video.src = 'sample.mp4';
	video.load();
```
##DEMO
http://jsrun.it/hadakadenkyu/iFDV
![http://jsrun.it/hadakadenkyu/iFDV](http://chart.apis.google.com/chart?chs=150x150&cht=qr&chl=http%3A%2F%2Fjsrun.it%2Fhadakadenkyu%2FiFDV)


##One more thing
WebGLでもイケます

##音声は？
[書いた](http://qiita.com/hadakadenkyu/items/b8accc395ccfa8348faf)
Sinatraでサブタイトルを付ける

たとえばQiitaだったら`[記事名] - Qiita`のような`[サブタイトル名] -(か|) [サイト名]`の形のタイトルをよく見ます。
それを実装するしかたがハマったので書いておきます。

```ruby:app.rb
get '/' do
    @subtitle = "サブタイトル"
    erb :index
end
```

```erb:layout.erb
<html>
<head>
    <title><%= @subtitle && @subtitle + " - " %>サイト名<title>

つづく…
```
これで「サブタイトル - サイト名」というタイトルになります
また、サブタイトルを設定しない場合は単に「サイト名」というタイトルになります

Ruby自体が初めて一週間で、Qiitaも初投稿なのでどしどしアドバイスください
ofxOpenNI Addon の追加方法

##概要
以前もopenNIを簡単に使う手順を紹介しましたが(http://qiita.com/Hiroki11x/items/f0cd4dd38867b296b9df)
既存のプロジェクトや、他のaddonを追加する際に問題が多かったため、その解決もできる方法を紹介します。
環境はMacOSで、Xcode7.2.1 openFrameworks0.9.2を使っています。
この記事では、既存のopenFrameworksプロジェクトに対して、OpenNIをopenFrameworksで利用出来るaddon、ofxOpenNIのプロジェクトへの追加方法に関して説明します。

##1. ofxOpenNIのダウンロード

https://github.com/gameoverhack/ofxOpenNI
から、ダウンロードし、addonsフォルダに追加。(zipでダウンロードする場合には、フォルダ名の語尾に-masterが入っている場合は消す)

##2. bin/dataへのopenniフォルダごとの追加
opeNI-SimpleExamples内のbin/dataにあるopenniというフォルダを、addonを追加するプロジェクトのbin/dataに追加
<img width="2014" alt="_Users_hirokinaganuma_Documents_hackenv_of_v0.9.2_osx_release_apps_201603_mySketch_bin_data_openni.png" src="https://qiita-image-store.s3.amazonaws.com/0/56510/879441a0-3a16-a6d9-897a-8c76c8c81ba6.png">



##3. Xcodeでprojectを開いた状態で、addonsに3つのフォルダを追加
ofxOpenNI内のsrc, include, libをプロジェクトのaddonに直に追加。ofxOpenNIごと行くとうまくいかないです。
このとき以下のように、addonを右クリックし、Add files to ...で、追加します。

<img width="714" alt="スクリーンショット 2016-03-29 23.58.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/56510/ba764438-5ca0-cda6-0f0e-79e8bc792174.png">


<img width="1628" alt="_Users_hirokinaganuma_Documents_hackenv_of_v0.9.2_osx_release_addons_ofxOpenNI_src.png" src="https://qiita-image-store.s3.amazonaws.com/0/56510/5c2307ac-9981-9c32-b4ed-aca1a9e351c9.png">

<img width="1636" alt="_Users_hirokinaganuma_Documents_hackenv_of_v0.9.2_osx_release_addons_ofxOpenNI_include.png" src="https://qiita-image-store.s3.amazonaws.com/0/56510/9de56a90-e514-88b0-f50b-7de5b372f62e.png">

<img width="2388" alt="_Users_hirokinaganuma_Documents_hackenv_of_v0.9.2_osx_release_addons_ofxOpenNI_win_copy_to_data_openni_path_lib.png" src="https://qiita-image-store.s3.amazonaws.com/0/56510/2ce860bc-601d-a8f3-ab2d-b6c19d24565c.png">
ここでポイントなのは、MacOS用のlibフォルダではなく、Windows用と思われるlibフォルダを追加するとMacOSで動く！という点！！
bin/dataに追加したopenni/libと同じ内容なので、追加の必要ない気がしますが一応追加

追加するとこんな感じ

![mySketch.xcodeproj.png](https://qiita-image-store.s3.amazonaws.com/0/56510/1355cdaf-598b-f386-23e2-8cf1f07e509c.png)

以上で、ofxOpenNIをaddonとして追加することができます。

## 追記
Library Search Pathをセットしないとうまくいかない、、

![Screen Shot 2018-03-11 at 11.37.59.png](https://qiita-image-store.s3.amazonaws.com/0/56510/3f915165-820f-cddb-54c2-e4e0327c685d.png)
Python Numpy array で列（Column) を指定してソートする方法。

##### Python初心者のメモ。内容の間違いなどご注意ください。

    import numpy as np

    def practice():
        data = np.array([[10,9],[8,7],[6,5],[4,3],[2,1]])
        
        print "Before:"
        print data 
        print 
        
        # argsort()で最後の列をソートして順番に並べ替える
        # 必要に応じて'-1'を指定する列に変える
        data = data[data[:,-1].argsort()]
        
        print "After:" 
        print data
    
    if __name__ == '__main__':
        practice()
        pass

##### Output: 

Before:
[[10  9]
 [ 8  7]
 [ 6  5]
 [ 4  3]
 [ 2  1]]

After:
[[ 2  1]
 [ 4  3]
 [ 6  5]
 [ 8  7]
 [10  9]]
JS初心者が盛大に勘違いしていたこと

今回はJavaScriptを学び初めて数週間の私がプログラムを書く上で盛大に勘違いしていて、先輩にコードレビューをしてもらった時にとても恥ずかしい思いをしたことを備忘録も兼ねて記録し、実は・・・と同じように勘違いしていた人が恥ずかしい思いをせずに済むように、また無駄に時間をかけずに少しでも綺麗なコードが書けるようになるようにと願っていろいろ書いていきたいと思います。
##関数を全て即時関数で記述していた
プログラムを学んだことのある人ならば関数はご存知かと思いますが、JavaScriptには関数にはざっくり分けて３種類存在しており、以下のようになります。
・通常の関数

```js
     function example(){
     処理内容1;
     処理内容2;
     }

     example();
```

・無名関数

```js
     var example = function(){
     処理内容1;
     処理内容2;
     }

     example();
```


・即時関数

```js
     (function example(){
     処理内容1;
     処理内容2;
     })();
```

特に使う理由がなければ通常の関数で問題ないのですが、関数の基本的な記述の仕方がわからなかったため、とりあえず間違いなく動く方法を最初に知ったのが即時関数だったので、そのまま全て即時関数で書いていました・・・・

最初は良かったのですが、複数の関数でループ処理（タイマー処理）を用いていたため、途中意味不明のバグに苦しめられまくりました(**)
##contextを複数定義していた
[JS初心者がCanvasを使っていたらぶち当たった壁 - Qiita](https://qiita.com/huji0327/items/5439ab6a4642529b73fa)
canvasを使っていて、色が正しく適用されないバグがあった際に、原因がコンテキストにあると勝手に勘違いしてしまい、それぞれの関数ごとに
・ctx
・ctx_1
・ctx_2
・ctx_3

のような感じで複数定義していた。確かに問題なく動くが後々、あまり良くない書き方だということを教えてもらいました。

##まとめ
JavaScriptはコンパイルしなくても動いてしまう分バグの原因を探るのが難しいように思います。間違って記述していても動いてしまうのが逆に厄介なこともあると実感しました。

基礎が全くない状態でドットインストールなどを見て、必要な箇所だけを勉強しているとこういうことが起きるんですが、最初はしょうがない気もします。一つ一つ問題を解決していく自力をつけることこそエンジニアとしてのスキルだとも思うからです。

##ちょっと脱線

解決不能なバグに頭を悩ませていた時にある先輩にコードを見せたところ、ありとあらゆる方法を駆使して解決してしまうのですが、その方法はまずググるのではなく

```js
       console.log(a);
```
や

```js
       alert(a);
```

をうまく使ってこの時点でこの変数にはこの値が入っている、ってことを一つ一つ確認しているんですね。
少しづつ自分もGoogle先生に頼りすぎず、自分でconsoleを使うようにしてみると、少しづつ自力でバグを解消できるようになってきています。
このように地に足をつけたプログラミングしていけるかどうかが、記述方法を覚えること以上にかなり大事なのではないでしょうか。

こういうことってネットにもなかなか載ってないし、正直かなり泥臭くてやりたくないです。
ネットで記述調べてパパっとコピペして終わり！！ってのは楽でいいんですけど、自分に理解力がなさすぎて、一度記述を読んだだけでは理解できないから、こういうやり方をもっと覚えていきたいな、と思います。
で？どのROMを確認すればいいの？への答え

# 作った経緯
リリースROMを定期的に出してはいるものの諸々の都合でバージョンが増える事がある
（特定の開発者向けとか何処何処迄しか進めなくしてあるROMとか）
Jenkinsでビルドしてるので○○のROMが出来た事はメールで飛んでるし
今回リリース対象のROMはこれだよ。と、まとめていても1，2件は必ず
「で？どのROMを確認すればいいの？」という質問が飛んでくる。

上記のような状態がうっとくなったのでサボるためにどうにかしてみた話です。

# 作った物
仕組みは単純でJenkinsで作ったROMのコピー先をリスト化しといて
そのリストにあるROMをローカルへコピー > 解凍 >エクスプローラで開く　といった事をしています。

```bat:start.bat
@echo off
set LIST_DIR=\\ロム置きようの共有サーバ\rom\release_list\
rem 対象ディレクトリの最新のリストファイルを取ってくる。
for /F "tokens=1* delims=" %%a in ('dir /b /O:D %LIST_DIR%*.txt') do set fname=%%a

collect.bat %LIST_DIR%%fname%

```

```bat:collect.bat
@echo off

rem ------------------------------
rem infomation
rem 確認すべきROMを収集し解凍する
rem ------------------------------

rem ------------------------------ 
rem 設定
set PROJECT_ROOT=%~dp0
set ROM_DIR=rom
set DECOMPRESS_EXE=..\app\7za.exe

rem ------------------------------ 
rem 実装部

rem 保存用フォルダ作成
if exist %ROM_DIR% (
	rmdir /s /q %ROM_DIR%
)
mkdir %ROM_DIR%

rem ドロップされたファイルからコピーするロム情報を取得してコピー
for /f "delims=" %%a in ( %1) do (
	copy /Y %%a %ROM_DIR%
)

rem コピーされたファイルを解凍
for /f "usebackq" %%i in (`dir /B /S %ROM_DIR%\*.zip`) do (
	mkdir %ROM_DIR%\%%~ni
	%DECOMPRESS_EXE% x -o%ROM_DIR%\%%~ni %%i
)

del %ROM_DIR%\*.zip

explorer %ROM_DIR%
```
SharedPreferencesをサクッと使う

# SharedPrefernceとは
SharedPreferencesとは情報をAndroidデバイス内に保存する仕組みです。「わーじゃあSQLiteいらないやん」と一瞬なるかもしれませんが、キー・バリュー形式で1対1で保存されるだけなのでデータをオブジェクトとしてidで紐付けて管理するといったようなことは出来ません。よって、主にユーザー設定や状態保存など、単純で少量の環境設定保存に用いられます。その実態はXML形式のテキストファイルです。保存できるデータの型は`String, int, float, long, boolean, Set<String>`です。<br>
今回は入門ということで基本的な使用方法を説明します。

# Quick Start
### 1.SharedPreferenceのインスタンスを生成します
自分のアプリの任意のContextから`getSharedPreferences()`を呼び出すことで、`SharedPreferences`インスタンスを取得します。
同様のインスタンスは1つのActivityからは、1つしか生成できません。

 ```
 SharedPreferences preferences = getSharedPreferences("DATA", Context.MODE_PRIVATE);

 ```
 ここで1つめの引数は生成する設定ファイルのキー（つまりファイル名のようなもの）です。これはアプリ内で固有のものである必要があります。2つめの引数はこの設定ファイルが自分のアプリ内のみからアクセス可能か、他のアプリからも読み書きが出来るかを設定する定数です。Android端末の設定（音量や明るさ）は外部アプリからも変更できるので、後者(Context.MODE_WORLD_READABLE)であることが多いと考えられます。


###2. データを書き込みます
続いて、SharedPreference.Editorを生成します。このオブジェクトはSharedPreferencesオブジェクトの持つデータを変更する複数のメソッドを持ちます。`putXXX(String key, xxx value)`といったようにキー・バリュー形式でデータをセットしてあげます。
そしてapply()することで、保存の反映を行います。

```
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("HEIGHT", 100);
editor.putBoolean("MARRIED", true);
editor.apply();
```

apply()と同様のメソッドでcommit()がありますが、得られる処理は同じです。
その違いとしては、commit()は同期処理でapply()は非同期処理だということです。以下の公式ドキュメントからの引用に示したように、同じSharedPreferenceインスタンスのeditオブジェクトで完了していない非同期のapply()処理が終わるまで、ブロックされてしまいます。ただ、データ量が少ないことを考えるとどちらでもあまり問題はないように思えます。

> If another editor on this SharedPreferences does a regular commit() while a apply() is still outstanding, the commit() will block until all async commits are completed as well as the commit itself.

### 3. データを読み込みます
呼び出し元のContextにおいて、1. 同様にSharedPrefereインスタンスを生成し、`getXXX(String key, XXX defaultValue)`メソッドを呼びます。1つめの引数は1. で指定した設定ファイルのキー、2つめの引数はもしそのキーに値が存在しないときに代入する初期値です。

```
SharedPreferences preferences = getSharedPreferences("DATA", Context.MODE_PRIVATE);
int height = preferences.getInt("HEIGHT", 150);
```

こんな感じでデータを保存できます。
今後はどういったケースで使用していくかをアプリ開発を通じて調べて、適宜更新していきます。

# 参考資料
* [Android公式トレーニング](http://developer.android.com/intl/ja/training/basics/data-storage/shared-preferences.html)
jupyter memo

# install anaconda

https://docs.continuum.io/anaconda/install



# install jupyter

```
conda install jupyter

```

# install R kernel 

```
conda install -c r r-essentials
conda install -c r r-rocr

```

# install scala kernel

https://github.com/rikima/jupyter-scala

```
wget https://oss.sonatype.org/content/repositories/snapshots/com/github/alexarchambault/jupyter/jupyter-scala-cli_2.10.5/0.2.0-SNAPSHOT/jupyter-scala_2.10.5-0.2.0-SNAPSHOT.zip

unzip jupyter-scala_2.10.5-0.2.0-SNAPSHOT.zip
cd jupyter-scala_2.10.5-0.2.0-SNAPSHOT
chmod +x bin/*
./bin/jupyter-scala

wget https://oss.sonatype.org/content/repositories/snapshots/com/github/alexarchambault/jupyter/jupyter-scala-cli_2.11.6/0.2.0-SNAPSHOT/jupyter-scala_2.11.6-0.2.0-SNAPSHOT.zip


unzip jupyter-scala_2.11.6-0.2.0-SNAPSHOT.zip
cd jupyter-scala_2.11.6-0.2.0-SNAPSHOT
chmod +x bin/*
./bin/jupyter-scala
```

# install spark kernel

https://github.com/apache/incubator-toree

```
pip install toree
jupyter toree install

wget http://ftp.kddilabs.jp/infosystems/apache/spark/spark-1.5.2/spark-1.5.2-bin-hadoop2.6.tgz

tar xvzf spark-1.5.2-bin-hadoop2.6.tgz
sudo ln -s spark-1.5.2-bin-hadoop /usr/local/spark

jupyter notebook
```

- spark-1.6.1-bin-hadoop2.6.tgzでもいける
- hdfs, yarnでもいける

# install matplotlib

```
cd anaconda3
sudo ./bin/pip install matplotlib

```

jupyter notebookで確認

http://matplotlib.org/examples/images_contours_and_fields/contourf_log.html
Vimの背景色をターミナルの背景色と揃える方法

iTerm2の背景色をそのまま適用したいのに、256色のカラーパレット内に背景色と同じ色のパレットが含まれていない…という事がありました。
色々なカラースキームを試してみたいけど、背景色を変えるのは嫌だという気持ちの方は結構居らっしゃるかと思われます。

結論を言うと、背景色を揃えたいグループの`ctermbg`に`none`を与えてあげればターミナルの背景色と同じになります。


```vim:.vimrc
# colorschemeより前に記述.
autocmd ColorScheme * highlight Normal ctermbg=none
autocmd ColorScheme * highlight LineNr ctermbg=none

colorscheme 任意のカラースキーム
```

背景色が違うぞ、というグループに片っ端から`ctermbg=none`を適用してやりましょう。

どんなグループがあるんだっけ？ と思った方は、`:help group-name` `:help highlight-groups`を叩くか、以下のリンクを参考にすると良いかと思われます。
[vimrcのcolorグループ一覧 – Alters Tech Blog](http://tech.alters.co.jp/vimrc/vimrc%E3%81%AEcolor%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E4%B8%80%E8%A6%A7/)
AWS Elastick Beanstalkの環境構築でハマったのでメモ

## Elastick Beanstalkの環境構築でハマったのでメモ

やりたい事としては、ステージ環境、本番環境をそれぞれ作り、AMIを作ったので、各環境で設定しようとした。

なぜかhealthyがwaitingしたまま。。。
```
Still waiting for the following 1 instances to become healthy: [インスタンスID].
```

ERRORで終了。。。

```
Failed to deploy configuration.

Service:AmazonCloudFormation, Message:Stack named 'awseb-e-tpn3cgpqzb-stack' aborted operation. Current state: 'UPDATE_ROLLBACK_IN_PROGRESS' Reason: null

Updating Auto Scaling group named: オートスケールグループ failed Reason: Failed to receive 1 resource signal(s) within the specified duration
```

# 解決
各環境ごとにAMIを作って、それぞれのAMIを設定するとうまくいきました。
ステージ環境で作ったAMIを本番環境で設定しようとしてたので、うまくいかなかったよう。。。
タスクスケジューラでログオフ中に実行するタスクがネットワークドライブにアクセスすると失敗する問題の対処法

Azure Storageを仮想マシンのネットワークドライブとして割り当てましたが
ドライブ文字を含むパスを記述したタスクでは失敗するケースでハマったので
対処法を残しておきます。


以下はタスクで実行するbat内の記述
Zドライブのtestフォルダ内のcsvファイルをCドライブのtestフォルダに移動するコマンド

-失敗例
`move Z:\test\*.csv C:\test\`

下記のように汎用名で記述すれば、ログオフ中に実行しても成功しました。
-成功例
`move \\myaccountname.file.core.windows.net\mysharename\test\*.csv C:\test\`
Mongoidからインデックスを操作する

MongoDBのインデックスをMongoidから個別に削除する方法を調べたので、これを期にMongoid経由でのインデックス操作をまとめておく。

## モデル全体

rakeタスクが用意されているのそれを使う

```
bundle exec rake db:mongoid:create_indexes
bundle exec rake db:mongoid:remove_indexes
```

## 単一のモデルに対して

ここからは`rails c`とかで。

```ruby
Account.create_indexes
Account.remove_indexes
```

## インデックスを個別に削除したい場合

まずは既存のインデックス一覧を取得。

```ruby
Account.collection.indexes.to_a
```

こんな結果が帰ってくる。

```ruby
[{"v"=>1, "key"=>{"_id"=>1}, "name"=>"_id_",    "ns"=>"database_name.accounts"},
 {"v"=>1, "key"=>{"name"=>1}, "name"=>"name_1", "background"=>true, "ns"=>"database_name.accounts"},
{"v"=>1, "key"=>{"email"=>1}, "name"=>"email_1", "background"=>true, "ns"=>"database_name.accounts"}]
```

削除したいkeyを指定してdrop_oneを呼べばOK。

```ruby
Account.collection.indexes.drop_one({"name"=>1})
```
Raspberry Pi3 のシリアルコンソールで通信速度が合わない

Raspberry Pi3 でシリアルコンソールを使おうとすると、bps をどのように設定しても速度が合わず、文字化けの嵐になります。

[Raspberry Pi 3 UART baud rate workaround]
(https://frillip.com/raspberry-pi-3-uart-baud-rate-workaround/) で詳しい解説がされているので、詳細はこちらを読んでもらえればよいのですが、結論から述べると、`config.txt` に

    core_freq=250

を追加することで、問題は解消します。

 
[Raspberry Pi 3 UART baud rate workaround]
(https://frillip.com/raspberry-pi-3-uart-baud-rate-workaround/) に書かれていることの要旨だけ挙げておきます。


> Raspberry Pi 3 になって、Bluetooth のサポートのために、GPIO の UART の割り当てが変更され、uart1 を使うようになった。
> uart0 は Bluetooth が使うようになっている。
> uart0 はコアクロックに影響されないが、uart1 の速度はコアクロックに依存する。
> コアクロックが変わるとシリアルの通信速度も変わる。
> 回避策として、コアクロックを 250MHz に設定する、つまり `/boot/config.txt` で `core_freq=250` を指定することで、適切な速度が設定される。
ものすごく長いrevert Pull Requestを作ることになってしまった場合に知っておくと便利なこと

##はじめに
今回あることがきっかけでメインブランチにマージされた大量のPull Requestマージをひとつずつrevertして大きなrevert pull requestを作ることがあってちょっと苦労するポイントがあったので忘備録を兼ねてメモしておく。

##前提
本記事においては、基本的にメインブランチへのPull Requestマージが行われているプロジェクトであるという前提が必要となります。

##実際に起きた問題
実際におきた問題というのは、Pull Requestマージされたリストを取得しようとしたときに何も考えずマージのログだけを取得して、対象のコミットハッシュだけをrevertしようとした途中でおきました。

```bash
$ git log --merges --oneline
xxxx1a Merge pull request ....
xxxxbd Merge pull request ....
xxxx38 Merge pull request ....
xxxx8e Merge pull request ....
```

基本的に上記のログで出力されたcommit hashを順番にrevertしていけば大丈夫だと思って実行していきました。
最初は順調にrevertされたのですが、あるところでrevertしても通常の変更コミットの記録がなくなり、特に気にせず進めていたら、途中でエラーが出てしまったのです。

```bash
$ git revert -m 1 --no-edit xxxxa0
[revert_topic_branch xxxxaa] Revert "Merge pull request ...."
 1 file changed, 11 insertions(+)

$ git revert -m 1 --no-edit xxxx5a
On branch revert_topic_branch
nothing to commit, working directory clean

... (中略)

$ git revert -m 1 --no-edit xxxx57
error: could not revert xxxx57... Merge branch 'topic_branch_hogehoge' into revert_topic_branch
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
```

##原因
結局原因は、何だったかというと途中にトピックブランチへのPull Requestのマージログも含まれていて、それもgit revertコマンドでrevertしようとしていたのが問題でした。
では、どのようにしてトピックブランチへのPull Requestのマージを省くかというと、`--graph`オプションを使うことでそれを見分けることができます。
簡単に言うと下記の例では一番左に`*`マージのある行だけをピックアップしてrevertしていけばいいということです。

```bash
$ git log --oneline --merges --graph
* xxxxxd0 Merge pull ....
* xxxxx48 Merge pull ....
* xxxxx30 Merge pull ....
* xxxxx82 Merge pull ....
* xxxxx25 Merge pull ....
* xxxxx9d Merge pull ....
* xxxxx95 Merge pull ....
* xxxxx08 Merge pull ....
* xxxxxa0 Merge pull ....
*   xxxxx26 Merge pull ....
|\
| * xxxxx5a Merge pull ....　 （← git revert対象外）
| * xxxxxf9 Merge pull .... （← git revert対象外）
| * xxxxxaf Merge pull .... （← git revert対象外）
| * xxxxxf7 Merge pull .... （← git revert対象外）
| * xxxxx17 Merge pull .... （← git revert対象外）
| * xxxxx03 Merge pull .... （← git revert対象外）
| * xxxxx57 Merge branch .... （← git revert対象外）
| * xxxxx38 Merge pull .... （← git revert対象外）
| * xxxxxb1 Merge pull .... （← git revert対象外）
* | xxxxx53 Merge pull ....
* | xxxxx95 Merge pull ....
* | xxxxx65 Merge pull ....
* | xxxxxad Merge pull ....
```

よくよく考えたらまぁそうだよなー、という内容でしたが危うくハマりかけました。

##参考サイト
* [git log よく使うオプションまとめ](http://qiita.com/take4s5i/items/15d8648405f4e7ea3039)

##おわりに
gitのコマンドを色々知っておくと便利な事って色々ありますよね。
今回の事も新たに勉強になってためになりました (^ω^)
[AWS]DNSサーバのRoute 53移行[Route53]


```
key = [AWS,Route 53,BIND,name.conf]
```

オンプレミスのBINDサーバをRoute53に移行しましょう。
Route53の基本的な設定方法は昔書いた記事を参考にしてください。

現在動いているものの移行
__現行稼働中⇒Route 53__

[はじめてのAmazon Route 53](http://qiita.com/Yuki_BB3/items/effdf1bb38263bfef82a)

---
###0.準備
DNSサーバからドメインのゾーン情報を取得

/etc/named.conf
に、ホストされてるドメイン情報が書かれていると思います。
その中に、各ドメインのゾーン情報ファイルの場所が書かれているのでそいつをGETしてください。

sample

```named.conf:named.conf
zone "example.jp" {　
        type master;
        file "/path_to/example.zone";　
};

```

上記サンプルの __file__ のところにあるのがゾーンファイルです

ゾーンファイルの中身はこんな感じ

sample

```named.conf:zone-file
$TTL	3600
@	IN	SOA	hogehoge.com. root.hogehoge.com  (
			//ここにTTLだとかリフレッシュだとかの数字がくる//
 			 )		
 			 
	IN	NS	ドメインに対するネームサーバ
	IN	MX	メール
www	IN	A	192.168.10.10
fuga IN A  192.168.10.10

```
みたいな感じで書いてあれば対象ファイルはそれです。

---

###Route 53の作業
[はじめてのAmazon Route 53](http://qiita.com/Yuki_BB3/items/effdf1bb38263bfef82a)の中ほどを参考にホスティッドゾーンを作成してください。
名前は、DNSでホスティングしているドメイン名を指定してください。
つくたドメインを選択すると次の画面の右上に __”import Zone”__ があるのでそれをクリックします。

![2ac98e75-57e1-84d8-724c-bd5d29a65023.jpeg](https://qiita-image-store.s3.amazonaws.com/0/52141/14c0c000-4b0e-93dc-5873-79a0fe3d90c9.jpeg "2ac98e75-57e1-84d8-724c-bd5d29a65023.jpeg")

右側にテキストエリアが出てくるのでその中に先ほどのゾーンファイルをまるまるコピペしましょう。
いちいち書かなくても一気に設定が流し込めます。

注意点
[Amazon Route 53(DNSサービス)にBINDゾーンファイルをインポートする](http://dev.classmethod.jp/etc/route53-import-zone-file/)
に書かれているように幾つか制限があったりするのでその辺は臨機応変に。

---
###ドメインレジストラ側の作業

レジストラ側でネームサーバを変更します。
指定するのはドメイン作成時に作られたNSレコードに入っている４つのネームサーバ

以前の記事でお名前.comに設定しているやつです。
ってかそのまんま。

お名前.com以外を使っててもやることは同じです。
管理画面のどこかにネームサーバの変更があるはずなのでそこを新しいものに書き換えてください。

---
###設定が浸透するまで待つ

多分１５分もあればネームサーバが切り替わっているはずなので確認してください。
ターミナルでnslookupを使って確認しましょう。

```bash:nsloolup
$ nslookup
$ hogehoge.com
```

設定したamazonなんちゃらかんちゃらが帰ってくれば大丈夫です。

###注意
いつまでも切り替わらない！といったときは、以前そこにアクセスしたことがあるばあい、ネットワークでキャッシュされているかもしれません。
自分はいつまでも切り替わらない！とハマりましたがキャッシュが原因でした。
テザるなりwimax使ってみるなりして確認してください。
マシンのキャッシュとかも疑うといいかと。

---

こんな感じでRoute 53側に切り替わればオンプレのDNSは止めても大丈夫。
OS X アプリでStoryboardとSegueを利用する（概略）

# Storyboardとは
StoryboardはiOS向けの画面の遷移をグラフィカルに指定できる画面遷移エディタのようなもので、これを作るだけで画面遷移が可能になるためプログラミングが不要（あるいはごくわずか）になる優れものです。
iOS専用のように思われてますが、実はOS Xアプリでも使えます。

# OS X での使いどころは？
ウインドウの表示(show)、ポップオーバー(popover)や、モーダル(modal)という既定のアクションがあり、これらを使用するとノーコーディングでこれらを行うことが可能です。（もちろん値の受け渡しなどでコーディングは必要になります）

しかし、一番の使いどころは画面遷移ではありません。
ひとつのウインドウに複数のビューを表示する場合、各ビューをNSViewContollerで管理し、-awakeFromNibなどで一つのウインドウに配置するということをやったことがないでしょうか？
これこそが、OS XでのStoryboardの使いどころです。
Storyboardを使えばビューの配置のために一切のコードを書く必要がなくなります。

# 複数のビューを一つのウインドウ（ビュー）に配置する

まず、Storyboardを作りましょう。
新規作成パネルからStoryboardを選ぶだけです。
![スクリーンショット 2016-03-29 20.24.04.png](https://qiita-image-store.s3.amazonaws.com/0/2117/7b6867a2-327e-f1c9-33f8-eadf8e36d2f6.png)


対象となるNSWindwControllerを配置します。通常のIBでの操作と同じで右のリストからドロップするだけです。
![スクリーンショット 2016-03-29 20.24.53.png](https://qiita-image-store.s3.amazonaws.com/0/2117/40d7f304-1b36-ec06-93cf-85a0226b0f7a.png)


IBとは違いNSWindowとそのContentViewControllerが関連付いた形で配置されます。
![スクリーンショット 2016-03-29 20.25.59.png](https://qiita-image-store.s3.amazonaws.com/0/2117/4b67895f-64a1-2248-e054-6971173537c6.png)

では、複数のビューを配置しましょう。今までですと、ここにダミーのカスタムビューを配置していたと思いますが、StoryboardではContainerViewという特別なビューを使用します。
配置自体は通常のアイテムと同じです。
![スクリーンショット 2016-03-29 20.26.19.png](https://qiita-image-store.s3.amazonaws.com/0/2117/4a5ac1e6-e224-c822-fa13-49eb9a4fe808.png)


ContainerViewを配置すると、自動的にNSViewControllerが配置され関連付けられます。
このNSViewControllerが持つViewがウインドウが開かれたとき自動的に対応したContainerViewの位置に配置されます。


![スクリーンショット 2016-03-29 20.38.21.png](https://qiita-image-store.s3.amazonaws.com/0/2117/54910ef4-523b-b0cd-485e-e44dbd633123.png)
Storyboardでの配置例

![スクリーンショット 2016-03-29 20.50.05.png](https://qiita-image-store.s3.amazonaws.com/0/2117/7ca22062-c228-033c-fbd2-7e8ad17672eb.png)
上の配置例を実行したところ


コードは一切必要ありません。

もちろん、対象がウインドウではなくビューの場合も、方法は同様です。
NSWindowControllerの代わりにNSViewControllerを配置して、そのビューにContanerViewを配置していくだけです。

恐ろしく簡単です。

## Outlet接続やCocoaBindingsなどに注意
ひとつのStoryboardにすべてのNSViewControllerが見えますが、Outlet接続などは今まで通りNSViewControllerごとになります。
NSViewControllerを超えてのOutlet接続などはできません。

# じゃあ、セグエって何？
英語の意味はよく分かりませんが、機能としてはビューの遷移時の動作をカプセル化したものです。（突っ込み歓迎）

ウインドウを表示するときにフェードイン＋ズームインではなくほかのアニメーションで表示させたいというときにカスタムセグエを作成し、表示動作を定義すれば、そのセグエをStoryboardで指定するだけで思い通りの遷移が可能となります。

また、ウインドウ内でビューの切り替えは既定のアクションではできませんが、カスタムセグエを用意することでStoryboard上で指定が可能になります。


# まとめ
僕自身「どうせStoryboardってiOS専用なんでしょ？　ﾌﾟﾝｽｶ」といままで食わず嫌いでしたが、かなり使えます。
画面遷移以外でも使えるということを知ったのがすごく大きいです。
これからは積極的に使っていくつもりです。


時間があれば実践編を書きたい。

4月3日追記:
実践編を投稿しました
[OS X アプリでStoryboardとSegueを利用する ビューを切り替える編](http://qiita.com/masakihori/items/d9bb915ca2a0918375ae)
SQLで文字列が何個含まれるか調べる方法

# SQLで文字列が何個含まれるか調べる方法

## やりたいこと

テーブル `hoge` の カラム `fuga` 内に、
何個 `foo` という文字列が含まれているかを調べたい。

## SQL

```
SET @keyword = 'foo';
SELECT 
  TRUNCATE((LENGTH(`fuga`) - LENGTH(REPLACE(`fuga`, @keyword, ''))) / LENGTH(@keyword), 0) as `cnt`
FROM `hoge`;
```

## 何をやってるか

『“`fuga` カラムに入ってる文字列”の文字数』から、
『“↑の文字列から `foo` を空文字に置換した文字列”の文字数』を
引いて
『`foo` の文字数』で割って、
最後に小数点以下を切り捨ててます。（.0000 が鬱陶しかったので）

## 更に

```
SET @keyword = 'foo';
SELECT 
  TRUNCATE((LENGTH(`fuga`) - LENGTH(REPLACE(`fuga`, @keyword, ''))) / LENGTH(@keyword), 0) as `cnt`
FROM `hoge`
WHERE
  `fuga` LIKE CONCAT('%', @keyword, '%')
;
```

みたいに 文字列が含まれるレコードを検索してやると、少しは早くなるかもしれない…。


## 最後に

ものすご～く遅いSQLなので、アプリ内で↑のSQLは叩かない方がいいと思う。
メンテナンス等で、直接DBに接続して、調査するときなどに使って下さい。
というか何か他にいい方法あったら教えて下さい。
ES2015 でのモジュールの書き方は？

いろいろ方法はあると思うけど、何が良いのかが分からない。
とりあえず以下の条件で考える。

- 複数のメソッドがある
- 値を保持しない

値を保持するなら class 化するけど、
しないならインスタンスを作る必要がないので、
その場合のモジュールってどう書くのがベストかが気になる。

### 呼び出す側
```js:main.js
const { addstr1, addStr2 } = require('./module');

addstr1('yamada'); // OK! yamada!!!
addstr2('tanaka'); // OK! tanaka???
```

### 呼び出される側

#### 1. 単純にオブジェクトを渡す
記述量が少ない。

```js:module.js
const addStr = (str) => {
  return `OK! ${str}`
};

module.exports = {

  addStr1: (str) {
    return addStr(`${str}!!!`);
  },

  addStr2: (str) {
    return addStr(`${str}???`);
  },

}
```

#### 2. 即時関数で処理して渡す
ザ・モジュールパターンって感じ？

```js:module.js
module.exports = (() => {

  const addStr = (str) => {
    return `OK! ${str}`
  };

  return {

    addStr1: (str) {
      return addStr(`${str}!!!`);
    },

    addStr2: (str) {
      return addStr(`${str}???`);
    },

  }

})();
```

#### 3. class 作ってインスタンスメソッドを渡す
ES2015 だから class 使っちゃう？的なのり。

```js:module.js
class Sample {

  addStr1(str) {
    return this.addStr(`${str}!!!`);
  }

  addStr2(str) {
    return this.addStr(`${str}???`);
  }

  // private
  addStr(str) {
    return `OK! ${str}`;
  }

}

const instance = new Sample();

module.exports = {
  addStr1: instance.addStr1.bind(instance),
  addStr2: instance.addStr2.bind(instance),
};
```

どれが良いのだろうか？
他にも方法があるとは思うけど。
全然わからん。
Vagrant で autofs を使って vboxsf マウントした中のディレクトリを mount --bind する

これ↓の vboxsf 版（VirtualBox の共有フォルダ）なのですが、妙なところでハマったのでメモ。

- [autofs で cifs マウントした中のディレクトリを mount --bind する](http://qiita.com/ngyuki/items/b3af921509c5dc0e4ed2)

## 結論

Vagrant で `/vagrant` にマウントしている場合、VirtualBox には `vagrant` という名前で共有フォルダが作成されています。

![virtualbox-01.png][]

autofs で設定するときはこの名前の先頭に `/` を付けて指定します。例えば `:/vagrant` です（`:vagrant` ではなく）。

*/etc/auto.oreore*

```
/opt/sandbox -fstype=vboxsf,uid=vagrant,gid=vagrant,rw :/vagrant \
  /vendor -bind :/var/opt/sandbox/vendor \
  /node_modules -bind :/var/opt/sandbox/node_modules
```

これで、

- `/opt/sandbox`
    - ホストを vboxsf でマウントしたもの
- `/opt/sandbox/vendor`
- `/opt/sandbox/node_modules`
    - 仮想環境のローカル

となります。


もし Vagrant で `/opt/aaa/bbb/ccc` などというパスにマウントするように設定したなら、VirtualBox には `opt_aaa_bbb_ccc` という名前で共有フォルダが作成されています。

![virtualbox-02.png][]

先頭に `/` を付けて `:/opt_aaa_bbb_ccc` をソースに指定します。

```
/opt/sandbox -fstype=vboxsf,uid=vagrant,gid=vagrant,rw :/opt_aaa_bbb_ccc \
  /vendor -bind :/var/opt/sandbox/vendor \
  /node_modules -bind :/var/opt/sandbox/node_modules
```

## 試行錯誤の跡

VirtualBox の共有フォルダの名前が  `vagrant` であれば、次のようにマウントすることができる。

```sh
sudo mount.vboxsf vagrant /mnt
```

一方 `/vagrant` という名前を指定すると失敗する。VirtualBox の共有フォルダの名前は `vagrant` なので当然。

```sh
sudo mount.vboxsf /vagrant /mnt
# mount.vboxsf: mounting failed with the error: Protocol error
```

autofs をインストールする。

```sh
sudo yum -y install autofs
```

`auto.master` を設定する。

```sh
sudo tee <<'EOS' /etc/auto.master.d/oreore.autofs
/-   /etc/auto.oreore
EOS
```

autofs で次のように `:vagrant` を指定すると成功する。

```sh
sudo tee <<'EOS' /etc/auto.oreore
/opt/sandbox -fstype=vboxsf :vagrant
EOS
```

がしかし、「[autofs で cifs マウントした中のディレクトリを mount --bind する](http://qiita.com/ngyuki/items/b3af921509c5dc0e4ed2)」と同じように Multiple Mounts すると失敗する。

```sh
sudo tee <<'EOS' /etc/auto.oreore
/opt/sandbox -fstype=vboxsf :vagrant \
  /vendor -bind :/var/opt/sandbox/vendor
EOS
```

```sh
ll -d /opt/sandbox
# drwxr-xr-x. 2 root root 0 Mar 29 11:21 /opt/sandbox
ll /opt/sandbox
# ls: cannot open directory /opt/sandbox: No such file or directory
```

マウントのソースを `:/vagrant` にするとなぜか大丈夫。

```sh
sudo tee <<'EOS' /etc/auto.oreore
/opt/sandbox -fstype=vboxsf :/vagrant \
  /vendor -bind :/var/opt/sandbox/vendor
EOS
```

[virtualbox-01x.png]: https://qiita-image-store.s3.amazonaws.com/0/8734/95deebc3-d329-498f-f1ab-21c7b3641c5c.png
[virtualbox-02x.png]: https://qiita-image-store.s3.amazonaws.com/0/8734/7a8ec0cf-9b8d-280b-e313-160aadaa838d.png

[virtualbox-01.png]: https://qiita-image-store.s3.amazonaws.com/0/8734/dc3d53f4-a069-e281-b237-58e7ca3543b4.png
[virtualbox-02.png]: https://qiita-image-store.s3.amazonaws.com/0/8734/863fc10a-72ef-2ebd-b84b-23bcbaa175d0.png
npm install時にpixivのデイリーランキングをターミナルに表示する

みなさん、pixiv好きですか？わたしは好きです。日々色々な絵がアップロードされ、本当に楽しいですよね。
今回は、`npm install`の時間にpixivのデイリーランキングを表示して、退屈な時間を最高の時間にするハックをすることにします。

[github: akameco/npm-pixiv](https://github.com/akameco/npm-pixiv)

## デモ
こんな感じです。

![demo.gif](https://raw.githubusercontent.com/akameco/npm-pixiv/master/media/demo.gif)


## インストール
npmからインストールできます。
しかし、残念ながら最新版のiTerm2でないと画像が表示されません。iTerm2が最新版でない人はインストールをお願いします。

```
$ npm i -g npm-pixiv
```

`npm-pixiv`というコマンドを提供しますが、.bashrcや.zshrcで以下のように設定するのがおすすめです。

```.zshrc
alias npm=npm-pixiv
```

## 実装
実装については、実はほぼおなじ内容(ポプテピピック版)の記事を書いたので、そちらを参照してください。

[npm installの無駄な待ち時間を圧倒的にカイゼンする方法 - Qiita](http://qiita.com/akameco/items/78f7d1dc151bb909128d)

差異についてだけ説明をしようと思います。
pixivをスクレイピングし画像を取得していますが、pixivの画像はリファラが制限されています。
リファラのついての説明をググったらちょうどpixivのヘルプがでてきたので引用しておきます。

> リファラとは、Webページのリンクをクリックして別のページに移動した際のリンク元（一つ前のページ）のページのことです。
> [pixiv ヘルプセンター｜リファラとは何ですか？](http://help.pixiv.net/457/)

これがどういうことかというと、pixivのサイトを経由せずに画像を表示しようとすると403が返るので閲覧することができないということです。これを制限しないと、いくらでも別のサイトのimgに埋め込まれてしまうのでこの対策は当然ですね。httpリクエストのヘッダーのRefererを`http://www.pixiv.net/`にすることで回避できます。
gotでは以下のように書きますが、他のhttpライブラリでも似た感じ書けると思います。

```js
got(url, {
	encoding: null,
	headers: {
		Referer: 'http://www.pixiv.net/'
	}
}).then(res => res.body);
```


## まとめ
以前、npm install時にポプテピピックの4コマを流していましたが、npm installを繰り返すごとに竹書房が破壊され罪悪感がありました。しかし、pixivのランキングを流すことで最高の気分でプログラミングができるようになりました。
むしろ今は、pixivのランキングを見るために無限にnpm installをするまであります。

75行程度の簡単なコードですが、普段のプログラミングが少し楽しくなりました。仕事のコードだけではなく、役に立つかどうかは置いといて小さなハックを楽しんでみるといいかもしれません。
なお、仕事中にこれを表示して怒られたなんて、そんな責任は一切負いませんのであしからず。

githubにて公開してるので、issueやプルリクエストをお待ちしております。
[github: akameco/npm-pixiv](https://github.com/akameco/npm-pixiv)

## 参考
[npm installの無駄な待ち時間を圧倒的にカイゼンする方法 - Qiita](http://qiita.com/akameco/items/78f7d1dc151bb909128d)
[node.jsによるコマンドラインツール - Qiita](http://qiita.com/akameco/items/585f2c53629f1e66f4f1)
[iTerm2の新機能を使ってターミナルにポプテピピックの4コマをランダムに表示する - Qiita](http://qiita.com/akameco/items/13a62b7b8f8efd542d98)
設定をコピーするツールをつくった

個人的備忘録です。
環境ごとに同じ設定なんだけど将来変えるかもしれないとかで、
どう考えても絶対にまちがえる自信があったので間違いようがないように
指定した引数をコピー元としてそれと同じ設定のグループにだけコピーしてくれるツールを作りました。
人より忘れんぼうとうっかりなのでその防止ということです。
bashだとなんか配列の扱いほかだいぶ色々面倒な気がしたのでrubyでがんばってみたっす。

```
##バージョン定義
version = "v1"

##同じ設定の環境グループを定義する
fuga_envs1 = ["fuga1","fuga3","fuga7","perf","fuga-test1","fuga-mng","fuga-test3"]
hoge_envs1 = ["hoge-dev1","hoge-dev6","hoge-prod","hoge-mng"]
piyo_envs1 = ["piyo-mng","piyo-dev1","piyo-dev6","piyo-prod","piyo6"]
nyan_envs1 = ["nyan-dev1","nyan-dev6","nyan-mng","nyan-perf","nyan-prod"]

###同じ設定のグループ名を登録(これあんまいみなかった）
#same_setting_groups = %w("fuga_envs1" "hoge_envs1" "piyo_envs1" "nyan_envs1")
#puts same_setting_groups

##引数からコピー元の環境を定義
sorce_file_env = ARGV[0]
#puts sorce_file_env

##コピー元環境が含まれる同じ設定のグループ名を特定
source_include_group = []
if fuga_envs1.include?("#{sorce_file_env}") 
 source_include_group=fuga_envs1
 region="us-xxxx-2"
elsif hoge_envs1.include?("#{sorce_file_env}")
 source_include_group=hoge_envs1
 region="us-xxxx-2"
elsif piyo_envs1.include?("#{sorce_file_env}")
 source_include_group=piyo_envs1 
 region="us-xxxx-2"
elsif nyan_envs1.include?("#{sorce_file_env}")
 source_include_group=nyan_envs1 
 region="ap-northxxxx-1"
end

##ディレクトリを定義（コピー元と同一である前提）
#dir=`/bin/find ./ -name "#{sorce_file_env}" -type d|/bin/sed -e "s/#{sorce_file_env}//g"`
pwd = Dir::pwd
pdir = "#{region}/#{version}"
#puts pdir

##コピーを実行
src = "#{pwd}/#{pdir}/#{sorce_file_env}/forward.conf"
dest_path = "#{pwd}/#{pdir}"
puts "source_file: #{src}"
#puts dest_path

#  system("\cp -pf #{pwd}/#{pdir}/#{sorce_file_env}/* #{pwd}/#{pdir}#{env}/")
require "fileutils"
source_include_group.each do |env|
 next if env.to_s == sorce_file_env.to_s
 dest = "#{dest_path}/#{env}/"
 puts "destination_dir: #{dest}"
 FileUtils.cp(src, dest)
end
```

バックアップとかはどうせgitで管理してるファイル群なので気にしていません。git checkoutすれば戻るし。
nextとto_sほかやりたいことは検索すると大体わかるいい時代ダナー。
これをつかえば絶対に間違えない気がします。定義があってれば。
【Wordpress向け】現在のページへのリンクを無効化して、スタイルを変える

Wordpress向けです。
##仕様
構造が同じページが複数ある。
サイドバーにそれらのページへのリンク一覧がある。
テンプレートは複数作らずに、ページ内にある現在のページへのリンクを無効にして背景色をつけるなどスタイルを変えたい。

##HTML
http://piyo.jp/hogehoge/kuma/
http://piyo.jp/hogehoge/tama/
http://piyo.jp/hogehoge/kiso/
という三つのページがある想定で進めます。

```html:HTML
<section>
   <h2>KUMAGATA</h2>
   <ul>
      <li><a href="../kuma" data-trigger="trigger">球磨</a></li>
      <li><a href="../tama" data-trigger="trigger">多摩</a></li>
      <li><a href="../kiso" data-trigger="trigger">木曽</a></li>
    </ul>
</section>
```
というサイドバーがあるとします。

```js:js
var temp = function(){
	var $target = $('[data-trigger]'),  //サイドバーにあるリンク達
		url = window.location.href,  //現在のページのurl
		before = /(http[\s\S\w]*?\/hogehoge\/)/,  //'http'から'hogehoge/'までを指定
		after = /(\/)/,  //url最後の'/'を指定
		$trigger = url.replace(before, '').replace(after, ''),  //現在のページurl文字列から上記のbeforeとafterを削除
		compare_fnc = function($target,other,current){
			var $target_url = $target.attr('href'),  //サイドバーにあるリンクのurl
				before = /(\.\.)/,  //'../'を指定
				after = /(\/)/,  //url最後の'/'を指定
				$target_url_r = $target_url.replace(before, '').replace(after, '');  //サイドバーにあるリンクのurl文字列から上記のbeforeとafterを削除
			if($target_url_r == $trigger) {  //現在のページurlとリンク先が同じtargetに対して以下の動作を実行
				$target.removeClass(other).addClass(current);  //引数otherに指定したクラスを削除し、引数currentに指定したクラスを追加
				$target.on('click',function(){
					return false;  //リンク機能を停止
				});
			}
		};
	if(!$target.length) return;  //targetが無い場合return
	$target.each(function(){  //eachでcompare_fncを回す
		compare_fnc($(this),'primary_btn','primary_btn-on');
	});
};
```

##まとめ
wordpress使うのやめたい
Slackみたいなbot機能を、Chatworkで実装してみた。

#動機
・バイト先で、SpreadSheetで項目が×になってる案件を周期的にメンバーに通知するシステムの作成を頼まれた。
・そこでは普段Chatworkベースのコミュニケーションをやっているので、Chatworkにアラートがいくようにしたい。
・GASとChatwork Apiで実装できるんじゃなかろうか。

#使用言語・環境
#####言語
・[Google Apps Script(GAS)](https://developers.google.com/apps-script/)
 Javascriptが元の言語。Google系のサービスをスクリプトで動かせる。

#####環境
・Google Drive
・[Chatwork](http://www.chatwork.com/ja/)

#やり方
**1.SpreadSheetを参照するシステムを作る。**

こんな感じ

```as

for(var j = 0; j < 15; j++){
    var counter = 0;
    var emailtext_tmp = "";
    emailtext_tmp += strings[j] + "\n";
    for(var i = 5; i < MAX_SIZE; i++){
      if(manage_values[i][13] == name){
        if(manage_values[i][j + 24] == "×" || manage_values[i][j + 24] == "△（不備あり）"){
          emailtext_tmp += manage_values[i][4] + " / " + manage_values[i][2] + " / " + manage_values[i][10] + " / " + manage_values[i][13] + "\n";
          counter++;
        }
      }
    }
    emailtext_tmp += "\n";
    if( counter != 0)emailtext += emailtext_tmp;
  }
```

**2.Chatwork Apiを取得**
詳細は[こちら](http://developer.chatwork.com/ja/)

**3.Google Apps Scriptから[このライブラリ](https://github.com/cw-shibuya/chatwork-client-gas)を入れる。**
入れ方は[こちら](http://www.bmoo.net/archives/2012/07/314406.html)

**4.2で取得したapiキーを3のスクリプトに入れて各roomにメッセージを送る。**

**5.GASでタイマー設定をすると、自動で送ってくれるようになる。**

#参考
・この[ライブラリ](https://github.com/cw-shibuya/chatwork-client-gas)がすごく便利。
プロダクトデザインの仕事フローについて

#1. Idea Sketch / Brain Storming
まずはテーマと、プロジェクトの納期や自由度に合わせてブレストを行う。
スケッチを描いて伝えるのが大切で、このときは下手な絵の方が意見が集まってむしろいいくらい。

#2. Brand Design
どこで、誰に、どのように売るか、というところを考える。
Lean Diagramなどを使うのもいい。

#3. Industrial Design Sketch
ブランドデザインをもとに、どんな機能とインターフェースを持った製品にするか、のスケッチを行う。

#4. Dirty Modeling (1/1 scale)
紙の上では見えなかったものを体感する。

#5. Modeling/Rendering
CADを使って設計する。

#6. Video Sketch
そのアイデア・製品が実現した時にどのようになるかをsimulationする。
偽のカタログを作るのもあり。

#7. Materializing
3D print等を行い、実際に手に持って確認する。

#8. Function Sketch
センサやアクチュェータをつけ、実際に動くものをつくる

#9. Real Prototyping
FunctionとDesignを融合させる
Your app(iOS) status is Pending Contract というメールが（大量に）来た場合どうすればいいか。

#Q:Your app(iOS) status is Pending Contractって何？
Your app(iOS) status is Pending Contractというメールが（大量に）来た場合どうすればいいでしょうか？
検索しても英語のページばっかりだし・・・。

#A:お金を払いましょう
developer program のお金を払い忘れて、全てのアプリの販売が停止されている
状態なのでお金を払いましょう。

お金払ったら、ちょっとずつストアに復活していきます！

それにしても、あせったー＞＜
Jetbrains Xodus メモ

# [Jetbrains Xodus](http://jetbrains.github.io/xodus/) とは

[IntelliJ IDEA](https://www.jetbrains.com/idea/)で有名な[Jetbrains](https://www.jetbrains.com/)社が開発してる Java 製の KVS データベースらしい。KVS と言うと Memcached とか Redis とかが代表的だけど、あっちが分散 KVS なのに対し、Xodus は Java 版 LevelDB とでもいうべき組み込み型のライブラリ。

特徴としては、最近の RDBMS では一般的になっている MVCC(マルチバージョン コンカレンシー コントロール)とスナップショット分離に対応したトランザクション制御が利用できるという点。

同系統で最近話題にのぼることが高い [MapDB](http://www.mapdb.org/) よりも速いとのこと。まだ正式版ではないので、本番には使えないし将来的に使い物になるかはわからないけど、使い方だけでもということで。

# インストール

現在は Maven Central からは取得できないので、Sonatype のリポジトリから取得が必要（以下は gradle の場合の記載例）。

```groovy:build.gradle
repositories {
    mavenCentral()  // for release artifacts
    maven {         // for snapshot artifacts
        url 'https://oss.sonatype.org/content/groups/public'
    }
}
dependencies {
    compile group: 'org.jetbrains.xodus', name: 'xodus-environment', version: '1.0-SNAPSHOT'
}
```

# 使い方

## 基本的な流れ

基本的な流れは次の通り。いちいちトランザクション制御が入るところが面倒ですが、それ以外は単純。

1. ファイルシステムから Environment（RDBMS でいうところのデータベース）を取得
2. Environment から Store（RDBMS でいうところのテーブル）を取得
3. Store にキーと値のペアを書き込んだり、キーを指定した値を取得したりする

openStore メソッドの第二引数に WITH_DUPLICATES を使うことで値の重複を許すことも可能。

```java
Environment env = Environments.newInstance("./data");
try {
    Store store = env.computeInTransaction(tx -> {
        return env.openStore("store", StoreConfig.WITHOUT_DUPLICATES, tx);
    });
			
    ...
} catch (Exception e) {
    env.close();
}
```

## 値の設定

Store の put メソッドにキーと値を指定する。値は、最終的にバイト列にする必要があるが、逆に言えばバイト列にできれば何でも設定できるということで、エンティティ変換系のユーティリティも用意されている。

```java
    env.executeInTransaction(tx -> {
        store.put(tx, StringBinding.stringToEntry("key"), StringBinding.stringToEntry("value"));
    });
```

## 値の取得

Store の get メソッドにキーを指定する。

```java
    String result = env.computeInReadonlyTransaction(tx -> {
        return StringBinding.entryToString(store.get(tx, StringBinding.stringToEntry("key")));
    });
```

WITH_DUPLICATES で複数値ある場合には、openCursor メソッドを使って Cursor を回す必要がある（キーによる頭出しは可能）ようだ。


```java
    List<String> result = env.computeInReadonlyTransaction(tx -> {
        List<String> list = new ArrayList<>();
        try (Cursor cursor = store.openCursor(tx)) {
            String key = "key";
            if (cursor.getSearchKey(stringToEntry(key)) != null) {
                do {
                    String ckey = entryToString(cursor.getKey());
                    if (key.equals(ckey)) {
                        list.add(entryToString(cursor.getValue()));
                    } else {
                        break;
                    }
                } while (cursor.getNext());
            }
        }
        return list;
    });
```

# まとめ

Pure Java ライブラリではない場合、マルチスレッド対応が不安になりますが、このライブラリなら安心かも。あとは、正式版が出てくれればというところでしょうか。
AtomのMarkdownプレビューをGitHubスタイルにしたり、カスタマイズしたりする。

コメントをいただいたので反映しました。
以下のかんたんな手順でGitHubスタイルに準拠できます。

1. Settingsを開く。
2. パッケージというサブメニューを選択する。
3. `markdown-preview`を検索して、Settingsボタンを押す。
4. Use GitHub.com styleにチェックする。

以上です。
カスタマイズをしたい人というのは、以下の記事を参照してください。

----


AtomのUI themeの何を選択するとしても背景色は黒系統で運用するわけじゃないですか。
そこでMarkdownプレビューすると背景色が黒いけど、プレビューは白背景で黒文字にしたいわけじゃないですか。
どうすればいいんですか？

ということを会社の人に言われて、CSS書きました。

Markdownのプレビューがこうなります。（AtomのREADME参考にちょっと追記してます。）

![Kobito.8Htn0r.png](https://qiita-image-store.s3.amazonaws.com/0/58800/72d34b4c-490c-f85e-efd2-e734a440a3e4.png "Kobito.8Htn0r.png")

`styles.less` に以下のコードを追記します。

```styles.less
.markdown-preview {
  background: white !important;
  p, h1, h2, h3, h4, h5, h6, li, th, td, strong {
    color: black !important;
  }
}
```

`Settings - Themes`からyour stylesheetのリンクをクリック。あるいは`Settings - Open config folder`から`.atom` ディレクトリ内にある`styles.less`を選択。

背景を白く。最低限のテキストを黒くしてるだけ（リンクなどは変更なし）です。

みなさまAtomに移行しましょーというメッセージ込です。
俺のRSpec死闘記_describeとitとexpect


###前回のお話

[俺のRSpec死闘記_プロローグ](http://qiita.com/steroid66/items/71942bef61baa3268ef5)

##今回は基本の基本describeとexpectと闘います。

- まずうまいことinstallされていれば、Rspecのテストコードはプロジェクトルート直下に```spec```ディレクトリができているはず。

- そこにapp配下と同じ感じのディレクトリ構造があるので、書きたいクラスのテストクラスを同じ階層におきましょう。

今回は、app/models/baku.rbというmodelクラスのテストをspec/models/baku_spec.rbとして、進めます。

##Rspecの基本構造
Rspecのコードは大体こんな感じ。今回はすげー最小限で。
今後どんどんカッコ良くしていく。

```ruby:baku_spec.rb
require 'rails_helper'

describe Baku do
  baku = Baku.create(name:"Baku",sex:"Man")

  it "インスタンスが無事に生成されること"　do
    expect(baku).to be valid
  end

  it "Bakuが表示されること"　do
    expect(baku.name).to eq "Baku"
  end
end
```

1行目の```require 'rails-helper'```はお約束。

###describeブロック
テストの一番外枠って位置づけ。
Bakuモデルのテストするよ！っていう感じ。この中にBakuモデルに必要なテストを書いていく。

###it ブロック
さて、describeでBakuモデルのテストを行うことはわかったので、どんなテストをするのか書いていく。
ここでは、Bakuモデルの「インスタンスが無事に生成されること」とBakuの「nameフィールドが表示されること」の２ケースを書いています。
**「○○な場合、XXであること」**
テストケースって突き詰めるとこれですよね。まあ単純化すると。
ここの、**XXであること**をitブロックに書くイメージ。（今回は○○であることのコードは書いてません。次回登場予定）

###expect

>expectとは	
>
>主な意味予期する、(…を)(当然のこととして)期待する、待つ、(…が)(…に)来るものと予期する、(…の)期待を寄せ>る、つもりである、(…が)期待する、望む。要求する、思う

英語の意味通り、期待値を書くためのメソッドです。実際にXXであることを比較するために使います。
単純に、ここに記載した内容がOKだったらテストがパスし、NGだったらターミナルが真っ赤に染まります。

例えば、

```ruby:baku_spec.rb
describe Baku do
  baku = Baku.create(name:"Baku",sex:"Man")

  it "インスタンスが無事に生成されること"　do
    expect(baku).to be valid
  end
```
ここで、bakuモデルに以下のような　validationが存在した場合

```ruby:baku.rb
validates_presence_of :name,:sex,:tel
```
このままだとテストはパスしません。（create時にtelを渡していないので）

###マッチャ
```expect(XXXX).to be_valid```の```be_valid```はマッチャと呼ばれるものです。
これも名前の通り、マッチングするかどうかを決めるもので、他にも```eq```とか```be_false```とかがあります。（内容は見ての通り、イコールかfalseであるかという感じです）マッチャについては後の記事でまとめたいと思っている。自分のためにも。アチキ。

###おしまいに
いかがでしたか。このくらいの超シンプルな構造から徐々にコードを増やしていくと、あのよくわからない複雑怪奇なRSpecのコードになるのですが、基本の構造から一つずつ追加していくと、なんとなく読めるようになった私は、お腹が空いたので、次回に続きます。
AngularJSでHello World


- Angular 1.5.3で確認

# HTML
```html
<!DOCTYPE html>

<html ng-app="app">
<head>
	<meta charset="UTF-8">
	<title>hello world</title>
	<script src="./angular.min.js"></script>
	<script src="./controller.js"></script>
</head>
<body>
	<div ng-controller="HelloController">
		<input type="text" ng-model="greeting.text" value="{{greeting.text}}">
		<p>{{greeting.text}}</p>
	</div>
</body>
</html>
```
- ng-app でモジュール定義
- ng-controller でコントローラの適用範囲を定義
- ng-model フォームコントロールとモデルのバインディング
- {{}} でモデルの参照

# JavaScript
```javascript
// コントローラとして呼び出されるメソッドの定義
function HelloController($scope) {
	$scope.greeting = { text : "hello world" };
}
// 'app'モジュールにHelloControllerコントローラの登録
angular.module('app', [])
	.controller('HelloController', HelloController);
```

- コントローラで読みだされる Functionの定義
- angularmodule で 'app' にコントローラの登録
今さら聞けないCSSのあれこれ

##CSSとは
・CSS: HTML要素の見た目を決めるもの

```css:例(h2の色を青に変更する)
h2(セレクター) {
 color(プロパティ): blue(値);
}
```

##idとclassの使い分け
 - idはサイト内に1つ、classは複数
 - 基本はclassで装飾。idはJSが絡んでくるときに使う


##CSSの単位(よく使うのだけ抜粋)
**・px**: ピクセル、画素数(絶対的)
**・%**: 親要素に対する割合(相対的)
**・em、rem**: 基準となる文字に対する大きさ(相対的)

##CSSの色
**・カラーネーム**：red,green,yellowなど
**・RGB法(10進法)**: Red、Green、Blueのバランスで指定   Ex:color(255,0,0);
**・RGB法(16進法)**: 上記と同じ(0~9 + A~Fの16進法で指定)  Ex: #ff0000;
　　※１６進法の繰り返しは省略可　#FFFFFF = #FFF;

##margin、paddingの指定順(ショートハンド)

```css
margin: 10px, 20px, 30px, 40px;(上、右、下、左の時計回り)
margin: 10px, 20px, 30px;(上10px、左右20px、下30px)
margin: 10px, 20px(上下10px、左右20px)
margin: 10px(上下左右10px)
margin: 0(0の時は、pxを省略できる)
```





##CSSの優先度
 - セレクタが被った場合、後ろに書いてあるものが優先。
 - HTMLファイルのタグ内に書いたstyle属性が最優先
 - classとidに違う値を指定した場合、idが優先。
 - セレクターが多いほうが優先(.content h2{} > h2{})
    - ポイント加算式で優先度が決まり、idは100P、classは10P、タグは1P...etc
 - !important; を値の後ろに記述することで、優先度が一番高くなる

##ブラウザの差異を吸収するためのCSS

**・リセットCSS**: ブラウザによる差異を無くすために、ブラウザに予め指定されているスタイルを無くす為のCSS
[リセットCSSの例](http://cssreset.com/)

**・ノーマライズCSS**: ブラウザごとの差異を細かく調整して無くしつつ、基本的なスタイルは残す為のCSS

##メディアクエリとレスポンシブWebデザイン

**・メディアクエリ**: ブラウザの幅によって適応させるCSSを変える方法

```css:記述方法(例)
@media screen and (max-width: 768px){
  CSS_for_SP;
}
@media (max-width: 1600px){
  CSS_for_PC;
}
```

**・グリッドシステム**: bootstrapで採用されているシステム。画面を12分割し、規定された幅ごとにレイアウトを変更できる。

```html:記述方法(例)
<div class="col-xs-8">
 hogehoge
</div>
<div class="col-xs-4">
 piyopiyo
</div>
```

##プリプロセッサー
・**プリプロセッサー**とは... 進化系CSS(CSSを楽に書ける)

####何が出来るの？
  - 変数が使える
  - CSSが入れ子で記述できる

####どんなものがあるの？
  - less
  - sass
  - stylus
  - tass   など

####従来のCSSに変換するには？
#####ツールを使う
  - [Prepros](https://prepros.io/)
  - [Codekit](https://incident57.com/codekit/)

####コマンドを使う
  - [Sassの教科書](http://book.scss.jp/code/c2/04.html)

#####タスクランナーを使う(色んな作業を一度に行う)
  - [gulp](http://gulpjs.com/)

##CSS3に関して

###ブラウザ別CSS対応の違い
[ブラウザ別対応表](http://fmbip.com/litmus/)
**・Graceful degradation**: 全てのブラウザに同じに見えようとするではなく、対応していないブラウザに対しては必要最低限の表示が出来るよう整えていく考え方。

**・ベンダープリフィクス**: Webブラウザー開発者が、先行して実装しているCSS3の頭につけるもの(W3C勧告前で正式なプロパティではないので、マークで見分ける)

```
・Safari、Chrome: -webkit-
・FireFox: -moz-
・IE:　-ms-
・Opera: -o-
```

```css:ベンダープリフィクスの例
-webkit-border-radius: 8px;
```

###CSS3で出来るようになったこと(抜粋)
- 角丸(border-radius)
- グラデーション(linear-gradient)
- ドロップシャドウ(box-shadow)
- 半透明(opacity)
- アニメーション
トップに戻るボタン

##仕様
トップ戻るボタン。
ある程度スクロールするとボタンがfadeinする。（今回は500で設定）


```html:HTML
<div data-trigger-pagetop="pagetop" style="opacity: 0;">
   <img src="/img/diagram/btn.png" alt="トップに戻る">
</div>
```

```js:js
var pageTop = function(){
	var $trigger = $('[data-trigger-pagetop]');
	if(!$trigger.length) return; //triggerがない場合return
	$(window).on('scroll',function(){
		var now = $(window).scrollTop();
		if (now > 500){//500px以上スクロールするとボタンを表示
			$trigger.stop(true).animate({
				opacity: 1
			}, 100);//0.1秒かけてfadein
		} else {//そうでない時はボタンを非表示
			$trigger.stop(true).animate({
				opacity: 0
			}, 100);//0.1秒かけてfadeout
		}
	});
	$trigger.on('click',function(){
		$('html,body').animate( {scrollTop:0} , 'slow' );
	});
};
```
TinyTinyRSSの導入方法

# TinyTinyRSSって何なん？
TinyTinyRSSとはサーバインストール型のRSSリーダーです。Feedlyなどクラウドサービスと比較して更新間隔や過去記事の検索などサービスによっては設定できなかったり有料プランを契約しないと利用できない機能を好き勝手に利用できる点がメリットです。

# 導入手順
## Tiny Tiny RSSをダウンロードする

```
git clone https://tt-rss.org/git/tt-rss.git
```

```
mv tt-rss ${スクリプトを置きたいパス}
```


### ユーザーとDBの作成 (MySQL)
MySQL以外のDBを使用している場合は適宜置き換えてください。
DB_USER_NAME(ユーザー名)やDB_USER_PW(ユーザーのパスワード)、DB_NAME(データベース名)は適宜置き換えてください。

```mysql
CREATE USER 'DB_USER_NAME'@'localhost' IDENTIFIED BY 'DB_USER_PW';
```

DBを作成して権限を付与します。

```mysql
CREATE DATABASE DB_NAME CHARACTER SET utf8;
GRANT ALL ON DB_NAME.* TO 'DB_USER_NAME'@'localhost';
```

### 初期テーブルの作成
shemaディレクトリ内にDBの初期化SQLが入っているため事前に実行しておく必要があります。(初回スクリプト実行時に自動で作成してくれたら良いのに..
```
mysql DB_NAME -u DB_USER_NAME -p < schema/ttrss_schema_mysql.sql
```

## 設定ファイルの編集
config.php-distというファイルに設定ファイルのサンプルが書かれています。このファイルを移動して拡張子を.phpに変更します。修正しないまま直接設定を書き込んで公開すると動作しないだけで無く設定ファイルを外部からダウンロード可能になりDBのID/PWが漏洩する可能性があります。(漏洩の可能性は低いにしてもこのは実装ダメでしょ

```
mv config.php-dist config.php
```

TinyTinyRSSを動作させるための設定ファイルを編集します。FEED_CRYPT_KEYはソースを読んでいないので正確な情報は分かりませんが恐らくパスワードをハッシュ化させる際のソルトだと思います。

```php:config.php
define('DB_TYPE', "pgsql"); // or mysql
define('DB_HOST', "localhost");
define('DB_USER', "fox");
define('DB_NAME', "fox");
define('DB_PASS', "XXXXXX");
define('DB_PORT', ''); // usually 5432 for PostgreSQL, 3306 for MySQL

define('SELF_URL_PATH', 'http://example.org/tt-rss/');

define('FEED_CRYPT_KEY', '');
```



## パーミッションの変更
一応マニュアル通りにディレクトリのパーミッションを設定しておきます。 (配布時に設定しておけば良いのに...

```
chmod -R 766 cache/images
chmod -R 766 cache/upload
chmod -R 766 cache/export
chmod -R 766 cache/js
chmod -R 766 feed-icons
chmod -R 766 lock
```

あとはWebサーバの設定をすれば以下のようにブラウザからTinyTinyRSSの画面を見ることが出来るようになると思います。
![ttrss.png](https://qiita-image-store.s3.amazonaws.com/0/72252/258c2220-e889-628e-c61e-4055bd8d4111.png)

初期ID/PWはadmin/passwordに設定してあります。ログイン後にすぐ変更しましょう。PWを変更入力して画面遷移するとエラーメッセージが表示されましたが、PWは変更されていました。

# フィードの自動更新
以下のスクリプトを叩くとフィードが更新されます。

```
${TinyTinyRSSのパス}/update.php --feeds
```

ちなみに、以下のスクリプトを叩くと1分間隔でフィードを更新し続けます。

```
${TinyTinyRSSのパス}/update_daemon2.php
```

また、cronかsystemd/Timersでupdate.phpを叩くように設定しても自動で更新されます。実際のRSSフィードの更新取得はTinyTinyRSS内の設定(デフォルトだと30分間隔)で取得するため1分間隔でスクリプトを叩いてもフィード取得先サーバに負荷がかかることはありません。

以下はsystemd/Timersを利用して更新スクリプトを一分間隔で実行する設定にした際のユニットファイルです。

```:~/.config/systemd/user/ttrssUpdate-1min.timer
[Unit]
Description=Run TinyTinyRSS update script 1min


[Timer]
OnBootSec=1min
OnUnitActiveSec=55sec
AccuracySec=5sec
Unit=ttrssUpdate.service

[Install]
WantedBy=timers.target
```

```:~/.config/systemd/user/ttrssUpdate.service
[Unit]
Description=Run TinyTinyRSS update script

[Service]
Type=simple
ExecStart={TinyTinyRSS_PASS}/update.php --feeds

[Install]
WantedBy=default.target
```

```
systemctl --user enable ttrssUpdate-1min.timer
systemctl --user start ttrssUpdate-1min.timer
```

# フィードの自動更新
TinyTinyRSS自体はローリングリリース形式であるため、

```
git pull
```

でアップデート可能です。
DBの更新を伴うアップデートの場合はスクリプトのアップデート後、TinyTinyRSSの管理者アカウントでログインすると自動で更新されるそうです。

# 最後に
ざっくりと使ってみた感想ですがTinyTinyRSSの実装自体雑な部分もあるような気がするのでlet's encrypt+(Basic|Digest)認証を設定するなどして可能な限り外部からログインフォームを見えないように制限した方が良いと思います。(NginxはDigest認証を公式にサポートしていなくてつらい...
Android DataBindingで java.lang.RuntimeException: view tag isn't correct on view:null

# 経緯

既存アプリのメンテで，せっかくだからDataBindingを導入しようと思いまして， `build.gradle` に `dataBinding { enabled = true }` として，レイアウトを `<layout>` タグで囲ったのですが， `ExampleActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.example_activity);` の実行時に `Caused by: java.lang.RuntimeException: view tag isn't correct on view:null` を吐いて落ちてしまいました．

# 原因

`R.layout.example_activity` は一つじゃありませんでした．
`layout-land` にもあることに気づかず， `layout/example_activity.xml` のみ `<layout>` で囲む対応を行って， `layout-land/example_activity.xml` はデフォルトのままだったのが原因でした．

`layout-land/example_activity.xml` もDataBindingに対応させたところ，ちゃんと動きました．
Node cloneモジュールを使ってコンテンツをコピーするけど、特定のフィールドは値を引き継ぎたくない

#Node cloneモジュールを使ってコンテンツをコピーするけど、特定のフィールドは値を引き継ぎたくない

そんな時はこれ。

```php:PHP
/**
 * Implements hook_clone_node_alter
 */
function MYMODULE_clone_node_alter(&$node, $context) {
    if ($context['original_node']->type !=== 'article_information') {
      return;
    }
  
    if (isset($node->field_email)) {
      unset($node->field_email);
    }

    if (isset($node->field_locale)) {
      unset($node->field_locale);
    }
}
```

#備考
hook_clone_access_alter もあるので、アクセス制御が少し楽になるかもしれませんね。