« April 2011 | Main | June 2011 »

May 2011

2011.05.31

OSQAのデータキャッシュがクリアされない

OSQAで何らかのデータを更新した際の挙動が謎・・・。

何度もページをリロードすると、更新前のページが表示されたり、更新後のページが表示されたり。2回以上更新をした場合(コメントを2つ以上登録した場合)など、前々回の状態だったり、前回の状態だったり、今回の状態だったり。

Apacheを再起動すると、問題なくなるので、おそらくキャッシュの内容が表示されてしまっているだけだと思うのですが・・・。Apacheのログを見ると、httpのレスポンスコードは200が戻されているので、ブラウザのキャッシュが悪さしているわけではないと思われるのですが(そもそも、ブラウザのキャッシュが表示されているのであれば、リロードの度にページが変わってしまうというのも不思議ですし)。

OSQAが使用しているフレームワーク(Django)にはキャッシュ機能が実装されているので、その影響かと思い、settings_local.py ファイルの内容を

CACHE_BACKEND = 'dummy://'

に書き換えてみたのですが、効果なし・・・。setting CACHE_BACKEND to dummy does not disable template caching の内容と同じような感じではあるのですが・・・。

なお、どうもDjango1.0~1.2と1.3でキャッシュの設定の仕方が変わっているっぽかったので、Djangoのバージョンを1.3から1.2.5に戻してみたのですが、現象は変わらず(OSQAは、1.2では動き、そもそも、4/19の時点では1.3では動かないようです)。

ちなみに、1.3から1.2.5に戻す方法。

# rm -rf /usr/local/share/python2.6.6/lib/python2.6/site-packages/django
# rm -rf /usr/local/share/python2.6.6/lib/python2.6/site-packages/Django-1.3-py2.6.egg-info
# http://www.djangoproject.com/download/1.2.5/tarball/
# tar zxvf Django-1.2.5.tar.gz
# cd Django-1.2.5
# python setup.py install

これと合わせて、settings_local.pyの内容も更新。
DJANGO_VERSION = 1.2

既にコンパイル済みのpycファイルをいったん削除(削除用のスクリプトが提供されています)。
sh rmpyc

1.2.5でもダメだったので、さらに1.1までバージョンを戻してみたところ、違うエラーが発生。

AttributeError: 'CacheClass' object has no attribute 'set_many'

What is the cause of this Internal Server Error? (CacheClass' object has no attribute 'set_many')によると、Djangoのバージョンが古いことが原因っぽい・・・。

ポストした内容が正しく反映されないというのは、アプリケーションとしては致命的だと思われるので、おそらくどこか設定の問題だとは思うのですが、mod_wsgiもDjangoも使うのは今回が初めてなので、どこに問題があるのかがさっぱりわからない・・・(涙)。

| | Comments (0) | TrackBack (0)

2011.05.30

VirtualHostを設定せずにOSQAを動かしてみる

OSQA の設定サンプル(Apache用)では、VirtualHostを使って、別のポート番号を・・・って感じになっています。ただ、使用するポートをあまり増やしたくないと言うこともあり、VirtualHostを使用せずに、他のアプリケーション(Trac/Subversionなど)と共存させるように設定を行ってみました(アプリケーションのURLとしては、http://servername/osqa/ を使用するように)。

/etc/httpd/conf.d/osqa.conf

WSGIPythonEggs /var/www/.python-eggs
Alias /osqa/m/ /opt/OSQA/forum/skins/
Alias /osqa/upfiles/ /opt/OSQA/forum/upfiles/
<Directory /opt/OSQA>
  Order allow,deny
  Allow from all
</Directory>
WSGIScriptAlias /osqa /opt/OSQA/osqa.wsgi

/opt/OSQA/settings_local.py(以下の2行の内容を確認)

APP_URL = 'http://servername'
FORUM_SCRIPT_ALIAS = 'osqa/'

Apacheを再起動。とりあえず、http://servername/osqa/ でアクセス可能なことを確認。ただ、一部リンク切れが発生してしまっているところがある模様。出力されたソースコードや、Apacheのアクセスログを確認してみると、

・アップロードしたファイル類(今回アップしたのはトップページ左上に表示されるロゴ画像ファイル)のURLが、/upfiles/... となってしまっている(本当は、/osqa/upfiles/... となって欲しい)。
・一部のファイルへのリンクが、/m/... となってしまっている(本当は、/osqa/m/... となって欲しい)。

といった感じ。いずれも内容としては同じような感じのもので、ApacheにAliasを追加することで回避可能ではあるのですが、他のアプリケーションと重なってしまう可能性が否定できない(もっとも、私が使っている範囲では重なることはないのですが)ところなので、生成されるリンクURLが正しくなるようにして欲しいところ。

・・・と思って調べてみると、アップロードのファイルに関しては UPFILES_ALIAS のパラメータの値が /upfiles/ のままになっていることが原因の模様。管理ページの「ファイルアップロードの設定」画面から、『アップロードされたエイリアスをファイル』の値を/osqa/upfiles/のように書き換えればOK。

ちなみに、

APP_URL = 'http://servername/osqa'
FORUM_SCRIPT_ALIAS = ''

という指定でも、問題なく動作するっぽい感じ。どっちが正しい設定なんでしょうかね??(APP_URLの値がキャッシュに影響しうるっぽい話もありますが・・・)

| | Comments (0) | TrackBack (0)

2011.05.29

OSQAの設定パラメータ類

setting_local.py ファイルに記述できる項目は、OSQA Installation and Upgrade Guides に記載されていました。

モジュールとして定義されている(DISABLED_MODULES に指定可能な値)としては、「localauth/openidauth/oauthauth/facebookauth/pgfulltext/sphinxfulltext/robotstxt/recaptcha/default_badges/books」となるようです。ただ、いつ時点の内容かは不明ですが・・・(^^;

例えば、OSQAの認証システムのみを利用する場合、openidauth/oauthauth/facebookauth を指定してlocalauthのみが残るようにしておけばいいようです。ただ、OpenIDの認証を無効にした場合、ログインページからOpenID連携用のリンク等はなくなるのですが、

OpenIDを使った外部のログインサーバを利用すると、パスワードをあなたとログインプロバイダ以外に知られる危険がなく、他のサイトのパスワードを覚えておく必要もなくなります。

というメッセージが残りっぱなしになってしまうようですが(^^; まぁ、これはメッセージを無理矢理書き換えればOKのような気はしますが。

ただ、「指定しなければデフォルトで有効」より、「指定した機能のみが有効」になる方が嬉しいかなぁ・・・。追加された機能が、運用ポリシーに合致するかどうかを確認してから導入したいところですし(まぁ、ASPサービスではなくローカルへインストールして使うシステムなので、テスト環境を準備し、検証してから導入するようにすればいいんでしょうけど)。

| | Comments (0) | TrackBack (0)

2011.05.28

インスタントラーメン発明記念館

インスタントラーメン発明記念館 に行ってきました。

チキンラーメン作成の予約はしていなかったので、「マイカップヌードルファクトリー」で。
一番難しかったのが、どんな絵を描くか、ってこと(笑)。絵心ないですからねぇ~。とりあえず、ひよこのイラストを見ながら、それっぽいものを描いてみましたが、言われなければわからないような気が(^^;

今やインスタントラーメンの種類はとっても多く、頻繁に新製品も登場(その裏では、消えゆく商品も)。その中で、登場以来ずっと残っている「チキンラーメン」「カップヌードル」は、すごいですね(マイナーチェンジはあるのかもしれませんが)。

作ったのは、キムチカレー(^^; カレー+キムチ×2+コーン+ベーコン・・・なんか、微妙な組み合わせかも~。まだ食べていないのですが、どんな味がするのやら??

| | Comments (0) | TrackBack (0)

2011.05.27

Java SE7

Java SE 7徹底理解 第1回 言語仕様の小さな変更 - Project Coin

私自身が実際にJava7で開発を行うようになるのがいつになるかは不明ですが(^^;

【Switch文で文字列】
・デコンパイル結果を見ると、ちょっと微妙かも・・・。
・同じ文字列から得られるハッシュ値は常に一定である、という前提のようですが、JVMのバージョンアップでハッシュ値計算アルゴリズムが変わった場合にどうなるんだろうか・・・?(まぁ、変わることはないような気もしますが)

【2進数リテラルと整数リテラル区切り文字】
・数値に区切り文字を含めることができるのは、そこそこ便利かも。
・カンマを使えず、"_"(アンダースコア)なのは仕方がないところでしょうかね・・・。

【例外のマルチキャッチと安全な再スロー】
・これは欲しかった機能かも。たくさんの例外をキャッチしなければいけないような処理の際に便利そう(例外発生時の処理の内容次第かとは思いますが)。

【ジェネリクスの省略記法】
・これも欲しかった機能かも。JavaSE5/6でのジェネリクスの記述って、微妙に冗長な感が否めないので・・・。

【リソースに対するtry節】
・これもよさげ。
・C#で言うところの、using節に似たような感じでしょうかね?

| | Comments (0) | TrackBack (0)

2011.05.26

OSQAをインストールしてみる

さて、OSQAのインストールを。環境としては、beta3がリリースされていますが、revision870の頃のもの。trunkは既に1040を超えており、リビジョンログを見るとそれなりの数の不具合が修正されている模様。ってことで、trunkのソースを用いてインストールすることに。

CentOSへのインストールは、RHEL, CentOS 5 Installation Guide のページにまとめられています。悩むのもアレなので、インストール先等は準じて、/opt ディレクトリに(オープンソースQ&Aシステム OSQAのインストール方法 も参考に)。

# cd /opt
# mkdir OSQA
# cd OSQA
# svn co http://svn.osqa.net/svnroot/osqa/trunk .
# chmod u+w cache
# chmod u+w log
# chmod u+w forum/upfiles
# mkdir db

mod_wsgiを使用するため、それ用のスクリプトファイルを準備する(テンプレートがあるので、それをコピーして使用)。

# cp osqa.wsgi.dist osqa.wsgi
# chmod a+x osqa.wsgi

sys.path.append のところ(2行)と、osqa.settings のところを書き換え。

import os
import sys
sys.path.append('/opt')
sys.path.append('/opt/OSQA')
os.environ['DJANGO_SETTINGS_MODULE'] = 'OSQA.settings'
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

DB設定等を行うファイルを準備(これもテンプレートがあるので、それをコピーして使用)。書き換えたのは以下の部分。

DATABASE_NAME = '/opt/OSQA/db/osqa.db'
DATABASE_ENGINE = 'sqlite3'
APP_URL = 'http://your.server.com'
TIME_ZONE = 'Asia/Tokyo'
LANGUAGE_CODE = 'ja'
DJANGO_VERSION = 1.3
DISABLED_MODULES = ['books', 'recaptcha', 'project_badges', 'updater', 'oauthauth', 'facebookauth' ]

DISABLED_MODULESは、そもそもどんなモジュールがあるのかを把握できていません・・・。

DBの初期化。

# python manage.py syncdb

途中で表示される以下の質問には、no を回答。

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no):

ディレクトリの所有者を設定。

# chown -R daemon:daemon .

Apacheの設定ファイルを作成。

# touch /etc/httpd/conf.d/osqa.conf

osqa.confの中身はこんな感じ。とりあえず、VirtualHostで定義。

WSGIPythonEggs /var/www/.python-eggs
Listen 8082
<VirtualHost *:8082>
  DocumentRoot /opt/OSQA/forum
  Alias /m/ /opt/OSQA/forum/skins/
  Alias /upfiles/ /opt/OSQA/forum/upfiles/
  <Directory /opt/OSQA/forum/skins>
    Order allow,deny
    Allow from all
  </Directory>
  WSGIScriptAlias / /opt/OSQA/osqa.wsgi
  CustomLog /var/log/httpd/osqa_access_log common
  ErrorLog /var/log/httpd/osqa_error_log
</VirtualHost>

ポート8082はiptablesで拒否しているので、とりあえずw3mでlocalhostから接続できることを確認。

ただ、最終的には、ポート80にまとめたいですね。URLとしては、http://servername/osqa/ でアクセスさせるような感じでしょうか。この辺はもう少し調査ですね。

| | Comments (0) | TrackBack (0)

2011.05.25

Tracの環境をPython2.6.6+mod_wsgiにしてみる

OSQAをインストールしてみたいなぁ・・・ということで、その準備を。

OSQA(およびそれが使用しているフレームワーク Django )はPython2.6や mod_wsgi を要求しているのですが、実際にOSQAの運用を行うとなった場合、おそらく、Trac/Subversionを稼働させているサーバーと同居させることになるため、Trac(現在Python2.5およびmod_pythonで動作)の環境もPython2.6およびmod_wsgiで動作させるように。

※今回は、Trac/Subversionがインストールされていない状態からの環境構築でしたが、既に稼働中の環境の移行の場合、もう少し手間がかかるかも・・・。

まずは作業用フォルダ作成およびPythonのインストール。

# mkdir /work
# cd /work
# wget http://www.python.org/ftp/python/2.6.6/Python-2.6.6.tgz
# tar zxvf Python-2.6.6.tgz
# cd Python-2.6.6
# ./configure --prefix=/usr/local/share/python2.6.6
# make
# make install
# ln -s /usr/local/share/python2.6.6/bin/python /usr/local/bin/python

mod_wgsiをインストール(http-develパッケージをインストールしておく必要があります)。

# wget http://modwsgi.googlecode.com/files/mod_wsgi-3.3.tar.gz
# tar zxvf mod_wsgi-3.3.tar.gz
# cd mod_wsgt-3.3
# ./configure --with-python=/usr/local/share/python2.6.6/bin/python
# make
# make install

easy_installをインストール。

# wget http://peak.telecommunity.com/dist/ez_setup.py
# python ez_setup.py

Trac/Subversionで使用するモジュール諸々をインストールする。なお、Subversionは都合により1.5系列を使用。ちなみに、Python2.5以降の場合、PySqliteは不要とのことなのですが、別途インストールしないとどうも動作してくれないようで・・・。

# wget http://www.clearsilver.net/downloads/clearsilver-0.10.5.tar.gz
# wget http://nchc.dl.sourceforge.net/sourceforge/docutils/docutils-0.5.tar.gz
# wget http://nchc.dl.sourceforge.net/sourceforge/silvercity/SilverCity-0.9.7.tar.gz
# wget http://subversion.tigris.org/downloads/subversion-1.5.9.tar.gz
# wget http://pysqlite.googlecode.com/files/pysqlite-2.6.3.tar.gz

細かいインストール手順に関しては省略(^^;

Tracのインストールを行い、python-eggsのテンポラリフォルダを作成。なお、Tracは、都合により0.11系列を使用しています(そのため、Subversionも1.5系列・・・)。

#mkdir /var/www/.python-eggs
#chown daemon:daemon /var/www/.python-eggs

※ServersMan@VPSのデフォルトのApacheなので、ユーザーがdaemonになっています。

Trac/Subversionのテスト用プロジェクト/リポジトリを作成(所有者変更が必要ですが、記載を省略しています)。

# mkdir /var/tracdata/trac
# mkdir /var/tracdata/svn
# cd /var/tracdata/svn
# svnadmin create test
# cd /var/tracdata/trac
# /usr/local/share/python2.6.6/bin/trac-admin test initenv

/var/tracdata/trac/trac.wsgi を作成。内容は以下のような感じ(実行権限を付与しておくのを忘れないように)。

import os

os.environ['TRAC_ENV_PARENT_DIR'] = '/var/tracdata/trac'
os.environ['PYTHON_EGG_CACHE'] = '/var/www/.python-eggs'

import trac.web.main
application = trac.web.main.dispatch_request

/etc/httpd/conf.d/trac.conf を作成。内容は以下のような感じ。

LoadModule wsgi_module modules/mod_wsgi.so

WSGIScriptAlias /trac /var/tracdata/trac/trac.wsgi
<Location /trac>
    WSGIApplicationGroup %{GLOBAL}
    Order deny,allow
    Allow from all
</Location>

Apacheを再起動して、http://servername/trac/ でアクセスすると、プロジェクト一覧が表示されることを確認。また、 http://servername/trac/test/ で作成したテスト用プロジェクトが表示されることを確認。

ちょっと気になるのは、mod_wsgi の導入に苦戦中mod_wsgi 導入完了(たぶん) に記載されている現象でしょうかね・・・(複数プロジェクトの運用を行っているので)。ただ、os.environ['TRAC_ENV']ではなく、os.environ['TRAC_ENV_PARENT_DIR']で指定しているから大丈夫なんでしょうかね・・・? Trac and mod_wsgiによると、

The TRAC_ENV variable should naturally be the directory for your Trac environment (if you have several Trac environments in a directory, you can also use TRAC_ENV_PARENT_DIR instead), while the PYTHON_EGG_CACHE should be a directory where Python can temporarily extract Python eggs.

とのことです。また、Trac と mod_wsgi では、
重要な Note: 複数の .wsgi ファイルを使用する場合 (それぞれのファイルに別個の Trac environment を設定するケースなど) は、 os.environ['TRAC_ENV'] には Trac environment のパスを 設定しない でください。この方法を使うと、別の Trac environment の設定が Trac にロードされてしまうことがあります。 (以前にロードした Trac environment のパスが使われてしまいます。) この問題は .wsgi ファイルの内容を下記の通り変更することで回避できます:

と記載されています。この部分は原文だと revision22 の頃の内容になるようですので、Tracのバージョンにより異なってくるのかもしれません・・・。

#その他参考資料:Integration With Trac

| | Comments (0) | TrackBack (0)

2011.05.24

Aipo6を自動起動させる

サーバー再起動時にAipoを自動起動するには? を参考に、自動起動の設定を実施。元はAipoの旧バージョンの時の資料ですが、Aipo6でも問題ないようです。

1)/etc/sudoers ファイルの Defaults requiretty の行をコメントアウト(cronでsudoを実行するために必要)。

2)/etc/init.d/aipo ファイルを作成。内容は以下のような感じ。

#!/bin/sh
# chkconfig: 345 99 1
# description: Aipo
# processname: Aipo
start(){
 /usr/local/aipo/bin/startup.sh
 return 0
}
stop(){
 /usr/local/aipo/bin/shutdown.sh
 return 0
}
case $1 in
 start)
  start
   ;;
 stop)
  stop
   ;;
esac

3)chmod a+x /etc/init.d/aipo で実行権限を設定。

4)chkconfig --add aipo で自動起動設定。

| | Comments (0) | TrackBack (0)

2011.05.23

Aipo6をインストールしてみた

Aipoのオープンソース版Aipo6をServersMan@VPSの環境にインストールしてみました。

Linuxへのインストール ページを参照しながらインストール。インストール先も、このページに記載されているものに合わせました( /usr/local )

コンパイル等にそれなりに時間はかかりましたが、簡単にインストール完了。Apacheが起動していたので、ポート番号は81で定義されたようです(他のTomcatが動作していても特に関係ないようですね)。ちなみに、PostgreSQLはデフォルトの5432となりましたが、他のPostgreSQLが動作していると、おそらくこれも自動的に別のポート番号になるのではないかと。

もっとも、ポート番号に関しては、Tomcat6のserver.xmlファイルで定義されているだけですので、あとからいくらでも変更可能ですが。

ただ、今回はApacheと連携させたかったので、server.xmlを書き換えて、proxy_ajpで転送するように。ただし、8009は既に使用していたので、8010で設定。

<Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />

同時に、ポート81のHttpConnectorをコメントアウト。Apache側に
ProxyPass /aipo/ ajp://localhost:8010/aipo/

の設定を追加してApache再起動。さっくりとApache経由でアクセスできるようになりました。

Aipo起動時に

eth0: error fetching interface information: Device not found

のメッセージが表示されてしまうのは致し方ないところ(ID15: 仮想サーバへインストール時エラーが出る)。

ちなみに、Entryプランだと、Tomcatの複数起動は無理っぽいですね。メモリ不足により起動失敗してしまうような感じです(苦笑)。

#Aipoは独自にユーザー管理を行っているため、他のアプリケーションと認証情報を共有させることはできないっぽいですね。

| | Comments (4) | TrackBack (0)

2011.05.22

ルートのindex.htmlに対するアクセスを別URLに転送する

http://servername/ とか、http://servername/index.html でのアクセスを、別途定義したhtmlファイルに転送したい場合の設定。実際にどの程度の必要性があるかは不明ですが、今回、以下のような環境で使用。

・Java(Teeda)で作成したあるページを、トップページとして使用したい(動的に生成)。
・ただし、/ 全体をTomcat側に転送するわけにはいかない(warファイルに対応するコンテキストルートに限り、Tomcat側に転送)。
・同一のサーバーで、他にphpアプリやPythonアプリなど、いろんなものが動いている。

ってことで、http://servername/ や http://servername/index.html に対するアクセスを、mod_rewriteで転送してしまうことにしました。

設定結果は以下のような感じ。

RewriteEngine on
RewriteRule ^/$ ajp://localhost:8009/javatools/toppage/index.html [P,L]
RewriteRule ^/index\.html$ ajp://localhost:8009/javatools/toppage/index.html [P,L]

注意点は、Pを指定する(Proxyとして転送する)ことでしょうかね。ajpで転送しているので、別途mod_proxy_ajpでの設定も当然必要となるかと思いますが、これはTomcatを使用する際に元々設定しているので、特に意識することもなく。

単純にRという手もあるのですが、これだと、ブラウザ側でのリダイレクトになってしまい、見た目のURLが変わってしまうので・・・(別に、http://servername/javatools/toppage/index.html で直接アクセスされても問題ないのですが)。

#SSL環境下で転送させる場合、設定を記述する場所に注意しなければいけない感じ? VirtualHost ディレクティブ( _default_:443 の設定を行っている箇所)の中に記述しないと、反応してくれませんでした・・・。

| | Comments (0) | TrackBack (0)

2011.05.21

Aipoのインストーラって・・・

Aipo は、インストーラでいろんなものを一式インストールするとのこと。内部でどういう処理をしているのか気になってLinux版のインストール用シェルスクリプトを見てみたところ・・・PostgreSQL等も含めて、文字通り「一式インストール」するようになっているんですね(^^;

TomcatやJRE等も自動的にインストールされるようですが、既に該当のアプリ類がインストールされていた場合にどうなるか、ちょっと気になるところです(それも考慮したインストーラになっているのかもしれませんが)。

一度試してみようかな・・・。

| | Comments (0) | TrackBack (0)

2011.05.20

XLSBeansでDate型にマッピング

Excelのデータの読込は、これまで Java Excel ApiApache POI を使っていたのですが、今回、何となく XLSBeans を使ってみました(ExCella にも興味があったのですが)。

@LabelledCell アノテーションを複数指定することで、「タイトル」的なものを複数持たせることができるんですね。で、どこからを「1行分のデータ」として認識させるのかと思っていたら、@HorizontalRecords アノテーションで tableLabel を指定すると、その次の行をヘッダー行として認識するような感じでしょうか?

で、ちょっとはまったのが、java.util.Date型へのバインドができないってことでしょうか。ソースを追ってみると、 net.java.amateras.xlsbeans.Utils#convertValue(Class type, String value) の処理で、Date型が処理されていないことが関係しているのではないかと(セルの値が String で渡されていることも関係?)。
Date型を諦めてStringにしてマッピングし、実際に使用する時にDate型に戻すことも考えたのですが、

} else if(type.equals(Date.class)) {
  if (value.length() == 0) {
    return null;
  }
  SimpleDateFormat f = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
  try {
    return f.parse(value);
  } catch (ParseException e) {
    return null;
  }
}

のような感じの処理を追加して対応。本当は、DateFormatでいろいろと考慮しなければいけないような気がするのですが、用途が限定されているので今回はこれで誤魔化しています(^^;

[XLSBeans]型変換を拡張できるようにして欲しい が近い内容のような感じですね。

| | Comments (0) | TrackBack (0)

2011.05.19

散瞳薬×晴天

快晴の真昼×散瞳薬 ⇒ めっちゃまぶしい・・・(涙)。

白い紙や白い壁は、さらにまぶしいってことを実感(笑)。

しかし、真昼に散瞳薬を点眼すると、夕方まで何もできなくなってしまいますね・・・(苦笑)。朝イチなら、昼過ぎには復活しているので、まだ何とかなるのですが。

| | Comments (0) | TrackBack (0)

2011.05.16

icalendarへのアクセスを制限する(2)

ID/PWの要否は設定できたので、次はアクセス元の制限。もっとも、アクセス元を制限できるだけなので、「無関係のGoogleCalendarのユーザー」でも、URLがわかればアクセスできてしまうことになってしまいますが・・・(複雑なURLにしておくことである程度は防止することが可能ですが、それも完全というわけではありませんし)。

それはさておき、Apache側の設定。本当は、User-Agentと接続元のホスト名でダブルチェックを行おうとしたのですが、

・SetEnvIf では、デフォルトでは Remote_Host の情報は取得できない(逆引きしていない)
・全体的に逆引きを行うように変更するという方法もあるが、いろんな事情により、できれば避けたい。
・Allow ディレクティブは、基本的に OR での条件結合となる(SetEnvIfを組み合わせることで、ある程度は回避可能ですが(参考:ApacheのAllow, Denyディレクティブでand条件した))。そのため、Allowディレクティブでリモートホスト名を指定すると、User-AgentとのAND条件にできない
・IPアドレス範囲が公開されていないので、SetEnvIf の Remote_Addr での制御は困難。

といった状況に。

ただ、よくよく考えると、わざわざUser-Agentも含めて絞り込んでも、あまり意味はないような気がしてきたので、結局、

Allow from googlebot.com

だけを指定することにしました(もちろん、Deny等、他の設定もありますが)。

ちなみに、Allowでホスト名を指定している場合、そのAllowが定義されているURLに対してアクセスされた場合のみ、逆引きが発生するようで(Apacheのアクセスログから確認)。

■その他メモ
・w3mはオプション画面(o)からUser-Agentを簡単に変更可能なので、User-Agentでのチェックテストの際にも便利。

| | Comments (0) | TrackBack (0)

2011.05.15

icalendarへのアクセスを制限する

wdCalendarの内容をGoogleCalendarに取り込む ことができるようになったのですが、GoogleCalendarでURLを指定してicalを取り込む際は認証情報を使用できない模様。つまり、URLさえわかれば誰でもスケジュールを取り込めてしまうってことに。

ということで、以下のような設定を行うことができるかどうかを検証。

1.wdCalendarで提供するカレンダーの閲覧/編集にはID/PWが必要。
2.icalendar(Teedaで提供)を取得するURLへのアクセスはID/PWは不要。
2-1.ただし、Teedaで提供している他のページへのアクセスはID/PWが必要。
2-2.認証は、Tomcat側で設定するのではなく、ApacheのBasic認証に委ねることとする。
3.icalendarへのアクセス元をGoogleCalendarに限定する。

Teedaの場合、http://server/teedaproject/appA/app1.html とか、 http://server/teedaproject/appB/app2.html のような感じで、war単位で共通のコンテキストルート(上記の場合、teedaproject)を使用。そのため、http://server/teedaproject/ 全体は原則認証を要求しつつ、http://server/teedaproject/icalapp/ のエリアのみ認証を不要とするように設定すればOK・・・のはず(あるエリアに含まれる、特定のサブエリア(サブディレクトリ)部分のみ認証が不要となるような設定を実施)。

サブディレクトリに対する設定でSatisfy anyとallow allを指定すればOKっぽい資料も見かけたのですが、どうにも期待通りの動きをしてくれません(サブディレクトリ側にアクセスしても、認証が要求される)。

それならば、Proxyの設定を工夫して、「別のURLでicalenderエクスポートページにアクセスするようにすればいけるのでは?」ということで、こちらの設定を変更。

ProxyPass /ical/ ajp://localhost:8009/teedaproject/wdcalendar/
ProxyPass /teedaproject/ ajp://localhost:8009/teedaproject/

のような感じ。ちなみに、設定の順番が逆だと、Apache起動時に、

worker ajp://localhost:8009/teedaproject/ already used by another worker

って感じでwarningが出てしまいます。どうも、転送先が「下位のURLから」順になるように指定してあげる必要があるようで。

かなり強引ではありますが、これで(期待通りの)認証の要否となる・・・はず。

| | Comments (0) | TrackBack (0)

2011.05.13

wdCalendarの内容をGoogleCalendarに取り込む

そんなこんなで、wdCalendarの内容をicalendar形式でエクスポートする仕組みを作ることができたので、それをGoogleカレンダー側にインポートしてみるテストを。

icalをエクスポートするためのURLをGoogleカレンダーに登録することで、サクッと簡単にインポートすることができました。ただ、いろいろと気になる点も・・・。

■元カレンダーを更新しても、Googleカレンダー側にすぐに反映されるわけではない
元カレンダーを設置しているサーバーのhttpログを確認してみると、6時間おきくらいにGoogleのサーバーからアクセスが来ているような感じ(Googleのサーバーからのアクセスの場合、UserAgentが Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)のような感じになるようです。
こちら のサイトでも、ただし,インポート後カレンダーに反映されるまで6時間ほど要する模様と記載されているので、そんなものなのかもしれません。ちなみに、Googleのヘルプによると、

現在、カレンダー フィードは、Google カレンダーによって数時間ごとに自動的に更新されます。 また、手動でカレンダーを更新したいというご要望も寄せられているため、この機能に対応することを検討しています。

とのことです。

■元カレンダーの既存の内容を更新しても、Googleカレンダー側に反映されない?
「元カレンダーに追加した」内容は、数時間後にGoogleカレンダーにも反映されるのは確認できたのですが、元カレンダーに既に登録していた内容を更新しても、その内容が反映されないという状況が。
iCalendarファイルのDTSTAMP、LAST-MODIFIEDか、SEQUENCE値が影響しているのかと思い、エクスポート時に毎回それらの値を更新するようにしてみました(wdCalendarのサンプルでは、それらの情報をDBに持っていないので・・・)。一応、Googleカレンダー側にも更新がきちんと反映されるようになったようです。ただ、3つの値のどれが効果があったのかは不明(^^; おそらく、SEQUENCE値ではないかと思うのですが・・・。ちなみに、wdCalendarのサンプルDBにはSEQUENCE値がないので、System.currentTimeMillis()/100000 の値をセットするようにして誤魔化しています(そのため、本来は更新がないはずなのにSEQUENCE値が増加してしまう)。

■「終日」を指定している予定がずれる
wdCalendarで「終日」を登録した場合、時刻は00:00で登録されます。終日以外だと、JSTで保存されていたのですが、iCalendarではGMTで出力する必要があったので、単純に時刻をずらしていたのですが、その結果、終日の予定が前日の15時で出力してしまっていました(^^;
あと、終日の予定の「終了日」ですが、例えば、「5/11終日」の予定は、Googleカレンダーの場合は「5/11~5/12」で扱われているようで(参考:iCalendar(rfc2445)で終日の予定のDTENDの正しい仕様は?)。なので、終日の場合、終了日を+1してエクスポートするようにして対応。

| | Comments (0) | TrackBack (0)

2011.05.12

JavaからwdCalendarのDBにアクセス

普段からphpで開発している人に取っては、wdCalendarのデータを元にiCal形式のテキストを出力する処理をphpで記述するなんて、おそらくなんてことない内容だと思われます。きっと、1時間もあればサクッと作れてしまうのではないかと。

しかしながら、私にとってはphpはほとんど未知の言語(phpで記述されたアプリのインストールや、ほんの少しの手直し(「直し」とも呼べないような内容)程度しかできない状態)。まぁ、これを機にphpの勉強をする、という選択肢もあるのかもしれませんが、事情により、Javaで記述することに(^^; wdCalendarを動作させようとしているサーバーは、幸いTomcatも動作させることができる余力はあるので。

JDBCドライバの設定をしてデータ取得のテスト(フレームワークとしてはTeeda/S2Daoを使用)。

・・・見事に、文字化け(苦笑)したので、その対処法のメモ。

参考資料:MySQL:4.1日本語問題

■mysqlの動作環境をutf8にする
/etc/my.cnf に以下の内容を記述し、MySQLを再起動。

[client]
default-character-set = utf8

[mysqld]
default-character-set = utf8
skip-character-set-client-handshake

[mysqldump]
default-character-set = utf8

[mysql]
default-character-set = utf8

■wdCalendar用のDBを再作成
setup.sql では、create tableの際にlatin1が指定されてしまっているので、utf8に変更。

ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
の部分を、
ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
に。
既にテーブルを作成している場合、 drop table jqcalendar; を実行してテーブルを削除しておきます。
データの移行が必要な場合、何らかの方法で対処する必要があります(今回は、テスト用のデータしか入力していなかったのでデータの移行なしに再作成を実施)。

とりあえず、この状態で、wdCalendarのサンプルスクリプト(php)で登録した内容を、文字化けすることなくJavaから参照することができました。もちろん、phpの画面からも問題なく表示できています。

ってことで、とりあえず環境は整った(?)ので、あとはがしがし実装するだけ・・・のはず。

#Teedaで使うdiconファイル等の設定も含め、ここまでの作業時間は1時間程度。う~ん・・・(苦笑)。

| | Comments (0) | TrackBack (0)

2011.05.11

FTPで共通(?)htmlファイルをアップロードする

【やりたいこと】
・ユーザー毎のhtml公開フォルダは不要(http://hostname/~username/ のような構成は不要)。
・できるだけ簡単な方法でサーバー上のhtmlファイルを更新したい。
・htmlファイル更新時、それ以外のフォルダへのアクセスを許可したくない。

【やってみたこと】
・FTPサーバーをインストール(CentOSにおいて標準で提供されているvsftpdを利用)。
・FTP用のアカウント(例:vsftpduser)を追加し、パスワードを設定。
・/home/vsftpduser/documents フォルダを作成し、ownerをvsftpduserに変更。
・ln -s /home/vsftpduser/documents /var/www/html/documents でシンボリックリンクを作成。
・httpd.confにおいて、FollowSymLinks が設定されていることを確認。

【結果】
・http://hostname/documents/ にアクセスすると 403。
・サーバーのログを確認すると、Symbolic link not allowed or link target not accessible:のエラーが。
・調べてみると、/home/vsftpduser の権限設定が700になっていることが原因の模様。

【対応】
・chmod a+x /home/vsftpduser を実行して権限設定を変更することで、ブラウザからアクセス可能に。
・また、ftpクライアントでアップロードしたファイルにアクセスできることを確認。

【気になる点】
・さすがに、homeの権限設定を変更することは躊躇してしまいます・・・他に、何かいい方法があればいいのですが。
・とはいうものの、単にhtml転送用のアカウントと割り切り、また、FTPへのアクセス制限(アクセス可能なユーザーの制限や接続元の制限)を行い、FTP接続用のユーザーでssh接続等を行えないようにすることで、それなりのセキュリティを担保することができるのでは?(まずは、useraddを行う際に /sbin/nologin を指定するとか)

とりあえずはこれで対応しますかねぇ・・・。

| | Comments (0) | TrackBack (0)

2011.05.10

wdCalendarの登録内容をical形式で(そもそも、書式は?)

wdCalendarの登録内容をiCalendar形式でエクスポートできないかなぁ・・・と思って、調査。
とりあえず、サンプルのフロントエンドにはそのような機能はなさげ。

そもそも、iCalendarの書式は? ってことで、見かけた参考資料。

iCalendar 仕様
googleカレンダーに予定をインポートする書式
iCalendar形式の最低限の書式メモ

あと、参考にしたのは、実際にデータが入っているGoogleCalendarからエクスポートしたicsファイル(必然的に、書式は上から2つ目のリンク先の内容と重なりますが)。

う~ん・・・。iCalendarの書式って、定義されているようで、ある程度は柔軟な感じ? まぁ、実際に私自身でRFCを読んだわけではないので、どこまでが必須で、どれが任意項目なのか把握できていませんが。

とりあえず、無理矢理以下のようなphpスクリプトを作成してみました。

<?php
header('Content-type:text/calendar;charset=UTF-8');
echo "BEGIN:VCALENDAR\n";
echo "PRODID:-//Example//Static Text//EN\n";
echo "VERSION:2.0\n";
echo "CALSCALE:GREGORIAN\n";
echo "METHOD:PUBLISH\n";
echo "X-WR-CALNAME:TestCalendar\n";
echo "X-WR-TIMEZONE:Asia/Tokyo\n";
echo "BEGIN:VEVENT\n";
echo "DTSTART:20110501T000000Z\n";
echo "DTEND:20110531T000000Z\n";
echo "DTSTAMP:20110509T000000Z\n";
echo "CREATED:20110211T000000Z\n";
echo "DESCRIPTION:\n";
echo "SUMMARY:TestEvent No.1\n";
echo "LOCATION:Example\n";
echo "TRANSP:OPAQUE\n";
echo "END:VEVENT\n";
echo "END:VCALENDAR\n";
?>

で、Google Calendarで http://servername/calendar/test.php のような感じでカレンダーを追加してみると、とりあえずそれっぽい内容が表示されました。

ただ、表示される時刻が意図したものと違っていたり、そもそも、日本語を含んだテキストで試していなかったり、まだまだ調査しなければいけませんが・・・(そもそも、DBからデータ取得する処理を書く必要がありますし)。

#phpは普段縁がないので、書き方が全然わからない・・・。

| | Comments (0) | TrackBack (0)

2011.05.09

wdCalendarのsample.phpの初期表示を変更する

wdCalendarに付属しているsample.phpはデフォルトでは「週間」表示となっています。

これを「月間」表示にしてみたので、そのメモ。

sample.phpの・・・

(1)

var view="week";

の部分を、
var view="month";

に変更。

(2)

<div id="showweekbtn" class="fbutton fcurrent">

の部分を
<div id="showweekbtn" class="fbutton">

に変更。

(3)

<div id="showmonthbtn" class="fbutton">

の部分を
<div id="showmonthbtn" class="fbutton fcurrent">

に変更。

(2)(3)の変更を忘れると、「月間表示」されているのに、「週間」のボタンが選択されている状態になってしまいます。

| | Comments (0) | TrackBack (0)

2011.05.08

wdCalendarのデータ抽出に関して

wdCalendarで以下のようなデータを作成。

2011/05/01-2011/05/07 の期間のスケジュール①を作成。システム日付 2011/05/08 の状態で「週間」スケジュール(2011/05/02-2011/05/08)を表示。

この状態だと、スケジュール①の内容が表示されません。一度月間スケジュールに変換してから再度週間スケジュールを表示すると問題ないのですが・・・。

調べてみると、おそらく、データ取得の条件文の問題ではないかと。ということで、php/datafeed.php の内容を修正してみました。

    $sql = "select * from `jqcalendar` where `starttime` between '"
      .php2MySqlTime($sd)."' and '". php2MySqlTime($ed)."'";

の部分を、

    $sql = "select * from `jqcalendar` where `starttime` between '"
      .php2MySqlTime($sd)."' and '". php2MySqlTime($ed)."' or `endtime` between '"
      .php2MySqlTime($sd)."' and '". php2MySqlTime($ed)."'
";

って感じで、endtimeも条件に含めるとよさげです。

・・・と思ったら、画面を切り替えた際(「前の週」を表示して開始日が表示期間内に含まれた場合)に同じ予定が2行表示されてしまうケースが・・・。

もう少し見直しが必要ですね。

| | Comments (0) | TrackBack (0)

2011.05.07

wdCalendarをCentOS5.5にインストールしてみた

Webベースで使えるカレンダーアプリを物色中・・・。
主な要件としては・・・

1.インストールが簡単
2.複数日に渡る予定を登録可能
3.操作が簡単
4.見た時に全体としてのスケジュールを目視しやすい

って感じでしょうか。「人別」でカレンダーを表示できる必要はなく(チーム全体としてのスケジュールが欲しい)、GoogleCalendarのような感じのものがいいなぁ、と(笑)。

で、探してみると、wdCalendar – jQuery Based Google Calendar Clone がいい感じ(phpで動作)。できればDBも不要な者が欲しいところですが、まぁ、これは許容範囲か・・・。

wdCalendarそのものはライブラリで、これを組み込んだアプリの開発を行うこともできますが、アーカイブに含まれているsample.phpでも充分使えそうな感じですね。セットアップの資料がほとんど見つからなかったので、とりあえず、CentOS5.5にインストールした時のメモを。

php(5.1.6)とMySQL(5.0.77)をyumでインストール。なお、wdCalendarは元々php5.2以降を前提としているようで、5.1.6で使用した場合、

PHP Fatal error: Call to undefined function json_encode()

のエラーを吐いて動作しないので注意が必要。php5.1でjsonライブラリを使用する場合、pecl経由でインストール可能とのことなので、php-develおよびphp-pearパッケージもインストール(参考:【PHP】json_decode, json_encodeを使えるようにjsonをインストール)。

# yum install php mysql mysql-server php-mysql php-devel php-pear
# pecl install json
# touch /etc/php.d/json.ini

json.iniの内容は以下の1行のみ。

extension=json.so

データベースの初期設定(rootのパスワード変更等もあわせて実施)。なお、下線の部分は任意の文字列を使用可能です。

# /etc/init.d/mysqld start
# /usr/bin/mysqladmin -u root password '.....'
# mysql -u root -p
Enter password:
mysql> create database wdcalendar;
mysql> grant usage on *.* to wdcalendar@localhost identified by 'wdcalendarPassword';
mysql> grant all privileges on wdcalendar.* to wdcalendar@localhost;
mysql> (ctrl+d)

wdCalendarのモジュールをダウンロードし、解凍&データベース準備。下線部分は各環境に応じて。

# wget http://www.web-delicious.com/jquery-plugins-demo/wdCalendar.zip
# unzip wdCalendar.zip
# cd /var/www/html
# mv ~/wdCalendar ./calendar
# cd calendar
# mysql -u wdcalendar -p wdcalendar
Enter password:
mysql> \. setup.sql

php/dbconfig.php の内容を以下のように編集(下線部分は(以下略))。

<?php
class DBConnection{
        function getConnection(){
                mysql_connect("localhost","wdcalendar","wdcalendarPassword") or
         die("Could not connect: " . mysql_error());
                mysql_select_db("wdcalendar") or
                     die("Could not select database: " . mysql_error());
        }
}
?>

ファイルのリネーム(および不要なファイルの削除)、ファイルの所有者の変更。

# rm setup.sql
# rm edit.php
# mv edit.db.php edit.php
# rm php/datafeed.php
# mv php/datafeed.db.php php/datafeed.php
# cd ..
# chmod -R apache:apache calendar

CentOS5.x のパッケージでインストールしたphpの場合、

Call to undefined function date_parse() in /var/www/html/calendar/php/functions.php on line 24

というエラーも発生してしまうので、[PHP-users 33070] Re: PHP Fatal error: Call to undefined function date_parse()を参考に、php/functions.php を編集。

function mySql2PhpTime($sqlDate){
    //$arr = date_parse($sqlDate);
    $arr = getdate(strtotime($sqlDate));
    //return mktime($arr["hour"],$arr["minute"],$arr["second"],$arr["month"],$arr["day"],$arr["year"]);
    return mktime($arr["hours"],$arr["minutes"],$arr["seconds"],$arr["mon"],$arr["mday"],$arr["year"]);
}

Apacheを再起動し、http://(hostname)/calendar/sample.php でアクセスすると、とりあえずカレンダーが表示されるかと。

| | Comments (0) | TrackBack (0)

2011.05.05

車・車・車・・・

急用ができて高松日帰り。行きは新幹線&マリンライナーだったのでラクだったのですが、帰りは高松~京都の高速バスを利用(名神高槻下車)。

・・・やっぱ、帰りもJRにすれば良かったかなぁ・・・。予定では3時間のところが、5時間半ほどかかりました(涙)。

・高松自動車道の大坂トンネル ⇒ 高松自動車道で渋滞すると言えばこの場所。
・鳴門西PA付近 ⇒ 2車線から1車線に減少することが関係?
・淡路~洲本 ⇒ 何故?? というか、淡路島で渋滞する理由がいまいちよくわからない・・・(^^;
・宝塚西トンネル ⇒ ここは定番ですね(苦笑)。
・中国豊中~中国吹田 ⇒ ここの渋滞はちょっと珍しいような?

ちなみに、淡路島の渋滞を回避するため、西淡三原~淡路を下道に、山陽自動車道の代わりに阪神高速北神戸線(7号線)に切り替えての運行でした。北神戸線を使っても、宝塚西トンネルの渋滞の完全回避はできませんが、場合によっては半分以上回避できますからねぇ。

途中で休憩をとった道の駅「淡路」で、普段は見ない近さで明石海峡大橋を見ることができたり、淡路島の西海岸沿いから眺めた夕日が綺麗だったりしたので、まぁ、良しとしますか(^^;

| | Comments (0) | TrackBack (0)

2011.05.02

交響組曲「ドラゴンクエスト」

スクウェア・エニックス、「ドラゴンクエストの思い出」をTwitterで募集 ・・・で、Twitterのメッセージを見ていると、妙に懐かしさがこみ上げてきてCDを衝動買い(笑)。

・交響組曲「ドラゴンクエストI」「ドラゴンクエストII 悪霊の神々」
・交響組曲「ドラゴンクエストIII そして伝説へ・・・」
・交響組曲「ドラゴンクエストIV 導かれし者たち」

いくつかのバージョン(交響楽団)があるようですが、今回購入したのはロンドンフィルハーモニー版。特に「何かが決め手」というわけではないのですが(^^;
ちなみに、I~IVまでしか購入していないのは、プレイしたことがあるのがI~IVだけ(Iは人の家でちらっとプレイしただけで、自分でクリアしたのはII~IVの3作品だけ)というのが理由(笑)。

某雑誌で、「何故、主人公は最初から『勇者』と呼ばれているのに、丸腰の状態なのか? せめて、その街で売っている最高の装備を与えてあげても良いのでは?」という突っ込みがあったというのも懐かしい記憶。

プレイしたのが20年以上も前(全てFC版)で、V以降やI~IVの復刻版(?)等は一切プレイしていないので、記憶もかなり薄れてしまっていますが、BGM類に関してはいろいろと打ち込みをしてました。元がPSG×3和音で、CD買うと楽譜が付いてきたりしていたので、それを見ながら音色を割り当ててみたり(FM音源だったりLA音源だったりPCM音源だったり)、他の音やドラムを追加してみたり。

ゲーム音楽で強烈なインパクトを受けたのはYsII(の TO MAKE THE END OF BATTLE)でしたが、ドラクエの音楽も好きでした(他には、MOTHERのBGMも良かったです)。定番なところでは「冒険の旅」などのフィールドBGMも好きですが、そのシーンにすごく当てはまっていたと感じたのが、IVの「エレジー」でしょうか。悲しい(もの悲しい)曲で一番印象に残っている曲かな・・・。

昔はハードウェアのサウンド能力の制限とも関連して、いろんなアレンジ版が出ていましたが、最近はどうなんでしょう?(最近のGM業界って全然知らないので・・・) 通常のプレイ中のBGMにふんだんな性能を盛り込めるから、想像を具現化する余地があまりないような。

#もっとも、アレンジ版が出ていたのも、一部のゲームに限られていたのかもしれませんが(日本ファルコムのYsシリーズはかなりたくさん出ていましたけど)。


| | Comments (0) | TrackBack (0)

2011.05.01

SB-700

スピードライトSB-700

とりあえずマニュアルを読み読み。結構いろんな設定があるんですね・・・なかなか難しそうです。

普段はD7000側はマニュアル露出設定で使っているのですが、SB-700使用時はファインダー内の露出計があまり当てにならないようなので、基本は絞り優先オート(+露出補正)になるんでしょうか。試しに何枚か撮影してみたのですが、ファインダー内は明らかに露出不足なのに、いい感じで写ってました(レンズはタムロンA09NII)。絞りの値を変えると、SB-700のパネルで撮影可能な距離が変わっていましたので、その範囲内では自動的に露出が調整されるってことなんですね。

しかし、SB-700使用(絞り優先)/SB-700なし(マニュアル)の使い方だと、設定変更を忘れてしまうこと多そう(笑)。

ちなみ、SB-700の方は、i-TTL調光モード、マニュアル発行モード、距離優先マニュアル発行モードがありますが、こちらは少なくとも当分はi-TTL調光モードばかり使うことになりそうです。というか、それ以外のモードって使う機会が出てくるのかどうか?(^^; もちろん、シーンに応じて使い分けた方がいいとは思うのですが。

#しかし、(カメラのキタムラの)ホームページには納期数週間と書かれていたのに、3日で到着するとは(笑)。他の店舗に在庫があったから早かったんでしょうかね?(どこにも在庫なしだともっと時間がかかったんでしょう)

| | Comments (0) | TrackBack (0)

« April 2011 | Main | June 2011 »