JS-Python

From OLPC
Jump to navigation Jump to search

Objective

With the increased use of Open Source software development in the field of programming, it is no wonder that we have witnessed a greater influx of better and more efficient platforms for implementing our ideas. Open source development enables programmers to have more exposure and interaction with programming communities and to imbibe the best ideas in order to come up with an eclectic program, which is more efficient in all possible ways.

The aim of this project is to integrate two highly useful platforms, Python and JavaScript in order to form an extremely powerful tool, via which it will be possible to use JavaScript functions on Python platforms. The functionality of this project is apparent in the fact that both Python and JavaScript have their own numerous advantages, but at the same time they also have their limitations.

Python forms a great tool for programming; it does not have the inbuilt features to aid in creation, packaging and distribution of various dynamic web based elements which are available in the web. These features include use of forms for data submission, use of various other web elements to provide users with an enriching experience, et al. These have become essential features of any application now. However, Python does not allow programmers to enjoy these.

On the other hand, JavaScript gives a great platform to provide users with the perfect web experience, including some major advantages like cross-browser support, validating data on the client, and being able to create more sophisticated user interfaces. JavaScript effects are also much faster to download than some other front-end technologies like Flash and Java applets. Nor do users need to download a plug-in before they can view your JavaScript. Other advantages include the fact that no extra tools are required to write JavaScript, any plain text or HTML editor will do. There is a thriving and supportive online community of JavaScript developers and information resources. However, JavaScript is not an independent language. It needs a program to act as a parasite on. JavaScript is included in HTML and PHP files to provide the web interface. But what about its functionality in open source development?

This is the question that we have to ask when we use Python to build various applications, wherein the user interface and the experience of the user forms a very important component. XPCOM or Cross Platform Component Object Model was introduced for this purpose. The goal of XPCOM is to allow different pieces of software to be developed and built independently of one another. In order to allow interoperability between components within an application, XPCOM separates the implementation of a component from the interface. XPCOM also provides several tools and libraries that enable the loading and manipulation of these components, services that help the developer write modular cross-platform code, and versioning support, so that components can be replaced or upgraded without breaking or having to recreate the application.

XPCOM has various components to it. PyXPCOM allows for communication between Python and XPCOM, such that a Python application can access XPCOM objects, and XPCOM can access any Python class that implements an XPCOM interface. With PyXPCOM, a developer can talk to XPCOM from a Python application. Similarly, XPConnect forms the JavaScript-XPCOM Bridge. But these interfaces create additional and complex programs. When we are faced with situations involving updating or memory retrieval, it would involve using a Javascript function on a Python interface. The reason why PyXPCOM is useful is because it allows us to build GUIs using Mozilla as the rendering engine but the application logic using Python and Perl. It is generally much quicker to build applications with Python and Perl than it is with C/C++ . Enabling this interface will allow a new breed of applications to be built that can utilize the Web for network transport and HTML (and XUL) for building the interface, but without relying on clumsy CGI/Servlets trying to hack a real user experience with just HTML. That is the whole point of XPCOM.

In such a situation, we can develop an inter browser functionality wrapping, which would enable users to have a JavaScript experience in Python interfaces directly, without having to depend on external programs. When handling applications such as Spreadsheet, Journal, Sharing, et al, the tasks would involve saving. While the applications themselves can be built on Python based programs such as Sugar, the functions such as Saving can be easily performed using JavaScript. Instead of depending completely of an external interface such as XPCOM, we can make an inbuilt function which mobilizes the inclusion of JavaScript into Python or vice versa.


Creating a Hello World Application

To create a Hello World Application in Javascript, for Mozilla using XPCOM, we rewrite certain components for the extension we want to create. The technique we use moves the parts common to Javascript XPCOM components (factory, registration, etc.) to a single place that can be left alone the ones related to XPCOM bookkeeping (class ID, contract ID, etc.) to another that can be customized, and the code that actually does something to yet another place (xpcom.js) which is where the 99% of the writing is done.If an init() function is provided in xpcom.js, it will be run each time an instance is created (or, in the case of a service, the first time a reference is acquired).

The required files for this have been uploaded at http://wiki.laptop.org/go/Image:Myextension.zip.

STEP 1:

We prepare the skeleton for an extension. The Firefox extension wizard can be used for the same. This consists of a folder containing

1.Components folder

2.Locale Folder

3.Skin Folder

4.Content Folder

5.Chrome.manifest

6.Config

7.install.rdf


STEP 2: In the components\ directory, we create the Interface for our extension, i.e. MyComponents.idl. A very simple program has been used for this.

  1. include "nsISupports.idl"

[scriptable, uuid(00000000-0000-0000-c000-000000000046)] interface nsIMyComponent: nsISupports {

   void reload();
   void sayHello();

};

The nsISupports.idl is included. In order to get both the right typelib and the right header we force the 'real' output from xpidl to be commented out in the generated header and includes a copy of the original nsISupports.h. Next we declare our own IDL, i.e. nsIMyComponent. Its basic function is to call the function for HelloWorld, i.e. sayHello();

STEP 3: Similarly, in the components\ directory, we create the JAVASCRIPT FILE for our extension, i.e. MyComponents.js.


STEP 4: Now we can generate a UUID for this extension, and insert it in the respective places in both MyComponent.js and MyComponent.idl. A UUID is basically a Universally Unique Identifier. It is an identifier standard used in software construction, standardized by the Open Software Foundation (OSF) as part of the Distributed Computing Environment (DCE). The intent of UUIDs is to enable distributed systems to uniquely identify information without significant central coordination. Thus, anyone can create a UUID and use it to identify something with reasonable confidence that the identifier will never be unintentionally used by anyone for anything else. It is very important for security reasons and to uniquely identify the component we have created. UUIDs can be easily generated on the Net. One such site is http://www.famkruithof.net/uuid/uuidgen. It generates a new id for every visit.


STEP 5: The next step is, compiling the .idl file and converting it into a typelib file, i.e. .xpt file. This is done using the xpidl.exe program available in the "gecko-sdk" interface.

Todo: Explain how this can be done from the XO laptop itself

STEP 6: In the content\ directory, we create an xpcom.js file. This file does the function of a Javascript function, calling the Hello World application, using the XPCOM. We also create a test.xul file, which is basically our test file, who's entry is made into the Chrome registry.

XPCOM.js is a simple javascript function declaration which defines the function sayHello(); It is defined as follows:

function init() {

   this._message = 'Hello, XPCOM world!';

}

function sayHello() {

   Components
       .classes["@mozilla.org/embedcomp/prompt-service;1"]
       .getService(Components.interfaces.nsIPromptService)
       .alert(null, 'Greeting...', this._message);

}

XUL is XML User Interface language. It is a markup language for creating user interfaces. XUL is an XML language and you can use numerous existing standards including XSLT, XPath and DOM functions to manipulate a user interface, all supported directly by Gecko. In fact, XUL is powerful enough that the entire user interface in the Mozilla application is implemented in XUL. XUL and Gecko make an excellent choice for building sophisticated Web applications. It provides a user interface toolkit, an HTML and CSS renderer with excellent standards-compliance and support for web services, all completely cross platform. It is way more reliability and usability than html. Our code consists of index.xul. The code is an xml that again specifies the components called by the sayHello() function.


STEP 7: Now we can register the extension, either by packaging and installing it or by creating a pointer to its directory. Then we can start Firefox and open chrome://myextension/content/test.xul. This runs the extension.


The Hello World Connecting Python and the Browser

Here we have proceeded a step furthur and are now working on the code for PYXPCOM.

We have made a Hello World for communication between the browser and python, using PYXPCOM. I came across a useful concept called the Python Shell.I modified the code for this and managed to make a useful Python Shell component for Firefox. You can download the code for this from

http://wiki.laptop.org/go/Image:Pyxpcomrunning.zip

Once you have the code, follow the following steps to see this running.

STEP 1: When you unzip it in the components folder and install the extension using the xpi file, you will get a shell


STEP 2: This can be used for the basic hello world component. Just type the following:

promptSvc = components.classes["@mozilla.org/embedcomp/prompt-service;1"].\

       getService(Components.interfaces.nsIPromptService)

promptSvc.alert(None, 'Greeting...', "Hello from Python")

This uses the xpcom's nsIPromptSevice to get a hello world prompt.

Project Team

Manusheel Gupta (manu@laptop.org), K.S. Preeti (kspreeti.13@gmail.com), Luke Closs (luke.closs@socialtext.com).