パッシブモードの時の対応を考えていなかったので改良版公開。ご指摘ありがとうございます。PASVモードなサーバを知らないので実際に動作するかは謎ですが、問題ないはずです。
ルートディレクトリだとうまく動かない問題もついでに対応しました。
今のところ、全てASCIIモードで転送しているので画像ファイルとかは送信しない方が無難です。次のバージョンアップの時に拡張子に合わせて動くようにする予定。
// +----------------------------------------------------------------------+
// | QuickFTP 2004-10-07T14:45:24Z |
// +----------------------------------------------------------------------+
// | Require BASP21 DLL - http://www.hi-ho.ne.jp/babaq/basp21.html |
// +----------------------------------------------------------------------+
// | Distributed at http://www.arielworks.net/ |
// +----------------------------------------------------------------------+
/* Settings ============================================================ */
// "Local Folder" : ["FTP Server", "Account", "Password", "Remote Root Directory", PASV mode]
var DirMap = {"D:\\SERVERS\\HTTP\\ishikawa" : ["s91.xrea.com", "arielworks", "********", "/public_html/ishikawa.arielworks.com", false],
"D:\\SERVERS\\HTTP\\web" : ["s91.xrea.com", "arielworks", "********", "/public_html/www.arielworks.net", false]};
/* ===================================================================== */
var CurrentPath = WScript.Arguments.Item(0);
// sort PathMap (transform into 2D(3D) array)
var DirMap = sortObjectByKeyLength(DirMap);
// select connection setting
var pos;
var ifExist = false;
for (pos in DirMap) {
var CurrentPathRE = new RegExp("^" + DirMap[pos]["Key"].replace(/\\/g, "\\\\") + (DirMap[pos]["Key"].match(/\\$/) ? "" : "\\\\")); // escape \ (\ -> \\)
if (CurrentPathRE.test(CurrentPath)) {
var Server = DirMap[pos]["Value"][0];
var User = DirMap[pos]["Value"][1];
var Pass = DirMap[pos]["Value"][2];
var lRoot = DirMap[pos]["Key"].replace(/\\$/, "");;
var rRoot = DirMap[pos]["Value"][3].replace(/\/$/, "");;
var bPASV = DirMap[pos]["Value"][4];
ifExist = true;
break;
}
}
if (!ifExist) {
WScript.Echo("Error: Invalid File Path");
WScript.Quit();
}
// Put File
var FTP = new ActiveXObject("basp21.FTP");
if (!FTP.Connect(Server, User, Pass)) {
if (bPASV) {
FTP.Command("pasv");
}
// C:\HTTP\LocalDocRoot\hoge\index.html -> C:\HTTP\LocalDocRoot\hoge -> \hoge -> /hoge
var lRootStripEX = new RegExp("^" + lRoot.replace(/\\/g, "\\\\")); // escape \ (\ -> \\)
var SC = FTP.PutFile(CurrentPath, rRoot + CurrentPath.replace(/\\[^\\]*?$/, "").replace(lRootStripEX, "").replace(/\\/g, "/"));
if (SC != 1) {
WScript.Echo("Error: FTP Transfer Error\n\"" + FTP.GetReply() + "\"");
FTP.Close();
WScript.Quit();
}
} else {
WScript.Echo("Error: FTP Connection Error\n\"" + FTP.GetReply() + "\"");
WScript.Quit();
}
FTP.Close();
WScript.Echo("SUCCESS");
WScript.Quit();
function sortObjectByKeyLength(obj)
{
var result /*: obj*/ = new Array();
var key /*: String*/;
for (key in obj) {
var Unit /*: obj*/ = new Array();
Unit["Key"] = key;
Unit["Value"] = obj[key];
result.push(Unit);
}
result.sort(_sortObjectByKeyLengthCompare);
return result;
}
function _sortObjectByKeyLengthCompare(a, b)
{
return b["Key"].length - a["Key"].length;
}
いやー、それにしもWSHは便利ですね。EmFTPをわざわざ使うより「ブラウザからローカルファイル表示 -> 編集してアップロード」の方が全然速いです。ExplorerもFFFTPも起動しないですむのでものすごく楽ちん。
個人的な話ですが、Photoshopの「Web用に保存」と同じCtrl+Shift+Alt+sにバインドしなおしました。統一が取れてるほうがよさげ。
そろそろ「Articles」のほうにまとめて移したほうがいいかな。
設定ファイル外のURIなのに間違えてブックマークレットを押してしまったときは「Firefoxのソースの表示を任意のエディタで」を参考にして、普通にソースを開いた方が便利かも。
改造してみよう。
OOP以前にサブルーチン化もしていなかったのでちょっと書き換えが面倒になった。
興味はPHPでWSHの方に移っていて、どうやったら巧くいくかで悩み中。RubyやPerlでも動くならPHPでも何とかならないかなぁ、と思ったのだが、スクリプトエンジンが無い、と怒られた。レジストリを参照してスクリプトエンジンを選んでいるようなのだけども、php.exeはだめらしい。
しかし、Windows版PHPではCOMが使えるので、WScript.Shellなどは普通に呼び出せる。ということは、「WScript」を呼び出せればほぼWSHそのものと言えそうなのだけど、どう呼び出せばいいのかがわからない。WScript->Echo()が使いたいのに。
というか、考えてみればWSH上でPHPを走らせなくてもphp.exeだけで良い様な気もする。JScriptみたいに言語それ自身が組み込み関数(ファイルシステムへのアクセスとか)を持たない場合以外は必要ないような。考えてみるとJScriptは外部からオブジェクトをもらわないと何も出来ない言語なわけで、それ故にWSH上で走らせる必要があるんだったり。
WSHのおいしさは「Windows上ならどこでも動くぜ」という点なので、標準以外のスクリプトエンジンを要求してしまうと、それだけで存在意義が怪しくなる気もする。
やっぱし無難にJScriptで書いた方がいいっぽいな。