いかにしておっぱい画像をダウンロードするか~2012 Dart編
(こんなこと書いてブログのカテゴリ変わったりしないよね?ね?)
元凶
いかにしておっぱい画像をダウンロードするか〜2012 - ゆーすけべー日記いかにしておっぱい画像をダウンロードするか〜2012 Haskell編 - 厨二病患者のプログラミング入門
D言語でいかにしておっぱい画像をダウンロードするか〜2012 — Gist
いかにしておっぱい画像をダウンロードするか〜2012 をC#で書きました - モデラート - C#とゲーム開発と雑記
そんなわけで
最近流行り(ステマ)のDartで書けないかなーと試してみました!背徳感がすごいですね!所々エラー処理は省きました。
(DartEditor build5759、Server applicationで動かせます。dataフォルダの作成と、Bing APIのAppIdの設定を忘れずに~)
(追記)
これもっとDartらしいコードにして欲しいですね > yutopp.hateblo.jp/entry/2012/03/…
— Mr. Fiberさん (@repeatedly) 3月 23, 2012
こうですか、分かりません><
#import("dart:io"); #import("dart:uri"); #import("dart:utf",prefix:"utf"); #import("dart:json"); class Url { static String encodeUtf8(final String src) => _encode(src, (s)=>utf.encodeUtf8(s)); static String _encode(final String rawSrc, List f(final String)) => new String.fromCharCodes((final List src, List dst) { src.forEach( (c) => dst.addAll( ((c >= 65/*'A'*/ && c <= 90/*'Z'*/) || (c >= 97/*'a'*/ && c <= 122/*'z'*/) || (c >= 48/*'0'*/ && c <= 57/*'9'*/) || c == 45/*'-'*/ || c == 95/*'_'*/ || c == 46/*'.'*/ || c == 126/*'~'*/) ? [c] : [37/*%*/, c.toRadixString(16).charCodes()[0], c.toRadixString(16).charCodes()[1]] ) ); return dst; }(f(rawSrc), new List()) ); } void main() { final String baseDir = "data"; final String AppId = "~ここにAppIdを入力~"; final int perDownloadNum = 10; final int maxDownloadNum = 50; final String word = "おっぱい"; int downloadedCount = 0; for (int i=0; i<maxDownloadNum/perDownloadNum; ++i) { final String queryString = (Map<String, String> q) { StringBuffer sb = new StringBuffer(); q.forEach((k,v) => sb.add("${k}=${v}&")); return sb.toString().substring(0, sb.length - 1); }({ "AppId" : AppId, "Version" : "2.2", "Markert" : "ja-JP", "Sources" : "Image", "Image.Count" : "${Math.min(maxDownloadNum-i*perDownloadNum, perDownloadNum)}", "Image.Offset" : "${i*perDownloadNum}", "Adult" : "off", "Query" : Url.encodeUtf8( word ) }); final client = new HttpClient().getUrl(new Uri(scheme: "http", domain: "api.bing.net", path: "/json.aspx", query: queryString)); client.onResponse = (HttpClientResponse res) { StringBuffer resStringBuf = new StringBuffer(); res.inputStream.onData = () => resStringBuf.add(new String.fromCharCodes(res.inputStream.read())); res.inputStream.onClosed = () => JSON.parse(resStringBuf.toString())["SearchResponse"]["Image"]["Results"].forEach((v) => ((Uri path) => new HttpClient().getUrl(path).onResponse = (HttpClientResponse r) { try { final ext = const RegExp(@"\w+$").firstMatch(r.headers["content-type"])[0]; if (ext == "jpeg" || ext == "png" || ext == "gif") { final String filename = const RegExp(@".+/(.+?)\..+$").firstMatch(path.toString())[1]; final File file = new File("$baseDir/$filename.$ext"); final fileStream = file.openOutputStream(); r.inputStream.pipe(fileStream); r.inputStream.onClosed = () => file.create(() => fileStream.close()); print("${++downloadedCount}. ダウンロード! : $baseDir/$filename.$ext"); } } catch(NullPointerException e) { print("error."); } } )(new Uri.fromString(v["MediaUrl"])) ); }; } }
いい感じですね!さぁ、Dart使いましょう!!
(昔の)
#import("dart:io"); #import("dart:uri"); #import("dart:utf"); #import("dart:json"); class Url { static String encode( final String src ) { List ls = <int>[]; for( final int c in encodeUtf8( src ) ) { if ( ( c >= 65/*'A'*/ && c <= 90/*'Z'*/ ) || ( c >= 97/*'a'*/ && c <= 122/*'z'*/ ) || ( c >= 48/*'0'*/ && c <= 57/*'9'*/ ) || c == 45/*'-'*/ || c == 95/*'_'*/ || c == 46/*'.'*/ || c == 126/*'~'*/ ) { ls.add( c ); } else { ls.add( 37/*%*/ ); ls.addAll( c.toRadixString(16).charCodes() ); } } return new String.fromCharCodes( ls ); } } void main() { final String baseDir = "data"; final int perDownloadNum = 10; final int maxDownloadNum = 50; final String word = "おっぱい"; int downloadedCount = 0; for ( int i=0; i<maxDownloadNum/perDownloadNum; ++i ) { final Map<String, String> query = { "AppId" : "~ここにAppIdを入力~", "Version" : "2.2", "Markert" : "ja-JP", "Sources" : "Image", "Image.Count" : "${Math.min(maxDownloadNum-i*perDownloadNum, perDownloadNum)}", "Image.Offset" : "${i*perDownloadNum}", "Adult" : "off", "Query" : Url.encode( word ) }; StringBuffer sb = new StringBuffer(); query.forEach( (k,v) => sb.add("${k}=${v}&") ); final String queryString = sb.toString().substring( 0, sb.length - 1 ); final String uri = "http://api.bing.net/json.aspx?${queryString}"; final client = new HttpClient().getUrl( new Uri.fromString( uri ) ); client.onResponse = ( HttpClientResponse res ) { StringBuffer resStringBuf = new StringBuffer(); res.inputStream.onData = () { resStringBuf.add( new String.fromCharCodes( res.inputStream.read() ) ); }; res.inputStream.onClosed = () { final resJson = JSON.parse( resStringBuf.toString() ); for( final Map v in resJson["SearchResponse"]["Image"]["Results"] ) { final Uri imageUri = new Uri.fromString( v["MediaUrl"] ); final picClient = new HttpClient().getUrl( imageUri ); picClient.onResponse = ( HttpClientResponse r ) { try { ++downloadedCount; final String ext = r.headers["content-type"].replaceAll( const RegExp(@"(\w+)/"), ""); if ( ext == "jpeg" || ext == "png" || ext == "gif" ) { final String filename = imageUri.path.replaceAll( const RegExp(@"(\w+/)"), "" ).replaceAll( const RegExp(@"/"), "" ).replaceAll( const RegExp(@"(\.\w+)"), "" ); print( "$downloadedCount : ダウンロード! : ${baseDir}/${filename}.${ext}" ); final File file = new File( "${baseDir}/${filename}.${ext}" ); final fileO = file.openOutputStream(); r.inputStream.pipe( fileO ); r.inputStream.onClosed = () => file.create( () => fileO.close() ); } } catch( NullPointerException e ) { print( "error." ); } }; } }; }; } }