在Heroku上部署django项目

最近尝试了下将自己的django项目部署到Heroku上。虽然大家都说Heroku是为Ruby on Rails准备的, 但它也支持python和django,在网站运行初期使用它还是比较方便的。

官方文档中对于部署django的方法有详细说明,这里就不再罗嗦了,只给出几个重点。

如何部署代码?

首先要安装Heroku工具链

如果我已用GitHub管理代码,怎样将代码部署到Heroku上?Heroku使用git实现部署,部署就像推送代码一样简单。 首先要登录Heroku建立你的App,然后在App的Settings里可以看到Git URL,例如:

git@heroku.com:yourapp.git

然后到你自己的代码库中,把这个代码库添加为remote

$ git remote add heroku git@heroku.com:yourapp.git

部署时只需执行

$ git push heroku master

就可以了。

如何安装依赖包?

在你自己的开发环境中执行:

$ pip freeze > requirements.txt

这个命令会把环境中安装的所有包输出到requirements.txt中。将这个文件放到代码库根目录下,部署后就可以自动安装依赖包了。 你也可以编辑下requirements.txt去掉不必要的包。

如何运行代码?

Heroku要求你自己指定运行服务的命令。一般使用gunicorn来运行django代码,所以要在代码仓库的根下建立一个Procfile文件, 以指定运行代码的命令:

$ cat Procfile
web: gunicorn -b 0.0.0.0:$PORT yourapp.wsgi

注意这里的-b参数(绑定地址)。每次Heroku运行代码时,会随机分配一个端口号,保存在环境变量$PORT里, 代理服务器会用这个端口号来访问你的应用。所以服务要绑定到0.0.0.0:$PORT上,否则Heroku的代理就找不到了。 yourapp.wsgi指的是django项目中的yourapp/wsgi.py

还有一点要注意的是,Heroku提供的运行环境中并不包括gunicorn,所以要把gunicorn也加到requirements.txt中。

如何判断Heroku环境/如何配置数据库

我们的代码需要判断当前环境是开发环境还是Heroku环境,以执行不同的操作(比如判断是否打开调试模式等)。 可以采用如下方法。

首先,在Heroku环境中建立环境变量:

$ heroku config:set HEROKU_ENV=TRUE

然后在代码里(一般在settings.py)这样写:

if 'HEROKU_ENV' in os.environ:
    # it is in heroku env
else:
    # it is in dev env

那么如何设置数据库呢?Heroku提供的数据库是PostgreSQL,连接字符串保存在$DATABASE_URL中。 可以使用dj_database_url包导入数据库配置。在settings.py中这样写:

# parse the database configuration from $DATABASE_URL
import dj_database_url
DATABASES['default'] = dj_database_url.config()

# Honor the 'X-Forwarded-Proto' header for request.is_secure()
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

当然,不要忘了把dj_database_url放到requirements.txt里。

关于Linksys PAP2中的Dial Plan设置

这几天在折腾家里的IP电话,查了些关于PAP2的Dial Plan的设置,总结如下。

Dial Plan是干什么的?

简单来说,Dial Plan告诉VoIP设备该如何处理电话机拨号盘的输入,以实现各种功能, 如本地电话前自动加区号、国际长途自动添加指定前缀、特服号码转到特定号码等功能。

Linksys PAP2中的Dial Plan位于Voice → Admin Login → switch to advanced view → Line 1/2的最底部。

Linksys PAP2 Dial Plan

Dial Plan的格式

例如,下面这个Dial Plan:

(<:1780>[2-4]xxxxxxS0|*xx|<911:17804213333>S0|011[2-9]x.|1[2-9]xx[2-9]xxxxxx|1900xxxxxxx!)

首先,Dial Plan必须放在一对括号()中。

其次,Dial Plan由|分隔成多个部分,每部分表示一条指令。

第一部分的<:1780>[2-4]xxxxxxS0中,<:>表示将:之前的内容替换成:之后的内容。 由于这里:前的字符串为空,所以匹配这条指令的号码都会加上前缀1780

接下来的[2-4]只匹配一位数字234,这个跟正则表达式有点相似。

接下来的xxxxxx,字符x匹配一位任意数字(0-9),所以这一段匹配六位数字。

最后的S0表示Straight Out,表示如果匹配了前面的指令,就无需等待后续拨号输入,而直接拨出。

因此,第一部分<:1780>[2-4]xxxxxxS0的意思是,任何以2、3、4开头后接6位数字的号码, 应当添加前缀1780,并直接拨出。于是212-3456这个号码会解释成+1(780)212-3456

第二部分为*xx,其中*表示拨号键盘上的*键,所以这部分匹配诸如*69等特殊号码。

第三部分<911:17804213333>S0将紧急电话911替换成本地号码+1(780)421-3333并立即拨出。

第四部分011[2-9]x.中,最后的.表示重复前一个符号任意次,所以这个指令匹配以01120119开头、 后接至少一位数字的号码。

第五部分1[2-9]xx[2-9]xxxxxx匹配正常的以1开头的十位电话号码。

最后一部分1900xxxxxxx!中,!表示阻拦符合该指令的号码,所以这条指令阻拦以1900开头、后接七位数字的电话拨出。

Sentry: 错误日志集中管理

Sentry是个很好用的错误日志服务器,可以将程序错误的详细情况集中捕获,并提供一个很漂亮的Web界面来浏览错误。 Sentry本身是用python写的,但它支持python、php、ruby、iOS等多种语言。

要使用Sentry,你需要一台服务器来运行Sentry服务器,然后需要在代码中插入Sentry客户端的代码。服务器安装方法如下:

$ sudo pip install sentry

目前(2013/1/22)安装过程中可能会发生找不到某些依赖的情况,比如无法安装Django-1.4.3等, 可能需要手工下载Django-1.4.3的代码、编译安装后再重新执行上述命令。

我遇到的另一个问题是,代码使用的是django-1.3,而sentry要求django-1.4,而且我打算在应用服务器上运行sentry, 所以不得不使用virtualenv来安装sentry。

装好之后需要使用以下命令建立配置文件:

$ mkdir ~/.sentry
$ sentry init ~/.sentry/sentry.conf.py

然后打开~/.sentry/sentry.conf.py,按照需要修改。我在SENTRY_WEB_OPTIONS中加了一项daemon: True, 使sentry以daemon模式运行。

然后启动sentry服务器即可。

$ sentry start

执行该命令会让你输入管理帐号和密码。

用浏览器访问 http://localhost:9000/,即可看到sentry的Web界面。登录之后建立一个项目,然后即可配置客户端。 对于使用django框架的项目,客户端可以如下配置:

$ sudo pip install raven       # 如果项目和sentry位于不同服务器,可能需要安装raven

打开django的settings.py,加入:

SENTRY_DSN = 'xxxxxxx'         # 在sentry的Web界面中建立项目后即可查看
                               # for django的配置文档,从中可以找到`SENTRY_DSN`的值
INSTALLED_APPS = {
    ....
    'raven.contrib.django',    # 加入这一行
    ....
}

这样django项目中产生的异常就都会集中到sentry服务器上了。

如果不想自己搭建sentry服务器,还可以使用官方提供的服务,价格也不算太高。

robotframework + selenium实现网站自动测试

本文参考:How to use RobotFramework with the Selenium Library

先来介绍下背景。Selenium是个强大的自动化测试工具,可以手工编写或自动录制测试脚本,可以手工执行,也可以自动执行。而robotframework是个通用的自动化测试框架。 robotframework-seleniumlibrary是robotframework的一个测试库,它可以集成Selenium,并提供一套简单易懂的语法用于书写测试用例(好处就是测试人员不用学任何编程语言也能写测试用例了)。

用这套工具能实现:

  • 无需学习编程语言即可编写测试脚本
  • 自动点击网站链接、输入文字、点击按钮、验证结果
  • 可以放在cron里每日自动执行
  • 自动生成测试报告
  • 对于fail的测试用例,保存输出结果并截图

下面是配置方法。操作系统用的是Ubuntu 12.04。

Continue reading

[git]subversion转git以及git仓库合并

公司决定转向github,所以今天遇到的问题是要把两个subversion仓库合并到一个github仓库中。

subversion转git这个问题很容易,github推荐使用svn2git这个脚本。 官方网站上写出了详细的安装方法,如下:

$ sudo apt-get install git-core git-svn ruby rubygems
$ sudo gem install svn2git

然后建立两个子目录,存放转换后的两个subversion仓库:

$ mkdir tmp && cd tmp 
$ mkdir projectA projectB

开始转换:

[charlee@ubuntu:~/tmp]$ cd projectA
[charlee@ubuntu:~/tmp/projectA]$ svn2git http://svn.example.com/projectA        # 由于是标准目录结构,这里不需要指定trunk分支
[charlee@ubuntu:~/tmp/projectA]$ cd ../projectB
[charlee@ubuntu:~/tmp/projectB]$ svn2git http://svn.example.com/projectB
[charlee@ubuntu:~/tmp]$ cd ..

这样就得到了projectA和projectB两个git仓库。接下来用stackoverflow上提到git-stitch-repo将这两个仓库合并成一个。首先安装git-stitch-repo:

$ tar xzvf Git-FastExport-0.07.tar.gz
$ make
$ sudo make install

[charlee@ubuntu:~/tmp]$ git clone https://github.com/charlee/project.git
[charlee@ubuntu:~/tmp]$ cd project
[charlee@ubuntu:~/tmp/project]$ git-stitch-repo ../projectA:projectA ../proejctB:projectB | git fast-import
[charlee@ubuntu:~/tmp/project]$ git checkout master-A
[charlee@ubuntu:~/tmp/project]$ git checkout master-B
[charlee@ubuntu:~/tmp/project]$ git checkout master
[charlee@ubuntu:~/tmp/project]$ git branch -d master-A master-B

然后扔到github上:

$ git push -u origin master

大功告成。

[iOS]制作native-like的webapp时的一些要点

当用户tap一个页面元素时,iOS会在元素周围显示橙色的外框,以表明该元素被tap了。如果你想自己实现tap时的响应效果,可以用以下方法“去除”这个高亮效果。(来源)

-webkit-tap-highlight-color: rgba(0,0,0,0);  

禁止用户选择页面文字:(来源)

-webkit-user-select: none;

如果你响应onclick事件,会发现click事件有大约半秒的延迟,这是因为iOS需要等待一段时间来判断用户是点击还是拖动。如想去掉这个延迟,可以用ontouchstart代替onclick:(来源)

$(".button").bind("touchstart", handler);

但这样在桌面浏览器中鼠标点击操作就不要用了。没关系,可以做一下判断。

if ('ontouchstart' in window) {
    // mobile version
    $(".button").bind("touchstart", handler);
} else {
    // desktop version
    $(".button").bind("click", handler);
}

禁止用户拖动页面:(来源

document.ontouchstart = function(e){ 
    e.preventDefault(); 
}

一些其他的信息:这里

Posted in web

Tags: , , ,

Permalink 1 Comment

cygwin下git出现ca-bundle.crt相关错误的解决办法

用cygwin下的git访问需要https连接的git repository(比如github)时,有时会报告错误:

error: error setting certificate verify locations:
  CAfile: /usr/ssl/certs/ca-bundle.crt
  CApath: none while accessing https://github.com/username/repositoryname/info/refs
fatal: HTTP request failed

这是因为缺少证书所致。重新运行cygwin的setup.exe,然后安装ca-certificates包即可解决问题。

FeinCMS Tutorial

FeinCMS是个基于django框架的开源CMS系统,简单高效,集成在django自身的admin界面中,用来做个blog、网站什么的非常方便。不过它的官方文档中没有一个合适的Tutorial,所以比较难以上手。这里把我安装FeinCMS的经历写下来作为Tutorial吧。

以下内容基于python-2.6, django-1.4, FeinCMS-1.6.2,操作系统为MacOS 10.5 + MacPort。

Continue reading

cufon,在网页上画出特殊字体

设计师们有时会使用特殊字体让网页更好看,但浏览器通常只支持Arial、Helvetica等通用字体。那么通常的解决办法就是将特殊字体做成图片。如果要动态生成文字内容怎么办?那也许只有使用CSS3的@font-face功能了……等下!其实还有cufon这个工具,可以帮我们在网页上”画”出特殊字体。

cufon的原理是将TTF字体转换成JavaScript代码,然后在需要特殊字体的地方创建一个<canvas>元素,将字体画出来。效果如下:

cufon的效果

使用方法也很简单,只需访问cufon,点击Download下载cufon-yui.js(目前版本为1.09i)。再点击Generator,上传你的字体文件,即可得到转换后的js文件(假设文件名为yourfont.font.js)。

然后在代码里引入这两个js文件,再写一点简单的代码:

<head>
<script src="cufon-yui.js"></script>
<script src="yourfont.font.js"></script>
<script>
Cufon.replace('h1', { color: '#333', textShadow: '2px 2px #ddd' });
</script>
</head>

这样h1的内容就被替换成了所需的字体。

更详细的讨论可以参考使用Cufon渲染网页字体

将Google Web Fonts保存成TTF

Google Web Fonts上有许多精美的字体,不过只能通过网页引用。有时页面设计需要使用这些字体,那么怎样才能把它们保存成TTF呢?

首先,访问Google Web Fonts,找到所需的字体。可以利用左侧的Search功能迅速找到字体。

搜索字体

然后点字体下面的”Quick-use”链接。

Quick-use

在Quick-Use界面找到第三步”3. Add this code to your website:”,复制代码中的链接,然后开个新的浏览器窗口,打开这个链接:

打开CSS链接

链接打开后就会看到下面的代码:

@font-face {
  font-family: 'Electrolize';
  font-style: normal;
  font-weight: 400;
  src: local('Electrolize'), local('Electrolize-Regular'), url(http://themes.googleusercontent.com/static/fonts/electrolize/v2/DDy9sgU2U7S4xAwH5thnJ7rIa-7acMAeDBVuclsi6Gc.woff) format('woff');
}

最后的url()中的链接就是字体文件,将它粘贴到新的浏览器窗口中即可下载。

如果字体文件扩展名为woff,那么需要将其转换为TTF。去Google搜索”woff to ttf”能找到很多这种工具,如Convert woff to otf

Posted in web

Tags: , ,

Permalink 2 Comments

分类目录

文章归档