Untitled Post - 65
tkinter(Tk interface)模块在python 3.x中的名字为”tkinter”,在python 2.x中的名字为”Tkinter”,好微妙!
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 | #!/bin/bash |
或者
1 | #!/bin/bash |
之后可以继续输出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 | Host gitsvr |
这里配置的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 | #!/bin/bash |
gitolite自动设置了一个环境变量GL_REPO,这个变量的值是当前操作的仓库的名字。为post-receive脚本添加执行权限,然后执行gitolite setup就可以了。
1 | $ chmod +x post-receive |
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 | sourceSets { |
如果不指定资源目录,则需要将资源放入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]
有时候可能会需要在加载RequireJS之前就加载jQuery,因为有些代码并不在RequireJS的管理范围之内,比如这样
[html]
[/html]
but这时候会出现错误,怎么办呢?
因为jQuery无论如何都是会暴露到全局名字空间的,所以为main.js文件的前部为jQuery定义一个占位模块好了
[html]
define(‘jquery’, [], function() {
return jQuery;
});
[/html]
其实最新版本的jQuery也是在检测到RequireJS之后这样来定义jQuery模块的。
References:
[1]Load jQuery before RequireJS and still use it as dependency
===
[erq]
vim不需要NERDTree,因为有原生的netrw. Vimmers, You Don’t Need NerdTree
postgresql psql命令修改列去掉非空约束: ALTER TABLE table_name ALTER COLUMN column_name DROP NOT NULL;