(こんなこと書いてブログのカテゴリ変わったりしないよね?ね?)
元凶
いかにしておっぱい画像をダウンロードするか〜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." );
}
};
}
};
};
}
}