「 Ruby 」一覧

radikoのタイムフリー&エリアフリーを保存する(ruby版)

以前にradikoのタイムフリー&エアフリーを保存するする手順を書きましたが、今回はRuby版です。

radikoのエリアフリーを保存する方法
以前、radikoのタイムフリーを保存する方法を書きましたが、今回はエリアフリー対応版です。 基本的な手順は同じですが、異なるのは最初...

環境

  • macOS Mojava
  • ruby 2.5
  • 事前にffmpegとswftoolsを導入しておく
  • httpclient gemをインストールしておく

事前準備

myplayer-release.swfのダウンロード

認証のための事前準備としてswfファイルをダウンロードする

$ curl -O http://radiko.jp/apps/js/flash/myplayer-release.swf

swfファイルから画像ファイルを取り出す

認証にキーとなる画像ファイルをswfextractで取り出す

$ swfextract myplayer-release.swf -b 12 -o authkey.png
$ ls authkey.png
authkey.png

実行方法

タイムフリー(エリア内)

$ ruby rec_radiko.rb --sid=LFR --ft=201812190000 --to=20181219010000

エリアフリー(mailとpassにプレミア登録している情報を設定する)

$ ruby rec_radiko.rb --sid=MBS --ft=201812190000 --to=20181219010000 --mail=hoge@example.com --pass=password

rec_radiko.rb

require 'optparse'
require 'date'
require 'httpclient'

M4A_FILE = DateTime.now.strftime('%Y%m%d%H%M%S') + ".m4a"

LOGIN_URL = 'https://radiko.jp/ap/member/login/login'
LOGIN_CHECK_URL = 'https://radiko.jp/ap/member/webapi/member/login/check'
AUTH1_URL = 'https://radiko.jp/v2/api/auth1_fms'
AUTH2_URL = 'https://radiko.jp/v2/api/auth2_fms'

params = ARGV.getopts("", "sid:", "ft:", "to:", "mail:", "pass:")

if params["sid"] == nil || params["ft"] == nil || params["to"] == nil
    puts "Usage: ruby rec_radiko.rb --sid=<station id> --ft=<start time> --to=<end time> --mail=<mail address --pass=<password>"
    exit
end

sid = params["sid"]
ft = params["ft"]
to = params["to"]

PLAYLIST_URL = "https://radiko.jp/v2/api/ts/playlist.m3u8?station_id=#{sid}&l=15&ft=#{ft}&to=#{to}"

mail = params["mail"]
pass = params["pass"]

client = HTTPClient.new

header = { \
    'Content-Type' => 'application/x-www-form-urlencoded', \
    'Referer' =>  'http://radiko.jp/', \
    'Pragma' => 'no-cache', \
    'User-Agent' =>  'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30', \
    'X-Radiko-Device' => 'pc', \
    'X-Radiko-App-Version' =>  '4.0.0', \
    'X-Radiko-User' =>  'test-stream', \
    'X-Radiko-App' => 'pc_ts' \
    }

# premium login
if mail != nil && pass != nil
    res = client.post(LOGIN_URL, {'mail' => mail, 'pass' => pass}, header)
    res = client.get(LOGIN_CHECK_URL, nil, header)
    if HTTP::Status.successful?(res.code) != true
        puts "Login failed"
        exit 1
    end
    puts "Login Succeed"
end

# Authentication 1
res = client.post(AUTH1_URL, nil, header)
if HTTP::Status.successful?(res.code) != true
    puts "Auth1 failed"
    exit 1
end
puts "Auth1 Succeed"

# X-Radiko-AuthToken が大文字の場合と小文字の場合があるため両方に対応
if res.headers['X-Radiko-AuthToken'] != nil
    header['X-Radiko-Authtoken'] = res.headers['X-Radiko-AuthToken']
elsif res.headers['X-RADIKO-AUTHTOKEN'] != nil
    header['X-Radiko-Authtoken'] = res.headers['X-RADIKO-AUTHTOKEN']
else
    puts "X-Radiko-AuthToken not found"
    exit 1
end
    
header['X-Radiko-Partialkey'] = `dd if=authkey.png ibs=1 skip=#{res.headers['X-Radiko-KeyOffset']} count=#{res.headers['X-Radiko-KeyLength']} 2>/dev/null | base64`.chomp

# Authentication 2
res = client.post(AUTH2_URL, nil, header)
if HTTP::Status.successful?(res.code) != true
    puts "Auth2 failed"
    exit 1
end
puts "Auth2 Succeed"

# ffmpegで保存
ffmpeg = "ffmpeg \
-content_type 'application/x-www-form-urlencoded' \
-headers 'Referer: http://radiko.jp/' \
-headers 'Pragma: no-cache' \
-headers 'X-Radiko-AuthToken: #{header['X-Radiko-Authtoken']}' \
-user_agent 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30' \
-i '#{PLAYLIST_URL}' \
-vn -acodec copy -bsf aac_adtstoasc #{M4A_FILE}"

`#{ffmpeg}`

CentOS7でApache+PassengerのRails本番環境を構築する手順

Apache + PassengerでのRails本番環境を作成する手順についてまとめました。

前提

  • Vagrant のCentOS7.5イメージを利用する
  • Rails のアプリケションはgithub等のリモートリポジトリから取得する
  • Vagrant + Virtual Boxはインストール済みとする

環境

  • CentOS 7.5(Vagrant Box)
  • Ruby 2.5.3 (rbenv)
  • Rails 5.2.2
  • DBはMysql

手順

Vagrant環境構築

ホストOSの任意のディレクトリでCentOS7.5の仮想環境を構築します

$ vagrant init centos/7

Vagrantfileの以下の部分のコメントアウトを外し、ホストOSの8080番ポートをゲストOSの80番ポートにフォワードするようにします。

config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

仮想環境を起動してログインします。

$ vagrant up
$ vagrant ssh

CentOS7.5の構成

OSを更新します。

$ sudo yum -y update

SELinuxを無効化します。

/etc/selinux/configのSELINUXをdisabledにします。

SELINUX=disabled

OSを再起動します。

$ sudo reboot

rbenv で Ruby をインストール

まずはrbenvのインストールに必要な各種パッケージをインストールします。

$ sudo yum -y install git-all openssl-devel readline-devel sqlite gcc gcc-c++

続いて、rbenvをインストールします。

$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ echo 'gem: --no-ri --no-rdoc' > ~/.gemrc
$ source ~/.bashrc
$ rbenv --version
rbenv 1.1.1-39-g59785f6

rbenvがインストールできたら、Rubyをインストールします。

バージョンは、公開しようとしているRailsアプリケーションが指定しているバージョン(2.5.3)に合わせます。

$ rbenv install 2.5.3
$ rbenv global 2.5.3
$ ruby -v
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]

bundlerもあわせてインストールします。

$ gem install bundler
$ bundle version
Bundler version 1.17.2 (2018-12-11 commit 43e950846)

Apacheのインストール

Apacheをインストールし、自動起動の設定を行います。

$ sudo yum -y install httpd httpd-devel curl-devel apr-devel apr-util-devel
$ sudo systemctl enable httpd

Passengerのインストール

Passengerをインストールします

$ sudo yum install -y epel-release pygpgme curl
$ sudo curl --fail -sSLo /etc/yum.repos.d/passenger.repo https://oss-binaries.phusionpassenger.com/yum/definitions/el-passenger.repo
$ sudo yum install -y mod_passenger

node.jsのインストール

Rails に必要なJavaScriptランタイムとしてnode.jsをインストールします。

なお、node.jsはEPELリポジトリから取得するため、Passengerのインストールの最初に実施しているepel-releaseのインストールが前提となっていますので注意してください。

$ sudo yum install -y nodejs

Mysqlのインストール

Mysqlをインストールします。

$ sudo yum install -y mariadb-server mariadb-devel
$ sudo systemctl enable mariadb
$ sudo systemctl start mariadb
$ sudo mysql_secure_installation

本番DBの作成

本番環境用のデータベースと接続ユーザを作成します。

以下の情報はRailsアプリケションのconf/database.yamlの内容と合わせます。

  • データベース名: prodution_db
  • 接続ユーザ: prod_user
  • パスワード: Password
$ mysql -u root -p

MariaDB [(none)]> CREATE DATABASE production_db DEFAULT CHARACTER SET utf8;

MariaDB [(none)]> GRANT ALL PRIVILEGES ON production_db.* TO prod_user@localhost IDENTIFIED BY 'Password' WITH GRANT OPTION;

Rails環境を構築

いよいよ、Railsの環境を構築します。

ここでは、github等のリモートリポジトリからファイルを取得する前提としています。
(SSH接続の設定については割愛します)

$ git clone <リモートリポジトリ>

以降、アプリケーションのディレクトリを rails_app とします。

アプリケーションのディレクトリを/var/www配下に移動します。

$ sudo mv rails_app /var/www

bundle install でRailsと必要なgemをインストールします。

なお、ここではpathを指定して、gemをローカルにインストールすることにします。

$ cd /var/www/rails_app
$ bundle install --path vendor/bundler
$ bundle exec rails -v
Rails 5.2.2

Credential情報の管理に使うキー情報をconfig/master.keyに設定します。

Rails5.2が生成する.gitignoreでは/config/master.keyがデフォルトで指定されているため master keyはリモートリポジトリに含まれません。

そのため、rails ini した環境のmaster.keyの内容を設定します

$ vi config/master.key

config/database.yamlの内容を先ほど作成したmysqlの環境と合わせます。

production:
  adapter: mysql2
  encoding: utf8
  database: production_db
  pool: 5
  username: prod_user
  password: Password

マイグレーションを行い、本番環境のデータベースを作成します。(必要に応じてdb:seedで初期データの登録も実施します)

$ bundle exec rails db:migrate RAILS_ENV=production
$ bundle exec rails db:seed RAILS_ENV=production

アセットのプリコンパイルを行います。

$ bundle exec rails assets:precompile

Apacheの設定

/etc/httpd/conf.d/passenger.conf を修正します。

  • PassengerRuby をrbenvのパスに変更
  • ServerName をlocalhostに変更
  • DocumentRoot と Directory をRailsアプリケーションのpublic フォルダに設定
<IfModule mod_passenger.c>
   PassengerRoot /usr/share/ruby/vendor_ruby/phusion_passenger/locations.ini
   PassengerRuby /home/vagrant/.rbenv/shims/ruby
   PassengerInstanceRegistryDir /var/run/passenger-instreg
</IfModule>

<VirtualHost *:80>
   ServerName localhost
   # Be sure to point to 'public'!
   DocumentRoot /var/www/rails_app/public
   <Directory /var/www/rails_app/public>
      # Relax Apache security settings
      AllowOverride all
      Require all granted
      # MultiViews must be turned off
      Options -MultiViews
   </Directory>
</VirtualHost>

設定を反映させるために、httpdを再起動します。

$ sudo systemctl restart httpd

動作確認

ホストOSのブラウザから http://localhost:8080 にアクセスし、railsアプリケーションにアクセスし正常に動作すれば成功です。

なお、エラーが発生した場合は、Apacheのエラーログ(/var/log/httpd/error_log)等を確認して切り分けていくことになります。


OS Xへのrailsのインストールではまった件

OS Xにrailsをインストールしようとしたら、初っぱなからつまずいたので対応をメモっておく。

環境

OS X EI Capitan 10.11.5
rbenv 1.0.0
ruby 2.2.5

問題点

rbenvで構成したruby 2.2.5 でrailsをインストールしようとしたところ、nokogiriのインストールで問題が発生しました。

ERROR:  Error installing nokogiri:
	ERROR: Failed to build gem native extension.

Building nokogiri using system libraries.
ERROR: cannot discover where libxml2 is located on your system. please make sure `pkg-config` is installed.

調査したところ、nokogiriのインストールにはlibxml2、libxslt、libiconvが必要とのこと。

対応

libxml2、libxslt、libiconvをbrewで入れるのですが、またまたややこしいことに、libconvはHomebrewの正式リポジトリから外れているので、tapで公式以外のリポジトリを追加する必要があります。

$ brew tap homebrew/dupes
$ brew install libxml2 libxslt libiconv
$ brew link --force libxml2
$ brew link --force libxslt

そして、一旦nokogiriだけをインストールしてみる。

gem install nokogiri -- --use-system-libraries

これがうまくいったら、railsをインストールする。

gem install rails -v 4.2.2

RubyのhttpclientでUser-AgentにGemのバージョン情報を入れない方法

Rubyのgemのhttpclientを使うと、Webサイトのスクレイピングなどが簡単に作れます。

以下のようにすることで、リクエスト送信時のUser-Agentも設定できます。

hc = HTTPClient.new('','XXXX')

ただし、これだと実際のHTTPリクエストのUser-Agentには、以下のようにパッケージとRubyのバージョンが追加されてしまいます。

User-Agent: XXXX (2.5.3.2, ruby 2.0.0 (2014-05-08))

これはsessin.rbに以下の様に書かれているためです。

def set_header(req)
  if @requested_version
    if /^(?:HTTP\/|)(\d+.\d+)$/ =~ @requested_version
      req.http_version = $1
    end
  end
  if @agent_name && req.header.get('User-Agent').empty?
    req.header.set('User-Agent', "#{@agent_name} #{LIB_NAME}")
  end

これを防ぎ、期待したUser-Agentだけを記録するには、以下のように default_header 引数として、User-Agentをハッシュで渡します。

hc = HTTPClient.new(default_header: {"User-Agent" => "XXXX"})

こうすることで、期待した文字列のみをUser-Agentとして設定できます。

User-Agent: XXXX


ServersManにrbenvでRubyをインストールする

サーバをさくらレンタルサーバからServersManのVPSに引っ越しました。
VPSということで、必要最低限のソフトしか入っていません。

Rubyを入れるにあたり、rootでグローバルに入れるのではなく、一般ユーザでrbenvで入れることにしました。

環境はCentOS7です。

$ uname -r
2.6.32-042stab092.2
$ cat /etc/redhat-release
CentOS Linux release 7.0.1406 (Core)

rbenvはgitでcloneするので、まずはgit自体をインストールします。
ついでにyumもアップデート。

$ sudo yum update
$ sudo yum install git

そして、rbenvをcloneしてパスを設定します。

$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo ‘export PATH=”$HOME/.rbenv/bin:$PATH”‘ >> ~/.bash_profile
$ echo ‘eval “$(rbenv init -)”‘ >> ~/.bash_profile
$ exec $SHELL -l
$ rbenv -v
rbenv 0.4.0-129-g7e0e85b

続いて、ruby-build をcloneします。

$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

ビルドに必要なgccとopenssl-devlを入れます

$ yum install gcc openssl-devel

そして、インストール可能なバージョンから最新版を確認し、バージョンを指定してインストールします。

$ rbenv install –list
Available versions:
1.8.6-p383
1.8.6-p420
(略)
2.1.4
2.1.5 <- 最新版 $ rbenv install -v 2.1.5

再読み込みします。

$ rbenv rehash
$ rbenv versions
2.1.5

環境全体でのバージョンを指定。

$ rbenv global 2.1.5
$ rbenv global
2.1.5

動作確認。

$ ruby -v
ruby 2.1.5p273 (2014-11-13 revision 48405) [x86_64-linux]

以上で完了です。


さくらのレンタルサーバにRuby 1.9をインストールする

さくらのレンタルサーバに標準でインストールされているRubyは1.8.7です。
そのため、1.9系を使用するには、ホームディレクトリ配下に自分でrubyをインストールすることになります。

ソースをFTPサーバから取得する

% mkdir ~/local
% mkdir~/loca/src
% cd ~/loca/src
% ftp ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p374.tar.gz

コンパイルしてインストールする

% tar zxvf ruby-1.9.3-p374.tar.gz
% cd ruby-1.9.3-p374
% ./configure –prefix=$HOME/local –with-iconv-dir=/usr/local
% make
% make install

パスを設定する

~/.cshrc の set path の先頭に、%HOME/local/bin を追加する

以上で、ruby 1.9が使用可能となります