水曜日, 5月 28, 2008

[Trac]Timing and Estimation Pluginのpost-commit-hookではメールが飛ばない!?そして解決

Timing and Estimation Pluginのpost-commit-hookを 普通に信じて使おうとしていたんですが、

Tracのpost-commitでメールが飛ばないよ~

って状況になっていたんですが、 やっとこさ解決した。 (というか、スクリプトをバリバリ改造してみた。) オリジナルではそのまま送信しようとすると env.abs_hrefなんて属性は無いぞ!!って怒られてたんですが、 従来のtrac-0.10.3.1-ja-2.zipに付いていたtrac-post-commit-hookでenv.abs_hrefを設定している部分を発見した。 そこで、さっそくそのあたりのコードを移植してみた。 こんな感じ
--- trac-post-commit.py.org Wed May 28 13:05:22 2008
+++ trac-post-commit.py Wed May 28 13:14:35 2008
@@ -103,6 +103,7 @@
from trac.ticket.web_ui import TicketModule
# TODO: move grouped_changelog_entries to model.py
from trac.versioncontrol.api import NoSuchChangeset
+from trac.web.href import Href

logfile = "/var/trac/commithook.log"
LOG = False
@@ -193,6 +194,10 @@
       self.rev = rev
       self.msg = "(In [%s]) %s" % (rev, chgset.message)
       self.now = int(time.time())
+        if url is None:
+            url = self.env.config.get('project', 'url')
+        self.env.href = Href(url)
+        self.env.abs_href = Href(url)

       cmd_groups = command_re.findall(self.msg)
       log ("cmd_groups:%s", cmd_groups)
最近になってユニファイド形式のdiff情報が便利だということにやっと気が付きました。。。 これで、Subversionサイドでコミットした際にコマンドがメッセージに記述されていたら、 チケットにコミットログを書き込みして、チケットの変更上をメールで送信することまでできるようになります。 しかし、これだけだとあくまでチケットが更新されたというメールしか飛びません。 (要はメッセージ内にこのスクリプトに反応するコマンドが書き込まれていないとメールなんて飛んでこない) そこで、メールを送信するスクリプトを作ってみた。 ※特殊文字が含まれると落ちちゃいます。。。 だめじゃん。。。 ※ちなみにWindows環境下で作っているんで、pathとかは適当に見直したほうがいいと思います。
#!D:/Tools/Trac/Python24/python.exe
# -*- coding: utf-8 -*-
# needs: nkf, head

import re
import sys
import popen2
import smtplib

smtpserver = 'xxx.xxx.xxx.xxx'
fromaddr = '○○○○○○'
maxdiffsize = 80000  # in bytes
repo_url = 'http://utsuutsu/projects/repo/changeset/'
_svnlook = 'D:/Subversion/bin/svnlook.exe'

logfile = "D:/Trac/projects/trac/log/mailsender.log"
LOG = True

if LOG:
  f = open (logfile,"w")
  f.write("Begin Log\n")
  f.close()
  def log (s, *params):
      f = open (logfile,"a")
      f.write(s % params)
      f.write("\n")
      f.close()
else:
  def log (s, *params):
      pass

def fromSJIStoISO2022JP(s):
  u = unicode(s,'japanese.shift_jis','replace')
  return u.encode('japanese.iso-2022-jp')

def fromUTF8toISO2022JP(s):
  u = unicode(s,'utf_8','replace')
  return u.encode('japanese.iso-2022-jp')

class CommitMailSender:

  def __init__(self, repo, rev):
      self.repo = repo
      self.rev = rev

      conffile = popen2.popen2(_svnlook + ' cat %s -r %s' % (self.repo, self.rev))[0].read().splitlines()
      changed = popen2.popen2(_svnlook + ' changed %s -r %s' % (self.repo, self.rev))[0].read().strip()

      log('%s' % (repo))
      log('%s' % (rev))
      log('%s' % (conffile))
      log('%s' % (changed))

      # changed     ->   pathlist
      # ------------------------
      # U    file1\n
      # U    file2\n    ['file1','file2']
      #
      pathlist = [l.split()[1] for l in changed.splitlines()]
      if log:
          for l in pathlist:
              log('path=%s' % (l))

      to = []
      to += ['xxx@utsuutsu']

      # decide who to send
      for line in conffile:
          lines = line.strip().split()
          if len(lines) < rule =" lines[0]" addrs =" lines[1:]" rule="%s" rule ="=" addrs ="=" path="%s" rule="%s" _author =" popen2.popen2(_svnlook" _author =" fromSJIStoISO2022JP(_author)" _date =" popen2.popen2(_svnlook" _date =" fromSJIStoISO2022JP(_date)" _log =" popen2.popen2(_svnlook" _log =" fromSJIStoISO2022JP(_log)" _changed =" popen2.popen2(_svnlook" _changed =" fromSJIStoISO2022JP(_changed)" _diff =" popen2.popen2(_svnlook" _diff =" fromSJIStoISO2022JP(_diff)" project_name =" fromUTF8toISO2022JP('プロジェクト名')" author_title =" fromUTF8toISO2022JP('更新者')" date_title =" fromUTF8toISO2022JP('日時')" log_title ="fromUTF8toISO2022JP('ログ')" changed_title =" fromUTF8toISO2022JP('変更箇所')" msg =" (">
reply-to: xxx@utsuutsu
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit
Subject: [%s] Revision:%s commit

[%s] Revision:%s commit to %s
%s:%s
%s:%s

%s:
%s

%s:
%s

diff:  (up to %d bytes)
------------------------
%s
""" % (project_name, rev, project_name, rev, repo_url+rev, author_title, _author, date_title, _date, log_title, _log, changed_title, _changed, maxdiffsize, _diff)
      )


      # send!!
      mail = smtplib.SMTP(smtpserver)
      mail.sendmail(fromaddr, to, msg)
      mail.quit()

      log(str(to))
これをさっきのtrac-post-commit.pyでコマンドが無い場合のみ呼び出すようにします。
--- trac-post-commit.py.org Wed May 28 13:27:19 2008
+++ trac-post-commit.py Wed May 28 13:28:32 2008
@@ -104,6 +104,7 @@
# TODO: move grouped_changelog_entries to model.py
from trac.versioncontrol.api import NoSuchChangeset
from trac.web.href import Href
+from CommitMailSender import CommitMailSender

logfile = "/var/trac/commithook.log"
LOG = False
@@ -200,6 +201,9 @@
       self.env.abs_href = Href(url)

       cmd_groups = command_re.findall(self.msg)
+        # 追加
+        if len(cmd_groups) == 0:
+            CommitMailSender(url, rev)
       log ("cmd_groups:%s", cmd_groups)
       tickets = {}
       for cmd, tkts, xxx1, xxx2 in cmd_groups:
しかし、思いつきで作った割りにはしっかり動いているじゃないかw

0 件のコメント:

failed to read qemu headerのときのメモ

かなり久々。。。 忘れないようにここに書きこんでおく。 ちょっとした手違いで libvirtでイメージを起動しようとすると failed to read qemu header なんておっしゃられて起動しない。。。 vmwareserverを使って...