2010年3月1日月曜日

メール本文をPDFに変換するアプリ

Google App Engineでメール本文をPDFに変換するアプリを作成しました。
味も素っ気もないWebページはこちら。
http://nakakenstudy.appspot.com/
このページは本質的には全然関係なくて利用に当たっては、mail2pdf@nakakenstudy.appspotmail.comまでメールを送ってください。メールの本文がPDFとなって返信されます。
PDFの変換を試すには、http://nakakenstudy.appspot.com/post2pdf をリクエストしてください。

今回はreportlabを使ってテキストをPDFに変換しました。といってもベタにテキストにするだけなので、ほとんど実装していません。あんまり短くできたので、記念にソース公開しておきます。うるさい事言わないので、勝手にコピペしてください。blogの制約上全角スペースでインデントをつけているので、各自で半角スペースに変換しておいてください。


# -*- coding: utf-8 -*-
#!/usr/bin/env python
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import logging
import StringIO

import pdf

from email.utils import parseaddr
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp.mail_handlers import *

SENDER_ADDRESS = 'nakaken@mediacat.ne.jp'

def main():
  application = webapp.WSGIApplication([
        (r'/', MainHandler),
        (r'/_ah/mail/.+', Mail2PdfHandler),
        (r'/post2pdf', Post2PdfHandler),
  ], debug=True)
  util.run_wsgi_app(application)

def goodDecode(encodedPayload):
  encoding = encodedPayload.encoding
  payload = encodedPayload.payload
  logging.debug(encoding)
  logging.debug(payload)
  if encoding and encoding.lower() != '7bit':
    payload = payload.decode(encoding)
  else:
    try:
      payload = payload.decode('ISO-2022-JP')
    except Exception, value:
      logging.warn(value)
  return payload

class MainHandler(webapp.RequestHandler):
  def get(self):
    self.response.out.write('Mail to "mail2pdf at nakakenstudy.appspotmail.com" and you can get pdf file converted from your mail.')
 
class Mail2PdfHandler(InboundMailHandler):
  def receive(self, message):
    logging.info('do Mail2PdfHandler.receive')
  
    editormail = parseaddr(message.to)[1]
    account = editormail.split('@')[0]
    if account != 'mail2pdf':
      logging.warn(account + ' is an undefined account.')
      return
  
    content = ''
    for body in message.bodies(content_type='text/plain'):
      content += goodDecode(body[1])
    logging.debug(content)
  
    buffer = StringIO.StringIO()
    pdf.go(buffer, content)
    pdffile = buffer.getvalue()
    buffer.close()
  
    logging.info('sender=' + SENDER_ADDRESS)
    logging.info('to=' + message.sender)
    mail.send_mail(
      sender=SENDER_ADDRESS,
      to=message.sender,
      subject='result of converted pdf from mail',
      body='Here is the pdf file you want, yeah!',
      attachments=[('content.pdf', pdffile)],
    )

class Post2PdfHandler(webapp.RequestHandler):
  def get(self):
    self.response.headers['Content-Type'] = 'text/html'
    self.response.out.write("""<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
  <form action="/post2pdf" method="post">
   <p>PDFに変換したい文字列を入力してください</p>
   <textarea cols="60" rows="30" name="content"></textarea><br />
   <input type="submit" value="変換" />
  </form>
</body>
</html>"""
)

  def post(self):
    content = self.request.get('content')
    buffer = self.response.out
    pdf.go(buffer, content)
    self.response.headers['Content-Type'] = 'application/pdf'
  
if __name__ == '__main__':
  main()

[[ pdf.py ]]
# -*- coding: utf-8 -*-
import cgi
import StringIO

from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfbase import pdfmetrics
from reportlab.platypus import SimpleDocTemplate, Spacer, XPreformatted
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.rl_config import defaultPageSize
from reportlab.lib.units import inch

pdfmetrics.registerFont(TTFont('Togoshi-mono', 'togoshi-mono.ttf'))

PAGE_HEIGHT=defaultPageSize[1]
PAGE_WIDTH=defaultPageSize[0]

styles = getSampleStyleSheet()
my_style = styles["Normal"]
my_style.name = "bonlife"
my_style.fontName = "Togoshi-mono"
my_style.fontSize = 0.15*inch
my_style.leading = 11

def go(filename, content):
    doc = SimpleDocTemplate(filename)
    Story = [Spacer(1, 0.5*inch)]
    style = my_style
  
    x = XPreformatted(cgi.escape(content), style)
    Story.append(x)
  
    doc.build(Story)

2010年2月14日日曜日

Joom!fishで翻訳文書が表示されない

Joom!fishは、サイトを他言語化するに、すばらしいソリューションを提供してくれるが、ちょっと動きが怪しいところがあった。完全に正しいかどうかわからないけれども、実際にあった事をかいておきます。

#1 保存し直したら表示された
Joom!fishで登録した翻訳文が、blogスタイルのページで表示できなかった。翻訳文を消して、もう一度登録し直したら表示された。

#2 アンケートが翻訳されなかった
コンポーネント「アンケート」で作成したアンケートが、メニュー内でだけ選択肢が翻訳されなかった。modules/mod_poll/helper.phpをハックする必要があるらしい。

$query = 'SELECT p.id, p.text' .
' FROM #__poll_data as p' .
' WHERE p.pollid = ' . (int) $id .
' AND p.text <> ""' .
' ORDER BY p.id';

単に、テーブル名のエイリアスを入れただけなんだけど、うまく動いた。
http://forum.joomla.org/viewtopic.php?p=2016608

2010年1月31日日曜日

無線LANのチャンネルを調べる

どうも無線LANの調子が悪いので、チャンネルを固定化する事にしてみた。
その場合、近くで使われていないチャンネルを探さないといけないのだけれど、それをmac(snow lepard)で調べるにはどうすれば良いかと思ったらコマンドラインでできる事がわかった。

$ cd /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/
$ ./airport -s

詳しい人たちがいるものだ、と感心。
http://blog.isocchi.com/2009/04/java-jamac-maclan.html

2010年1月16日土曜日

Joomla1.5サイトを構築する #2

とりあえず日本語化が完了したら、次は見た目を整える。Joomlaはとても使いやすいCMSで、いつでもテンプレートを変更する事が可能だ。だがしかし、色合いの違うテンプレートに差し替えると、思った通りのサイトにはならない。やる気を出すためにも、はじめの段階でテンプレートを最終版に決定するべきだ。

テンプレートは、とりあえず以下のサイトから見つけるのがよい。とにかく数が多いのでだんだん大変になってくるが、根気よく作成するサイトにマッチするものを見つけよう。
http://www.joomla24.com/

気に入ったテンプレートを見つけたら、管理サイトからテンプレートを次の手順でインストールする。管理サイトも日本語化がされている前提でメニューなどは表記している。
1. メニューから「エクステンション - インストール/アンインストール」を選択する。
2. パッケージファイルのアップロードに、ダウンロードしたテンプレートのzipファイルを選択してインストールボタンを押す。あるいは、URLからインストールにテンプレートをダウンロードしたときに使ったURLを指定したインストールボタンを押す(joomla24のサイトは、一番最初に手作業でdownloadを行わないと、zipファイルをダウンロードするためのURLが使えない仕様になっているので注意)。
3. メニューから「エクステンション - テンプレート管理」を選択する。
4. 適用したいテンプレートのラジオボタンを選択して、デフォルトボタン(星形のアイコン)をクリックする。

これでよい。
テンプレート内のタイトル画像などは、サーバ内のファイルを直接置き換える事で差し替え可能だ。しかしサイズを変えるとレイアウトが崩れる事が多いので、元々の画像とサイズは合わせるのが吉である。

Joomla1.5サイトを構築する #1

Joomlaをインストールして、サンプルデータベースで遊んで、さて空の状態から自分のサイトを作ろうかと思ってはいるが、どこから手を付けてよいのやら迷ってしまった、そんな自分のためのJoomla備忘録。

日本人なら、まずはじめにしなければならない事は、サイトの日本語化ではないだろうか。
これは次のように行う。

1. 管理サイトにログインする。
2. メニューから「Extension - Install/Uninstall」を選択する。
3. 「URLからインストール」の欄に、サイト用と管理サイト用のランゲージパックをそれぞれ選択してInstallボタンを押す
4. メニューから「Extension - Language Manager」を選択する。
5. SiteとAdministratorのそれぞれについて、Japaneseのラジオボタンを選択し、デフォルトボタン(星のアイコン)をクリックする

これで完了。管理サイトが日本語化されるはず。
通常のサイトは、この設定によって日本語化されたかどうかはわからない(ログインモジュールなどを表示すると、日本語化されているのがわかる)

ちなみにランゲージパックは、以下のサイトからダウンロードできる。
Joomla! Accredited Translations Project(http://joomlacode.org/gf/project/jtranslation/)
メニューから「ファイル」を選択して、日本語関係のファイルを探してほしい。Joomla1.5.10の場合は
・ja-JP_Joomla_1.5.15_site.zip
・ja-JP_Joomla_1.5.15_admin.zip
の二つだ。

2010年1月13日水曜日

MACからさくらのサーバーにSSHで接続する方法

ターミナルを開き、次のコマンドを入力する。

>ssh -l ユーザー名 サーバーパスワード

2009年11月2日月曜日

無料素材

「写メ de 新聞」サービスを作るにあたって、利用した無料のサービスを紹介します。
これがなければ、もっとしょぼいデザインになるところでした。

「携帯サイト簡単構築」携帯サイトのテンプレート
携帯サイトを作るのは初めてだったので、通常のPCブラウザ用のHTMLとはいろいろな面で異なる事が多いです。携帯サイト用のテンプレートもいろいろ世の中に存在しているのですが、ここのテンプレートはシンプルなのと三つのキャリアで共通で使えるところが気に入りました。
http://web.rejec.net/

「Open Source Web Design」PCサイトのテンプレート
アメリカのサイトですが、そのまま使えるクールなテンプレートが2,000個以上も用意されています。ぱらぱらとたどっていけば、きっと気に入るテンプレートが見つかります。今回は割とシンプルなテンプレートを入手しました。中身のHTMLが想像以上にシンプルだったので、動的コンテンツを利用するサイトでも大変使いやすいです。
http://www.oswd.org/

「Interspire」ロゴのデザイン
いろんなテンプレートがあるようですが、Resouces - Website Templatesを選択して、さらにLogo Designsを選択すると、かっこいいアイコン付きのロゴデザインが用意されています。ロゴの文字は入っていないですが、Illustratorファイルとしてダウンロードできます。Illustrator(自分のように貧乏な人はInkscape)を用意すれば、文字を編集する事ができます。なかなかおすすめです。
http://www.interspire.com/

「FavIcon from Pics」favicon画像の作成
faviconとは、ブラウザのアドレスバーの左側やブックマークの一覧などで使われる、ちっちゃな画像です。意外と作るためにはツールなどが必要で、かつそれはWindows用が多いのでにわかマカーは一苦労です。それでもこのサイトを使えば、大きめの画像をアップロードするだけでちっちゃなfaviconを返してくれます。
http://www.html-kit.com/favicon/