2019年7月7日日曜日

SOLVED: "Japanese IME not ready yet" & "Downloading language dictionary" trouble

If you are having one of these issues described below on Windows 10 computers, try my solution. It cleared up both issues (on two separate machines).

1. When you try to type in Japanese, you are told "Japanese IME is not ready yet."

2. When you try to type in Japanese, you are told "Downloading language dictionary" but it never finishes.

CAUSE:

The two machines were missing dictionary files. The error messages make sense.

SOLUTION:

Find a machine with working Japanese IME and copy the dictionary files. You may not have a working machine, so I have the files here.

Unzip and copy these files to c:/Windows/IME/IMEJP/DICTS, and that's it. No reboot necessary.

2011年9月20日火曜日

星の子守唄

2011年10月2日、ハミングバードさんのお陰で、『星の子守唄』を世に送り出すことができました。

● ハミングバードバージョン
● 器楽バージョン
● 歌詞

星の子守唄

聖なる夜の静寂(しじま)の中で
遥か彼方、銀河の果て
星が生まれた

星は次第に輝きを増し
多くの星に囲まれて
育まれてた

太陽の光にも月の明かりにも
かき消されることのない星

星を見守るもう一つの星
光を放ち遠くから
照らし続ける

美しき星よ
輝け永遠(とわ)に


* カバーのご相談、楽譜、カラオケのリクエスト、著作権に関するお問い合わせは、YouTube上でafukadaytにメッセージをお送りください。

2011年2月13日日曜日

CentOS 5.5でhttpd + SSLを設定時の落とし穴

サーバ管理の目的(phpmyadmin, webminなど)でSSLが必要になったが、そのためにSSL証明書を買うのは馬鹿馬鹿しい。そこで自作の証明書(self-signed certificate)を作って使うことにした。証明書の作り方はここに説明がある。

http://www.akadia.com/services/ssh_test_certificate.html

CentOSでの証明書のインストール方法はここを参照した。

http://www.centos.org/docs/5/html/Deployment_Guide-en-US/s1-httpd-secure-server.html

これですんなりいくはずだったが、ブラウザはタイムアウトばかりで一向につながらない。OpenSSLのs_clientコマンドではつながるのに。そこで思いついたのはファイアーウォール(iptables)の設定。何とCentOSのデフォルトでは443番ポートはクローズでした。そこで次のコマンドでポートを開いたら、すべて動き出しました。

iptables -I INPUT -p tcp -m state --state NEW,ESTABLISHED --dport 443 -j ACCEPT

Configure httpd with SSL on CentOS 5.5

I needed web SSL support for private server-admin purposes, i.e. phpmyadmin and webmin. It'd be silly to pay for an SSL certificate just for that. This site explains how to create a self-signed certificate.

http://www.akadia.com/services/ssh_test_certificate.html

Certificate installation instructions for CentOS are here:

http://www.centos.org/docs/5/html/Deployment_Guide-en-US/s1-httpd-secure-server.html

I followed the instructions found at these sites, but my server kept giving me timeout errors despite the fact that I could connect to the secure site through OpenSSL's s_client command. Then, it occurred to me that I should check my firewall (iptables) setting. That was it! CentOS's default is port 443=closed. I opened it with this command, and everything started working.

iptables -I INPUT -p tcp -m state --state NEW,ESTABLISHED --dport 443 -j ACCEPT

2009年7月2日木曜日

getElementById使用時のobject required エラー

HTMLの方でちゃんとsIDというフィールドを作ったのに、

  <input type="hidden" id="sID" name="sID" />

このgetElementByIdがIEでエラーになるのはどうしてでしょうか。

  <script type="text/javascript">
  document.getElementById("sID").value = User;

原因を見つけるのに数時間かかりましたが、このポストを見つけた人はもっと早く解決できるかも。

答えはHTMLのロードとJavascriptの実行のタイミングにありました。問題のgetElementById("sID") が呼び出される時にsIDというフィールドがロードされていなければエラーになるというわけです。ということはHTMLのロードを待ってからJavascriptを実行するようにすればいいわけです。例えば、

  <script type="text/javascript">
  function init() {
    //関数に入れる
     document.getElementById("sID").value = User;
  }
  .
  .
  .
  <body onLoad="init()"> <!-- HTMLのロードを待って呼び出す-->
     <input type="hidden" id="sID" name="sID" />

Beware: getElementById object required error

Why does this Javascript statement cause an object required error in IE

  <script type="text/javascript">
  document.getElementById("sID").value = User;

when there is an object by that name?

  <input type="hidden" id="sID" name="sID" />

It took me several hours to figure it out. Maybe this post will help those who will follow.

The answer is that you need to make sure that when getElementById("sID") is called, an object by that name has already been created. Yes, the HTML section of your code must load first before the Javascript code can be executed. So, a solution is as follows:

  <script type="text/javascript">
  function init() {
    //put it in a function
     document.getElementById("sID").value = User;
  }
  .
  .
  .
  <body onLoad="init()"> <!-- call the function after HTML loads-->
     <input type="hidden" id="sID" name="sID" />

2008年11月16日日曜日

字幕翻訳の覚え書き(1)

「ちぇっ、気の長い奴だな。」東宝映画『少年漂流記』より

少年たちだけを乗せた船がなぜか港を離れ漂流を始める。少年の一人が無線機を直そうとしているが、なかなか直りそうにない。いらいらした別の少年の台詞が上の台詞。

「気の長い」というとpatientなどを思い浮かべますが、これはいい意味で使うからここでは合いません。「気の長い奴」から「のろま」などを思い浮かべ、それにあたる軽蔑的な言葉を探すと、slowpokeなどが見つかりますが、

Tut, you slowpoke.

ではちょっと違うかな、という感じ。それで発想を変えて、日本語には捕われず、こういう状況で英語話者なら何を言うかなと考えてみると、

We don't have all day, you know.

に思いあたりました。うん、これならニュアンスもかなり近いです!

2007年11月19日月曜日

茶筌chasen-2.4.2, Darts 0.31, UniDic1.3.5のインストール

最新版茶筌chasen-2.4.2をDarts 0.31、UniDic1.3.5と組み合わせてインストールしました。結構落とし穴があるようなので、参考のためにブログに記します。

Darts 0.31のインストール

wget http://chasen.org/~taku/software/darts/src/darts-0.31.tar.gz
tar xvzf darts-0.31.tar.gz
cd darts-0.31
./configure

*configure error: C++ prerrocessor "/lib/cpp" fails sanity check
などのエラーが出たら、C++のコンパイラがインストールされていないということなので、gcc-c++をインストールする。
yum install gcc-c++

そして作業再開。

make
make install

chasen-2.4.2のインストール

wget http://keihanna.dl.sourceforge.jp/chasen-legacy/26441/chasen-2.4.2.tar.gz
tar xvzf chasen-2.4.2.tar.gz
./configure --with-darts=/usr/local/include --with-libiconv=/usr/local

gcc(g++) verison 3.4.3以上でコンパイルエラーが起こるので、lib/dartsdic.cppの180行目を以下のように修正する。

修正前:(const char*)keys[size] = key.data();
修正後:keys[size] = (char*)key.data();

make
make install

uniDic-1.3.5のインストール


システムをEUCで統一しているので、http://www.tokuteicorpus.jpから個別ファイル->Linuxと進んで、UniDic-chasen-1.3.5_eucj.tar.gzをダウンロードする。

tar xvzf UniDic-chasen-1.3.5_eucj.tar.gz

/unidicというディレクトリに辞書ファイルや文法ファイルが入るので、それを/usr/local/lib/chasen/dicの下に移動する。

mv unidic /usr/local/lib/chasen/dic

これで/usr/local/lib/chasen/dicの下にipadicとunidicが並ぶ格好になる。

ipadicを使いたい時は、

chasen -r /usr/local/lib/chasen/dic/ipadic/chasenrc

unidicを使いたい時は、

chasen -r /usr/local/lib/chasen/dic/unidic/chasenrc

とすればよい。

2007年10月13日土曜日

[PHP] Finding the latest RSS item date

I’ve been podcasting for about a year. Recently, I thought of adding something like “(Last update: 12/10/06)” by a link to my podcast page. I also thought that it’d be neat to have this generated automatically (dynamically). After a few hours of experimentation in PHP, I came up with the following function.

I’ll list the whole code first, and then, go though it bit by bit later.

To use this code, put the following function definition in the header part of an HTMLfile.

<?php

function Find_Latest_From_RSS($filename) {
$str=file_get_contents($filename);
$p = xml_parser_create();
xml_parse_into_struct($p, $str, $vals, $index);
xml_parser_free($p);
for ($i=0; $i<count($vals); $i++)
if ($vals[$i][tag]=="ITEM") {
break;
}
}
$latest="January 1 1970 00:00:00 GMT"; // initialize
for (; $i<count($vals); $i++) { // start looking for PUBDATEs
if ($vals[$i][level]==4 && $vals[$i][tag]=="PUBDATE") {
$dateTime=strtotime($vals[$i][value]);
if ($latest<$dateTime) {
$latest=$dateTime;
}
}
}
return date("n/j/y",$latest);
}

?>

Then, in the body, where you want the date to appear, put

<?php echo Find_Latest_From_RSS("your_RSS_file"); ?>

For example,

(Lat update: <?php echo Find_Latest_From_RSS("your_RSS_file"); ?>)

will give you

(Last update: 12/11/06)

If you want to change the date format, modify this line:

date("n/j/y",$latest)

Breif documentation on the code follows. First, a function declaration.

function Find_Latest_From_RSS($filename) {

You pass the name of an RSS file as the argument. This means that it is possible to process multiple RSS files in a HTML file. This function returns the latest publication item date.

$str=file_get_contents($filename);

First, the entire RSS file is read in.

$p=xml_parser_create();
xml_parse_into_struct($p, $str, $vals, $index);
xml_parser_free($p);

These three lines go together. The first line creates a PHP xml parser object. The second line parses the RSS file content. The third line removes the parser object from the memory. The parsed data are put in $vals.

for ($i=0; $i<count($vals); $i++)
if ($vals[$i][tag]=="ITEM") {
break;
}
}

This loop looks for an <ITEM> tag and exits when it finds one. The purpose of this is to skip the materials that precede <ITEM> definitions.

$latest="January 1 1970 00:00:00 GMT";

In order to find the latest publication date, initialize $latest to some old date.

for (; $i<count($vals); $i++) {

Here’s another for loop. Notice that $i is not initialized. $i starts at the value from the last loop.

if ($vals[$i][level]==4 && $vals[$i][tag]=="PUBDATE") {

Look at each element in the array and if you find an element whose level is 4 and whose tag is PUBDATA, you’ll look at its value. What’s level 4? An item pubdate comes under <rss><channel><item>. Therefore, it’s level 4. There’s another pubdate at level 3, but it’s a publication date of the feed itself. Because the first loop skips over everything before the first item tag, we don’t really need to check on the level of each element here. This piece of code is there for the purpose of illustrating the data structure.

$dateTime=strtotime($vals[$i][value]);

strtotime is used here to convert a string representing a date into the date format. Once this is done, you can use comparison operators to compare between dates.

if ($latest<$dateTime) {
$latest=$dateTime;
}

A comparison is made here. Whenever a more recent date is found, it is stored in $latest.

This way, at the end of the loop, $latest should contain the latest item publication date.

return date("n/j/y",$latest);

The last thing to do is to convert the value in $latest into a string and return it as the return value of the whole function.

[PHP] RSSファイル内の最新itemの日付を探す

Podcastingを始めて1年ほどになります。最近、Podcastのページへのリンクのところに(12/10/06更新)などのように表示できたらいいなと思いました。さらに、更新日付が自動的に生成できたらいいなと考え、PHPのプログラミング開始。次のような関数を書くにいたりました。

まず全体を紹介して、後で少しずつ解説します。

このコードを使うには、HTMLのヘッダのところに以下の関数宣言を挿入します。

<?php

function Find_Latest_From_RSS($filename) {
$str=file_get_contents($filename);
$p = xml_parser_create();
xml_parse_into_struct($p, $str, $vals, $index);
xml_parser_free($p);
for ($i=0; $i<count($vals); $i++) { // skip over stuff before <ITEM>
if ($vals[$i][tag]=="ITEM") {
break;
}
}
$latest="January 1 1970 00:00:00 GMT"; // initialize
for (; $i<count($vals); $i++) { // start looking for PUBDATEs
if ($vals[$i][level]==4 && $vals[$i][tag]=="PUBDATE") {
$dateTime=strtotime($vals[$i][value]);
if ($latest<$dateTime) {
$latest=$dateTime;
}
}
}
return date("n/j/y",$latest);
}

?>

そして更新日付を表示したいところに以下を挿入します。

<?php echo Find_Latest_From_RSS("your_RSS_file"); ?>

例えば、

(<?php echo Find_Latest_From_RSS("your_RSS_file"); ?>更新)

とすれば、
 
(12/11/06更新)

のように表示されます。

日付の表示形式を変えたい場合は、この部分を変更します。

date("n/j/y",$latest)

さて、ここからコードの解説をします。

まず関数の宣言です。

function Find_Latest_From_RSS($filename) {

RSSファイル名を引き渡せるようになっていますので、一つのHTMLファイルの中で複数のRSSファイルを処理する事が可能です。この関数は、戻り値として日付(文字列)を返します。

ここではRSSファイルを一気に読み込みます。
 
$str=file_get_contents($filename);

次の三行はセットになっています。

$p=xml_parser_create();
xml_parse_into_struct($p, $str, $vals, $index);
xml_parser_free($p);

一行目でパーサーオブジェクトを作り、二行目で解析をして、三行目で不要になったパーサーオブジェクトをメモリから消します。解析結果は、$valsの中に入れてくれます。

次に最初の<ITEM>タグを探します。

for ($i=0; $i<count($vals); $i++) { // skip over stuff before <ITEM>
if ($vals[$i][tag]=="ITEM") {
break;
}
}

見つかったらループから抜けます。これは、<ITEM>以前に記述されているRSS feed全体に関する情報を飛び越すためです。

最新のPUBDATEを探すために、$latestという変数を、1970年1月1日に初期化します。

$latest="January 1 1970 00:00:00 GMT";

またforループに入りますが、今度は$iを初期化しません。以前のループを抜けた時の$iの値から繰り返しが始まります。

for (; $i<count($vals); $i++) {

$vals配列内の個々の要素を調べて、「その要素のレベルが4で、タグがPUBDATEだったら」という条件になっています。

if ($vals[$i][level]==4 && $vals[$i][tag]=="PUBDATE") {

レベル4とは、ITEMのPUBDATEが<rss><channel><item>の下に来るから4なのです。レベル3にもPUBDATEがあり、これはRSS feed全体の公開日です。ITEM以前のデータは飛び越していますから、レベルチェックは本当は必要ありませんが、念のためというのと、データ構造を見ていただくために入れました。

上の条件に合った配列要素は、itemの公開日です。これは文字列データですから、比較ができるようにするためにstrtotimeで日付時間データに変換します。

$dateTime=strtotime($vals[$i][value]);

変換後なら、以下のように不等号を使って比較ができます。

if ($latest<$dateTime) {
$latest=$dateTime;
}

より新しい日付が見つかるたびに、$latestを更新していきます。

このように処理していけば、ループが終わった時点で、$latestには、もっとも最近公開されたitemの公開日付が入っているはずです。

最後にこの日付データを好みの形式の文字列に変換してやります。

return date("n/j/y",$latest);

この文字列が、この関数の戻り値となります。

[LINUX] useradd後にsshでログインできない

useraddで新規ユーザを作り、エラーも出なかったので、これでよしと思ったのですが、sshでログインしようとするとPermission deniedでログインできませんでした。ここにLinuxの落とし穴がありました。以下で解説しましょう。

まず

% useradd -gusers -p himitsu -s /bin/bash -d /home/okato -m okato

のように入力します。エラーは出ませんでした。確認したら/home/okatoというユーザディレクトリもできていました。すべて良好と思いsshでログインを試みたら、

$ ssh okato@myserver.com
Permission denied

となってログインできません。

パスワードを変えたりしていてわかったのですが、Linuxは実在する単語などのパスワードを受け付けてくれません。例えばpasswdでパスワード変更する場合にはこのチェックが働きます。ところがuseraddコマンドの時にはこのチェックが裏で働き、ダメなパスワードだとログインできないような設定にされてしまうようです。これは裏で起こっており、エラーメッセージの形でフィードバックされないため、管理者を悩ませる結果となったわけです。

教訓:パスワードは常に強力なものを使おう!

なお、コマンドラインでパスワードを設定する場合は、特殊な記号が使えないことに注意してください。| や>や<などの文字はコマンドラインで特別な意味を持つので、パスワードの一部として使えません。""で囲めばいいかもしれませんが、実験していません。

[LINUX] Can't login after useradd

After creating a new user account with the useradd command, I couldn't login through ssh. Here's a common pitfall to watch out for. Let me discuss it.

I first entered this command as root.

% useradd -gusers -p himitsu -s /bin/bash -d /home/okato -m okato

There was no error. I was able to verify that /home/okato had been created. Thinking that all is well, I proceeded to login through ssh, but I was rejected.

$ ssh okato@myserver.com
Permission denied

After a bit of experimenting, I discovered that Linux checks on your password choice. If it's an existing word or something weak like that, Linux rejects it. You can see this behavior in the passwd command. However, with useradd, apparently, this check operates in the background and if the check doesn't succeed, the user account is rendered unusable. Since this occurs in the background and there's no feedback to the operator, it misleads the operator into thinking all is well.

LESSON TO BE LEARNED: Always use strong passwords!

Also, you should pay attention to use of certain symbols that have special meaning on the command line. Symbols like "|", "<", ">" cannot be used as part of the password to be specified on the command line. You may be able to quote the password and get away with it, but I haven't tried it yet.