2009-12-17

Scriptでコンテンツタイプの変換 (Plone)

plone-usersのML(海外)をチェックしていたら、普段はぜんぜん英語についていけないのですが、たまたま目に留まったのでメモします。

内容は、オブジェクトのコンテンツタイプを変更する、というもの。
ざっと見ると、ExFileで作成したコンテンツを、スクリプトでATFileに変更する際の質問でした。

『おお!』と思ったのは、そのもの、タイプを変更する手順です。

Ploneに特殊なコンテンツタイプの場合は変更は難しいのですが、ちょうどバイナリファイルのタイプの扱いに悩んでいたところです。

Data.fsの肥大化は避けたいと思い、plone.app.blobを使ってファイルの格納先をファイルシステムにしたのはいいのですが、保存されるファイル名がなにやらハッシュのため、どうも今ひとつな印象を持っています。

可能なら、いったんblob化されたATFileをExFileとかに変えたいなあと思っていたのですが、膨大(?)かもしれない数を自分で1つ1つ間違いなく取り出すのは至難の業です。

なにかできないかな、と思っていたところに、こちらの記事でした。(こちらの場合は、ExFile –> ATFileへの変換なので、パターンは逆ですが)

まだ何も試してはいませんが、ソースが出ていましたので、とても参考になりました。

2009-12-11

ezFAQを入れてみました (Redmine0.8.7)

現在稼動中のRedmineを、0.8.7にアップデートするために、いろいろ動作確認をしています。Redmine本体は問題ないのですが、心配なのはPluginまわりです。

今回は、r-labsで提供されている、Redmine0.8x対応の ezFAQ を組み込もうと、プラグイン追加の処理を行いました。
(※ezFAQ本家のtrunkは、Redmineのtrunk / 0.9x のみの対応です)

さて、動作確認をしたところ…。

新規投稿のところで、いきなりエラーが発生してしまいました(^^;
画面には特にエラーメッセージが出ずに、『真っ白』…。

しかし、前の画面に戻って、FAQの一覧表示画面を参照すると、ちゃんとFAQのエントリは作成されています。

production.log に表示されたエラーは、以下の通りです。

ActionView::TemplateError (Translation value "FAQ %s は %s によって更新されました。" with arguments [{:title=>"#11", :author=>#<User id: 3, login: “…….", hashed_password: "", firstname: "xx", lastname: "xxx", mail: "xxxxx", mail_notification: false, admin: true, status: 1, last_login_on: "2009-xx-xx 08:35:37", language: "ja", auth_source_id: 2, created_on: "2008-02-14 13:31:34", updated_on: "2009-xx-xx 09:26:19", type: nil>}] caused error 'too few arguments') on line #1 of faq_mailer/faq_add.text.html.rhtml:
1: <%= l(:text_faq_added, :title => "##{@faq.id}", :author => @faq.author) %>
2: <hr />
3: <%= render :partial => "faq_text_html", :locals => { :faq => @faq, :faq_url => @faq_url } %>

    vendor/plugins/gloc-1.1.0/lib/gloc-internal.rb:93:in `_l'
    vendor/plugins/gloc-1.1.0/lib/gloc.rb:19:in `l'….

 

どうやら、メール送信用のテンプレートでエラーが発生している模様。素直にメッセージを読むと、Transrationのための引数が足りてない、とのことです。でも、前後のソースを読むと、引数は足りているっぽい。

どうしたものかしら…と思ったのですが、このエラーは新規登録の時だけで、更新の場合にはエラーが出ていません。(更新の場合も、models/faq_mailer.rb でメール送信の処理を行っています)

ja.ymlなどの言語ファイルを見ても、更新と新規登録の際のフォーマットはほとんど同じ。

なぜだろう…と思って、views/ 以下のファイルを比べてみたところ、微妙な違いがありました。

  1. faq_add.text.html.rhtml
    <%= l(:text_faq_added, :title => "##{@faq.id}", :author => @faq.author) %>
  2. faq_update.text.html.rhtml
    <%= l(:text_faq_updated, "##{@faq.id}", @faq.author) %>

こちらを、後者(2)のように治したところ、ひとまずエラーが回避できました。Railsの多言語化のところでひっかかったのだろうなあ..。とは思うのですが、同じRedmien0.8.7を使っていても、エラーになるのは私だけかもしれません。(ちなみに、ezFAQのtrunkでは、(1)の記載で統一されています)

ちゃんとRORを理解せずに使いだしたので、これはいけないなあ…と思い始めた今日この頃です….。

2009-12-10

Redmineの(なんちゃって?)SSO対応

現在利用中のRedmineですが、同一ドメインで動かしているWebアプリケーションとSingle Sign Onで運用できたらいいなあ…と思い始めました。

※ なお、Redmineも他のアプリケーションも、IDとパスワードについては同じLDAPを参照しているので、少なくとも、IDとパスワードは一元化されています。

そこで、RedmineとSSOをキーワードに検索をしてみたところ、以下の記事がヒットしました。(Redmine.org本家のフォーラムです)

Running redmine on Apache2 on Windows; using SSPI authentication; is it possible?

上記の内容では、Apacheの環境変数に入ったユーザ情報を、RemineのApplicationControllerで取得して、Sessionに格納されているUserIdの代わりに利用する、というものでした。

わたしの環境では、WindowsのSSOではなく、また、Apacheの環境変数にもユーザを識別する情報は入らないのですが、なんらかの方法でユーザIDを取得して、ここだけ修正すれば問題なさそうです。

 if session[:user_id]
# existing session
(User.find_active(session[:user_id]) rescue nil)
+elsif (forwarded_user = request.env["HTTP_X_REMOTE_USER_6E3RZQKX"])
+ # web server authentication
+ (User.find_by_login(forwarded_user) rescue nil)

elsif cookies[:autologin] && Setting.autologin?
# auto-login feature
User.find_by_autologin_key(cookies[:autologin])


Apacheの基本認証であれば request.env[“REMOTE_USER”]を指定すればいいし、Cookieなどであれば、cookies[“….”]で値を拾って処理すれば大丈夫でした。



動作としては、以下のようになりました。(Apacheの基本認証の例)




1. Redmineのログインフォームから認証済みであれば、そちらをまず利用。

2. Redmineにログインしていない場合で、Apacheの認証済みの場合、その情報を利用。



3. ただし、Apacheの認証を行っていても、Redmineのユーザ登録を行っていなければ、User.find_by_login でヒットしないため、匿名アクセス扱いになる。




どちらの認証も済んでいるのであれば、Redmine本来のセッション情報のほうが優先されます。

やってみると、少しの調整で済んだので、大変ありがたいです。


逆に、Redmineに認証済みで、その情報を他のアプリにも渡したいとなると、Redmineから他のアプリからも取得できるようなCookieをセットしてもらうとか、ユーザ情報を返すAPIを追加するとか、ちょっと面倒ですね…。



他にいろいろ(もっと良い)方法があるかと思いますので、見つかったらまた追記したいと思います。

2009-12-07

Plone3.3.2 –> python-ldap-2.3.10 が入らない!

順序がちぐはぐですが、Plone3.3.2の覚え書き。

一番最初の構成は成功したので、次に必須であるLDAP対応のPloneを構成しようと思いました。

こちらは、いろいろ参考にさせていただいている、清水川さまの設定に倣って、LDAP用のプロダクトを追加しました。

  • Products.LDAPMultiPlugins
  • Products.LDAPUserFolder

buildoutなので、依存プロダクトなどは勝手に追加されるはず…。

ところが。

PythonはOSにインストールしたpython2.4.6 を利用しているんですが、buildoutの途中に python-ldap-2.3.10 のインストールのステップが入るのですが、これがどうしても失敗してしまいます。

前に作ったStandaloneのPlone(Plone3.3)では、python-ldapは別途、setup.py でインストールして、Products.LDAPMultiPlugins なども buildoutではなく /Products に追加する形で動かしていたので、そちらの構成と見比べてみました。

Plone3.3のほうは、python-ldap-2.3.8 で、バージョンが古いものになっています。こちらのソースが残っていたので、pythonのモジュールとして組み込んでみましたが、Plone3.3.2のbuildoutでは、このバージョンではNGの模様。
相変わらず、python-ldap-2.3.10 のインストールを促され、途中で失敗となりました。

では、と思って、python-ldap-2.3.10 のソースをダウンロードして setup.py してみたところ、これもNG!

どうすればいいんだ~!と困り果て、再度清水川さまの記事を見ると、ちゃんと、python-ldap-2.3.10 のインストールで不具合がある旨の記載がありました…。

こちらを眺めると、HEADリビジョンは修正がなされているらしい書き込みがあったので、CVSリポジトリからチェックアウトしてみることにしました。

# cvs -d:pserver:anonymous@python-ldap.cvs.sourceforge.net:/cvsroot/python-ldap login

# cvs -z3 -d:pserver:anonymous@python-ldap.cvs.sourceforge.net:/cvsroot/python-ldap co -P python-l
dap

#ちなみに、使っているCentOSには、CVSは入っていません…。せめてSVNなら良いのに、と思いつつ、yum install cvs してしまいました。

ということで、上記のソースを再度、setup.py してみると、あっさりインストールが完了。buildout も通るようになりました。

buildoutの出力を眺めてみると、インストールされたHEADのpython-ldap は python-ldap-2.3.11 でした。

こちらは、まだhttp://pypi.python.org/ には登録されていない模様ですが、いずれ対応するのかと思います。

とりあえず、清水川さま、ありがとうございました!

Plone3.3.2のインストール(以前)

※続きがあるかどうかは不明ですが、自分用の覚え書き。

現在使っているPlone3.3は、Unified Installerの形式になってから、初めて作ったものです。以前のPlone2.1xも、Windows環境だったので、本来の正しいZope/Ploneの作り方がわかっていたわけではありませんが、Unified Installerになってからは、buildoutやら easy_installやら、さらに謎の世界になっていました。

あれこれ思考錯誤しているうちに、なんとかPlone3.3の利用にこぎつけたものの、パフォーマンスやバックアップの問題が出てきて、やっぱりちゃんと理解して作らないとだめかなあ…と(いまさら)思うようになりました。

特に、PackやIndexの再構築の際、CPUの負荷が上がってしまい、閲覧専用の動作にも支障をきたすようになっ(てしまいました。VarnisやCacheの調整を行ってみましたが、こちらもZope側とのセッションでタイムアウトが発生したりすると、お手上げです。

作り直すなら、まだユーザの少ないうちに…と思い、改めて別環境にPloneをインストールすることにしました。(もちろん、本番は問題を抱えながらもそのままですが)

今回は、先の経験を踏まえ、以下のような方針にしてみました。

  • Pythonのバイナリ は、Unified Installで /usr/local/Ploneに専用に追加されるものではなく、先にOSにインストールした /usr/local/python を利用。
  • CentOS付属のPython2.3は削除もしくはそのまま残し、Zopeに対応するバージョンを別途インストール。
  • 管理用のプロセスと通常利用のプロセスを分けられるように、ZEOの構成をとる。
  • blobは引き続き利用。
  • なんでもかんでもbuildout.cfgに記載してインストールをすることは避ける(不要なプロダクトは追加しない)
  • 本番環境ではbuildoutは使えない点に注意し、ソースを個別にダウンロードしてのeasy_install, setupに慣れるようにする。

一番の課題は、やはりZEOに慣れる、実際に使えるかどうか評価することです。幸い、easy_install や buildout はおぼろげながら慣れてきているので、まっさらな状態で開始するよりはマシかな、と思っています。

また、Plone3の情報も、日本語のリソースも含め、今年の春の段階よりもずいぶん増えてきています。(これは本当にありがたいこと)

さて、どうなることやら。
続きは次のエントリで…(^^;

2009-11-29

Reflecto & plone.app.blob を入れましたが…。

Plone2.1.3の時は、サイズの大きいPDFや画像、バイナリドキュメントは、Data.fsには保存しませんでした。代わりに、PloneLocalFolderNGというファイルシステム連携のプロダクトがありましたので、Data.fs のサイズを抑えつつ、こちらを便利に使っていました。

このプロダクトの良いところは、以下の通り。

  • Ploneの認証機能を利用しつつ、ファイルシステム上のコンテンツをマウントし、公開できる
  • コンテンツのインデクシングにも対応していて、ファイルについてのコメントやタイトル(ファイル名とは別)も、メタデータとして保持することができる
  • ファイルシステム側からコンテンツを登録することも、Ploneの側からコンテンツを登録することも可能

Ploneの稼動するサーバは、ActiveDirectory (AD) のメンバサーバーだったので、ファイルシステムからの書き込みはADで定義した編集用のユーザグループに許可していました。

同様に、Ploneを通しての書き込みも、PloneとLDAP(AD)の連携機能で、ADの編集用グループをPloneのメンバーグループに割り当てて権限設定を行っていました。

この機能があったおかげで、チーム内のPlone利用がどんどん進みました。特に、たくさんのコンテンツを一度に公開する場合、WebUIでアップするのは面倒です。定期的にプログラムで生成した、たくさんのコンテンツを公開する必要があったのですが、PloneにはWebDAV機能があると言っても、Windowsのクライアントがあまりよくなかったりして、ほとんどファイルシステム側からの操作が中心でした。

さて、Plone2.5が出るようになってから、残念ながら、PloneLocalFolderNGの開発は止まってしまったようでした。
プロダクトの公開はされているものの、Plone3には対応していませんので、このまま利用するわけには行きません。

何か代替案を考えないと…と、いろいろ探したところ、Reflecto というプロダクトを発見。
使ってみると、LocalFolderNGほど自由度は無く、メタデータの付加などは出来ないけれど、ローカルファイルシステムのファイルをPloneを通して表示でき、また、コンテンツのインデクシングも可能な模様です。

※ただし、文字コードはPloneサイトにあわせたもの、(常はUTF-8)でないといけません。

もう1つ、ファイルシステムにドキュメント(バイナリデータ)を保存するためのプロダクトとして、plone.app.blob というものがありました。

ZopeのDBはわたしにとってはブラックボックスなので、まずはこちらも導入してみました。
一見、何事もなくファイル(Office系ドキュメント)のアップロードや登録ができるようになったのですが、『実際のファイルはどこにあるんだろう?』という、根本的な疑問が沸いてきました…。

blobを利用するに当たって、zope.confに格納先を指定するのですが、その下を見てみると、0x00 ….. というディレクトリが何階層もできており、その先に、xxxxxx.blobというファイルがありました。

たとえば、こんな感じです。

0x00/0x00/0x00/0x00/0x00/0x16/0x4b/0x6e/0x0xxxxxxxxx.blob

ファイル名は、なにかしらハッシュを使って生成しているのだと思われます。でも、本来のファイル名を推測できる情報が、パスだけでは分からないので、plone.app.blobを使った場合も、ブラックボックスが単純に増えた…という感覚です(^^;

データの出し入れがWEBのインタフェースを通したアクセスのみの場合は、これで問題ないと思いますが、やはりファイルシステム側から更新することも、ZOPEを介さずに単独でデータを開くことも難しくなってしまいました。

Data.fsの肥大を防ぐという意味ではOKなのですが、なかなか悩ましいところです。

やっぱり、自分でプロダクト作るしかないのかな…と思うこのごろです。

2009-11-25

TS Web Access が効かない~!

もろもろの理由で、Windows Server 2008 R2をインストールすることとなりました。

2008に触るのは、これがはじめて。

せっかくなので、新機能のTS Web Accessを試そうといろいろ設定をしてみました。

ローカルでのTS Web Accessは動作確認が取れたので、クライアントマシンから、Web経由でアクセスしようと試みたのですが、どういうわけか、以下のメッセージが出て、機能が使えません(x_x)

リモート デスクトップ サービスの ActiveX クライアント コントロールを使用できません

クライアントマシンは、Windwos XP SP3で、RDCクライアントもちゃんと6.1にUpdateしています。MSの推奨環境をチェックしても、その設定どおりなのに先に進めません…。

日本語で検索しても、これといった解決策が見つかりません。

ついに、英語のサイトも範囲を広げたところ、以下のBlogがヒット。

Remote Desktop Services (Terminal Services) Team Blog

こちらのエントリの最後のほうに、わたしと同様の現象らしきコメントがあり、そちらのアドバイスには、レジストリキーを削除したら動いた、との記載がありました。

regeditで確認すると、なるほど、そういうキーがあります。

OSは再インストールしてもいいや、という気でいたので、ためしにキーを削除してみると、IEの再起動、OSの再起動をしなくとも、あっさり解決(^_^;;;;

  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Ext\Settings\{7390f3d8-0439-4c05-91e3-cf5cb290c3d0}
  • HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Ext\Settings\{4eb89ff4-7f78-4a0f-8b8d-2bf02e94e4b2}

なお、レジストリをいじった際の不具合は、一応自己責任ということになりますので、ご了承を…。

remoteTS

2009-10-16

CentOS 5.3にVarnish

申し訳ないですが、簡単にメモ。

yumによるネットワークインストールができない状況で、varnishをインストールしたいのだけれど、どうしたらいいのか分からない。

sourceforgeからソースを取ってきて、コンパイルするものの、うまく起動しないです…orz

やっとのことで見つけたRPMは、Fedoraのサイトからでした(^^;

これで、RPMコマンドで、やっと入りました…(もちろん依存するパッケージやバイナリは別途追加の上です)

# rpm -ivh varnish-libs-2.0.4-1.el5.i386.rpm varnish-2.0.4-1.el5.i386.rpm

2009-10-07

PloneFormGen

今回は、PloneFormGenについて。

このプロダクトを使うと、コーディングの知識とかがなくとも、また、Plone/Zopeの管理者権限が無くとも、簡単に『連絡』フォームのようなものが作成できます。
凝ったレイアウトはできませんが、通常、入力フォームは上から下にレイアウトして行けばいいので、その点は問題なし。プルダウンやチェックボックスなども、コンポーネント化されているので、面倒なHTMLを書かなくとも、GUIっぽく追加、位置を調整するだけで済みます。
ploneFormGenのスクリーンショットプロダクトに関しては、以下のサイトにとても詳しく書かれていますので、ご興味のある方は、ぜひどうぞ 。
(作者のお二方、本当にありがとうございます!)

  1. nyusukeさま / http://nagosui.org/Nagosui/COREBlog2/ploneformgen
  2. 鈴木たかのりさま / http://takanory.net/takalog/946
    ※メールのJIS化についても、2の鈴木さまの方法で対応できました。

さて、動作確認のため、簡単なフォームを作ったのはいいのですが、気になる点が2つほど出てきました…。

  1. メッセージをPOSTした本人には、メッセージのコピーがCCという感じで送信されたりしない。
  2. jaMailHostと組み合わせると、添付ファイル(テキスト)がうまく扱えないらしい。(添付ファイルがtext/plainの場合、メール本文中にインライン展開されるが、その際のエンコーディングがasciiで文字化けしてしまう)

1点目は、ZMI上のテンプレートやスクリプトで対応できるかしら、と思ったのですが、どうやらそうではなさそうです。
差出人のアドレス(replytoというフォーム名)の値は、毎回動的に変わりますが、ToおよびCCは編集画面で指定した値が固定になってしまいます。

Poiもそうなのですが、投稿者本人にも内容をCcして欲しいなあと思ったので、ソースを見て修正してみることに。

PloneFormGenは、buildout.cfgでeggs = に指定していたので、ソースを修正してコンパイルしてくれるように、buildout.cfg を変更しました。

# Provide the *paths* to the eggs you are developing here:
develop = src/Products.SecureMailHost
          src/Products.PloneFormGen

つぎに、それらしい箇所を見つけたので、修正してみました。
修正ファイルは、以下です。

  • PloneFormGen/content/formMailerAdapter.py

返信用のReplyToは、reply_addr という変数に入ります。この値をCCに追加できれば良いので、次にCCの指定をしている箇所を探しました。

headerinfo['Cc'] = self._destFormat( cc_recips ) という一行があったので、ここでCCを指定しているはず。
ここにreply_addrを追加すればいいや…と思って、以下のような感じにしてみました。

headerinfo['Cc'] = self.secure_header_line(reply_addr) + ',' + self._destFormat( cc_recips )

無理やりですが、めでたくCCにPOSTした本人も加わったみたいです…。

もう一点のほうは、すごく安直?な方法ですが、インライン展開させず、ほかのコンテンツタイプ(画像やバイナリ)などと同じ扱いにすることにしました。

#if maintype == 'text':
#    msg = MIMEText(content, _subtype=subtype)
#elif maintype == 'image':
if maintype == 'image':
    msg = MIMEImage(content, _subtype=subtype)
elif maintype == 'audio':
    msg = MIMEAudio(content, _subtype=subtype)
else:
    msg = MIMEBase(maintype, subtype)
    msg.set_payload(content)
    # Encode the payload using Base64
    Encoders.encode_base64(msg)

# Set the filename parameter
msg.add_header('Content-Disposition', 'attachment', filename=filename)
outer.attach(msg)

つまり、mimetypeがtextの場合はMIMETextとして扱っていたものをコメントアウトしてしまい、その他のMIMEBaseと一緒にしてしまいました。

今のところ、これでうまく行ってくれているようです。

なお、メールの送信については、2の鈴木さまのエントリで触れられているとおり、MailHostが使われていません。この点は、同じようにメール送信を行うPoiというプロダクトでかなり悩まされていたので、Pythonに明るくない私にとっては、コードの調整のために非常に参考になりました。

2009-08-18

COREBlog2とbuildout

ただいま構築中のPlone3.2.2 は、ほぼ(手探りですが)buildout を使っています。

ただし、最初はUnifiedinstallerを利用しました。そこからちょっとづつカスタマイズして作っている、という感じです。

いったんbuildoutに慣れると、外部ネットワークへつながっている限りは、ソースのダウンロードからコンパイルまで勝手に行ってくれるし、依存関係は解消してくれるので、なかなか便利で手放せなくなって来ます。

でも、buildoutに対応していないプロダクトもあるので、そこは従来どおり自分でソースを取得して、Productsディレクトリにソースを展開しないといけません。

COREBlog2やjaMailHost、PoiなどはProductsディレクトリに追加しています。これらのプロダクトも、起動時にコンパイルではなく、buildoutの時に一緒にコンパイルをしてくれるのは有難いことです。

さて、そうした中で、毎回COREBlog2のコンパイル時に、こんなエラーメッセージが出てしまいます。

……………

Updating unifiedinstaller.
Updating precompile.
  precompiling python scripts in /usr/local/Plone/zinstance/products
Compiling /usr/local/Plone/zinstance/products/COREBlog2/migration_stuff.bak/port.py ...
  File "/usr/local/Plone/zinstance/products/COREBlog2/migration_stuff/port.py", line 179
    return printed
SyntaxError: 'return' outside function

precompiling python scripts in /usr/local/Plone/zinstance/parts/productdistros

 

さて、こういうエラーが出ても、一応Zope & Ploneは立ち上がってくれます。

気にしないでおこう….と思っても、やはり気になるもの。
調べてみると、同様の症状について書かれているBlogのエントリがありました。

データの移行などは無いので、特に動作に問題はなさそうなので、このまま(見なかったこと)にしておくことにしました。

2009-08-14

Windows Update: KB973869 (Windows Server2003 x64) Fail?

8月のMicrosoftのセキュリティ情報が公開されたので、早速お世話になっているサーバをWindows Updateしました。

たいていは単純にUpdateするだけで、自動でパッチが当たってくれるのですが、今回はなにやら不具合が。

サーバの中に、 x64bit のものが複数あるのですが、一回目、二回目の再起動でたいていUpdateが終わるはずが、何回試しても『KB973869』というパッチが当たってくれません…。

32bitのサーバでは、問題なし。

でも、64bitだとうまくいかない、というか、残りのパッチが無いか確認のためにブラウザからWindows Updateを開くと、何度当ててもKB973869というエントリが消えてくれないのです…。

個別に履歴を見てみると、『成功』で終わっているのですが。

心配になって、Windowsupdate.logと、KB973869.logを参照してみると、いちおう、FatalとかErrorのような文字はなく、"Content Install Installation Successful "というメッセージが。

とりあえず、ログを信用して、適応されてるものとしました…。

2009-08-13

Bloggerのフィード設定

実は、Blogについては、意外といろいろ試したことがあります…。オープンソースだとMT,WordPress,COREBlog2(Plone), .Text (.NET)。サービス用だと、goo Blogとか。

#でも、どれも中途半端になってしまっており、そういう点がわたしの至らないところです。

さて、Bloggerは、最近始めたばかり。

(とは言っても、Blogという言葉が世に出だした頃、多分5年以上前に、Bloggerは一度試したことがあります。ただ、あまりよく判っていなかったので、アカウントを作っただけで終わってしまいました)

更新はFeedでチェックするのですが、Bloggerはどうなのかな、と思って設定を調べたので、メモ。

Bloggerの場合はこちらにヘルプがあります。

http://www.google.com/support/blogger/bin/answer.py?answer=97933&&hl=en (英語のみ)

通常のFeedは、各Blogのリンクや、HTMLのヘッダ<link rel="alternate" type="application/rss+xml" …/>で判りますが、コメントだけのRSSや、タグ(カテゴリごと)のFeedの提供もしているようです。

こちらのBlogの場合、こんな感じです。

[指定のタグのPOSTのRSS]

タグ別に取得できるのは便利ですね。コメントの場合は、posts –> comments に変更すれば良いそうです。

ついでに色々とBloggerのヘルプを見てみると、テンプレートでかなりカスタマイズできるんですね。そこまでは設定しないとは思いますが…。

Bloggerのフィード設定

実は、Blogについては、意外といろいろ試したことがあります…。オープンソースだとMT,WordPress,COREBlog2(Plone), .Text (.NET)。サービス用だと、goo Blogとか。

#でも、どれも中途半端になってしまっており、そういう点がわたしの至らないところです。

さて、Bloggerは、最近始めたばかり。

(とは言っても、Blogという言葉が世に出だした頃、多分5年以上前に、Bloggerは一度試したことがあります。ただ、あまりよく判っていなかったので、アカウントを作っただけで終わってしまいました)

更新はFeedでチェックするのですが、Bloggerはどうなのかな、と思って設定を調べたので、メモ。

Bloggerの場合はこちらにヘルプがあります。

http://www.google.com/support/blogger/bin/answer.py?answer=97933&&hl=en (英語のみ)

通常のFeedは、各Blogのリンクや、HTMLのヘッダ<link rel="alternate" type="application/rss+xml" …/>で判りますが、コメントだけのRSSや、タグ(カテゴリごと)のFeedの提供もしているようです。

こちらのBlogの場合、こんな感じです。

[指定のタグのPOSTのRSS]

タグ別に取得できるのは便利ですね。コメントの場合は、posts –> comments に変更すれば良いそうです。

ついでに色々とBloggerのヘルプを見てみると、テンプレートでかなりカスタマイズできるんですね。そこまでは設定しないとは思いますが…。

2009-08-08

TypeError: len() of unsized object (Plone3.2.2)

今回のエラーは、Ploneのコンテンツルールの拡張用プロダクトを追加した際に発生しました。
※追加プロダクトは、collective.contentrules.mailtogroup です。


Plone3.xには、コンテンツルールという機能が追加されました。

こちらは、コンテンツが指定の条件にマッチすると、登録しておいたアクションを実行してくれるという機能です。(SQLで言うところの、トリガのようなものでしょうか)

たとえば、こんなことができます。

  • ニュースコンテンツを編集し、『非公開』から『公開』に遷移させた時に、指定のメールアドレスにそのURLやタイトルを送信する。
  • 指定のフォルダの配下のコンテンツを削除したり更新した場合、バックアップ用のフォルダにコピーを作成する。

Plone2での利用中も、こういう機能は欲しかったのですが、とてもそんなカスタマイズやコーディングは無理でしたので、あきらめていました。出来るとしても、プロダクト個別対応くらいで、すべてのコンテンツタイプに適用できるようにPloneのコアの部分をいじるというのは、もっと無理です(^^;

それがPlone3.xでは、コードを書かなくとも、ニーズの高い条件とアクションが標準的に用意されていて、プルダウンやチェックボックスで選択して条件やルールを組み合わせることができるようになっていました。

用意されているアクションは、メール配信のほかには、コピーやバックアップ、ロギングなど。また、作成したルールも、コンテンツタイプやフォルダの場所に応じて使い分けが可能です。

使ってみたところ、なかなか良い感じだったので、冒頭で触れた、この機能の拡張用のプロダクトを追加してみることにしました。
手順は、buildout.cfg の[instance]セクションで、eggs & zcmlにcollective.contentrules.mailtogroupのエントリを追加するだけです。
あとは、buildout –> Ploneの管理画面から普通に プロダクトを追加。

これで、コンテンツルールのアクションの一覧に、『Plone上のグループ宛(グループに属するメンバー宛)にメールを送信』(Send email to groups and members) する項目が増えました。

Plone: Contents Roules 

さて、じゃあ実際に試してみようとすると…。

2009-08-07T14:16:31 ERROR Zope.SiteErrorLog http://………………/Plone/++rule++rule-1/+action/plone.actions.MailGroup
Traceback (innermost last):
  Module ZPublisher.Publish, line 119, in publish
  Module ZPublisher.mapply, line 88, in mapply
  Module ZPublisher.Publish, line 42, in call_object
  Module zope.formlib.form, line 770, in __call__
  Module zope.formlib.form, line 885, in render
  Module zope.formlib.form, line 764, in render

……[長いので略] …………

Module zope.tales.tales, line 696, in evaluate - URL: /usr/local/Plone/buildout-cache/eggs/plone.app.form-1.1.6-py2.4.egg/plone/app/form/widgets/ubermultiselectionwidget.pt - Line 15, Column 2 - Expression: - Names: {'args': (), 'context': , 'default':  …………..

Module zope.tales.pythonexpr, line 59, in __call__
   - __traceback_info__: (len(options['value']) == 0 and 'display: none' or None)
  Module <string>, line 0, in ?
TypeError: len() of unsized object

プルダウンで選択し、条件を登録しようとしたところでエラーが発生!

調べてみたところ、どうやら、このバグに該当する模様でした。

トラッカーのチケットを見ると、バグはFixされているようですが、リリースPlone3.3での反映になるようなので、取り急ぎ、差分を適用させることに。と言っても、2行程度のコード追加だったので、助かりました。

ただいま、PloneはUnified Installerをベースにbuildしたものなので、以下のファイルを修正。そのあと、bin/buildout –n しました。

  • /usr/local/Plone/buildout-cache/eggs/plone.app.form-1.1.6-py2.4.egg/plone/app/form/widgets/uberselectionwidget.py

こういう修正の仕方は初めてだったのですが、buildout-eggsにダウンロードされたものは、再度ダウンロード&上書きされることは無かったので、いちおう変更は反映されて、OKになったようです。

良かった…。

2009-08-07

Windows Live Writerを使ってみる。

もしかして、「今さら何言ってるの?」と言われそうですが、Windows Live Writerを使ってBlogの記事をPOSTしてみることにしました。

きっかけは、最近復活した、河端さんのBlogで。

#Blogを復活してくださって、とても嬉しいです!実は、PASSJが休会し、Blogも停止してしまったので、どうしようかなあと思いBloggerをはじめたものですから…

プレビュー画面です

 

よし、早速インストールしてみよう!と思ってダウンロードサイトに行くと、すでにOSにインストール済みの模様。Windows Live Messangerを入れた時に、一緒に入ったらしいです…。

(ちなみに使っているOSは未だXPで、MessangerはWindows Live Messangerではなく、Windows Messangerのほうを使っています)


実は、ちょうどPlone付属のエディタの不具合をチェックしていたところでした。どうしてもうまくいかない場合は「外部エディタ」というもので対応しようかな…とも考えていたところに、こちらのWindows Live Editorに遭遇。

残念ながら、Plone上で使っているCOREBlog2は、選択できるブログの一覧にはなかったので、このBloggerで試すべく、記事を書いているところです。

河端さんのご指摘のとおり、特にプレビューがいい感じです。

Bloggerの場合、Webからでもプレビューできますが、HTTP通信の関係で遅く感じたりします。また、画面も少なからず遷移します。

こちらのLive Writerだと、切り替えが非常にスムーズな印象があります。

もう少し使ってみようと思います。

2009-07-30

qi.LiveChat を試してみました (Plone)

Ploneも、buildoutな環境にもようやく慣れてきた気がします。


最初はやりかたが良く判らなくて、『何それ?』な状態でしたが、設定ファイルに追加したいプロダクトを記載さえしておけば良いので、以前のように自分でソースをダウンロードし、Products/ 以下に配置してZOPEの再起動....という手間が省けるようになりました。

また、何よりサーバを起動する前にプロダクトのビルドがうまくいくか確認できますし、先にビルドされる分、起動も早くなっているようです。

* * * * *



さて、本日は、『何か楽しいものも入れよう!』と思い、いろいろとCMS Infoを眺めておりました。そこで目にとまったのが、Chat用プロダクト。

メッセージのやり取りには、色々なIMもありますし、いまさらChatなんて...とも思ったりしました。でも、ブラウザだけで済むのと、外部のWebサービスを利用しなくても済むことが良さそうだったので、qi.LiveChatというプロダクトを追加してみることにしました。

buildout.cfgへの設定は、このような感じです。(eggs, zcmlにプロダクト名を追加)



# If you want Zope to know about any additional eggs, list them here.

# e.g. eggs = ${buildout:eggs} my.package

eggs =
${buildout:eggs}

qi.LiveChat



# If you want to register ZCML slugs for any packages, list them here.

# e.g. zcml = my.package my.other.package

zcml =

${buildout:zcml}

qi.LiveChat



# For Chat

[scripts]

recipe = zc.recipe.egg

eggs = qi.LiveChat

インストールは、bin/buildout -n でつつがなく終了。

また、チャット用のサーバプログラム(XML-RPC)がプロダクトに付属しているので、外部のサービスなどを使わずともすぐにサービスが開始できます。 以下のとおりコマンドを実行すると、デフォルトで8000番でチャット用サーバが起動します。

% python /usr/local/Plone/buildout-cache/eggs/qi.LiveChat-0.21-py2.4.egg/qi/LiveChat/server/xmlrpcServer.py

スクリーンショットは、こんな感じです。
フォームからメッセージを入力すると、Ajax通信でサーバにPOSTされます。また、サーバからのデータは、デフォルトで20秒間隔でGETし、Ajax.Updateさせて画面を更新しています。

メッセージ用のサーバは、localhost:8000 (ZOPEのインスタンスと同じホスト)でプログラムの中で決めうちになっています。

Ploneの管理画面やChatコンテンツの編集画面で変更できれば良いのですが、Ajax利用のため、少なくともlocalhost固定になっているのは仕方がなさそうです。

でも、できればPortくらいは任意で切り替えられると嬉しいな、と思います。


* * * * *


※お約束の、本日のトラブル(?)


Ajaxを使ってデータをPOSTしているんですが、私のWindowsの環境だと、エンターキー押すだけでPOSTされちゃいます。メッセージの途中で漢字変換を行い、変換を確定させると、それがPOST用のイベントだと判断されてしまいました。

メッセージが切れ切れになっちゃうので、これだと嬉しくないですね。上記の点に加え、プロダクトの日本語化は未だなので、うまく動くように修正して使ってみようと思います。

2009-07-21

DB内のオブジェクト(テーブル)の全部の制約を無効/有効にする

#PASSJ Blogからの転記+修正版です。

SQL ServerのExport & Import作業やデータの削除時に、制約が邪魔をして、うまくお掃除できないことがあります。

そこで、一括して制約を無効/有効にするストアドを作ってみました。

※ただし、制約を無効化しても、制約が無くなるわけではありません。SQL Server 2005の場合、テーブル間の制約があると、制約が無効化状態であっても、TRUNCATEは出来ません。(ここは、Oracleと違うところみたいです)
TRUNCATEだと、とトランザクションが発生しないからでしょうか。

SQL Serverで、テーブルをTRUNCATEするためには、制約の削除 -> 再作成というステップを行わないとだめのようで、これはちょっと悲しい....。(他にもっといい方法があるのかもしれません。また、2008ではOKかもしれませんが、こちらは未確認)

ちなみに、DELETEとかINSERTは可能になります。(その代わり、SQLのトランザクションが発生するので、実行時間はそれなりにかかるかと思います)




とりあえず、全部のテーブルに対し、有効化/無効化を切り替えるストアドは、こんな感じとなりました。

CREATE PROCEDURE maintenance.sp_Disable_AllConstraints
@disable BIT = 1
AS
DECLARE
@sql VARCHAR(500),
@tableName VARCHAR(128),
@tableSchema VARCHAR(128)

-- List of all tables
DECLARE triggerCursor CURSOR
FOR
SELECT
t.TABLE_NAME AS TableName,
t.TABLE_SCHEMA AS TableSchema
FROM
INFORMATION_SCHEMA.TABLES t
ORDER BY
t.TABLE_NAME,
t.TABLE_SCHEMA

OPEN triggerCursor

FETCH NEXT FROM triggerCursor
INTO @tableName, @tableSchema

WHILE ( @@FETCH_STATUS = 0 )
BEGIN
IF @disable = 1
SET @sql = 'ALTER TABLE ' + @tableSchema
+ '.[' + @tableName + '] NOCHECK CONSTRAINT ALL'
ELSE
SET @sql = 'ALTER TABLE ' + @tableSchema
+ '.[' + @tableName + '] CHECK CONSTRAINT ALL'

PRINT 'Executing Statement - ' + @sql

EXECUTE ( @sql )
FETCH NEXT FROM triggerCursor
INTO @tableName, @tableSchema
END

CLOSE triggerCursor
DEALLOCATE triggerCursor






今回は、maintenanceというスキーマに作ってみました。
使い方は、こんな感じです。 ( -- 1で全制約を無効化、0で有効化 )

EXECUTE maintenance.sp_Disable_AllConstraints @disable = 1
-- 結果
Executing Statement - ALTER TABLE xxxx.[Application] NOCHECK CONSTRAINT ALL
Executing Statement - ALTER TABLE xxxx.[ApplicationAttachementFile] NOCHECK

CONSTRAINT ALL
:
:

実は、上記のコードは、ほぼMSDNライブラリのコードを参考にしました。

外部キーの無効化って、Transact-SQLだとどうやるのかな...と思って検索したところ、NOCHECK CONSTRAINT で行えることが判明。しかも、テーブル単位で、ALL指定ができるんですね。

さらに、一括でトリガや外部制約を無効化するサンプルコードがMSDNライブラリに載っていたのですが、なぜか外部制約のためのスクリプトが「トリガの無効化」のコードになっていました(^^;

とりあえずSQLを良く見て、ちょこちょこと変えたら、希望通りの動作になったので、こちらに載せてみました。
ただ、実際は全部のスキーマに操作しちゃうのは良くないと思うので、スキーマ名を引数にとって実行するのが良いかなあ...と思っています。

2009-07-17

Redmineの日本語メールJIS対応のはずが?

今日のトラブルは、RedmineのメールのJIS化にともなうものです。

Redmineのバージョンアップ作業で、ユーザさんからのリクエストに応えようと、メールのJIS対応を行ってみました。あんまりRORには詳しくないので、まずは検索。

そして、参考にさせていただいたのが、以下のサイトです。

おかげさまで、めでたくメールがISO-2022-JPになってくれました。

メールの件は片付いたので、しばらくはその他のプラグインの検証などを行っていたのですが、意外なところで不具合が発生。

Redmine0.7xの環境で登録したデータを、バージョンアップの検証環境にインポートし、Redmine0.8.4の動作確認ということを行っていたのですが、検証環境で新たにユーザを追加すると、そのユーザだけ、正常にログインが出来なくなってしまったのです

最初は何がなんだかわからなかったのですが、ログを見ると、エラーの発生するユーザには、すべて以下のようなメッセージが出ていました。

ActionView::TemplateError (uninitialized constant GetText::Rails::SecretKeyGenerator) on....

最初の疑惑は、バージョンアップそのものでしたが、これはどうも考えにくい。

次に、ユーザの認証に関してです。追加ユーザは、Internalではなく、LDAP認証を利用しています。でも、すでに0.7xの環境でも同じLDAPサーバを利用してのユーザ追加は問題ないので、これも考えにくいのでした。

そして、最後に疑ったのが、gettextまわり。

実は、gettextもインストールにするにあたって、Railsのバージョンやgettextのバージョンとの組み合わせで、Redmineがうまく動かなかったり、migrateでエラーになったりして、結構一苦労していました。

また、せっかくメールはJIS対応させたものの、SystemNotificationsという、ユーザへの一斉通知用プラグインに関しては、HTMLを含む送信メールがうまくJIS化できませんでした。

なんだか危険だなあ...と思っていたgettextだけに、エラーメッセージをキーに検索をすると、とても有難い情報が!

  • 2009-07-01 Redmine にチャレンジ中 (By JULYさま)

まさにビンゴ、という感じで、早速Gettextのコードを解除し、もとのUTF-8に戻すと、あっけなく不具合が解決しました。
参考にしたBlogの方法が有効化はまだ判らないのですが、あまりgettextまわりはいじりたくないと直感が働いているので、メールのJIS化は保留としました。

ですが、タイムリーなことに、別の方法(プラグイン)を、お世話になっている方から教えていただいたので、こちらを試してみようと思っています。

それにしても、助かりました、JULYさま、本当に有難うございました。
(コメントが付けられないので、かげながらお礼申し上げます....)

2009-07-14

うっかり再起動

今日のトラブルはこちら。

VMWareのGuestOS上で、vmware-toolsのプロセスを再起動すると、いったん接続が切れてしまいます...。 たとえば、こんな感じで。

# /etc/rc.d/init.d/vmware-tools restart

....あとはターミナルがだんまり.....

なるべくScreenコマンドを使ったりしておきましょう...。

2009-07-11

Local Avatars plugin

Redmine0.8.4に、Local Avatars pluginを追加してみました。
プラグイン組み込みの後、動作チェックをしていたところ、チケットの一覧から個別のチケットを表示する画面へ遷移すると、こんなエラーが...。

undefined method `attachments' for #<User:0xb7233be4>

こんな基本的な動作でもエラーになってしまっては、ぜんぜん使い物になりません!
そのほかにも、自分のアカウントの情報を表示する画面でもエラーが発生。
どうやら、Avatarの表示にかかわる箇所でエラーが発生しているようでした。

画面に出ているエラーは、こんな感じ。
vendor/rails/activerecord/lib/active_record/attribute_methods.rb:256:in `method_missing'
vendor/plugins/redmine_local_avatars/lib/application_helper_avatar_patch.rb:14:in `avatar'
app/views/account/show.rhtml:5:in `_run_erb_47app47views47account47show46rhtml'
/usr/bin/mongrel_rails:19:in `load'
/usr/bin/mongrel_rails:19


困ったなあ~と思い、環境をチェックしてみると、そう言えばdevelopmentモードで起動させていたことに気が付きました。

実は、Local Avatars以外にも、プラグインに関しては、developmentモードだとうまくいかないものが幾つかあったのです。もしや、と思ってproductionモードに切り替えると、今度は正常に動作してくれました。

...とまあ、これでひと安心。

でも、productionモードでないと動かないというのは、ちょっと困りますね。
せっかくテストと本番を切り替える仕組みがあるのに。

2009-07-10

buildout.cfg

buildoutを使ってPloneをビルドすると、毎回zope.confが書き換わってしまいます。
たとえば、Zopeを再起動してもSessionのタイムアウト設定がクリアされないように、
session-timeout-minutes 180

の一行を、zope.confに書いておいても、bin/buildout すると値がデフォルトに戻ってしまいます。

そういうときは、おおもとのbuildout.cfgの [instance] の部分に設定を書いておけば良いとのこと。


[instance]
# Added by akiko for session
zope-conf-additional = session-timeout-minutes 180