Subscribe toideal's blog

1 十二 2008

pycat 0.0.2 released

Posted by ideal. No Comments

Pycat is the web login client for BJTU. It is easy to use. Now the 0.0.2 version is released.

ChangeLog:

  • improved the gui interface
  • fixed some problems
  • modified Makefile
  • added tangshi 300 poems which are from fortune-zh
  • a deb package is provided

Download:
source
deb package

Tags: ,

18 十一 2008

west lake, a song by Miserable Faith

Posted by ideal. No Comments

对于西湖我几乎没有印象,偶尔算是路过。

那天听到此歌,居然想哭。白驹过隙,呼啸而过,一切都不曾逃脱。

西湖 痛仰乐队

01 行船入三潭 嬉戏着湖水
02 微风它划不过轻舟
03 时而又相远 时而又相连
04 断桥何曾踏过残雪
05
06 再也没有留恋的斜阳
07 再也没有倒映的月亮
08 再也没有醉人的暖风
09 转眼消散在云烟
10
11 单车过长堤 欢歌笑语
12 一路却错看了风景
13 望不到云河 也望不到天际
14 流星刹那已然掠过
15
16 再也没有留恋的斜阳
17 再也没有倒映的月亮
18 再也没有醉人的暖风
19 转眼消散在云烟
20
21 那一天 那一夜
22 没有察觉竟已走远
23 那一天 那一夜
24 从我的故事里走远

Tags:

5 十一 2008

use python to track friends’ status on xiaonei

Posted by ideal. No Comments

Although I am not very interested in xiaonei.com. I just want to write a program to know the status of my friends and classmates. Through this program, you can receive the status infomation of your friends in gtalk. The post_status section (to login to a gtalk account and send a message using xmpp) of the code is referred from solrex.(the exact post is here)

To use this program, you need to install the python-xmpp library, if you are using debian or ubuntu, you can install it by sudo apt-get install python-xmpp. Also it means that you need to have two gtalk accounts, you can use the not usually used one to send the message to the usually used one. Notice that these two accounts need to be in friend list. Maybe there are better ways.

#!/usr/bin/python
# -*- coding: UTF-8 -*-
#
# Author: ideal (idealities AT gmail.com)
# Date:   2008-11-04
# Homepage: http://qdhedu.com/ideal

from sgmllib import SGMLParser
import urllib
import urllib2
import xmpp

def post_status(sendto = 'username@gmail.com', message = ''): #put your usually used account here in sendto
    login = 'bjtulinux' #your not usually used account
    passwd = '' #and the password
    talk = xmpp.Client('gmail.com', debug=[])
    talk.connect(server = ('talk.google.com', 5223))
    talk.auth(login, passwd, 'python')
    talk.send(xmpp.Message(sendto, message))

def get_status(email = 'idealities@gmail.com', passwd = ''): #your account and password for xiaonei.com
    url = 'http://xiaonei.com/Login.do'
    vals = {'email': email, 'password': passwd}
    useragent = 'Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3'

    import cookielib
    cook = cookielib.CookieJar()
    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cook))
    opener.addheaders = [('User-Agent', useragent)]
    urllib2.install_opener(opener)
    sock = urllib2.urlopen(url, urllib.urlencode(vals))
    text = sock.read()
    sock.close()
    return text

class Status(SGMLParser):
    def reset(self):
        self.message = []
        self.isInBlogDiv = False
        self.isInStatusDiv = False
        self.isInH4 = False
        self.isInH4A = False
        self.isInDate = False
        self.count = 0
        SGMLParser.reset(self)

    def start_div(self, attrs):
        if self.isInBlogDiv or self.isInStatusDiv:
            self.count += 1
        for key, value in attrs:
            if key == "class":
                if value == "feed feed-blog text-story expand bold-feed ":
                    self.isInBlogDiv = True
                elif value == "feed feed-status text-story expand ":
                    self.isInStatusDiv = True

    def end_div(self):
        if self.isInBlogDiv or self.isInStatusDiv:
            self.count -= 1
        if self.count == -1:
            if self.isInBlogDiv:
                self.isInBlogDiv = False
            elif self.isInStatusDiv:
                self.isInStatusDiv = False
            self.count = 0

    def start_h4(self, attrs):
        if self.isInBlogDiv or self.isInStatusDiv:
            self.isInH4 = True

    def end_h4(self):
        if self.isInH4:
            self.isInH4 = False

    def start_a(self, attrs):
        if self.isInH4:
            self.isInH4A = True

    def end_a(self):
        if self.isInH4A:
            self.isInH4A = False

    def start_span(self, attrs):
        if self.isInH4:
            for key, value in attrs:
                if key == "class" and value == "date":
                    self.isInDate = True

    def end_span(self):
        if self.isInDate:
            self.isInDate = False

    def handle_data(self, text):
        if self.isInH4A:
            if text != "回复":
                self.message.append(text)
        elif self.isInDate:
            self.message.append(text + "n")
        elif self.isInH4:
            self.message.append(text)

    def output(self):
        """Return processed HTML as a single string"""
        return "".join(self.message)

if __name__ == '__main__':
    html = get_status()
    msg = Status()
    msg.feed(html)
    post_status(message = msg.output())
    msg.close()

You can put it in cron and let it run every n hours.

Tags:

29 2008

a python program to search english words

Posted by ideal. No Comments

Because running stardict on my laptop always lead to a 100% cpu utilization, and I haven’t found a better dictionary software under linux, I have to use online dictionaries like stardict.cn or baidu’s dictionary (actually it is powered by DrEye). But I feel that it is not so convenient to use these online dictionaries, for example, if I am reading a document with evince, I have to switch to the browser and open a tab directing to the website. (although I can keep the tab open till the time that I don’t need it)

So I write a simple CLI python program to fetch the translation from website and print the result in the terminal. It is really simple, and now it can’t deal with example sentences, and only supports one website (other ones are similar).


01 #!/usr/bin/python
02 """Search the word"""
03
04 from sgmllib import SGMLParser
05 import sys
06
07 class SearchWord(SGMLParser):
08     def reset(self):
09         self.result = []
10         self.isInResult=False
11         SGMLParser.reset(self)
12
13     def start_div(self, attrs):
14         for key, value in attrs:
15             if key == "class" and value =="pexplain": self.isInResult=True
16
17     def end_div(self):
18         if self.isInResult:
19             self.isInResult=False
20    
21     def handle_data(self, text):
22         if self.isInResult:
23             self.result.append(text+"n")
24
25     def output(self):
26         """Return processed HTML as a single string"""
27         return "".join(self.result).decode("gb2312").encode("utf8")
28
29 def get_search():
30     import urllib
31    
32     if(len(sys.argv) < 2):
33         print "Usage: %s word" % sys.argv[0]
34         return
35     url = "http://www.baidu.com/s?lm=0&si=&rn=10&ie=gb2312&"
36           "ct=1048576&wd=%s&tn=baidu" % urllib.quote(sys.argv[1].decode("utf8").encode("gb2312"))
37     sock=urllib.urlopen(url)
38     trans=SearchWord()
39     trans.feed(sock.read())
40     print trans.output()
41     sock.close()
42     trans.close()
43
44 if __name__ == "__main__":
45     get_search()

screenshot-idealnever

Tags: ,

11 2008

future is not what we think it is

Posted by ideal. No Comments

Now the no-exam graduation students registration is almost done and the decision that who goes to which school has also decided. Although I have the chance to choose to go to another school other than BJTU, I have never thought that I have the ability to go to cas or even BeiHang, I even have never thought that I am one of the students who have that chance. And the fact is that cas refused me finally.

At the very beginning I have agreed with Mr. Lin that I was going to stay at BJTU. That made me have a thought that breaking the promise is not appropriate.

But when I saw my classmates were busy contacting the schools, I also want to have a try at that time. If I can be accepted by cas, my father maybe will be very happy. So I send a resume to cas. But finally I can’t achieve this.

I am not good at speaking, never, and also have few planning of myself. I think that my classmates have the clear thoughts of their future life, and also mature plans. But I am not capable to be one like them.

When I came from cas, I sent a message to her, which was the message I sent months later after last one, it was her birthday. And she replied "Thank you!". That is all between us. Maybe we are just friends even since the first year when we are in this university, but why I can’t accept this fact.

Tags:

12 2008

./miscd

Posted by ideal. No Comments

The songs I am listening these days:

  • 张楚–姐姐
  • 大乔小乔–星座
  • nightwish–you are my sin
  • nightwish–bless the child

Books:

  • The art of UNIX programming

Tags: ,

8 2008

where to go if i can decide

Posted by ideal. No Comments

    从家里回来一个多星期了。在实验室基本啥也没干。其中有一天还和几个同学去什刹海后海逛了一圈。他们做学院的网站热火朝天,而我又不想去碰asp.net的东西(当然我也不懂),更何况还得弄个visual studio,本来打算用虚拟机,后来死活没搞出来,便作罢。搜了些论文,关于索引和大规模数据,没怎么看。我数学实在不好,对算法又不敏感,看这些甚是头痛。倒是把lxtask的代码看了一些,还算简单,涉及到glib和gtk的都可以查devhelp,还算方便。

    后来往bjtulinuxer.cn加了些东西,又觉得意义不大。果园的很多东西这些天一直没管,本来打算暑假完成的东西至今未见踪影。想起未来的去处,满是忧愁。

    三年一瞬间。

 

1 2008

a special day

Posted by ideal. No Comments

It is really busy in the school today. New students (or freshmen) come for registration. Every college has a place at the South Gate Little Forest (really little) to welcome their new students. 3 years ago, I came here with my father, with little imagination of the coming university life (I have no idea what it would be like).

Also it is the teacher’s day. I send a message to my sister in the morning. I still remember the early days when she became a teacher after she graduated from Hangzhou Normal College. We are in the same school at that time, when I was in my third year at Lishang Middle School.

When I come out from the lab for launch, I see some graduation students take flowers to their advisors. And a long queue at China Mobile’s activity place (add more fees for your cell phone, and you will get better present). Then I remember my aigo usb flash disk, which is as a present from the same activity in the beginning of last semester, broken suddenly some days ago.

The BBS accepts for registration again. But the school asks for real name registration. I searched for the old threads in the BBS and still has no idea of how I can figure it out. I just got a conclusion that the code is finished. Or I need to recompile the source code? As a technical supporter of the BBS, I am ashamed that I contributed little to the BBS,except some lines of php code and python script. Hope that will be changed.

Our project goes slowly.
For the coming days:English listening, Data structure, A biography,

Tags: ,

29 2008

ext2文件系统分析(一)

Posted by ideal. No Comments


    Filesystem HOWTO上的关于ext2文件系统的结构图,把每个文件系统boot sector单独画出来,不在Block group之内。如下图:

fs

  通过dumpe2fs发现,我的/dev/sda1的块大小为1024字节,sda1本身比较小,是/boot分区,情况确实如上图所示。即Group 0是从块1开始的,即块0作为boot sector单独在 block group之外。而/dev/sda5并不是这样。sda5的块大小为4096字节。Group 0是从块0开始的。没有把boot sector单独放在外面。但块0的前1024字节仍预留。因此文件系统的主超级块都是从偏移地址1024开始的。并且ext2/ext3的超级块大小为1024字节。如果块大小为1024,超级块正好占用一个块。如果块大小为4096,块0的1024-2047为超级块,而2048-4095则空闲。块的计数从0开始,在一个文件系统上是全局的。

ext2

  这样的设计也避免了块的大小为4096字节时把前一个块留给boot sector有点浪费。
  并且并不是每个block group中都有super block和group descriptors的备份。只是在某些奇数的块中才有(具体的机制不清楚)。

  ext2超级块的结构(在源代码树的include/linux/ext2_fs.h中)。 

/*
 * Structure of the super block
 */
struct ext2_super_block {
    __le32    s_inodes_count;        /* inode总数 */
    __le32    s_blocks_count;        /* block总数 */
    __le32    s_r_blocks_count;    /* 保留的block总数 */
    __le32    s_free_blocks_count;    /* 空闲的block总数 */
    __le32    s_free_inodes_count;    /* 空闲的inode总数 */
    __le32    s_first_data_block;    /* 第一个数据块 */
    __le32    s_log_block_size;    /* Block的大小 */
    __le32    s_log_frag_size;    /* Fragment size */
    __le32    s_blocks_per_group;    /* 每个block group的block数量 */
    __le32    s_frags_per_group;    /* # Fragments per group */
    __le32    s_inodes_per_group;    /* 每个block group的inode数量 */
    __le32    s_mtime;        /* 挂载时间 */
    __le32    s_wtime;        /* Write time */
    __le16    s_mnt_count;        /* 挂载计数 */
    __le16    s_max_mnt_count;    /* Maximal mount count */
    __le16    s_magic;        /* Magic 签名 */
    __le16    s_state;        /* File system state */
    __le16    s_errors;        /* Behaviour when detecting errors */
    __le16    s_minor_rev_level;     /* minor revision level */
    __le32    s_lastcheck;        /* 上一次检查时间 */
    __le32    s_checkinterval;    /* max. time between checks */
    __le32    s_creator_os;        /* OS */
    __le32    s_rev_level;        /* Revision level */
    __le16    s_def_resuid;        /* Default uid for reserved blocks */
    __le16    s_def_resgid;        /* Default gid for reserved blocks */
    /*
     * These fields are for EXT2_DYNAMIC_REV superblocks only.
     *
     * Note: the difference between the compatible feature set and
     * the incompatible feature set is that if there is a bit set
     * in the incompatible feature set that the kernel doesn’t
     * know about, it should refuse to mount the filesystem.
     *
     * e2fsck’s requirements are more strict; if it doesn’t know
     * about a feature in either the compatible or incompatible
     * feature set, it must abort and not try to meddle with
     * things it doesn’t understand…
     */
    __le32    s_first_ino;         /* First non-reserved inode */
    __le16   s_inode_size;         /* inode structure 的大小*/
    __le16    s_block_group_nr;     /* block group # of this superblock */
    __le32    s_feature_compat;     /* compatible feature set */
    __le32    s_feature_incompat;     /* incompatible feature set */
    __le32    s_feature_ro_compat;     /* readonly-compatible feature set */
    __u8    s_uuid[16];        /* 128-bit uuid for volume */
    char    s_volume_name[16];     /* volume name */
    char    s_last_mounted[64];     /* directory where last mounted */
    __le32    s_algorithm_usage_bitmap; /* For compression */
    /*
     * Performance hints.  Directory preallocation should only
     * happen if the EXT2_COMPAT_PREALLOC flag is on.
     */
    __u8    s_prealloc_blocks;    /* Nr of blocks to try to preallocate*/
    __u8    s_prealloc_dir_blocks;    /* Nr to preallocate for dirs */
    __u16    s_padding1;
    /*
     * Journaling support valid if EXT3_FEATURE_COMPAT_HAS_JOURNAL set.
     */
    __u8    s_journal_uuid[16];    /* uuid of journal superblock */
    __u32    s_journal_inum;        /* 日志文件的inode号 */
    __u32    s_journal_dev;        /* 日志文件的设备号 */
    __u32    s_last_orphan;        /* start of list of inodes to delete */
    __u32    s_hash_seed[4];        /* HTREE hash seed */
    __u8    s_def_hash_version;    /* Default hash version to use */
    __u8    s_reserved_char_pad;
    __u16    s_reserved_word_pad;
    __le32    s_default_mount_opts;
     __le32    s_first_meta_bg;     /* First metablock block group */
    __u32    s_reserved[190];    /* Padding to the end of the block */
};

  superblock的大小为1024个字节。ext2和ext3的magic签名是一样的。ext3增加了日志功能。

  可以使用xxd -s 1024 -l 1024 /dev/sdax(将x替换为你要查看的盘块号)来获得这些数据信息

screenshot

  此处第一个32位的数为0x0000cbf0(i386为Little-Endian,即高字节在高地址,低字节在低地址),转换为十进制即52208,所以该分区inode的数目最多为52208,这和使用dumpe2fs得到的结果是一样的。其他的值可按同样的方法得到。

18 2008

为灾区同胞祝福

Posted by ideal. 3 Comments

明天离地震发生就一周了。

深深地为灾区同胞祝福,愿死者安息。

我们看到了一个团结的民族,我们被深深得感动着。

希望与中国同在!