Memoize

BasicWerk   EC Support   Technique   Facebook  

20140614111235_factor_http_download_recover

factor_http_download_recover

 

例えば複数の画像URLが含まれているリストを元にダウンロードしようとしたとき、リスト中のいずれかがエラー(404 Not Found など)になると、HTTP request failed エラーが throw されてそこで止まってしまう。

 
IN: scratchpad auto-use USE: http.client
 
! include Bad request
! "http://basicwerk.com/image/bw_SSxxxxx.png" is not exist.
IN: scratchpad auto-use { "http://basicwerk.com/image/bw_SSxxxxx.png" "http://basicwerk.com/image/bw_SS.png" }
 
IN: scratchpad auto-use [ >url download ] each
HTTP request failed:
 
T{ response
    { version "1.1" }
    { code 404 }
    { message "Not Found" }
    ...
}
 
Type :help for debugging help.
 
--- Data stack:
{ "http://basicwerk.com/image/bw_SSxxxxx.png"...
 

 

recover で囲ってみると、

 
IN: scratchpad auto-use [ >url [ download ] [ ] recover ] each
 
--- Data stack:
URL" http://basicwerk.com/image/bw_SSxxxxx.png"
T{ download-failed f ~response~ }
 

 

ダウンロードが失敗すると download-failed という Tuple が返されていることが分かる。

download-failed? というエラーチェックワードがあるのでこれを利用しよう。

それと、いきなり download だと、失敗している場合でも同名のファイルがローカルに作られてしまう。

これを回避するために、以下の手順にしてみる。

 

  1. 一度 http-head でファイルの存在を確認する。
  2. エラーが投げられて download-failed? が t なら、以降の if の為に f を残す。
  3. recover を通過した後、ヘッダー情報の Tuple が TOS にあれば t に評価される -> download

 

コードに直すとこんな感じ。

 
! list
IN: scratchpad auto-use { "http://basicwerk.com/image/bw_SSxxxxx.png" "http://basicwerk.com/image/bw_SS.png" }
 
--- Data stack:
{ "http://basicwerk.com/image/bw_SSxxxxx.png"...
 
IN: scratchpad auto-use
    [ >url dup 
        [ http-head ] [ download-failed? not ] recover 
        [ drop download ] [ 2drop ] if 
    ] each
 

 

これで実際には 404 になる画像はスルーされて each が続行し、200 の画像はちゃんとダウンロードされる。

 

http://docs.factorcode.org/content/word-recover%2Ccontinuations.html

http://docs.factorcode.org/content/vocab-http.client.html

http://docs.factorcode.org/content/word-download-failed__que__%2Chttp.client.html

 


© Shin Nakamura/BasicWerk 2014