Dec 13

微软效仿Eclipse推Visual Studio 2008 Shell平台
2007年06月13日 上午 11:06
Visual Studio以插件的形式支持非微软语言也有多个年头了。但是,Visual Studio高昂的价格使它很难成为第三方语言开发者的平台。随着Visual Studio 2008 Shell计划的宣布,这一情况有望得到改善。

从字面上理解,Visual Studio 2008 Shell只是一个没有编译器的Visual Studio内核。VS Shell是完全免许可费(License Fee)和版权费(Royalty Fee)的,这使得它很适合作为不同语言的统一平台。

VS Shell包能以两种模式部署。集成模式(Integrated Mode)将包融合到标准的Visual Studio环境,也就是说,现在开发者在一个平台上既可以使用传统的VS语言,如C++、VB或者C#等,也可以使用像IronPython等比较新的语言。

第二种模式,就是为人熟知的独立模式(Isolated Mode),它更多地是应用开发而不是语言开发。比如在Visual Studio Shell网站上展示了一个名为“Fabrikam Home Automation Studio”的终端用户应用,这个应用更像是一个定制的工具,而非典型的编程语言工具,因为它带有只为自己所需而定制的工具条和菜单等。这种情况可以理解为Visual Studio Express的一个通用场景,尽管技术上他们共享一个IDE,但每个版本之间都是独立的。

VS Shell不支持任何微软的工具或者内建语言。但是,如果用户有一套付费的Visual Studio SKU(Standard/标准版,Professional/专业版,或者Team System/团队协作版),这些工具和语言就会和VS Shell包一起以集成模式的方式提供。

VS2008 Shell简直是对于我们这些菜鸟的福音啊。脱离asp.net写python或者php最不习惯的就是缺少一个native & powerful 的IDE,现在有了VS2008 Shell,简直爽YY了

给几个下载:
Integrated mode
http://download.microsoft.com/download/b/0/1/b01bf855-24ad-43ce-b488-b12854eb8fde/vs_ideredist.exe
Isolated mode
http://download.microsoft.com/download/e/5/7/e5790d53-3010-46a4-882f-b10d6eac4172/vs_AppEnvRedist.exe
IronPython Studio
http://www.codeplex.com/Project/Download/FileDownload.aspx?ProjectName=IronPythonStudio&DownloadId=23452

Nov 13

Django官方文档关于flatpages上写到:

Installation
To install the flatpages app, follow these steps:

Add ‘django.contrib.flatpages’ to your INSTALLED_APPS setting.
Add ‘django.contrib.flatpages.middleware.FlatpageFallbackMiddleware’ to your MIDDLEWARE_CLASSES setting.
Run the command manage.py syncdb.

这里官方文档写得不完整,其实应该有5步:

  1. 在settings.py里添加’django.contrib.flatpages’ 到 INSTALLED_APPS
  2. 把 ‘django.contrib.flatpages.middleware.FlatpageFallbackMiddleware’ 添加到 MIDDLEWARE_CLASSES
  3. 找到当前调试用的域名,修改settings.py里SITE_ID的值
  4. 在urls.conf最后添加上 (r'', include('django.contrib.flatpages.urls')),
  5. 运行 manage.py syncdb

缺少了任何一步,flatepages都不会成功。

Nov 08

Python本来有一个解码gzip流非常方便的方法 string.decode(’zip’) ,但是要求string包含一个gzip头 ‘x\x9c’ 和尾部4 byte的CRC32校检值,所以平时HTTP抓取的gzip流就无法用 .decode(’zip’) 方法解了,只有用 zlib 库。
zlib.decompressobj().decompress('x\x9c' + binary_str)
这个方法不需要尾部4 byte的CRC校检值,但是还是需要手动添加一个 ‘x\x9c’ 的标志头。还将就吧。

Oct 30

I am transferring my GTalkBot From XMPPPy to PyXMPP, but PyXMPP’s echobot.py example does not work with Google Talk, I tried Mikal’s patch and got it work!

Here is the patched source for echobot.py

#!/usr/bin/python -u## This example is a simple "echo" bot## After connecting to a jabber server it will echo messages, and accept any# presence subscriptions. This bot has basic Disco support (implemented in# pyxmpp.jabber.client.Client class) and jabber:iq:vesion.
import sysimport loggingimport localeimport codecs
From pyxmpp.all import JID,Iq,Presence,Message,StreamErrorFrom pyxmpp.jabber.client import JabberClientFrom pyxmpp import streamtls
class Client(JabberClient):    """Simple bot (client) example. Uses `pyxmpp.jabber.client.JabberClient`    class as base. That class provides basic stream setup (including    authentication) and Service Discovery server. It also does server address    and port discovery based on the JID provided."""
    def __init__(self, jid, password):
        # if bare JID is provided add a resource -- it is required        if not jid.resource:            jid=JID(jid.node, jid.domain, "Echobot")
        # setup client with provided connection information        # and identity data        tls = streamtls.TLSSettings(require=True, verify_peer=False)        auth = [ 'sasl:PLAIN' ]
        JabberClient.__init__(self, jid, password,            disco_name="PyXMPP example: echo bot", disco_type="bot",            tls_settings=tls, auth_methods=auth)
        #        disco_name="PyXMPP example: echo bot", disco_type="bot")
        # register features to be announced via Service Discovery        self.disco_info.add_feature("jabber:iq:version")
    def stream_state_changed(self,state,arg):        """This one is called when the state of stream connecting the component        to a server changes. This will usually be used to let the user        know what is going on."""        print "*** State changed: %s %r ***" % (state,arg)
    def session_started(self):        """This is called when the IM session is successfully started        (after all the neccessery negotiations, authentication and        authorizasion).        That is the best place to setup various handlers for the stream.        Do not forget about calling the session_started() method of the base        class!"""        JabberClient.session_started(self)
        # set up handlers for supported  queries        self.stream.set_iq_get_handler("query","jabber:iq:version",self.get_version)
        # set up handlers for  stanzas        self.stream.set_presence_handler("available",self.presence)        self.stream.set_presence_handler("subscribe",self.presence_control)        self.stream.set_presence_handler("subscribed",self.presence_control)        self.stream.set_presence_handler("unsubscribe",self.presence_control)        self.stream.set_presence_handler("unsubscribed",self.presence_control)
        # set up handler for        self.stream.set_message_handler("normal",self.message)
    def get_version(self,iq):        """Handler for jabber:iq:version queries.
        jabber:iq:version queries are not supported directly by PyXMPP, so the        XML node is accessed directly through the libxml2 API.  This should be        used very carefully!"""        iq=iq.make_result_response()        q=iq.new_query("jabber:iq:version")        q.newTextChild(q.ns(),"name","Echo component")        q.newTextChild(q.ns(),"version","1.0")        self.stream.send(iq)        return True
    def message(self,stanza):        """Message handler for the component.
        Echoes the message back if its type is not 'error' or        'headline', also sets own presence status to the message body. Please        note that all message types but 'error' will be passed to the handler        for 'normal' message unless some dedicated handler process them.
        :returns: `True` to indicate, that the stanza should not be processed        any further."""        subject=stanza.get_subject()        body=stanza.get_body()        t=stanza.get_type()        print u'Message From %s received.' % (unicode(stanza.get_from(),)),        if subject:            print u'Subject: "%s".' % (subject,),        if body:            print u'Body: "%s".' % (body,),        if t:            print u'Type: "%s".' % (t,)        else:            print u'Type: "normal".' % (t,)        if stanza.get_type()=="headline":            # 'headline' messages should never be replied to            return True        if subject:            subject=u"Re: "+subject        m=Message(            to_jid=stanza.get_from(),            from_jid=stanza.get_to(),            stanza_type=stanza.get_type(),            subject=subject,            body=body)        self.stream.send(m)        if body:            p=Presence(status=body)            self.stream.send(p)        return True
    def presence(self,stanza):        """Handle 'available' (without 'type') and 'unavailable' ."""        msg=u"%s has become " % (stanza.get_from())        t=stanza.get_type()        if t=="unavailable":            msg+=u"unavailable"        else:            msg+=u"available"
        show=stanza.get_show()        if show:            msg+=u"(%s)" % (show,)
        status=stanza.get_status()        if status:            msg+=u": "+status        print msg
    def presence_control(self,stanza):        """Handle subscription control  stanzas -- acknowledge        them."""        msg=unicode(stanza.get_from())        t=stanza.get_type()        if t=="subscribe":            msg+=u" has requested presence subscription."        elif t=="subscribed":            msg+=u" has accepted our presence subscription request."        elif t=="unsubscribe":            msg+=u" has canceled his subscription of our."        elif t=="unsubscribed":            msg+=u" has canceled our subscription of his presence."
        print msg        p=stanza.make_accept_response()        self.stream.send(p)        return True
    def print_roster_item(self,item):        if item.name:            name=item.name        else:            name=u""        print (u'%s "%s" subscription=%s groups=%s'                % (unicode(item.jid), name, item.subscription,                    u",".join(item.groups)) )
    def roster_updated(self,item=None):        if not item:            print u"My roster:"            for item in self.roster.get_items():                self.print_roster_item(item)            return        print u"Roster item updated:"        self.print_roster_item(item)
# XMPP protocol is Unicode-based to properly display data received# _must_ convert it to local encoding or UnicodeException may be raisedlocale.setlocale(locale.LC_CTYPE,"")encoding=locale.getlocale()[1]if not encoding:    encoding="us-ascii"sys.stdout=codecs.getwriter(encoding)(sys.stdout,errors="replace")sys.stderr=codecs.getwriter(encoding)(sys.stderr,errors="replace")
# PyXMPP uses `logging` module for its debug output# applications should set it up as neededlogger=logging.getLogger()logger.addHandler(logging.StreamHandler())logger.setLevel(logging.INFO) # change to DEBUG for higher verbosity
if len(sys.argv)<3:    print u"Usage:"    print "\t%s JID password" % (sys.argv[0],)    print "example:"    print "\t%s test@localhost verysecret" % (sys.argv[0],)    sys.exit(1)
print u"creating client..."c=Client(JID(sys.argv[1]),sys.argv[2])
print u"connecting..."c.connect()
print u"looping..."try:    # Component class provides basic "main loop" for the applitation    # Though, most applications would need to have their own loop and call    # component.stream.loop_iter() From it whenever an event on    # component.stream.fileno() occurs.    c.loop(1)except KeyboardInterrupt:    print u"disconnecting..."    c.disconnect()
print u"exiting..."
Oct 29

每次新建一个python都要写coding:utf-8之类的,麻烦。干脆修改注册表,添加一个模板

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\.py\ShellNew]
“FileName”=”E:\\Python\\install\\模板.py”

E:\Python\install\模板.py 内容为:
[code:python]
#!/usr/bin/env python
#coding:utf-8

def main():
#Add your code here

if “__main__” == __name__:
main()
[/code]

这样每次可以直接在资源管理器里 右键 -> 新建 -> Python File

Oct 29

想实现类似django那样的modify while debugging功能,应该是reload()函数做的

[code:python]
#!/usr/bin/env python
#coding:utf-8

import time, settings

while 1:
reload(settings)
print settings.settings1
time.sleep(0.2)
[/code]

配置文件 settings.py:
[code:python]
#!/usr/bin/env python
#coding:utf-8

settings1 = “variable1″
[/code]

在命令行运行主脚本,然后用记事本修改settings.py的变量,可以看到变量值被即时更新了。

Oct 24

TinyUrl可以把任意长度的URL转换成 http://tinyurl.com/xxxxxx ,后面6位字符是hash。TinyUrl本身不提供API,但是我们可以方便的通过第三方API实现tinyurl的转换

>>> urllib2.urlopen(’http://remysharp.com/tinyurlapi?callback=tinyurlCallback&ur
l=http://initiative.yo2.cn/’).read()
‘tinyurlCallback(”http://tinyurl.com/25485h”);’
>>> urllib2.urlopen(’http://remysharp.com/tinyurlapi?callback=tinyurlCallback&ur
l=http://initiative.yo2.cn’).read()
‘tinyurlCallback(”http://tinyurl.com/22u9vv”);’

说几点。
1. TinyUrl最多能表示36^6 = 2176782336 个网址
2. TinyUrl有大量的重复网址,比如 http://initiative.yo2.cn/ 和 http://initiative.yo2.cn 完全是同一个网址,不同之处只是后面的 / 符号。
3. 第三方API的存在造就了Web 2.0

Oct 23
#coding:utf-8import re, urllib2re.search("td>(\d+\.\d+\.\d+\.\d+)</td", urllib2.urlopen("http://whois.ipcn.org/").read(), re.M).group(1))

对了,whois.ipcn.org在教育网和电信访问都很快,推荐用来看自己的IP

Oct 14

Python网络编程的几种方式是:mod_python, CGI, FastCGI, 几个Python Web Framework(Django, web.py)都需要用到一个组件:flup。但是flup在Windows下运行回出现错误:

Traceback (most recent call last):  File "1.py", line 7, in    WSGIServer(myapp).run()  File "C:\\Python25\\lib\\site-packages\\flup\\server\\fcgi.py", line 111, in run    sock = self._setupSocket()  File "C:\\Python25\\lib\\site-packages\\flup\\server\\fcgi_base.py", line 976, in _setupSocket    sock = socket.fromfd(FCGI_LISTENSOCK_FILENO, socket.AF_INET,AttributeError: 'module' object has no attribute 'fromfd'

网上搜索了下,得到答案:修改fcgi_base.py,找到975行把这几行注释掉

            sock = socket.fromfd(FCGI_LISTENSOCK_FILENO, socket.AF_INET,                                 socket.SOCK_STREAM)            try:                sock.getpeername()            except socket.error, e:                if e[0] == errno.ENOTSOCK:                    # Not a socket, assume CGI context.                    isFCGI = False                elif e[0] != errno.ENOTCONN:                    raise

然后把isFCGI = True改成isFCGI = False

Oct 14

Using ez_setup.py is very easy to install Python libraries, but uploading via CERNET is quit slow without proxy. I searched the maillist and found no solution. So I started to modify ez_setup.py.

Locate to line 143, add these few lines

                    version, download_base, delay, url                ); From time import sleep; sleep(delay)            log.warn("Downloading %s", url)            # Add code here            src = urllib2.urlopen(url)            # Read/write all in one block, so we don't create a corrupt file            # if the download is interrupted.            data = _validate_md5(egg_name, src.read())            dst = open(saveto,"wb"); dst.write(data)

The code will be:

                    version, download_base, delay, url                ); From time import sleep; sleep(delay)            log.warn("Downloading %s", url)            try:                proxy=os.environ["http_proxy"].split('//')[1]                url=urllib2.Request(url)                print proxy                url.set_proxy(proxy,"http")            except:                pass            src = urllib2.urlopen(url)            # Read/write all in one block, so we don't create a corrupt file            # if the download is interrupted.            data = _validate_md5(egg_name, src.read())            dst = open(saveto,"wb"); dst.write(data)

Try:

export http_proxy="http://202.115.22.x:13500"python ez_setup.py