静态网站生成程序上站测试。 ohoh,还没取名字...

已完成功能:

  • cli生成post模板
  • 根据md文件生成对应的html文件
  • 根据目录生成整站html文件
  • 生成首页面index.html
  • 首页下部生成页码导航
  • 生成tag目录
  • 生成最新文章列表
  • 包含多说的ajax评论
  • 除多说的ajax评论不支持file://,其他页面均能用file://方式浏览.
  • 用Contango Theme做了一个默认模板。

wordpress转移方式

  1. 在wordpress中导入所有post到xml文件中
  2. hexo Pelican 二者都有对应工具,从xml中提取所有post为对应的.md格式文件。建议用hexo的工具,转换得更好一点。本程序支持这二者转换后的格式。
  3. md格式修正。主要是换行,代码块等,多加点空行。
  4. 生成全站静态html。

运行环境(Ubuntu on Virtualbox)

uname -a

Linux openerp7 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:32:08 UTC 2012 i686 i686 i686 GNU/Linux

cat /proc/cpuinfo

...
processor       : 3
vendor_id       : GenuineIntel
cpu family      : 6
model           : 58
model name      : Intel(R) Core(TM) i5-3210M CPU @ 2.50GHz
stepping        : 9
cpu MHz         : 2394.400
bogomips        : 4788.80

生成速度

 ls ./sources | wc
     59      59    1206

 time ./main.py build

real    0m0.390s
user    0m0.092s
sys     0m0.120s

如果按照这个速度不变,生成一万篇文章需时一分钟多点。

Tenjin是个好模板. (签名)

满足我喜欢的三个要求:

  • 快速
  • HTML友好
  • 能直接用python代码。

当然能直接用python代码是件好事也是件坏事。

在做静态html生成程序时,因为动态生成了不同内容的同名模板,导致Tenjin解析时总是取缓存中的内容。 Tenjin对1秒内生成的缓存文件总是做有效处理,这样解决办法为:

  1. sleep 1s吧,喝个茶什么的等缓存失效…
  2. 将Tenjin里的timestamp_interval参数由原1s,改为一个更小的值,0.001什么的。小手术。
  3. 给Tenjin添加个属性,记住文件大小,在文件大小改变时,总是重新生成缓存。大手术啊~~~~
  4. 动态生成的模板,别用同样的文件名.

1会带来时间浪费,测试中生成50+ html文件才半秒不到,不能浪费2倍的生命。 2,3都要改动Tenjin,通用性不好。 4算比较满意的,会稍提高点代码的复杂度。

BTW,如果要压榨性能,通过2中将值改大,或者3增加文件大小检查,模板文件不变时直接用.cache文件,应该有不少的性能提升。

连续碰到几次BLOG打开卡住的情形,在VPS上重启一下nginx及php就好了。原因不详,但有可能是因为wordpress连续升级导致?

最好的解决方案就是将博客网站静态化。

试用了一下现成的解决方案,比较好用的有hexo以及Pelican。 这二个都有工具能将wordpress导出的xml转化为md格式的文件。

其中hexo转化并生成静态网站后,效果相当不错。但问题是在使用时发现50+ md文件,生成时间在20s左右,这个速度太慢了一点。比较奇怪的是其他使用者都反应hexo是相当快的,所以也有可能是我这有个什么地方设置有问题。 同样的环境下Pelican的速度相当理想,同样多的md文件,生成时间3s左右。问题是他自己生成的md文件格式有点奇怪,和hexo的相比有差别,且感觉hexo的md文件格式更好点。

如果再考虑长远点,比如有海量的md文件要生成,那么就要求生成工具要么有极快的速度,要么有增量生成功能(已经生成的文件不用再生成)。这样hexo一者因为速度原因不能不放弃,二者可惜是node写的,我更偏好python一点。而pelican刚可能要修改一下格式问题,以及增加其他功能。

本着轮子不怕多的精神,干脆再做个相关工具好了。

初期目标

博客类小型网站,静态页面生成

生成方式

  1. 全静态生成,所有文件需要更新。可用目录控制生成层次。
  2. shtml包含,只更新必要文件
  3. ajax包含,只更新必要文件

工作方式

  1. cli
  2. web gui

文章分类(初期只考虑tag)

  1. 分类,一对一或一对多
  2. tag标记,一对多

页面分类

  1. index.html
  2. tags.html
  3. tag.html
  4. comment.html
  5. side_right.html
  6. side_left.html
  7. head.html
  8. body.html ->要生成的主体文件
  9. foot.html

菜单大体上分三层:顶层,侧边,子菜单 添加子菜单分为二种情况,一是添加全新的菜单,此时必须先添加顶层和侧边菜单,只用指定name及id,然后挂上子菜单. 其中顶层菜单不用指定parent,子菜单是必须指定action.

<menuitem id="top_menu" name="Top"/>
<menuitem id="section_top_menu" parent="top_menu" />
<menuitem id="sub_menu" parent="section_top_menu" action="your_action"/>

二是挂上已经存在的侧边菜单,此时parent的取值为:对象.菜单id

<menuitem id="real_menu" parent="name_of_module_of_parent.section_top_menu" action="your_action">;

不指定对象则会重复建立同名菜单(三层均如此),哪怕id值也相同。

1.不同的jquery upload插件,发送的字段有很大差别,可以通过打印wsgi_input来查看。

2.文件在比较小时,直接用web.input()取得上传的文件内容及其他相关值。官网例子在这种情况下能正常工作。

3.文件在很大时,web.input无法一次读写,此时可以用rawinput,一次读入一部分数据再写入. 原理上rawinput的数据应该是已经放在磁盘上,这样会有二次写入操作。但能够写入超过内存容量的数据。 此时有二种方法取得文件大小:一是客户端传入一个filesize字段,html5能取得上传文件的大小,IE不支持; 二是服务端用file.seek方法,取得rawinput.file的长度.

4.文件特别大且,不想二次写入时,可用wsgi_input,一边读取传入的数据,一边进行写入。但此时读到的是原始数据,会包含一些文件相关的信息,写入后要进行数据整形。可以客户端传入时,简化传入数据以方便整形。

大多数情况下, 可以采用方式3。 方式4最安全,服务端能根据情况随时中断传输。但没测试是否会阻塞后续页面请求。当然阻塞可以用其他方式解决(eg,协程等)。

R6300v2的dd-wrt已经有一个版本可用,但可惜wifi接入还是有问题,只好换回原厂固件。打算稍修改一下原厂固件,让它能自动运行usb设备上指定目录下的脚本,这样暂时没有好用的dd-wrt的时候,可以满足现有的大部分情况。

第一步,则是要先完成能用的编译环境,并能成功编译出能在R6300v2上运行的程序。因为常用ngrep,所以第一步则以编译能用的ngrep为目标.

R6300v2硬件参数

工具链是hndtools-arm-linux-2.6.36-uclibc-4.5.3,和R6250的一样,可以下载R6250的原代码,取得工具链。并顺便下载R6300的源代码备用.

主系统为ubuntu 12.04 32位,创建/projects/hnd/tools/linux目录,并解压R6250源码包中的hndtools-arm-linux-2.6.36-uclibc-4.5.3.tar到此目录。

将新编译工具目录放到PATH环境的最前面:

export PATH=/projects/hnd/tools/linux/hndtools-arm-linux-2.6.36-uclibc-4.5.3/bin:$PATH

下载libpcap-1.4.0.tar.gz及ngrep-1.45.tar并解压。

编译libpcap:

./configure CC=arm-uclibc-linux-2.6.36-gcc --host=arm-linux --with-pcap=linux && make

编译ngrep:

./configure CC=arm-uclibc-linux-2.6.36-gcc CXX=arm-uclibc-linux-2.6.36-g++ AR=arm-uclibc-linux-2.6.36-ar RANLIB=arm-uclibc-linux-2.6.36-ranlib LD=arm-uclibc-linux-2.6.36-ld  --prefix=/usr/local/arm/ngrep --host=arm-linux --build=arm --with-pcap-includes=../libpcap-1.4.0 && make

检查编译出来的文件:

file ngrep
ngrep: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped

开启R6300v2的telnet(R6300v2 ip为192.168.1.1) 下载telnetenable.py

python telnetenable.py 192.168.1.1 $(arp -n | awk "/192.168.1.1/"'  { gsub(/:/, "", $3); print toupper($3)}') Gearguy Geardog

出现"Sent telnet enable payload to '192.168.1.1:23'"则成功,否则多运行几次.

将ngrep copy到u盘,并在R6300上挂载,然后telnet到R6300v2,到/tmp/mnt/usb0/part1下找到ngrep并运行之。

./ngrep -V
ngrep: V1.45, $Revision: 1.93 $

北京联通的临时提速100M,每月20小时左右。 

提速前:

其实在提速前,已经比刚安装的速度稍好了一点,主要是上传多给了一点点。 提速后,明显上传加了很多,不过下载速度没快多少,最主要原因是加在前面的路由器性能不行。

换了个新路由测试提速后:

update 2025: 图丢失啦。

有台iphone 5莫名可用容量急剧减少,查看可用容易,估计有大约4~7G容量不见。 ssh到iphone,du -k查看并查找最占容间的前50个目录,发现明显 mobile/Library/Caches/com.apple.passd/com.apple.Shoebox 目录有问题,占用空量4G+,删除之,能释放近6G容量。 另外照片流也会占用不少容量。

附前50条记录:

"bytes";"dir";"id"
10291118;"mobile";1458101
5041749;"mobile/Library";1454199
4542087;"mobile/Library/Caches";1450783
4447000;"mobile/Library/Caches/com.apple.passd";1450713
4442425;"mobile/Library/Caches/com.apple.passd/com.apple.Shoebox";1450711
3070707;"mobile/Applications";664860
2178545;"mobile/Media";1458099
971237;"mobile/Media/DCIM";1454440
970566;"mobile/Media/DCIM/100APPLE";1454439
660713;"mobile/Media/PhotoStreamsData/1330973174";1458010
660713;"mobile/Media/PhotoStreamsData";1458011
638525;"mobile/Media/PhotoStreamsData/1330973174/100APPLE";1457952
544488;"mobile/Media/PhotoData";1455066
403330;"mobile/Media/PhotoData/Sync";1455058
403251;"mobile/Media/PhotoData/Sync/100SYNCD";1455056
351152;"stash";1468737
313584;"mobile/Applications/68C74FC1-8A0C-4369-8E86-4E599335F7EC";589987
254071;"mobile/Applications/68C74FC1-8A0C-4369-8E86-4E599335F7EC/Library";589955
254069;"mobile/Applications/68C74FC1-8A0C-4369-8E86-4E599335F7EC/Library/Application Support/No_Backup";589947
254069;"mobile/Applications/68C74FC1-8A0C-4369-8E86-4E599335F7EC/Library/Application Support";589948
204621;"mobile/Media/DCIM/100APPLE/IMG_0199.mov";1454398
181566;"mobile/Library/VoiceServices/Assets/zh-CN";1453650
181566;"mobile/Library/VoiceServices/Assets";1453651
181566;"mobile/Library/VoiceServices";1453652
143007;"mobile/Library/Mail";1452332
142401;"stash/share.VNy9as";1468736
140309;"stash/Applications.50zavX";1466111
139514;"mobile/Library/VoiceServices/Assets/zh-CN/synth_ting-ting_full_155mrf22_270_06.dat";1453645
134015;"mobile/Media/PhotoData/Thumbnails";1455062
131209;"mobile/Applications/68C74FC1-8A0C-4369-8E86-4E599335F7EC/Library/Application Support/No_Backup/iphone";589920
131208;"mobile/Applications/68C74FC1-8A0C-4369-8E86-4E599335F7EC/Library/Application Support/No_Backup/iphone/1.0.226789.rsb";589919
129490;"mobile/Applications/06E1377D-3D25-4736-96B7-287255AC8DC3";556778
129399;"mobile/Applications/06E1377D-3D25-4736-96B7-287255AC8DC3/VoiceGuideAll.app";556774
128167;"mobile/Media/DCIM/100APPLE/IMG_0223.MOV";1454419
122421;"mobile/Applications/68C74FC1-8A0C-4369-8E86-4E599335F7EC/Library/Application Support/No_Backup/ipad2";589918
122420;"mobile/Applications/68C74FC1-8A0C-4369-8E86-4E599335F7EC/Library/Application Support/No_Backup/ipad2/1.0.226789.rsb";589917
116232;"mobile/Applications/F32D96FF-8020-4BFE-BF3A-C22B7F4E6EF6";660087
116131;"mobile/Applications/F32D96FF-8020-4BFE-BF3A-C22B7F4E6EF6/PvZ-iPhone_ZH.app";660084
114695;"mobile/Applications/9ADE3F3B-D880-4918-A565-09B879094997";617869
110752;"mobile/Applications/06E1377D-3D25-4736-96B7-287255AC8DC3/VoiceGuideAll.app/data";556488
105033;"mobile/Applications/F8F8FE94-CA5A-4272-92C4-276948EE1706";663324
105029;"mobile/Applications/F8F8FE94-CA5A-4272-92C4-276948EE1706/AR.Rescue.app";663310
99381;"mobile/Applications/0CCB1B6C-9EE9-4F4B-852F-1ED0C26113C2";558084
99379;"mobile/Applications/0CCB1B6C-9EE9-4F4B-852F-1ED0C26113C2/MerriamWebster.app";558081
97250;"root";1458263
94877;"root/Library";1458252
94852;"root/Library/Caches";1458221
94550;"mobile/Media/DCIM/100APPLE/IMG_0172.mov";1454373
89964;"mobile/Applications/0CCB1B6C-9EE9-4F4B-852F-1ED0C26113C2/MerriamWebster.app/definitions.db";557980
89116;"mobile/Library/Mail/ExchangeActiveSync979797EC-C70C-4940-9076-2BA004C4C5DD";1451893