旅費comというサービスを作りました

f:id:xibbar:20151207125117j:plain

長い間自分のためだけのウェブアプリだったのですが、 社長仲間からチラホラ使いたいという声がでてきていましたので、 奮起して外部公開できるように作りなおしました。

http://ryohi.com/

このサービス何?

旅費精算書を簡単に印刷するためのサービスです。

www.youtube.com

旅費と交通費の登録をすると、綺麗に印刷されます。 交通費はテンプレート化できるので、いちいち調べ直す必要がありません。 日当と宿泊費を登録することができます。

なんで必要なの?

別にエクセルでやるからいいよって人には必要な気かもしれません。 私がエクセルで管理するのが嫌になったので作りました。

たったそれだけなの?

旅費精算書には秘密があって、絶大な節税効果があります。 そのための条件は、

  • 法人であること
  • オーナー社長であること

です。法人であることは絶対条件です。後者はやりやすさが影響します。

税法上問題ないの?

もちろんきちんとやらないと税務調査でクロ判定されますので、 きちんとやってください。節税のノウハウはここでは書けません。

いくらかかるの?

広告を貼る予定なので、無料です。5名という上限がありますので、 それ以上使いたい場合はご連絡ください。

広告を外せないの?

1アカウントに付き500円(税抜)/月で広告を外すことができます。

節税ノウハウ教えてくれないの?

面識のある人にしか教えません。知り合いになってください。

スマホで使える?

スマホで使えるようにレスポンシブなデザインになっています。 ブラウザをキュッと小さくすると確認できます。

あんた誰?

xibbarこと藤岡と言います。Ruby界隈と不動産賃貸業界隈に出没します。 就職もせずにRubyの会社を立ち上げて14年、不動産賃貸事業をはじめて8年ぐらいです。 このサービスはxibbarの個人プロジェクト扱いです。

欲しい機能があるんだけど

@xibbarまで連絡ください。検討します。

バグを見つけたんだけど

@xibbarまで連絡ください。なおします。

サーバはどこにあるの?

herokuを使っています。今は日本リージョンが正式版にないので、アメリカにあります。 そのため、反応が若干遅いです。

ぜひ、お使いいただき、感想をいただけると嬉しいです。

OSX El Capitanにrbenvで1.8.7-p375を入れる

もういい加減にしたいと思っている1.8.7なのですが、 残っているところがある以上、こちらでも開発環境を用意しなければならないのです。

rbenv install 2.2.3

とかは問題なくインストールできました。しかし、

rbenv install 1.8.7-p375

とやってみたのですが、エラーが出ます。

ERROR: This package must be compiled with GCC, but ruby-build couldn't
find a suitable `gcc` executable on your system. Please install GCC
and try again.

DETAILS: Apple no longer includes the official GCC compiler with Xcode
as of version 4.2. Instead, the `gcc` executable is a symlink to
`llvm-gcc`, a modified version of GCC which outputs LLVM bytecode.

For most programs the `llvm-gcc` compiler works fine. However,
versions of Ruby older than 1.9.3-p125 are incompatible with
`llvm-gcc`. To build older versions of Ruby you must have the official
GCC compiler installed on your system.

TO FIX THE PROBLEM: Install Homebrew's apple-gcc42 package with this
command: brew tap homebrew/dupes ; brew install apple-gcc42

You will need to install the official GCC compiler to build older
versions of Ruby even if you have installed Apple's Command Line Tools
for Xcode package. The Command Line Tools for Xcode package only
includes `llvm-gcc`.

BUILD FAILED (OS X 10.11 using ruby-build 20150818-4-g8d6ff29)

こんなエラーが出ます。エラーメッセージのとおりにやってみたのですが、 全然ダメでした。仕方ないのでビルドディレクトリに移動してみて、 ./configureをやったらあっさり通ります。 なんだ、ruby-buildの問題か。というわけで、デバッグをしはじめました。 ちょっとだけ追ってみたら、require_gccのあたりのようで、 gccのチェックをしている模様。

--- a/share/ruby-build/1.8.7-p375
+++ b/share/ruby-build/1.8.7-p375
@@ -1,3 +1,3 @@
-require_gcc
+# require_gcc

これであっさり通るようになりました。 ちゃんと直すのは面倒だなぁ。っというわけで誰かお願いします。 bashの動きを調べるのめんどい。

あなたならどうするこのルーター設定

とあるシステムと接続するにあたって、 サービス元のIPアドレス 192.168.10.1/24 持ち込みルータのIPアドレス 192.168.20.1/24 サービス先のIPアドレス 192.168.30.1/24 ポート番号10000 ってな感じで、全部サブネットと違っていて、ポートが指定されてしまっている。 NATで変換したいんだけど、間に192.168.30.0/24のネットワークを 構築する余地もない。

f:id:xibbar:20151005165356p:plain

さてどうする?

解1. がんばってLANを構築し直して、192.168.30.0/24のネットワークにしてしまう。

解2. 静的ルーティングで192.168.100.2のサーバに192.168.30.0/24のルートを向けて、ループバックに192.168.30.2を指定する。仕方ないのでポートはそのまま使う。

どちらの案もNAT使っていないんだけど、通過するだけのパケットのIPとかポートを 捻じ曲げる方法があるって人は教えて下さい。 もうわからん。

追記

lan1にサービス先のサブネットを振り、Static NATをすることで実現できました。 試していないのですが、ポートとIPを組み合わせてmasquaradeする方法でもいけるでしょう。

ip lan1 address 192.168.20.1/24
ip lan1 secondary address 192.168.30.2/24
ip lan1 nat descriptor 1
nat descriptor type 1 nat
nat descriptor address outer 1 192.168.30.1-192.168.30.254
nat descriptor address inner 1 192.168.20.1-192.168.20.254
nat descriptor static 1 1 192.168.30.1=192.168.100.1 254

f:id:xibbar:20151006151627p:plain

16進数が文字列になっちゃっているものを配列にしたい

お題 "FF2E0A" => [255, 46, 10] と変換したい

16進数が文字列として入っている。

"FF2E0A".scan(/.{2}/).map{|c|Integer("0x#{c}")}

これだとやはり長い。

["FF2E0A"].pack("H*").bytes

これがやはり最強だな。knuさんに教えてもらったけど、考えてもすぐには出てこない。

["FF2E0A"].pack("H*")

これだけだと文字列になりますので、これはこれで使えます。

pack / unpack は最強。

C言語の外部コマンドへの入出力がよくわからない

とりあえず、現状で必要なのはgzip圧縮されたデータを受信して、展開したいだけ。 あっさりzlibライブラリで解決するかと思いきや、 zlibを読んだ感じでは、gzipはファイル化しなけりゃならないっぽい。 ファイル化とか面倒だと思ってgunzip -cに吸い込ませた結果を 読みこめばいいかとRubyのOpen3感覚で思っていたらハマってしまった。

とりあえず、やりたかったことをRubyで書いた。

gzipdata = open(ARGV[0], "rb").read

# やりたいことは、gzip圧縮されたデータを展開したいだけ
pipe = IO.popen("gunzip -c", "r+")
pipe.write gzipdata
pipe.close_write

data = pipe.read
pipe.close

# 結果の出力
result_file = open("result.jpg", "wb")
result_file.write data
result_file.close

これ、C言語でやろうとするとめんどくさい。 ネットなどで検索すると、pipeを作ってforkしろと書いてある。 プロセス複製とかしなきゃならんのか〜とか思ってちょっと萎える。

もう、gzipデータをRubyプログラムに丸っとパイプかドメインソケットで渡して そっちで処理してくれというプログラムにしちまうか。。

というわけで、誰か偉い人教えて下さい。

  • Cでforkせずともできるものなのか
  • Cではforkするのが常識なのか
  • そもそも何か間違っているのか
  • zlibでファイル作らずともあっさり出来るよ〜みたいな情報

もうわからん。

Rubyでサーバを作ってクライアントにデータを配信 vol.6

vol.5のように時間がかかる処理があると待たされてしますので、 それを解決したコードが次のコードです。

require "socket"

port = if ARGV[0] then ARGV[0] else 'echo' end
gate = TCPServer.open(port)

sockets = [gate, STDIN]
clients = []
loop do
  r_sockets = IO.select(sockets+clients)[0]
  r_sockets.each do |socket|
    case socket
    when STDIN
      str = socket.gets
      threads = []
      clients.each do |client|
        threads << Thread.new do
          client.puts str.upcase
          sleep 2
        end
      end
      threads.each{|t|t.join}
    when TCPServer
      client = socket.accept
      clients << client
      p clients
    when TCPSocket
      unless socket.eof?
        str=socket.gets
        socket.puts str.upcase
      else
        socket.close
        clients.delete(socket)
        p clients
      end
    end
  end
end

gate.close

スレッドを使って次々と並列して処理を開始し、最後にjoinで処理が全て終了するのを待ちます。

とりあえずRubyではここまで検証をしたかったので一旦終了。