Explore. Dream. Discover.

Samuel Chen's life

Twenty years from now you will be more disappointed by
the things that you didn't do than by the ones you did do.
So throw off the bowlines. Sail away from the safe harbor.
Catch the trade winds in your sails.

Explore. Dream. Discover.
—— Mark Twain

2011年6月18日星期六

下一代互联网初见端倪

现在的互联网,以及所谓的物联网,争的是两块,一块是服务端,也就是云端,另一块是终端。

云端现在是Amazon, Google暂时领先于基础架构领域,MS, Apple 处于追赶之中,Facebook/Twitter则领先于SNS(此SNS含义相当广,包括身份,信用,关系,服务,应用等等)方面。传统厂商如IBM, HP基于其固有的优势,大力推广所谓私有云,实质是企业cluster,在下一代互联网中已经落后一步。

而终端则是Apple,Google 和 MS 三足鼎立。iOS和Android,已经成为了移动领域事实上的领头羊,MS在桌面的固有优势以及家庭媒体中的发力,使其保持在第一梯队中。而HP,虽然购买了3Par, Palm/webos,但依然未能表现出足够的进取。其他厂商,目前看来,只是陪太子读书的角色。

标签: , , , ,

2011年4月15日星期五

python 的编码,关于 encode, decode 的简单原则

Python 中 encoding 的处理其实已经很简单了,根据我这近一个月来用python的经验,有一个简单的原则可以作为参考。

基于python 2.7
1. 类型要清楚, unicode 不是 str
2. decode 之后的结果都是 unicode
3. encode 之后的结果都是 str,其编码是你encode的参数
4. 输出一律用 str
5. 存取一律用 unicode

 就这么简单,编码基本上就不会错了。 
举个例子,有个GBK编码的文件 name.txt,每行一个人名

for line in open('name.txt').readlines():
    print line  # 这时候 line 都是 gbk 的 str 
    x = line.decode('gbk')  # 转成 unicode了 >> 建议这么做, 原则: 但凡输入的,一律转换成unicode后处理
    print x  # 输出 unicode >> 不建议这么做
    print x.encode('utf-8') # 输出 str >> 建议这么做,原则:但凡输出,一定编码成str
    store_to_db(x)   # 这时候存的都是unicode
    my_str = x.encode('big5') # 转成 big5了
    print m_str   # 输出的是 big5 的 str

此外,encode 的时候不一定会成功,这时候会raise一个exception,这是因为 encode 还有一个参数用来控制encode失败后的处理,default是strict,也就是抛异常。

你可以用 encode(src, 'replace') 来处理,replace就表示碰到转不了的,用问号'?'来代替,而不是抛异常。

具体用法,查文档。

同样,输出的时候,输出流也需要有编码。比如stdout默认是ascii的,而你要输出unicode,就需要得到一个基于unicode的输出流,output = codecs.getwriter('utf-8')(sys.stdout)


标签: ,

2011年4月2日星期六

web.py 在 apache + fastcgi 配置 tips

根据web.py官网的说明,配置使其运行在apache + fastcgi 上,碰到了许多问题,耗了两天时间才整明白。一方面是apache的配置不熟悉,另外一方面是其官方文档也有些疏漏,问题及解决办法如下(ubuntu 10.04):
  • 调试日志
    web.py 应用挂在服务器上以后,stdout/stderr,都好像转了(查网上的,未验证),另外apache的用户是www-data,用户当前目录也是没有权限,所以logging要记录在/tmp下,或者单独建一个/log目录给写权限才行,这个一般规划好了没什么问题。
    另外,也可以做个ApacheLogHandler来将日志记到apache的日志文件中,这个网上可以搜到。
    然后就是,apache的日志文件在/var/log/apache2/ 。如果你的网站配置文件修改了日志位置,要注意这个地方只记录了一部分,还有一些仍然会记录在default位置。
    最后,可以使用traceback包来记录未处理的异常,代码如下:
    
    try:
        # web.py code
        # urls = ...
        # ...
        # app.run()
    
    except Exception, e:
        f = None
        if os.name == 'posix':
            f = open('/tmp/yule_unhandled_error.log', 'w')
        else:
            f = open('%s/yule_unhandled_error.log' % os.environ['temp'], 'w')
        traceback.print_exc( file=f )
        traceback.print_exc( file=f )
        f.close()
    
    
  • python 库路径 (PYTHONPATH)
    在 apache + fastcgi 中运行 python cgi,如果你使用了 PYTHONPATH 来引用库,你会发行看到的永远是 500 Internal Error。这是因为apache没有复制shell中的环境变量。
    注意,不要使用envvar文件,或者在网站配置文件中用setEnv,passEnv 等方法,这些方法我试过完全没有用。
    你要做的是,用代码将所有的路径全部都加到sys.path中。代码如下:
    
        import os, sys
        python_path = "/you/python/lib/path:/you/python/lib/path2".split(':')
        for path in python_path:
            sys.path.insert(0, path)
    
    
    当然你可以检查path是否已经加入了,注意路径访问权限,牢记现在的用户是www-data。
  • 静态文件
    好了,现在都配好了,再访问网站 ... OK 出来了!
    等等! 怎么搞的,样式表,图像怎么都显示不出来了?
    原来是web.py 官网的配置文件有少许疏漏,静态文件的转发不对!
    假设静态目录是网站根下的 /static/ (这也是web.py的推荐位置),那么我们要做的是修改网站配置文件的mod_rewrite 规则为:
    
    
        # 修改 ifmodule 这一节,注意蓝色行
           RewriteEngine on
           RewriteBase /
           RewriteCond %{REQUEST_URI} !^/icons
           RewriteCond %{REQUEST_URI} !^/favicon.ico$
           RewriteCond %{REQUEST_URI} !^/static/  ### 注意这一行 
           RewriteCond %{REQUEST_URI} !^(/.*)+code.py/
           RewriteRule ^(.*)$ code.py/$1 [PT]
    
    
    
好了,现在再试试,是不是已经好了 :)


标签: , , , , ,

2011年3月5日星期六

Django 如何在模板(template)中使用settings中预定义的变量


在Django中编写模板(template)的时候,有时候可能会用到settings中设定的变量,比如说STATIC_URL。此时,如果你直接使用 {{ STATIC_URL }} 是取不到值的。那么怎么才能在模板中使用呢?难道非得在每个view中添加到context中吗?

答案是否定的。根据Django文档中所描述,我们至少有两种方法可以直接使用。http://docs.djangoproject.com/en/dev/howto/static-files/#referring-to-static-files-in-templates

方法1:

使用 {% load static %} 载入 static 模块,然后使用 {% get_static_prefix %} 就可以了。
{% load static %}

<img src="{% get_static_prefix %}images/hi.jpg" />
当然也可以将其定义为变量以多次使用
{% load static %}

{% get_static_prefix as STATIC_PREFIX %}

<img src="{{ STATIC_PREFIX }}images/hi.jpg" />
<img src="{{ STATIC_PREFIX }}images/hi2.jpg" />

方法2:

这个方法是推荐的方法,直接使用 RequestContext 来传递。其原因就是因为settings中定义的变量都会在request中传递,但是response的时候是没有这些context的,所以Django专门定义了RequestContext来帮你组合(其实你自己也可以做这件事)。


#注意这里是django.template,由此可见是专门为template设计的
from django.template import RequestContext

def some_view(request):
    # ...
    return render_to_response('my_template.html',
                              my_data_dictionary,
                              context_instance=RequestContext(request))

这个实际作用就是将request中的context全部都加到response的context中去。

这样,你就可以直接在模板中使用{{ STATIC_URL }} 来使用了,当然其他的变量也是可以的,不需要每个都单独去load了。

标签: ,

2011年3月4日星期五

Django 静态文件配置


Django 自带的admin 用户及权限管理是一个很不错的功能,但在开发的时候,如果仅仅只是按照教程中介绍的去掉 urls.py 中相应的注释,那么你很有可能看到的是一个光秃秃的裸体页面,换句话说,就是页面的样式都失效了。

这是怎么回事?其原因就是 Django 不处理静态文件,其静态文件管理需要通过配置,让服务器直接访问。同时,在开发环境中,如果你是用manage.py runserver 的方式运行调试,更是麻烦。在网上找了很久,始终也没有一个很全面的解决方案。

自动动手,丰衣足食,参考 Django 官网的介绍,终于解决了。废话不多说,解决方案如下:

开发环境(manage.py)

参考 http://docs.djangoproject.com/en/dev/howto/static-files/#serving-static-files-in-development.
网上有很多介绍改这个 MEDIA_ROOT, MEDIA_URL 改那个 STATIC_ROOT, STATIC_URL 的,注意,完全没有必要,开发时,这些都不需要改就可以运行。
MEDIA 是指你上传的文件存放,比如图像,视频,压缩包之类的,而STATIC是你网站运行需要依赖的一些静态文件,比如css, js, template 等等。开发时先不管它们。

  • 首先,复制 C:/Python27/Lib/site-packages/django/contrib/admin/media/ 下的文件,到你网站的 c:/mysite/static/ 下,那么就有了 c:/mysite/static/media/ 目录。
  • 其次,将 /static/media/ 改为 /static/admin/ 。 这个修改是为了符合 ADMIN_MEDIA_PREFIX='/static/admin/',你网站上的admin的静态文件都会渲染成 http://server/{{ADMIN_MEDIA_PREFIX}}/xxx/xxx.css 之类,也就成了 http://server/static/admin/xxx/xxx.css ,这样就能找到正确的服务器静态文件了。同时,也是为了避免 media 和 static 造成混淆了,前面说了,MEDIA 实际上是用来存放上传下载文件的。
  • 然后,打开你网站的 c:/mysite/settings.py ,修改 STATICFILES_DIRS 段
    STATICFILES_DIRS = (
        'c:/mysite/static/',
    )
  • 最好,修改 c:/mysite/urls.py,在 urlpatterns 下面增加一行
    urlpatterns += staticfiles_urlpatterns() 
    别忘了头上加上一句
    from django.contrib.staticfiles.urls import staticfiles_urlpatterns
运行python manage.py runserver,用浏览器访问 http://localhost:8000/admin/ , 看看是不是好了。

部署环境

以后试过了再写。


标签: , , ,