スポンサーサイト

Tags :
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

InDesignでSocketを使ってWeb上のファイルをローカルにダウンロードしてみる

やってみたら出来てしまったので。

InDesignのみでWebにある画像等のファイルをローカルに保存出来れば色々と出来る事が広がるんじゃないか、と思ったのでやってみました。業務等でもっとちゃんとした事やるにはWeb Access libraryに含まれるHttpConnectionオブジェクトを使って書いた方が良いと思いますが、セットアップする必要がある様だし、もっとお手軽にコピペで使えるようなもの、みたいな感じで。

今回のコードは、HTTPのリクエストを送ってレスポンスを受け取る部分と、その関数を呼び出して実際にファイルとして保存する部分とに分かれてます。

HTTPのリクエストを送って、レスポンスを受け取る部分は、関数getHttpResponse(requests)として書きましたが、これは先日のエントリのHTTPでのやり取りをするコードに、
・画像等のバイナリデータを受け取れるようにする
・Basic認証が必要なサイトに対してユーザ名とパスワードを送れるようにする
部分を新たに加えました(相変わらずOOPな書き方が全く出来てませんけど)。URLを処理する部分の正規表現はO'REILLYの『JavaScript: The Good Parts』から拝借しています。

この関数には引数を
{
	method: 'GET', 
	url: 'http://www.example.com/hogehoge.jpg',
	encoding: 'BINARY'
	basic_auth: 'ZHVtbXk6ZHVtbXk='
}
の様な連想配列で渡します。

引数の内容は以下の通り
・method リクエストのメソッド 'GET','HEAD','POST'等。省略可。デフォルトは'GET'。
・url リクエストのURL(クエリも全て含んだもの)
・encoding 受け取るデータのエンコーディング。省略可。デフォルトは'UTF-8'。
・basic_auth Basic認証に必要な、『ユーザ名:パスワード』の文字列をBase64でエンコーディングした文字列。Basic認証が必要な場合のみこの引数を与える。

この関数は戻り値として、サーバからのレスポンスをヘッダ付きのまま丸ごと返します。値のチェックは最低限の事しかやってないので変な引数を渡すと動作しません。

そして、上記の関数を呼び出してファイルに書き出し、保存する部分の関数、downloadFile(url, localFile)ですが、これの引数は、
・url ダウンロードしたいファイルのURL
・localfile ローカルでのファイル名を含めたファイルのパス('~/Desktop/hogehoge.jpg'等)
となっていて、戻り値として保存したファイルオブジェクトか返ります。

下のコードを実行すると、AdobeのサイトのCS4のパッケージ画像(http://tryit.adobe.com/jp/cs4/family/images/familyBox.jpg)がデスクトップに保存されます。(保存されるファイルのパスはMacOSX用の記述です)


■2009.3.19 追記
コードを一部修正。

■動作確認
MacOSX 10.5.6
InDesign CS4
#target InDesign

//HTTPレスポンスを得る
function getHttpResponse(requests) {
	var parseUrl = function(url) {
		var urlObj = {};
		//[url, scheme, slash, host, port, path, query, fragment] via O'REILLY JavaScript: The Good Parts
		var url_re = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
		var m = url_re.exec(url);
		urlObj.host = m[3];
		urlObj.port = m[4] || '80';
		urlObj.path = m[5];
		urlObj.query = (m[6]) ? '?' +  m[6] : '';
		urlObj.frag = (m[7]) ? '#' + m[7] : '';
		return urlObj;
	}
	var urlObj = parseUrl(requests.url);
	var encoding = requests.encoding || 'UTF-8';
	var method = requests.method || 'GET';
	var auth = (requests.basic_auth != undefined) ? 'Authorization: Basic ' + requests.basic_auth + '\r\n' : '';
	var conn = new Socket;
	conn.timeout = 10;
	if (conn.open (urlObj.host + ':' + urlObj.port, encoding)) {
  	conn.write (method + ' /' + urlObj.path + urlObj.query + urlObj.frag + ' HTTP/1.0\r\n'
		+ 'Host: ' + urlObj.host + '\r\n'
		+ 'User-Agent: ' + 'InDesign/6.0' + '(Macintosh; U; Intel Mac OS X 10_5_6; ja-jp)' + '\r\n'
		+ auth
		+ '\r\n');
		var reply = conn.read(999999);
		conn.close();
		return reply; //ヘッダ込みで返す
	} else {
		return conn.error;
	}
}

//Webからファイルをダウンロードする
function downloadFile(url, localFile) {
	var rep = getHttpResponse({
		method: 'GET',
		url: url,
		encoding: 'BINARY',
	});
	if (rep.match(/HTTP.*\d{3}/).toString().indexOf('200') != -1) {
		//レスポンスのヘッダを除去 
		var body = rep.slice(rep.indexOf('\r\n\r\n') + 4);
		//ファイルに書き出し
		var f = new File(localFile);
		if (f.open("w")) {
			f.encoding = 'BINARY';
			f.write(body);
		}
		f.close();
		return f;
	} else {
		return false;	
	}
}

var f = downloadFile('http://tryit.adobe.com/jp/cs4/family/images/familyBox.jpg', '~/Desktop/familyBox.jpg');
if (f) {
	alert(f.name + ' を保存しました。');
}
関連記事
スポンサーサイト

コメント

非公開コメント

Profile
choco
Author : choco

印刷・製版の現場を経て、広告制作会社でPhotoshopを使ったビジュアル制作を担当。

→現在は車載機器開発ベンダにて、組み込み3Dデータ作成やUIデザインなどを行っています。

Categories
Favorites


Search
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。