11
6
2010
2

privoxy与火狐智能地址栏两者兼得

privoxy是一款强大的代理调度器,看到muzuiget同学的介绍我就心动了,由于比较忙所以前两天才开始尝试,很快就发现了一个问题:直接在火狐地址栏里输入关键字会转到privoxy的“找不到域名”的错误页。

依我的推测,火狐总是尝试解析用户在地址栏输入的字符串,当解析失败时就尝试添加.com这样的后缀,然后尝试向Google查询,或者返回一个最接近的结果,或者返回Google搜索页面。(所以,我非常讨厌垃圾电信的114广告,使得任何原本不能解析的域名都解析到它的广告页了。)

在使用HTTP代理之后,火狐无法得知域名解析是否成功,因为代理在出错时返回了出错页面。这让我这个重试依赖她的地址栏的火狐迷郁闷了一天,最终(部分地)解决了此问题。

privoxy果然强大,出错页都是可以自定义的,默认这些模板在配置目录的templates目录下,很容易猜到处理域名解析失败的文件是no-such-domain。于是我在改了下其外观的同时,先是加上搜索功能:

<p>
    This is often a temporary failure, so you might just
    <a href="@protocol@@hostport@@path@">try again</a>,
    or <a href="https://encrypted.google.com/search?hl=zh-CN&q=@hostport@">Google @host@</a>.
</p>

这样还不行,不光得点一下,而且只能跳转到Google的搜索页。想到Google有个“手气不错”按钮,于是利用之:

var abar = function(){
  if(document.referrer) return;
  var host = "@host@";
  if(host.indexOf('.')<0 || host.indexOf(' ')>-1){
    document.title = "跳转中...";
    window.location = "https://encrypted.google.com/search?hl=zh-CN&q="+host+"&btnI=1";
  }
};
abar();

将这段代码加到<head>后即可实现输入关键字后自动使用Google的“手气不错”服务跳转到接近的页面,或者是Google搜索页面。

但测试几次后发现,这样还有问题:如果输入中文,将搜索其punycode而不是中文了。比如在地址栏输入“测试”,回车之后会搜索“xn--0zwm56d”,进而跳转到http://www.iana.org/domains/root/db/xn--0zwm56d.html。看来需要用Javascript解punycode了。Google下,在stackoverflow看到了一个实现,还是放弃版权的~只是我没发现怎么才能让privoxy的错误页调用本地的外部Javascript文件,所以直接把代码嵌进去了,这让我这个喜欢代码整洁的人有点不爽。。。

var abar = function(){
  if(document.referrer) return;
  var host = punycode.ToUnicode("@host@");
  if(host.indexOf('.')<0 || host.indexOf(' ')>-1){
    document.title = "跳转中...";
    window.location = "https://encrypted.google.com/search?hl=zh-CN&q="+host+"&btnI=1";
  }
};
abar();

按说这样的设计是跨浏览器的,于是我测试了下Google Chrome,发现其并不买帐,输入看起来不像域名的字符串后,Chrome直接进到搜索页面。。。。还是火狐好啊~~

Category: 火狐 | Tags: javascript 火狐 privoxy
10
29
2010
7

金山快盘之跨平台同步脚本

金山快盘是和Dropbox差不多的同步服务,区别只是快盘(目前)只支持Windows,容量只有2G多(我的Dropbox都4G多了~),安全性不好(网页版的使用不加密的HTTP协议)、同步文件夹被设为系统属性等等。

由于某些原因,同学和我通过金山快盘分享文件。于是开始研究之。客户端上传下载时使用XML格式,但数据都加密过了,无解。于是转攻网页版。基本上都是很简单的json,上传使用了个Flash,用Wireshark抓包一看还是HTTP POST。

于是ksync诞生了,仅支持从服务器到本机的单向共享文件同步。如有其它需求可自行扩展。本程序仅需要Python3支持,目前仅在Ubuntu Linux上测试通过。

下载链接。使用前记得编辑ksync文件,把自己的用户名、cookie文件存放路径、同步目标路径替换掉。

Category: python | Tags: linux python json
10
24
2010
4

把Parted Magic装到移动硬盘

首先,不知道Parted Magic为何物的童鞋请先移步这里

之前折腾了Gparted live,然后看到了muzuiget童鞋的留言,决定有时间还是折腾下。首先去官网,结果官网说

As of Parted Magic version 5.3 the USB zip has been discontinued. We are only supporting Unetbootin as the method for booting Parted Magic from a USB drive.

Note: If you still want to do it manually, extract the files from the ISO image and execute the syslinux commands. If you know what you are doing this shouldn't be an issue.

好吧,我在看到第一段,在失望之余,“note”到了后面那段。

fuseiso ~/dl/pmagic-5.5.iso pm

我不喜欢需要根用户权限的mount,所以有一天在新立得里翻到了这个fuseiso,现在用上了。

里边就两个目录,boot和pmagic。pmagic比较简单,先说说它。

它下面也就三项,内核bzImage,initrd文件initramfs,和一个可以用来自定义其模块的目录pmodules,目前只包含pmagic-5.5.sqfs,file之可以知道它是一个Squashfs filesystem。

boot下东西有点多,还好我需要的很少,就是boot/isolinux/isolinux.cfg这个isolinux的配置文件了,里面有需要传给内核的参数,有好几个选项,基本上是这样子的:

LINUX /pmagic/bzImage
INITRD /pmagic/initramfs
APPEND edd=off noapic load_ramdisk=1 prompt_ramdisk=0 rw vga=788 loglevel=0 max_loop=256

APPEND那行就是内核的参数了。于是,grub2的参数应该这么写:

menuentry "Parted Magic (中文)" {
	set root="(hd1,1)"
	echo "Loading kernel..."
	linux /boot/pmagic/bzImage edd=off noapic load_ramdisk=1 prompt_ramdisk=0 rw vga=791 loglevel=0 max_loop=256 keymap=us zh_CN
	echo "Loading initrd..."
	initrd /boot/pmagic/initramfs
}

vga参数我自然要改下的,呵呵。

但是——

内核加载完毕之后它就告诉我找不到pmagic-5.5.sqfs文件……看来需要把它放到分区的/pmagic/pmodules下才行啊。可是我又不是做LiveUSB,是移动硬盘耶,不可能随随便便就把整个分区弄乱的。

于是——

file一下那个initramfs可知它是gzip压缩过的。

zcat initramfs > ../../initrd

然后继续file之,cpio文件。那就继续解包吧:

cat initrd|cpio -i

其实两步是可以一起做的。但没有file以及man cpio之前谁知道呢。

然后我很惊奇地看到一个名为init的可执行文件躺在当前目录下!我都没file,直接把它扔给Vim了。接下来就是看shell脚本了。

find_pmagic () {

   if [ ! -e /test_mnt/${directory}/pmagic/pmodules/pmagic-$VERSION.sqfs ]; then
      umount /test_mnt &> /dev/null
      return
   fi

关键是${directory}变量。继续寻找。。。

for i in $(cat /proc/cmdline); do
   case $i in
      directory=*)     directory=$(get_opt $i) ;;
      iso_location=*)  iso_location=$(get_opt $i)  ;;
      iso_filename=*)  ISO_VERSION=$(get_opt $i) ;;
      root=*)          root=$(get_opt $i)  ;;
      label=*)         label=$(get_opt $i)  ;;
      uuid=*)          uuid=$(get_opt $i) ;;
   esac
done

OK,原来是内核参数,于是在linux那行后面再加上directory=other,重启OK!

10
21
2010
6

Python HTTP 请求时对重定向中的 cookie 的处理

首先说明一下,我使用的是 Python3 的 urllib,但 Python2.x 同理(使用 urllib2)。

想用脚本去登录一个网站。和很多网站一样,该网站使用 cookie 来保存会话信息。这个我以前是自己提取 response 中的 Set-Cookie 头来处理的。这次本想如法炮制,却发现没保存需要的 cookie,所以登录失败。

很郁闷地想了半天,最后出去 wireshark 抓包,终于发现原来重要的 cookie 在登录后的应答中,但这个应答是个 302 重定向,所以 urllib 默认的 opener (urllib.request.urlopen)直接就跟从这个重定向了,没有对 cookie 进行任何处理。

我首先想到的是,不要跟从重定向。我看到有个 HTTPRedirectHandler,但文档里没写它怎么用。郁闷……自己找到 request.py 文件看源代码,折腾了好久无果,遂想到 Google (早该想到了。。。)于是找到了 StackOverflow 上。有两个解决办法:要么不跟从重定向,要么弄个 HTTPCookieProcessor 保存 cookie 信息。看我自己的需求,当然选后者了。而且,那个回答问题的人也没有给出如何不让它跟从重定向(所给代码只是在重定向前对 cookie 进行处理而已)。

于是,我再一次地打开了 http.cookiejar 的文档,尝试弄明白这东西到底怎么用。当初折腾 cookie 的时候,没弄明白这个,所以才自己处理的。

看 request.py 里的代码,这个 CookieJar 用起来相当不错:

class HTTPCookieProcessor(BaseHandler):
    def __init__(self, cookiejar=None):
        import http.cookiejar
        if cookiejar is None:
            cookiejar = http.cookiejar.CookieJar()
        self.cookiejar = cookiejar

    def http_request(self, request):
        self.cookiejar.add_cookie_header(request)
        return request

    def http_response(self, request, response):
        self.cookiejar.extract_cookies(response, request)
        return response

    https_request = http_request
    https_response = http_response

不过我需要将 cookie 信息保存到文件。从文档上看到有个 FileCookieJar。我尝试了下,出错了,没有 _really_load 方法,我晕。。。之后才注意到其源代码开头有个ASCII图:

						CookieJar____
                        /     \      \
            FileCookieJar      \      \
             /    |   \         \      \
 MozillaCookieJar | LWPCookieJar \      \
                  |               |      \
                  |   ---MSIEBase |       \
                  |  /      |     |        \
                  | /   MSIEDBCookieJar BSDDBCookieJar
                  |/
               MSIECookieJar

原来具体实现还在子类啊。好吧,我就用 MozillaCookieJar 好了。

用法很简单,初始化时把文件名传给它,载入用 load(),保存用 save()。不过要注意的是,文件不存在时不能载入,touch 个空文件出来也不行的。

另外,那个 StackOverflow 的页面还提到了 mechanize 这个模块,有时间去尝试下 :-)

最后,如果我不要它重定向该怎么做呢?难道非要我去用更底层的 http.client?

Category: python | Tags: python 网络
10
15
2010
2

wget 默认文件名附加URL查询部分的去除

拿wget下文件,它总是把URL的查询部分(?q=test这种)附加到默认的文件名后,让人十分不爽。查了man手册,也Google过,结论是没有办法解决。虽说拿shell写个脚本在下载完之后把这种尾巴也不难,但总觉得应该从根本上解决问题。于是就hack源码了。

要改的地方其实很好找,在url.c的第1556行附近:

/* Append "?query" to the file name. */
  u_query = u->query && *u->query ? u->query : NULL;
  if (u_query)
    {
      append_char (FN_QUERY_SEP, &fnres);
      append_uri_pathel (u_query, u_query + strlen (u_query), true, &fnres);
    }

把这几行注释掉,然后重新编译就可以了。不需要安装,可以直接覆盖掉系统的wget,但不推荐,因为更新后就没了。我是把它放到~/bin下。这个目录在我的$PATH变量的前面,所以会优先使用这里的wget。

Category: Linux | Tags: wget C代码
10
14
2010
2

QQ群邮件:美好生活路上的又一障碍

如果能够不用QQ,生活会变得美好。可现实是,我不仅不得不使用QQ,而且还得使用腾讯烂得要命的群邮件服务。

QQ邮箱又挂掉了

WebQQ不知从什么时候开始不再提示新(群)邮件了。由于我们课件什么的都只知道往群邮件里发,我只好每隔几天去查收一次,不然所谓的“超大附件”会过期的。

说起“超大附件”我觉得好笑。现在都什么年代了,我网易邮箱现在6G的存储空间,附件大小可达50M,其它邮箱附件也至少可以20M。我还以为“超大附件”有几百M呢,原来才超过5M就是“超大”了。为什么腾讯不设置成1.44M的限制呢?

看到群邮箱里有不少课件,一个个手动下吧。很快就下好了,结果双击一个PPT,却是用OpenOffice Write打开的,还是空白页面。。。。我还没弄明白出什么事了,到虚拟机的XP里用MS Office打开,结果是“无法打开xxx所代表的文件类型”(微软的用词一向很怪异,我就不追究了)。再试试那些rar文件,也出错。这才注意到文件的大小不对。

OK,算我网络不行,那重新下吧。结果回邮箱里就遇到上面截图里的情况了。。。

这不是我第一次遇到,也不是第二次。我相信也不会是最后一次

唉,难道这就是劣币驱逐良币

PS: wget rocks!

Category: 未分类 | Tags: QQ 腾讯
10
7
2010
3

grub2不显示自定义菜单项的解决

今天弄gparted的live版,在虚拟机里按照这里的说明配置grub2,却始终不见自己新加的菜单项,只好每次尝试启动gparted时手动输入那一串长长的指令,郁闷啊。。。

Google了半天,用中文只能找到些grub2的配置说明的文章,而且代码十分地不整洁,光看到页面鼠标就不由自主地中键点击标签页标题了。于是换用英文,搜索“grub2 menuentry not display”,也没什么有针对性的结果,于是我点了第一项,是Ubuntu的文档。看了一小会儿后,终于有了重大发现——

  • Do not leave empty spaces at the end of lines

再看看自己复制过来的配置,果然在最后一个}后多了一个空格!

但我还是有点纳闷:为什么行末多了一个空格就不行了呢?也没有错误或警告。。。

Category: Linux | Tags: linux grub
9
30
2010
12

colorpicker: 给 Vim 加一个调色板!

作为一名一直喜欢写网页前端的vimmer,自然会使用Vim来编写CSS了。但是,CSS中经常需要调色。虽然相继有一些工具的出现(见可视化的配置Vim(gVim)配色-colorsel.vim),但一直不太理想。编辑CSS的颜色,不仅需要细致的调色,而且需要方便修改,并且支持从屏幕取色是最好不过了!

既然没有现成的,而自己不管怎么说已经入了GTK的门,就自己写了一个简单的工具。本来有个叫gcolor2的调色/取色工具的,可惜它不支持把取到的颜色输出到标准输出,或者任何其它可被其它程序调用的地方(难道这只是某个大牛闲着没事做时写着玩儿的 :-P)。所以,colorpicker与之类似,只有一个标准的GTK调色板。重要的不同之处在于:它可以和其它程序交互。

还是先放个图吧:

就是这样。从图中可以看到,这个标准的调色板除了支持RGB值,还支持HSV,而后者非常适合对色彩进行微调,不像RGB那样只有机器能够理解。左下角有之前颜色和当前颜色的显示(截图时没注意,都是白色。。。)。之前颜色是可以从命令行设置的,这个很有用(请往下看)。也有取色器,在Linux下是可以取到屏幕上任何一点的颜色的。但根据我使用GIMP的经验,好像在Windows上只能取到本程序的颜色。另外还可以看到,图中显示了“透明度”一项。关注Web前端的童鞋都知道,CSS3支持半透明色彩了,所以,本程序也支持输出rgba(79, 0, 159, 0.51)这样的颜色值。

关于程序自身的介绍就到这儿。下面是在Vim里使用的截图:

我需要输入一个颜色值,于是按了我自己定义的Alt-C键,colorpicker启动了。因为是新颜色,加之之前我没使用过,所以“之前颜色”那里显示的是默认的白色。

颜色已经输入了,但我想换一个颜色,怎么办呢?在普通模式下按cac(change a color)就可以了,“之前颜色”会被置为待修改的颜色,方便进行微调。


PS: 在图中可以看到CSS中的颜色值下方背景被高亮成了相应的颜色。这是使用css.vim实现的。

PS2: 这里演示的是修改CSS文件,但实际上是和文件类型无关的。你可以将它用于任何你想用的文件中。

PS3: colorpicker是独立的GTK程序,所以不一定非要和Vim配合工作啦。Emacs什么的一样可以调用,只要有人写出调用代码。

PS4: 程序在哪里下载呢?请移步我的陈列室。Vim调用部分的代码尚未整理,在我的vimrc中,搜索colorpicker就可以了(共两个函数,截图中可以看到函数名。目前(2010年9月30日)它们处于我的vimrc的前50行内)。


2011年4月9日更新

这里 jiazhoulvke 提供了编译好的 Windows 版程序(以及分离出来的 Vim 配置),当然GTK Runtime 环境还是得装,而且还可能遭遇著名的DLL Hell(如果不幸地出现了,那么请把出问题的 DLL 文件从 GTK 的 bin 目录复制到 colorpicker.exe 所在的目录中)。

2014年11月8日更新:

颜色值的高亮显示可以使用 colorizer 插件了哦~

Category: Vim | Tags: gtk css vim C代码
9
28
2010
2

Vim73之ruby $curbuf.number恒为零问题终于解决了!

上回说到Vim7.3在种种优点背后隐藏着种种bug,今天,其中之一终于被解决了!

Command-T 的作者在 vim_use 上的bug报告贴无人回应之后若干天,又在 vim_dev 上发了贴,今天终于有人回应了,指出configure时加上--disable-largefile选项此bug就消失了。我于是迅速地重新编译了下,果然OK了!

Category: Vim | Tags: vim ruby
9
16
2010
9

Vim的hidden选项真是好东西!

我在编辑一些HTML文件。写得觉得差不多了,浏览器里看过还不满足,竟然想到去W3C验证一下。这一验证,差点出大事了!

因为需要使用程序来处理,所以这些HTML文档全部都是合格的XML文件,所以我给它们加上了<?xml version="1.0" encoding="UTF-8"?>。但W3C却告诉我HTML里不能写这个。好吧,我把它们都删掉:

sed -i '/<\?/d'  *.html

我想的是,凡是有<?的行全部删掉。命令执行完后忽然有点不好的感觉,于是ll一下,结果看到了一堆长度为0的HTML文件!我愣了一下,随即欲哭无泪!虽然这些文件在SVN里,但是自我这次开始编辑后我就没提交过!sed也是危险的命令啊!

我只想到火狐里还保留着改动最多的一个页面,赶紧先把它的源代码复制出来。直接“查看源代码”还不管用,因为本地文件是没有缓存的,查看时火狐会去磁盘上找文件。于是打开Firebug,在<html>元素上点右键,复制HTML,然后手工整理。剩下的文件没办法,只有SVN和Vim的*~备份文件了,555……

好吧,我认命。于是我在Vim里打开另一个文件,想趁着还记得改了些什么赶紧重做一遍,却意外地发现打开的文件显示着我sed之前的内容。来不及多想,我赶紧:w保存了,然后想了下,才恍然大悟——

我现在习惯于一直开着一个GVim实例,而又经常只是挂起或者休眠,几天才shutdown一次,所以经常会有100多个buffer。虽然我通常是把hidden选项关闭的,但有时候为方便切换buffer,会去se hidden一下,然后一直忘记再设置回来。这次,不记得什么时候设置了hidden选项,于是,那些被我关闭的buffer都还在内存里!终于知道了hidden在文件已保存的情况下有什么重要作用了!怀着对Vim的感激,我在buffer找到了所有被sed误删的文本,泪流满面~~


2011年3月17日更新:

现在才知道,sed 原来是支持备份的,只要告诉它备份文件的后缀就行了,像这样-i~

另外,Perl 也支持类似的操作,但用的是PCRE,功能强大许多我也熟悉许多。用法是

perl -pin -e 'print /regex/' #相当于 sed -i '/regex/d'
perl -pi -e 's/regex/replacement/g' #相当于 sed -i 's/regex/replacement/g'

 

Category: Vim | Tags: vim 失误 perl sed

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com