2011年11月6日星期日

用python写firefox extension

Technorati 标签: ,,

直接用javascript写复杂的firefox extension简直是个梦魇,而且performance也会有很多问题,还有一堆限制(同源…),而用C/C++写XPCOM又太大材小用,很不适合于prototype开发。
于是想找找直接用python来写logic的firefox extension,于是就找到了pyxpcomext
其实它也是基于PyXPCOM的,参见说明:
Why do this?
  • It gives the power of Python to Mozilla extension developers
  • Easy to setup multi-threaded tasks
  • Rapidly build cross platform extensions, no compilation issues!
  • Great base of core library functionality
  • Not limited to JavaScript
  • Provides a Python GUI toolkit to build applications (XULRunner)
How does it all work?
  • The Python extension is download and installed into a Mozilla application as a regular extension
  • Upon starting of the application, the extension is registered, and loads the internal dynamic linked libraries (python, pyxpcom and pydom)
  • Additional extension directories are then checked to see if there are any extensions using pyxpcom that need to be registered (and appropriately registers them)
  • The internal Python path (sys.path) is updated to reflect any "pylib" directories found in the installed extensions

OK,本着庖丁解牛的精神,这里给出一个step by step的python extension

必备


首先要做firefox extension,当然得有firefox咯(废话,这里使用ff 3.6),要做xpi当然也得有zip工具了,linux下这不是问题,win上可以去找UnxTools,或者也可以使用ff的Extension Developer
至于像FireBugExplore ChromeJavascript Debugger等等,就看你的心情咯~~~
其次,既然要PyXPCOM,装pyxpcomext先,这个是平台相关的,win/lnx会有不同的xpi:
http://pyxpcomext.mozdev.org/downloads.html
还有,既然俺们好歹也算是个XPCOM,总得搞个XulRunner-SDK/Gecko-SDK玩玩啊,其实主要我们也只是用它帮我们compile一下idl~~~

动工


如果有firefox extension开发经验,到这一步已经很简单了~~~
首先先做个简单的框架,把下面几个文件按部就班找个sample抄一下:
chrome.manifest
install.rdf
content/
    overlay.xul
    overlay.js
components/
然后定义IDL(components/pyIDemo.idl)
#include "nsISupports.idl"      
#include "nsIVariant.idl"
[scriptable, uuid(2B3D3376-3312-4a2d-8A1E-C93AAFBC8EF7)]
interface pyIDemo: nsISupports {
    // attributes, constants, methods, ...
    nsIVariant doPythonCmd(in wstring code);
};
写python的实现(components/pyDemo.py)
import os      
import sys
import time
import traceback
from cStringIO import StringIO
from xpcom import components, ServerException, nsError
from xpcom.server import WrapObject
class pyDemo:
    _com_interfaces_ = [components.interfaces.pyIDemo]
    _reg_clsid_ = "{ED590407-D31B-4076-8D3C-3AFA999960A8}"
    _reg_contractid_ = "@zouf.trendmicro.com.cn/pyDemo;1"
    _reg_desc_ = "Python Plugin Demo"
    pyshellGlobals = {
        # Give away some free items...
        "os": os,
        "sys": sys,
        "time": time,
        # And xpcom accessors.
        "components": components,
        "Components": components
    }
    def __init__(self):
        pass
    def doPythonCmd(self, code):
        # Ensure the code ends with an empty newline
        try:
            try:
                result = code + 'Hello'
                try:
                    # See if the result can be turned into an xpcom object
                    return WrapObject(result, components.interfaces.nsIVariant)
                except ValueError:
                    # else, we'll just return a string representation
                    return repr(result)
            except SyntaxError:
                return self._exec_code_and_get_output(code)
        except Exception, e:
            # Format the exception, removing the exec/eval sections.
            exc_tb = traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)
            return "".join(exc_tb[:1] + exc_tb[3:])
这个python就太简单不过了,只是在输入的wstring上在加个Hello把它返回~~~
好,实质内容都有了,下一步就是让javascript做个中转器,帮UI来调用python了,这个我们把它放在overlay.js里:
function do_cmd() {      
    _pySvc = Components.classes["@zouf.trendmicro.com.cn/pyDemo;1"].
                    getService(Components.interfaces.pyIDemo);
    alert(_pySvc.doPythonCmd('abc'));
}
OK,基本上到这一步你的coding工作就完成了,当然实际上在这一步你会花费数百倍的精力去写你的python logic~~~
下一步就是收尾,打包,一下的简单批处理可以帮忙(build.cmd)
@echo off
SET XUL_PATH=D:\projects\xulrunner-sdk
SET PATH=%XUL_PATH%\bin;%PATH%
xpidl -I %XUL_PATH%\idl -I components -o components/pyIDemo -m typelib components/pyIDemo.idl
zip pydemo.xpi install.rdf chrome.manifest pydemo.jar -r components -r content -r locale
它干的活也很干净,只是编译IDL,zip打包,出XPI,大功告成~~~
最后把出来的xpi拖到你的ff里试试吧,看看能不能出结果?
#END#

没有评论:

发表评论

Test Ads
Hello World