2013年7月8日月曜日

cassandra cql3 jdbc

Cassandra のSQLライクなQLであるところのCQL3をjdbc越しに使う方法。 どうも昔は、Cassandraのディストリビューションに必要なDriverが入っていた らしいのだけど、1.2.4現在、なぜか外されている? よくわからないことに、org.apache.cassandra.cql.jdbc というそれっぽいパッケージ は残っており、そこにはJDBC関連の型があるのだけどドライバがないのだ。

driver のダウンロードとインストール

https://code.google.com/a/apache-extras.org/p/cassandra-jdbc/ にコードが有る。

自前でビルドしようとしたら、変なコードが混じっていてJavaCompiler が通らなかったり、 Java1.7 の JDBCで追加されたsetSchema/ getSchemaをサポートしていなかったりでコンパイルが 通らない。。

とりあえず1.2.5向けのjarを持ってきてCLASSPATHを通したら動いた。

public static void main(String[] args) throws Exception {

    Class.forName("org.apache.cassandra.cql.jdbc.CassandraDriver");
    Connection con = DriverManager.getConnection("jdbc:cassandra://localhost:9160/testks");

    String query = "INSERT INTO simpledata (id, content)    VALUES (?, ?);";
    
    PreparedStatement statement = con.prepareStatement(query);

    statement.setString(1, "002");
    statement.setString(2, "foobarfoobar");
    
    statement.execute();

    statement.close();
}

2013年6月28日金曜日

Apps Scriptで差し込みメイル

多数の相手に文面を少しだけ変えながらメイルを出すためのスクリプト。Google Docs上に文を置き、それの*NAME* というフィールドを置き換えながら送信する。

サーバ上で完結しているので手元にブラウザだけあれば使えるのが便利。
Docs上の文書のIDはURLに含まれているのを抽出しなければならないのが面倒。
Here documentがJavascriptで使えればDocsにおいたりする必要もなくて、もっと便利なのにね。

function myFunction() {
  var docname = "xxxx";
  var doc = DocumentApp.openById(docname);

  var list = [
    {name: "test1", email: "addr"},
    {name: "test2", email: "addr"},
  ];

  var mailBody = doc.getBody().getText();

  for (var i = 0; i < list.length; i++) {
     var name = list[i].name;
     var addr = list[i].email;
     var body = mailBody.replace(/\*NAME\*/g, name);
     Logger.log(addr);
     Logger.log(body);
     MailApp.sendEmail({
       to: addr,  
       subject: "サブジェクト",
       body: body,
     });
  }
}

2013年5月10日金曜日

Cassandra の複数サーバを1ノードで動かす

普通この種のものは、ポートを設定ファイルで切り替えてやれば1ノードで複数サーバを動かすことができるのだけど、Cassandraではむずかしい。というのは、システムのポート番号が全てのサーバで同一であることが前提となっているらしいからだ。サーバのノード情報はゴシップでやり取りしているはずだから、一度接続出来ればポート番号を交換して共有できそうなものなのだが、その接続ができない。

yamlファイルのseedsを指定するフィールドが、IPアドレスのみを指定するようになっていて、ポート番号を指定できない。簡単に修正できれば修正してみようかと、ソースを追ってみたけど割に中の方までIpAddressだけしか持っていないので難しいと判断。

VMの中なので、ネットワークインターフェイスを増やすのは簡単なので、それで何とかしようかと思ったのだが、 ググったらもっと簡単な方法があった。 3年前の記事

ローカルホストのloインターフェイスにaliasで別のIPアドレスをふり、それを使うという方法。 本物のネットワーク・インターフェイスを増やすと色々面倒だけどこれなら、ずっと楽だしVMじゃなくてもできる。

以下ubuntuでの方法。

  • sudo ifconfig lo:1 127.0.0.2 up    
    
    とかやって、lo:1というインターフェイスを作る。必要な数だけつくる。
  • conf ディレクトリをサーバの数だけ複製する。
  • cassandra.yamlの data_file_directories, commit_log_directory, saved_caches_directory が重複しないように 別々のディレクトリを掘って指定する。
  • cassandra.yamlの listen_address と rpc_address を127.0.0.2などに変更する。
  • cassandra.yamlのseeds にアドレスを並べる
      - seeds: "127.0.0.1,127.0.0.2"
    
  • log4j-server.properties の /var/log/cassandra となっている部分を適宜重複しないように変更する。
  • cassandra-env.sh のJMX_PORTは別の値を指定する。このポートは常に0.0.0.0に対してバインドされるらしいので 複数のサーバ間が同じポートで共有することができないらしい。
  • 起動時には新しく作ったconfディレクトリを環境変数で指定して起動すれば良い。
    CASSANDRA_CONF=conf1 bin/cassandra
    

2013年4月17日水曜日

ufw のlogの抑制

ubuntu 12.04のデフォルトの設定だと、ufwのログが/var/log/ufw.log 以外のmessages やら kern.logに出てしまって、 何がおこっているのかわからなくなってしまう。ということで、 /etc/rsyslog.d/20-ufw.conf の最後の行
#& ~
のコメントを外す。これがあるとfall through でデフォルトのログ分配の方にも流れてしまう らしい。これが流れないようにする、と。

あとは

sudo restart rsyslog
でOK。

2013年4月13日土曜日

ubuntu preseed で rootのssh pub keyを仕込む

preseed はdebian/ubuntuのインストーラの返答を自動化する仕掛け。RedHatでいうところのkickstartみたいなものか。 この機能を使うとインストールの最後にスクリプトを実行することができる。 それをつかって、rootアカウントにsshの公開鍵を仕込むことができた。 インストールしたらすぐにsshでrootに入れるので、自動的に様々な設定ができて便利。
d-i preseed/late_command string \
in-target /bin/mkdir /root/.ssh ;\
in-target /bin/chmod 700 /root/.ssh ;\
in-target /bin/sh -c 'echo "ssh-rsa 略" > /root/.ssh/authorized_keys'

2013年3月22日金曜日

pythonでredirectするとエンコーディングエラー

Pythonでprintで日本語の文字を書き出している場合、画面に出してると大丈夫なのに、redirectすると したのようなエラーがでることがある。
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
調べてみるとttyのときだけ親切に色々やってくれているんだけど、 redirectとかpipeだとそれが機能しなくなり、内部で持ってるunicode表現文字をデフォルトのasciiにエンコードしようとして失敗する、 ということのようだ。 ここにいい方法がのってた。
import sys
import codecs
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
としておくと以降のstdoutへの出力が常にutf8で自動的にencodeされるようになる。

jquery で入力フィールドに透かしを入れる

多分佃煮にするほどあるのだろうけど、 http://digitalbush.com/projects/watermark-input-plugin/にあるのを使ってみる。
としておいて、
  
<script src="jquery.watermarkinput.js"></script>
  
<input id="tag"></input>
とやって作ったinputに対して、
  
$( '#tag' ).Watermark("label", "#999");
とやって出来上がり。第2引数が色。

2013年3月17日日曜日

ubuntu ネットワーク増設

/etcnetwork/interfaces に追記する。
auto eth1
iface eth1 inet dhcp
DHCPで取らない場合には
auto eth1
iface eth1 inet static
    address 192.168.11.15
    netmask 255.255.255.0
    gateway 192.168.11.1
とかするようだ。 で、networkを下げてあげる。
sudo start network-interface INTERFACE=eth1
などとやるとeth1がupする。 service とかつかわずにstart, stopなどを用いるようだ。

2013年2月26日火曜日

mac のpreviewからの切り貼りで濁点が離れる

macのpreviewで表示しているPDFからコピペで文章を切り出してEmacsに貼りこむとなんだかよくわからないが、濁点が別の文字となってしまう。これはいわゆるUTF-8-MACというものらしく、ある意味で正規化した状態なのだそうだ。アプリの側がちゃんと対応していれば大丈夫らしく、例えばwordに貼りこむ文には問題にならないようだ。

しかしこれだとすごく困るのでemacsのマクロとか書いたのだけど、もっといい方法はないかと検索してみたところ Automatorを使ったかっこいい方法があった。 サービスというものを作ってそれで変換する。変換自体はiconvを呼び出しているが、アプリケーションからのデータを受け取って直接クリップボードに入れるようになっている。 これだと、コピーする代わりに、右クリックで出てくるサービスメニューに登録したサービスを指定するだけでUTF-8に変換されたデータがクリップボードに入る。便利便利。っていうか、なんでUTF-8-MACなんて余計なものを使うんだ、って話なわけだが。

2013年2月13日水曜日

github でforkしたrepositoryのupdateに追従

なんとなくgithub内で完結できるのかと思ったらできないらしい。やりかたは ここに書かれてる。

forkしたレポジトリをローカルにclone。以下PROJがプロジェクト名、ORGが元のユーザ、MEが自分とする。

git clone https://github.com/ME/PROJ
cd PROJ
元のプロジェクトをupstreamに登録
git remote add upstream https://github.com/ORG/PROJ
フェッチ
git fetch upstream
こうすると upstream/xxxx というところに内容がとれてくる。 で、これをマージする
git merge upstream/XXXX
XXXXはmaster とかtrunk? mergeに失敗したら修正してから
git add xxx
git commit
最後にpushして終わり
git push origin master
面倒。

2013年2月6日水曜日

lucene-gosen 導入

http://www.mwsoft.jp/programming/munou/lucene_gosen.htmlのとおりに。 google codeからおとす。ipadicとnaist-chasenが選べるが、よくわからんのでIPAで。 こんなふうにして、
import net.java.sen.*;
import net.java.sen.dictionary.*;
import java.io.*;

class Test {
  public static void main(String [] args) throws Exception {
 StringTagger stringTagger = SenFactory.getStringTagger(null);
 Reader reader = new InputStreamReader(System.in, "utf-8");
 PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out, "utf-8"));
 
 StreamTagger tagger = new StreamTagger(stringTagger, reader);
 while (tagger.hasNext()) {
   Token token = tagger.next();
   writer.println(token.getSurface());
 }
 writer.flush();
  }
}
コンパイル。
javac -cp ".:lucene-gosen-4.1.0-ipadic.jar" -encoding UTF8 Test.java
実行
java -cp ".:lucene-gosen-4.1.0-ipadic.jar" Test
テストです。  <- 入力文
テスト       <- 解析結果
です
。

2013年2月1日金曜日

luceneを動かしてみる

まずはここからtar ballをダウンロード で、
 tar zxvf ~/Downloads/lucene-4.1.0-src.tgz   
 cd lucene-4.1.0
ビルドにivyが必要なのでインストールされていなければ
ant ivy-bootstrap
ant
あっさりビルドできた。便利な世の中になったものだ。

とりあえず、demoをビルド

cd demo
ant
これで、lucene_home/build 以下に色々作られる。できたjarをCLASSPATHに登録する。 lucene_homeで
CLASSPATH=. ; for jar in `find . -name '*.jar'` ; do CLASSPATH=$CLASSPATH:$jar ; done 
export CLASSPATH

さて、indexingしてみる。

java org.apache.lucene.demo.IndexFiles -docs . 
これでindexというディレクトリが作られて、そこにいろんなファイルができるようだ。 で、サーチしてみる。
> java org.apache.lucene.demo.SearchFiles                                                                    [~/test/lucene-4.1.0]
Enter query: 
testing
Searching for: testing
162 total matching documents
1. ./analysis/icu/src/test/org/apache/lucene/analysis/icu/segmentation/TestCharArrayIterator.java
2. ./test-framework/src/java/org/apache/lucene/analysis/package.html
3. ./analysis/common/src/test/org/apache/lucene/analysis/util/TestCharArrayIterator.java
4. ./test-framework/src/java/org/apache/lucene/search/package.html
5. ./test-framework/src/java/org/apache/lucene/util/automaton/package.html
6. ./analysis/common/src/test/org/apache/lucene/analysis/compound/compoundDictionary.txt
7. ./analysis/common/src/test/org/apache/lucene/analysis/compound/da_compoundDictionary.txt
おお。うごいた。とりあえず。