详细的更新请到google code 查看。
- get_info()函数参数处理who遗失的情况;
- 向服务器以HTTP方式提交密码时使用urllib.quote()编码;
- 修改send_msg()函数;
- 清理代码中直接退出的exit函数;
- 重写__tcp_recv()函数,以前这里有可能会丢失数据,比如好友列表过长;
- 增加隐身登录功能,login(True)表示隐身登录。
以前还有人提到增加隐身登录,我看了下08 PC版的飞信,只能是先登录,然后再设置隐身模式,这样的话增加设置隐身模式就没必要了。
至于登出飞信更是没必要了。
09.02.23 Update:
- 上次的代码get_uri被我改出错了,修正了一下;
- 修改了使用手机号直接发送的方式,因为目前可以使用tel: 13888888888的方式发送短信,不用从联系人中一个一个找了;不过以前似乎这种方式不行;
- 修正了获取联系人信息的XML数据,可以完整的获取联系人;
以前在用bash的时候觉得TAB补齐如果能做得更智能一些就好了,比如我使用evince ,bash就会自动列出目录下所有的pdf文件,我还想着自己动修改bash来实现,不过偶然发现了bash-completion这个东西,它不仅可以实现上面的功能,而且还可以补全sudo,补全命令的参数,下面这个图可以很好的代表bash-completion

http://www.caliban.org/bash/
Reply from 192.168.1.1: bytes=32 time=24ms TTL=64
Reply from 192.168.1.1: bytes=32 time=94ms TTL=64
Reply from 192.168.1.1: bytes=32 time=117ms TTL=64
Reply from 192.168.1.1: bytes=32 time=100ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time=1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time=106ms TTL=64
Reply from 192.168.1.1: bytes=32 time=176ms TTL=64
Reply from 192.168.1.1: bytes=32 time=35ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time=2ms TTL=64
Reply from 192.168.1.1: bytes=32 time=31ms TTL=64
Request timed out.
Reply from 192.168.1.1: bytes=32 time=43ms TTL=64
Reply from 192.168.1.1: bytes=32 time=26ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
Reply from 192.168.1.1: bytes=32 time<1ms TTL=64
ping路由时通时不通,而且延时很大,交换机上灯闪得也很慢,而别人的灯闪得很快,而且一致。
看个网页还能凑合着打开,要是玩个即时通信的游戏非得卡死,VS中延时好几百ms。
同样是一个交路机出来的,别人网络没有任何问题,我这里确这样,连电脑的线也换了好几根,也都一样,看来只能是网卡的问题了,有时间去买个网卡。
可惜我这里有好几个有线的交换机,不然现在弄无线网络现在挺方便,而且也相当便宜,一个无线路由80多块钱,无线网卡30多块钱,觉得比拉网线划算多了。
整理Python写的小工具,发现这个导出抓虾收藏的工具还比较有用,以前也是一同学让帮写的,也放在google code里面
代码
代码把抓虾收藏中的文章全部导出为html格式的书签,方便导入进delicious等书签。
从房东说开始拉网线已经过去了整整两个月了,今天终于好了,不过还是遇到了些问题,我这个机子还挑得很,网线插上好一直丢包,半天也没搞清楚是哪儿的问题,电信的人说是网卡有问题,但是换隔壁小伙的网线就没有问题,我自己试了几根网线都不行,折腾了半天,换了个接线盒还是不行,后来电信的人走后我又自己试了一会儿,结果我第一次试的那根网线插上后正常了,实在是很无耐,小心翼翼地把机箱放好,不管了,反正现在是能上了。
上次写到读E680联系人,后来又增加了读短信,并且做了一些代码上的修改,代码放在了google code里,使用的方法是需要读数据库(native.db)中的什么内容就在databases这个list中添加相应的数据库名,获取数据库名的方法也在代码的首部给出了。
地址
PyFetion也放在了这里,以后Python的脚本就统一用google code管理,这样就方便我在多台电脑修改代码了。
前几天看到一篇文章比较SQLite与Bdb的文章,提到了Bdb中数据存放是使用的原始数据,所以在读到短信中的日期时需要使用struct.unpack来进行处理。
本来以为Bdb也应该是代码很小七的,类似与SQLite,没想到竟然有十多兆的代码:-(
可可熊的Python仓库:
http://code.google.com/p/pytool
————————-google code 中svn使用————————————-
svn checkout https://pytool.googlecode.com/svn/trunk/ pytool –username cocobear.cn
svn status
? cang.py
svn add cang.py
A cang.py
svn ci -m”add cang.py”
给俺的boss写的一个小工具,使用Python对Excel进行统计,然后把结束生成一个新的Excel表格,使用到了xlrd和pyExcelerator两个库。
简单的介绍一下这两个库,先说xlrd,这个库读Excel比较方便,各种方法使用起来也挺方便:
bk = xlrd.open_workbook('your.xls')
sh = bk.sheets()[-1]
上面两句就可以打开Excel表格中的一个sheet,sheets得到的是一个list,存放所有的sheet。
sh.nrows是该sheet中的行数,知道这个后就可以使用for循环来读所有的单元格了:
sh.row(i)[3]这个就代表第i行的第4列。
再看看pyExcelerator,这个用起来有点别扭:
sheets = parse_xls('result.xls')
先打开一个表格,sheets是一个list,包含了所有表格的内容,每一项就是一个sheet,而每个sheet是二元tuple,第一个是该sheet的名字,第二个是一个dict,dict的key是一个二元组,表示单元格的坐标,如(0,0),第一行第一列。
从上面的分析中可以得出要访问Excel中第一个sheet的第一行第一列元素需要:
sheets[0][1][(0,0)]
pyExcelerator也不能得到行列数。
写文件也比较简单:
wb = Workbook()
ws = wb.add_sheet('result')
ws.write(0,0,“hello”)
wb.save('result.xls')
就不解释了:-)
写文件时需要注意直接写Unicode内容进去,而不要写编码过的内容。
给boss的代码:
PYTHON:
-
-
# -*- coding=utf-8 -*-
-
#Using GPL v2
-
#Author: cocobear.cn@gmail.com
-
-
import xlrd
-
from pyExcelerator import *
-
-
city = [(u'山城','[2,3]d+'),(u'水国','4d+'),(u'火县','5d+'),
-
(u'土城','6d+'),(u'土国','7d+'),(u'火乡','8[1-5]d+'),
-
(u'水乡','8[067]d+'),]
-
-
fname = '0107CRM.xls'
-
bk = xlrd.open_workbook(fname)
-
sh = bk.sheets()[-1]
-
nrows = sh.nrows
-
#result中按顺序存放各city中各套餐的数量
-
#顺序为XTa+、XTb、XTb+
-
result = []
-
for i in range(len(city)):
-
result.append([0,0,0])
-
-
-
for r in range(1,nrows):
-
num = str(sh.row(r)[3])[7:]
-
flag = False
-
for i in range(len(city)):
-
if re.match(city[i][1],num):
-
flag = True
-
if sh.row(r)[2].value == 3001.0:
-
break
-
name = sh.row(r)[0].value.encode('utf8')
-
if 'XTa+' in name:
-
result[i][0]+=1
-
if 'XTb' in name and 'XTb+' not in name:
-
result[i][1]+=1
-
if 'XTb+' in name:
-
result[i][2]+=1
-
if not flag:
-
print "NO:"+num
-
-
print result
-
-
titles = [u'局向',u'数',u'M录入数',u'X数',…………]
-
wb = Workbook()
-
ws = wb.add_sheet('result')
-
for i in range(len(titles)):
-
ws.write(0,i,titles[i])
-
-
for i in range(len(city)):
-
ws.write(i+1,0,city[i][0])
-
ws.write(i+1,1,result[i][0])
-
ws.write(i+1,4,result[i][1])
-
ws.write(i+1,7,result[i][2])
-
ws.write(i+1,10,result[i][0]+result[i][1]+result[i][2])
-
ws.write(i+2,1,"=SUM(B2:B8)")
-
wb.save('result.xls')
E680手机使用了Berkeley DB,关于这个数据库的一些信息可以看我给的链接。
很早以前就有打算要写个Python读取native.db(不知道这个的请G之)中联系人,短信的程序,不过没能成功,这两天又接触到了bsddb,于是今天分析了下这个native.db,没想到原来挺简单的。Berkeley DB本来就是一个很简单的数据库,只是在E680中系统把多个数据库同时存放在了一个文件中native.db,所以不可以直接使用bsddb.btopen来直接打开这个文件。由于Berkeley DB中只是一种类似Python中dict的数据库(key=value)所以要存放手机联系人(有很多字段,如地址,电话...),就需要使用多个数据库,然后每个数据库使用索引来与其它数据库建立联系。按照一般的想法应该是多个数据库的key是作为索引,然后value分别存放各种信息,但E680中的native.db恰好相反。
其实这样的结构也是很简单的,但是我在写代码的时候遇到一个问题,从某个数据库中读取一个key,然后使用bsddb中的get方法去取这个key对应的value,结果确是None,以前好像就是卡在了这一块,似乎与这个value的值有关系,这个value是二进制数据:“< x03x00x00”,不理解为什么这里不直接用整数作为索引而用这么奇怪的数据,或者这里是某种编码?
先不理这个,不管这个value是什么,使用sorted把每个数据库按照其value排序,下面是所有代码:
读取E680联系人:
PYTHON:
-
#!/usr/bin/env python
-
# -*- coding=utf-8 -*-
-
#Using GPL v2
-
#Author: cocobear.cn@gmail.com
-
-
"""
-
获取数据库名:
-
db = bsddb.db.DB()
-
db.open('native.db',bsddb.db.DB_UNKNOWN,bsddb.db.DB_RDONLY)
-
db.keys()
-
"""
-
-
import bsddb
-
-
db_file = 'native.db'
-
databases = [('姓名','780_contact_table.first name'),('手机1','780_contact_table.mobile1'),('手机2','780_contact_table.mobile2'),('家庭1','780_contact_table.home1'),('家庭2','780_contact_table.home2'),('工作1','780_contact_table.work1'),('工作1','780_contact_table.work1'),]
-
databases = [('姓名','780_contact_table.first name'),('手机1','780_contact_table.mobile1')]
-
out = []
-
-
for database in databases:
-
#进行单文件多数据库操作 需要每次新建一个环境
-
#因此下面这行在for循环里
-
db =bsddb.db.DB()
-
db.open(db_file,database[1],bsddb.db.DB_UNKNOWN,bsddb.db.DB_RDONLY)
-
#每次读一个数据库
-
#原本数据库中的value是系统的id key是具体有意义的内容
-
#下面这行把db.items()得到的list进行反转 为以后有序输出
-
out.append(sorted(db.items(),key=lambda (k,v): (v,k)))
-
db.close()
-
-
#格式化输出
-
for i in databases:
-
print i[0]+":",
-
print
-
-
for i in range(len(out[0])):
-
for j in range(len(out)):
-
#如果输出内容属于电话号码需要反转
-
#根据databases中各位置含义来来判断
-
if j in [1,2,3,4,5,6]:
-
print out[j][i][0].decode('utf16')[::-1],
-
else:
-
#非ascii字符使用utf16进行解码
-
print out[j][i][0].decode('utf16'),
-
print
不到50行就搞定了:-)
还清晰的记得去年写这篇文章的情景,然而又一篇同样的总结又要被敲出来了。
不过没什么好说的了,今年净是些不愉快的事,所以就都让它过去吧,不提了。不过至少我现在可以自己养活自己不用和家里要钱了,算是一点进步,鼓励一下。
俺八六年出生,已经不小了(去年也是这句),虽然今年遇到的事比较多,但还是挺了下来,最难的时刻(也许还有更难的时候)也过去了,以后会越来越好的,今天看到一篇文章说”信仰使人更有自制力“,挺有道理的,不过俺这个年龄才开始培养这个是不有点难了:-) 还有也不知道该信佛呢还是信上帝:-)
昨天冯小刚在他女儿18岁成人礼上说了这些一句话:“学着面对一切真实,接受一些不完美,承担一些责任,自己做一些决定,孩子们,十八岁的你们,是时候了。” 可能我成熟的比较慢吧,不过总要经历过一些事才会懂得。
上班这几个月做的东西比较杂,下班后前段时间连电脑也没,让俺无聊了三个多月,买了电脑后不能上网也很郁闷,想折腾东西没网实在很痛苦的,而且屋子里没有暖气只能躺在被窝里,所以电脑大部分时间是看看电影。这种状态很不好啊。
08年有很多事都没有想到,也没有过心理准备,所以就这样混混沌沌的过了下来,不管怎么样得失之间方显人生色彩。
爱情,越来越不懂了,不知道为什么,不管是不是欺骗,就当一切只是一场梦而已。俺现在单身,呼唤一个像《再说一次我爱你》中蔡卓妍扮演的那样一个女孩,俺喜欢那样的,性格以及外貌。
工作,刚开始能养活自己就行了,是否有利于发展,是否满意,是否合适都不重要,过了明年7月再说吧。就目前来说还行吧,至少不用打卡,不用加班,不用害怕迟到。
生活,自己会做饭了,周末的时候自己弄个菠菜烩豆腐,挺好吃的。
前几天看了下sdcv(Console version of Stardict),感觉很不爽,C++的代码,花了好长时间才理清楚那些结构,我觉得使用C语言来写的话可以让代码更清晰、简洁,或者C++也可以写得更好一些。因为本来就是个很简单的东西,从一个文件中读取单词索引,然后与输入比较,最后在另外一个文件里面查到解释,加上一些模糊匹配,如果需要再加上对国际化的支持,就这些东西。
因为打算在我做的东西里面使用字典,想用stardict的字典,找到了一个PyStardict,不过速度太慢了,加载一个11M的字典需要10s的时间,原因是字典的idx文件中存放的索引使用Python需要一个字节一个字节的去判断字符串长短,而sdcv在实现的时候使用的是C++,它里面读idx文件的时候使用到了指针来确实一个字符串的大小,而Python没办法做到,只能一个一个读然后判断是否字符串结束。
sdcv-0.4.2/lib/lib.cpp:629:
C++:
-
for (guint32 i=0; i<wc; i++) {
-
index_size=strlen(p1) +1 + 2*sizeof(guint32);
-
-
if (i % ENTR_PER_PAGE==0) {
-
wordoffset[j]=p1-idxdatabuffer;
-
++j;
-
}
-
p1 += index_size;
-
}
谁有什么好的办法吗?