毕设中期报告

On 2010年04月29日, in IT生活, by antmanler

做了一个多月的毕业设计,今天实验室例会上给老师做了个报告,同时悲痛的得知这个难得的暑假估计大半时间要贡献给实验室了

今天报告的PPT

视频演示 : 清晰版 (On youtube)

Tagged with:
 

Python Socks Proxy

On 2010年02月8日, in IT生活, by antmanler

在python中 urllib, 以及 urllib2 都是可以设置http代理的,但是却不支持socks4/5的代理链接而且如果要通过代理访问ssl的安全链接还要稍稍hack一下。

SocksiPy是一个可以为python提供socks4/5支持的客户端,设计简洁轻量,很小的代码量就可以实现socks代理。但我在这几天使用中发现一个问题:socksipy本身是提供远程DNS解析的,但是在使用urllib建立链接是却会受到来自天朝DNS污染,经过分析发现问题出在httplib的HTTPConnection在建立连接时调用的是socket.create_connection()函数,而在create_connection中使用getaddrinfo()会返回本地解析的结果,所以才会出现DNS污染。

解决方法是主动使用SockiPy提供的socket链接,具体做法见示例代码:

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import socks
import socket
import urllib2
import traceback

socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, "127.0.0.1", 1080)

socket.socket = socks.socksocket

def _create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
    msg = "getaddrinfo returns an empty list"
    host, port = address
    for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
        af, socktype, proto, canonname, sa = res
        sock = None
        try:
            sock = socket.socket(af, socktype, proto)
            if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT:
                sock.settimeout(timeout)
            sock.connect(address)
            return sock

        except socket.error, msg:
            if sock is not None:
                sock.close()

    raise socket.error, msg

socket.create_connection = _create_connection
re = urllib2.urlopen("http://www.twitter.com")

print re.read()

最后至于python使用socks代理有什么用呢,请各位看官特别是主机在国内又有一个免费ssh的童鞋联想一下 ssh -D。

Tagged with:
 

Integrated Panda3d into QTWidget

On 2010年02月6日, in IT生活, by antmanler

Recently I’m learning the Panda3D Game Engine, I find it’s a wonderful opensource game engine I’ve met.

I’m about to write a tools to display the art gallery provided by its tutorials, but I don’t want to use the DirectUI instead  I’d like to apply PyQT as user interface.

At the beginning I had no idea of how to integrate the normal panda3d window into a QtWidget, finally  I found the solution at its forum.

I post it here with my modifications (just add a walking panda to make it fun),  and I hope this can help somebody that has the same problem when learning panda3d.

here is the screen shot:

screenshot of walking panda

here comes the code:

# -*- coding: utf-8-*- 

from pandac.PandaModules import loadPrcFileData
loadPrcFileData("", "window-type none") 

import direct.directbase.DirectStart
from direct.actor import Actor
from direct.interval.IntervalGlobal import Sequence
from direct.task import Task
from pandac.PandaModules import Point3
from direct.showbase.DirectObject import DirectObject
from pandac.PandaModules import WindowProperties
import math

from PyQt4.QtCore import *
from PyQt4.QtGui import * 

import sys 

P3D_WIN_WIDTH = 400
P3D_WIN_HEIGHT = 240 

class QTPandaWidget(QWidget):
   def __init__(self, parent=None):
      super(QWidget, self).__init__(parent)
      self.setSizePolicy(QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)) 

   def resizeEvent(self, evt):
      wp = WindowProperties()
      wp.setSize(self.width(), self.height())
      wp.setOrigin(self.x(),self.y())
      base.win.requestProperties(wp) 

   def minimumSizeHint(self):
      return QSize(400,300)

class QTTest(QDialog):
    def __init__(self, pandaCallback, parent=None):
        super(QDialog, self).__init__(parent)
        self.setWindowTitle("Test")
        self.setGeometry(0,0,400,300) 

        self.pandaContainer = QTPandaWidget(self)
        self.pandaContainer.setGeometry(0,0,P3D_WIN_WIDTH,P3D_WIN_HEIGHT) 

        self.lineedit = QLineEdit("Write something...does it work?") 

        layout = QVBoxLayout()
        layout.addWidget(self.pandaContainer)
        layout.addWidget(self.lineedit) 

        self.setLayout(layout) 

        # this basically creates an idle task
        timer =  QTimer(self)
        self.connect( timer, SIGNAL("timeout()"), pandaCallback )
        timer.start(0) 

class World(DirectObject):
    def __init__(self):
        self.accept("a", self.pressedA)
        self.accept("escape", sys.exit)

        environ = loader.loadModel("models/environment")
        environ.reparentTo(render)
        environ.setScale(0.25, 0.25, 0.25)
        environ.setPos(-8, 42, 0)
        taskMgr.add(self.spinCameraTask, "SpinCameraTask")

        #Load the panda actor, and loop its animation
        pandaActor = Actor.Actor("models/panda-model", {"walk": "models/panda-walk4"})
        pandaActor.setScale(0.005, 0.005, 0.005)
        pandaActor.reparentTo(render)
        pandaActor.loop("walk")

        #Create the four lerp intervals needed to walk back and forth
        pandaPosInterval1 = pandaActor.posInterval(13, Point3(0, -10, 0), startPos=Point3(0, 10, 0))
        pandaPosInterval2 = pandaActor.posInterval(13, Point3(0, 10, 0), startPos=Point3(0, -10, 0))
        pandaHprInterval1 = pandaActor.hprInterval(3, Point3(180, 0, 0), startHpr=Point3(0, 0, 0))
        pandaHprInterval2 = pandaActor.hprInterval(3, Point3(0, 0, 0), startHpr=Point3(180, 0, 0))

        #Create and play the sequence that coordinates the intervals
        pandaPace = Sequence(pandaPosInterval1, pandaHprInterval1, pandaPosInterval2, pandaHprInterval2,
                             name="pandaPace")
        pandaPace.loop()

    #Task to move the camera
    def spinCameraTask(self, task):
        angleDegrees = task.time * 6.0
        angleRadians = angleDegrees * (math.pi / 180.0)
        base.camera.setPos(20 * math.sin(angleRadians), -20.0 * math.cos(angleRadians), 3)
        base.camera.setHpr(angleDegrees, 0, 0)
        return Task.cont

    def pressedA(self):
        print "a pressed, keyboard focus ok" 

    def step(self):
        taskMgr.step() 

    def bindToWindow(self, window):
        wp = WindowProperties().getDefault()
        wp.setOrigin(0,0)
        wp.setSize(P3D_WIN_WIDTH, P3D_WIN_HEIGHT)
        wp.setParentWindow(int(window.winId()))
        base.openDefaultWindow(props=wp)
        #print 'window: %s' % base.win
        #print 'window properties: %s' % base.win.getProperties()
        self.wp = wp 

if __name__ == '__main__':
    world = World()
    app = QApplication(sys.argv)
    form = QTTest(world.step)
    world.bindToWindow(form) 

    form.show()
    sys.exit(app.exec_())
Tagged with:
 

更改文件链接为相对路径

On 2010年01月20日, in 未分类, by antmanler

前几天重新装回了Ubuntu 9.10, 发现以前建立的符号链接都失效了,原来是之前建立的符号链接都是绝对路径,之前使用Opensuse的时候用的root,在Ubuntu下所有链接都变成 Broken Link了,所以今天写了一个脚本,把~/目录下的所有符号链接都修复,并且改成了相对路径,这样的话如果再迁移系统只要保证相对位置不变就可以了。

#!/usr/bin/python
'''
Created on Jan 20, 2010

@license: License: LGPL
@copyright: (c) 2010, dogsing.cn
@author: antmanler
'''

import os
import sys

USEAGE = '''Usage: chlink starts
  scan and change the symlink's origin path to related path from home folder

  starts: is a directory where the scaning starts
'''

LOGFILE = open("chlink.log", "w+a")
HOME = os.path.expanduser("~")

def visit(verbose, dirname, names) :
    os.chdir(dirname)
    print >>LOGFILE, dirname
    if verbose : print "Enter ", dirname

    REL_DIR = os.path.join(HOME, dirname)
    for _file in names :
       if verbose : print "  Parse file ", _file
       if os.path.islink(_file) :
           lnfile = os.readlink(_file)
           print >>LOGFILE, "  %s -> %s" % (_file, lnfile)
           if lnfile.startswith("/root") :
               lnfile = lnfile.replace("/root", HOME)

           lnfile = os.path.relpath(lnfile)
           os.remove(_file)
           os.symlink(lnfile, _file)
           print >>LOGFILE, "    new :-> %s" % lnfile

if __name__ == "__main__" :

    if len(sys.argv) != 2 :
        print >> sys.stderr, USEAGE
        sys.exit(-1)

    starts = sys.argv[1]
    if not os.path.isdir(starts) :
        print >> sys.stderr, USEAGE
        sys.exit(-1)

    #start to scan and change
    os.path.walk(starts, visit, True)
Tagged with:
 

Python中让脚本只启动一个实例

On 2009年12月28日, in IT生活, by antmanler

今天在论坛里看到讨论如何只允许一个脚本运行,清风给出了比较满意的回答,遂收藏之:

方法是用文件锁,uliweb下面就用这样一个模块,跨平台的,

#coding=utf-8
#用于防止两个程序同时启动

__all__ = ['LOCK_EX', 'LOCK_SH', 'LOCK_UN', 'lock_file',
'unlock_file',
    'LockFile', 'LockError']
import os
class LockError(Exception):
    """Couldn't get a lock
    """
LOCKTYPE_FCNTL = 1
LOCKTYPE_MSVCRT = 2
LOCKTYPE = None
try:
    import fcntl
except:
    try:
        import msvcrt
    except:
        LOCKTYPE = None
    else:
        LOCKTYPE = LOCKTYPE_MSVCRT
else:
    LOCKTYPE = LOCKTYPE_FCNTL
LOCK_EX = 1
LOCK_SH = 2
LOCK_UN = 3
def lock_file(f, lock=LOCK_SH):
    try:
        fd = f.fileno()
        if LOCKTYPE == LOCKTYPE_FCNTL:
            if lock == LOCK_SH:
                fcntl.flock(fd, fcntl.LOCK_SH)
            elif lock == LOCK_EX:
                fcntl.flock(fd, fcntl.LOCK_EX)
            elif lock == LOCK_UN:
                fcntl.flock(fd, fcntl.LOCK_UN)
            else:
                raise Exception, "BUG: bad lock in lock_file"
        elif LOCKTYPE == LOCKTYPE_MSVCRT:
            if lock == LOCK_SH:
                # msvcrt does not support shared locks
                msvcrt.locking(fd, msvcrt.LK_LOCK, 1)
            elif lock == LOCK_EX:
                msvcrt.locking(fd, msvcrt.LK_LOCK, 1)
            elif lock == LOCK_UN:
                msvcrt.locking(fd, msvcrt.LK_UNLCK, 1)
            else:
                raise Exception, "BUG: bad lock in lock_file"
        else:
            raise Exception, "BUG: bad locktype in lock_file"
    except IOError:
        raise LockError("Couldn't lock %r" % f.name)
def unlock_file(f):
    lock_file(f, LOCK_UN)
class LockFile(object):
    def __init__(self, lockfilename):
        self._f = lockfilename
        self._create_flag = False
        self._checkfile()
    def _checkfile(self):
        if os.path.exists(self._f):
            self._fd = open(self._f, 'rb')
        else:
            dir = os.path.dirname(self._f)
            if dir and not os.path.exists(dir):
                os.makedirs(dir)
            self._fd = open(self._f, 'wb')
            self._create_flag = True
    def lock(self, lock_flag=LOCK_EX):
        lock_file(self._fd, lock_flag)
    def close(self):
        unlock_file(self._fd)
        self._fd.close()
    def delete(self):
        self._fd.close()
        os.unlink(self._f)
if __name__=="__main__":
    locker = LockFile('locked.txt')
    try:
        locker.lock()
    except Exception,e:
        print 'program have already run'
        exit()
    else:
        print 'successful'
    import time
    time.sleep(20)
Tagged with:
 

看来真没免费的午餐

On 2009年12月20日, in IT生活, 非技术, by antmanler

今天收到火山互联发的邮件,说要提交域名白名单,我原以为可以恢复以前绑定在免费vps的域名了,就悻悻的跑到volit.com,进入管理页面发现赫然几个大字“对不起,免费VPS停止服务,不能再延期!”。怒阿!真是说停就停,说关就关,免费用户怎么了?免费用户就一点权利都毛得?真应了那句“No free lunch”。

关就关呗,谁叫咱是P民呢,在twitter上看到“网监”都近群了,我就。。。。就无语了,不是真无语,是不敢言阿!

算了牢骚就发发,再说连累了stdyun.com提供的空间就不好了,这年头还能享受自由的互联网多久呢?听说XX已经断网半年了~

网监叔叔们,您好!河蟹Long live!

Tagged with:
 

Linux 日积月累

On 2009年12月15日, in IT生活, by antmanler

算算到今天用linux也有小两年了,从opensuse到ubuntu再到Mint又回opensuse,从Kde到gnome到xface又回Kde可是还是好多工具,特别是命令记不牢,遂决定开贴,记录脑残时弄错的命令。

下面的各种命令以及技巧,均亲自实验保证可行。

1. 查看文件大小:

du -sh  #查看当前文件夹大小
du -sh * | sort -n  #统计当前文件夹(目录)大小,并按文件大小排序
du -sk filename  #查看指定文件大小

2. 解决Mp3乱码:
需要:python-mutagen

mid3iconv -e gbk filename

3.Ubuntu下默认vpn链接无法连接,解决方法:

终端输入gconf-editor
进入这个中的”System” ->”Networking”-> “Connections”. 在连接的这个文件夹,找到有vpn信息的那个数字的文件夹.选择vpn,点右键,选择新建。
这个的名字为 “refuse-eap”, 设置它为”String” 和它的值为” yes”.点OK退出

4. 切换JDK

sudo update-alternatives --config java

5. 修复Eclipse 3.5 在linux下部分按钮失效问题

在 ~/.bashrc 或 ~/.profile 中添加环境变量

export GDK_NATIVE_WINDOWS=1

6. 查看系统当网络链接情况

netstat -utnp

7. 修复ubuntu下pdf文件中文问题

sudo apt-get install poppler-data
修改 /etc/fonts/conf.d/49-sansserif.conf 中 append_last 的字体为系统中中文字体即可

8. gnome-shell设置为默认启用

gconftool-2 –set /desktop/gnome/session/required_components/windowmanager –type string gnome-shell
恢复默认的gnome窗口管理,运行命令
gconftool-2 –unset /desktop/gnome/session/required_components/windowmanager

9. 启用PPA的Network-Manager源

sudo add-apt-repository ppa:network-manager/ppa

10. 快速修复类似“The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY F13930B14BB9F05F” 错误

Quick fix:
gpg –keyserver subkeys.pgp.net –recv F13930B14BB9F05F
Then enter the following:
gpg –export –armor F13930B14BB9F05F | sudo apt-key add -
Then, to finish off, enter the following:
sudo apt-get update

11. 如何查看计算机活动端口

lsof -i4

12. 制作ISO镜像

1、从CD/DVD制作iso,将关盘介质放置到光盘,不要挂载。如果系统自动挂载,首先卸载它。
使用dd命令:
dd if=/dev/dvd of=dvd.iso # for dvd
dd if=/dev/cdrom of=cd.iso # for cdrom
dd if=/dev/scd0 of=cd.iso # if cdrom is scsi
2、从本地硬盘制作iso,创建一个目录,拷贝你要的文件到此目录下,使用mkisofs命令:
mkisofs -o /home/cd.iso /home/directory/
这将在/home目录下找到一个叫cd.iso的文件,里面包含/home/directory/目录下的所有文件。

Tagged with:
 

终于有了稳定的空间了

On 2009年12月11日, in IT生活, by antmanler

最近最我朝严打,众多网站被拔,可怜的appspot.com由于是众多翻墙爱好者必经之路,也未幸免于难。更悲剧的是,在严打风暴下免费用户永远都是最悲哀的,说不让你干吗你就不能干吗了,火山的免费vps是不指望用来建站了(即使你的域名已经备案)。所以痛定思痛之后决定:咱也做回上帝!用了365块大洋买了stdyun.com的一年5G空间,说实话价格并不是主要考虑因素,重点是它提供堪比vps的服务,还有对python,php的支持,昨天买的,立即就开通了,马上把wordpress装上,感觉踏实了,好歹总算有个稳定的家了,而且访问速度十分令人满意!

刚才用Dolphin连到ssh上传文件,谁知过一会就资源紧张了,连忙问了下张教主,原来是自己的进程太多了,分析可能是dolphin为没个人物单独连接一个ssh了吧,这里再次感谢stdyun.com的张教主,教会我怎么将所有连接绑定到一个进程上,赶紧收藏下:

把下面三行加到 ~/.ssh/config或者/etc/ssh/ssh_config:

Host *
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
Tagged with:
 

华为ET128 OpenSuse 3G 上网

On 2009年09月4日, in Blogbus搬家过来, IT生活, by antmanler

[牢骚]原来到交管局上”交规”也是这么痛苦的一件事……

上个月寝室网就停了,于是准备体验”无限”的快感,总在电脑城跑,老板也认识不少,折腾了几天终于能上3G了……
然后就是几天被OpenSuse折腾……还好现在好多了,已经平稳运行一个星期了.

我买的移动的G3无线上网,主要咱基本不用电脑,也要在网上爬着,这样包小时就要命了,所以买了张移动G3,20G/月,一张福建的2G/月(省外用),设备是华为的ET128.

之前给小黑做了个大手术,随即系统也投奔opensuse了,在网上查了好多ET128在linux中的配置,最后终于自动化了,鉴于网上其它资料都不是很全,所以把自己的经历写下来和大家分享.

系统:
opensuse 11.1 – 11.2M6 都行(Linux lyy 2.6.31-rc7-4-default #1 SMP 2009-08-24 17:40:12 +0200 i686 i686 i386 GNU/Linux)
其它的发行版本同理(没有一一测试),新测,在Ubuntu 9.10中可行

需要: 一般源里都有,实在不行就google下
usb_modeswitch 1.0.2 (libusb 0.1.12 is required), 把华为的光盘转换称usb modem.
WvDial 1.60 拨号软件,试了好多就着个好用,kppp貌似也行,但没成功过.

下面就是修改配置文件,随便用你喜欢的编辑器就行(in super mode):

[/etc/usb_modeswitch.conf]
如果你没有其它设备需要用usb_modeswitch的话,建议就把ET128的设备添加进去就行
ET128的 ID是12d1:1da1 (切换后会变成12d1:1d09), 可以用 lsusb | grep Huawei 查看
下面是配置文件的内容,来源(以及后面的一部分)l1nuxer

#———————————-
# HUawei ET128 TD-SCDMA/GSM
# Editor: l1nuxer
# Date: 2009-07-10

DefaultVendor=0×12d1
DefaultProduct=0×1da1

TargetVendor=0×12d1
TargetProduct=0×1da1

HuaweiMode=1

之后在终端里用root用户执行: usb_modeswitch -W, 在这一步有时候会报错,但是发现只要在 /dev 里出现 ttyACM0, ttyACM1, ttyACM2就没有问题,错误可以乎略
上一步如果成功,就可以配置wvdial了, 同样在终端里: wvdialconf

[/etc/wvdial.conf]
移动G3在这里拨号设置都一样,直接把下面的贴过去就行(当然你有多个拨号设置,可以参考wvdial的文档,进行配置):

[Dialer Defaults]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Modem = /dev/ttyACM0
Phone = 0
Idle Seconds = 300
Modem Type = USB Modem
Stupid Mode = 1
Compuserve = 0
Baud = 460800
Auto DNS = 1
Dial Command = ATDT
Ask Password = 0
ISDN = 0
Phone = *99***1#
Password = any
Username = any
Stupid Mode = 1

[拨号]
上面都搞定之后就可以拨号了, 终端命令: wvdial (如果不是默认,要跟对应拨号名称如: wvdial myg3)
如果正常的话应该是下面这个样子那么恭喜你可以畅游3g了.

–> WvDial: Internet dialer version 1.60
–> Cannot get information for serial port.
–> Initializing modem.
–> Sending: ATZ
ATZ
OK
–> Sending: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
OK
–> Modem initialized.
–> Idle Seconds = 300, disabling automatic reconnect.
–> Sending: ATDT*99***1#
–> Waiting for carrier.
ATDT*99***1#
CONNECT 2800000
–> Carrier detected. Starting PPP immediately.
–> Starting pppd at Fri Sep 4 21:03:00 2009
–> Pid of pppd: 20683
–> Using interface ppp0
–> local IP address 10.210.179.136
–> remote IP address 192.200.1.21
–> primary DNS address 211.136.17.107
–> secondary DNS address 211.136.20.203
–> Script /etc/ppp/ip-up run successful
–> Default route Ok.
–> Nameserver (DNS) Ok.
–> Connected… Press Ctrl-C to disconnect

如果出现

–> warning, no nameserver found `/etc/resolv.conf`
–> Nameserver (DNS) failure, the connection may not work.

目前我是通过手动将DNS信息(拨号时会显示)添加到 /etc/resolv.conf 文件中,同样可以畅游3g了….网上找了久未发现完美解决方法,后面我编写了个脚本,自动完成这步,断线时重新netconfig update.   解决这个问题其实很简单,少少修改一下wvdial.conf文件,在其中加入:

Init3 = AT+CGDCONT=1,”IP”,”CMNET”

即可。

DnetStats 修改版

DnetStats 修改版

[自动化脚本]
上面收工步骤固然可以上网,但是太麻烦了,于是要写个脚本自动化点….
—–USB 自动转换, 同样参考l1nuxer, 脚本在压缩包里,放到 /etc/udev/rules.d/
—–自动拨号, 在上一个脚本种实现了,只要插上无线网卡就自动拨号,更改DNS
—–拨号脚本, 挂断脚本都放在 /usr/sbin/ 种
—–流量统计:基于 DNetStats-v1.2.3, 自己增加了统计总流量和设置初始流量的功能,有图有真相:

[脚本下载及说明]

下载地址: antmanler.g3dial.tar.gz

—-conf/  文件夹里是配置文件,把里面的文件都放在 /etc中
|– g3dial/ 文件夹里面是脚本, 把里面的文件放到 /usr/sbin/ 中
|– DNetStats-v1.2.3/ 文件夹是流量统计软件源码,我修改过的,编译后可以试用,需要QT 4
|– 40-myg3modem-drivers.rules 文件,放到 /etc/udev/rules.d/里面

哦了, 拨号:直接把ET128查进去就行,然后 alt+f2 打开 dnetstats 监控流量, 上网…..
或者终端里用 g3dialon, 挂断: g3dialoff

GOOD LUCK!

Tagged with:
 

vi命令 学习

On 2009年03月27日, in Blogbus搬家过来, IT生活, by antmanler

之前发现一个很好的VI壁纸,今天在老外那里发现了一个更加形象的vi教程,分享之:
猛击这里:
Graphical vi-vim Cheat Sheet and Tutorial

vi命令图

Tagged with: