作者:wwashington 来源:ChinaUnix论坛   酷勤网收集 2007-08-22

摘要
  一个是基于 Java 的商业软件 JIRA,一个是基于 Perl 的免费软件 Bugzilla。已经用了比较长的时间了,觉得效果非常好, 这次先补充一些错误解决方案,将来有空再写完整的指南吧。

说明:其实以前工作中也用过缺陷管理系统,不过那个是公司自己开发的。
离开新太集团后,自己曾经试图找一些好的替代方案,ClearQuest 很有名
但是太贵而且复杂,不利于中小企业迅速从生存向规范转移。

这里推荐使用两个工具,一个是基于 Java 的商业软件 JIRA,一个是基于
Perl 的免费软件 Bugzilla。已经用了比较长的时间了,觉得效果非常好,
这次先补充一些错误解决方案,将来有空再写完整的指南吧。

Part A. 参考网址

1) 关于选型

[url]http://www.blueidea.com/tech/program/2006/3479.asp[/url]
[url]http://www.blueidea.com/tech/program/2006/3479_2.asp[/url]
[url]http://www.phpchina.cn/jiaocheng/html/supter/2006/0818/1424.html[/url]
如何用正确的方法来写出质量好的软件的75条体会 [转]

2) 关于 JIRA

[url]http://oneboy.org/?p=69[/url]
elliott's Blog -- JIRA安装批南(MYSQL)

[url]http://www.blogjava.net/lucky/archive/2006/05/01/44301.aspx[/url]
使用 JIRA 搭建企业问题跟踪系统

[url]http://www.360doc.com/showWeb/0/3/178896.aspx[/url]
伊莲的文章--JIRA一出,谁与争锋

[url]http://dog.xmu.edu.cn/modules.php?op=modload&name=News&file=article&sid=253[/url]
JIRA。。。忘了bugzilla吧。

3) 关于 Bugzilla

[url]http://www.bugzilla.org/installation-list/[/url]
Bugzilla 用户名单,很多知名企业,其中以开源系统为主

[url]http://cs.cuc.edu.cn/linweiguo/archives/000044.html[/url]
Win2000下Bugzilla安装实录 (作者:Jackey)

[url]http://www.chinahtml.com/programming/4/2005/cgi-11343023012506.shtml[/url]
在 Win32 下安装 Bugzilla (Good!)

[url]http://www.yuanma.org/data/2006/0808/article_1334.htm[/url]
安装bugzilla (作者 dreamstone)

[url]http://blog.donews.com/ymliu888/archive/2005/12/13/656701.aspx[/url]
解答:为什么在应用了Bugzilla汉化包后,原来存在的汉字变成了乱码?

[url]http://blog.donews.com/ymliu888/archive/2005/12/14/658121.aspx[/url]
关于Bugzilla2.20发邮件以及邮件乱码的问题

4) 下载 Bugzilla

[url]http://www.bugzilla.org/download/[/url]
Download :: Bugzilla

[url]http://sourceforge.net/projects/bugzilla-cn/[/url]
[url]http://sourceforge.net/project/showfiles.php?group_id=75477[/url]
Bugzilla 的汉化包和模块

bugzilla-2.20-cn-1.0.zip
BugzillaModules-2.20.zip

[url]http://landfill.bugzilla.org/ppm/[/url]
bugzilla-bundle.zip

[url]http://download.pchome.net/php/dl.php?sid=15654[/url]
Mail Direct Pro 2.3.0.0

[url]http://crackdb.org/index_1_o_1.html[/url]
Mail Direct Pro v2.3.0.0-SSG

[url]http://www.glob.com.au/sendmail/[/url]
Fake Sendmail 1.9

5) 关于 Perl

[url]http://www.superdown.com/soft/947.htm[/url]
ActivePerl 5.8.8 Build 819

[url]http://www.perlchina.org/conf/slides/cnhacktnt_PerlUnicodeIn5Min.ppt[/url]
讨论 Perl 和 Unicode 的关系

[url]http://www.cnbruce.com/blog/showlog.asp?cat_id=27&log_id=690[/url]
[url]http://blog.csdn.net/fmddlmyy/archive/2005/05/04/372148.aspx[/url]
[url]http://dev.csdn.net/develop/article/69/69883.shtm[/url]
谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词

[url]http://www.hongen.com/pc/program/tutors/perl/perl0003.htm[/url]
--CGI编程--Perl标量的操作符--

[url]http://net.pku.edu.cn/~yhf/perlstep/perlstep6.html[/url]
Perl程序设计中的函数(子程序)

[url]http://www.cnblogs.com/netcobra/archive/2004/04/16/6322.html[/url]
[转移]安装 BugZilla 时 Perl 模块的安装

Part B. 补充事项

1) JIRA 的管理比 Bugzilla 要强一些,使用也比较方便,本身已经
   支持多国语言(包括中文)。可惜,这个是要花钱的。虽然网上有
   注册机,如果没有真正购买,将来遭到版权局的调查还是会被罚。
   如果公司有预算,建议购买 JIRA,否则推荐用免费的 Bugzilla。

2) 上面那篇《JIRA安装批南》漏了讲一点,为了方便支持中文,在
   安装 MySQL 的时候要选 Custom,数据库的默认类型要选 UTF8。
   这个问题,对于 Bugzilla 也是一样,建议用 UTF8 来存储中文。
   如果不指定 UTF8,要么无法正确显示中文,要么不能创建 Bug。

3) Bugzilla 的 Perl 包安装,其实是有很多简便的方法的,没必要
   自己编译,而且发送邮件并不用修改大量 Code,只要装两个东西
   就可以了。一是 Mail Direct Pro 作为本地 SMTP 服务器,注意
   不要用最新的 2.3.1.0,这个版本破解不完全,显示未注册。二是
   Fake Sendmail 作为 sendmail 程序,必须装在跟 Bugzilla 同一
   个盘。例如 Bugzilla 在 H:\Server\Webz\Site\bugzilla\2.20.2
   那么,sendmail 就应该装在 H:\Usr\Lib,并且配置 ini 文件。

   需要注意的是,必须配置好 SMTP 转发服务器。Mail Direct Pro
   是支持中文的,选\"工具-->配置-->SMTP转投-->添加\",如果你的
   SMTP 服务器如 smtp.21cn.com 需要验证,则必须填写帐号和密码。
   在\"如果发送失败则转投\"这个选项上打勾,保证邮件可以正确发送。
   当某些邮件服务器有特殊限制时,转发到外网专业 SMTP 较有保障。

4) Bugzilla 2.20 有汉化版,可以用于 2.20.2,但最新版2.22还没
   汉化。而且汉化后还有一些问题,主要是发 Mail 不正常。对于
   网页和邮件的乱码,请大家使用 UTF-8 汉化包,并参考汉化作者
   的 Blog 里的解答,里面已经提到怎样消除这些乱码。我这里只是
   补充一个目前翻遍整个 Google 都找不到答案的问题。

   在汉化版里 sendmail 是表面正常,实际上并没有发出。经过我用
   WinHex 研究 debug 文件,发现汉字编码是 UTF-8,注意:如果用
   UltraEdit 按 Ctrl-H 则会自动将文档转为 UCS-2 (Unicode)。由
   于里面的 From 向下跑了好几行,所以 sendmail 报告没有发信人。
   通过查找 Bugzilla 的资料,发现是在 Token.pm 里处理忘记密码,
   例如 H:\Server\Webz\Site\bugzilla\2.20.2\Bugzilla\Token.pm。

   错误现象:

   Bugzilla 2.20.2 汉化版的 sendmail 失败,错误报告如下所示:
   exception message : Message is missing sender's address.

   解决方案:

   通过使用 index 和 substr 找到正确的 From 字串。首先是用
   UltraEdit 打开 Token.pm 找到 sub IssuePasswordToken 位置,
   在最后一句 Bugzilla::BugMail::MessageToMTA($message); 的
   前面插入下面这几句,问题就可以消除,真正发出邮件。

sub IssuePasswordToken {
...
# --------- 插入部分开始 --------------
    my $tmpmsg = $message;
    my $msgadr = index($tmpmsg,'From');
    $message = substr($tmpmsg,$msgadr);
# --------- 插入部分结束 --------------
   Bugzilla::BugMail::MessageToMTA($message);
#   Bugzilla::BugMail::MessageToMTA($message.\"$msgadr\");
## Notes: String result: \"$msgadr\"=13, '$msgadr'=$msgadr
## See the . symbol in Perl means String A plus String B
}

Part C. 错误记录

1) 不用sendmail,直接smtp(本机安装Mail Direct Pro),注册失败
>553 From <postmaster@Welcome>, message blocked.

2) 直接指定sendmail用21cn,则From必须是21cn.com,否则会报错
06-08-27 21:52:25 : From <bugzilla-daemon@21cn.com>, message
         blocked, sender not exist or has no privilege..<EOL>

06-08-28 02:25:49 : From <bugzilla-daemon@localhost.com>, 
         message blocked.<EOL>

3) 把sendmail设置为localhost,用smtp(本机Mail Direct Pro).
250 Requested mail action okay, completed.  
Message-ID=<7B939171977752.09550@receive2.inner-21cn.com>
Mail delivered successful.

Part D. 关于 Unicode

或许有些朋友对用 Perl 进行 Unicode 编码感兴趣,补充两个小程序。
在忘记密码的环节里,邮件里的标题依然是乱码,这里提供了修正版。

1) 推荐代码

type u1.pl {执行时候请用 perl u1.pl 你好}
<----------
use Encode;
use Unicode::UCD 'charinfo';
$str=decode('gb2312',shift);
# 由于系统环境为gb2312,所以cmd后的中文参数也为
# gb2312编码,因此告诉perl先把shift得到的参数按
# gb2312解码成unicode

$a=charinfo(unpack 'U',$str);
for(keys %$a)
{
print \"$_ ==> $a->{$_}\n\";
}
---------->

type u2.pl {执行时候请用 perl u2.pl 你好}
<----------
use Encode;
use Unicode::UCD;
$str=decode('GBK',shift);
# 由于系统环境为gb2312,所以cmd后的中文参数也为
# gb2312编码,因此告诉perl先把shift得到的参数按
# gb2312解码成unicode

$str = encode('MIME-Q', $str); 
print $str;
---------->

2) 运行结果

H:\Usr\bin>perl u2.pl 系统更改密码请求
=?UTF-8?Q?=E7=B3=BB=E7=BB=9F=E6=9B=B4=E6=94=B9=E5=AF=86=E7=A0=81=E8=AF=B7?=
 =?UTF-8?Q?=E6=B1=82?=
H:\Usr\bin>perl u2.pl 系统更改密码请
=?UTF-8?Q?=E7=B3=BB=E7=BB=9F=E6=9B=B4=E6=94=B9=E5=AF=86=E7=A0=81=E8=AF=B7?=
H:\Usr\bin>perl u2.pl 请求
=?UTF-8?Q?=E8=AF=B7=E6=B1=82?=

3) 邮件模版

从上推断出 template\cn\default\account\password\forgotten-password.txt.tmpl

[% PROCESS global/variables.none.tmpl %]

[% expiration_ts = token_ts + (max_token_age * 86400) %]
From: bugzilla-admin-daemon
To: [% emailaddress %]
Subject: [% terms.Bugzilla %]=?UTF-8?Q?=E7=B3=BB=E7=BB=9F=E6=9B=B4=E6=94=B9=E5=AF=86=E7=A0=81=E8=AF=B7=E6=B1=82?=
Content-Type: text/plain; charset=\"UTF-8\"
Mime-Version: 1.0

系统更改密码请求:

你(或者是其他的某个人)申请改变你的[%+ terms.Bugzilla %]密码。 
如果确认这个改变,请访问下面的链接:

[%+ Param('urlbase') %]token.cgi?t=[% token FILTER url_quote %]&a=cfmpw

如果你不是这个请求的申请者,或者想放弃这个请求,请访问下面的链接:

[%+ Param('urlbase') %]token.cgi?t=[% token FILTER url_quote %]&a=cxlpw

如果你不进行任何操作,那么在 [%+ max_token_age +%] 日 
(即 [%+ time2str(\"%H:%M on the %o of %B, %Y\", expiration_ts) -%]) 后,
或者在你下次成功登录后,该申请将会自动失效。

Part E. MySQL 故障

使用 Bugzilla 连接 MySQL 时会告诉你数据库连接失败,其实这是因为密码算法更新了。

1) 参考网址

[url]http://www.cnblogs.com/huqingyu/archive/2004/12/09/74989.html[/url]
[url]http://www.kehui.net/html/article/39/39822.html[/url]

[url]http://www.phpv.net/article.php/288[/url]
[url]http://dev.mysql.com/doc/mysql/en/old-client.html [/url]

mysql4.1以上版本连接时出现Client does not support authentication protocol问题解决办法

2) 解决方案

C:\> mysql -u root -p
mysql> \u mysql
mysql> select user,host,password from user;
mysql> set password for 'bugs'@'localhost' = old_password('bugs');
mysql> set password for 'bugs'@'%' = old_password('bugs');
mysql> select user,host,password from user;

Part F. Perl 故障

1) 参考网址

[url]http://www.bugzilla.org/docs/win32install.html[/url]
[url]http://blog.csdn.net/emu/archive/2005/03/15/320326.aspx[/url]
在apache下发布了bugzilla

couldn't create child process — 原来是无法创建子过程。看来是没有找到perl.exe。

2) 解决方案

把下面这个东西保存为 Perl.reg,然后鼠标双击导入就可以了。请注意修改
安装路径 [HKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI\Command]。

<-----------------------------------------------------

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.cgi]
@=\"ActivePerl\"

[HKEY_CLASSES_ROOT\.cgi\Shell]

[HKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI]

[HKEY_CLASSES_ROOT\.cgi\Shell\ExecCGI\Command]
@=\"H:\\Server\\Lang\\Perl\\bin\\perl.exe -T\"

Part E. 完美解决用Perl发送Bugzilla Mail  (来自: http://bbs.chinaunix.net/viewthread.php?tid=826054

说明:上次发表了“正确使用JIRA/Bugzilla做缺陷管理”之后,有朋友告
诉我,邮件标题在中英文和括号混用的时候仍然有问题,会引起乱码或丢失
字符。针对这个情况,今天上午我专门进行了深入研究,并且得到了满意的
解决。由于问题比较特殊,我打算独立一个专题来讲。引用的文章如下。

http://bbs.chinaunix.net/viewthread.php?tid=823695
[原创] 正确使用JIRA/Bugzilla做缺陷管理

1) 推荐代码

当中文太长、中英文和括号混用的时候,会引起 MIME-Q 编码换行,但是
目前的 Mail 系统如 21cn.com、163.com 以及 Mail Direct Pro 都无法
正确识别这些特殊的编码。需要改进 Perl 程序,使 MIME-Q 兼容邮件。

上次我已经给出过 u1.pl 和 u2.pl 的代码。现在 u1.pl 保持不变,看到
u2.pl 实在太简单了,于是把它扩充了一下,解决中文太长的问题。针对中
英文和括号混用引起换行的问题,专门编写了 u3.pl 并应用于 Bugzilla。

type u2.pl {执行时候请用 perl u2.pl "你好"}
<----------
use Encode;
use Unicode::UCD;
$str=decode('GBK',shift);
# 由于系统环境为gb2312,所以cmd后的中文参数也为
# gb2312编码,因此告诉perl先把shift得到的参数按
# gb2312解码成unicode

$str = encode('MIME-Q', $str);
print $str."\n";

my $tmp = $str;
my $len = length($str);
my $adr = index($tmp,'?==?');
my $pos = 0;
if ($adr == -1) {
   print "[info] string ?==? not found, adr=$adr len=$len\n";
   $adr = index($tmp,'?=',10);                 # 前缀 =?UTF-8?Q? 占了10个字符
   $pos = $pos + 2;                            # 如果换行,则必须再删除2个字符
   print "[info] string ?=   is  found, adr=$adr len=$len\n";
   }

if ($adr == $len-2) {                          # 后缀 ?= 如果已经是最后的一个
    $adr=-1;
   }

if ($adr > 0) {                                # 这表明已经发现了多余的字符串
   $str = substr($tmp,0,$adr).substr($tmp,$adr+12+$pos);
   }          # 后缀 ?= 占2个字符,前缀 =?UTF-8?Q? 占10个字符,一共12个

print "\n".$str."\n[info] adr=$adr len=$len";
---------->

type u3.pl {执行时候请用 perl u3.pl "你好"}
<----------
use Encode;
use Unicode::UCD;
$str=decode('GBK',shift);
# 由于系统环境为gb2312,所以cmd后的中文参数也为
# gb2312编码,因此告诉perl先把shift得到的参数按
# gb2312解码成unicode

$str = encode('MIME-Q', $str);
print $str."\n";

my $tmp = $str;
my $len = length($str);
my $utf = index($tmp,'=?UTF-8?Q?');
my $adr = 0;                                   # 设置开始条件
my $pos = 0;
my $flag = "X";
my $plus = "X";

while ($adr != -1) {                           # 首先处理遇到 ?= 符换行的情况
  $adr = index($tmp,'?=',$utf+10);             # 前缀 =?UTF-8?Q? 占了10个字符
  $flag = substr($tmp,$adr+3,1);               # 通常换行符出现在 ?= 后第三个
  $plus = substr($tmp,$adr+2,1);       # . , : ; = ? @ / < > ( ) [ ] 导致换行
  if ($flag eq "\n") {                         # 如果出现换行标记 "\n" 则删除
    print "\nFound ?= at right";
    $str = substr($tmp,0,$adr).$plus.substr($tmp,$adr+5);
    $tmp = $str;
  }
  $utf = $adr;
}
print "\n".$str."\n";

$adr = 0;                                      # 设置开始条件
$utf = index($tmp,'=?UTF-8?Q?');
$plus = "X";

while ($adr != -1) {                           # 然后处理遇到 =? 符换行的情况
  $adr = index($tmp,'=?',$utf+10);             # 前缀 =?UTF-8?Q? 占了10个字符
  $flag = substr($tmp,$adr-3,1);               # 通常换行符出现在 =? 前第三个
  $plus = substr($tmp,$adr-1,1);       # . , : ; = ? @ / < > ( ) [ ] 导致换行
  if ($flag eq "\n") {
    print "\nFound =? at left!";
    $str = substr($tmp,0,$adr-3).$plus.substr($tmp,$adr);
    $tmp = $str;
  }
  $utf = $adr;
}
print "\n".$str;

$adr = 0;                                      # 设置开始条件
$utf = index($tmp,'=?UTF-8?Q?');
$plus = "X";

while ($adr != -1) {                           # 处理遇到 =?UTF-8?Q? 换行情况
  $adr = index($tmp,'=?UTF-8?Q?',$utf+10);     # 前缀 =?UTF-8?Q? 占了10个字符
  $flag = substr($tmp,$adr-2,1);               # 通常换行符出现在 =? 前第二个
  $plus = substr($tmp,$adr-3,1);       # . , : ; = ? @ / < > ( ) [ ] 导致换行
  if ($flag eq "\n") {
    print "\nFound =?UTF-8?Q? at left!";
    $str = substr($tmp,0,$adr-3).$plus.substr($tmp,$adr);
    $tmp = $str;
  }
  $utf = $adr;
}
print "\n".$str;

$adr = 0;                                      # 设置开始条件
$utf = index($tmp,'=?UTF-8?Q?');

while ($adr != -1) {
  $adr = index($tmp,'=?UTF-8?Q?',$utf+10);     # 前缀 =?UTF-8?Q? 占了10个字符
  print "\n[info] string =?UTF-8?Q? is found, utf=$utf adr=$adr len=$len\n";

  if ($adr > 0) {                              # 找到多余 =?UTF-8?Q? 应当删除
    $str = substr($tmp,0,$adr).substr($tmp,$adr+10);
    print "\n".$str;
    $utf = $adr;
    $tmp = $str;
    $len = length($str);
  }
}

$adr = 0;                                      # 设置开始条件
$utf = index($tmp,'=?UTF-8?Q?');

while ($adr != -1) {
  $pos = index($tmp,'?=',$utf+10);             # 首先从左向右依次搜索 ?= 位置
  $utf = $pos;
  $adr = index($tmp,'?=',$utf+10);             # 搜索下一个 ?= 位置,判断末尾
  if ($adr != -1) {                            # 找到 $adr,说明 $pos 不是末尾
    $str = substr($tmp,0,$pos).substr($tmp,$pos+2);
    $tmp = $str;
  }
  $len = length($str);
  print "\n".$str;
# print "\n".$pos." --- ".$adr;
  print "\n[done] string ?= is found, utf=$utf adr=$adr len=$len\n";
}

$flag = "X";
$utf = index($tmp,'=?UTF-8?Q?');
if ($utf > 1) {
  $pos = $utf-2;
  $flag = substr($tmp,$pos,1);               
  if ($flag eq "\n") {    # 首个UTF-8符前 . , : ; = ? @ / < > ( ) [ ] 导致换行
    $str = substr($tmp,0,$pos).substr($tmp,$utf);
  }
  $len = length($str);
  print "\n".$str;
# print "\n".$pos." --- ".$flag;
  print "\n[-OK-] string =?UTF-8?Q? is found, utf=$utf adr=$adr len=$len";
}
---------->

2) 运行结果

H:\Usr\bin>perl u2.pl "Buffer Overflow 问题处理"
=?UTF-8?Q?Buffer=20Overflow=20=E9=97=AE?=
=?UTF-8?Q?=E9=A2=98=E5=A4=84=E7=90=86?=
[info] string ?==? not found, adr=-1 len=82
[info] string ?=   is  found, adr=39 len=82

=?UTF-8?Q?Buffer=20Overflow=20=E9=97=AE=E9=A2=98=E5=A4=84?=
[info] adr=39 len=71

H:\Usr\bin>perl u2.pl "Buffer Overflow 问题"
=?UTF-8?Q?Buffer=20Overflow=20=E9=97=AE?==?UTF-8?Q?=E9=A2=98?=

=?UTF-8?Q?Buffer=20Overflow=20=E9=97=AE=E9=A2=98?=
[info] adr=39 len=62

--------------------------------------------------------------------------------------

H:\Usr\bin>perl u2.pl "[Bugzilla Mail] 系统更改密码请求 系统更改密码请求"

......

[Bugzilla Mail]
=?UTF-8?QE7=BB=9F=E6=9B=B4=E6=94=B9=E5=AF=86=E7=A0=81?=
=?UTF-8?Q?=E8=AF=B7=E6=B1=82=20=E7=B3=BB=E7=BB=9F=E6=9B=B4=E6=94=B9?=
=?UTF-8?Q?=E5=AF=86=E7=A0=81=E8=AF=B7=E6=B1=82?=
[info] adr=26 len=207

H:\Usr\bin>perl u3.pl "[Bugzilla Mail] 系统更改密码请求 系统更改密码请求 系统更改密码"

......

[Bugzilla Mail]=?UTF-8?Q?=20=E7=B3=BB=E7=BB=9F=E6=9B=B4=E6=94=B9=E5=AF=86=E7=A0=
81=E8=AF=B7=E6=B1=82=20=E7=B3=BB=E7=BB=9F=E6=9B=B4=E6=94=B9=E5=AF=86=E7=A0=81=E8
=AF=B7=E6=B1=82=20=E7=B3=BB=E7=BB=9F=E6=9B=B4=E6=94=B9=E5=AF=86=E7=A0=81?=
[-OK-] string =?UTF-8?Q? is found, utf=17 adr=234 len=234

--------------------------------------------------------------------------------------

H:\Usr\bin>perl u3.pl "[Bugzilla]更改系统密码<Bugzilla>更改系统密码(Bugzilla)更改密码"

......

[Bugzilla]=?UTF-8?Q?=E6=9B=B4=E6=94=B9=E7=B3=BB=E7=BB=9F=E5=AF=86=E7=A0=81<Bugzi
lla>=E6=9B=B4=E6=94=B9=E7=B3=BB=E7=BB=9F=E5=AF=86=E7=A0=81(Bugzilla)=E6=9B=B4=E6
=94=B9=E5=AF=86=E7=A0=81?=
[-OK-] string =?UTF-8?Q? is found, utf=12 adr=186 len=186

H:\Usr\bin>perl u3.pl "更改密码[Bugzilla]更改密码<Bugzilla>更改密码(Bugzilla)更改密码"

......

=?UTF-8?Q?=E6=9B=B4=E6=94=B9=E5=AF=86=E7=A0=81[Bugzilla]=E6=9B=B4=E6=94=B9=E5=AF
=86=E7=A0=81<Bugzilla>=E6=9B=B4=E6=94=B9=E5=AF=86=E7=A0=81(Bugzilla)=E6=9B=B4=E6
=94=B9=E5=AF=86=E7=A0=81?=
[done] string ?= is found, utf=0 adr=138 len=186

--------------------------------------------------------------------------------------

H:\Usr\bin>perl u3.pl "更改密码[Bugzilla]更改密码<Bugzilla>"

......

=?UTF-8?Q?=E6=9B=B4=E6=94=B9=E5=AF=86=E7=A0=81[Bugzilla]=E6=9B=B4=E6=94=B9=E5=AF
=86=E7=A0=81?=<Bugzilla>
[done] string ?= is found, utf=92 adr=-1 len=104

H:\Usr\bin>perl u3.pl "[Bugzilla]更改密码"

......

[Bugzilla]=?UTF-8?Q?=E6=9B=B4=E6=94=B9=E5=AF=86=E7=A0=81?=
[-OK-] string =?UTF-8?Q? is found, utf=10 adr=-1 len=58

H:\Usr\bin>perl u3.pl "更改[Bugzilla]密码"

......

=?UTF-8?Q?=E6=9B=B4=E6=94=B9[Bugzilla]=E5=AF=86=E7=A0=81?=
[done] string ?= is found, utf=56 adr=-1 len=58

--------------------------------------------------------------------------------------

3) 邮件模版

从上面的运行结果,我们知道 Bugzilla 里面的 BugMail.pm 需要继续修改才能完美地支持中文。
修改的办法是用 UltraEdit 打开文件,搜索字符串 $substs{"summary"},在它的下面插入代码。

##  Use Encode function in Perl to make an UTF-8 string.
    use Encode;
    $substs{"summary"} = encode('MIME-Q', $substs{"summary"});
    my $str = $substs{"summary"};
  
my $tmp = $str;
my $len = length($str);
my $utf = index($tmp,'=?UTF-8?Q?');
my $adr = 0;                                   # 设置开始条件
my $pos = 0;
my $flag = "X";
my $plus = "X";

while ($adr != -1) {                           # 首先处理遇到 ?= 符换行的情况
  $adr = index($tmp,'?=',$utf+10);             # 前缀 =?UTF-8?Q? 占了10个字符
  $flag = substr($tmp,$adr+3,1);               # 通常换行符出现在 ?= 后第三个
  $plus = substr($tmp,$adr+2,1);       # . , : ; = ? @ / < > ( ) [ ] 导致换行
  if ($flag eq "\n") {                         # 如果出现换行标记 "\n" 则删除
    $str = substr($tmp,0,$adr).$plus.substr($tmp,$adr+5);
    $tmp = $str;
  }
  $utf = $adr;
}

$adr = 0;                                      # 设置开始条件
$utf = index($tmp,'=?UTF-8?Q?');
$plus = "X";

while ($adr != -1) {                           # 然后处理遇到 =? 符换行的情况
  $adr = index($tmp,'=?',$utf+10);             # 前缀 =?UTF-8?Q? 占了10个字符
  $flag = substr($tmp,$adr-3,1);               # 通常换行符出现在 =? 前第三个
  $plus = substr($tmp,$adr-1,1);       # . , : ; = ? @ / < > ( ) [ ] 导致换行
  if ($flag eq "\n") {
    $str = substr($tmp,0,$adr-3).$plus.substr($tmp,$adr);
    $tmp = $str;
  }
  $utf = $adr;
}

$adr = 0;                                      # 设置开始条件
$utf = index($tmp,'=?UTF-8?Q?');
$plus = "X";

while ($adr != -1) {                           # 处理遇到 =?UTF-8?Q? 换行情况
  $adr = index($tmp,'=?UTF-8?Q?',$utf+10);     # 前缀 =?UTF-8?Q? 占了10个字符
  $flag = substr($tmp,$adr-2,1);               # 通常换行符出现在 =? 前第二个
  $plus = substr($tmp,$adr-3,1);       # . , : ; = ? @ / < > ( ) [ ] 导致换行
  if ($flag eq "\n") {
    $str = substr($tmp,0,$adr-3).$plus.substr($tmp,$adr);
    $tmp = $str;
  }
  $utf = $adr;
}

$adr = 0;                                      # 设置开始条件
$utf = index($tmp,'=?UTF-8?Q?');

while ($adr != -1) {
  $adr = index($tmp,'=?UTF-8?Q?',$utf+10);     # 前缀 =?UTF-8?Q? 占了10个字符

  if ($adr > 0) {                              # 找到多余 =?UTF-8?Q? 应当删除
    $str = substr($tmp,0,$adr).substr($tmp,$adr+10);
    $utf = $adr;
    $tmp = $str;
    $len = length($str);
  }
}

$adr = 0;                                      # 设置开始条件
$utf = index($tmp,'=?UTF-8?Q?');

while ($adr != -1) {
  $pos = index($tmp,'?=',$utf+10);             # 首先从左向右依次搜索 ?= 位置
  $utf = $pos;
  $adr = index($tmp,'?=',$utf+10);             # 搜索下一个 ?= 位置,判断末尾
  if ($adr != -1) {                            # 找到 $adr,说明 $pos 不是末尾
    $str = substr($tmp,0,$pos).substr($tmp,$pos+2);
    $tmp = $str;
  }
  $len = length($str);
}

$flag = "X";
$utf = index($tmp,'=?UTF-8?Q?');
if ($utf > 1) {
  $pos = $utf-2;
  $flag = substr($tmp,$pos,1);               
  if ($flag eq "\n") {    # 首个UTF-8符前 . , : ; = ? @ / < > ( ) [ ] 导致换行
    $str = substr($tmp,0,$pos).substr($tmp,$utf);
  }
  $len = length($str);
}

    $substs{"summary"} = $str;
##  Encode function ends here. Code is adapted from Perl script u3.pl

如果不想自己动手改,可以直接下载附件。里面包含了安装 Bugzilla 汉化包之后,还需要继续
修改的文件,覆盖到相应的目录就能用了。现在我已经解决邮件标题的中文乱码或字符丢失问题,
至于邮件内部的乱码,处理起来非常简单,汉化包的作者已经讲过这个问题,大家自己看吧。

http://blog.donews.com/ymliu888/archive/2005/12/14/658121.aspx
关于Bugzilla2.20发邮件以及邮件乱码的问题

原文链接:http://bbs.chinaunix.net/viewthread.php?tid=823695

转载请注明作者名及原文出处

分类: 管理工具 项目管理 软件工程



关于酷勤 | 联系方式 | 免责声明 | 友情链接