blog mail me! feed

Archive for Program

实现Github的代码仓库权限控制.

Github这个social coding的代码托管网站风骚得总有让人push, 攒蓝条的冲动.
以上是题外话.

最近回头去, 把以前断断续续没写完的Project gitar(web端的多用户仓库管理界面)继续拾起来开发,
也遇到了些问题: 比如, 如何实现github那样的, 对用户的公共仓库进行权限控制,
今天仔细翻了翻sshd和git的文档, 终于找到了一个解决方法.

[1] 修改sshd_config, 将PermitUserEnvironment设置为yes, 以保证能够在authorized_keys文件中, 对环境变量进行设置.

[2] 对于每个用户提交的RSA公钥, 在其

ssh-rsa AA….== foo@bar

的前面, 加上

environment=”GITAR_USER=username”

这样用户通过了公钥认证后, 当前的session的环境变量中, 即保存了用户的gitar用户名.

[3] 使用git hooks, 匹配环境变量 $GIT_DIR 路径中所包含的用户名信息, 和$GITAR_USER 中的当前用户名,
用户名不匹配时, 即通过产生不为0的exit code, 终止远端的push操作.

[4] 当然Github中还可以添加collaborators, 也可以对特定仓库添加public keys, 可以通过扩充用户session的环境变量来实现目的.
或者, 也可以使用shell脚本调用一个python脚本, 将 $GITAR_USER 的值与数据库中的collaborators进行比对.

X-Accel-Redirect的一点教训.

栋力博客使用的是wpmu, 不过版本比较低了, 因此wp-content/blogs.php中还没有用X-Sendfile或者X-Accel-Redirect头来处理静态文件的代码.
于是乎, 很久以前做了一个基于nginx和X-Accel-Redirect的hack,  不过今天bluef提醒我说静态文件的Content-Type有问题,
回头去看了下NginxXSendfile模块的文档, 才发现里面提到:

You should also know that the following headers aren’t modified by nginx:

Content-Type
Content-Disposition
Accept-Ranges
Set-Cookie
Cache-Control
Expires

于是把wpmu原来的处理mimetype的函数加了回去.

当然, wpmu 2.9.1.1的这个blogs.php已经很完善了, 可以直接通过配置, 支持X-Sendfile, X-Accel-Redirect头的同时, 也有了较好的缓存控制.
改天有空可以考虑把栋力博客迁移到新版本上去, 最担心的还是栋力博客启用的大量自定义插件的兼容性问题.

公交路线–>KML

如图, TG的漂移立功了...

如图, TG的漂移立功了...

下午坐82路回家, 看到一站”新南门”, 但是实在难以揣测这个站点是在府南河的哪一头, 为了避免少走弯路, 提前在滨江路下车了.
车还在浆洗街的时候, 摸出手机, 打开Google Maps看了看, 最后发现无法显示具体的公交线路图, 作罢.
回家后有点无聊, 就动手自己写了一个.

这个API的一个示例: http://tremblefrog.org/bus.php?lane=56

56是公交线路编号, 嗯, 这个URL里面没有城市.
设计得比较山寨, 只能支持成都的公交查询.
打算明天扩充一下功能, 顺便加一个URL Rewrite.

关于这个API怎么用:
你可以直接在(手机)浏览器中访问这个地址, 即会得到一个生成好的KML文件.
与KML关联的程序(Google Maps, Google Earth)可以直接打开.
你也可以在手机版的Google Maps中使用”搜索”功能, 搜索这个URL, 不一会儿就会看到结果显示了.

已知的bug: 地图漂移. TG的这个政策太恶心了.
你要知道, 我做这个web service的初衷是因为不知道公交站具体位置在哪里,
现在漂移了一条街, 这个破玩意儿还有毛用.

*UPDATE*
感谢来自dongmeng110的研究, 现在已经加入了偏移补偿, 可以正常显示了 :)
(maps.google.com的卫星图显示因为本身没有偏移, 补偿后反而会有偏移 -.-)

Read the rest of this entry »

把Nodebox的Graph库移植到了Shoebot

Nodebox强大之处在于, 有无数第三方的扩展库, 可以快速的实现数据处理和可视化.
Graph就是一个很方便的用于图论可视化的扩展库.

不过Nodebox是Mac-only的(基于Cocoa), Shoebot是其基于GTK+和Cairo的移植.
断断续续花了两天时间把graph库移植到了shoebot下, 一些诡异的细节问题折磨了我n久.

经过了对原graph库的一些hack, 现在基本上可以正常的跑起来了.
除去对graph库的hack外, 我也改了不少shoebot的源码,
一方面是使得shoebot的命令调用更兼容Nodebox, 一方面是移植了部分Nodebox更新后, shoebot还没有移植的功能.

先放一张example图, 改天把源码再仔细检查下, 就放到github上去.graph_ex1

keywords visualization.

忘了最早哪儿看到的了, 去年用AS3写了一个,
不过我的AS3实在是烂.

今天est大神提到了这个, 我就顺便用shoebot重写了一次.
分词使用的pymmseg, 不过缺点是分词后不会有词性, 这样就无法通过词性筛掉一部分出现频率高但是实际上重要性不大的词.

胡core讲话
如图是胡core在十七大上的讲话, 当然太长了, 我只用了新华社稿子的前两页.
(社会主义果然无比强大啊!)

几点总结:
1. shoebot的确很好用, 或者应该说nodebox真的很好用 -__-!
2. 关于文字排布, 最简单的方法往往是最简单的.

接下来准备把这个东西继续完善下,
1. 做一个HTTP的服务, 免得只能在本机跑很无趣.
2. 做一点语义元素上的挖掘, 我倒是想看看单词在给定距离下的邻接性会不会有什么有趣的东西… 比如根据单词的邻接图绘制最小生成树?
3. 有空了打算做个cluster, 说不定也是一个有趣的结果.

SVM, CAPTCHA, hack

无聊得蛋痛, 想起了电子科大附属幼儿园”门户”的那个CAPTCHA.
前几周帮导师准备支持向量机的上机实验的时候, 正好看到一个用svm识别手写阿拉伯数字的数据库.
简单来说, 手写数字的图形被缩放为16×16的二值图像最后转化为256参数的多元分类问题,
考虑到上面这个阿拉伯数字数据库不错的交叉检验准确率, 我也就顺便拿来做”门户”的CAPTCHA识别了.

写了个脚本拖了100+个验证码样本回来, 仔细看了下,
虽然这个第二版山寨门户的CAPTCHA比第一版的CAPTCHA有了不少的进步(第一版的数字无比规则以至于可以直接写一个Greasemonkey脚本用canvas来识别),
但是总体上还是比较好识别的, 统一是二值图片, 字符间有清晰的间隙(除了有一张图有一点毛刺外),
只是图片加上了一些简单的几何变换.

CAPTCHA sample

上面是一个CAPTCHA的例子。
考虑到几何变换对字符产生的形变所造成的相同字符间差异,还没有手写阿拉伯数字样本间的差异大,
我就没做任何校正处理直接把字符切割了送去做训练和识别了.
通过识别各个字符的最大边界, 将四个字符分割出来, 统一复制到60×60的一块空画布上,
最后缩放到15×15, 转化为标准的二值 bitmap, 最后输出为libsvm的标准格式.

训练集我一共下载了124张CAPTCHA图片, 也就是496个字符的samples,
用libsvm对训练集做了5重的Cross-Validation, 自检验准确率: 97.1311% (Radial Basis核).
*EDIT* 又用线性核做了一次, 可以跑到98.1557%

总的来说, 支持向量机识别这个轻微几何变形的CAPTCHA还是有相当高的准确率的.
最后感谢无比handy的PIL以及Python,
这让我突然想起了用C/CPP写酵母基因预测程序时候的繁琐和折磨.

最后的最后, 我也不知道把这个CAPTCHA hack了有什么实质性的用处,
电子科大附属幼儿园门户系统如此山寨, 以至于从上一版本到现在的版本,
都可以绕过CAPTCHA直接提交信息进行认证,
回扣万岁!!

附简化原理图一张:
CAPTCHA DEMO

豆瓣-电子科大图书馆馆藏查询的GM脚本更新了.

豆瓣图书解决了图书的版本问题后, 豆瓣图书可以被用户进行归类了.
比如, 你可以通过王小波的<黄金时代>找到其对应的<时代三部曲>,
也可以找到<黄金时代>的不同发行版本.

考虑到:

  1. 不同版本的书图书馆一般只买一本
  2. 肯定有怪叔叔怪姐姐想查询一个系列的所有书目

今天更新了豆瓣-电子科大图书馆馆藏查询的GreaseMonkey脚本,
新功能我就不累赘的描述了, 因为要费很多口舌而我急着填饱肚子,
请看以下截图(点击看大图):

×EDIT× 有人说没有感觉出来任何差别, 这里要说的新版本只更新了对于图书丛书和不同图书版本的页面,
在每本具体图书的页面没有做任何的改变, 因为如果每本书自动查询一次图书馆馆藏的话, API请求会超过限制.

对于单独的图书条目, 请点击右边的”馆藏查询”就行了. Read the rest of this entry »

A practical guide to SVM classification.

今天早上起来寻思着是不是还可以对SVM的准确率再挖掘下,
就上libsvm的网站看了看, 本来是想了解下各个参数的意义和各种kernel function的区别的.
正好看到这篇libsvm作者写的: A practical guide to SVM classification

写得很不错, 看了以后就发现文章把我使用中的N个错误都指出来了 (一皿一).
简单来说, 还需要改进的地方就是:
1. 对data-set进行scale的时候, 要保存训练集的scale数据, 以对test set进行等比例的缩放.
2. 通过一个grid-search找到最优的C和gamma值组合.

看来我得把我的程序重新大动手术一番,
凄惨的是还得加上一个grid-search的程序段.
为了尽快出结果, 我还是直接偷懒用工具包好了, 否则改代码会严重拖后腿滴.

豆瓣-图书馆馆藏信息Mashup.

今天回家, 突然想起某逆飞JR给我提过的在豆瓣对应页面显示图书馆馆藏信息的事情了.
正好图书馆系统(不得不说, 新系统和川大那个图书馆系统比起来, 还是垃圾)上线了, 就折腾了漫长的一段时候后, 弄出来了.

可以在这里访问到这个脚本: http://tremblefrog.org/libdb/
目前我还没有把它改成一个GreaseMonkey脚本, 不过本身是很简单的事情.
在豆瓣任意一本书的界面, 运行脚本就可以看到一个小窗口显示的豆瓣藏书信息了.

Screenshot

"Screenshot"

我校图书馆特立独行, 有的书储存的ISBN10, 有的书储存的ISBN13, 这逼得我必须去调用豆瓣的API,
在此要愤慨的凸一下图书馆信息的混乱.

不过新图书馆系统总的来说, 速度上总算有了点指数级的提升, 使得这个脚本不会像蜗牛一样慢.
当然现在功能还很简单了, 比如信息是按照ISBN对应查找的, 所以可能不同版次的图书, 还有不同出版社的图书, 尽管同名, 但是会显示没有.
我也正在考虑在搜索页面也加上这个脚本, 然后用Python多线程去并行的抓取图书馆的数据.

因为Javascript的安全性的问题, 搞得本来想在Javascript实现的很多东西, 基本都扔到PHP里实现去了.
之所以用PHP没用Python是因为偷懒, 服务器上的nginx的mod_wsgi模块没有装 -.-#
谢谢汪峰童鞋的歌陪伴了俺敲代码和调试的2个小时.

改天把API的计数器加上, 再把搜索页面的查询完成了,
就把源代码也一并扔出来.
有人想改进它再好不过了, 反正我未来一年也基本不会怎么借图书馆的书了.
>.<

最后很无奈的说一句: 用了这个系统才知道学校图书馆的图书资源多么的稀少
尤其是人文类的, 唉, 工科学校嘛, 认了, 其实反正我也不看人文社科书, 哈哈.

关于web.py的一点笔记.

最近在试图用web.py这个轻量级框架写个网站,
实现的时候把每个页面的controller单独成module, 放在ctrls目录下,
接下来就发现了问题: 各个module和main module之间没法传递变量,
因此session, database, template render都没法在全局共享, 糟糕的问题.

问题的来源很简单:
web.py把request这一块完全托管了, 由其来初始化各个controller的类,
因此没法通过初始化函数传递我需要的变量进去.

今天仔细钻研了下才发现是我Python太菜的缘故,
其实用setattr()就可以把需要的变量传递给对应的类/模块了.

以下是一个实现的sample:

*UPDATE* 另外一个实现里我把所有模块都在load_controller()函数里通过__import__动态加载, 再通过globals()[CTRL_NAME] = CTRL_CLS 来实现, 这样可以省去前面的无数 from xxx import xxx

Read the rest of this entry »

Next entries »