Rubyでsambal を使ってデータを取得する
仕事でsambaにアクセスして自動でデータを取ってくるツールを作ることがあったので、その記録をしていきます。
以下サイトが大変参考になりました。
Ruby から Windows の共有フォルダにアクセスする - akishin999の日記
sambalライブラリ
今回はRubyでsambalというライブラリを使って実現しました。そもそもsambaアクセスがどのように出来るかは以下のサイトがわかりやすいです。
実践初級ITブログ LinuxからWindowsの共有ドライブにアクセス(smbclientコマンド)
samba-clientのインストール
sambalはsamba-clientをラッパーしているようなのでまずはsamba-clientをインストールします。
yum install -y samba-client
sambalのインストール
Gemでsambalのインストールを行います。
bundle init
Gemfileが生成されるのでgem 'sambal'と記載してbundle installします。
これにて事前準備完了です。
sambalのコマンド
sambalのコマンドについては下記で公開されています。今回使用したものについて説明します。
GitHub - akishin/sambal: Ruby Samba Client
Sambal::Client.new: インスタンスの生成
client = Sambal::Client.new(host: host, share: dir, user: user, password: pass)
まず何をするにしてもこれが必要になります。これでclientオブジェクトを生成することで下記のコマンドが使えるようになります。
client.ls : ディレクトリのファイル一覧を取得
puts client.ls
このコマンドの戻り値から以下のような情報が取得できます。
- type => ファイル or ディレクトリ
- size => ファイルサイズ
- modified => 更新日
puts client.ls { "data"=>{ :type=>:directory, :size=>"0", :modified=>2018-06-25 14:26:53 +0900}, "test.zip"=>{ :type=>:file, :size=>"7331462", :modified=>2018-06-25 14:17:24 +0900}, "IMG_0217.mp4"=>{ :type=>:file, :size=>"2042582", :modified=>2018-06-25 11:51:09 +0900}, }
データの取り出し方サンプル
info = client.ls info.each do |key, data| if((data[:type].to_s == "file") && (data[:size] != 0)) then #ファイルを取得 client.get(key.to_s, "hoge.mp4") end end
keyには例でいうdataやtest.zip,IMG_0217.mp4が入ってきます。
そしてdataからハッシュで:typeや:size,:modifiedの中身を取り出すことができます。
client.get: sambaからデータを取得する
実際にsambaからデータを取得する際に使うコマンドです。第一引数にはそのファイル名(path)をいれ、第二引数には取得後のファイル名をいれます。
client.get("remote_file.*", "local_file.*")
ここで注意しなければならないのは、あくまでダウンロードできるのはファイルだけということです。
いろいろと調べたのですが、おそらくフォルダごとダウンロードすることはできなさそうです。そのためフォルダごとダウンロードしたい場合は、自分で再帰処理を作ってダウンロードしなければなりません。
client.close :終了処理
これもお作法で最後にcloseしてインスタンスを破棄します。
sambalを使ってデータを取ってくる
ここからが本題のデータ取得方法についてです。今回は下記のようなディレクトリ構成になっている想定でやっていきます。
例として、ファイル実行時に取ってきたいファイルの日付を入力するとそのフォルダの中のテキストファイルを取ってくるようにします。
ソースコードsample
# download_samba.rb require 'yaml' require 'date' begin # config情報取得 config = YAML.load_file("config.yml") host = config["user"]["host"] dir = config["user"]["dir"] user = config["user"]["user_id"] pass = config["user"]["pass"] # SambaClient open client = Sambal::Client.new(host: host, share: dir, user: user, password: pass) puts " When will you get a data?(YYYYMMDD):" date = STDIN.gets.chomp # データ取得後のファイル格納フォルダをsystem関数を使って作成 # 日付と日時から生成 now = Time.now output_fld = now.strftime('%Y%m%d_%H%M%S') system("mkdir " + output_fld) puts "******** Download Start ********" # download file ret = download_file(client, date, output_fld) puts "******** Download End ********" client.close end #---------------------------------------------- # module : ダウンロード処理 # function name : download_file() # input : client => samba client object # input : date => YYYYMMDD # input : wk_fld => work directory path #---------------------------------------------- def download_file(client, date, wk_fld) # samba(data/YYYYMMDD)にあるファイル一覧を取得 client.cd "data" client.cd date dir_info = client.ls # Download dir_info.each do |key, data| if((data[:type].to_s == "file") && (data[:size] != 0)) then # ファイルを取得 client.get(key.to_s, "./" + wk_fld.to_s + "/" + key.to_s) end end return end
※ruby初心者のため誤っていたり、もっと良い書き方があるかもしれません。
またブログ用に修正しており、このまま実行するとエラーが出るかもしれません。
configファイル
# download_samba.rb require 'yaml' begin # config情報取得 config = YAML.load_file("config.yml") host = config["user"]["host"] dir = config["user"]["dir"] user = config["user"]["user_id"] pass = config["user"]["pass"]
# config.yml user: host: example.co.jp dir: data user_id: hoge pass: hogehoge
今回はチーム内に展開する想定だったためログインのためのconfig情報を外に出して、変更出来るようにしました。
Rubyでyaml形式の設定ファイルを用意して、値を取得する - Code Log
ポイント client.ls
やはりディレクトリ内のファイル情報の扱い方(client.ls)がポイントとなると思います。下記のようにファイル種別が"file"のみを取得して、フォルダ内のフォルダ以外のファイルをすべてダウンロードします。
dir_info = client.ls # Download dir_info.each do |key, data| if((data[:type].to_s == "file") && (data[:size] != 0)) then # ファイルを取得 client.get(key.to_s, "./" + wk_fld.to_s + "/" + key.to_s) end end
最後の一言
今回はrubyによるsambalライブラリを使ってsambaにアクセスすることができました。
sambalに関する情報が意外と調べてもなかったので、今後使いたい人の手助けになれば幸いです。