2009年12月17日木曜日
memcached client
memcachedb on Mac Leopard
まずはberkeley DB.デフォルトで入っているというはなしなのだが,どこにあるのかわからず, Oracleから落としてきて普通に入れてみた.version4.8が最新だが,4.7で. UNIX扱いで入る.
libeventは port で.
memcachdb はconfigureの際に--with-libevent=/opt/local とすればOK.
2009年12月13日日曜日
log4j - java.util.logging bridge
import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.spi.LoggingEvent; import java.util.HashMap; import java.util.Map; import java.util.logging.Logger; public class JDKLogAppender extends AppenderSkeleton { static Mapmap = new HashMap (); static Map levelMap = new HashMap (); static { levelMap.put(org.apache.log4j.Level.FATAL, java.util.logging.Level.SEVERE); levelMap.put(org.apache.log4j.Level.ERROR, java.util.logging.Level.SEVERE); levelMap.put(org.apache.log4j.Level.WARN, java.util.logging.Level.WARNING); levelMap.put(org.apache.log4j.Level.INFO, java.util.logging.Level.INFO); levelMap.put(org.apache.log4j.Level.DEBUG, java.util.logging.Level.FINE); levelMap.put(org.apache.log4j.Level.TRACE, java.util.logging.Level.FINER); } private Logger getLogger(String name){ Logger logger = map.get(name); if (logger != null) return logger; logger = Logger.getLogger(name); map.put(name, logger); return logger; } @Override protected void append(LoggingEvent event) { String loggerName = event.getLoggerName(); Logger logger = getLogger(loggerName); logger.log(levelMap.get(event.getLevel()), layout.format(event)); } @Override public void close() { } @Override public boolean requiresLayout() { return true; } }
2009年12月12日土曜日
html parser for GAE
他にもパーザはやまほどある. htmlcleanerと言うものを使ってみたが,いまいちうまくいかない. 原因は,文書内のMETAタグの中のcharsetをちゃんと読んでくれないせい. 本来,HTTPのヘッダに含まれるContent-typeに含まれているべき情報なのだけど, HTTPサーバだって各文書の文字コードのことまでは知らないので,ちゃんと設定するのはむずかしい.なので,METAタグでhttp-equivで書くのが普通. htmlcleanerに渡すReaderを適当な文字コードで作ってやれば読めるのだけど,それには,先に一度文書の中を読んで,METAタグを調べてから,htmlcleanerに食わせてやらなければならない. 面倒だ.
HTML Parser(どうでもいいが,もうすこし個体を識別できる名前をつけてほしい)は,まずは適当な仮定を持ってストリームを読み,meta tagを読み込んだ時点で,仮定と異なる文字コードだった場合には,頭からパーズし直してくれるらしい.
使ってみると確かにちゃんと読めているようだ. EUCのasahi.comもutf-8のwikipedia.jpも何も気にしないで読める. こりゃ便利.ツリーの中のノードに対して適当な条件をつけて,合致するノードだけ返す,なんてこともできる.a タグ で href があるものだけ,という条件で読んでみるとこんな感じ.
parser = new Parser(con); Parser.getConnectionManager ().setRedirectionProcessingEnabled (true); NodeFilter filter = new AndFilter(new TagNameFilter("a"), new HasAttributeFilter("href")); NodeList nodeList = parser.parse(filter); for (Node node: nodeList.toNodeArray()) { TagNode tagNode = (TagNode)node; writer.println(tagNode.getAttribute("href")); writer.println(getText(tagNode)); }いわゆるDomとは仕様が違うのが気になるけど,とりあえずこまらないかな.