2015/07/11

epgのデータベース登録

シンプルなサーバーアプリが出来たところで番組データを取り込んで、リストアップするところまで。

以前は素のRubyスクリプトでActiveRecordを直接使う流れでしたが、今回はRailsのタスクで用意してみる。

lib/tasks/epg.rakeファイルを作成。以下の様な感じになった。

タスクからタスクを呼ぶのは、executeとinvokeがあるが、invokeは処理中に1度しか呼ばないという仕様がある。チャンネル分回すので、今回はexecuteにした。

タスク引数は、Rake::TaskArgumentsを使うことになるが、executeの場合シンプルに渡すだけらしいので、execute(ch)ってやれば、|task,arg|のargに直接chが入るので、スッキリはする。
ただし、executeからしか呼べなくなるという制約がつく。外から引数付きのタスクとして呼べなくなる。

それから、:updateはただ呼ぶだけのタスクだから :environment は不要だろうと思ったが、親タスクも必要だった。因みに、 :environment はActiveRecordでのレコードクラスインスタンス作成などをやってくれるところらしい。詳しくは知らないっすが・・

後は、んん?というところは無いはず。ごく自然な流れ。


namespace :epg do

  EPG_PATH = Rails.root.join('tmp').join('epg')
  Chs = [27,26,25,24,23,22,21,16]
#  Chs = [27]

  desc "EPG 更新"
  task :update => :environment do
    Chs.each do |ch|
      arg = Rake::TaskArguments.new([:ch],[ch])
      Rake::Task['epg:get'].execute(arg)
      Rake::Task['epg:put'].execute(arg)
#      Rake::Task['epg:get'].execute(ch) ##1 個別に呼ぶのを諦めれば、こっちでもいける.
    end
  end

  desc "EPG 取得"
#  task :get do |t,arg| ##1
  task :get,[:ch] do |t,arg|
    `recfsusb2n -b -i epg #{arg.ch} 10 #{EPG_PATH}/#{arg.ch}.ts`
    `epgdump json #{EPG_PATH}/#{arg.ch}.ts #{EPG_PATH}/#{arg.ch}.json`
  end

  desc "EPG 登録"
  task :put,[:ch] => :environment do |t,arg|
    json = open("#{EPG_PATH}/#{arg.ch}.json").read
    data = ActiveSupport::JSON.decode(json)

    if data.present?
      # Channelレコード 登録
      Channel.create( ch: arg.ch,
                      name: data[0]['name'],
                      code: data[0]['id']) if Channel.where(ch: arg.ch).empty?

      # 過去のプログラムを削除
      Program.destroy_all ["end_at < ?",Time.now]

      # 登録
      data[0]['programs'].each do |prog|
        set_program( prog )
      end
    end
  end

  # レコード 登録
  def set_program( prog )
    if Program.where(event_id: prog['event_id']).empty?

      # category
      category = prog['category']
      if category.present?
        cate = Category.where(name:
                              [category[0]['large']['ja_JP'],' (',category[0]['middle']['ja_JP\
'],') '].join
                              ).first_or_create
      end

      # program
      Program.create( channel_id: Channel.where(code: prog['channel']).first.id,
                      event_id: prog['event_id'],
                      title: prog['title'],
                      detail: prog['detail'],
                      start_at: Time.at(prog['start']/10000),
                      end_at: Time.at(prog['end']/10000),
                      duration: prog['duration'],
                      category_id: cate.try(:id) )
    end
  end
end

2015/07/10

録画システムをrails4で開発

録画ツールや開発環境が整いましたので、いよいよ録画システムのフロントエンドとなる
サーバーアプリケーションをRails4を使って構築していきます。

mysql

用途から言ってsqlliteで十分だと思うけれど、データベースは使い慣れているmysqlにする。

$ sudo apt-get install mysql-server
$ sudo apt-get install libmysqlclient-dev ← gem mysqlで使うから

後これくらいはやっておこう。
$ mysql_secure_installation

ユーザ作成
mysqlにrecmanユーザを作成して、recmanデータベースのアクセス権を与える。

$ mysql -uroot -p
> create user 'recman'@'localhost' identified by 'pw';
> grant all privileges on recman.* to 'recman'@'localhost';


railsアプリ(recman)の作成
$ rails new recman -d mysql

gitリポジトリ
$ cd recman
$ git init
$ git add .
$ git commit -m "the first recman"

gem
recman/conf/database.ymlのproductionセクションが以下のようになっていたので
production:
  <<: br="" default="">  database: recman_production
  username: recman
  password: <%= ENV['RECMAN_DATABASE_PASSWORD'] %>
 ↑直接パスワードに書き換える。環境変数で管理するほどじゃないし。
その他データベース名とかは自分のすきに書き換える。

Gemfileに追記
gem 'therubyracer'
gem 'mysql'
gem 'unicorn' ←productionをunicornで駆動するから


今回デプロイしないで直接駆動の予定なので、capistranoは使わないな。

$ bundle install

これでrailsアプリの母体が出来ました。

model作成

Channelモデル
$ rails g model channel code:integer name:string

Categoryモデル
$ rails g model category name:string

Programモデル
$ rails g scaffold program \
    channel_id:integer \
    title:string \
    detail:text \
    start_time:datetime \
    end_time:datetime \
    duration:integer \
    category_id:integer \
    event_id:integer

 scaffoldで作ると、VMC全部作ってくれます。楽ちん。
event_idはどう使うかイメージできていないけど、放送終了まではユニークなコードらしいので録画スケジュールとかで使えるかと。

後で、ChannelとProgramのchannel_idが関係付けられる感じ。Categoryも同じ。


 index作成
モデル作成時に出来たmigrationファイルに書き加えてもいいけど、区別した方が自分は好きなので。

$ rails g migration AddIndexToPrograms

db/migration/[TIME]_add_index_to_programs.rbにadd_indexを書いていく
 def change
    add_index :programs, :channel_id
    add_index :programs, :title
    add_index :programs, :category_id
    add_index :programs, :start_at
    add_index :programs, :end_at
    add_index :programs, :event_id
    add_index :programs, [:start_at,:end_at]
    add_index :programs, [:start_at,:duration]
    add_index :programs, [:category_id,:start_at]
 end
な感じ? ありそうなクエリをひと通りインデクス作っておこう。マスターレコードのChannelやCategoryも一応ね。

データベース作成
$ bundle exec rake db:create
$ bundle exec rake db:migrate


viewを確認(データ入ってないけど)
$ rails s -b 0.0.0.0

ブラウザで http://shuttle:3000/programs へ

Listing Programs

Channel_id Title Detail Start_at End_at Duration Category_id

New Program
とりあえず出ましたね。

おお。パスをわざと間違えてみたら、RoutingErrorページが格好いいじゃないですか。
多分これDevelopmentで動かしている時に出るんでしょうね。Rails3はこんなじゃなかったなぁ。
ちょっと感動。

データベースの中身が入ってこないとつまらないんで、次はそっちから片付けます。

2015/07/08

rvm + rails4 でサーバーアプリ開発環境

いつもの流れではあるので特出すべきことはないですが・・・
Shuttleで録画システム再開発ということで、前回の反省点を踏まえながら進めていく。

まずは、rvmとrails4.2 railsは仕事では3までしか使ってないんで4は自分的に初!

rvm

$ sudo apt-get intall curl

-- ここからは全部自分環境なので sudo じゃないよ --

$ curl -sSL https://rvm.io/mpapis.asc | gpg --import -
$ curl -sSL https://get.rvm.io | bash -s stable
$ source /home/shuttle/.rvm/scripts/rvm ← shuttleというユーザ名でやってます
$ rvm list known ←選択可能なrubyバージョンを確認
$ rvm install ruby-2.2.1 --default
↑
これが長いんだ・・・暫し待つ。
この時点で gemとgem基本パッケージが入っている

rails4.2

$ gem i rails --no-ri --no-doc
↑
これも長いよねぇ・・・


アプリ作成

$ rails new recman ←という名のアプリ作成
$ cd recman
$ bundle install
$ rails s

とりあえずWebrickでHTTPサーバー起動するかな?

あぁ、そうだった。developmentでWebrick起動するためには、'therubyracer'が必要でした。
Gemfileに、gem 'therubyracer' を追記。

もう一度
$ bundle install
$ rails s

別のPCから、http:://shuttle:3000/ へアクセス。およ?アクセス出来ない・・・?

最初は、ufw とか考えたけれど、いやいやEnforceしてないし・・・結局調べたら
何と rack version 1.6から仕様が変わったらしく、デフォルトが http://localhost:3000 となるらしい。
要するに自分自身以外からのアクセスが出来ないと。

これだと困るので

$ rails s -b 0.0.0.0

ってやると、どこからでもアクセスできるようになる。むぅ、ちょっとめんどくさいな。
rails4.2環境は初めてなので、こんなところでも引っかかってしまう。