wget.js ― 2008年06月11日 03時54分48秒
wget.js
まったくもってくだらんと思うが、コマンドライン引数でURL渡すとローカルに保存するコンソールスクリプト。なんで作ろうとしたのか忘れたけど、なんか作ってみたので載せてく。
ソース
※:同じローカルファイル名で上書きできないバグを修正しました(08.06.13)
※:この記事のコメント欄でhATrayfloodさんからContent-Disposition対応ソースのURLを教えていただきました。ソースはこちら(JSファイル直リン)。(11.08.25)
以下のソースをコピーして「wget.js」とでもつけてローカルに保存するか、これを名前をつけて保存。
依存ライブラリは一切なし。ライセンスはNYSLね。
var fso = new ActiveXObject("Scripting.FileSystemObject");
var shell = new ActiveXObject("WScript.Shell");
// コマンドライン引数の取得
var args = new function() {
var args = WSH.Arguments, result = [];
for(var col = new Enumerator( args ); ! col.atEnd(); col.moveNext()) {
result[ result.length ] = String( col.item() );
}
var named = {};
for(var col = new Enumerator( args.Named ); ! col.atEnd(); col.moveNext()) {
named[ String( col.item() ) ] = String( args.Named.Item( col.item() ) );
}
var unnamed = [];
for(var col = new Enumerator( args.Unnamed ); ! col.atEnd(); col.moveNext()) {
unnamed[ unnamed.length ] = String( col.item() );
}
result.named = named;
result.unnamed = unnamed;
result.toArray = function() {
var result = [];
for(var i = 0, l = this.length; i < l; i++) {
result[ i ] = /((^".*"$)|(^'.*'$))/.test( this[i] ) ?
this[i] : [ '"', this[i], '"' ].join("");
}
return result;
};
result.toString = function() {
return this.toArray().join(" ");
};
return result;
}();
// cscriptで強制起動
if( /wscript\.exe$/i.test( WSH.FullName ) ) {
shell.Run( [
"cscript",
/((^".*"$)|(^'.*'$))/.test( WSH.ScriptFullName ) ? WSH.ScriptFullName : [ '"', WSH.ScriptFullName, '"' ].join(""),
args
].join(" ") );
WSH.Quit();
}
// ユーティリティ関数定義
var echo = function(s) {
print( [ s, "\n" ].join("") );
}
var print = function(s) {
WSH.StdOut.Write( s || "" );
}
var input = function() {
if( arguments[0] ) print( arguments[0] );
print( ">" );
return WSH.StdIn.ReadLine();
}
var nameFromUrl = function(url) {
var parts = url.split( /[\\\/]/g );
var f = parts[parts.length - 1];
f = f.replace( /[\\\/:,;\*\?"<>\|]/g, "_" );
parts[parts.length - 1] = f;
return f;
}
Error.prototype.toString = function() {
return this.description || this.message || this.number || this;
}
if( ! args.length || /^\/(\?|(help))/i.test( args[0] ) ) {
// 引数がないか、ヘルプスイッチが指定された場合は使い方を表示して終了
echo( "使い方 : [cscript | wscript] wget.js [ ]" );
echo( "オプション : " );
echo( " アクセスするインターネットリソースのURL" );
echo( " 保存先ファイルパス。省略時はURLのファイル名と" );
echo( " 同じ名前でカレントディレクトリに保存" );
echo();
input( "Enter キーで終了します" );
} else {
// メイン処理
var url = args.unnamed[0], fileName = args.unnamed[1] || nameFromUrl(url);
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
xhr.open( "get", url, true );
var completed = false;
xhr.onreadystatechange = function() {
print( "." );
if( xhr.readyState < 4 ) return;
echo();
try {
var headers = (function(headers) {
var result = {}, lines = headers.split( /((\r\n)|\r|\n)/g );
for(var i = 0, l = lines.length; i < l; i++) {
var matches = /^([^:]+): (.*)$/.exec( lines[i] );
if( matches ) result[ matches[1].toLowerCase() ] = matches[2];
}
return result;
})( xhr.getAllResponseHeaders() );
echo( [ "ファイルサイズ : ", headers[ "content-length" ] || "不明" ].join("") );
var stream = new ActiveXObject("ADODB.Stream");
stream.Open();
stream.Position = 0;
stream.Type = 1;
stream.Write( xhr.responseBody );
stream.SaveToFile( fileName, 2 ); // adSaveCreateOverWrite
echo( "完了" );
} catch(e) {
echo( e );
} finally {
if( stream ) {
try { stream.Close(); } catch(ie) {}
}
}
completed = true;
}
print( [ "url '", url, "' に接続中..." ].join("") );
xhr.send();
while( ! completed ) {
WSH.Sleep( 50 );
}
}
使い方
コマンドラインからcscript経由で使う。別にwscriptでもいいけど。
んで、カレントにwget.jsがあるとして、「http://server.domain/path/to/file.zip」をダウンロードするには
C:\wget_js>cscript wget.js http://server.domain/path/to/file.zip Microsoft (R) Windows Script Host Version 5.6 Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. url 'http://server.domain/path/to/file.zip' に接続中... ファイルサイズ:1024 完了 C:\wget_js>なんて感じ。
保存時のファイル名を指定したい場合は第二引数を使う。
C:\wget_js>cscript wget.js http://server.domain/path/to/file.zip myfile.zip Microsoft (R) Windows Script Host Version 5.6 Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. url 'http://server.domain/path/to/file.zip' に接続中... ファイルサイズ:1024 完了 C:\wget_js>て具合。保存先は当然パス指定もOK。
あとは
@echo off cscript //nologo C:\wget_js\wget.js %*みたいなバッチファイルを%SystemRoot%にでも入れとけばそこはかとなくwget風。
仕組みとか注意点とか
Microsoft.XMLHTTPでURLにアクセスして、受信したresponseBodyをそのままADODB.Streamに喰わせて保存してるだけ。
こんな乱暴なアプローチなので、いきおいすべてのデータをメモリ上で取り扱う構造なので、大きいファイルをこれで落とそうなんてしないほうがよいかと。あと、ftpでコケたときあったなー。XHRがエラー吐きやがるの。
あ、あとURLにfile://~とかやるとコピーコマンド代わりになるとか。まったく意味ないけど。
作ったはいいけど、自分でも使わなそうだなー。

最近のコメント