本想将代码先整理下,不过似乎也没多少整理的必要。为项目新添加了netbeans的项目配置文件,这样使用netbeans的用户也可以方便的打开工程了。另外还做了个简单的视频演示,空间太烂,似乎要花挺久才能下载完。
项目地址:http://code.google.com/p/springside2vik/
视频演示:http://vik.haoluobo.com/static/springside2vik/springside2vik.htm
分类目录归档:编程
完成对老照片的调整,Django版本升级到1.0
今天完成了对老照片的调整,将Django的版本升级到了1.0。1.0版本的Django相比以前版本相比最大的变化就是那个newforms了。不过好在我在newforms出来不久就直接切换过去了,这次升级只需要在import的时候将newforms改成forms就可以。
admin也是0.96到1.0变化比较大的。不过老照片本来就不太依赖admin,所以我只修改了admin的url映射部分,保证admin后台可以正常打开。以后如果需要用到admin,再对admin部分进行调整。
由于我需要对用户上传的图片进行编辑,因此没有使用Django默认的上传处理。文件上传的变动给我带来了不少麻烦。以前从request.files里取出的文件是个map,但在新版本中变成了一个对象。这个对象虽然提供了files的相关接口,但却又不全,导致PIL无法正常处理。为此我增加了一个临时文件。先将用户上传的文件保存到临时文件再进行处理。在网上看到有用户遇到了和我同样的问题,不知Django在日后的版本中是否会修正。
至于目录的调整,我将那个碍眼的apps给去掉,把所有的文件放到oldphoto这个包下。
此外对项目的配置文件做了一些调整,将默认的数据库改为sqlite,保证程序可以在不做任何设置的情况下直接用manage.py runserver跑起来。
最后再将项目地址贴一下:
http://code.google.com/p/oldphoto/
将项目从SVN中取下后,依次运行scripts目录里的syncdb.bat、runserver.bat就可以跑起来了。当然,那些有些必备的环境还是需要的,python(>=2.4)+django(>=1.0)+PIL。
后记
本来休整工作还包括部分重构以及i18n等,不过在完成Django的升级后就开始没多少兴趣了。由于代码比较老,里面不少东西在现在看来都有更好的处理方式,如果全部都改工作量有点大,只是改部分打打补丁又没多少意思。或许那天重新写个自己看得顺眼点的新项目。
Google App Engine学习日志(三)不写了-_-,最后写点感受
又整了几天的GAE,感觉也没什么好写的了。除了API部分和Django有些不同,其他的开发基本和Django差不多,边查手册变写也没啥问题(感觉Google的手册写的不是太好)。数据库部分感觉一些不是太习惯,自的管理后台比Django差太多,想手动编辑数据非常麻烦。数据库的变更也是一个麻烦事。新加属性后必须将数据库里的数据全部取出来重新put(保存)一次,不然所有用到该字段的地方都会查不出任何的东西。
Google App Engine学习日志(二)选个葫芦,开始自己的新工程
GAE的API手册厚厚的一叠,如果要全部看完再动手,那估计还不得看完热情就已经跑光了。将GAE的入门手册看完后,我决定先找个范例工程,然后开始照葫芦画瓢。
最终锁定了两个工程OnlyPy和Rietveld。
OnlyPy
OnlyPy是国人用GAE写的一个Blog系统。我简单的看了下它的代码,还比较简单,挺具有参考价值的。
项目地址:http://code.google.com/p/onlypy/
演示站点(作者的Blog):http://onlypython.appspot.com/
Rietveld
从Google内部开源出来的代码审核工具,据说是蟒爹的作品(Guido)。有了Google和蟒爹做招牌,这东西自然要多看两眼了。只是这东西的代码量并不太少,而且将非常多的代码都写在同一个文件里,阅读起来挺不爽的。
项目地址:http://code.google.com/p/rietveld/
演示站点:http://codereview.appspot.com/
选择好葫芦后就要开始画了。我根据以往的习惯,将项目的目录结构整理好,然后今天的工作先到此结束,改天继续。
整理好的项目结构如下。
/myProject/google apps/haoluobo/
|~haoluobo/将站点的主要文件都丢到haoluobo这个包下
| |~portal/我习惯将首页信息放到portal目录,然后将顶层的所有url转发给portal.urls
| | |+templatetags/
| | |-__init__.py
| | |-urls.py
| | `-views.py
| `-__init__.py
|~script/将些常用的命令写成bat,这样直接双击就可以执行了(可以偷懒一点点)。
| |-clear_tmp.bat*
| |-runserver.bat*
| |-runserver_with_clear.bat*
| `-update.bat*
|+static/程序用到的静态文件
|+templates/模板文件
|~vik/放自己通用工具的目录,目前还没啥内容
| |~utils/
| | |~gae/
| | | |-__init__.py
| | | `-webutils.py
| | `-__init__.py
| `-__init__.py
|-app.yaml
|-django.zip
|-haoluobo_bootstrap.py
|-index.yaml
|-settings.py
|-tags
`-urls.py
Google App Engine学习日志(一)使用Django 1.0 部署django_example
开篇的废话
虽然GAE(http://appengine.google.com/)已经发布挺久了,而且我也在第一时间去抢了个测试名额,只是一直都没再去关注。说来我并不是太喜欢GAE这东西。GAE就是一个平台,要使用还得先学习一遍。而且由于限制很多,导致程序的移植性不怎么样。差不多用了GAE以后,就很难将应用再部署到自己的服务器上了。不过我想找个地方放东西,做一些自己的小应用玩,除了GAE外还真找不到啥其他比较好的免费资源。
废话基本上说完了,下面开始正式进入主题。
准备工作(申请开通GAE)
GAE在刚发布的时候需要先提交申请,再等待开通,现在似乎已经放宽限制可以随便申请了。但开通项目的时候会提示要用手机接收验证码。有人说移动的手机无法接收验证码,不过我的移动号码没遇到问题。这里需要注意的是,google是面对全球服务的,手机号码前需要添加国家标识,中国大陆的是86。
使用GAE需要下载Google提供的GAE SDK。GAE SDK就是一个普通的安装包,直接安装就可以使用的。GAE计划支持多种开发语言,不过就目前而言还只支持python,因此在安装GAE前确保Python已经安装也是必须的。
安装范例程序django_example
GAE本身就是一个WEB开发框架,即使不使用任何其他的WEB开发框架也可以直接使用。不过选用一个自己熟悉的,或者是自己认为方便的第三方开发框架也是一个不错的选择。目前GAE官方支持的WEB开发框架有Django0.96/pylons/web.py等。不过即使是GAE没有官方提供的,你也可以选择自己安装。
由于对Django比较熟悉,而且万一日后真的需要迁移到自己的服务器上,使用Django开发日后的迁移工作也可以相对轻松点。选定Django做GAE的web开发框架。
为了尽快的了解GAE的特性,我直接去GAE的sample项目(http://code.google.com/p/google-app-engine-samples/)上将Django的sample(django_example_20080409.tar.gz)给down了回来。
解压后,运行命令dev_appserver.py django_example/,sample就跑起来了。可以使用http://localhost:8080/进行访问。这个Demo提供了简单的登陆/添加/修改功能。
简单的看了下目录结构,其中下面几个文件比较重要。
|-app.yaml
|-django_bootstrap.py
|-index.yaml
app.yaml
应用程序的基本配置信息,主要就是程序名,以及url映射。这里所有的url都交给django_bootstrap.py处理。
index.yaml
这个文件是建索引用的。
django_bootstrap.py
这其实就是一个wsgi的处理程序,将请求以wsgi的形式交给django进行处理。
更新Django到1.0
如果使用GAE自带的Django,不需要做任何配置,不过现在Django1.0已经发布,似乎没有必要再使用0.96。于是动手将Django升级到1.0。
察看官方的相关教程使用zipimport引入Django1.0(使用zipimport主要是GAE有文件数限制,而django的文件数本来就不少)。
具体做法文章里已经说得比较清楚,我就不再啰嗦。不过有个问题需要注意的,在windows下会出现问题’module’ object has no attribute ‘unlink’,在网上看了下GAE将os的unlinlk给禁用了,需要做点修改。
在django_bootstrap.py里加上
if os.name == ‘nt’:
os.unlink = lambda: None
更新后sample终于再次跑起来了,不过不幸的是点击添加gift的时候再次出错。这次是Django的错误。可能是Django在1.0里对url tag有做改动,在参数不存在的时候会出错。修改gift.html,将表单的提交地址修改为action=""。
所有问题修正,使用命令appcfg.py update haoluobo/(haoluobo?:),我换了个自己喜欢的名字)上传到服务器。访问服务器http://haoluobo.appspot.com/,应用已经跑在Google的服务器上了。
后记
没想到写个简单的学习日志这么费事,不知道还会不会有后继的日志。
推荐一个vim插件eclim(将eclipse集成到vim)
非常棒的一个vim插件,可以将eclipse的功能集成到vim。
eclim的具体功能可以参考官方的命令说明http://eclim.sourceforge.net/translations/zh_TW/vim/cheatsheet.html
(繁体中文翻译)
虽然eclim主要目标是要将eclipse的功能集成到vim,不过eclim本身的vim脚本也是非常实用的(我就没去集成eclipse)。
对我而言,我主要使用了它的自动python语法检查,以及对html标签的</自动完成。
官方的安装版本没有eclipse会无法安装,可以直接到http://eclim.svn.sourceforge.net/viewvc/eclim/trunk/src/vim/,点击页面上的Download
GNU tarball,将eclim的vim脚本down回来,并复制到Vim\vimfiles目录。
如果没有和eclipse集成,有部分功能无法使用并会弹出不少讨厌的提示,可以修改文件Vim\vimfiles\eclim\autoload\eclim\project\util.vim。
找到函数function! eclim#project#util#IsCurrentFileInProject (…)
在函数的最开头增加 return 0
表示文件不在eclipse工程里。
这样eclim就不会再做和eclipse相关的操作。
备注:
今天在使用的时候发现在打开Django的模板文件的时候还是会有些错误提示,不知道是否是他的脚本写的有问题(我看过代码似乎没有问题)。我修改了一点屏蔽了问题。具体修改方法为在\Vim\vimfiles\eclim\ftplugin\htmldjango\eclim.vim中增加以下脚本
if !exists(‘g:HtmlDjangoUserBodyElements)
let g:HtmlDjangoUserBodyElements = []
endif
Nutch部署及相关问题(中文乱码等)修正
Nutch介绍
Nutch是一个开源的WEB搜索引擎,能提供高质量的搜索服务。
对于一些内部系统或中小型网站来说是一个不错的全文搜索解决方案。
Nutch的部署
最新版本的Nutch可从Nutch的官网获取。下载后直接解压就可以进行使用。 由于我使用的是windows系统,这里以windows下部署进行介绍。
Nutch爬虫设置
Nutch本身包含一个对目标站点进行索引的爬虫和一个提供搜索用的web界面。在查询界面可以使用前需要先设置Nutch爬虫对目标站点进行抓取。
部分配置文件的解释:
- nutch\conf\nutch-default.xml
- 设置http.agent.name,如果http.agent.name为空,爬虫将无法正常启动。这里可以设置任意你喜欢的名字,比如设置为vik-robot。
- indexer.mergeFactor/indexer.minMergeDocs这两个值都改成500。这两个参数值越大,性能越高,所需要花费的内存也需要相应的增加。如果设置过大,可能出现内存溢出。就实际使用情况,在当前参数下,内存的最大使用量为3xxM。
-
http.timeout表示最大超时等待时间,如果访问的连接长时间没有反应将丢弃。
- db.max.outlinks.per.page该参数表示单个页面最多支持多少个外连的连接,如果过多将不抓取。 如果是自己的内部系统那就设置一个任意大的数吧。
- nutch-default.xml 解读
-
创建文件nutch\urls,并填入爬虫的起始url。比如:
http://mysite.com/
-
nutch\conf\crawl-urlfilter.txt 该文件用于设置需要索引的url的过滤关系。每行一个过滤条件,–表示不包含该url,+表示包含。
- [?*!@=],该行表示对所有动态url都不抓取。 现在的大部分系统都会有很多动态url,该过滤条件很可能使你抓不到任何内容。
-
针对各系统分别设置url的过滤关系。具体的设置方法得根据各自应用系统的不同而不同,这里以广为流行的论坛discuz为例。在这url过滤将只抓取板块列表和帖子内容。
# skip file:, ftp:, & mailto: urls
-^(file|ftp|mailto):
# skip image and other suffixes we can't yet parse
-\.(gif|GIF|jpg|JPG|png|PNG|ico|ICO|css|sit|eps|wmf|zip|ppt|mpg|xls|gz|rpm|tgz|mov|MOV|exe|jpeg|JPEG|bmp|BMP)$
# skip URLs containing certain characters as probable queries, etc.
#-[?*!@=]
# skip URLs with slash-delimited segment that repeats 3+ times, to break loops
-.*(/.+?)/.*?\1/.*?\1/
# accept hosts in MY.DOMAIN.NAME
#+^http://([a-z0-9]*\.)*MY.DOMAIN.NAME/
#discuz
+^http://mysite.com/discuz/index.php$
+^http://mysite.com/discuz/forumdisplay.php\?fid=\d+$
+^http://mysite.com/discuz/forumdisplay.php\?fid=\d+&page=\d+$
+^http://mysite.com/discuz/viewthread.php\?tid=\d+&extra=page%3D\d+$
+^http://mysite.com/discuz/viewthread.php\?tid=\d+&extra=page%3D\d+&page=\d+$
# skip everything else
-.
- nutch\conf\regex-urlfilter.txt 我不清楚该配置文件是否有起作用,但建议注释掉其中的,-[?*!@=]。
执行爬虫
-
由于Nutch的脚本采用的是linux下是shell,在windows下需要使用cygwin来执行。至于cygwin的具体使用…,这个到网上找其他文章吧。cygwin官网
-
进入Nutch目录后执行命令 sh bin/nutch crawl urls -dir crawl -threads 2 -depth 100 -topN 1000000 >& crawl.log 完成网站的抓取和索引。
- threads 抓取网页的线程数,理论上线程数越多速度越快,但过多的线程会给服务器带来比较大的负担,影响正常使用。
- depth 页面的抓取深度。
- topN 每层最多抓取的页面数
- crawl.log 日志存放文件
windows定时任务的建立
Nutch的索引建立好后并不会自动更新,需要使用windows的计划任务建立计划任务来定期更新索引。
-
具体做法待续
WEB搜索界面的部署
Nutch使用Java开发,其WEB界面需要跑在相应的web容器中,这里采用的是tomcat6。
部署到tomcat
- 复制nutch-0.9.war到tomcat6\webapps,运行tomcat6\bin\startup.bat启动tomcat。
-
tomcat将自动对war文件进行解压。修改文件tomcat6\webapps\nutch\WEB-INF\classes\nutch-site.xml,设置nutch的索引文件位置。
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>searcher.dir</name>
<value>D:\AppServ\nutch\crawl\</value>
</property>
</configuration> - 重启tomcat并测试搜素功能,如果没有意外,服务将正常运行。
相关问题修正
- 搜索页面上的部分中文出现乱码。该问题主要由jsp:include引起。将被包含文件nutch\zh\include\header.html由UTF-8转换为GBK,修正该问题。
-
搜索中文出现乱码。修改tomcat配置文件tomcat6\conf\server.xml。增加URIEncoding/useBodyEncodingForURI两项。
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"
useBodyEncodingForURI="true"/> - 网页快照乱码问题修正。修改页面tomcat6\webapps\nutch\cached.jsp,将content = new String(bean.getContent(details))修改为content = new String(bean.getContent(details),"utf-8")。
-
apache整合。修改apache配置文件\conf\httpd.conf,增加如下配置
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
<IfModule mod_proxy.c>
ProxyPass /nutch http://localhost:8080/nutch
ProxyPassReverse /nutch http://localhost:8080/nutch
</IfModule> -
url问题。在和apache整合后会出现url不正确的问题。主要表现为用户看到的url的前缀为ProxyPass中配置的url。目前还没有比较好的解决方案,只能手动修改所有问题jsp页面。使用命令findstr /s requestURI *.jsp查找出所有问题页面。在String base = requestURI.substring(0, requestURI.lastIndexOf(‘/’));后面增加base = base.replace("localhost:8080", "mysite.com");,将错误的url替换为正确的url地址。
- 删除页面tomcat6\webapps\nutch\cached.jsp,关闭网页快照功能。由于部分页面,当前用户可能无访问权限,关闭快照功能。
中文问题修改
Nutch默认支持中文搜索,只是Nutch对中文采用安字进行分词,例如搜索“中国”不使用双引号,将返回所有包含“中”和“国”的网页。为方便使用,系统自动为搜索内容添加双引号。
-
修改文件tomcat6\webapps\nutch\search.jsp。增加格式化搜索字符的函数,同时对queryString进行处理。
<%!
public static String format_query_str(String s) {
s = s.replace("”", "\"").replace("“", "\"");// 处理中文符号
if (s.indexOf("\"") > -1) {// 如果包含"则不继续进行处理
return s;
}
String[] ss = s.split(" ");
String ret_s = "";
for (String str : ss) {
if (str.trim().equals("")) {
continue;
}
if (str.indexOf("-") == 0) {
str = "-\"" + str.substring(1) + "\"";
} else {
str = "\"" + str + "\"";
}
ret_s += str + " ";
}
return ret_s.trim();
}
%>
queryString = format_query_str(queryString);
搜索帮助
- 使用方法和常见的搜索引擎类似,支持多关键字,多个关键字之间使用空格进行分割。
- 对中文采用安字进行分词,因此对中文搜索时最好加上双引号。例如搜索“中国”如果不使用双引号,将返回所有包含“中”和“国”的网页。
- 可以在一个词前面加减号丛而禁止它出现在搜索结果中, 例如, 搜索football -nfl 会找到讨论football, 但不出现"nfl"的网页。
- 搜索英文单词不区分大小写, 因此搜索NuTcH 等同于搜索 nUtCh。
相关网站
Trac部署说明
Trac介绍
Trac是一个项目管理工具,同时提供了良好的插件接口,可以以Trac作为平台开发自己的基础应用。
部署
获取相关资源
Trac使用python编写,首先需要python的支持。Trac使用GenShi作模板引擎,在安装Trac前需要先安装GenShi。Trac的用户管理非常的难用(需要使用apache的权限设置),通过使用第三方扩展AccountManagerPlugin来方便用户的管理。
相关的资源下载地址如下。
安装/部署相关组件
-
进入GenShi/Trac的根目录,使用setup.py install对GenShi/Trac进行安装。
-
进入AccountManagerPlugin根目录使用setup.py bdist_egg命令生成egg。
配置Trac环境
在安装好Trac之后,需要使用Trac的管理命令对Trac环境进行初始化。
-
使用命令trac-admin %prjpath% initenv初始化Trac环境,其中%prjpath%为您指定的数据存放的位置。
-
初始化好Trac环境后使用tracd –port 9000 %prjpath%命令及可通过Trac的内置服务器启动Trac。此时可以以匿名用户的方式访问Trac。
-
在初始化好Trac环境后需要继续完成Trac的用户认证配置。将前面AccountManagerPlugin生成的egg文件复制到%prjpath%/plugins,增加AccountManagerPlugin插件。
-
修改Trac的配置文件%prjpath%\conf\trac.ini,增加如下内容。
[components]
;关闭Trac自带的认证模块
trac.web.auth.LoginModule = disabled
;关闭注册功能
;acct_mgr.web_ui.registrationmodule = disabled
[account-manager]
password_store = SessionStore
hash_method = HtDigestHashMethod -
通过AccountManagerPlugin的注册功能,注册一个Trac帐户admin,并使用命令trac-admin %prjpath% permission add admin TRAC_ADMIN将该用户设置为管理员。
- 使用新增加的管理员帐户登陆Trac,就可以顺利的进入Trac的管理后台对Trac进行管理。
和Apache的整合
Trac和Apache的整合可以使用mod_python/wsgi等,具体方法,请查看Trac官方的相关文档。
Awstats部署说明
Awstats介绍
AWStats是在Sourceforge上发展很快的一个基于Perl的WEB日志分析工具。通过分析服务器的访问日志,可以了解服务器的使用情况,方便服务器的维护和管理。
基础安装
-
AWStats使用perl编写,因此需要perl的环境支持。对于windows用户,下载ActivePerl,并安装。
-
从AWStats官网获取最新的AWStats。
- 将AWStats解压,并进入目录awstats\tools,执行命令perl awstats_configure.pl,按照提示完成配置(依次输入apache位置/apache配置文件位置/统计站点的域名)。
- 修改Apache配置文件Apache2.2\conf\httpd.conf,找到Awstats新添加的配置(配置文件的最下面),将里面的文件位置换成AWStats的实际位置。
- 修改文件awstats\wwwroot\cgi-bin\awstats.pl,将第一行的perl路径换成实际位置(如:#!c:\perl\bin\perl.exe)。
- 重新启动apache,浏览器中输入http://mysite/awstats/awstats.pl?config=mysite,查看AWStats是否正常运行。
日志分析的相关配置
在完成基础配置后AWStats已可以正常运行,但由于没有进行日志分析,将看不到任何的统计信息。
-
Apache默认只使用一个日志文件,如果日志文件太大,将给日志分析带来极大的负担。修改Log配置,将Log配置修改为CustomLog "|bin/rotatelogs.exe -l logs/access%Y-%m-%d.log 86400" combined。每天生成一个文件。
-
Apache的日志文件格式LogFormat,如果包含LogFormat "%h %l %u %t \"%r\" %>s %b" common,则注释掉,不然日志信息中将不包含User-Agent信息(浏览器/操作系统类型等)。
- Awstats的站点配置文件在awstats\wwwroot\cgi-bin,配置文件名字为 awstats.你的站点名字.conf(如:awstats.mysite.conf)。
-
修改LogFile配置Apache的日志位置和文件名的格式,文件格式需要和apache的日志文件格式相匹配。如:LogFile="D:/AppServ/Apache2.2/logs/access%YYYY-24-%MM-24-%DD-24.log"。这里表示日志格式为2008-10-10.log,-24表示24小时以前,也就是前一天日志文件。
-
LogFormat默认为1,如果Apache日志中没有包含User-Agent信息,则需要将LogFormat设置为4。
- 进入目录awstats\wwwroot\cgi-bin,执行脚本awstats.pl -config=mysite -update -lang=cn完成日志分析。如果日志分析成功,重新进入AWStats,将可看到服务器的访问信息。
- 在windows的计划任务中创建任务awstats.pl -config=mysite -update -lang=cn,设置每天晚上对前一天的日志进行分析。
Awstats访问权限设置
Awstats默认情况系任何人都可以访问。可以通过apache限制Awstats限制只有登陆的用户才能访问。
-
在Apache的配置文件,Awstats的目录权限配置中添加访问权限控制。
<Directory "D:/AppServ/awstats/wwwroot">
Options None
AllowOverride None
AuthName "admin onssw Access"
Order allow,deny
Allow from all
AuthType Basic
AuthName "Restricted Files"
AuthUserFile D:/AppServ/Apache2.2/conf/passwords
Require user admin
</Directory> -
使用Apache2.2\bin\htpasswd.exe生成密码问题。htpasswd -c D:\AppServ\Apache2.2\conf\passwords admin。
- 在配置好Awstats的访问权限后,每次访问Awstats将被要求登陆。输入用户名admin和刚设置的密码,完成登陆验证。
ClearQuest二次开发
ClearQuest API概述
Rational ClearQuest 是重要的变更管理工具,Rational ClearQuest 更能让客户根据自己的具体需求,灵活的设计变更管理流程。除此之外,Rational ClearQuest 还提供了一套编程接口,即 Rational ClearQuest API,让用户和开发人员可以根据需要通过编程来实现 Rational ClearQuest 的相关功能,同时还可以通过编程来实现模式中 Hook 脚本的开发和定制,从而使整个 Rational ClearQuest 产品的功能更加灵活和强大。
通过CQ的二次开发接口,我们可以更灵活的定义自己的统计,或是使用脚本来批量修改CQ中的MR。
ClearQuest API 提供了VBS实现和Perl实现。也就是说可以使用VBS或Perl进行CQ的二次开发,两种开发方式提供了完全一致的开发接口。同时由于VBS是用过调用COM来使用CQ接口,理论上可以使用其他开发语言通过直接调用COM的方式来使用CQ的API。
由于VBS和COM都为MS的专有技术,VBS的脚本只能在windows平台上执行,Perl脚本则可以实现跨平台。 相比VBS,Perl的使用面更广,功能也更为强大,且考虑到Perl的跨平台性,使用Perl进行CQ的二次开发会是一个比较好的选择。
Perl语言基础知识
需要使用CQ的API需要先安装CQ的客户端。CQ的客户端有带一个专供CQ使用的perl引擎,cqperl,在运行perl脚本时候直接使用cqperl xx.pl运行。
考虑到熟悉Perl的用户并不多,在介绍CQ API前先对Perl的相关语法等做个简单的介绍。这里只提供基础的入门介绍,以便perl程序的阅读,如需要更深入的了解请阅读参考中的相关文档。
基本语法
perl里面语句也是用“;”来分开的。注释使用“#”。
变量符号
- 标量定义,以$号开头,如:$num =1;
-
数组定义,以@开头,如:@array = (1,2,3);
数组元素调用 @array[index],其中index表示数组下标,如上例,@array[0]的值是1 -
散列定义,以%开头,如:%hash=("a",1,"b",2);
散列调用 %hash,其中key表示键值,如上例,%hash{"b"}的值是1
变量范围
- $xx什么都不写,表示全局变量。整个文件中都可以访问到;
- local $xx 表示局部变量,但是这个值可以被其调用的子程序访问到
- my $xx 表示局部变量,只能在这一个函数里面可以使用,子程序就不能使用
函数定义
sub FunctionName
{
local ($a,$b)=@_;
return “”;
}
注意: 函数后便没有(),也没有参数列表定义。也就是说,他接受任何形式的参数,以数组的方式传递过来。所以内部使用的话,就用@_这个默认当前参数来取之。
操控语句(语法)
- 除" " "0"(空字符,0),以外都为真。
- if/while/until/for等语法类似c/cpp/java
-
使用foreach进行遍历。
foreach $user (@users) {
do something...
} - 跳出控制结构: next 和 last。next跳过当前操作,进入下一循环。last直接跳出循环。
-
perl包含文件。具体说明参考Perl中的文件包含(do, require, use)
ClearQuest API使用说明/范例
连接CQ库
CQ的数据存储在数据库(用户数据库)中,我们公司使用的是SQL Server。虽然可以通过直接访问SQL Server数据库的方式获取MR信息,但由于数据库的表结构复杂且受权限的约束(没有开放写权限),很多时候直接访问数据库并不是一个好主意。
在使用CQ API时,首先要做的是和CQ建立session,连接上CQ的库(模式库)。主要步骤为:
-
创建session对象
my $session = CQSession::Build();
-
登陆CQ库
$session->UserLogon(login_name, password, database_name, database_set);
- login_name 登陆的用户名,也就是使用CQ客户端登陆的用户名。
- password 用户密码,同CQ客户端登陆的密码。
- database_name 库名
- database_set 库集。
操作完成后关闭session。
CQSession::Unbuild($session);
创建查询
在成功建立session后就可以对CQ库进行操作了。
创建查询的主要步骤如下。
-
创建Query对象。
my $queryDef = $session->BuildQuery(entitydef_name);
- entitydef_name 这个就是在CQ客户端创建查询时候选择的record type。
-
设定需要返回的字段(同CQ客户端上选择的输出字段)。
$queryDef->BuildField("id");#id
$queryDef->BuildField("Headline");#标题
...... - 创建查询条件。
-
创建查询条件对象。
my $operator = $querydef->BuildFilterOperator(bool_operator);
- bool_operator 这个为逻辑条件。常用的逻辑条件如:$CQPerlExt::CQ_BOOL_OP_AND(与) $CQPerlExt::CQ_COMP_OP_EQ(等于)
-
为查询对象,设置过滤条件。
$operator->BuildFilter(field_name, comparison_operator, value);
- field_name 进行过滤的字段名,同CQ客户端中设置的过滤条件字段。
- comparison_operator 逻辑判断条件。$CQPerlExt::CQ_COMP_OP_EQ 等。
- value 该字段的值
-
创建结果集
my $resultSet = $session->BuildResultSet($queryDef);
执行查询,获取查询结果
-
执行查询
$resultSet->Execute();
-
遍历,获取查询的结果集的值。
while (($resultSet->MoveNext()) == 1)
{
my $mr_id=$resultSet->GetColumnValue(1);
}-
使用$resultset->GetColumnValue(columnNum);获取字段的返回结果,其中columnNum为返回字段的序列,由1开始。
-
编辑MR
除获取MR外,对MR进行一些编辑也是常用的操作。编辑MR主要需要以下操作。
-
获取需要编辑的MR对象
$session->GetEntity(entity def_name, display_name);
-
def_name 这里同BuildQuery的参数类似
- display_name 这里填写MR ID
-
编辑对象
$session->EditEntity(entity, edit_action_name);
- entity 需要编辑的对象
- edit_action_name 编辑操作的名称,(例如: "modify" or "resolve")
设定字段的值
$entity->SetFieldValue(field_name, new_value);
- field_name 字段名称
- new_value 修改后的值
-
提交 $entity->Commit();
-
回滚 $entity->Revert();
完整范例
在这个范例中,将查找出在dbname里Product为prd10000且Verified的MR,并将其Close。
use CQPerlExt;
###连接CQ###
my $loginName = "loginName";
my $loginPassword = "loginPassword";
my $databaseName = "dbname";
my $databaseSet = "dbset";
my $session = CQSession::Build();
$session->UserLogon($loginName, $loginPassword, $databaseName, $databaseSet);
###创建查询,查询出需要close的MR###
my $queryDef = $session->BuildQuery("Dev_Defect");
$queryDef->BuildField("id");#id
my $operator1 = $queryDef->BuildFilterOperator($CQPerlExt::CQ_BOOL_OP_AND);
@Product = ("%prd10000%");
$operator1->BuildFilter("Product", $CQPerlExt::CQ_COMP_OP_LIKE, \@NE_Product);
@State = ("Verified");
$operator1->BuildFilter("State", $CQPerlExt::CQ_COMP_OP_EQ, \@State);
my $resultSet = $session->BuildResultSet($queryDef);
$resultSet->EnableRecordCount();
$resultSet->Execute();
my $count = $resultSet->GetRecordCount();#获取查询出的MR个数
print "count: $count\n";
###遍历查询出的MR,并进行Close操作###
while (($resultSet->MoveNext()) == 1)
{
$id = $resultSet->GetColumnValue(1);
print "$id\n";
###执行Close操作###
$entity = $session->GetEntity( "Dev_Defect", $id );
$session->EditEntity($entity,"close");
$entity->SetFieldValue("Closed_Information", "Close");
my $Status = $entity->Validate();
if($Status eq "")
{
# 提交数据记录
$entity->Commit();
}
else
{
# 打印错误信息
print $Status;
$entity->Revert();
}
}
CQSession::Unbuild($session);
参考资料
-
ClearQuest API Reference
ClearQuest API使用手册,安装CQ客户端附带。