Category Archives: Programming

Posting douban saying using python / 用python發送豆瓣廣播

Finally I got sometime to work on implementing my own python script for posting douban saying, again. This time I used the library written by Leah Culver, and everything went smoothly. It’s just that I have no idea why douban chose to use a different signing algorithm(if a thing as stupid as it is can be called a algorithm) for requesting access token.

終於又有時間再一次捯鼓豆瓣. 這次在 Leah Culver 寫的 library 的基礎上, 終於把python腳本發送豆瓣廣播終於搞定了. 唯一理解不能的事就是豆瓣在獲取access token的時候用了一個莫名其妙的簽名算法(如果這種也能叫做算法的話 = =).

Click on read more to view the actual code of the script.
查看腳本內容請點擊 read more
Continue reading

Syncing twitter to digu using python / 用python同步twitter到嘀咕

#!/usr/bin/env python
import base64
import simplejson as json
import os
import sys
import urllib
import urllib2

global twitter_username
global digu_username
global digu_password
twitter_username = 'username'
digu_username = 'username'
digu_password = 'password'

def post_to_digu(msg):
	url = 'http://api.minicloud.com.cn/statuses/update.json'
	data = urllib.urlencode(msg)
	req = urllib2.Request(url, data)
	req.add_header("Authorization", "Basic %s" % base64.encodestring('%s:%s' % (digu_username, digu_password))[:-1])
	handle = urllib2.urlopen(req)

def main():
	path = sys.path[0]
	if (sys.platform[:3] == 'win'):
		path += '\\'
	else:
		path += '/'
	id_file = path + 'last_id'
	last_id = 0
	if os.path.exists(id_file):
		f = open(id_file, 'r')
	        last_id = int(f.read())
        	f.close()
	else:
		f = open(id_file, 'w')
		f.write('0')
		f.close()
	url = 'http://twitter.com/statuses/user_timeline/' + twitter_username + '.json?last_id='
	updates = json.load(urllib.urlopen(url+str(last_id)))
	new_last_id = None
	n = 0
	for update in updates:
		text = update['text']
		id = update['id']
		if (text[0] != '@') and (id > last_id):
			if (new_last_id < id):
				new_last_id = id
			text = urllib.quote(text.encode('utf-8'))
			msg = {'content': text}
                        stack.append(msg)
        while (stack)
                post_to_digu(stack.pop())
	if (new_last_id != None):
		f = open(id_file, 'w')
		f.write(str(new_last_id))

if __name__ == "__main__":
    main()

Sysinfo plugin for xchat2 on linux

It’s my first time writing something in perl, the code is not very efficient and for now it can only display info of cpu, memory, bandwidth and uptime.

# Configuration
$eth = "eth0";

# Script
Xchat::register("Sysinfo", "0.1", "System Information Displayer");
Xchat::print("Sysinfo 0.1 Loaded.");
Xchat::hook_command("uptime", "uptime");
Xchat::hook_command("os", "os");
Xchat::hook_command("bw", "bw");
Xchat::hook_command("cpu", "cpu");
Xchat::hook_command("mem", "mem");

sub uptime {
	$uptime = `cat /proc/uptime | awk '{printf \$1}'`;
	$_day = 60 * 60 * 24;
	$_hour = 60 * 60;
	$_minute = 60;
	$day = int($uptime/$_day);
	$uptime %= $_day;
	$hour = int($uptime/$_hour);
	$uptime %= $_hour;
	$minute = int($uptime/$_minute);
	$uptime %= $_minute;
	$second = int($uptime);
	$uptime = "";
	if($day != 0) {
		$uptime .= $day;
		if($day == 1) {
			$uptime .= " day ";
		} else {
			$uptime .= " days ";
		}
	}
	if($hour != 0) {
		$uptime .= $hour;
		if($hour == 1) {
			$uptime .= " hour ";
		} else {
			$uptime .= " hours ";
		}
	}
	if($minute != 0) {
		$uptime .= $minute;
		if($minute == 1) {
			$uptime .= " minute ";
		} else {
			$uptime .= " minutes ";
		}
	}
	$uptime .= $second;
	if($second == 1) {
		$uptime .= " second";
	} else {
		$uptime .= " seconds";
	}
	Xchat::command("SAY \002[UPTIME]\002 $uptime");
	Xchat::EAT_ALL;
}

sub os {
	$_kernel_release = `uname -r`;
	$_operating_system = `uname -o`;
	chomp($_kernel_release);
	chomp($_operating_system);
	$os = $_operating_system . " " . $_kernel_release;
	Xchat::command("SAY \002[OS]\002 $os");
	Xchat::EAT_ALL;
}

sub bw {
	$old = `cat /proc/net/dev | grep $eth | cut -d ":" -f 2 | tr -s " "| cut -d " " -f 1,9`;
	sleep(1);
	$new = `cat /proc/net/dev | grep $eth | cut -d ":" -f 2 | tr -s " "| cut -d " " -f 1,9`;
	@ary_old = split(/\s/, $old);
	@ary_new = split(/\s/, $new);
	$down = $ary_new[0] - $ary_old[0];
	$up = $ary_new[1] - $ary_old[1];
	$bw = "";
	if($down < 1000) {
		$bw .= $down . " B/s Down ";
	} else {
		$bw .= sprintf("%.02f", $down / 1000) . " KB/s Down ";
	}	
	if($up < 1000) {
		$bw .= $up . " B/s Up";
	} else {
		$bw .= sprintf("%.02f", $up / 1000) . " KB/s Up";
	}
	Xchat::command("SAY \002[BW]\002 $bw");
	Xchat::EAT_ALL;
}

sub cpu {
	$model_name = `cat /proc/cpuinfo | grep "model name" | tail -1 | cut -d ":" -f 2 | tr -s " "`;
	$number_cores = `cat /proc/cpuinfo | grep "model name" -c`;
	$freq = `cat /proc/cpuinfo | grep "cpu MHz" | tail -1 | cut -d ":" -f 2 | tr -s " "`;
	$idle = `vmstat | tail -1 | awk '{printf \$15}'`;
	$load = 100 - $idle;
	chomp($model_name);
	chomp($number_cores);
	chomp($freq);
	$cpuinfo = $number_cores . " CPU";
	if($number_cores > 1) {
		$cpuinfo .= "'s";
	}
	$cpuinfo .= " -" . $model_name;
	$cpuinfo .= " @ " . int($freq) . " MHz" . " (" . $load . "% Load)";
	Xchat::command("SAY \002[CPU]\002 $cpuinfo");
	Xchat:EAT_ALL;
}

sub mem {
	$mem_total = `free -m | grep Mem | awk '{printf \$2}'`;
	$mem_used = `free -m | grep - | awk '{printf \$3}'`;
	$swap_total = `free -m| grep Swap | awk '{printf \$2}'`;
	$swap_used = `free -m| grep Swap | awk '{printf \$3}'`;
	$meminfo = "\002[MEM]\002 " . $mem_used . "/" . $mem_total . " MB \002[SWAP]\002 " . $swap_used . "/" . $swap_total . " MB";
	Xchat::command("SAY $meminfo");
	Xchat::EAT_ALL;
}

Download Link Converter / 下載鏈接轉換器

I was extremely bored this afternoon, so here it is, the converter for converting download links among FlashGet, QQ Tornado and Xunle, and also decrypting the real link. The tool is pretty much self-explanatory (and useless) so I guess there’s no need for any manuals or instructions. If you are bored too, you can check out the source below, just don’t tell me how ugly it is, coz I’m fully aware of it! 😀 You can find this converter on the “Tool” page, link is at the top of the page.

今天下午極度無聊, 就隨便寫了個可以在 FlashGet, QQ旋風和迅雷間轉換下載鏈接的小工具, 也可以直接看到真實鏈接. 功能及其直白, 就不提供什麼說明了. 如果你跟我一樣無聊, 以下有代碼奉上. 我知道代碼寫得很醜, 所以就不要提到這點啦! 😀 你可以在”Tool”頁面看到這個工具, 鏈接在頁面頂部.

Continue reading

豆瓣小組引用回復插件

在顯示樓層插件的基礎上加上了引用回復功能

因為是以顯示樓層插件為基礎, 所以要求依然是 firefox+greasemonkey, 並且包括顯示樓層功能

引用回復的 link 只有在鼠標在回復區塊上時才會顯示

如果想引用留言所在頁面不是最後一頁, 因此沒有回復框, 插件會自動在頁面上加上回復框

引用完成後頁面會滾動到底部回復框

* 增加: ctrl+enter 回復功能 (04/06/2009)
* 修正bug: 不能在非第一頁或最後頁創建回復框 (10/06/2009)
* 增加: 如果討論分頁, 在頁首也顯示導航條 (10/06/2009)

Continue reading

同步 twitter 到 飯否

google 看到 raptium同學的 post Twitter和饭否同步

像我這種懶人自然就拿來用了

不過又不想把 twitter 上的回復也 sync 到飯否

so 加了一個 statement 把 @blah 都過濾了

如果有比我更懶得同學也想這麼做的話只要把

elif snode.nodeName == 'text':

改成

elif (snode.nodeName == 'text') and (snode.childNodes[0].nodeValue[0] != '@'):

就可以了 😀

How to distinguish incoming trunks in asterisk-java

Suppose you have asterisk 1.6 with freepbx and you are developing with the latest asterisk-java library. Somehow you wanna perform different tasks based on calls coming through different SIP trunks.

When there’s a new incoming call, asterisk-java will trigger a newChannelEvent, but there’s no information in this event that can be used for distinguish from which trunk this call is coming in.

By default the accountcode in this NewChannelEvent is null, which makes sense because the accountcode is used for billing, and no one, at least not many people, wants to record the charge of SIP trunk because that’s usually done by the SIP provider to which the trunk is registered to. But since the accountcode is null and useless here, maybe we can use it as an identifier to distinguish the incoming trunk, it may be not the smartest solution, but at least it’s a working one 😀 Continue reading