Ruby Mechanize wiki (ja) - Mechanize::Form::FileUpload

Mechanize::Form::FileUpload


ファイルアップロード欄を表現するクラスです。

<form name="upload_test">
<input type="file" name="upfile" enctype="multipart/form-data">
</form>

Mechanize::Form#file_upload_with でアップロード欄を選択できます。
#file_name= メソッドでファイル名を「参照」させることができ、送信時に指定のファイルから実際に読み込んでデータを送信します。

通常の Web ブラウザは「参照ボタンで提示されたファイルを読み取ってファイルタイプとファイル内容とファイル名を確定して3つとも送信する」という動作を行います。Mechanize でこれを行うのは #file_name= です。
# 画像をアップロードその1
page.form_with(:name => 'upload_test').file_upload_with(:name =>'upfile').file_name = './hoge.jpg'

Ruby 上の文字列を送信したい場合は #file_data= でファイル内容を指定することもできます。ただし、ファイルタイプとファイル名が送られない不審なものになるので、極力 #file_name=#mime_type=)を併用することをお勧めします。
# 画像をアップロードその2
page.form_with(:name => 'upload_test').file_upload_with(:name =>'upfile'){|up|
  up.file_data = File.open('/tmp/resized_output','rb'){|f| f.read}
  up.mime_type = 'image/jpeg'
  up.file_name = '0001.jpg' # サーバに見せるためだけの文字列
}

Mechanize::Form::Field をいちおう継承しています。



Mechanize::Form::FileUpload オブジェクトを生成します。ユーザーが使用することはありません。

このアップロード欄の名前を返す #name メソッドの返り値を文字列 str に変更します。
Mechanize::Form::Field#name= を参照してください。

このアップロード欄の name 属性の値を文字列で返します。
Mechanize::Form::Field#name= を参照してください。
<input type="file" name="upfile" size="35">
という HTML で表されるアップロード欄オブジェクトだった場合、name メソッドは upfile を返します。

アップロード内容の本文(ファイル本体そのもの)を設定します。#file_data= はこのメソッドのエイリアスです。

アップロード内容の本文(ファイル本体そのもの)を返します。#file_data はこのメソッドのエイリアスです。

このアップロード欄の HTML ノードを返す #node の返り値を node_obj に変更します。
Mechanize::Form::Field#node= を参照してください。

このアップロード欄オブジェクトを作成したときに使用した HTML ノードを返します。
Mechanize::Form::Field#node を参照してください。

HTML 上での出現位置を引数のオブジェクトと比較し、sort 可能な答を返します。
Mechanize::Form::Field#<=> を参照してください。

アップロードするファイルのパスを文字列で設定します。
引数の path は文字列です。File.open できる文字列を指定してください。通常の Web ブラウザの「参照...」ボタンからのファイル指定動作に似ています。
送信実行時にファイル本文としてバイナリモードで読み込まれ、パスの basename が送信ヘッダ Content-Disposition: 内の filename= トークンとして使用され、拡張子から送信文字列内の Content-Type 行が推測され記述されます。
ただし、既に #file_data= メソッドでファイル本文が設定されていた場合は「参照先」としては機能せず、filename= トークンとしての名称の使用のみが行われます。

送信文字列内の Content-Type 行(送信ヘッダの Content-Type: ヘッダは Mechanize::Form#enctype で別物)の 推測は、引数 path 末尾の拡張子によって文字処理的に行われます(たとえば、hoge.jpg だったら Content-Type: image/jpeg)。推測不能だった場合は Content-Type: application/octet-stream という行が送信文字列に含まれます。#mime_type の値は使用されないので注意してください(これは #file_data= 専用です)。直接指定する方法がないので、処理する拡張子を増やしたい場合は WEBrick::HTTPUtils::DefaultMimeTypes の Hash に拡張子と Content-Type のペアを追加します。
# 拡張子 .rar は rar のファイル
WEBrick::HTTPUtils::DefaultMimeTypes['rar'] = 'application/rar'
agent.page.form(:name => 'upform'){|f|
  f.file_upload(:name => 'up'){|up|
    up.file_name = '1277337978.rar'
  }
}
具体的にどんな拡張子が対応しているかは WEBrick::HTTPUtils::DefaultMimeTypes のソースを見てください。

アップロードするファイルのパスを文字列で返します。
デフォルトは nil です。filename に関する HTML 上の初期値は反映されません。
通常、#file_name= によってユーザーが指定します。

送信ヘッダではなく、リクエスト文字列に含まれるほうの Content-Type 行の値を指定します。
#file_data= でファイル内容を直接指定したときにのみ有効です。送信に際して一時的にどう変換されるかではなく、オリジナルデータのファイルタイプ(image/jpeg 等)を指定してください。#file_name= で「参照」したときはパスの拡張子で決まり、このメソッドの値は使用されません。ここで設定しなかった場合には、#file_data= で本文を指定しても送信文字列内に Content-Type 行は記載されません。
送信ヘッダの Content-Type: はこれとは無関係に HTML に書かれていた Mechanize::Form#enctype(または Mechanize#post 等の追加ヘッダ)で決まります。

送信ヘッダではなく、リクエスト文字列に含まれるほうの Content-Type 行の値を返します。
ユーザーが #mime_type= で設定した値を返します。デフォルトは nil です。#file_name= でファイルパスを指定したときに Content-Type 行としてどんな文字列が使用されるかはこのメソッドからはわかりません。

アップロード内容の本文(ファイルそのもの)を返します。
デフォルトは nil で、#file_data= で設定された文字列かオブジェクトがあればそれがそのまま返ります。

アップロード内容の本文(ファイルそのもの)を設定します。
通常の Web ブラウザの「参照...」ボタンを押してファイルを指定したときの送信データとは違い、ファイル名に相当する部分と mimetype に相当する部分が送信されません。通常の Web ブラウザの動作と同一にしたい場合は #file_name= でファイル名を、#mime_type= でファイルタイプを指定する必要があります。
agent.page.form_with(:name => 'f1'){|form|
  form.file_upload_with(:name => 'upfile'){|up|
    up.file_data = File.open('./data/output.dat'){|f| f.read}
    up.mime_type = 'image/jpeg'
    up.file_name = 'hoge.jpg'
  }
}
最初から #file_name= だけで読みたいファイルのパスを(拡張子つきで)指定した場合はこれらの処理は不要で、通常の Web ブラウザでの動作と同じになります。
引数の str_or_readable は文字列か、read メソッドが可能なオブジェクトです。read がいわゆるバイナリモードで行われるかどうかは read の実装依存です(Ruby1.8のFileは駄目、Ruby1.9のFileはOK)。実際に post されるときに read されます。
#value= はこのメソッドの本体です。