OmniAICreator/Qiita-1.07M huggingface dataset:
PHPUnit_SkeletonGeneratorをインストールするときにハマった


##現象

```
$ pear install phpunit/PHPUnit_SkeletonGenerator

すると以下のエラーがでてハマった。
 
attempting to discover channel "phpunit"...
Attempting fallback to https instead of http on channel "phpunit"...
unknown channel "phpunit" in "phpunit/PHPUnit_SkeletonGenerator"
invalid package name/package file "phpunit/PHPUnit_SkeletonGenerator"
install failed
```

##解決策
チャネルが登録できていなかったらしい。

```
$ sudo pear channel-discover pear.phpunit.de
$ sudo pear install phpunit/PHPUnit_SkeletonGenerator
```

##参考
[Manual :: チャネルの使用法](http://pear.php.net/manual/ja/guide.users.commandline.channels.php)
Scala: 文字列の最初/最後から特定の文字を取り除く (PHPのltrim, rtrimのようなことをする)



# 文字列の最初から特定の文字列を取り除く

文字列 `///abc///` から頭のスラッシュを取り除いて `abc///` にする。複数の方法がある。


## dropWhileを使う

```scala
val string = "///abc///"
string.dropWhile(_ == '/')
```

## stripPrefixを使う

取り除く文字数が分かっている場合に使える

```scala
val string = "///abc///"
string.stripPrefix("/" * 3) 
```

## 正規表現を使う

```scala
val string = "///abc///"
string.replaceAll("^/*", "")
```

## org.apache.commons.lang3.StringUtils.stripStart を使う

```scala
import org.apache.commons.lang3.StringUtils

val string = "///abc///" 

StringUtils.stripStart(string, "/")
```

# 文字列の最後から特定の文字列を取り除く

文字列 `///abc///` からけつのスラッシュを取り除いて `///abc` にする。複数の方法がある。

## dropWhileを使う

```scala
val string = "///abc///"
string.reverse.dropWhile(_ == '/').reverse
```

## stripSuffixを使う

取り除く文字数が分かっている場合に使える

```scala
val string = "///abc///"
string.stripSuffix("/" * 3)
```

## 正規表現を使う

```scala
val string = "///abc///"
string.replaceAll("/*$", "")
```

## org.apache.commons.lang3.StringUtils.stripEnd を使う

```scala
import org.apache.commons.lang3.StringUtils

val string = "///abc///" 

StringUtils.stripEnd(string, "/")
```
windowsのコンソールからPopupでメッセージを出して、ビルド終了を気づきやすくしてみる

Windows7でdosやcygwinなどのコンソールで作業していて、数十分かかるようなビルドをかけて、その間に別の作業を。
ふと気がついたら10分前にビルド終わってた。。。
なんてのはよくあること。

そこで、

## windowsのポップアップを叩くようなコマンドがないか調べてみた。

あった。

[msg ユーザにメッセージを送信する](http://itpro.nikkeibp.co.jp/article/COLUMN/20060224/230564/)

![uploading msg_popup.png...]()


本来はサーバクライアント間でメッセージを送ったりするためのコマンドのよう。
XPまでは"net send"なるコマンドだったらしい。
そして昔は友達に送って遊べたらしき記事が出てきて、なにやら古きよき時代の懐かしい匂い。

### DOSプロンプト

```shell-session
> msg 1 "build finished!"
```

第一引数は、とりあえずセッションIDとして1でいけたが、失敗するときは
タスクマネージャを開いて、「ユーザー」タブに表示されるIDを確認すればよい。
それか、セッション名"Console"
または、ログインしているユーザ名でいけるはず。

### cygwin
cygwinは当然ながらwindowsの環境へパスが通ってないのだが、直接pathを指定したらいけた

```shell-session
$ /cygdrive/c/Windows/Sysnative/msg 1 "build finished!"
```

#### makeファイル

これをmakeファイルへ。
環境が限定されるので主にローカルで変更して使うことにはなるが、

```mf
popup:
    /cygdrive/c/Windows/Sysnative/msg 1 "build finished!"
```

ビルドのタスクの最後などに追加してあげればOK。
[備忘録]symfony2の認証処理でユーザープロバイダを、serviceで定義したクラスを使う


```services.yml
parameters:
     yakitori.user_service.class: Yakitori\Bundle\Service\GkgkUserService

services:
    yakitori.user_service:
         class:     %yakitori.user_service.class%
         arguments: ['@service_container']

```

上記のように定義されてるなら、こう書く。


```security.yml
security:
    providers:
        yakitori_users:
            # サービスを指定
            id: yakitori.user_service

```
[備忘録]symfony2の認証処理で標準と違うユーザー名パスワードのタグ名を使用した時の設定



```
<div ng-controller="LoginController as Login">
<form action="/login" id="loginForm" name="loginForm" method="post" novalidate>

  <input type="text" id="loginId" name="form[loginId]" placeholder="Login ID"
    required="true" ng-model="Login.loginId" value="" autofocus/>

  <input type="password" id="loginPwd" name="form[loginPwd]"
    placeholder="password" required="true" ng-model="Login.loginPwd" value=""/>

  <button type="button"ng-click="Login.doLogin()">Sign in</button>

</form>
</div>
```

の場合、こう書く。

```secrity.yml
        secured_area:
            form_login:
                # ログイン画面URL
                login_path: /login
                # ログイン実行URL
                check_path: /login_check
                # ユーザ名とパスワードのタグ名
                username_parameter:             form[loginId]
                password_parameter:             form[loginPwd]

```
Python: zipfile を使って、標準入力からunzipする



標準入力があればそちらから、なかったら argv[1]をunzipする。

--dst でunzip先を指定。デフォルト ./_unzipディレクトリ。
--setupを付けると、$VIRTUAL_ENV/bin/uz.py にいれてくれるのでパスが通るようになりますが、setup()がよくわからないので適当:

```py
    from zipfile import ZipFile
    import os
    import sys
    from StringIO import StringIO
    
    
    def unzip(src,outdir='.'):
        _unzip = lambda z,out : map(lambda n:  z.extract(n, out),
                                    z.namelist())
    
        if not os.path.exists(outdir):
            os.makedirs(outdir)
        
        if not sys.stdin.isatty() :
            _unzip(ZipFile(StringIO(sys.stdin.read())), outdir)
        
        elif src:
            with open(src) as stream:
                _unzip(ZipFile(stream), outdir)
        
    
    def main():
        from argparse import ArgumentParser
        parser = ArgumentParser(description='Unzip stdin or specifile file.')
        parser.add_argument('zipfile', metavar='ZIPFILE', type=str, nargs='?',
                       help='File to be unziped.')
    
        parser.add_argument('--dst', dest='destination',
                            default='_unzip', required=False, )
    
        parser.add_argument('--setup', dest='setup', action='store_true',
                            required=False, )
    
    
        args = parser.parse_args()
    
        if args.setup:
            sys.argv = [__file__,'install']
            setup_me() 
        else:
            unzip(args.zipfile, args.destination)
    
    def setup_me():
        from setuptools import setup
    
        setup(
            name = 'uz.py',
            version = "1",
            license = 'Simplfied BSD License',
            author = 'Hideki Nara of LaFoaglia,Inc.',
            author_email = 'gmail [at] hdknr.com',
            maintainer = 'LaFoglia,Inc.',
            maintainer_email = 'gmail [at] hdknr.com',
            description = "uz : Unzip",
            long_description = "unzip script",
            platforms=['any'],
            classifiers = [
                'Development Status :: 4 - Beta',
                'Environment :: Library',
                'Intended Audience :: Developers',
                'License :: OSI Approved :: Simplifed BSD License',
                'Natural Language :: English',
                'Operating System :: OS Independent',
                'Programming Language :: Python',
            ],
            scripts= [os.path.abspath(__file__)]
        )
    
    if __name__ == '__main__':
        main()
```
Missing proxy for identifier IBFilesOwnerエラーで落ちる原因と対処法

# 現象

* UITableViewCell に、 reloadRowsAtIndexPaths:withRowAnimation: でテーブルセルのリロードをかけるとアプリが落ちる。
* アニメーションを UITableViewRowAnimationNone にしてもダメ。

# エラーメッセージ

```cobol
 Missing proxy for identifier IBFilesOwner
```

# 原因

* 画面の更新系の処理をBackgroundで実行しようとしていたことが原因。
* 自分は、通信しその結果をテーブルへ反映させるという処理を、すべてBackgroundスレッドで実行するコードを書いていたのが原因でした。

# 解法法
* メインスレッドで実行する

# サンプルコード
```objc
    dispatch_async(dispatch_get_main_queue(), ^{
            [self reloadRowsAtIndexPaths:@[indexPath]
                        withRowAnimation:UITableViewRowAnimationFade];
    }
```

これでエラーは解消する。

ただ、実際にはreloadRowsAtIndexPaths:だけでなくメソッド全体をメインスレッドで呼び出すように変更しました。
「データの取得等をしているクラス」と「テーブルクラス」が別クラスなので、前者は極力バックグラウンドで実行、後者はメインスレッドで実行される前提でコーディング。
前者から後者へのメソッド呼び出し時にメインスレッドへ戻す、という整理です。

# メモ

* NotificationCenter経由で通知しても、通知元がバックグラウンドスレッドだったら通知を受け取る側もバックグラウンドで動くんですね。知りませんでした。
* もっといい方法や気になる点があれば、気軽にコメントください。

# 参考リンク
objective c - Missing proxy for identifier IBFilesOwner - Stack Overflow
http://stackoverflow.com/questions/10937103/missing-proxy-for-identifier-ibfilesowner
SHIFT_ruby_on_rails

最近Ruby on Rails始めました。

ビューになんで変数渡ってこないのー！ってなって
よく見たら@hogeが$hogeと書いていて小一時間ハマったりしています。

## はじめるにあたって読んだ本
- たのしいRuby
http://www.amazon.co.jp/%E3%81%9F%E3%81%AE%E3%81%97%E3%81%84Ruby-%E7%AC%AC4%E7%89%88-%E9%AB%98%E6%A9%8B-%E5%BE%81%E7%BE%A9/dp/4797372273

Rubyたのしい！

## はじめるにあたって読んだサイト
- ドットインストール　Ruby on Rails 4入門
http://dotinstall.com/lessons/basic_rails_v2
- Railsドキュメント　http://railsdoc.com/

Railsべんり！

## 開発環境づくり
Mac！

rbenvでRubyをインストール

```sh
brew install rbenv ruby-build

echo 'if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi' >> ~/.bash_profile
exec $SHELL -l

rbenv install -v 2.1.1
rbenv global 2.1.1
rbenv rehash
```

railsをインストール

```sh
gem install rails --pre
rbenv rehash
```

MySQLをインストール

```sh
brew install mysql
mysql_install_db --verbose --user=`whoami` --basedir="$(brew --prefix mysql)" --datadir=/usr/local/var/mysql --tmpdir=/tmp
mysql.server start

/usr/local/opt/mysql/bin/mysqladmin -u root password 'root'
/usr/local/opt/mysql/bin/mysql_secure_installation
```


## コーディング環境メモ
gfでrailsとかカーソル配下のクラスとか、文脈が書いてあるソースに飛べて便利。
gfしよう、gf。


```
gem install gem-ctags gem-browse
```

```.vimrc
" ruby {{{
NeoBundle 'vim-ruby/vim-ruby'
NeoBundle 'tpope/vim-rails'
NeoBundle 'tpope/vim-bundler'
NeoBundle 'tpope/vim-rake'
" }}}
```


Rails覚えながら、スニペットを書き溜めようと思ってはじめました。
技を増やすぞ！
https://github.com/violetyk/neosnippet-rails


## これから読みたいサイト
- BetterSpecs http://betterspecs.org/jp/
- Ruby on Rails Tutorial http://railstutorial.jp/

長いけど、読もう！
angularjsでフォーム部品名がjavascriptの変数名にならない時の指定方法


タグのnameにカッコとか入ってると、変数名に直接出来ない。

```
<div ng-controller="LoginController as Login">
<form action="/login" id="loginForm" name="loginForm" method="post" novalidate>

  <input type="text" id="loginId" name="form[loginId]" placeholder="Login ID"
    required="true" ng-model="Login.loginId" value="" autofocus/>

  <input type="password" id="loginPwd" name="form[loginPwd]"
    placeholder="password" required="true" ng-model="Login.loginPwd" value=""/>

  <button type="button"ng-click="Login.doLogin()">Sign in</button>

</form>
</div>
```

上記の場合、こんな風にはかけないので、

```
$scope.loginForm.form[loginId].$valid
```

こう書く。

```
$scope.loginForm['form[loginId]'].$valid
```
SinatraでCompassを使う

## 公式になかったのでメモ

```ruby:app.rb
require 'sinatra'
require 'compass'

class App < Sinatra::Base
	register Sinatra::Reloader

	# Compassの設定
	configure do
    	Compass.configuration do |config|
      		config.project_path = File.dirname(__FILE__)
      		config.sass_dir = 'views'
    	end
    	set :sass, Compass.sass_engine_options
    	set :scss, Compass.sass_engine_options
    end
	# sass
	get '/style' do
      		scss:style
    end
end
```

```scss:views/style.scss
@import "compass";
```

```Gemfile:Gemfile
source "https://rubygems.org"

gem "sinatra",require:"sinatra/base"
gem "sinatra-contrib",require:"sinatra/contrib/all"

gem "sass"
gem "compass"



```

```config.ru
require 'bundler'
Bundler.require

require './app'

run App
```

$ bundle exec rackup config.ru で起動
Selenium2: 現在のURLを取得する


```scala
val driver = new WebDriver()
val url = driver.getCurrentUrl
```

ローカルスコープでは関数を定義しておくと便利。
JavaBean風のget***というメソッド名が隠れるので見た目キレイ。

```scala
{
	def currentURL = driver.getCurrentUrl

	if (currentURL) {
		// ...
	}
}
```
Rails3でのバッチ実行

自分用メモ

lib/tasksに適当な処理用クラスを作成

```rb:test.rb
class Tasks::Test
  def self.batch
    # ここに処理を記述
  end 
end
```

実行は

```
rails runner Tasks::Test.batch
```

Task::はおきまりのおまじない、クラス名.呼び出したいメソッドで実行したい物を指定する。
[Obsoleted] BuildHiveでビルドしているリポジトリにPull Requestがあった時

## 20151123 追記：BuildHiveについて

BuildHiveを紹介させていただいたこちらの記事ですが、2012年から利用させていただいていたサービスは、2015年11月にクロージングとなった模様です。

- Ref. [BuildHive](https://www.cloudbees.com/blog/buildhive) on 20151109 @ CloudBees Blog

フリーのCI環境のホスティングサービスとして、拙いコードながらもいろいろと勉強させていただくことができ、個人的には本当に感謝しきれません！
いずれにしても、この記事は古くなってしまいましたが、記録として残させていただきたいと思います。

以下から、元記事となります。

---------------------

GitHubに載せているささやかなコードを、BuildHiveを使ってビルド（テスト）してみるようになって、1ヶ月くらい経ちました。

本来、コミットが無い限りは、自動でビルドは行われません。（手動実行は可能です）

### 執事からの、身に覚えの無い通知。

そんな、ある日のこと。
GitHubからのPull Requestの通知を受け取ったのですが、その後すぐに、差出人　"BuildHive" で同じリポジトリに対する通知が来ていました。

![mail.png](https://qiita-image-store.s3.amazonaws.com/0/27976/b34f4bdd-2c80-72ac-3707-5b45eb6125e5.png "mail.png")

『何ですか？』と思って中を覗くと、このようなメッセージが…。

```
Akiko Takano » redmine_banner #15 SUCCESS
This pull request looks good
(what's this?)

# 『意訳：ビルドしてみたけど、このプルリクエストは良さげだよ。』
```
### プルリクエストがビルドされてた！
メールにはリンクが貼ってあったので、クリックすると、BuildHiveのプロジェクトに飛びました。

![build-info.png](https://qiita-image-store.s3.amazonaws.com/0/27976/df0042cd-c8de-cad8-e54a-0e4d7fb7f732.png "build-info.png")

ビルドの説明も、勝手に付加されるようです。
履歴一覧を見ると、通常のビルドにはコメント無しですが、プルリクエストの処理をした#15には、コメントが付いています。

![build-log.png](https://qiita-image-store.s3.amazonaws.com/0/27976/71ee7938-4cc6-ea6a-a13b-c12b1fd65339.png "build-log.png")

### GitHub側にもコメントが！

さて、GitHubのPull Requstの画面を見ると…。

なんと、GitHub側にも『ビルドしてみたけど、このプルリクエストは良さげだよ。』という **buidhive** （執事さん）からのコメントが付いていました…。

リクエストを出して下さった方、ビックリしてたらごめんなさい。

![pull-request.png](https://qiita-image-store.s3.amazonaws.com/0/27976/42aa6782-fb87-14c0-4b92-3a7585b803d7.png "pull-request.png")

### プルリクエストのテストについて

今までは、ささやかな経験ではありますが、プルリクエストがあったら、一応ローカルの環境に取り込んでテストをし、devブランチにマージして、devブランチでのテスト（外部のCIサーバで綺麗な環境でテスト）をして、問題なければmasterにマージ、ということをしていました。

ですが、執事さんが勝手にやってくれるというのは、大変有り難い！

実際は、プルリクエストはtarnslation（翻訳）ファイルに対する変更で、モノの動作にはあまり影響はしません。

なので、『translationファイルのリクエストまでビルドを試さなくとも…』と思われるかもしれませんが、このtranslationファイルの文字コードがおかしかったりすると、アプリケーションがInternal Server Errorを起こすこともあります。
（実際そういうことが、自分にもありました）

慎重なアプリケーションであれば、translationファイルに変更があった場合も、言語を切り替えての動作テストをするのが真っ当なんでしょうね。

そして、こんなふうに執事が気を利かせてくれるんであれば、言語切替のテストもやり方を調べて組み込んでみてもいいな、なんて思いました。

＃ただし、わたしの場合はテストのためにいろいろいじっているので、マージしてくれたソースをちゃんと使ってビルドしないと意味がないので、ビルドスクリプトの修正が必要なことが分かりました…。

### なんかすごい執事力！

この機能については、[BuildHive](http://wiki.cloudbees.com/bin/view/DEV/BuildHive)のページにも載っていました。

```
* Building Pull Requests
When you set up your repository for a CI build on BuildHive, pull requests submitted to your repository will be automatically built, and its result will be posted as a comment to the pull request.

#意訳：『BuildHiveでビルドする場合、プルリクエストがあったら自動で取り込んでビルドします。で、結果をコメントとしてプルリクエスト側に通知しますよ』
```

うーん、なんかすごい執事力。
drone.ioも良いかな、と思ったんですが、執事さんはやっぱり面白いですね。

もっといろんなものを作って試せるようになりたいです。
RubyMineの個人的に使えるショートカット集


折角高い金出して買ったので、有効活用しないとね。ということで個人的に便利だと思っているショートカットをまとめてみました。

# 1.view, controller, helper, test間を相互移動する
### command+control+up

地味にスコープ見てくれてるので、Controllerのアクション内で実行すると、そのアクションに対応するviewへのリンクが、class全体のスコープの場合は、コントローラーに紐づくすべてのviewへのリンクがポップアップで現れます。

# 2.ファイル検索

### command+shift+o

user_controller.rbというファイルがある場合、'userco'とかやると候補に上がります。アンダーバーは打たなくて大丈夫。

### command+up

command+1でプロジェクトの階層構造を表示して開発してて、よくマウスを操作してディレクトリたどったりするんですが、command+upでナビゲーションバーを出してたどる方が早いことに気づきました。

ナビゲーションバーが出ている状態で、文字列を入れると、その階層における絞込ができる！便利！

# 3.最近編集したファイル一覧

### command+shift+e

ファイルの行ったり来たりが多い場合はこちらで十分かもしれません。

# Rails Console

ショートカットとはちょっと違うのですが、Tools→Run Rails Consoleでreplなターミナルが立ち上がります。ここではプロジェクトで作っているClassとかが使えるので、ちょっとした確認はここでできるので便利です。
forever運用環境で手動gc

node.jsを使っていると、メモリ使用量がすんごい増えていくことがあります。

使用量は

    process.memoryUsage()

とかで見ることが出来ます。
こんなときは手動でガーベージコレクションを行うようにします。

    if(global.gc) {
     global.gc();
    }

を適当な場所に入れます。

手動gcを行うときは、nodeを起動するときに、オプションを付けないと行けません。

    node --expose_gc app.js


そしてforeverを使っているときは、以下のようにします。

    forever restart -c 'node --expose_gc' app.js


これでforeverで実行しているときでも手動gcが動きます。
Androidでsocket.ioを使う


Androidでsocket.ioを利用しましたのでメモ
クライアントライブラリとして https://github.com/Gottox/socket.io-java-client を利用しました。

簡単にまとめると２つ問題が発生して。

    socketIO = new SocketIO();
    socketIO.connect("http://10.0.2.2:3000", socketIOCallback);

普通にhttpでローカルと接続しようとすると。Null Pointer Exceptionがでました。

    SocketIO.setDefaultSSLSocketFactory(SSLContext.getDefault());

を追加したら、なおりました。

次にSSLで接続しようとすると、何のエラーも無くつながりませんでした。onConnectが呼ばれない状態です。

    socketIO = new SocketIO();
    socketIO.connect("https://mlkcca.com", socketIOCallback);

https://github.com/Gottox/socket.io-java-client/issues/60
に解決方法がありました。ライブラリのソースコード WebsocketTransport.javaを修正してビルドし直せばいいようです。
Raspberry PI(Raspbian)でbluezインストール、SensorTagに接続してみる

raspberry piからSensorTagへ接続、データの取得を試してみた。

OSはraspbian
bluetoothのドングルはplanexのBT-Micro4
※ネットで調べるとラズパイで割と使ってる人が多く実績がありそうだったのでこれを購入。
SensorTagはもちろんTIのもの。

## raspbianにbluezをインストール

```console:
# apt-get install libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline6-dev
# wget http://www.kernel.org/pub/linux/bluetooth/bluez-5.15.tar.xz
# tar xvJf bluez-5.15.tar.xz
# cd bluez-5.15
# ./configure --disable-systemd --enable-library
# make
```

ここまでやって調べていたところ、
http://ohwhsmm7.blog28.fc2.com/blog-entry-390.html
のように
割とapt-get install bluetooth bluezutilとかやってるのがみつかったのでここでやめた。
※が、後からわかったのはbluetoothキーボードなどのLEでないデバイスとの接続には問題ないようだが、
今回はソースからビルドしたほうがよさげ。

## SensorTagへの接続

ここ
http://joost.damad.be/2013/08/experiments-with-bluetooth-low-energy.html
を参考にしたが、connectのところで何故かtimeout.

下記を参考にしたところ、
http://www.zephyr-labs.com/?p=87
`hcitool lecc`が足りなかったらしい。

まず
`# lsusb`
でbluetoothデバイス確認。

SensorTagの横のスイッチを押してアドバタイズ状態にし、
`# hcitool lescan`
これでmacアドレスを確認。※ctrl-cで止める。
さらに

```console:
# hcitool lecc XX:XX:XX:XX:XX:XX
# gatttool -b XX:XX:XX:XX:XX:XX -I
[   ][XX:XX:XX:XX:XX:XX][LE]> connect
Attempting to connect to XX:XX:XX:XX:XX:XX
Connection successful
[CON][XX:XX:XX:XX:XX:XX][LE]> 
[CON][XX:XX:XX:XX:XX:XX][LE]> char-read-hnd 0×25
[CON][XX:XX:XX:XX:XX:XX][LE]> 
Characteristic value/descriptor: 00 00 00 00
```

ここまではよかったが

```console:
[CON][XX:XX:XX:XX:XX:XX][LE]> char-write-cmd 0×29 01
A valid handle is required
```

となってうまくいかない。

http://mike.saunby.net/2013/04/raspberry-pi-and-ti-cc2541-sensortag.html
によると、
`IF you get 'A valid handle is required' when you try to enable the sensor, you need to update your gatttool by building bluez from scratch. `

やはり、当初のソースコードからビルドしたほうがよかったのかも。

というわけで当初ビルドしたソースツリーを探すとattribディレクトリの中にgatttoolがあった。
このバイナリを使って上記をもう一度試したところ、無事データが返ってきた。

遅くなったので今回はここまで。
次回は何らかプログラム(cかjava,python？）を作成してデータ取得できるようにする予定。


### 参考
* https://www.eyemovic.com/blog_it/4269.php
* http://www.zephyr-labs.com/?p=87
* http://joost.damad.be/2013/08/experiments-with-bluetooth-low-energy.html
* http://processors.wiki.ti.com/index.php/SensorTag_User_Guide
SublimeText2の設定データを複数のWindowsPCで共有するためにしたこと

この記事を書いた動機としては、Google検索を試みてもMacの情報があまりにも多く、なかなかWindowsで設定しているサイトにありつけなかったから。（サーチが足りない）

今回は、普段使用しているデスクトップPCのSublime Text 2の設定データを、持ち歩き可能なノートパソコンでも利用したかったので、設定データを共有するためにDropboxで同期することにしました。

##まずはデスクトップPC側で行う
###Dropbox内に[app]フォルダを作った
※フォルダ名を[]でくくっていますのでご覧になられている方はご自身の環境に合わせてください。

その[app]フォルダ内にその中に[Sublime Text 2]ってフォルダを作成した。[app]/[Sublime Text 2]というふうに。

###Sublime Text 2の設定データが入るフォルダにアクセス
```
C:¥Users¥[User名]¥AppData\Roaming¥Sublime Text 2¥Installed Packages
C:¥Users¥[User名]¥AppData\Roaming¥Sublime Text 2¥Packages
C:¥Users¥[User名]¥AppData\Roaming¥Sublime Text 2¥Pristine Packages
```
上に記載した３つのフォルダを、作ったフォルダ[Dropbox\app\Sublime Text 2]に入れた。

以上のフォルダを入れたら、3つのフォルダを消去した（一応バックアップ）
```
Sublime Text 2¥Installed Packages
Sublime Text 2¥Packages
Sublime Text 2¥Pristine Packages
```

###管理者権限でコマンドプロンプトを開き、mklinkコマンドを打つ
▼ カレントディレクトリ
```
C:¥Users¥[User名]¥AppData\Roaming¥Sublime Text 2
```

▼ このディレクトリでmklinkコマンドを打つ
```
mklink /D "C:\Users\[User名]\AppData\Roaming\Sublime Text 2\Installed Packages" "C:\Users\[User名]\Dropbox\app\sublime text 2\Installed Packages"
mklink /D "C:\Users\[User名]\AppData\Roaming\Sublime Text 2\Packages" "C:\Users\[User名]\Dropbox\app\sublime text 2\Packages"
mklink /D "C:\Users\[User名]\AppData\Roaming\Sublime Text 2\Pristine Packages" "C:\Users\[User名]\Dropbox\app\sublime text 2\Pristine Packages"
```

▼ コマンドを打ち込むとこのような感じになります
※自分のUser名のところをモザイク処理しています

![sublime-3.png](https://qiita-image-store.s3.amazonaws.com/0/11432/ffb2d3f2-b383-5423-5293-812bfdfb2f81.png)

▼ その後消去したフォルダの中身を確認するとこのような感じに。
![sublime-4.png](https://qiita-image-store.s3.amazonaws.com/0/11432/023250f8-ad09-e832-6518-72d7b3fdb266.png)

##次は同じことをノートパソコン側で行う
先ほどと同じように設定データのフォルダを消去。

▼管理者権限でコマンドプロンプトを開いてmklinkコマンドうつ．
![sublime-8.png](https://qiita-image-store.s3.amazonaws.com/0/11432/283aa3d3-b806-565b-2d23-9abd11f082ef.png)

これでOK

##無事に同じ設定データで使うことができた
▼ デスクトップPCでの表示
![sublime-5.png](https://qiita-image-store.s3.amazonaws.com/0/11432/c92f549f-b4d5-80d6-46e9-5ab981acf1da.png)

▼ ノートパソコンでの表示
![sublime-10.png](https://qiita-image-store.s3.amazonaws.com/0/11432/12992d53-19ba-c4c0-8fd1-1c23bb56ac87.png)

ここでは見た目だけですが、デスクトップPC側で使用している環境とノートパソコン側で使用する環境が同じになりました。

これで片方の環境でプラグインを導入して使い始めても、同じ設定データを参照するので、もう片方のPCでも同じプラグインが使える状態になります。

以上です。
angularでmessagepack

messagepackのライブラリは https://github.com/uupaa/msgpack.js を使用。

```js:ngMsgpack.js
angular.module('ngMsgpack', []).config(function($provide, $httpProvider) {
  
  // リクエストするときに余計なことをさせないようにする&オブジェクトはmessagepack形式に変換
  $httpProvider.transformRequest = [function(data) {
    switch (Object.prototype.toString(data)) {
      case '[object Uint8Array]':
      case '[object Int8Array]':
      case '[object Uint16Array]':
      case '[object Int16Array]':
      case '[object Uint32Array]':
      case '[object Int32Array]':
      case '[object Float32Array]':
      case '[object Float64Array]':
      case '[object CanvasPixelArray]':
      case '[object Uint8ClampedArray]':
      case '[object File]':
      case '[object Blob]':
        return data;
    }
    if (data !== null && typeof data === 'object') {
      return msgpack.pack(data);
    } else {
      return data;
    }
  }];

  // $httpBackendをラップ
  $provide.decorator('$httpBackend', function($delegate) {
    return function $httpBackend(method, url, post, callback, headers, timeout, withCredentials, responseType) {
      var xhr = new XMLHttpRequest;
      xhr.open(method, url);
      xhr.responseType = 'arraybuffer';
      angular.forEach(headers, function(v, k) {
        if (angular.isDefined(v)) {
          xhr.setRequestHeader(k, v);
        }
      });
      xhr.onloadend = function() {
        var responseHeaders = xhr.getAllResponseHeaders();

        if (xhr.status === 200) {
          callback(xhr.status, msgpack.unpack(new Uint8Array(xhr.response)), responseHeaders);
        } else {
          callback(xhr.status, null, responseHeaders);
        }
      };
      xhr.send(post || null);
    }
  });

});
```

つかうときはいつも通りこんなかんじで。

```js:app.js
angular.module('foo', ['ngMsgpack']).controller(function($scope, $http) {
  $http({
    method: 'POST',
    url: '/foo',
    data: {
      a: 1,
      b: 'bar'
    }
  }).success(...);
});
```
プロジェクトディレクトリ以外でartisanコマンドを使う

すごい単純だけどどうするんだろーとちょっと悩んだのでメモ

```
cd Laravelプロジェクトのパス && php artisan --version
```

結果Laravelとかphpとかなんも関係なくLinuxコマンドの問題だった。

割と悩む･･･よね？
ttygifでターミナルを録画してgifにする

## デモ

![gitgif_demo.gif](https://qiita-image-store.s3.amazonaws.com/0/38647/86b91c27-f894-c969-89b0-5846408ad1db.gif)

早すぎます。こんなタイピング早くないです。
後でこの調整方法も載せます。

## ttyrecのインストール

* Mac

```bash
$ brew install ttyrec
```

* Debian,Ubuntu

```bash
$ sudo aptitude install ttyrec
```

## ttygifのビルド

* Debian/Ubuntu

```bash
$ sudo aptitude install imagemagick ttyrec gcc
$ git clone https://github.com/icholy/ttygif.git
$ cd ttygif
$ make
```

* Mac

```bash
$ brew install imagemagick
$ git clone https://github.com/icholy/ttygif.git
$ cd ttygif
$ make
```

## 使ってみる

1. `ttyrec`による録画

2. `ttygif`による画像化

3. `concat`によるgif化

の３段構成

録画前にttygifディレクトリ内にcdしといてください。

```bash
$ ttyrec rec_name
```

rec_nameを省略した場合ttyrecordでファイルが作成されます。
この後、録画したい部分の動作をやります。
`Ctrl-D`押下か`exit`入力まで撮り続けます。

```bash
$ ./ttygif rec_name
```

ttyrecにより作成されたファイルからコマ送り画像を作成します。
0001_0538のようなファイルがたくさんできますが順番_遅延時間(ミリ秒)になっています。
打ち間違えたり、考えていて手が止まっていたりした部分の要らないファイルを消したり、遅延時間の部分を調整してgifの再生速度を制御できます。
遅延時間は通常の入力(アルファベット１文字あたり)を50-150msとか、ちょっと止まっておきたい時は1000msを設定しておけばいいかと思います。
Macで最後に`-f`オプションを付けるとターミナルの外観(ウィンドウ枠)が表示されます。まぁ要らないです。

最後にコマ送り画像をgifに変換します。

* Debian,Ubuntu

```bash
$ ./concat.sh output.gif 
```

* Mac

```bash
$ ./concat_osx.sh output.gif
```

outputの部分にファイル名を指定して終了です。
最初に紹介したデモのようなgif画像が出来上がります。

## 参考

* [ttygif](https://github.com/icholy/ttygif) - 本家です。

## 追記
LinuxやMacOSなら[asciinema](https://asciinema.org/)というのもあって、こっちはgifにしたり細かい調整はできませんが、より手軽にターミナルを動画として提供できます
node.jsを試した(EコマースAPI)②

 [前回](http://qiita.com/shogirin/items/c68b88e0c93fe65a4f48 "前回")に加えSignature発行が必要な [セブンアフィリエイトAPI](https://www.7netshopping.jp/affiliate/regist/goApi.do "セブンアフィリエイトAPI")の通信モジュールについて書きたいと思います。

```js:common.js

var http        = require('http')
,querystring  = require('querystring')
,xml2js = require('xml2js')
,crypto = require('crypto');

function common(path)
{
  this.host = 'api.7netshopping.jp';
  this.path = path;
  this.secret_key = '発行した鍵';

  // Default Options
  this.options = function(){
    return {ApiUserId: '登録ユーザーID'
    ,Timestamp: null
    ,Version:'2010-08-01'
    ,ResponseFormat: 'JSON'};
  };

  Date.prototype.toUTCString = function(){
      return [
          this.getUTCFullYear(),
          this.getUTCMonth() + 1,
          this.getUTCDate()
          ].join( '-' ) + 'T'
          + [
             this.getUTCHours(),
             this.getUTCMinutes(),
             this.getUTCSeconds()
          ].join( ':' ) + 'Z'
  }
}

common.prototype = {

  generateURL: function (addOptions) {
    var options = this.options();
    for(var key in addOptions){
      options[key] = addOptions[key];
    }
    options['Timestamp'] = new Date().toUTCString();
    options['Signature'] = createSignature('http://' +this.host + this.path, options, this.secret_key);
    var url = 'http://' +this.host + this.path + '?' +
          require('querystring').stringify(options);
    console.log(url);
    return url;
  },

  get: function (options, callback) {
        var req = http.get(this.generateURL(options), function(res){
            res.setEncoding('utf8');
            var data = '';
            res.on('data', function(str) {data += str;});
            res.on('end',function(){
                callback(JSON.parse(data));
            });
        });
   },
};

var createSignature = function(url, request, secret_key){
    var str = "GET|" + url;
    keys = Object.keys(request);
    keys.sort();
    for ( var i = 0; i < keys.length; i++) {
         str += "|"  + keys[i] + "=" + request[keys[i]];
    }
    str = encodeURIComponent(str);

    return crypto.createHmac('sha256', secret_key).update(str).digest('base64');
}

module.exports = common;

```

amazonのapiと認証方式とだいぶ似てるので、コピペ可能かと。
（自作せずとも、node-apacというモジュールでamazonAPIが使えます。）
UTC形式のタイムスタンプが必要なので、強引にDateクラスのtoUTCStringをねじ込んでます。
肝心の Signatureの発行ですが、node-cryptoを利用すれば簡単です。

後は、これに各api用のクラスを作成しましょう。

```js:SearchProduct.js

var common = require('./common.js');

function api () {
    //このパス部分を各apiにて書き換える
    common.apply(this, ['/ws/affiliate/rest/SearchProduct']);
}
api.prototype = Object.create(common.prototype);
api.prototype.constructor = api;

api.prototype.execute = function(obj, callback){
  this.get(obj, callback);
}

```

後は、これに検索条件であるリクエストを渡して実行

```js:使い方
module.exports = api;
var api = require('./SearchProduct.js');
//　カテゴリ「rock」で検索
new api().execute({CategoryCode: 'rock'},function(res){console.log(res.SearchProductResponse.Products.Product);});

```

後で、API絡みのモジュールはgithubでも登録しておこう。
.so ファイルの中を覗く方法

[Android NDK](https://developer.android.com/tools/sdk/ndk/index.html)を使うと、ビルド時に共有ライブラリ(.so)ファイルにお世話になることがある。

そこで、.soファイルが正しく作られているのか、Mac環境で確認したい。

nmとかstringsとかobjdumpを使う方法があるが、詳しくは参考サイト参照。(objdumpを使うと、調べたかった.soファイルが壊れていたのか、"曖昧なファイルです"と怒られてしまった。)

今回はgreadelfコマンドを使う。

1. インストール

    ```bash
    brew install binutils
    ```
  - binutilsにobjdumpやreadelfが入っている
    - gobjdump, greadelfといように、先頭にgがついたコマンド群になっている模様

2. 実行例

    ```bash
    $ greadelf -l sample.so
    ```

  - プログラムヘッダ等などかなり色々な情報が見れる。詳しくはmanページ参照。
    - http://www.unix.com/man-page/OpenSolaris/1/greadelf/



## 参考サイト
http://d.hatena.ne.jp/aki-yam/20091122/1258905636
http://d.hatena.ne.jp/amachang/20080401/1207027290
ストリームを行ごとに処理~readline編~

# ストリームを行ごとに処理~Readline編~

## はじめに

本投稿は、自分がログファイルなどのでかい容量のファイルにおいて、一定行ごとに処理を上手く実装できないかいろいろな方法を模索している最中のメモ帳みたいなものです。
グダグダですが参考になれば幸いです。
一応Readline、Stream2のReadable・Transformについて調査する予定です。

## readlineについて

ストリームを行ごとに読み込むことができるモジュール
主な使用用途としてターミナルからの入力を想定していそうです。
詳細は下記マニュアル参照
http://nodejs.org/api/readline.html

## 1行ごとに処理

基本的な例として、ストリームを1行ごとに読み込み、読み込んだ行ごとに処理をしていく例を作ってみました。

### 例1:行を逆順にして出力
```js:main.js
var fs = require('fs');
var rs = fs.createReadStream('./hoge.txt');
var readline = require('readline');

var rl = readline.createInterface(rs, {});

rl.on('line', function(line) {
  // 受け取ったlineを逆順にして出力
  console.log(line.split('').revers().join(''));
});
```
```text:hoge.txt
abcde
fghij
klmno
pqrst
uvwxy
z
```

###実行結果
```
edcba
jihgf
tsrqp
yxwvu
z
```
###説明

5行目の第一引数はreadStream,第二引数にwriteStreamを渡す必要があり、今回は読み込みのみのため第二引数には空オブジェクトを渡しています。
7行目でlineイベントをセットしており、lineイベントは['\n']を見つけたとき発火し、その行を引数として取得しています。
今回は受け取った文字列を逆順にしてコンソールに出力する関数をlineイベントに登録しています。
(lineイベントを登録した段階で初めてstreamの読み込みが始まるため、すぐ出力されます)

## 複数行ごとに処理

1行ごとの処理なら、上記のlineイベントを適切に設定することで上手くかけそうでした。
しかし、個人的にやりたいことは一定行ごとにまとめてDBに保存するなりなんなり処理することだったため、ストリームを指定行ごとに取得できるような例も作ってみました。

### 例2:複数行ごとに処理
```js:linereader.js
var readline = require('readline');

function Linereader(stream) {
  var self = this;
  self.rl = readline.createInterface({
    input: stream,
    output: {},
  });
  self.list = [];
}

module.exports = Linereader;

/**
 * @param {Number} unit // unit行ごとに取得する
 * @param {Function} fn // unit行取得した際に実行する関数
 * @param {Function} callback // ストリームの読み込みが終わった際のコールバック
 */
Linereader.prototype.forEach = function(unit, fn, callback) {
  var self = this;

  self.rl.on('line', function(line) {
    self.list.push(line);
    if (self.list.length >= unit) {
      fn(self.list);
      self.list = [];
    }
  });
  self.rl.on('close', function(line) {
    if (self.list.length) {
      fn(self.list);
    }
    callback();
  });
};
```
```js:main.js
var fs = require('fs');
var rs = fs.createReadStream('./hoge.txt');
var Linereader = require('./linereader');

var linereader = new Linereader(rs);

linereader.forEach(5, function(list) {
  console.log(list);
}, function() {
  console.log('end');
});
```
###実行結果
```
[ 'abcde', 'fghij', 'klmno', 'pqrst', 'uvwxy' ]
[ 'z' ]
end
```
###説明
上記のプログラムは、hoge.txtを5行(指定行)ごとの配列として取得し、コンソールに出力しています。
また、全て取得し終わった際にendを出力させています。
linereader.forEachの第二引数に処理を書くことで、複数行ごとに処理を実行することができます。
また、第三引数に処理をかくと、ストリーム読み込み後に処理を実行することができます。

##検討

例2のプログラムで、自分がしたかった複数行ごとに処理を挟むことができるようになりました。
ただ、このままだとlinereader.forEachの第二引数に非同期の処理を入れた場合、処理を待たずに次の処理が開始されてしまいます。
自分的には大きなファイルを複数行ごとに対してDBにどんどん入れていくような処理がしたいため、callbackできるようにできないか調べてみたのですが、Readlineのソース( https://github.com/joyent/node/blob/master/lib/readline.js )を確認したところ、以下の2点の理由からReadlineを使うことを断念しました。
・冒頭でも述べたようにそもそもReadlineが端末からの入力などのようなものを想定して組まれていること
・改行ごとにlineイベントをcallbackではなくfor文で回して発火しているため、非同期にできないこと

以上から、次は非同期に対応できるようStream2のReadableを用いて、Bufferから適切に行を取得できるようなプログラムについて検討したいと思います。
Selenium IDE で作成した HTML 形式のテストケースを Windows のコマンドラインから実行する

Selenium IDE で作成したテストケースを保存すると HTML 形式で保存されます。これを Windows のコマンドラインから実行する方法を調べました。

## Selenium Server をダウンロードする

まずは下記から `selenium-server-standalone-x.x.x.jar` の最新版をダウンロードします。今日の時点では最新は `selenium-server-standalone-2.39.0.jar` でした。ダウンロードしたら今回は仮にデスクトップに置いておきます。

## テストスイートを保存する

https://code.google.com/p/selenium/downloads/list?can=1&q=&colspec=Filename+Summary+Uploaded+ReleaseDate+Size+DownloadCount

下記は Selenium IDE で作成した http://qiita.com のタイトルを検査する簡単なテストケースを含むテストスイートです。テストケースを `assertTitle.html` 、テストスイートを `SampleTestSuite.html` としてデスクトップに保存しておいたとします。

```SampleTestSuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="assertTitle.html">assertTitle</a></td></tr>
</tbody></table>
</body>
</html>
```

```assertTitle.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="https://www.google.co.jp/" />
<title>assertTitle</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">assertTitle</td></tr>
</thead><tbody>
<tr>
	<td>open</td>
	<td>/</td>
	<td></td>
</tr>
<tr>
	<td>assertTitle</td>
	<td>Qiita - プログラマの技術情報共有サービス</td>
	<td></td>
</tr>
</tbody></table>
</body>
</html>
```

## コマンドを実行する

コマンドプロンプトのカレントディレクトリをデスクトップにしてから下記のコマンドを実行します。

```bat
java -jar selenium-server-standalone-2.39.0.jar -htmlSuite "*firefox" "http://qiita.com" "SampleTestSuite.html" "results.html"
```

すると Firefox が勝手に立ち上がり、テストを実行してくれます。そしてその結果は最後の引数で指定している `results.html` に HTML 形式で保存されます。ただ、`results.html` を開くとテストは成功しているものの日本語が文字化けしていました。何らかの対応が必要になりそうです。

![Test suite results.png](https://qiita-image-store.s3.amazonaws.com/0/16758/3e367125-0b9a-5189-baaf-ed5615fa5548.png)
EditTextの入力を制限する方法


InputFilterインターフェイスを実装し、Editableインターフェイスを採用したUI(EditText)に設定することでキー入力を制限できるようになる。

####注意
制限されたキーを押下しても入力はされないが、キーボード上部の補完は入力されたような振る舞いをする。
ただしEditTextの内容をTextViewなどに出力しても入力はされていない。



```java:MainActivity.java
		englishNameEditText = (EditText) findViewById(R.id.englishNameEditText);
		InputFilter inputFilter = new InputFilter() {
			@Override
			public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
				if (source.toString().matches("^[a-zA-Z]$")) {
					return source;
				}
				return "";
			}
		};
		InputFilter[] filters = { inputFilter };
		englishNameEditText.setFilters(filters);
```
【Unity3D】ファイル保存パス

#ファイル保存パス

自分メモとしてまとめました。

※Androidの外部ストレージは端末によってパスが変わります。

##Application.dataPath

アプリケーションが保存されているパス。

|環境|取得パス|
|:---|:---|
|Android(本体)|/data/app/<アプリのID>.apk|
|Android(SDカード)|/mnt/asec/<アプリのID>/pkg.apk|
|iOS|/var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/myappname.app/Data|

##Application.persistentDataPath

永続的なデータを保存するパス。
ユーザーデータなど、アプリが再生成できないファイルを配置する。

|環境|取得パス|
|:---|:---|
|Android(本体)    |/data/data/<アプリのID>/files/              |
|Android(SDカード)|/mnt/sdcard/Android/data/<アプリのID>/files/|
|iOS|/var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/Documents|

##Application.temporaryCachePath

一時的なデータを保存するパス。
ダウンロードデータなど、アプリが再生成できるファイルを配置する。

|環境|取得パス|
|:---|:---|
|Android(本体)|/data/data/<アプリのID>/cache/|
|Android(SDカード)|/mnt/sdcard/Android/data/<アプリのID>/cache/|
|iOS|/var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/Library/Caches|


##iOSの注意点

Application.dataPath
Application.persistentDataPath
のファイルは iCloud の保存対象になっています。
iCloud には無駄なデータを保存してはいけないようで、容量が大きすぎるとリジェクトされる事もあるようです。


##参考サイト

http://hiiro-game.seesaa.net/article/272455420.html
http://createwave.blog104.fc2.com/blog-entry-199.html
http://d.hatena.ne.jp/murishinai/20130606/p2

http://iaseteam.eshizuoka.jp/e1068667.html
amavisでclamavとの疎通が取れない、エラーの解決法


##経緯
CentOSでウィルススキャンを運用していて、Logwatchに気になるログを確認しました。

```
(!!)WARN: all primary virus scanners failed, considering backups
```

ウィルススキャンで入れているamavisが、ウィルススキャンをしていない！

##対応方法
amavisは、clamavと連携してウィルススキャンの対応をしているみたいです。

参考サイト：
[№3319 Logwatchの見方](http://fedorasrv.com/bbshtml/webpatio/3319.shtml)

```amavisd.conf
/tmp/clamd.socket
```

```clamd.conf
LocalSocket /tmp/clamd.sock
```

sockとsocketは違いますね。
これが原因でウィルススキャンがスルーされていたようです。

とても勉強になりました。
Papertrailを使って、ログを気軽にオンラインで閲覧可能にしてみる


[Papertrail](https://papertrailapp.com/)はLinuxサーバやWebアプリケーション等の様々なログをオンラインで集約し、閲覧・検索することができるサービスです。rsyslogやsyslog-ng等のsyslogデーモンに数行追記するだけで導入できるほか、Heroku等のPaaSからもプラグインとして利用することが出来ます。

同様のサービスには、[Loggly](https://www.loggly.com/)や[Logentries](https://logentries.com/)があります。また、オープンソースだと、[logstash](http://logstash.net/)や、全て構造化して[Fluentd](http://fluentd.org/)+Hive等で処理する、という方法もありそうです。

また、集約されたログをS3上に自動的に保管する機能も利用することが出来ます。S3上のデータはHiveのWHERE文で直接扱えるフォルダ形式になっており、別途Amazon EMRでクエリすることもできます。

* [Log analytics with Hadoop and Hive](http://help.papertrailapp.com/kb/analytics/log-analytics-with-hadoop-and-hive)

## 導入

[Papertrail](https://papertrailapp.com/)にユーザ登録すると、管理画面から`logs.papertrailapp.com:PORT_NUMBER`のようなログの送信先を取得することが出来ます。

実際に、rsyslogに導入するには`rsyslog.conf`に以下のように追記します。

```
*.* @logs.papertrailapp.com:PORT_NUMBER
```

rsyslogなので、例えば、

```
*.warn @logs.papertrailapp.com:PORT_NUMBER
```

などと指定することで、例えば、WARNING以上のログのみを転送し容量を節約するような運用も可能です。


また、上記設定の場合は、UDPで送信されますが、TLSで暗号化して送信することもできます。

* [Encrypting remote syslog with TLS (SSL)](http://help.papertrailapp.com/kb/configuration/encrypting-remote-syslog-with-tls-ssl)


これで、Papertrailのサイトからサーバログをリアルタイムに閲覧することができるようになります。

## アラートの作成

Papertrailは、検索条件をあらかじめ指定しておくことで、それにマッチしたログがあった場合に、通知することが出来ます。通知先には、メールや[HipChat](http://www.hipchat.com)などを選ぶことが出来ます。

例えば、特定のキーワードがログに出てきた場合や、`severity:(err crit alert emerg)`などのように指定し、err以上のログレベルの通知があった場合などに自動的にメールやHipChatに通知する、というような運用が可能です。

## さいごに

Papertrailはログのサイズが月100MBまでは無料で使うことができます。ログのボリュームが多いようであれば、例えば、上記のように、[WARN以上のログを通知する](http://help.papertrailapp.com/kb/configuration/controlling-verbosity)だけでも十分に有用に使用できそうです。
GITで特定のコミットで修正したファイルの一覧をエクスポートする。


GITで特定のコミットで修正したファイルの一覧を出力する方法
.gitconfigのAliasに以下を追加。

```shell-session
# 指定したコミットで修正されたファイルを出力する
# 例：git export a85419253dd8eaffcaa718a443365be9f57d63ea ./output
export = "!f() {\n\
             for file in `git diff --name-only $1 $1^`; do \n\
                 git archive --prefix=$2/ $1 $file | tar -xf - ; \n\
             done ; \n\
         }; f"
```
XCTestでViewControllerのテストを良い感じにやる方法


ViewControllerのテストって難しいですよね。

ContainerViewを活用している場合、addChildViewControllerしていても子ViewControllerのviewWillAppearが呼ばれなくて苦戦しました。
結局、非常に安易な手段で非常に効果的に対処出来たのでメモ。

```YourTestCase.m

@implementation UIViewController (TestHelper)

- (void)prefix_viewDidAppearWithObject:(NSNumber*)number
{
    [self viewDidAppear:number.boolValue];
}

@end


@interface YourTestCase : XCTestCase

@property YourViewController *viewController;

@end

@implementation YourTestCase

- (void)setUp
{
    [super setUp];
    
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:Main_iPhoneStoryboardName bundle:[NSBundle mainBundle]];
    self.viewController = [storyboard instantiateViewControllerWithIdentifier:Main_iPhoneStoryboardFeedViewControllerIdentifier];
}

- (void)testHoge
{
	// こんな感じで、実アプリでは遷移元でのprepareForSegue辺りで渡されるオブジェクトを渡す
    self.viewController.image = someImage; 

	// メインウィンドウのrootViewControllerに表示(をテスト)したいViewControllerをセット
    [UIApplication.sharedApplication.delegate.window setRootViewController:self.viewController];

	 // この行がないとメインスレッドをブロックせずに下に処理が走ってしまうので、正しくテスト出来ない模様。
	[self.viewController performSelectorOnMainThread:@selector(prefix_viewDidAppearWithObject:) withObject:@(YES) waitUntilDone:YES];

	// あとは好きにテストコードを書いてください！ 例えば以下のような。
	XCTAssertNotNil(self.viewController.imageView.image, @"画像があることを確認、とか。そんな感じ。");
}

@end

```
GITのリモートに増えてきた古いタグを一括で削除する


リリースの度にタグを作成していたら、リモートにタグが増えてきた。
整理したい気分なので、「v1.X.X」だけを削除する。

```shell-session
git ls-remote --tags origin | awk '/^(.*)v1([0-9.]*)$/ {print ":" $2}' | xargs git push --tags origin
```
PowerShell で文字・文字列を書き換える便利関数

PowerShell を使っていて、文字列をゴニョゴニョしたくなること、あると思います。
私の場合は特に「ある文字列の i 番目の文字を c に書き換えたい」「ある文字列の i 番目からの文字列を s で書き換えたい」というような事がしたかったのです。
残念なことに、.NET にはそういうのが無く、PowerShell 独自の関数としても見つけられなかったので、ちゃちゃっと書いてみました。

```Rewrite.ps1
function rewriteCharAt {
  param(
    [int]$index,
    [char]$value,
    [Parameter(ValueFromPipeline=$true, Mandatory=$true)][string[]]$target
  )
  
  process {
    foreach ($s in $target) {
      $s.Substring(0, $index) + $value.ToString() + $s.SubString($index + 1)
    }
  }
}
 
function rewriteStringAt {
  param(
    [int]$index,
    [string]$value,
    [Parameter(ValueFromPipeline=$true, Mandatory=$true)][string[]]$target
  )
  
  process {
    foreach ($s in $target) {
      $s.Substring(0, $index) + $value + $s.Substring($index + $value.Length)
    }
  }
}
```

エラー処理とかはしていないので、インデックスの指定を間違えたりするとお察しです。

この関数は書き換えたい元の文字列をパイプラインで受け取ることができるので、こんな風に使えます。

```Usage.ps1
PS C:\home> "This is a pen." |
>> rewriteStringAt 0 "That" |
>> rewriteCharAt 13 "!"
>> 
That is a pen!
PS C:\home> 
```

ほげーヾ(๑╹◡╹)ﾉ
RubyInstallerをサイレントインストールせよ

せっかくRubyを使うんだったらインストールも自動化しましょう。

#RubyInstaller編

##コマンド

```bat
rubyinstaller.exe /dir="path\to\ruby" /verysilent /tasks=modpath /lang=ja
```
###解説

RubyInstallerはインストーラーにInno Setupを利用しています。

|オプション|説明|
|:-----------|:-----------|
|/dir=path|インストール先。指定なしなら`c:\ruby200` (2.0の場合)|
|/verysilent|サイレントインストール。/silentとの違いはプログレスバーの有無|
|/tasks=modpath|環境変数PathにRubyを追加する。Pathは自力で追加してもよい|
|/lang=ja|日本語化する。なくてもよい|

その他細かいオプションはRubyInstallerの[FAQ](https://github.com/oneclick/rubyinstaller/wiki/faq)やInnoの[ドキュメント](http://www.jrsoftware.org/ishelp/topic_setupcmdline.htm)を参照してください。

## Chef
###前提
[windows cookbook](http://community.opscode.com/cookbooks/windows)を入れておくこと

###recipeのサンプル
```rb
windows_package "ruby" do
  source 'http://dl.bintray.com/oneclick/rubyinstaller/rubyinstaller-xxx.exe'
  installer_type :inno
  action :install
  options '/dir=path\to\ruby /tasks=modpath'
end
```
windows_packageリソースは[公式](http://docs.opscode.com/lwrp_windows.html)を見れば簡単に使えます。

# DevKit編
##コマンド
```bat
DevKit-xxx.exe -y -o"path\to\devkit"
```

###解説

DevKitはインストーラーに7-Zipの自己展開形式を利用しています。
-oはディレクトリ、
-yはプロンプトに全部Yes
です。
メタマジック・ゲームからハノイの塔写経



```

(define carry-one-disk
  (lambda (sn dn)
	(string-append sn dn)))

(define move-tower
  (lambda (n sn dn hn)
	(cond ((= n 1) (carry-one-disk sn dn))
		  (else (list (move-tower (sub1 n) sn hn dn)
					  (carry-one-disk sn dn)
					  (move-tower (sub1 n) hn dn sn))))))


(define carry-one-disk-flatten
  (lambda (sn dn)
	(list (string-append sn dn))))

(define move-tower-flatten
  (lambda (n sn dn hn)
	(cond ((= n 1) (carry-one-disk-flatten sn dn))
		  (else (append (move-tower-flatten (sub1 n) sn hn dn)
					  (carry-one-disk-flatten sn dn)
					  (move-tower-flatten (sub1 n) hn dn sn))))))


```
Google testを試してみた


C++でもテストができるようにGoogle Testを試してみた。

## インストール
参考にしたのはこのページ：
http://qiita.com/kuchida1981/items/9bb8fa4cc04635e7e909

以下のように標準的な手順でインストールできる

- gtestをダウンロード
- cmake, make でビルド

## テストの実行方法

インクルードパスを通して、gtest.a, gtest_main.a とリンクすればテストを行う実行ファイルがビルドされる。

ビルド方法は以下のようになる。（gtestへのパスは各自の環境ごとに設定すること）

```sh
export GTEST_HEADER_PATH=/path/to/gtest-1.7.0/include
export GTEST_BUILD_PATH=/path/to/gtest-1.7.0/build
g++ MyLib.cc MyLibTest.cc -I#{GTEST_HEADER_PATH} -L#{GTEST_BUILD_PATH} -lgtest -lgtest_main
```

- テストの書き方はここに乗っている。http://opencv.jp/googletestdocs/primer.html
- 基本的には `EXPECT_...` というマクロを使って条件判定を書いていけばOK。

```
EXPECT_EQ( my_queue.pop(), 10 );
EXPECT_LT( my_queue.size(), 3 );
```

## fixtureの書き方

- 複数のテスト間で共通処理をするためにfixtureクラスを用意する。
    - rspecでいうところの `before`, `after` などのフック処理を定義できる。
- `::testing::Test` クラスを継承したクラスを作る。このクラスのメンバにはテストケースからアクセス可能になる。
    - `SetUp()`, `TearDown()` などテスト前後の共通処理を定義できる
    - 複数のテストで共通で使える変数を定義できる
    - 共通処理の関数を書くこともできる。その中でアサーションも使える。
- `TEST` の代わりに `TEST_F` マクロを使って、先ほどのFixtureクラスを第一引数にする

```cpp
class MyTest : public ::testing::Test {
protected:
  virtual void SetUp() {
    double p1 = 0.1;
    double p2 = 0.05;
    m_myclass = new MyClass(p1, p2);
  };
  virtual void TearDown() {
    delete m_myclass;
  };

  MyClass* m_myclass;

  void CommonProcUsedByTests() {
      // something ...
      EXPECT_NE(j, 3);  // you can also write assertion here
    }
  }
};

TEST_F(MyTest, TestCaseA) {
  CommonProcUsedByTests();
  EXPECT_EQ( m_myclass.foo(), 1 );
}
```

## privateメンバーのテスト方法

概要は以下の通り。

- fixtureクラスを用意する
- ライブラリの側で、fixtureクラスをfriend指定する
- fixtureクラスの関数内でassertionを呼ぶ。
- TEST_F マクロ内でその関数を呼ぶ

詳細は[ここ](http://opencv.jp/googletestdocs/advancedguide.html#adv-testing-private-code)を参照。
キュードライバにbeanstalkdを使用する

Laravelではキュードライバに下記3つを使用できる

* Beanstalkd
* Amazon SQS
* IronMQ

それぞれ軽く調べてみた結果

* Amazon SQS･･･なんかお金かかるっぽい
* IronMQ･･･日本語のドキュメント無し(多分)

という都合によりBeanstalkdを使うことにした。

今回は、Beanstalkdを使う際、

* 処理を永続化する
* タスク状況を監視する

という実際キュードライバを使ってシステム運用するなら必要になるっぽい二つの設定とかを備忘録に。

Beanstalkdについて
とりあえずインストール

```
sudo yum install beanstalkd
```

処理の永続化
/etc/sysconfig/beanstalkd
の


```
#BEANSTALKD_BINLOG_DIR=/var/lib/beanstalkd/binlog
```

のコメントアウトを外す。

これだけでOk

この指定をすることでログにキューのタスク情報(曖昧)を書き込むようになる。
のでサーバ落ちたりしてもキューにジョブがたまっていた場合、続きから再開できる。


管理ツールの導入
じゃあそもそもキューがどうなっているかを管理できるインターフェースあったら便利だよねってことで調べたところ、いいものがありました。

* beanstalk_console

https://github.com/ptrofimov/beanstalk_console

早速インストールしてみる

```
curl -s http://getcomposer.org/installer | php
```

composer.pharファイルができるので、実行

```
php composer.phar create-project ptrofimov/beanstalk_console -s dev path/to/install
```

これでツールがインストールされる。特に何も設定しなくても
http://localhost/作業ディレクトリ/path/public/index.php
にアクセスすると問題なく使えた。

キューがどんな感じかを知るなら下記記事が大変参考になる。
http://blog.ishinao.net/2013/07/05/28289/


サンプルを作ってジョブを登録→beanstalkdを停止させて再起動

みたいなことをすれば永続化のテストが割りと簡単にできる。

これでLaravelでキューを使うための準備は整った！･･･はず。
Android/Eclipseの爆速環境構築


##はじめに
Android開発といえばEclipse
そしてEclipseといえば尋常じゃない遅さ
初めて導入したときに感動したいくつかの環境改善方法を紹介します

##Eclipseの高速化
Eclipseはもともとのメモリの割当が少ないです
なので設定を変えてメモリの割当を拡張しましょう

[素人アプリの開発日記](http://andante.in/i/eclipse/eclipse%E3%81%A7%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%83%A1%E3%83%A2%E3%83%AA%E3%82%92%E5%A2%97%E9%87%8F%E3%81%99%E3%82%8B%E3%80%82/)がすごい分かりやすいです
　
##Androidエミュレーターを変える
Android開発の一番辛いところ
それはDefaultのエミュレーターが尋常じゃないくらい重いことです。
基本的には実機を使えば良いのですがLocalServerなどに接続するためにエミュレーターを使いたくなることも結構出てきます。
そんなときのためにgenymotionをinstallしましょう
　
[Developpers.IoのAndroid爆速エミュレーター環境を構築する](http://dev.classmethod.jp/smartphone/android/genymotion-install/)が分かりやすいです

まじ爆速

ちなみにgenymotionでローカルServerにアクセスする場合はIPアドレスが通常と異なります。“10.0.2.2"では動きません。"192.168.56.1"にアクセスする必要があるので気をつけてください
(例 : Rails http://192.168.56.1:3000/sampleController/sampleAction)

　
##おまけ　Eclipseの色を変える
普段他のエディタを使っていると真っ白なEclipseの画面に慣れないと思います。
Pluginを使えば簡単に黒色にすることができます。

[Futurismo 黒背景のEclipseでめちゃガチャクールな男前に！目にも優しいEclipse-Juno-DarkプラグインとEclipse Color Themeの[Dark Juno]の設定方法](http://futurismo.biz/archives/1314)が分かりやすいです。

黒色の方が目に優しいらしいですよ
　

##その他参考
　http://bbowden.tumblr.com/post/58650831283/accessing-a-localhost-server-from-the-genymotion
cssのtransformで遷移すると、scrollTop()では値が取れない。

## cssのtransformで遷移すると、scrollTop()では値が取れない。

表題の通りなのですが、$(window).scrollTop()で現在のスクロールの位置を取ろうとしても、cssのtransformで移動していると、値がずっと0のままでした。

そこで対処法としては、

```js
var getPoint = new Object();  // 座標を保存

$(function(){
   $(document).on({
     "mousedown":function(e){dragOn(e);}
   });
});

function dragOn(e) {

  var scrollY;
  if (e.pageX) {
    scrollY = getPoint.y - e.pageY;
  } else {
    scrollY = e.y - document.body.scrollTop;
  }
   // scrollYが一番上の座標
}

```

## htmlの底の座標

ついでに、htmlの一番下の座標も取得に困っていたので、メモ。

```js
var documentHeight = - window.scrollMaxY;
```

ただ、DOM構築前に呼び出してしまうと、うまく正しい値が取れないので、</body>の直前で呼ぶ必要がある。
Solrクライアントからのクエリにタイムアウトを設定する


[Timing out a query in Solr](http://stackoverflow.com/questions/19557476/timing-out-a-query-in-solr, "Timing out a query in Solr")

上のリンク先を参考にする。

solrconfig.xml

```xml
<requestHandler name="standard" class="solr.StandardRequestHandler" default="true">
    <lst name="defaults">
        <!-- other parts left out -->
        <!-- timeout (in milliseconds) -->
        <int name="timeAllowed">5000</int>
    </lst>
</requestHandler>
```

[Solr Wiki timeAllowed](http://wiki.apache.org/solr/CommonQueryParameters#timeAllowed, "timeAllowed")

> The time allowed for a search to finish. This value only applies to the search and not to requests in general. Time is in milliseconds. Values <= 0 mean no time restriction. Partial results may be returned (if there are any).

[Common Query Parameters](https://cwiki.apache.org/confluence/display/solr/Common+Query+Parameters, "Common Query Parameters")

> timeAllowed
Defines the time allowed for the query to be processed. If the time elapses before the query response is complete, partial information may be returned.