[Whodo.SVN] r82 - in trunk/doc/agile_python: . images

0 views
Skip to first unread message

SVN 提交记录

unread,
Sep 11, 2008, 10:38:47 PM9/11/08
to s...@list.worldhello.net
Author: jiangxin
Date: 2008-09-11 00:49:02 +0800 (四, 2008-09-11)
New Revision: 82

Added:
trunk/doc/agile_python/images/check_controller.png
trunk/doc/agile_python/images/html_design.png
trunk/doc/agile_python/images/security_controller.png
trunk/doc/agile_python/images/snapshot_acl.png
trunk/doc/agile_python/images/snapshot_check.png
trunk/doc/agile_python/images/snapshot_hooks.png
Modified:
trunk/doc/agile_python/ch01-preface.xml
trunk/doc/agile_python/ch02-model-tdd.xml
trunk/doc/agile_python/ch03-pylons.xml
trunk/doc/agile_python/ch04-auth.xml
trunk/doc/agile_python/ch06-i18n.xml
trunk/doc/agile_python/ch07-package.xml
trunk/doc/agile_python/ch08-submit.xml
trunk/doc/agile_python/ch09-appendix.xml
trunk/doc/agile_python/index.xml
Log:
add ulink; add sidebar for snapshot

已修改: trunk/doc/agile_python/ch01-preface.xml
===================================================================
--- trunk/doc/agile_python/ch01-preface.xml 2008-09-10 07:00:44 UTC (rev 81)
+++ trunk/doc/agile_python/ch01-preface.xml 2008-09-10 16:49:02 UTC (rev 82)
@@ -2,9 +2,10 @@
<sect1 id="psm.preface">
<title>前言</title>

- <para>本文来自于笔者最近完成的一个小项目 pySvnManager,源代码已经贡献到开源项目网站
- SorceForge.net。该项目从一开始,就采用了测试驱动开发(TDD)技术,通过一系列的迭代
- 最终敏捷的实现了预期的需求。</para>
+ <para>本文来自于笔者<ulink url="http://www.ossxp.com/News/2008-09-02"
+ >最近完成的一个小项目 pySvnManager</ulink>,源代码已经贡献到开源项目网站
+ <ulink url="http://pySvnManager.sf.net"/>。该项目从一开始,
+ 就采用了测试驱动开发(TDD)技术,通过一系列的迭代最终敏捷的实现了预期的需求。</para>

<para>在该项目中采用了Python最新流行的MVC框架:
Pylons。并在Web页面中大量使用了AJAX技术。本文涉及到的技术术语有:敏捷,TDD,MVC,
@@ -17,8 +18,7 @@
<para>Subversion使用配置文件进行基于路径的授权,手工配置易于出错。下面是一个
错误百出的配置示例:</para>

- <blockquote>
- <screen>
+ <screen>
[groups]
admin = &amp;admin, admin1, admin2
group1 = @group2, user1
@@ -43,8 +43,7 @@
* =
@group1 = rw
@visiters = r
- </screen>
- </blockquote>
+</screen>

<para>其中的错误或可能的错误有:</para>

@@ -83,8 +82,8 @@
<sect2 id="psm.preface.implement">
<title>最终的实现</title>

- <para>我们先来看看最终的实现。下面的命令是在Debian Linux下完成,
- Windows或其他平台,与之类似。</para>
+ <para>我们先来如何部署最终的实现。下面的安装配置过程中的命令是在
+ Debian Linux下完成。至于 Windows 或其他平台,应该与之类似。</para>

<!-- =============================================================== -->
<sect3 id="psm.preface.implement.install">
@@ -93,55 +92,57 @@
<para>理论上最简单的安装模式:</para>

<screen>
-$ sudo easy_install pySvnManager
+$ <emphasis>sudo easy_install pySvnManager</emphasis>
Searching for pySvnManager
Reading http://pypi.python.org/simple/pySvnManager/
Reading https://sourceforge.net/projects/pysvnmanager
</screen>

- <para>理论上的简单的东西,现实当中可能会有些复杂:</para>
+ <para>理论上很简单的东西,也奈何不了复杂的现实:</para>

- <para>安装过程在进行到访问sourceforge.net以获取pySvnManager最新版本列表时被阻塞。
- 虽然我打算把项目移到别处,但发现一些依赖的包如:
- python-ldap也是要访问sourceforge.net网站,因此我取消了搬家的打算,默默静等解风。
- 同时将代码镜像在网址:http://svn.worldhello.net/svn/pysvnmanager 上,
- 供不能访问SourceForge.net的用户参考。</para>
+ <para>在项目刚刚开发完成,就出现了相当长的一段时间 SourceForge.net 无法访问!
+ 导致 <command>easy_install</command> 为了搜索最新版本,在连接到
+ <ulink url="http://SourceForge.net"/> 时发生了死锁而阻塞。
+ 虽然我打算把项目移到别处,但发现一些依赖的包如: python-ldap
+ 也是要访问 SourceForge.net网站。因此我取消了搬家的打算,耐心且无助的等。
+ 同时将代码镜像在网址:<ulink url="http://svn.worldhello.net/svn/pysvnmanager"/>
+ 上,供不能访问 <ulink url="http://SourceForge.net"/> 的用户参考。</para>

- <para>可以使用curl命令或者用浏览器连接到 http://pypi.python.org/simple/pySvnManager/
- 以查找可下载的pySvnManager软件包:</para>
+ <para>如果遇到阻塞,则需要花费更多的时间,手工下载软件包。<command>easy_install</command>
+ 也可以安装下载到本地的软件包。</para>

<screen>
-$ curl http://pypi.python.org/simple/pySvnManager/
-&lt;html&gt;&lt;head&gt;&lt;title&gt;Links for pySvnManager&lt;/title&gt;&lt;/head&gt;&lt;body&gt;&lt;h1&gt;Links for pySvnManager&lt;/h1&gt;&lt;a href='https://sourceforge.net/projects/pysvnmanager' rel="homepage"&gt;0.1.2dev-r9 home_page&lt;/a&gt;&lt;br/&gt;
-&lt;a href='http://pypi.python.org/packages/2.5/p/pySvnManager/pySvnManager-0.1.2dev_r9-py2.5.egg#md5=f0546558f3974308e0d24bd5195f8694'&gt;pySvnManager-0.1.2dev_r9-py2.5.egg&lt;/a&gt;&lt;br/&gt;
-&lt;a href='http://pypi.python.org/packages/source/p/pySvnManager/pySvnManager-0.1.2dev-r9.tar.gz#md5=eb54172084c67514251dbcfda29f4d23'&gt;pySvnManager-0.1.2dev-r9.tar.gz&lt;/a&gt;&lt;br/&gt;
+$ <emphasis>wget http://pypi.python.org/packages/source/p/pySvnManager/pySvnManager... </emphasis>
+$ <emphasis>sudo easy_install pySvnManager-... </emphasis>
</screen>
+
+ <note>
+ <para>PySvnManager 的软件包有两种格式。一种是二进制的格式:<filename>pysvnmanager-xxx.egg</filename>,
+ 另外一种是源码包 <filename>pysvnmanager-xxx.tar.gz</filename>。</para>
+ <para>二进制包,是针对特定的 Python 版本编译的,如果您当前的 Python 版本和二进制包的版本不符,
+ 就必须从源码包开始安装过程。无论源码包还是二进制的 Egg 包,都可以方便的使用
+ <command>easy_install</command> 进行安装。</para>
+ </note>

- <para>看到链接了么? http://pypi.python.org/packages/2.5/p/pySvnManager/pySvnManager... </para>
- <para>如果是Python2.5,可以直接安装egg包,如果不是,需要下载源码包。
- 无论源码包还是egg包,都可以方便的使用easy_install进行安装:</para>
- <screen>
-$ wget http://pypi.python.org/packages/source/p/pySvnManager/pySvnManager...
-$ sudo easy_install pySvnManager-...
-</screen>
-
</sect3>

<!-- =============================================================== -->
<sect3 id="psm.preface.implement.deploy">
<title>网站部署</title>
- <para>执行make-config和setup-app完成部署。部署过程的细节参见后面软件集成的相关内容。</para>
-
- <screen>
-$ mkdir deploy
-$ cd deploy
-$ paster make-config pySvnManager config.ini
+
+ <para>执行 <command>make-config</command> 和 <command>setup-app</command>
+ 完成部署。部署过程的细节参见后面软件集成的相关内容。</para>
+
+ <screen>
+$ <emphasis>mkdir deploy</emphasis>
+$ <emphasis>cd deploy</emphasis>
+$ <emphasis>paster make-config pySvnManager config.ini</emphasis>
Distribution already installed:
pySvnManager 0.1.2dev-r9 from /home/jiangxin/pyenv/lib/python2.5/site-packages/pySvnManager-0.1.2dev_r9-py2.5.egg
Creating config.ini
Now you should edit the config files
config.ini
-$ paster setup-app config.ini
+$ <emphasis>paster setup-app config.ini</emphasis>
Running setup_config() from pysvnmanager.websetup
</screen>

@@ -155,20 +156,28 @@

<itemizedlist>
<listitem>
- <para>config.ini :应用默认运行于5000端口,可以在此文件中定制</para>
+ <para><emphasis>config.ini :</emphasis>
+
+ 应用默认运行于5000端口,可以在此文件中定制</para>
</listitem>

<listitem>
- <para>config/localconfig.py :设置应用缺省的认证方式,缺省用config/svn.passwd口令认证</para>
+ <para><emphasis>config/localconfig.py :</emphasis>
+
+ 设置应用缺省的认证方式,缺省用config/svn.passwd口令认证</para>
</listitem>

<listitem>
- <para>config/svn.passwd : 缺省该口令文件内所有用户的口令均为 "guess"</para>
+ <para><emphasis>config/svn.passwd :</emphasis>
+
+ 缺省该口令文件内所有用户的口令均为 "guess"</para>
</listitem>

<listitem>
- <para>config/svn.access : svn路径授权文件,本应用要处理的文件。
- 注意该文件开头的注释是版本号和版本库管理员帐号设置,不要随意删除!</para>
+ <para><emphasis>config/svn.access :</emphasis>
+
+ svn路径授权文件,本应用要处理的文件。注意该文件开头的注释是版本号和版本库管理员帐号设置,
+ 不要随意删除!</para>
</listitem>

</itemizedlist>
@@ -178,10 +187,10 @@
<sect3 id="psm.preface.implement.start">
<title>运行应用</title>

- <para>启动应用,自动开启Web服务于5000端口。用Web浏览器访问。推荐使用Firefox。</para>
+ <para>启动应用,自动开启Web服务于5000端口。用Web浏览器访问。推荐使用 Firefox。</para>

<screen>
-$ paster serve config.ini
+$ <emphasis>paster serve config.ini</emphasis>
Starting server in PID 28937.
serving on 0.0.0.0:5000 view at http://127.0.0.1:5000
</screen>
@@ -192,19 +201,42 @@
<!-- =============================================================== -->
<sect3 id="psm.preface.implement.snapshot">
<title>软件截屏</title>
- <para>参见演示网站: http://demo.ossxp.com/svnadmin/</para>
+
+ <para>参见演示网站:<ulink url="http://demo.ossxp.com/svnadmin/security/submit?username=admin&amp;password=admin"
+ >http://demo.ossxp.com/svnadmin/</ulink></para>

+ <para>Subversion 的授权机制,可能存在互相冲突的策略,导致用户权限的设置可能并不符合预期。
+ 可以通过“权限检查”的功能对用户权限进行检查。参见:
+ <xref linkend="psm.preface.implement.snapshot.check"/></para>
+
+ <sidebar>
+ <figure id="psm.preface.implement.snapshot.check">
+ <title>用户权限测试功能</title>
+ <graphic fileref="images/snapshot_check.png"/>
+ </figure>
+ </sidebar>

- <figure id="psm.preface.implement.snapshot.img1">
- <title>路径授权验证功能</title>
- <graphic fileref="images/snapshot_check.png"/>
- </figure>
+ <para>管理员可以用图形界面对用户帐号进行角色管理,可以对版本库的授权进行设置。参见:
+ <xref linkend="psm.preface.implement.snapshot.acl"/></para>
+
+ <sidebar>
+ <figure id="psm.preface.implement.snapshot.acl">
+ <title>路径授权设置功能</title>
+ <graphic fileref="images/snapshot_acl.png"/>
+ </figure>
+ </sidebar>
+
+ <para>PySvnManager 还提供的版本库创建和删除(仅限空版本库),
+ 以及版本库钩子脚本的设置界面。参见:
+ <xref linkend="psm.preface.implement.snapshot.hooks"/></para>
+
+ <sidebar>
+ <figure id="psm.preface.implement.snapshot.hooks">
+ <title>版本库创建及钩子脚本扩展</title>
+ <graphic fileref="images/snapshot_hooks.png"/>
+ </figure>
+ </sidebar>

- <figure id="psm.preface.implement.snapshot.img2">
- <title>路径授权设置</title>
- <graphic fileref="images/snapshot_acl.png"/>
- </figure>
-
<para>下面将整个开发过程予以概要介绍,以了解Python的Web编程框架以及Python的敏捷实践。</para>

</sect3>

已修改: trunk/doc/agile_python/ch02-model-tdd.xml
===================================================================
--- trunk/doc/agile_python/ch02-model-tdd.xml 2008-09-10 07:00:44 UTC (rev 81)
+++ trunk/doc/agile_python/ch02-model-tdd.xml 2008-09-10 16:49:02 UTC (rev 82)
@@ -20,41 +20,42 @@
<sect2 id="psm.tdd.iter1">
<title>迭代1:测试框架的建立</title>

+ <para>首先搭建单元测试框架,并完成一个最小的功能集合。</para>

<!-- =============================================================== -->
<sect3 id="psm.tdd.iter1.goal">
<title>假想任务目标</title>

- <para>首先为我们的模型起个名字:svnauthz。</para>
+ <para>首先为我们的模型起个名字:<filename>svnauthz</filename>。</para>

<para>Subversion路径授权中,用户对象(用户/别名/组)显然是最重要的基本单位,
每一条授权策略都包含一个用户对象。那么我们第一个迭代就实现用户对象:
User类,Alias类,Group类。</para>

<para>假设svnauthz的 User, Alias, Group 类已经完成,我们期望他们实现的功能是什么呢?
- 于是在纸上写下(模拟python交互式命令行):</para>
+ 于是在纸上写下假想任务目标(模拟python交互式命令行):</para>

<screen>
&gt;&gt;&gt; <emphasis>from svnauthz import User, Group, Alias</emphasis>
-&gt;&gt;&gt; user1=User('Tom')
-&gt;&gt;&gt; user2=User("Jerry")
-&gt;&gt;&gt; print user1
+&gt;&gt;&gt; <emphasis>user1=User('Tom')</emphasis>
+&gt;&gt;&gt; <emphasis>user2=User("Jerry")</emphasis>
+&gt;&gt;&gt; <emphasis>print user1</emphasis>
Tom # 显示 user1 内容(字符串化)

-&gt;&gt;&gt; alias1=Alias('admin')
-&gt;&gt;&gt; alias1.user = user1
-&gt;&gt;&gt; print alias1
+&gt;&gt;&gt; <emphasis>alias1=Alias('admin')</emphasis>
+&gt;&gt;&gt; <emphasis>alias1.user = user1</emphasis>
+&gt;&gt;&gt; <emphasis>print alias1</emphasis>
admin = Tom # 显示 alias1 内容(字符串化)

-&gt;&gt;&gt; group1 = Group('team1')
-&gt;&gt;&gt; group2 = Group('team2')
-&gt;&gt;&gt; group1.append(group2, user2, alias1, user1)
-&gt;&gt;&gt; print group1
+&gt;&gt;&gt; <emphasis>group1 = Group('team1')</emphasis>
+&gt;&gt;&gt; <emphasis>group2 = Group('team2')</emphasis>
+&gt;&gt;&gt; <emphasis>group1.append(group2, user2, alias1, user1)</emphasis>
+&gt;&gt;&gt; <emphasis>print group1</emphasis>
team1 = &amp;admin, @team2, Jerry, Tom # group1 的成员列表要进行排序
-&gt;&gt;&gt; group2.append(group1, user1)
+&gt;&gt;&gt; <emphasis>group2.append(group1, user1)</emphasis>
Exception: ... # 抛出异常! group1 引起了组间的循环引用
-&gt;&gt;&gt; group2.append(group1, user1, autodrop=True)
-&gt;&gt;&gt; print group2
+&gt;&gt;&gt; <emphasis>group2.append(group1, user1, autodrop=True)</emphasis>
+&gt;&gt;&gt; <emphasis>print group2</emphasis>
team2 = Tom # 使用 autodrop 参数,自动抛弃冲突的组成员,而不引发异常。(即容错性)
</screen>

@@ -64,7 +65,7 @@
<sect3 id="psm.tdd.iter1.unittest.failed">
<title>建立测试用例</title>

- <para>将假想的任务目标翻译为测试用例。建立单元测试文件 test_svnauthz.py 如下:</para>
+ <para>将假想的任务目标翻译为测试用例。建立单元测试文件 <filename>test_svnauthz.py</filename> 如下:</para>

<screen>
#!/usr/bin/env python
@@ -104,7 +105,7 @@
<para>执行测试用例:</para>

<screen>
-$ python test_svnauthz.py
+$ <emphasis>python test_svnauthz.py</emphasis>
Traceback (most recent call last):
File "test_svnauthz.py", line 8, in &lt;module&gt;
from svnauthz import *
@@ -119,16 +120,16 @@
<title>编写模组,使测试用例通过</title>

<para>之前执行测试用例失败,报告:找不到 svnauthz 模组。因为模组还没有创建,当然找不到了。
- 于是创建一个空的模组文件 svnauthz.py。</para>
+ 于是创建一个空的模组文件 <filename>svnauthz.py</filename>。</para>

<screen>
-$ touch svnauthz.py
+$ <emphasis>touch svnauthz.py</emphasis>
</screen>

<para>执行测试用例:</para>

<screen>
-$ python test_svnauthz.py
+$ <emphasis>python test_svnauthz.py</emphasis>
EEE
======================================================================
ERROR: testAlias (__main__.TestStage1)
@@ -201,16 +202,16 @@
<para>将 def testGroup(self) 改为 def _testGroup(self)</para>
</listitem>

- <listitem>
- <para>注:只要不是以 test 开头都好。</para>
- </listitem>
-
</itemizedlist>
-
+
+ <note>
+ <para>注:只要不是以 test 开头都好。</para>
+ </note>
+
<para>再次执行测试用例,太棒了完全通过!</para>

<screen>
-$ python test_svnauthz.py -v
+$ <emphasis>python test_svnauthz.py -v</emphasis>
testUser (__main__.TestStage1) ... ok

----------------------------------------------------------------------
@@ -229,7 +230,7 @@
就可以使用coverage命令了。</para>

<screen>
-$ coverage -x test_svnauthz.py
+$ <emphasis>coverage -x test_svnauthz.py</emphasis>
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
@@ -259,13 +260,13 @@
<para>再次检查一下测试用例对代码的覆盖度。哇,100% 通过!</para>

<screen>
-$ coverage -x test_svnauthz.py
+$ <emphasis>coverage -x test_svnauthz.py</emphasis>
.
----------------------------------------------------------------------
Ran 1 test in 0.002s

OK
-$ coverage -r -m svnauthz.py
+$ <emphasis>coverage -r -m svnauthz.py</emphasis>
Name Stmts Exec Cover Missing
----------------------------------------
svnauthz 8 8 100%
@@ -283,7 +284,7 @@
<para>执行测试用例:</para>

<screen>
-$ python tests/test_svnauthz.py
+$ <emphasis>python tests/test_svnauthz.py</emphasis>
Traceback (most recent call last):
File "tests/test_svnauthz.py", line 8, in &lt;module&gt;
from svnauthz import *
@@ -307,9 +308,8 @@
可以用easy_install 来安装:</para>

<screen>
-$ easy_install nose
-执行nosetests:
-$ nosetests
+$ <emphasis>easy_install nose</emphasis>
+$ <emphasis>nosetests</emphasis>
.
----------------------------------------------------------------------
Ran 1 test in 0.008s
@@ -320,7 +320,7 @@
<para>代码覆盖度测试</para>

<screen>
-$ nosetests --with-coverage --cover-package=svnauthz
+$ <emphasis>nosetests --with-coverage --cover-package=svnauthz</emphasis>
.
Name Stmts Exec Cover Missing
----------------------------------------
@@ -351,45 +351,45 @@
<para>在Python交互模式下测试svnauthz模组:</para>

<screen>
-&gt;&gt;&gt; buff = '''# admin: / = administrator
-... [groups]
-... group1=user1,user2
-... [/]
-... $authenticated=r
-... [/trunk]
-... @group1 = r
-... user3 = rw'''
-&gt;&gt;&gt; import StringIO
-&gt;&gt;&gt; file = StringIO.StringIO(buff)
-&gt;&gt;&gt; authz=SvnAuthz()
-&gt;&gt;&gt; authz.load(file)
-&gt;&gt;&gt; [x.name for x in authz.reposlist]
+&gt;&gt;&gt; <emphasis>buff = '''# admin: / = administrator</emphasis>
+... <emphasis>[groups]</emphasis>
+... <emphasis>group1=user1,user2</emphasis>
+... <emphasis>[/]</emphasis>
+... <emphasis>$authenticated=r</emphasis>
+... <emphasis>[/trunk]</emphasis>
+... <emphasis>@group1 = r</emphasis>
+... <emphasis>user3 = rw'''</emphasis>
+&gt;&gt;&gt; <emphasis>import StringIO</emphasis>
+&gt;&gt;&gt; <emphasis>file = StringIO.StringIO(buff)</emphasis>
+&gt;&gt;&gt; <emphasis>authz=SvnAuthz()</emphasis>
+&gt;&gt;&gt; <emphasis>authz.load(file)</emphasis>
+&gt;&gt;&gt; <emphasis>[x.name for x in authz.reposlist]</emphasis>
['/']
-&gt;&gt;&gt; [x.uname for x in authz.userlist]
+&gt;&gt;&gt; <emphasis>[x.uname for x in authz.userlist]</emphasis>
[u'administrator', u'user1', u'user2', u'user3']
-&gt;&gt;&gt; [x.uname for x in authz.userlist]
+&gt;&gt;&gt; <emphasis>[x.uname for x in authz.userlist]</emphasis>
[u'administrator', u'user1', u'user2', u'user3']
-&gt;&gt;&gt; [x.uname for x in authz.grouplist]
+&gt;&gt;&gt; <emphasis>[x.uname for x in authz.grouplist]</emphasis>
[u'@group1', u'$authenticated']
-&gt;&gt;&gt; [x.uname for x in authz.aliaslist]
+&gt;&gt;&gt; <emphasis>[x.uname for x in authz.aliaslist]</emphasis>
[]
-&gt;&gt;&gt; print authz.grouplist
+&gt;&gt;&gt; <emphasis>print authz.grouplist</emphasis>
[groups]
group1 = user1, user2

-&gt;&gt;&gt; print authz.aliaslist
+&gt;&gt;&gt; <emphasis>print authz.aliaslist</emphasis>
[aliases]
-&gt;&gt;&gt; authz.is_admin('administrator','/')
+&gt;&gt;&gt; <emphasis>authz.is_admin('administrator','/')</emphasis>
True
-&gt;&gt;&gt; authz.is_admin('administrator','repos1')
+&gt;&gt;&gt; <emphasis>authz.is_admin('administrator','repos1')</emphasis>
True
-&gt;&gt;&gt; authz.add_rules('/', '/trunk', '&amp;admin=rw; $authenticated=')
-&gt;&gt;&gt; module1 = authz.get_module('/', '/trunk')
-&gt;&gt;&gt; [str(x) for x in module1]
+&gt;&gt;&gt; <emphasis>authz.add_rules('/', '/trunk', '&amp;admin=rw; $authenticated=')</emphasis>
+&gt;&gt;&gt; <emphasis>module1 = authz.get_module('/', '/trunk')</emphasis>
+&gt;&gt;&gt; <emphasis>[str(x) for x in module1]</emphasis>
['@group1 = r', 'user3 = rw', '$authenticated = ', '&amp;admin = rw']
</screen>

- <para>现在是时候给svnauthz套上一个华丽一点的外衣了。</para>
+ <para>现在是时候给 svnauthz 套上一个华丽一点的外衣了。</para>

</sect2>

已修改: trunk/doc/agile_python/ch03-pylons.xml
===================================================================
--- trunk/doc/agile_python/ch03-pylons.xml 2008-09-10 07:00:44 UTC (rev 81)
+++ trunk/doc/agile_python/ch03-pylons.xml 2008-09-10 16:49:02 UTC (rev 82)
@@ -17,16 +17,16 @@
<para>我们的应用定名为pySvnManager。建立同名的Pylons框架:</para>

<screen>
-$ paster create -t pylons pySvnManager
-$ cd pySvnManager
-$ ls -F
+$ <emphasis>paster create -t pylons pySvnManager</emphasis>
+$ <emphasis>cd pySvnManager</emphasis>
+$ <emphasis>ls -F</emphasis>
development.ini docs/ MANIFEST.in pysvnmanager/ pySvnManager.egg-info/ README.txt setup.cfg setup.py test.ini
</screen>

<para>启动Web应用:</para>

<screen>
-$ paster serve --reload development.ini
+$ <emphasis>paster serve --reload development.ini</emphasis>
Starting subprocess with file monitor
Starting server in PID 817.
serving on 0.0.0.0:5000 view at http://127.0.0.1:5000
@@ -43,7 +43,7 @@
controllers/check.py,另外一个是单元测试文件:tests/functional/test_check.py。</para>

<screen>
-$ paster controller check
+$ <emphasis>paster controller check</emphasis>
Creating /home/jiangxin/pyenv/pySvnManager/pysvnmanager/controllers/check.py
Creating /home/jiangxin/pyenv/pySvnManager/pysvnmanager/tests/functional/test_check.py
</screen>
@@ -115,7 +115,7 @@
<para>实验一下nosetests是否依然可靠运行。</para>

<screen>
-$ nosetests
+$ <emphasis>nosetests</emphasis>
.............
----------------------------------------------------------------------
Ran 13 tests in 0.546s
@@ -193,8 +193,7 @@
<title>视图模板用参数填充</title>

<screen>
-
- &lt;input type="submit" name="submit" value="提交"&gt;
+&lt;input type="submit" name="submit" value="提交"&gt;
${h.end_form()}

&lt;hr&gt;
@@ -397,8 +396,7 @@
Pylons内置了prototype脚本。如果想要启用Pylons自带prototype
的JavaScript框架,只要在模板中嵌入如下WebHelpers语句:</para>

- <screen>
-<![CDATA[
+ <screen><![CDATA[
<html>
<head>
${h.javascript_include_tag(builtins=True)}
@@ -406,8 +404,7 @@

<para>实际上会在页面中产生下面两个JavaScrip包含语句:</para>

- <screen>
-<![CDATA[
+ <screen><![CDATA[
<script src="/javascripts/prototype.js" type="text/javascript"></script>
<script src="/javascripts/scriptaculous.js" type="text/javascript"></script>
]]></screen>
@@ -453,8 +450,7 @@
<para>文件 check/index.mako 中用WebHelpers.rails的form_remote_tag
快速创建了一个Ajax Form。</para>

- <screen>
-<![CDATA[
+ <screen><![CDATA[
## AJAX Form
<%
context.write(
@@ -471,8 +467,7 @@

<para>出现在页面中,则是如下的代码:</para>

- <screen>
-<![CDATA[
+ <screen><![CDATA[
<form action="/check/access_map" id="main_form" method="POST" onsubmit="showNoticesPopup();
new Ajax.Updater({success:'acl_msg', failure:'acl_error'}, '/check/access_map',
{asynchronous:true, evalScripts:true, method:'post', onComplete:function(request)
@@ -548,16 +543,14 @@

<para>版本库下拉框(②)更新时,执行JavaScript函数:update_path(),而非提交表单:</para>

- <screen>
- <![CDATA[
+ <screen><![CDATA[
<input type="radio" name="reposinput" value="select" Checked onClick="update_path(this.form)">
]]></screen>

<para>函数update_path(),执行Ajax.Request,从"get_auth_path"这个action获取信息,
并用返回值(request.reponseText)为参数调用JavaScript函数ajax_update_path。</para>

- <screen>
-<![CDATA[
+ <screen><![CDATA[
function update_path(form)
{
var repos = "";
@@ -586,8 +579,7 @@
最终这些JavaScript代码在函数ajax_update_path中被执行,
并用相应的数据更新了授权路径的列表(③)。</para>

- <screen>
-<![CDATA[
+ <screen><![CDATA[
function ajax_update_path(code)
{
var id = new Array();
@@ -650,8 +642,7 @@
<sect3 id="psm.pylons.controller.unittest.sample1">
<title>测试示例一</title>

- <screen>
-<![CDATA[
+ <screen><![CDATA[
res = self.app.get(url_for(controller='check'))
assert res.status == 200
assert '''<input type="submit" name="submit" value='Check Permissions'>''' in res.body
@@ -664,8 +655,7 @@
<sect3 id="psm.pylons.controller.unittest.sample2">
<title>测试示例二</title>

- <screen>
-<![CDATA[
+ <screen><![CDATA[
params = {
'userinput':'select',
'userselector':'user1',

已修改: trunk/doc/agile_python/ch04-auth.xml
===================================================================
--- trunk/doc/agile_python/ch04-auth.xml 2008-09-10 07:00:44 UTC (rev 81)
+++ trunk/doc/agile_python/ch04-auth.xml 2008-09-10 16:49:02 UTC (rev 82)
@@ -96,8 +96,7 @@

<para>在测试用例中调用login方法:</para>

- <screen>
-<![CDATA[
+ <screen><![CDATA[
self.login('root')
res = self.app.get(url_for(controller='check'))
assert res.status == 200

已修改: trunk/doc/agile_python/ch06-i18n.xml
===================================================================
--- trunk/doc/agile_python/ch06-i18n.xml 2008-09-10 07:00:44 UTC (rev 81)
+++ trunk/doc/agile_python/ch06-i18n.xml 2008-09-10 16:49:02 UTC (rev 82)
@@ -12,8 +12,7 @@
<para>函数_()实际上是gettext模组的 ugettext方法别名。将程序中出现的字符串输出改为
_()调用。例如,在模板文件中:</para>

- <screen>
-<![CDATA[
+ <screen><![CDATA[
<tr>
<th>Account</th>
<th>Repository</th>
@@ -23,8 +22,7 @@

<para>修改为</para>

- <screen>
- <![CDATA[
+ <screen><![CDATA[
<tr>
<th>${_("Account")}</th>
<th>${_("Repository")}</th>
@@ -91,8 +89,7 @@
</row>
<row>
<entry>根据模板文件,创建本地语种文件(*.po)</entry>
- <entry><para>$ python setup.py init_catalog -l zh_CN</para>
- <para>$ python setup.py init_catalog -l en</para></entry>
+ <entry>$ python setup.py init_catalog -l zh_CN</entry>
</row>
<row>
<entry>翻译*.po文件(工具: kbabel)</entry>

已修改: trunk/doc/agile_python/ch07-package.xml
===================================================================
--- trunk/doc/agile_python/ch07-package.xml 2008-09-10 07:00:44 UTC (rev 81)
+++ trunk/doc/agile_python/ch07-package.xml 2008-09-10 16:49:02 UTC (rev 82)
@@ -15,9 +15,9 @@
部署第一步是在部署目录中创建一个INI文件:</para>

<screen>
-~/deploy$ paster make-config pySvnManager config.ini
+~/deploy$ <emphasis>paster make-config pySvnManager config.ini</emphasis>
...
-~/deploy$ ls
+~/deploy$ <emphasis>ls</emphasis>
config.ini
</screen>

@@ -34,11 +34,11 @@
<para>当在部署目录中创建INI文件后,还要执行setup-app命令,以完成应用的部署。</para>

<screen>
-~/deploy$ paster setup-app config.ini
+~/deploy$ <emphasis>paster setup-app config.ini</emphasis>
Running setup_config() from pysvnmanager.websetup
-~/deploy$ ls -F
+~/deploy$ <emphasis>ls -F</emphasis>
config/ config.ini
-~/deploy$ find config -type f
+~/deploy$ <emphasis>find config -type f</emphasis>
config/localconfig.py
config/svn.access
config/svn.passwd
@@ -98,16 +98,16 @@
<para>创建源码包</para>

<screen>
-$ python setup.py sdist
-$ ls dist/
+$ <emphasis>python setup.py sdist</emphasis>
+$ <emphasis>ls dist/</emphasis>
pySvnManager-0.1.2dev-r14.tar.gz
</screen>

<para>创建二进制包</para>

<screen>
-$ python setup.py bdist_egg
-$ ls dist/
+$ <emphasis>python setup.py bdist_egg</emphasis>
+$ <emphasis>ls dist/</emphasis>
pySvnManager-0.1.2dev_r14-py2.5.egg
</screen>

已修改: trunk/doc/agile_python/ch08-submit.xml
===================================================================
--- trunk/doc/agile_python/ch08-submit.xml 2008-09-10 07:00:44 UTC (rev 81)
+++ trunk/doc/agile_python/ch08-submit.xml 2008-09-10 16:49:02 UTC (rev 82)
@@ -8,19 +8,19 @@
<para>PYPI是Python包索引(Python Package Index)的缩写,是Python语言的代码库,
相当于Perl的CPAN或者PHP的PEAR。pySvnManager已经提交到PYPI,
这样就可以用easy_install下载和安装。</para>
- <para>网址:http://pypi.python.org/pypi/pySvnManager/ </para>
+ <para>网址:<ulink url="http://pypi.python.org/pypi/pySvnManager/"/></para>
</listitem>

<listitem>
<para>Sourceforge.net</para>
<para>SourceForge.net是最大的开源软件代码库,提供代码托管以及其他项目管理工具。
pySvnManager已经上传到SourceForge.net上。</para>
- <para>项目首页:http://pysvnmanager.sourceforge.net/</para>
+ <para>项目首页:<ulink url="http://pysvnmanager.sourceforge.net/"/></para>
</listitem>

<listitem>
<para>代码下载: </para>
- <para>svn checkout https://pysvnmanager.svn.sourceforge.net/svnroot/pysvnmanager</para>
+ <para><command>svn checkout https://pysvnmanager.svn.sourceforge.net/svnroot/pysvnmanager</command></para>
</listitem>
</itemizedlist>

已修改: trunk/doc/agile_python/ch09-appendix.xml
===================================================================
--- trunk/doc/agile_python/ch09-appendix.xml 2008-09-10 07:00:44 UTC (rev 81)
+++ trunk/doc/agile_python/ch09-appendix.xml 2008-09-10 16:49:02 UTC (rev 82)
@@ -1,60 +1,59 @@
<!-- =================================================================== -->
-<sect1 id="psm.reference">
+<appendix id="psm.reference">
+
<title>参考资料</title>

<orderedlist>
<listitem>
<para>
- pySvnManager 演示: http://demo.ossxp.com/svnadmin/
+ pySvnManager 演示: <ulink url="http://demo.ossxp.com/svnadmin/"/>
</para>
</listitem>
<listitem>
<para>
- pySvnManager 代码镜像: http://svn.worldhello.net/svn/pysvnmanager
+ pySvnManager 代码镜像: <ulink url="http://svn.worldhello.net/svn/pysvnmanager"/>
</para>
</listitem>
<listitem>
<para>
- pySvnManager项目首页: http://sourceforge.net/projects/pySvnManager
+ pySvnManager项目首页: <ulink url="http://pySvnManager.sourceforge.net/"/>
</para>
</listitem>
<listitem>
<para>
- 《Python 学习笔记》参见: http://worldhello.net/wiki/Python
+ 《Python 学习笔记》参见: <ulink url="http://worldhello.net/wiki/Python"/>
</para>
</listitem>
<listitem>
<para>
- Pylons Wiki:http://wiki.pylonshq.com/
+ Pylons Wiki:<ulink url="http://wiki.pylonshq.com/"/>
</para>
</listitem>
<listitem>
<para>
- Pylons 文档:http://docs.pylonshq.com/index.html
+ Pylons 文档:<ulink url="http://docs.pylonshq.com/index.html"/>
</para>
</listitem>
<listitem>
<para>
- Mako模板文档: http://www.makotemplates.org/docs/documentation.html
+ Mako模板文档: <ulink url="http://www.makotemplates.org/docs/documentation.html"/>
</para>
</listitem>
<listitem>
<para>
- Prototype JavaScript 参见: http://www.prototypejs.org/api/ajax
+ Prototype JavaScript 参见: <ulink url="http://www.prototypejs.org/api/ajax"/>
</para>
</listitem>
<listitem>
<para>
- Scriptaculous JavaScript特效参见: http://wiki.script.aculo.us/
+ Scriptaculous JavaScript特效参见: <ulink url="http://wiki.script.aculo.us/"/>
</para>
</listitem>
<listitem>
<para>
- Setuptools文档: http://peak.telecommunity.com/DevCenter/setuptools
+ Setuptools文档: <ulink url="http://peak.telecommunity.com/DevCenter/setuptools"/>
</para>
</listitem>
</orderedlist>

-</sect1>
-
-
+</appendix>

已增加: trunk/doc/agile_python/images/check_controller.png
===================================================================
(二进制文件不同)


Property changes on: trunk/doc/agile_python/images/check_controller.png
___________________________________________________________________
已增加: svn:mime-type
+ image/png

已增加: trunk/doc/agile_python/images/html_design.png
===================================================================
(二进制文件不同)


Property changes on: trunk/doc/agile_python/images/html_design.png
___________________________________________________________________
已增加: svn:mime-type
+ image/png

已增加: trunk/doc/agile_python/images/security_controller.png
===================================================================
(二进制文件不同)


Property changes on: trunk/doc/agile_python/images/security_controller.png
___________________________________________________________________
已增加: svn:mime-type
+ image/png

已增加: trunk/doc/agile_python/images/snapshot_acl.png
===================================================================
(二进制文件不同)


Property changes on: trunk/doc/agile_python/images/snapshot_acl.png
___________________________________________________________________
已增加: svn:mime-type
+ image/png

已增加: trunk/doc/agile_python/images/snapshot_check.png
===================================================================
(二进制文件不同)


Property changes on: trunk/doc/agile_python/images/snapshot_check.png
___________________________________________________________________
已增加: svn:mime-type
+ image/png

已增加: trunk/doc/agile_python/images/snapshot_hooks.png
===================================================================
(二进制文件不同)


Property changes on: trunk/doc/agile_python/images/snapshot_hooks.png
___________________________________________________________________
已增加: svn:mime-type
+ image/png

已修改: trunk/doc/agile_python/index.xml
===================================================================
--- trunk/doc/agile_python/index.xml 2008-09-10 07:00:44 UTC (rev 81)
+++ trunk/doc/agile_python/index.xml 2008-09-10 16:49:02 UTC (rev 82)
@@ -37,10 +37,9 @@
</revhistory>

<abstract>
- <para>本文来自于笔者最近完成的一个小项目 pySvnManager,源代码已经贡献到开源项目网站 SorceForge.net。该项目从一开始,就采用了测试驱动开发(TDD)技术,通过一系列的迭代最终敏捷的实现了预期的需求。</para>
+ <para>敏捷也许就是保障项目成功的“银弹”。笔者通过最近完成的一个小项目切身体验了一下
+ Python 语言在Web敏捷开发上的强大力量,愿与您共享。</para>

- <para>在该项目中采用了Python最新流行的MVC框架: Pylons。并在Web页面中大量使用了AJAX技术。本文涉及到的技术术语有:敏捷,TDD,MVC,单元测试,代码覆盖测试,AJAX,重构,i18n,开放源代码。</para>
-
<para>(版本号: 0.1.&doc.revision;,最后更新时间: &doc.lastchange;)</para>
</abstract>


_______________________________________________
Svn mailing list
S...@list.worldhello.net
http://www.worldhello.net/mailman/listinfo/svn

Reply all
Reply to author
Forward
0 new messages