Others

July 29, 2008

SWT Browser Widget

HTMLをレンダリングするJavaクライアントアプリを作成する。

JDKをインストールする。
http://java.sun.com/javase/downloads/index.jsp

Eclipse(Eclipse IDE for Java EE Developers)をダウンロードする。
http://www.eclipse.org/downloads/

SWTをダウンロードする。
http://www.eclipse.org/swt/

SWT(zip)をC:\java\swttestに解凍する。

JAVA_HOME\binを環境変数PATHに追加する。
C:\Program Files\Java\jdk1.6.0_07\bin
Eclipseに含まれるSWTを展開する。
C:\HOME>cd C:\ECLIPSE_HOME\plugins
C:\ECLIPSE_HOME\plugins>jar xvf org.eclipse.swt.win32.win32.x86_x.x.x.vxxxxf.jar
展開して出てきた.dllファイルをC:\java\swttestに移動する。

BrowsetTestクラスを作成する。
import org.eclipse.swt.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.browser.*;

public class BrowserTest
{
  public static void main(String args[])
  {
    Display display = new Display();
    Shell shell = new Shell(display);
    shell.setSize(800, 600);
    shell.open();
    
    Browser browser = new Browser(shell, SWT.NONE);
    browser.setBounds(shell.getClientArea());
    browser.setUrl("http://www.google.com/");
    
    while (!shell.isDisposed()) {
      if (!display.readAndDispatch()) {
        display.sleep();
      }
    }
    
    display.dispose();
  }
}
コンパイル & 実行
C:\java\swttest>javac -classpath swt.jar;. BrowserTest.java
C:\java\swttest>java -classpath swt.jar;. BrowserTest


July 13, 2008

ssh-agent

ssh-agentの起動、パスフレーズ入力の自動化。
vi ~/.bashrc

echo -n "ssh-agent: "
if [ ! -f ~/.ssh-agent-info ]; then
  ssh-agent > ~/.ssh-agent-info
fi

source ~/.ssh-agent-info
ssh-add -l >&/dev/null

if [ $? == 1 ]; then
  ssh-add ~/.ssh/priv_key
fi


July 05, 2008

Sabel JS - DatePicker(Sabel.Widget.Calendar)

Sabel 1.1で追加されるSabel.Widget.Calendarのサンプル。

カレンダーで日付を選択し、その選択された日付をインプットに適用するDatePicker.jsを書いてみた。
DatePicker.js

function datepicker(inputs) {
  Sabel.Array.each(inputs, function(input) {
    var div = document.createElement("div");
    div.style.position = "absolute";
    div.style.zIndex = 100;
    document.body.appendChild(div);
    
    var self = {
      element: Sabel.get(input),
      calendar: new Sabel.Widget.Calendar(div, {
        callback: function(date) {
          self.element.value = date.join("-");
        }
      }),
      render: function() {
        self.calendar.render();
      }
    };
    
    div.style.top  = Sabel.Element.getCumulativeTop(self.element)  + "px";
    div.style.left = Sabel.Element.getCumulativeLeft(self.element) + "px";
    
    self.calendar.WeekDays = ["日", "月", "火", "水", "木", "金", "土"];
    self.element.observe("mousedown", self.render);
  });
}
インプットのidをdatepicker()関数に渡すだけで使用できる(簡単に使えるようにしているため、任意のタイミングでカレンダーを消すなどの処理はできない)。インプットをクリックすると、そのインプットの位置にカレンダーが表示され、日付をクリックするとインプットに年-月-日が入る。
<script type="text/javascript" src="Sabel.js"></script>
<script type="text/javascript" src="DatePicker.js"></script>

<script type="text/javascript">
  new Sabel.Event(window, "load", function() {
    datepicker(["inputid1", "inputid2", ...]);
  });
</script>
動作の様子はこちら
* 実際にサンプルのように表示するにはSabelに含まれるcssや画像が必要


July 04, 2008

Internet Explorerではこのページは表示できません

JavaScriptを使用していて「Internet Explorerではこのページは表示できません」と出ることがある。IEがDOMの構築を終える前にDOM操作などを行おうとする場合にこうなったりならなかったり。

とりあえず、window.onloadイベントのリスナーで処理すれば安全な様子。
new Sabel.Event(window, "load", function(){
  // process
});


July 03, 2008

grep | sed

以下のような実行ログから失敗したid(\[\d+\]の部分)を抽出する。
20080701 15:20:01 SUCCESS: username [10502]
20080701 18:14:41 FAILURE: username [3821]
20080702 08:39:22 SUCCESS: username [9134]
20080702 14:43:52 FAILURE: username [6810]
20080702 21:11:05 SUCCESS: username [8819]
20080703 08:31:34 SUCCESS: username [13266]
...
grepで失敗の行を取り出してsedに渡す。
結果をfailures.phpに出力。
grep FAILURE some.log | sed -e 's/^.*\[\([0-9]*\)\]/\1 => 1,/' > failures.php
こんな感じになる。
3821 => 1,
6810 => 1,
...
ちょっと付け足してphpの配列にする。
使用する側のプログラムではissetでチェックしたいのでこの形式に。
in_array()だと遅い。
<?php

$failures = array(
3821 => 1,
6810 => 1,
...
);

...

if (!isset($failures[$targetId])) {
  // process
}
キャプチャに使う括弧をバックスラッシュでエスケープする必要がある。
これに少しはまった。

June 25, 2008

response headers in the download script

日本語ファイル名のファイルをダウンロードさせる場合、少しブラウザ(ユーザエージェント)を気にする必要がある。

Safariはサーバ側でどうにもできないため、ダウンロードリンクの最後(ファイル名として扱われる)をファイル名をURLデコードしたものにする。
<a href="/dlscript/<?php echo urlencode($filename) ?>">
  <?php echo htmlentities($filename, ENT_QUOTES) ?>
</a>
サーバ側では、IEの場合にヘッダに付加するファイル名をShift-JISに変換する。Safariの場合はヘッダにファイル名を付加しない(付加すると文字化けする)。
$filename = urldecode($filename);
$path = "/path/to/" . $filename;

header("Content-Type: application/octet-stream");
header("Content-Length: " . filesize($path));

$ua = (isset($_SERVER["HTTP_USER_AGENT"])) ? $_SERVER["HTTP_USER_AGENT"] : "unknown";
if (strpos($ua, "MSIE") !== false) {
  $filename = mb_convert_encoding($filename, "SJIS", "UTF-8");
}
      
if (strpos($ua, "Safari") === false) {
  header("Content-Disposition: attachment; filename="' . $filename . '"');
} else {
  header("Content-Disposition: attachment");
}
      
echo file_get_contents($path);
以下のブラウザで文字化けすることなくダウンロードできることを確認。
  • Windows: IE6, IE7, Firefox2, Opera9.?, Safari3
  • Linux: Firefox2, Opera9.?
  • Mac: Firefox3, Opera9.?, Safari3


June 20, 2008

mailtoを使用する際のスパム対策

HTMLでメールアドレスを素で書くとスパムロボットに拾われるため、JavaScriptを使ったスパム対策をする。

今回利用したスクリプトがこちらで、ほんの少し改造して使いやすくした。

使い方はCryptMailto.jsを読み込み、idを振った空のタグを用意し、popup_mailer()関数にアカウント名・ドメイン名・idを渡す。

例えばHTMLは次のようになる(ソース上にメールアドレスが現れない)。
<p>
  お問い合わせ先: <span id="info"></span>
</p>

<script type="text/javascript" src="/js/CryptMailto.js"></script>
<script type="text/javascript">
  popup_mailer("info", "example.com", "info");
</script>
サンプルはこちらで。

June 15, 2008

Javascript - mouseover, mouseout

Javascriptでdivなどのmouseoverやmouseoutイベントを扱う際、そのdivが他の要素を内包していると厄介な挙動をする。

div3
<div id="a" onmouseover="alert('over');" onmouseout="alert('out');">
  <div id="b">
    <div id="c"></div>
  </div>
</div>
例えば上記のように、a内にbがあり、b内にcがある状態で、aのmouseover, mouseoutイベントでアラートを表示すると、マウスがb上に移動すると一度outし直後に再びoverする。c上に移動した時も同様。

IEでは以前からonmouseenterやonmouseleaveがあるようで、これを使うとbやcは関係なく、aに入った時と出た時だけイベントが発生してくれる。
他のブラウザでも同様の振る舞いを実現するにはそれ用の実装をする必要があるが、Sabel JS(Sabel 1.1以降)だと以下のようにできる。
<div id="a">
  <div id="b">
    <div id="c"></div>
  </div>
</div>

<script type="text/javascript">
  var a = Sabel.get("a");
  a.observe("mouseenter", function(){ alert('over'); });
  a.observe("mouseleave", function(){ alert('out');  });
</script>
動作の様子はこちらで。

June 11, 2008

Thunderbird - Sorting messages by Thread

Thunderbirdでスレッド表示すると、同じ件名だと全く関係ないメールでもスレッド化してしまうので、それの対処。

以下の作業をする前に、Thunderbirdを閉じておく。

ホームディレクトリ以下のどこかにある、prefs.jsを変更する。
Windowsだと次のようなパスにある。
C:\Documents and Settings\user\Application Data\Thunderbird\Profiles\xxxxx.default\prefs.js
Linuxだと次のようなパスにある。
/home/user/.thunderbird/xxxxx.default/prefs.js
prefs.jsに以下の一行を追加。
user_pref("mail.thread_without_re", false);
この"xxxxx.default"ディレクトリの下の、MailやImapMailディレクトリ内の*.msfファイル(インデックスファイル)を削除する。


June 06, 2008

Install Java on Linux

Linux(CentOS, Fedora)にSunのJavaをインストールする。

インストールする前はこんな感じ。
$ java -version
java version "1.7.0"
IcedTea Runtime Environment (build 1.7.0-b21)
IcedTea Server VM (build 1.7.0-b21, mixed mode)

JDKをhttp://java.sun.com/javase/ja/6/download.htmlの辺りからダウンロードしてくる。

・インストールする
$ chmod +x jdk-6u6-linux-i586-rpm.bin
$ sudo ./jdk-6u6-linux-i586-rpm.bin
・環境変数の設定
$ vi /etc/profile.d/java.sh

#!/bin/sh

export JAVA_HOME="/usr/java/jdk1.6.0_06"
export JAVA_PATH="$JAVA_HOME"
export PATH="$JAVA_HOME/bin:$PATH"
・設定を有効にする
$ source /etc/profile.d/java.sh

インストール後はこんな感じ。
$ java -version
java version "1.6.0_06"
java(TM) SE Runtime Environment (build 1.6.0_06-b02)
java HotSpot(TM) Server VM (build 1.6.0_06-b22, mixed mode)


Sabel

Sabel PHP Frameworkを開発しています。
http://www.sabel.jp/

Search
Categories
Tags
Recent Articles
Archives