0%

tkinter(Tk interface)模块在python 3.x中的名字为”tkinter”,在python 2.x中的名字为”Tkinter”,好微妙!

各大浏览器,除了fireofx,对select控件option子元素的样式支持都很差。为option设置padding,margin和text-indent只有firefox会正确的展现,其他浏览器,包括chrome,safari,opera和ie,根本没有任何效果。所以对于option的层次缩进只能使用空白填充大法了。

nginx fastcgi程序执行带有sudo命令的脚本时,前台报错”502 Bad Gateway”,后台日志中有错误记录”sudo: no tty present and no askpass program specified”,是因为nginx是以用户www-data来执行脚本的,而www-data用户默认是不在sudoers中的,并且执行脚本时没有tty,sudo也无法执行请求用户密码的程序,故有此提示。因此若要nginx可以执行使用sudo命令的CGI脚本,则必须将www-data加入sudoers,并且不能提示输入密码,也就是不用验证密码即可。

使用bash写fastcgi程序时,一定要先输出Content-type和一个空行,不然nginx会报错502 Bad Gateway,后台访问日志中会有”upstream prematurely closed FastCGI stdout while reading response header from upstream”错误。

下面两种写法皆可:

1
2
3
#!/bin/bash 

echo -e "Content-type: text/html\\n"

或者

1
2
3
4
#!/bin/bash 

echo "Content-type: text/html"
echo ""

之后可以继续输出text或者html文本

jenkins可以集成gitolite,这样代码推到仓库后,jenkins可以立即构建工程,并可以自动发布。

1、配置gitolite用户

jenkins要执行构建任务,必须可以从gitolite仓库获取代码,因此需要为jenkins配置访问gitolite的用户。可以参考”gitolite v3安装配置“。只要记住jenkins的用户主目录在/var/lib/jenkins就可以了,与普通用户的配置并无二致。同样可以在用户主目录下的.ssh目录下添加config来访问gitolite,注意known_hosts中要添加gitolite主机的fingerprint。

1
2
3
4
5
Host gitsvr
Hostname *.*.*.*
User git
Port 2022
IdentityFile /var/lib/jenkins/.ssh/id_rsa

这里配置的gitolie访问别名为gitsvr,然后jenkins使用如gitsvr:project就可以访问到gitolite管理的仓库project了。

2、配置gitolite hook

jenkins的git插件目前只支持定时poll,虽然设置一个较短时间的轮询间隔也能满足要求,但总觉不太爽利。幸好git和
gitolite都支持hook,而且jenkins的git插件提供了一个url接收通知来进行构建。所以使用gitolite的post-receive
钩子通知jenkins构建就可以了。

gitolite用户的~/.gitolite/hooks/common/post-receive添加如下脚本:

1
2
3
4
5
6
7
#!/bin/bash

JENKINS_URL=http://*.*.*.*:8082
GIT_URL=gitsvr
echo -n "Notifying Jenkins..."
wget -q $JENKINS_URL/git/notifyCommit\\?url=$GIT_URL:$GL_REPO -O /dev/null
echo "done."

gitolite自动设置了一个环境变量GL_REPO,这个变量的值是当前操作的仓库的名字。为post-receive脚本添加执行权限,然后执行gitolite setup就可以了。

1
2
$ chmod +x post-receive
$ gitolite setup

3、配置jenkins job

现在就可以添加jenkins job了

几个关键的地方:

源代码管理选择git后,设置Repository URL为配置好的别名加仓库名就可以,比如gitsvr:project

构建触发器(build trigger)要选择poll SCM,但不要输入任何值,保持空白即可。

这里采用gradle进行构建,选择Invoke Gradle,如果构建文件名字采用默认的build.gradle,则除了tasks那里填写build,其他字段空着使用默认值即可。

构建后在自动发布到tomcat7,因此这里选择”Deploy war/ear to a container”,然后选择tomcat7。WAR/EAR files填写相对于当前job的workspace目录的需要部署的文件的名字,比如build/libs/project.war。Context path输入自己想使用的访问路径,比如输入foo,则需要这样访问应用程序http://domain.tld/foo。其他字段为tomcat7的管理用户账号和访问tomcat7的URL。

如果想将应用程序部署到root context,只需在Context path里输入”/“即可,这样访问应用程序时就更简单了,http://domain.tld/就是访问的root context。

这样jenkins就算配置完了,可以通过手动构建进行测试。

4、其他问题

  • 由于项目使用了myBatis,因此有一些xml资源文件分散在dao接口目录中,所以需要在build.gradle脚本中添加资源目录,否则这些xml文件不会被打包,从而出现错误:

    1
    2
    3
    4
    5
    sourceSets {
    main {
    resources.srcDirs = \['src/main/java'\]
    }
    }

    如果不指定资源目录,则需要将资源放入src/main/resources目录。

  • gradle war插件默认生成的war包名字格式为:
    ${baseName}-${appendix}-${version}-${classifier}.${extension}
    也就是war.archiveName变量的默认值。

    gradle自动构建时生成的war包名字可能不是你想要的,因此可以明确的指定war包名字,比如在build.gradle文件中添加如下行:
    war.archiveName = ‘project.war’

  • 用于tomcat7自动部署的管理用户必须具有manager-script角色,manager-gui角色是不够的,不然会有错误出现:
    The username you provided is not allowed to use the text-based Tomcat Manager (error 403)

    在/etc/tomcat7/tomcat-users.xml文件中为管理用户添加manager-script角色即可。

References:
[1]Gitolite to Jenkins Post Commit Kick

===
[erq]

HTML5新增加了很多input元素类型,比如color,date,datetime,datetime-local,email,month,number,range,search,tel,time,url,week等。

通过以下方法可以检测浏览器是否支持这些新的input类型:

[html]
var i = document.createElement(‘input’);
i.setAttribute(‘type’, ‘date’);
//浏览器不支持date类型
if(i.type == ‘text’){
}
[/html]
这里为新添加的input元素设置type特性(attribute)为date,如果浏览器支持date类型,则其对应的dom对象的type属性(property)会设置为date,否则会设置为text,这里一定要注意”特性(attribute)”和”属性(property)”的区别。attribute是标签的特性,而property是标签对应的DOM对象的属性。

所以,即使浏览器不支持新的input类型,虽然其DOM对象的type属性被设置为text,但其标签的type特性仍然是原来设置的值,对上面这个栗子来说就是date

[html]
i.getAttribute(‘type’) == ‘date’; //true
[/html]

特性与属性的区别见”DOM对象属性(property)与HTML标签特性(attribute)

===
[erq]

添加一个尺寸为1英寸物理div,然后获取其尺寸的逻辑单位值就可以了。

1
2
3
4
5
6
<div id="ppitest" style="width:1in;height:1in;visible:hidden;"></div>
<script>
var ppi_x = document.getElementById('ppitest').offsetWidth;
var ppi_y = document.getElementById('ppitest').offsetHeight;
alert('ppi_x='+ppi_x+'; ppi_y='+ppi_y);
</script>

===
[erq]

有时候可能会需要在加载Re­quireJS之前就加载jQuery,因为有些代码并不在Re­quireJS的管理范围之内,比如这样
[html]

[/html]
but这时候会出现错误,怎么办呢?
因为jQuery无论如何都是会暴露到全局名字空间的,所以为main.js文件的前部为jQuery定义一个占位模块好了
[html]
define(‘jquery’, [], function() {
return jQuery;
});
[/html]

其实最新版本的jQuery也是在检测到Re­quireJS之后这样来定义jQuery模块的。

References:
[1]Load jQuery be­fore Re­quireJS and still use it as de­pend­ency

===
[erq]

postgresql psql命令修改列去掉非空约束: ALTER TABLE table_name ALTER COLUMN column_name DROP NOT NULL;