Class: Dratools::ExternalCommandRunner
- Inherits:
-
Object
- Object
- Dratools::ExternalCommandRunner
- Defined in:
- lib/dratools/external_command_runner.rb
Overview
curl, wget, aria2c のいずれかを使って URL の確認とダウンロードを行うラッパー。
probe は短時間・無出力で済ませ、download は外部コマンドの進捗を端末へ流す。 巨大ファイルを扱うため、download には総時間制限ではなく失速検知を使う。
Constant Summary collapse
- CURL_COMMAND =
'curl'- WGET_COMMAND =
'wget'- ARIA2_COMMAND =
'aria2c'- AUTO_COMMANDS =
[CURL_COMMAND, WGET_COMMAND].freeze
- SUPPORTED_COMMANDS =
[*AUTO_COMMANDS, ARIA2_COMMAND].freeze
- COMMAND_NOT_FOUND_MESSAGE =
'curl または wget が見つかりません'- PREFERRED_COMMAND_NOT_FOUND_MESSAGE =
'指定されたダウンロードコマンドが見つかりません'- UNSUPPORTED_COMMAND_MESSAGE =
'未対応のダウンロードコマンドです'- DEFAULT_PROBE_TIMEOUT_SECONDS =
5- PROBE_BYTE_RANGE =
'0-0'- SINGLE_ATTEMPT_COUNT =
1- CURL_PROBE_OPTIONS =
リダイレクト、HTTP エラー、静かな probe、範囲取得。
['--location', '--fail', '--silent', '--show-error', '--range'].freeze
- CURL_TIMEOUT_OPTION =
probe 全体のタイムアウト。
'--max-time'- CURL_CONNECT_TIMEOUT_OPTION =
'--connect-timeout'- CURL_SPEED_LIMIT_OPTION =
失速判定に使う最低転送速度。
'--speed-limit'- CURL_SPEED_TIME_OPTION =
最低速度を下回ってよい秒数。
'--speed-time'- CURL_RETRY_OPTION =
'--retry'- CURL_OUTPUT_OPTION =
'--output'- CURL_DOWNLOAD_OPTIONS =
部分ファイルがあれば続きから再開。
['--location', '--fail', '--continue-at', '-'].freeze
- WGET_PROBE_OPTIONS =
probe でファイルを保存しない。
['--spider'].freeze
- WGET_TIMEOUT_OPTION =
probe 全体のタイムアウト。
'--timeout'- WGET_CONNECT_TIMEOUT_OPTION =
'--connect-timeout'- WGET_READ_TIMEOUT_OPTION =
wget で失速検知に近い意味で使う。
'--read-timeout'- WGET_TRIES_OPTION =
probe では 1 回だけにする。
'--tries'- WGET_WAITRETRY_OPTION =
'--waitretry'- WGET_CONTINUE_OPTION =
部分ファイルがあれば続きから再開。
'--continue'- WGET_OUTPUT_OPTION =
'--output-document'- ARIA2_PROBE_OPTIONS =
probe で保存せず、通常出力も抑える。
['--dry-run=true', '--quiet=true'].freeze
- ARIA2_CONNECT_TIMEOUT_OPTION =
'--connect-timeout'- ARIA2_TIMEOUT_OPTION =
aria2c で失速検知に近い意味で使う。
'--timeout'- ARIA2_LOWEST_SPEED_LIMIT_OPTION =
curl の --speed-limit に相当する最低転送速度。
'--lowest-speed-limit'- ARIA2_MAX_TRIES_OPTION =
'--max-tries'- ARIA2_RETRY_WAIT_OPTION =
'--retry-wait'- ARIA2_CONTINUE_OPTION =
部分ファイルがあれば続きから再開。
'--continue=true'- ARIA2_DIR_OPTION =
aria2c は保存先をディレクトリとファイル名に分ける。
'--dir'- ARIA2_OUT_OPTION =
'--out'- ARIA2_SINGLE_CONNECTION_OPTIONS =
既定では並列取得しない。
['--split=1', '--max-connection-per-server=1'].freeze
Instance Method Summary collapse
- #available_command ⇒ Object
- #download_url(url, output_path) ⇒ Object
-
#initialize(preferred: Config.download_command) ⇒ ExternalCommandRunner
constructor
A new instance of ExternalCommandRunner.
- #probe_url(url, timeout: DEFAULT_PROBE_TIMEOUT_SECONDS) ⇒ Object
Constructor Details
#initialize(preferred: Config.download_command) ⇒ ExternalCommandRunner
Returns a new instance of ExternalCommandRunner.
74 75 76 |
# File 'lib/dratools/external_command_runner.rb', line 74 def initialize(preferred: Config.download_command) @preferred = preferred end |
Instance Method Details
#available_command ⇒ Object
78 79 80 81 |
# File 'lib/dratools/external_command_runner.rb', line 78 def available_command candidates = @preferred ? [@preferred] : AUTO_COMMANDS candidates.find { |command_name| executable_command?(command_name) } end |
#download_url(url, output_path) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/dratools/external_command_runner.rb', line 109 def download_url(url, output_path) tool = available_command || raise(CommandError, ) command = case File.basename(tool) when CURL_COMMAND # curl の低速検知は「指定秒数のあいだ指定速度を下回ったら失敗」。 # ネットワークが完全に切れず低速で固まるケースを、総時間制限なしで検出する。 # 例: curl --location --fail --continue-at - --connect-timeout 30 # --speed-limit 1024 --speed-time 60 --retry 3 --output OUT URL [tool, *CURL_DOWNLOAD_OPTIONS, CURL_CONNECT_TIMEOUT_OPTION, Config.download_connect_timeout_seconds.to_s, CURL_SPEED_LIMIT_OPTION, Config.download_stall_speed_bytes_per_second.to_s, CURL_SPEED_TIME_OPTION, Config.download_stall_timeout_seconds.to_s, CURL_RETRY_OPTION, Config.download_retry_count.to_s, CURL_OUTPUT_OPTION, output_path, url] when WGET_COMMAND # wget では --read-timeout を失速検知に近い意味で使う。 # --continue は部分ファイルの続きから再開し、--output-document は保存先を固定する。 # 例: wget --continue --connect-timeout=30 --read-timeout=60 # --tries=4 --waitretry=5 --output-document OUT URL [tool, WGET_CONTINUE_OPTION, "#{WGET_CONNECT_TIMEOUT_OPTION}=#{Config.download_connect_timeout_seconds}", "#{WGET_READ_TIMEOUT_OPTION}=#{Config.download_stall_timeout_seconds}", "#{WGET_TRIES_OPTION}=#{download_attempt_count}", "#{WGET_WAITRETRY_OPTION}=#{Config.download_retry_wait_seconds}", WGET_OUTPUT_OPTION, output_path, url] when ARIA2_COMMAND # aria2c は保存先をディレクトリとファイル名に分けて指定する。 # --continue=true は部分ファイルがあれば続きから再開する。 # 例: aria2c --continue=true --split=1 --max-connection-per-server=1 # --connect-timeout=30 --timeout=60 --lowest-speed-limit=1024 # --max-tries=4 --retry-wait=5 --dir DIR --out FILE URL [tool, ARIA2_CONTINUE_OPTION, *ARIA2_SINGLE_CONNECTION_OPTIONS, "#{ARIA2_CONNECT_TIMEOUT_OPTION}=#{Config.download_connect_timeout_seconds}", "#{ARIA2_TIMEOUT_OPTION}=#{Config.download_stall_timeout_seconds}", "#{ARIA2_LOWEST_SPEED_LIMIT_OPTION}=#{Config.download_stall_speed_bytes_per_second}", "#{ARIA2_MAX_TRIES_OPTION}=#{download_attempt_count}", "#{ARIA2_RETRY_WAIT_OPTION}=#{Config.download_retry_wait_seconds}", "#{ARIA2_DIR_OPTION}=#{File.dirname(output_path)}", "#{ARIA2_OUT_OPTION}=#{File.basename(output_path)}", url] else unsupported_command!(tool) end run_streaming(command) end |
#probe_url(url, timeout: DEFAULT_PROBE_TIMEOUT_SECONDS) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/dratools/external_command_runner.rb', line 83 def probe_url(url, timeout: DEFAULT_PROBE_TIMEOUT_SECONDS) tool = available_command || raise(CommandError, ) # 巨大ファイルを落とさないよう、短時間・最小範囲の確認に留める。 command = case File.basename(tool) when CURL_COMMAND # 例: curl --location --fail --silent --show-error --range 0-0 # --max-time 5 --output /dev/null URL [tool, *CURL_PROBE_OPTIONS, PROBE_BYTE_RANGE, CURL_TIMEOUT_OPTION, timeout.to_s, CURL_OUTPUT_OPTION, null_device, url] when WGET_COMMAND # 例: wget --spider --timeout=5 --tries=1 URL [tool, *WGET_PROBE_OPTIONS, "#{WGET_TIMEOUT_OPTION}=#{timeout}", "#{WGET_TRIES_OPTION}=#{SINGLE_ATTEMPT_COUNT}", url] when ARIA2_COMMAND # 例: aria2c --dry-run=true --quiet=true --connect-timeout=5 --timeout=5 --max-tries=1 URL [tool, *ARIA2_PROBE_OPTIONS, "#{ARIA2_CONNECT_TIMEOUT_OPTION}=#{timeout}", "#{ARIA2_TIMEOUT_OPTION}=#{timeout}", "#{ARIA2_MAX_TRIES_OPTION}=#{SINGLE_ATTEMPT_COUNT}", url] else unsupported_command!(tool) end run_quietly(command) end |