<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>天地一沙鸥 &#187; 编程</title>
	<atom:link href="http://haoluobo.com/category/%e7%bc%96%e7%a8%8b/feed/" rel="self" type="application/rss+xml" />
	<link>http://haoluobo.com</link>
	<description>to be continue....</description>
	<lastBuildDate>Wed, 16 May 2012 13:53:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>迁移到python3</title>
		<link>http://haoluobo.com/2012/04/python3porting/</link>
		<comments>http://haoluobo.com/2012/04/python3porting/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 01:40:55 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://haoluobo.com/?p=10479</guid>
		<description><![CDATA[python3自2008发布以来，已经历经了快4个年头。python3发布初期的速度慢，第三方开发库少的问题已得到了很好的改善。似乎已经没有太多的理由死抱着python2不放了。 考虑到目前的大多系统还都跑在python2.x上，直接迁移到python3还是有些冒进。最理想的方式是新代码都可实现python2&#38;python3的兼容，日后可以平滑升级。下面的一些资料可以帮助你实现到python3的迁移。 Should I use Python 2 or Python 3 for my development activity? Porting to Python 3: An in-depth guide 一本免费的电子书，教你如何迁移到python3 six 一个帮你写出兼容python2&#38;python3代码的第三方库，目前支持到python2.4+。如果你需要支持到比较低版本的python2.x，可以考虑使用。 Python 3 Porting Guide 一个比较简短的迁移指南。]]></description>
			<content:encoded><![CDATA[<p>python3自2008发布以来，已经历经了快4个年头。python3发布初期的速度慢，第三方开发库少的问题已得到了很好的改善。似乎已经没有太多的理由死抱着python2不放了。
考虑到目前的大多系统还都跑在python2.x上，直接迁移到python3还是有些冒进。最理想的方式是新代码都可实现python2&amp;python3的兼容，日后可以平滑升级。下面的一些资料可以帮助你实现到python3的迁移。</p>

<ul>
<li><a href="http://wiki.python.org/moin/Python2orPython3">Should I use Python 2 or Python 3 for my development activity?</a></li>
<li><a href="http://python3porting.com/">Porting to Python 3: An in-depth guide</a> 

<ul>
<li>一本免费的电子书，教你如何迁移到python3</li>
</ul></li>
<li><a href="http://pypi.python.org/pypi/six/">six</a> 

<ul>
<li>一个帮你写出兼容python2&amp;python3代码的第三方库，目前支持到python2.4+。如果你需要支持到比较低版本的python2.x，可以考虑使用。</li>
</ul></li>
<li><a href="http://docs.pythonsprints.com/python3_porting/py-porting.html">Python 3 Porting Guide</a> 

<ul>
<li>一个比较简短的迁移指南。</li>
</ul></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2012/04/python3porting/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>使用反向代理为SAE“绑定”顶级域名</title>
		<link>http://haoluobo.com/2012/03/domain_mod_proxy/</link>
		<comments>http://haoluobo.com/2012/03/domain_mod_proxy/#comments</comments>
		<pubDate>Tue, 06 Mar 2012 13:08:53 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[mod_proxy]]></category>
		<category><![CDATA[SAE]]></category>

		<guid isPermaLink="false">http://haoluobo.com/?p=10429</guid>
		<description><![CDATA[朋友的VPS服务器近期经常出现内存超标的问题。想我的SAE免费资源闲着也是闲着，于是将上面的博客迁移到SAE平台。 SAE商店中的wordpress可以免费安装使用。受SAE平台的限制，SAE版的wordpress有部分功能限制，比如可用的主题也就那么2~3款。另外一个比较大的问题是无法绑定域名。解决该问题的方法之一即是使用反向代理。 我的虚拟主机上用的是apache，下面是相关设置。 httpd.conf LoadModule rewrite_module modules/mod_rewrite.so LoadModule wsgi_module modules/mod_wsgi.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so .htaccess RewriteEngine On RewriteCond %{HTTP_HOST} ^domain.com$ RewriteRule ^(.*)$ http://domain.sinaapp.com/$1 [P]]]></description>
			<content:encoded><![CDATA[<p>朋友的VPS服务器近期经常出现内存超标的问题。想我的SAE免费资源闲着也是闲着，于是将上面的博客迁移到SAE平台。<br />
SAE商店中的wordpress可以免费安装使用。受SAE平台的限制，SAE版的wordpress有部分功能限制，比如可用的主题也就那么2~3款。另外一个比较大的问题是无法绑定域名。解决该问题的方法之一即是使用反向代理。<br />
我的虚拟主机上用的是apache，下面是相关设置。</p>
<p><strong>httpd.conf</strong></p>
<pre>LoadModule rewrite_module modules/mod_rewrite.so
LoadModule wsgi_module modules/mod_wsgi.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so</pre>
<p><strong>.htaccess</strong></p>
<pre>RewriteEngine On
RewriteCond %{HTTP_HOST} ^domain.com$
RewriteRule ^(.*)$ http://domain.sinaapp.com/$1 [P]</pre>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2012/03/domain_mod_proxy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SAE部署Django1.3应用问题总汇</title>
		<link>http://haoluobo.com/2012/02/sae-django1-3/</link>
		<comments>http://haoluobo.com/2012/02/sae-django1-3/#comments</comments>
		<pubDate>Tue, 28 Feb 2012 12:13:03 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[jstnote]]></category>
		<category><![CDATA[SAE]]></category>

		<guid isPermaLink="false">http://haoluobo.com/?p=10421</guid>
		<description><![CDATA[花了些工夫将碎片网部署到了SAE，中途遇到各类问题。感觉SAE看上去很美，实际上却并不是太成熟（至少python版如此）。 下面记录下我遇到的一些主要问题以及解决方法。 django版本问题 Django1.4都即将发布了，SAE平台自带的SAE版本依旧为1.2x。为使用django1.3版本，你需上传自己的django。具体做法可参考SAE手册中的runtime.html#virtualenv 日志模块出错 最先遇到的是日至模块的问题。错误显示AdminEmailHandler中构造某个类时带了is_mail这个参数，但目标类的构造函数根本就不支持。好在日至模块不是必须。将日至处理模块换成django.utils.log.NullHandler解决问题。 'null’: { 'level’:'DEBUG’, 'class’:'django.utils.log.NullHandler’, }, local_thread问题 在index.wsgi中加入 import threading from django.utils import _threading_local threading.local = _threading_local.local settings文件 SAE默认安装了不少python包，其中包括django-userena。糟糕的是SAE将django-userena的demo项目也加到了python路径，而且加载的优先级比项目代码还高。直接导致os.environ['DJANGO_SETTINGS_MODULE'] = &#8216;settings&#8217;找到的是userena的settings文件。最终将settings文件改名为qnotes_settings.py解决该问题。 其他问题 昨天部署上线后经常出现数据库错误，错误提示为Caught OperationalError while rendering: (1045, &#8216;access deny&#8217;)  。SAE数据库不支持长连接，30s后主动超时。但django本就会在每次请求后自动关闭数据库连接，理论上不应当出现类似问题。该问题今天莫名其妙的自己好了。 服务器非常不稳定，经常长时间的无法访问，不定期的可以正常访问。 SAE可能hack了python的包加载机制的原因，SAE的python包的加载行为有些奇怪。本应当最先加载当前目录下的包，实际上却不一定。]]></description>
			<content:encoded><![CDATA[<p>花了些工夫将<a href="http://qnotes.sinaapp.com">碎片网</a>部署到了SAE，中途遇到各类问题。感觉SAE看上去很美，实际上却并不是太成熟（至少python版如此）。<br />
下面记录下我遇到的一些主要问题以及解决方法。</p>
<h3>django版本问题</h3>
<p>Django1.4都即将发布了，SAE平台自带的SAE版本依旧为1.2x。为使用django1.3版本，你需上传自己的django。具体做法可参考SAE手册中的<a href="http://appstack.sinaapp.com/static/doc/release/testing/runtime.html#virtualenv">runtime.html#virtualenv</a></p>
<h3>日志模块出错</h3>
<p>最先遇到的是日至模块的问题。错误显示<strong>AdminEmailHandler</strong>中构造某个类时带了is_mail这个参数，但目标类的构造函数根本就不支持。好在日至模块不是必须。将日至处理模块换成<strong>django.utils.log.NullHandler</strong>解决问题。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #483d8b;">'null’: { '</span>level’:<span style="color: #483d8b;">'DEBUG’, '</span><span style="color: #ff7700;font-weight:bold;">class</span>’:<span style="color: #483d8b;">'django.utils.log.NullHandler’, },</span></pre></div></div>

<h3>local_thread问题</h3>
<p>在index.wsgi中加入</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">threading</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">utils</span> <span style="color: #ff7700;font-weight:bold;">import</span> _threading_local
<span style="color: #dc143c;">threading</span>.<span style="color: black;">local</span> = _threading_local.<span style="color: black;">local</span></pre></div></div>

<h3>settings文件</h3>
<p>SAE默认安装了不少python包，其中包括django-userena。糟糕的是SAE将django-userena的demo项目也加到了python路径，而且加载的优先级比项目代码还高。直接导致<strong>os.environ['DJANGO_SETTINGS_MODULE'] = &#8216;settings&#8217;</strong>找到的是userena的settings文件。最终将settings文件改名为<strong>qnotes_settings.py</strong>解决该问题。</p>
<h3>其他问题</h3>
<ul>
<li>昨天部署上线后经常出现数据库错误，错误提示为Caught OperationalError while rendering: (1045, &#8216;access deny&#8217;)  。SAE数据库不支持长连接，30s后主动超时。但django本就会在每次请求后自动关闭数据库连接，理论上不应当出现类似问题。该问题今天莫名其妙的自己好了。</li>
<li>服务器非常不稳定，经常长时间的无法访问，不定期的可以正常访问。</li>
<li>SAE可能hack了python的包加载机制的原因，SAE的python包的加载行为有些奇怪。本应当最先加载当前目录下的包，实际上却不一定。</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2012/02/sae-django1-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>使用nginx做pypi的反向代理，搭建pypi官方镜像</title>
		<link>http://haoluobo.com/2012/02/nginxpypi/</link>
		<comments>http://haoluobo.com/2012/02/nginxpypi/#comments</comments>
		<pubDate>Tue, 14 Feb 2012 07:06:23 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[pypi]]></category>

		<guid isPermaLink="false">http://haoluobo.com/?p=10369</guid>
		<description><![CDATA[受国内的网络环境限制，直接使用python官方的pypi源速度不稳定还经常抽风。对公司来说，搭建一个自己的pypi镜像非常有必要。 搭建pypi镜像的目的以及相关方案 方案 优点 缺点 PyPiImplementations 功能强大，提供用户注册、包管理等各项功能。 配置复杂，需对pypi源进行全量同步。全量同步速度慢，且经常失败。 PyPiImplementations Simple repository with fallback using Apache 配置相对简单。可通过ftp等方式实现私有包的管理。增加反向代理缓存后可实现官方pypi源的加速。 部分python包只是在pypi上放了一个链接，真正的包放在自己的服务器上（极少数包），对这类包无法通过反向代理进行加速。 权限管理功能稍弱。 私有包需要通过ftp等方式进行管理。 注：私有包管理的问题可通过安装web版的文件管理工具来规避。 考虑到部门内部pypi镜像的需求简单，不需涉及太多权限功能方面的工作，建议使用“Simple repository with fallback using Apache”方案。 反向代理方案 “Simple repository with fallback using Apache”中只是将本地无法处理的pypi请求直接转发到官方pypi源。在对官方源进行同步时无法实现对官方pypi源进行加速。为解决该问题，需要对官网的请求进行反向代理并缓存。 关于反向代理的支持请参考：代理、反向代理知识普及squid apache-mod_proxy lighttpd nginx squid是老牌的反向代理服务器，但在实际使用过程中发现squid太过强大的功能导致配置复杂，不推荐使用。 nginx发展迅速的新兴服务器，对反向代理提供良好的支持，并被多家大型网站使用。最重要的是nginx的配置比squid要容易太多。 nginx配置要点 参考： 使用nginx的proxy_cache缓存功能取代squid nginx ChsHttpProxyModule nginx的文档化做的不是太好，在配置中有些要点需要注意。 安装 官方安装文档 ubuntu官方源版本比较老，建议添加ppa源再安装。 按照说明添加ppa源不可用时，可查看 /etc/apt/sources.list.d 中的nginx ppa源配置并修正 nginx配置 nginx默认启用了gzip支持。pip无法识别gzip后的网页，需要关闭gzip支持。 proxy_cache_path <a href="http://haoluobo.com/2012/02/nginxpypi/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>受国内的网络环境限制，直接使用python官方的pypi源速度不稳定还经常抽风。对公司来说，搭建一个自己的pypi镜像非常有必要。</p>
<h4>搭建pypi镜像的目的以及相关方案</h4>
<table>
<tbody>
<tr>
<th>方案</th>
<th>优点</th>
<th>缺点</th>
</tr>
<tr>
<td><a href="http://wiki.python.org/moin/PyPiImplementations">PyPiImplementations</a></td>
<td>功能强大，提供用户注册、包管理等各项功能。</td>
<td>配置复杂，需对pypi源进行全量同步。全量同步速度慢，且经常失败。</td>
</tr>
<tr>
<td><a href="http://wiki.python.org/moin/PyPiImplementations">PyPiImplementations</a><br />
Simple repository with fallback using Apache</td>
<td>配置相对简单。可通过ftp等方式实现私有包的管理。增加反向代理缓存后可实现官方pypi源的加速。</td>
<td>部分python包只是在pypi上放了一个链接，真正的包放在自己的服务器上（极少数包），对这类包无法通过反向代理进行加速。<br />
权限管理功能稍弱。<br />
私有包需要通过ftp等方式进行管理。<br />
注：私有包管理的问题可通过安装web版的文件管理工具来规避。</td>
</tr>
</tbody>
</table>
<p>考虑到部门内部pypi镜像的需求简单，不需涉及太多权限功能方面的工作，建议使用“Simple repository with fallback using Apache”方案。</p>
<h4>反向代理方案</h4>
<p>“Simple repository with fallback using Apache”中只是将本地无法处理的pypi请求直接转发到官方pypi源。在对官方源进行同步时无法实现对官方pypi源进行加速。为解决该问题，需要对官网的请求进行反向代理并缓存。<br />
关于反向代理的支持请参考：<a href="http://sealbird.iteye.com/blog/1320559">代理、反向代理知识普及squid apache-mod_proxy lighttpd nginx</a><br />
squid是老牌的反向代理服务器，但在实际使用过程中发现squid太过强大的功能导致配置复杂，不推荐使用。<br />
nginx发展迅速的新兴服务器，对反向代理提供良好的支持，并被多家大型网站使用。最重要的是nginx的配置比squid要容易太多。</p>
<h4>nginx配置要点</h4>
<ul>
<li>参考：</li>
<ul>
<li><a href="http://blog.163.com/insync@126/blog/static/109669852201010160433175/">使用nginx的proxy_cache缓存功能取代squid</a></li>
<li><a href="http://wiki.nginx.org/ChsHttpProxyModule">nginx ChsHttpProxyModule</a> nginx的文档化做的不是太好，在配置中有些要点需要注意。</li>
</ul>
<li>安装</li>
<ul>
<li><a href="http://wiki.nginx.org/Install">官方安装文档</a> ubuntu官方源版本比较老，建议添加ppa源再安装。</li>
<li>按照说明添加ppa源不可用时，可查看 /etc/apt/sources.list.d 中的nginx ppa源配置并修正</li>
</ul>
<li>nginx配置</li>
<ul>
<li>nginx默认启用了gzip支持。pip无法识别gzip后的网页，需要关闭gzip支持。</li>
</ul>
</ul>

<div class="wp_syntax"><div class="code"><pre class="perl" style="font-family:monospace;">proxy_cache_path  <span style="color: #339933;">/</span>var<span style="color: #339933;">/</span>lib<span style="color: #339933;">/</span>nginx<span style="color: #339933;">/</span>cache<span style="color: #339933;">/</span> levels<span style="color: #339933;">=</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">:</span><span style="color: #cc66cc;">2</span> inactive<span style="color: #339933;">=</span>24000h keys_zone<span style="color: #339933;">=</span>cache<span style="color: #339933;">:</span>100m<span style="color: #339933;">;</span>
&nbsp;
server <span style="color: #009900;">&#123;</span>
        <span style="color: #000066;">listen</span>   <span style="color: #cc66cc;">8000</span> default<span style="color: #339933;">;</span>
        server_name  localhost<span style="color: #339933;">;</span>
&nbsp;
        access_log  <span style="color: #339933;">/</span>var<span style="color: #339933;">/</span><span style="color: #000066;">log</span><span style="color: #339933;">/</span>nginx<span style="color: #339933;">/</span>localhost<span style="color: #339933;">.</span>access<span style="color: #339933;">.</span><span style="color: #000066;">log</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">#中间省略部分默认配置</span>
&nbsp;
        location <span style="color: #339933;">/</span>pypi <span style="color: #009900;">&#123;</span>
                proxy_pass http<span style="color: #339933;">://</span>pypi<span style="color: #339933;">.</span>python<span style="color: #339933;">.</span>org<span style="color: #339933;">/</span>simple<span style="color: #339933;">;</span>
        proxy_cache cache<span style="color: #339933;">;</span>
        proxy_cache_valid  any 2400h<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        location <span style="color: #339933;">/</span>packages <span style="color: #009900;">&#123;</span>
                proxy_pass http<span style="color: #339933;">://</span>pypi<span style="color: #339933;">.</span>python<span style="color: #339933;">.</span>org<span style="color: #339933;">/</span>packages<span style="color: #339933;">;</span>
        proxy_cache cache<span style="color: #339933;">;</span>
        proxy_cache_valid  any 24000h<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<h4>相关链接</h4>
<ul>
<li><a href="http://www.worldhello.net/2011/03/14/2357.html">搭建本地pypi服务器</a></li>
<li><a href="http://wiki.python.org/moin/PyPiImplementations">PyPiImplementations</a></li>
<li><a href="http://sealbird.iteye.com/blog/1320559">代理、反向代理知识普及squid apache-mod_proxy lighttpd nginx</a></li>
<li><a href="http://blog.163.com/insync@126/blog/static/109669852201010160433175/">使用nginx的proxy_cache缓存功能取代squid</a></li>
<li><a href="http://wiki.nginx.org/ChsHttpProxyModule">nginx ChsHttpProxyModule</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2012/02/nginxpypi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>timeline项目开发日志&#8211;登陆、注册模块</title>
		<link>http://haoluobo.com/2012/01/timeline-re/</link>
		<comments>http://haoluobo.com/2012/01/timeline-re/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 14:35:34 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[vicalloy的庄家]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[django-userena]]></category>
		<category><![CDATA[timeline]]></category>

		<guid isPermaLink="false">http://haoluobo.com/?p=10353</guid>
		<description><![CDATA[利用twitter/bootstrap，项目的基础模板算是顺利搞定。接下来开始处理用户中心。 用户中心主要包括用户登陆、注册以及头像等个人信息维护。此前，用户的注册管理我一直使用django-registration。只是这个APP有些不思进取，09年发布了0.8alpha版后就一直没什么动静。这次决定尝试另外一个用户模块组件django-userena。 相比django-registration，django-userena的功能要完善的多。除基础的登陆注册模块外django-userena甚至还带了站内消息功能。django-userena的易用性方面也做的非常的不错。django-userena自带了默认模板，并有提供一个完整的演示项目，让你可以轻松上手。这里有个官方的在线demo，感兴趣可以去看看。 django-userena同twitter/bootstrap的整合 我们自然是希望所有的APP不用做任何修改，拿来就能用了。不过事与愿违，在整合的过程中多多少少都会遇到一些问题。django-userena默认的模板在项目中显示的非常难看。我们需要重写django-userena的默认模板，并且用django-bootstrap来生成form。 forms.py #为原始form添加BootstrapMixin from bootstrap.forms import BootstrapMixin &#160; class BsAuthenticationForm&#40;AuthenticationForm, BootstrapMixin&#41;: def __init__&#40;self, *args, **kw&#41;: super&#40;BsAuthenticationForm, self&#41;.__init__&#40;*args, **kw&#41; self.__bootstrap__&#40;&#41; urls.py #重写urls，指定使用的form from django.conf.urls.defaults import * from userena import views as userena_views from profiles.forms import BsSignupForm, BsAuthenticationForm &#160; urlpatterns = patterns&#40;'', url&#40;r'^signup/$', userena_views.signup, &#123;'signup_form': BsSignupForm&#125;, name='userena_signup'&#41;, url&#40;r'^signin/$', userena_views.signin, &#123;'auth_form': BsAuthenticationForm&#125;, name='userena_signin'&#41;, &#40;r'^', <a href="http://haoluobo.com/2012/01/timeline-re/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>利用<a href="https://github.com/twitter/bootstrap" target="_blank">twitter/bootstrap</a>，项目的基础模板算是顺利搞定。接下来开始处理用户中心。</p>
<p>用户中心主要包括用户登陆、注册以及头像等个人信息维护。此前，用户的注册管理我一直使用<a href="https://bitbucket.org/ubernostrum/django-registration" target="_blank">django-registration</a>。只是这个APP有些不思进取，09年发布了0.8alpha版后就一直没什么动静。这次决定尝试另外一个用户模块组件<a href="https://github.com/bread-and-pepper/django-userena" target="_blank">django-userena</a>。</p>
<p>相比django-registration，django-userena的功能要完善的多。除基础的登陆注册模块外django-userena甚至还带了站内消息功能。django-userena的易用性方面也做的非常的不错。django-userena自带了默认模板，并有提供一个完整的演示项目，让你可以轻松上手。这里有个官方的在线demo，感兴趣可以<a href="http://django-userena.org/accounts/signup/" target="_blank">去看看</a>。</p>
<h3>django-userena同twitter/bootstrap的整合</h3>
<p>我们自然是希望所有的APP不用做任何修改，拿来就能用了。不过事与愿违，在整合的过程中多多少少都会遇到一些问题。django-userena默认的模板在项目中显示的非常难看。我们需要重写django-userena的默认模板，并且用<a href="https://github.com/earle/django-bootstrap" target="_blank">django-bootstrap</a>来生成form。</p>
<p><strong>forms.py</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#为原始form添加BootstrapMixin</span>
<span style="color: #ff7700;font-weight:bold;">from</span> bootstrap.<span style="color: black;">forms</span> <span style="color: #ff7700;font-weight:bold;">import</span> BootstrapMixin
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> BsAuthenticationForm<span style="color: black;">&#40;</span>AuthenticationForm, BootstrapMixin<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>BsAuthenticationForm, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.__bootstrap__<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p><strong>urls.py</strong></p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#重写urls，指定使用的form</span>
<span style="color: #ff7700;font-weight:bold;">from</span> django.<span style="color: black;">conf</span>.<span style="color: black;">urls</span>.<span style="color: black;">defaults</span> <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">from</span> userena <span style="color: #ff7700;font-weight:bold;">import</span> views <span style="color: #ff7700;font-weight:bold;">as</span> userena_views
<span style="color: #ff7700;font-weight:bold;">from</span> profiles.<span style="color: black;">forms</span> <span style="color: #ff7700;font-weight:bold;">import</span> BsSignupForm, BsAuthenticationForm
&nbsp;
urlpatterns = patterns<span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span>,
    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^signup/$'</span>, userena_views.<span style="color: black;">signup</span>,
        <span style="color: black;">&#123;</span><span style="color: #483d8b;">'signup_form'</span>: BsSignupForm<span style="color: black;">&#125;</span>, name=<span style="color: #483d8b;">'userena_signup'</span><span style="color: black;">&#41;</span>,
    url<span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^signin/$'</span>, userena_views.<span style="color: black;">signin</span>,
        <span style="color: black;">&#123;</span><span style="color: #483d8b;">'auth_form'</span>: BsAuthenticationForm<span style="color: black;">&#125;</span>, name=<span style="color: #483d8b;">'userena_signin'</span><span style="color: black;">&#41;</span>,
    <span style="color: black;">&#40;</span>r<span style="color: #483d8b;">'^'</span>, include<span style="color: black;">&#40;</span><span style="color: #483d8b;">'userena.urls'</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>,
<span style="color: black;">&#41;</span></pre></div></div>

<h3>中文用户名问题</h3>
<p>同django-admin一样，django-userena也无法使用中文进行注册。对于一个中文网站而言，不能使用中文注册ID似乎有些太不合理的。</p>
<p>django-userena使用正则表达式对用户名进行校验，重写注册form修改认证规则即可取消该限制。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">USERNAME_RE = r<span style="color: #483d8b;">'^<span style="color: #000099; font-weight: bold;">\S</span>+$'</span>
attrs_dict = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'class'</span>: <span style="color: #483d8b;">'required'</span><span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> BsSignupForm<span style="color: black;">&#40;</span>SignupForm, BootstrapMixin<span style="color: black;">&#41;</span>:
    username = forms.<span style="color: black;">RegexField</span><span style="color: black;">&#40;</span>regex=USERNAME_RE,
                                max_length=<span style="color: #ff4500;">30</span>,
                                widget=forms.<span style="color: black;">TextInput</span><span style="color: black;">&#40;</span>attrs=attrs_dict<span style="color: black;">&#41;</span>,
                                label=_<span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;Username&quot;</span><span style="color: black;">&#41;</span>,
                                error_messages=<span style="color: black;">&#123;</span><span style="color: #483d8b;">'invalid'</span>: _<span style="color: black;">&#40;</span><span style="color: #483d8b;">'Username must contain only letters, numbers, dots and underscores.'</span><span style="color: black;">&#41;</span><span style="color: black;">&#125;</span><span style="color: black;">&#41;</span>
&nbsp;
    <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, <span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>:
        <span style="color: #008000;">super</span><span style="color: black;">&#40;</span>BsSignupForm, <span style="color: #008000;">self</span><span style="color: black;">&#41;</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #66cc66;">*</span>args, <span style="color: #66cc66;">**</span>kw<span style="color: black;">&#41;</span>
        <span style="color: #008000;">self</span>.__bootstrap__<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2012/01/timeline-re/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django数据库迁移组件（South）</title>
		<link>http://haoluobo.com/2011/12/django-south/</link>
		<comments>http://haoluobo.com/2011/12/django-south/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 15:52:39 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[south]]></category>

		<guid isPermaLink="false">http://haoluobo.com/?p=10295</guid>
		<description><![CDATA[django提供syncdb命令，用于从models自动生成数据库。但在models结构变化后，syncdb并无法自动实现数据库的更新。South组件即是为了解决该问题而出现的。 下面简单介绍一下South的一些最常见用法，更详细的使用方法见South的官方手册。 假设我们创建了一个名叫southtut的app 生成初始化数据库的south脚本。允许上述命令后将在对于的app目录下生成 migrations目录，south的数据库迁移脚本即保存在该目录。 ./manage.py schemamigration southtut --initial 在所用south后，syncdb命令不会为使用south托管的app生成数据库。migrate命令用于执行south的数据库迁移脚本， 实现数据库更改。在这里执行的操作是为southtut创建相关的数据库表。不带app名字时，将对project中的所有app进行migrate操 作。 ./manage.py migrate southtut 在很多应用场景中，我们已经用syncdb将数据库给创建好了。这时候运行上面的migrate命令将会提示相关表已经存在，命令执行失败。这 时候我们需要告诉south需要跳过某些migrate操作。上面的命令将告诉south，系统已经执行过了0001号数据库迁移脚本。 ./manage.py migrate southtut 0001 --fake 接下来我们对models进行了某些改动，修改后增减了某些字段。 该命令将自动生成数据库的迁移脚本。在migrations目录下可以看到新增加了文件0002_xxx.py，该文件即是此次models改 动的数据库升级脚本。打开文件后可看到其中有一个类Migration，类中有两个方法forwards和backwards。这两个方法分别实现数据库 升级和会滚时对数据库的操作，具体指令的含义参考south的数据库API。 ./manage.py schemamigration southtut --auto 应用models的改动到数据库 ./manage.py migrate southtut]]></description>
			<content:encoded><![CDATA[<p>django提供syncdb命令，用于从models自动生成数据库。但在models结构变化后，syncdb并无法自动实现数据库的更新。<a href="http://south.aeracode.org/" rel="nofollow">South<sup><img src="http://iot-kb.insigma.com.cn/images/icons/linkext7.gif" alt="" width="7" height="7" align="absmiddle" border="0" /></sup></a>组件即是为了解决该问题而出现的。<br />
下面简单介绍一下South的一些最常见用法，更详细的使用方法见South的官方手册。</p>
<p>假设我们创建了一个名叫southtut的app</p>
<ol>
<li>生成初始化数据库的south脚本。允许上述命令后将在对于的app目录下生成 <strong>migrations</strong>目录，south的数据库迁移脚本即保存在该目录。
<div>
<div>
<div>
<div id="highlighter_715347">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div title="Hint: double-click to select code">
<div><code>./manage.py schemamigration southtut --initial</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
<li>在所用south后，syncdb命令不会为使用south托管的app生成数据库。migrate命令用于执行south的数据库迁移脚本， 实现数据库更改。在这里执行的操作是为southtut创建相关的数据库表。不带app名字时，将对project中的所有app进行migrate操 作。
<div>
<div>
<div>
<div id="highlighter_169492">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div title="Hint: double-click to select code">
<div><code>./manage.py migrate southtut</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
<li>在很多应用场景中，我们已经用syncdb将数据库给创建好了。这时候运行上面的migrate命令将会提示相关表已经存在，命令执行失败。这 时候我们需要告诉south需要跳过某些migrate操作。上面的命令将告诉south，系统已经执行过了0001号数据库迁移脚本。
<div>
<div>
<div>
<div id="highlighter_881531">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div title="Hint: double-click to select code">
<div><code>./manage.py migrate southtut </code><code>0001</code> <code>--fake</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
<li>接下来我们对models进行了某些改动，修改后增减了某些字段。</li>
<li>该命令将自动生成数据库的迁移脚本。在migrations目录下可以看到新增加了文件0002_xxx.py，该文件即是此次models改 动的数据库升级脚本。打开文件后可看到其中有一个类Migration，类中有两个方法forwards和backwards。这两个方法分别实现数据库 升级和会滚时对数据库的操作，具体指令的含义参考south的数据库<a href="http://south.aeracode.org/docs/databaseapi.html" rel="nofollow">API<sup><img src="http://iot-kb.insigma.com.cn/images/icons/linkext7.gif" alt="" width="7" height="7" align="absmiddle" border="0" /></sup></a>。
<div>
<div>
<div>
<div id="highlighter_6912">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div title="Hint: double-click to select code">
<div><code>./manage.py schemamigration southtut --auto</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
<li>应用models的改动到数据库
<div>
<div>
<div>
<div id="highlighter_589483">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div title="Hint: double-click to select code">
<div><code>./manage.py migrate southtut</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/12/django-south/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>合理的组织django的settings文件</title>
		<link>http://haoluobo.com/2011/10/django-settings/</link>
		<comments>http://haoluobo.com/2011/10/django-settings/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 04:26:46 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[dj-scaffold]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://haoluobo.com/?p=10232</guid>
		<description><![CDATA[django在一个项目的目录结构划分方面缺乏必要的规范，因此不同人的项目组织形式也千奇百怪，而且也很难说谁的做法就比较好。我根据自己的项目组织习惯，发布了一个项目dj-scaffold。 前些天在reddit上为我的项目dj-scaffold打了个“广告”（见：http://redd.it/kw5d4）。不想评价甚糟，甚至差点被打成负分。其中更也人将这个项目说的一文不值。面对负面声音虽然会有些不爽，但其中的建设性意见还是需要听取的，至于那些纯属个人偏好部分就自动过滤了。 在谈及settings文件如何组织时，coderanger建议参考The Best (and Worst) of Django中的做法。文中的主要观点是开发环境和生产环境的配置都需要放到VCS中进行版本控制。参考文中的做法，我对settings模块做了部分调整。注：代码 https://github.com/vicalloy/dj-scaffold/tree/master/dj_scaffold/conf/prj/sites/settings local_settings的弊病 为将项目的默认配置和本地配置区分开，最常用的做法是增加一个local_settings.py文件，并在settings文件的最后对该文件进行import。 try: from local_settings import * except: pass 由此引发的问题是你不能对local_settings.py进行版本控制，部署环境的配置万一丢失将难以找回。 解决方案 针对该问题，建议的解决方案如下 合理的配置文件组织方式 &#124;~settings/ &#124; &#124;-__init__.py &#124; &#124;-base.py #默认配置信息 &#124; &#124;-dev.py #开发环境的配置 &#124; &#124;-local.sample #本地的扩展配置在dev和production的最后进行import &#124; &#124;-pre.sample #设置当前使用的配置为生产环境还是开发环境 &#124; `-production.py #生产环境的配置 使用方式 DJANGO_SETTINGS_MODULE django的admin脚本提供了settings参数用于指定当前使用的配置文件 django-admin.py shell --settings=settings.dev 在wsgi脚本中则可直接设置需要使用的settings deploy.wsgi os.environ['DJANGO_SETTINGS_MODULE'] = settings.production 简化参数 当然，如果每次使用django-admin.py的时候都要带上settings参数还是非常恼人，所以推荐的做法是在pre.py中配置自己所需要使用的配置文件。 SETTINGS = <a href="http://haoluobo.com/2011/10/django-settings/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>django在一个项目的目录结构划分方面缺乏必要的规范，因此不同人的项目组织形式也千奇百怪，而且也很难说谁的做法就比较好。我根据自己的项目组织习惯，发布了一个项目<a href="https://github.com/vicalloy/dj-scaffold/">dj-scaffold</a>。</p>
<p>前些天在<a href="http://www.reddit.com/r/django/">reddit</a>上为我的项目<a href="https://github.com/vicalloy/dj-scaffold/">dj-scaffold</a>打了个“广告”（见：<a href="http://redd.it/kw5d4">http://redd.it/kw5d4</a>）。不想评价甚糟，甚至差点被打成负分。其中更也人将这个项目说的一文不值。面对负面声音虽然会有些不爽，但其中的建设性意见还是需要听取的，至于那些纯属个人偏好部分就自动过滤了。</p>
<p>在谈及settings文件如何组织时，coderanger建议参考<a href="http://www.slideshare.net/jacobian/the-best-and-worst-of-django/51">The Best (and Worst) of Django</a>中的做法。文中的主要观点是开发环境和生产环境的配置都需要放到VCS中进行版本控制。参考文中的做法，我对settings模块做了部分调整。<strong>注：</strong>代码 <a href="https://github.com/vicalloy/dj-scaffold/tree/master/dj_scaffold/conf/prj/sites/settings">https://github.com/vicalloy/dj-scaffold/tree/master/dj_scaffold/conf/prj/sites/settings</a></p>
<h3>local_settings的弊病</h3>
<p>为将项目的默认配置和本地配置区分开，最常用的做法是增加一个local_settings.py文件，并在settings文件的最后对该文件进行import。</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">try</span>:
    <span style="color: #ff7700;font-weight:bold;">from</span> local_settings <span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #66cc66;">*</span>
<span style="color: #ff7700;font-weight:bold;">except</span>:
    <span style="color: #ff7700;font-weight:bold;">pass</span></pre></div></div>

<p>由此引发的问题是你不能对local_settings.py进行版本控制，部署环境的配置万一丢失将难以找回。</p>
<h3>解决方案</h3>
<p>针对该问题，建议的解决方案如下</p>
<h4>合理的配置文件组织方式</h4>
<pre>|~settings/
| |-__init__.py
| |-base.py   #默认配置信息
| |-dev.py    #开发环境的配置
| |-local.sample    #本地的扩展配置在dev和production的最后进行import
| |-pre.sample    #设置当前使用的配置为生产环境还是开发环境
| `-production.py    #生产环境的配置</pre>
<h4>使用方式</h4>
<pre><strong>DJANGO_SETTINGS_MODULE</strong></pre>
<p>django的admin脚本提供了settings参数用于指定当前使用的配置文件</p>
<pre>django-admin.py shell --settings=settings.dev</pre>
<p>在wsgi脚本中则可直接设置需要使用的settings</p>
<pre>deploy.wsgi
os.environ['DJANGO_SETTINGS_MODULE'] = settings.production</pre>
<p><strong>简化参数</strong></p>
<p>当然，如果每次使用django-admin.py的时候都要带上settings参数还是非常恼人，所以推荐的做法是在pre.py中配置自己所需要使用的配置文件。</p>
<pre>SETTINGS = 'production' #dev</pre>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/10/django-settings/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Gliffy confluence插件的破解</title>
		<link>http://haoluobo.com/2011/09/gliffy-confluence-creak/</link>
		<comments>http://haoluobo.com/2011/09/gliffy-confluence-creak/#comments</comments>
		<pubDate>Wed, 21 Sep 2011 13:13:13 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[confluence]]></category>
		<category><![CDATA[Gliffy]]></category>

		<guid isPermaLink="false">http://haoluobo.com/2011/09/gliffy-confluence%e6%8f%92%e4%bb%b6%e7%9a%84%e7%a0%b4%e8%a7%a3/</guid>
		<description><![CDATA[Gliffy是一个在线画流程图的工具，或者简单的说Gliffy就是web版的Visio。Gliffy的用户体验非常的好，加打开浏览器就可以使用，使用起来非常的方便。Gliffy同时推出了confluence的插件版本。在安装插件后可在confluence中方便的编辑和插入流程图。 同事对Gliffy甚为垂涎，只是Gliffy还有些小贵。confluence插件版，500用户的许可要卖到2000$。 虽然同事的利诱有些不靠谱，但偶尔干干着方面的事也还算有趣，那就动手吧。 注：下面只是简单的讲解一些关键点，如果你对java一窍不通，那还是罢手吧。 java应用破解的通常做法是：将文件反编译，找到认证部分的处理，直接将认证结果返回true。java的反编译工具推荐Java Decompiler。 Gliffy的jar包比较大，但其中java代码并不是很多。而且Gliffy采用的是仿君子不防小人的做法，里面的java代码并未混淆过。在代码中有个目录非常的扎眼\src\com\gliffy\core\license\。再做些简单的分析我们即可找到真正的关键点SimpleLicenseManager.java。 不得不说Gliffy的命名还是非常规范的。以函数名为线索，很容易就可以找到我们要的函数validLicenseValues。简单粗暴的将函数返回值改为true。打包并重新安装插件。 如果问题就这么解决了，那也未免顺利的有些不太寻常。虽然可以成功安装，但运行的时候抛出一堆的异常。试着进入Gliffy的管理界面，依旧是一堆的异常。虽然我们强制的将认证结果设置为了true，但某些地方还需要获取license的到期日期等信息。由于读不到相关数据，直接出异常了。 既然如此，那我们需要先将license信息写入系统。 把validLicenseValues还原，然后找到设置license的函数installLicense。在函数中注释掉license认证相关的代码，让系统在忽略认证结果的情况下强行写入注册信息。修改后的java文件在执行时还会报getHostedStatus的虚函数错误。按理说这个函数应当会在子类中被重写。不过我们先不管这么多，把它修改为普通函数并直接返回0。 重新打包安装，然后进入Gliffy的管理界面，license信息随便填写，然后保存。保存是成功的，但认证还是失败。修改validLicenseValues函数，重新打包安装。这次由于我们有写入注册信息，因此就不会再出现先前的空指针异常了。 享受Gliffy吧。 注：Gliffy确实是个好东西，如果喜欢，还是尽量说服公司出钱买吧。]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.gliffy.com/" target="_blank">Gliffy</a>是一个在线画流程图的工具，或者简单的说Gliffy就是web版的Visio。Gliffy的用户体验非常的好，加打开浏览器就可以使用，使用起来非常的方便。Gliffy同时推出了confluence的插件版本。在安装插件后可在confluence中方便的编辑和插入流程图。</p>
<p>同事对Gliffy甚为垂涎，只是Gliffy还有些小贵。confluence插件版，500用户的许可要卖到2000$。</p>
<p>虽然同事的利诱有些不靠谱，但偶尔干干着方面的事也还算有趣，那就动手吧。</p>
<p><strong>注：</strong>下面只是简单的讲解一些关键点，如果你对java一窍不通，那还是罢手吧。</p>
<p>java应用破解的通常做法是：将文件反编译，找到认证部分的处理，直接将认证结果返回true。java的反编译工具推荐<a href="http://java.decompiler.free.fr/" target="_blank">Java Decompiler</a>。</p>
<p>Gliffy的jar包比较大，但其中java代码并不是很多。而且Gliffy采用的是仿君子不防小人的做法，里面的java代码并未混淆过。在代码中有个目录非常的扎眼<strong>\src\com\gliffy\core\license\</strong>。再做些简单的分析我们即可找到真正的关键点<strong>SimpleLicenseManager.java</strong>。</p>
<p>不得不说Gliffy的命名还是非常规范的。以函数名为线索，很容易就可以找到我们要的函数<strong>validLicenseValues</strong>。简单粗暴的将函数返回值改为true。打包并重新安装插件。</p>
<p>如果问题就这么解决了，那也未免顺利的有些不太寻常。虽然可以成功安装，但运行的时候抛出一堆的异常。试着进入Gliffy的管理界面，依旧是一堆的异常。虽然我们强制的将认证结果设置为了true，但某些地方还需要获取license的到期日期等信息。由于读不到相关数据，直接出异常了。</p>
<p>既然如此，那我们需要先将license信息写入系统。</p>
<p>把<strong>validLicenseValues</strong>还原，然后找到设置license的函数<strong>installLicense</strong>。在函数中注释掉license认证相关的代码，让系统在忽略认证结果的情况下强行写入注册信息。修改后的java文件在执行时还会报<strong>getHostedStatus</strong>的虚函数错误。按理说这个函数应当会在子类中被重写。不过我们先不管这么多，把它修改为普通函数并直接返回0。</p>
<p>重新打包安装，然后进入Gliffy的管理界面，license信息随便填写，然后保存。保存是成功的，但认证还是失败。修改<strong>validLicenseValues</strong>函数，重新打包安装。这次由于我们有写入注册信息，因此就不会再出现先前的空指针异常了。</p>
<p>享受Gliffy吧。</p>
<p>注：Gliffy确实是个好东西，如果喜欢，还是尽量说服公司出钱买吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/09/gliffy-confluence-creak/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Django标准化项目dj-scaffold</title>
		<link>http://haoluobo.com/2011/08/dj-scaffold/</link>
		<comments>http://haoluobo.com/2011/08/dj-scaffold/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 15:38:39 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[vicalloy的庄家]]></category>
		<category><![CDATA[编程]]></category>
		<category><![CDATA[dj-scaffold]]></category>
		<category><![CDATA[django]]></category>

		<guid isPermaLink="false">http://haoluobo.com/2011/08/django%e6%a0%87%e5%87%86%e5%8c%96%e9%a1%b9%e7%9b%aedj-scaffold/</guid>
		<description><![CDATA[由于Django没有象rails一样指定项目的目录结构规范，很多人都对django项目的目录结构要如何组织而感到困惑。为此我又新创建了一个开源项目dj-scaffold（django的脚手架）。这个项目用于自动生成一个标注化的django项目和app。 项目地址：https://github.com/vicalloy/dj-scaffold 安装 已经发布到了pypi，所以你可以用pip或easy_install 来进行安装。 pip install dj-scaffold easy_install dj-scaffold 使用 dj-scaffold主要提供了两个命令，dj-scaffold.py和lbstartapp。 dj-scaffold.py 该脚本用于取代django的startproject命令。使用方式如下： dj-scaffold.py projectname 在该命令执行后，将创建项目projectname。在项目的scripts目录中提供了脚本create_env.py和env.rc。 create_env.py 执行该脚本将自动初始化python虚拟环境。新生成的python虚拟环境在env目录。 env.rc 该脚本用户启动python虚拟环境（source env.rc）。该脚本同时为python manage.py设置了快捷方式$mg。你可以在任何目录调用$mg来执行django命令。比如你用$mg runserver来启动测试服务器。 项目对应的目录结构如下： 注：文件太多，去掉了部分不重要的文件 dj-scaffold.py projectname &#124;+docs/ #用于存放项目的相关文档 &#124;+env/ #python虚拟环境，由脚本自动生成 &#124;~requirements/ #第三方依赖包的存放位置 &#124; `-requirements.pip #pip的依赖说明文件 &#124;~scripts/ #系统相关的脚本 &#124; &#124;-create_env.py #创建python虚拟环境（env目录） &#124; `-env.rc #进入python虚拟环境。同时提供python manger.py的快捷方式$mg。可在任意目录使用$mg。 &#124;~sites/ #Django的项目文件。在settings文件中增加了部分默认配置。如数据库默认使用sqlite，设置项目的模板以及静态文件目录。 &#124; &#124;+media/ #项目静态文件（用户上传） &#124; &#124;+static/ #项目静态文件（css、js等） &#124; <a href="http://haoluobo.com/2011/08/dj-scaffold/"> read more <span class="meta-nav">&#187;</span></a>]]></description>
			<content:encoded><![CDATA[<p>由于Django没有象rails一样指定项目的目录结构规范，很多人都对django项目的目录结构要如何组织而感到困惑。为此我又新创建了一个开源项目<a href="https://github.com/vicalloy/dj-scaffold" target="_blank">dj-scaffold</a>（django的脚手架）。这个项目用于自动生成一个标注化的django项目和app。</p>
<p><strong>项目地址：</strong><a href="https://github.com/vicalloy/dj-scaffold">https://github.com/vicalloy/dj-scaffold</a></p>
<h3>安装</h3>
<p>已经发布到了pypi，所以你可以用pip或easy_install 来进行安装。</p>
<pre>pip install dj-scaffold
easy_install dj-scaffold</pre>
<h3>使用</h3>
<p>dj-scaffold主要提供了两个命令，<strong>dj-scaffold.py</strong>和<strong>lbstartapp</strong>。</p>
<h4>dj-scaffold.py</h4>
<p>该脚本用于取代django的startproject命令。使用方式如下：</p>
<pre>dj-scaffold.py projectname </pre>
<p>在该命令执行后，将创建项目projectname。在项目的scripts目录中提供了脚本<strong>create_env.py</strong>和<strong>env.rc</strong>。</p>
<ul>
<li><strong>create_env.py</strong> 执行该脚本将自动初始化python虚拟环境。新生成的python虚拟环境在env目录。 </li>
<li><strong>env.rc</strong> 该脚本用户启动python虚拟环境（source env.rc）。该脚本同时为python manage.py设置了快捷方式<strong>$mg</strong>。你可以在任何目录调用<strong>$mg</strong>来执行django命令。比如你用<strong>$mg runserver</strong>来启动测试服务器。 </li>
</ul>
<p>项目对应的目录结构如下：</p>
<pre>注：文件太多，去掉了部分不重要的文件</pre>
<pre>dj-scaffold.py projectname </pre>
<pre>|+docs/    #用于存放项目的相关文档
|+env/     #python虚拟环境，由脚本自动生成
|~requirements/     #第三方依赖包的存放位置
| `-requirements.pip    #pip的依赖说明文件
|~scripts/    #系统相关的脚本
| |-create_env.py    #创建python虚拟环境（env目录）
| `-env.rc    #进入python虚拟环境。同时提供python manger.py的快捷方式$mg。可在任意目录使用$mg。
|~sites/    #Django的项目文件。在settings文件中增加了部分默认配置。如数据库默认使用sqlite，设置项目的模板以及静态文件目录。
| |+media/    #项目静态文件（用户上传）
| |+static/    #项目静态文件（css、js等）
| `+templates/    #项目模板
|+tools/    #一些项目依赖的第三方工具包。如python虚拟环境初始化脚本等。
`~wsgi/    #项目部署用的wsgi文件
  `-dj_scaffold.wsgi</pre>
<h4>lbstartapp</h4>
<p><strong>lbstartapp</strong>作为django的扩展命令提供。将dj_scaffold加到INSTALLED_APPS后即可使用该命令。该命令将生成一个标准的app，相比django自带的startapp，lbstartapp将那些不太常用的app默认目录也都给生成了出来。对应目录结构如下：</p>
<pre>|+management/    #命令目录
|+static/    #静态文件目录
|+templates/    #模板目录
|+templatetags/    #tag目录
|-__init__.py
|-admin.py    #admin管理后台的models配置文件
|-forms.py
|-models.py
|-settings.py    #app自己的settings文件
|-tests.py
|-urls.py    #urls配置文件
`-views.py</pre>
<h3>NOTE</h3>
<ul>
<li>项目的大多代码来自：<a href="https://github.com/lincolnloop/django-startproject">https://github.com/lincolnloop/django-startproject</a> </li>
<li>类似项目：<a href="https://github.com/mozilla/playdoh">https://github.com/mozilla/playdoh</a> 个人觉得这个项目还可以。不过我个人觉得自己写的更符合自己的习惯。 </li>
<li>“摒弃魔法”是Django的哲学之一。为此Django没有为用户提供太多的默认操作，它希望一切对用户都是显示可见的。这本没太大的问题，但在我看来“no magic”并不代表连规范都不要。Django实在是太缺乏一些必要的规范。 </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/08/dj-scaffold/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>利用mod_rewrite实现域名的切换</title>
		<link>http://haoluobo.com/2011/07/mod_rewrite-exchange-domain/</link>
		<comments>http://haoluobo.com/2011/07/mod_rewrite-exchange-domain/#comments</comments>
		<pubDate>Tue, 19 Jul 2011 13:44:58 +0000</pubDate>
		<dc:creator>vicalloy</dc:creator>
				<category><![CDATA[编程]]></category>
		<category><![CDATA[mod_rewrite]]></category>

		<guid isPermaLink="false">http://haoluobo.com/2011/07/%e5%88%a9%e7%94%a8mod_rewrite%e5%ae%9e%e7%8e%b0%e5%9f%9f%e5%90%8d%e7%9a%84%e5%88%87%e6%8d%a2/</guid>
		<description><![CDATA[最初想将haoluobo.com的域名做其他用途，于是创建了子域名vik.haoluobo.com，并将博客挂在blog目录。最终haoluobo.com的域名一直被空了下来。最近想域名空着也是浪费，干脆将博客和知识库切换到haoluobo.com下。 切换后 博客地址为：http://haoluobo.com 知识库地址：http://haoluobo.com/trac/ 这时候问题来了。切换域名后，此前老域名上的所有链接都失效了。为了保证原有地址依然有效，我利用mod_rewrite将老地址的链接都转发到新地址。 博客的老地址：http://vik.haoluobo.com/blog/ 在 http://vik.haoluobo.com/ apache的静态文件目录www下创建目录blog，并在改目录下添加.htaccess文件 RewriteEngine On RewriteRule (.*) http://haoluobo.com/$1 [R=301] 知识库的处理类似， 知识库的老地址：http://vik.haoluobo.com/trac/ 在www目录下创建trac目录，并在改目录下添加.htaccess文件 RewriteEngine On RewriteRule (.*) http://haoluobo.com/trac/$1 [R=301] 注：在http协议中，状态码301标示永久重定向，这样搜索引擎就知道你的老地址今后就不用了。]]></description>
			<content:encoded><![CDATA[<p>最初想将haoluobo.com的域名做其他用途，于是创建了子域名vik.haoluobo.com，并将博客挂在blog目录。最终haoluobo.com的域名一直被空了下来。最近想域名空着也是浪费，干脆将博客和知识库切换到haoluobo.com下。</p>
<p>切换后</p>
<p>博客地址为：<a href="http://haoluobo.com">http://haoluobo.com</a></p>
<p>知识库地址：<a href="http://haoluobo.com/trac/">http://haoluobo.com/trac/</a></p>
<p>这时候问题来了。切换域名后，此前老域名上的所有链接都失效了。为了保证原有地址依然有效，我利用mod_rewrite将老地址的链接都转发到新地址。</p>
<p>博客的老地址：<a href="http://vik.haoluobo.com/blog/">http://vik.haoluobo.com/blog/</a></p>
<p>在 <a href="http://vik.haoluobo.com/blog/">http://vik.haoluobo.com/</a> apache的静态文件目录www下创建目录blog，并在改目录下添加<strong>.htaccess</strong>文件</p>
<pre>RewriteEngine On
RewriteRule (.*) http://haoluobo.com/$1 [R=301]</pre>
<p>知识库的处理类似，</p>
<p>知识库的老地址：<a href="http://vik.haoluobo.com/trac/">http://vik.haoluobo.com/trac/</a></p>
<p>在www目录下创建trac目录，并在改目录下添加<strong>.htaccess</strong>文件</p>
<pre>RewriteEngine On
RewriteRule (.*) http://haoluobo.com/trac/$1 [R=301]</pre>
<p>注：在http协议中，状态码301标示永久重定向，这样搜索引擎就知道你的老地址今后就不用了。</p>
]]></content:encoded>
			<wfw:commentRss>http://haoluobo.com/2011/07/mod_rewrite-exchange-domain/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

