Olivier Lalonde's blog http://syskall.com Rants on technology and startups posterous.com Wed, 10 Aug 2011 04:39:00 -0700 First "Startup Tuesday" in Shenzhen a success! http://syskall.com/first-startup-tuesdays-in-shenzhen-a-success http://syskall.com/first-startup-tuesdays-in-shenzhen-a-success

Only a few weeks ago, there seemed to be absolutely no interest for tech startups in Shenzhen, China (or at least, among the English speaking community). As a startup guy, I was pretty upset by the seemingly nonexistent community. Of course, there was Hong Kong nearby with a vibrant community but I wanted something in Shenzhen. I decided I'd prove myself wrong by creating a "Startups and technology SZ" group on a popular expat social network called ShenzhenStuff.com

It turned I was wrong about the lack of interest! The group grew to 32 members within only a few days. Within the same time frame, Michael Michelini, an American expat, and his associates were officially launching a coworking space aimed at web workers and freelancers. Talk about timing! Michael from SZTeam offered to host and run a first "Startup Tuesday" meeting which turned out to be a huge success.

Michael wrote a nice outline of the event and published his slides. The ~50 (I suck at guesstimates) attendees came from all kinds of backgrounds (technical, business, finance, curious people, etc.) and the crowd was about half foreigners, half Chinese. 

For the upcoming events, many suggestions were made: invite speakers to talk about a specific topic, co-founder "speed dating", startup weekends, pitch nights, etc. I'm particularly interested in co-founder speed dating as I'm looking for a co-founder :)

This first meeting was a huge success and Michael deserves all the credit. I would also recommend SZTeam to freelancers or anyone who is working on a startup. The people are friendly, there is a nice conference room, free coffee and the pricing is pretty cheap: hot desk for 500 RMB/month (80 USD/month) and fixed desk for 1500 RMB/month (235 USD/month).

From now on, we will try to gather the community around the Shenzhen Startup mailing list and the Startups and technology SZ group. SZTeam will continue to host Startup Tuesday every Tuesday 7pm.

I think we are on the right path to build a vibrant startup community in Shenzhen!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Wed, 01 Jun 2011 19:58:00 -0700 Adding Google's +1 (plus one) button to your Posterous http://syskall.com/adding-googles-1-plus-one-button-to-your-post http://syskall.com/adding-googles-1-plus-one-button-to-your-post

As well all know, Javascript isn’t allowed in Posterous themes. Luckily, iframes are and that’s what we’ll use to go around the no Javascript limitation.

posterous screenshot

Simply go to your Posterous dashboard, click "Settings" on the top right, then click the "Edit Theme" button and select the "Advanced tab". Now, all you have to do is paste one of the following snippets where you want the button to show up and click the "Save, I’m done!" button.

  • Standard button:

1
<iframe src="http://dev.syskall.com/plusone/?url={Permalink}" marginheight="0" marginwidth="0" frameborder="0" scrolling="no" style="border:0;width:110px;height:30px;"></iframe>

  • Tall button:

1
<iframe src="http://dev.syskall.com/plusone/?url={Permalink}&size=tall" marginheight="0" marginwidth="0" frameborder="0" scrolling="no" style="border:0;width:50px;height:60px;"></iframe>

That’s all you have to do to integrate Google +1 to your Posterous.

If you want to host the script yourself, the source code is available on Github:

git clone https://olalonde@github.com/olalonde/google-plusone-posterous.git

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Thu, 12 May 2011 10:54:00 -0700 How to write your own native Node.js extension http://syskall.com/how-to-write-your-own-native-nodejs-extension http://syskall.com/how-to-write-your-own-native-nodejs-extension

Introduction

This is a follow up to How to roll out your own Javascript API with V8. You should still be able to follow if you haven’t read it.

We will now port the code we have written for V8 to Node.js and package it for npm.

node-notify screenshot

The full source code of this tutorial is available from github:

git clone git://github.com/olalonde/node-notify.git

You can also install it through npm:

npm install notify

The code was tested on Ubuntu 10.10 64-bit and Node.js v0.5.0-pre.

Getting started

First let’s create a node-notify folder and with the following directory structure.

.
|-- build/                   # This is where our extension is built. 
|-- demo/
|   `-- demo.js              # This is a demo Node.js script to test our extension.
|-- src/
|   `-- node_gtknotify.cpp   # This is the where we do the mapping from C++ to Javascript.
`-- wscript                  # This is our build configuration used by node-waf

This fine looking tree was generated with the tree utility.

Now let’s create our test script demo.js and decide upfront what our extension’s API should look like:

// This loads our extension on the notify variable. 
// It will only load a constructor function, notify.notification().
var notify = require("../build/default/gtknotify.node"); // path to our extension

var notification = new notify.notification();
notification.title = "Notification title";
notification.icon = "emblem-default"; // see /usr/share/icons/gnome/16x16
notification.send("Notification message");

Writing our Node.js extension

The Init method

In order to create a Node.js extension, we need to write a C++ class that extends node::ObjectWrap. ObjectWrap implements some utility methods that lets us easily interface with Javascript.

Let’s write the skeletton for our class:

#include <v8.h> // v8 is the Javascript engine used by Node
#include <node.h>
// We will need the following libraries for our GTK+ notification 
#include <string>
#include <gtkmm.h>
#include <libnotifymm.h>

using namespace v8;

class Gtknotify : node::ObjectWrap {
  private:
  public:
    Gtknotify() {}
    ~Gtknotify() {}
    static void Init(Handle<Object> target) {
      // This is what Node will call when we load the extension through require(), see boilerplate code below.
    }
};

/*
 * WARNING: Boilerplate code ahead.
 * 
 * See https://www.cloudkick.com/blog/2010/aug/23/writing-nodejs-native-extensions/ & http://www.freebsd.org/cgi/man.cgi?query=dlsym
 *  
 * Thats it for actual interfacing with v8, finally we need to let Node.js know how to dynamically load our code. 
 * Because a Node.js extension can be loaded at runtime from a shared object, we need a symbol that the dlsym function can find, 
 * so we do the following:  
 */

v8::Persistent<FunctionTemplate> Gtknotify::persistent_function_template;
extern "C" { // Cause of name mangling in C++, we use extern C here
  static void init(Handle<Object> target) {
    Gtknotify::Init(target);
  }
  // @see http://github.com/ry/node/blob/v0.2.0/src/node.h#L101
  NODE_MODULE(gtknotify, init);
}

Now, we’ll have to we have to write the following code in our Init() method:

  1. Declare our constructor function and bind it to our target variable. var n = require("notification"); will bind notification() to n: n.notification().

    // Wrap our C++ New() method so that it's accessible from Javascript
     // This will be called by the new operator in Javascript, for example: new notification();
     v8::Local<FunctionTemplate> local_function_template = v8::FunctionTemplate::New(New);
    
     // Make it persistent and assign it to persistent_function_template which is a static attribute of our class.
     Gtknotify::persistent_function_template = v8::Persistent<FunctionTemplate>::New(local_function_template);
    
     // Each JavaScript object keeps a reference to the C++ object for which it is a wrapper with an internal field.
     Gtknotify::persistent_function_template->InstanceTemplate()->SetInternalFieldCount(1); // 1 since a constructor function only references 1 object
     // Set a "class" name for objects created with our constructor
     Gtknotify::persistent_function_template->SetClassName(v8::String::NewSymbol("Notification"));
    
     // Set the "notification" property of our target variable and assign it to our constructor function
     target->Set(String::NewSymbol("notification"), Gtknotify::persistent_function_template->GetFunction());
  2. Declare our attributes: n.title and n.icon.

    // Set property accessors
     // SetAccessor arguments: Javascript property name, C++ method that will act as the getter, C++ method that will act as the setter
     Gtknotify::persistent_function_template->InstanceTemplate()->SetAccessor(String::New("title"), GetTitle, SetTitle);
     Gtknotify::persistent_function_template->InstanceTemplate()->SetAccessor(String::New("icon"), GetIcon, SetIcon);
     // For instance, n.title = "foo" will now call SetTitle("foo"), n.title will now call GetTitle()
  3. Declare our prototype method: n.send()

    // This is a Node macro to help bind C++ methods to Javascript methods (see https://github.com/joyent/node/blob/v0.2.0/src/node.h#L34)
     // Arguments: our constructor function, Javascript method name, C++ method name
     NODE_SET_PROTOTYPE_METHOD(Gtknotify::persistent_function_template, "send", Send);

Our Init() method should now look like this:

// Our constructor
    static v8::Persistent<FunctionTemplate> persistent_function_template;

    static void Init(Handle<Object> target) {
      v8::HandleScope scope; // used by v8 for garbage collection

      // Our constructor
      v8::Local<FunctionTemplate> local_function_template = v8::FunctionTemplate::New(New);
      Gtknotify::persistent_function_template = v8::Persistent<FunctionTemplate>::New(local_function_template);
      Gtknotify::persistent_function_template->InstanceTemplate()->SetInternalFieldCount(1); // 1 since this is a constructor function
      Gtknotify::persistent_function_template->SetClassName(v8::String::NewSymbol("Notification"));

      // Our getters and setters
      Gtknotify::persistent_function_template->InstanceTemplate()->SetAccessor(String::New("title"), GetTitle, SetTitle);
      Gtknotify::persistent_function_template->InstanceTemplate()->SetAccessor(String::New("icon"), GetIcon, SetIcon);

      // Our methods
      NODE_SET_PROTOTYPE_METHOD(Gtknotify::persistent_function_template, "send", Send);

      // Binding our constructor function to the target variable
      target->Set(String::NewSymbol("notification"), Gtknotify::persistent_function_template->GetFunction());
    }

All that is left to do is to write the C++ methods that we used in our Init method: New, GetTitle, SetTitle, GetIcon, SetIcon, Send

Our constructor method: New()

The New() method creates an instance of our class (a Gtknotify object), sets some default values to our properties and returns a Javascript handle to this object. This is the expected behavior when calling a constructor function with the new operator in Javascript.

std::string title;
std::string icon; 

// new notification()
static Handle<Value> New(const Arguments& args) {
  HandleScope scope;
  Gtknotify* gtknotify_instance = new Gtknotify();
  // Set some default values
  gtknotify_instance->title = "Node.js";
  gtknotify_instance->icon = "terminal";

  // Wrap our C++ object as a Javascript object
  gtknotify_instance->Wrap(args.This());

  return args.This();
}

Our getters and setters: GetTitle(), SetTitle(), GetIcon(), SetIcon()

The following is pretty much boilerplate code. It boils down to back and forth conversion between C++ values to Javascript (V8) values.

// this.title
static v8::Handle<Value> GetTitle(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
  // Extract the C++ request object from the JavaScript wrapper.
  Gtknotify* gtknotify_instance = node::ObjectWrap::Unwrap<Gtknotify>(info.Holder());
  return v8::String::New(gtknotify_instance->title.c_str());
}
// this.title=
static void SetTitle(Local<String> property, Local<Value> value, const AccessorInfo& info) {
  Gtknotify* gtknotify_instance = node::ObjectWrap::Unwrap<Gtknotify>(info.Holder());
  v8::String::Utf8Value v8str(value);
  gtknotify_instance->title = *v8str;
}
// this.icon
static v8::Handle<Value> GetIcon(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
  // Extract the C++ request object from the JavaScript wrapper.
  Gtknotify* gtknotify_instance = node::ObjectWrap::Unwrap<Gtknotify>(info.Holder());
  return v8::String::New(gtknotify_instance->icon.c_str());
}
// this.icon=
static void SetIcon(Local<String> property, Local<Value> value, const AccessorInfo& info) {
  Gtknotify* gtknotify_instance = node::ObjectWrap::Unwrap<Gtknotify>(info.Holder());
  v8::String::Utf8Value v8str(value);
  gtknotify_instance->icon = *v8str;
}

Our prototype method: Send()

First we have to extract the C++ object this references. We then build our notification using the object’s properties (title, icon) and finally display it.

// this.send()
static v8::Handle<Value> Send(const Arguments& args) {
  v8::HandleScope scope;
  // Extract C++ object reference from "this"
  Gtknotify* gtknotify_instance = node::ObjectWrap::Unwrap<Gtknotify>(args.This());

  // Convert first argument to V8 String
  v8::String::Utf8Value v8str(args[0]);

  // For more info on the Notify library: http://library.gnome.org/devel/libnotify/0.7/NotifyNotification.html 
  Notify::init("Basic");
  // Arguments: title, content, icon
  Notify::Notification n(gtknotify_instance->title.c_str(), *v8str, gtknotify_instance->icon.c_str()); // *v8str points to the C string it wraps
  // Display the notification
  n.show();
  // Return value
  return v8::Boolean::New(true);
}

Compiling our extension

node-waf is the build tool used to compile Node extensions which is basically a wrapper for waf. The build process can be configured with a file called wscript in our top directory:

def set_options(opt):
  opt.tool_options("compiler_cxx")

def configure(conf):
  conf.check_tool("compiler_cxx")
  conf.check_tool("node_addon")
  # This will tell the compiler to link our extension with the gtkmm and libnotifymm libraries.
  conf.check_cfg(package='gtkmm-2.4', args='--cflags --libs', uselib_store='LIBGTKMM')
  conf.check_cfg(package='libnotifymm-1.0', args='--cflags --libs', uselib_store='LIBNOTIFYMM')

def build(bld):
  obj = bld.new_task_gen("cxx", "shlib", "node_addon") 
  obj.cxxflags = ["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall"]
  # This is the name of our extension.
  obj.target = "gtknotify"
  obj.source = "src/node_gtknotify.cpp"
  obj.uselib = ['LIBGTKMM', 'LIBNOTIFYMM']

We’re now ready to build! In the top directory, run the following command:

node-waf configure && node-waf build

If everything goes right, we should now have our compiled extension in ./build/default/gtknotify.node. Let’s try it!

$ node
> var notif = require('./build/default/gtknotify.node');
> n = new notif.notification();
{ icon: 'terminal', title: 'Node.js' }
> n.send("Hello World!");
true

The previous code should display a notification in the top right corner of your screen!

Packaging for npm

That’s pretty cool, but how about sharing your hard work with the Node community? That’s primarily what the Node Package Manager is used for: making it easy to import extensions/modules and distribute them.

Packaging an extension for npm is very straightforward. All you have to do is create a package.json file in your top directory which contains some info about your extension:

{
  // Name of your extension (do not include node or js in the name, this is implicit). 
  // This is the name that will be used to import the extension through require().

  "name" : "notify",

  // Version should be http://semver.org/ compliant

  "version" : "v0.1.0"

  // These scripts will be run when calling npm install and npm uninstall.

  , "scripts" : {
      "preinstall" : "node-waf configure && node-waf build"
      , "preuninstall" : "rm -rf build/*"
    }

  // This is the relative path to our built extension.

  , "main" : "build/default/gtknotify.node"

  // The following fields are optional:

  , "description" : "Description of the extension...."
  , "homepage" : "https://github.com/olalonde/node-notify"
  , "author" : { 
      "name" : "Olivier Lalonde"
      , "email" : "olalonde@gmail.com"
      , "url" : "http://www.syskall.com/"
    } 
  , "repository" : { 
      "type" : "git"
      , "url" : "https://github.com/olalonde/node-notify.git"
    }
}

For more details on the package.json format, documentation is available through npm help json. Note that most fields are optional.

You can now install your new npm package by running npm install in your top directory. If everything goes right, you should be able to load your extension with a simple var notify = require('your-package-name');. Another useful command is npm link which creates a symlink to your development directory so that any change to your code is reflected instantly – no need to install/uninstall perpetually.

Assuming you wrote a cool extension, you might want to publish it online in the central npm repository. In order to do that, you first need to create an account:

$ npm adduser

Next, go back to the root of your package code and run:

$ npm publish

That’s it, your package is now available for anyone to install through the npm install your-package-name command.

Conclusion

Writing a native Node extension can be cumbersome and verbose at times but it is well worth the hard earned bragging rights!

Thanks for reading. Let me know in the comments if you run into any problem, I’ll be glad to help.

If you liked this, maybe you’d also like what I tweet on Twitter! Might even want to hire me?

References

How to roll out your own Javascript API with V8

Writing Node.js Native Extensions

V8 JavaScript Engine Embedder’s Guid Part 1 (V8 extension) available here: http://syskall.com/how-to-roll-out-your-own-javascript-api-with

Introduction to npm

Node.js

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Thu, 10 Mar 2011 23:03:00 -0800 Minimalist shell in C (for educational purposes only!) http://syskall.com/minimalist-shell-in-c-for-educational-purpose http://syskall.com/minimalist-shell-in-c-for-educational-purpose

Introduction

I was kind of bored tonight so I decided to write a very minimalist shell in C. Here’s how it looks:

/*
 * DISCLAIMER: THIS CODE IS FOR EDUCATIONAL PURPOSES ONLY. USE AT YOUR OWN RISKS.
 *
 * This code shows the basic workings of a shell.
 *
 * Append "/path/to/dashell" to /etc/shells, to make it a valid shell:
 * sudo echo "/path/to/dashell" >> /etc/shells
 *
 * Change your "username"'s shell. "username" should have execute permission for the shell:
 * chsh --shell /path/to/dashell username
 *
 */

#include <unistd.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <sys/signal.h>

#define STDIN 0
#define STDOUT 1
#define STDERR 2

#define BUFFER_SIZE 1024

void parse_arguments(char buffer[], int *args_count, char *args[]) {
  char *delimiters = " \r\n";
  char *token;
  *args_count = 0;
  // "abc def ghi" => {"abc", "def", "ghi"}
  while(token = strsep(&buffer, delimiters)) {
    args[*args_count] = token;
    (*args_count)++;
  }
}

int main(int argc, const char* argv[]) {
  // The weird characters are used to format the text's appearance.
  // See http://en.wikipedia.org/wiki/ANSI_escape_code
  char prompt[] = "\033[1mdashell\033[2m>\033[0m ";
  char exec_error[] = "Cannot execute program %s.\n";
  char buffer[BUFFER_SIZE + 1];

  int args_count;
  char *args[BUFFER_SIZE];

  int n;
  while(1) {
    write(STDOUT, prompt, strlen(prompt) + 1);
    n = read(STDIN, buffer, BUFFER_SIZE); // Read from STDIN (keyboard input)
    buffer[n] = '\0'; // Null character to indicate string end

    // "abc def ghi" => {"abc", "def", "ghi"}
    parse_arguments(buffer, &args_count, args);

    // No arguments
    if(args_count == 0 || strcmp(args[0], "") == 0) continue;

    // Argument = exit
    if(strcmp(args[0], "exit") == 0) exit(0);

    pid_t child_pid = fork(); // Duplicate process
    if(child_pid == 0) {
      // Child
      if(execvp(args[0], args) < 0) { // Replace executable code by command passed
        fprintf(stderr, exec_error, args[0]);
      }
    }
    else {
      // Parent
      // Wait for child to finish
      wait();
    }
  }
}

The full source code is freely available at Github:

git clone git://github.com/olalonde/dashell.git

Note that I never code in C so it might not be perfect… I’m looking at you parse_arguments() ;)

Install & have fun

The optional steps will let you use the shell as a login shell for a given user.

  1. make

  2. (optional) Append “/path/to/dashell” to /etc/shells, to make it a valid shell:

    sudo echo "/path/to/dashell" >> /etc/shells
  3. (optional) Change “username”’s shell. “username” should have execute permission for the shell:

    chsh --shell /path/to/dashell username

Now, you can launch the shell and start having fun with it and be reminded how great bash really is!

./dashell
dashell> ls -al
dashell> ./launchme 1 2 3
....
dashell> exit

Feel free to ask questions!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Thu, 10 Mar 2011 16:24:00 -0800 Resizing a VDI in VirtualBox 3 with one command http://syskall.com/resizing-a-vdi-in-virtualbox-3-in-one-command http://syskall.com/resizing-a-vdi-in-virtualbox-3-in-one-command

Here’s a quick way to expand a (VDI) Virtual Disk Image in VirtualBox 3.

  1. Create a new VDI with the new size of your choice. (File / Virtual Media Manager / New…)
  2. Run this command:

    $ VBoxManage clonehd --existing old.vdi new.vdi

    This may take a few minutes.

  3. Simply replace the attached old.vdi with the new.vdi in your virtual machine’s storage settings.

  4. You will need to extend your partition from your guest OS. This can be done under Windows 7 from the control panel (Create and format hard disk partitions) and with GParted in Ubuntu and compatible Linux distributions.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Sat, 26 Feb 2011 14:43:00 -0800 How to roll out your own Javascript API with V8 http://syskall.com/how-to-roll-out-your-own-javascript-api-with http://syskall.com/how-to-roll-out-your-own-javascript-api-with

Update: I wrote a new tutorial on porting our V8 code as a Node.js extension: How to write your own native Node.js extension.

Introduction

This tutorial will teach you how to:

  1. Compile the V8 Javascript engine
  2. Bind a Javascript function to your own C++ function

For the sake of demonstration and to impress your co-workers, we will bind a Javascript function “alert()“ that will display desktop notifications through the GTK library. Here’s what the end result looks like:

jsnotify screenshot

You can get the full source code of this tutorial from github:

git clone git://github.com/olalonde/jsnotify.git

This tutorial was tested on Ubuntu 10.04 and 10.10 64-bit but should work fine on any Linux distribution. The notification part requires the GTK+ library.

Compiling Google’s V8 Javascript engine

First, let’s make sure we have all the required tools and dependencies to compile.

sudo apt-get install build-essential scons subversion
  • The build-essential package is a meta package that installs all the necessary tools and libraries to compile C++ programs.
  • SCons is a build tool which attempts to replace the classic “make” and is used by the V8 project.
  • Subversion is needed to checkout the source code of V8.

Now, let’s grab V8’s source from the official repository:

svn checkout http://v8.googlecode.com/svn/trunk/ v8

We can now move into the V8 directory and try to compile!

cd v8;
scons arch=x64;

The “arch=x64” option specifies that we want to build a 64-bit version of V8 (the default value would be 32-bit otherwise).

If V8 compiled fine, you should now have a libv8.a file in your v8/ directory. As you probably guessed, libv8.a is the library that our C++ program will use to execute Javascript code.

So, if everything compiled fine, just skip to the next section. Otherwise, keep on reading.

When you get errors as a result of compiling third party code, it is usually due to the fact that the compiler can’t find required libraries (/usr/lib) and/or their associated header files (/usr/lib/include). The latter are usually available through packages conventionally named libname-dev . In order to find out which package installs a given file, there is a neat utility called apt-file.

sudo apt-get install apt-file;
apt-file search missing-header-file.h;

The apt-file search command lists the package(s) that install a given file (missing-header-file.h in this case). If there are more than one package listed, we have to take a semi-educated guess on which package we should install based on its name (let me know in the comments if you know of a better trick!). We then simply install the package with the usual apt-get install package-name command.

Hint: If you are on Ubuntu 10.04, you might need to install the following packages:

sudo apt-get install libc6-dev-i368 lib32stdc++6

Now that we’ve installed all the missing files, the compilation should work. Let’s move on to the next section.

If you are still stuck with compiling V8, this tutorial might help.

Building our own Javascript API

Now that we have successfully compiled the V8 library, we will build our own C++ project that will be “Javascript scriptable”. This means that our program will be able to run Javascript code which in turn will be able to call our custom C++ functions.

Note: You can also get the full source code of this tutorial from my jsnotify github repository): git clone git://github.com/olalonde/jsnotify.git

First let’s create our file structure.

jsnotify/
  |-- deps/  # third party code
  |   `-- v8  # move your v8 folder here
  `-- src/ # our code goes here
      `-- jsnotify.cpp

Now let’s copy the sample code available at deps/v8/samples/shell.cc and paste it into jsnotify.cpp. The sample code given by V8 let’s you execute a Javascript file or start an interactive Javascript shell. It also binds some useful Javascript functions such as print() which will output text to the terminal.

Let’s try to compile this!

g++ src/jsnotify.cpp;

Of course, this gives us a bunch of errors since we haven’t specified where the V8 header and library files are. Let’s try again!

g++ src/jsnotify.cpp -Ideps/v8/include -Ldeps/v8/ -lv8

Oops, still some errors. Looks like we also have to link the pthread library.

g++ src/jsnotify.cpp -Ideps/v8/include -Ldeps/v8/ -lv8 -lpthread

This finally compiles! Now that we have our mini Javascript shell, let’s play a bit with it.

$ ./a.out 
V8 version 3.1.5
> var foo = “Hello World”;
> print(foo);
Hello World

Now, all we have to do is to create our custom alert() function in C++.

// INSERT THIS BEFORE int RunMain(int argc, char* argv[]) {
// We need those two libraries for the GTK+ notification 
#include 
#include 
v8::Handle Alert(const v8::Arguments& args);

// INSERT THIS AT END OF FILE   
// The callback that is invoked by v8 whenever the JavaScript 'alert'
// function is called.  Displays a GTK+ notification.
v8::Handle Alert(const v8::Arguments& args) {
  v8::String::Utf8Value str(args[0]); // Convert first argument to V8 String
  const char* cstr = ToCString(str); // Convert V8 String to C string

  Notify::init("Basic");
  // Arguments: title, content, icon
  Notify::Notification n("Alert", cstr, "terminal");
  // Display notification
  n.show();

  return v8::Undefined();
}

Now that we have our Alert C++ function, we need to tell V8 to bind it to the Javascript alert() function. This is done by adding the following code in the RunMain function:

// INSERT AFTER v8::Handle global = v8::ObjectTemplate::New();
// Bind the global 'alert' function to the C++ Alert callback.
global->Set(v8::String::New("alert"), v8::FunctionTemplate::New(Alert));

Now, in order to compile, the compiler needs to know where to find the two header files we introduced. This is done using the pkg-config utility:

g++ src/jsnotify.cpp -Ideps/v8/include -Ldeps/v8/ -lv8 -lpthread pkg-config --cflags --libs gtkmm-2.4 libnotifymm-1.0

We can now try our new alert function.

$./a.out 
V8 version 3.1.5
> alert(“wow, it works!”);

You should see a nice notification in the top right of your screen! Note that you can also put you Javascript code in a file and pass the file name as an argument ./a.out filename.js.

Conclusion

It’s quite easy to make a C++ program “Javascriptable” with V8 and the proper setup. If you’d like to practice your newfound skills, I suggest you try to add a title argument to the alert function. You might also want to follow me on Posterous in order to be informed when I post the follow up to this tutorial on how to extend Node.js with our alert function.

That’s all for today, thanks for reading! Let me know in the comments if you run into any problem, I’ll be glad to help.

If you liked this, maybe you’d also like what I tweet on Twitter!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Mon, 14 Feb 2011 20:53:00 -0800 The benefit of hindsight http://syskall.com/twttr-and-the-benefit-of-hindsight http://syskall.com/twttr-and-the-benefit-of-hindsight

I recently stumbled upon a quite interesting piece of history buried in TechCrunch's archives. It's a July 2006 article written by Michael Arrington which introduces a "sort of “group send” SMS application" as he described it at the time. For those who haven't guessed yet, the "application" he is referring to is now known as Twitter, a 190 million users strong social network and company currently valued at around $10 billion. Yet, at the time, very few people believed the startup had any chance of success and even fewer could have predicted it would grow to become a billion dollar company. 

Here are some gems from the article and comments. It would be superfluous to comment them as I believe they speak for themselves. If you find yourself laughing at this (as I did), take a moment to realize just how wonderful the benefit of hindsight is. 

All comments date from 2006. I didn't include the names of the commenters (but they aren't really hard to find).

There is also a privacy issue with Twttr. Every user has a public page that shows all of their messages. Messages from that person’s extended network are also public. I imagine most users are not going to want to have all of their Twttr messages published on a public website. 

I do not understand the utility of adding the SMS messages to a public webpage or making messages from my network public. I would have to pass on that type of offering. The ability to make messages private should be added asap. 

Odeo was a failure from the get go. No revenue model. I asked their VC - CRV - what the revenue model was a year ago and he said "to sell to someone bigger." Okay, that was a web 1.0 answer, and now we get Twttr - an even dumber idea with no revenue model, but a 2.0 concept.

I think this is the dumbest thing ever! Who would want all their personal text messages on a public website for anyone to read and track? 

Not innovative and not focused. Twttr sounds like a disaster in the making...

i do not want to be woken up at 4 a.m. because my friend got drunk and decided to text Twttr with "asdl im at barasdf sooo drunksalkfjs"...i find it interesting such an annoying feature is supposedly causing viral growth...i'm done developing social software if the key to success is to be intrusive 

Finally, a last blog comment that caught my attention on an other old Twitter article:

It's kinda wierd, John Resig and I had been thinking about building this exact system, though it never really got past the, "Wouldn't it be cool if" stage. Meh, I'm just glad it exists now. It was a personal itch I wanted to scratch and I'm not going to complain at all if someone else scratches it. Plus the Odeo guys made it much prettier than I would have. - Bob Aman

I'd be curious to know if the John Resign being referred to is the same guy who went on to build jQuery. Did John Resig really almost build a Twitter before Twitter?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Tue, 09 Nov 2010 22:56:00 -0800 MultiVac, the line tracking robot http://syskall.com/multivac-the-line-tracking-robot http://syskall.com/multivac-the-line-tracking-robot

Here's a line tracking robot I built with friends at university. I thought I would post it here before it sinks into oblivion. It was built using a 16bit micro-controller (ATmega16), a PCB, a small motor and some sensors. The programming was done in C/C++. Source code and hardware (if you can pick it up - Montreal) available upon request.

Any ideas of how I could turn it into something useful? I also got a proximity sensor if that can be of any use.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Sat, 25 Sep 2010 13:13:00 -0700 HN Crunch: Greasemonkey script for Hacker News http://syskall.com/hn-crunch-greasemonkey-script-for-hacker-news http://syskall.com/hn-crunch-greasemonkey-script-for-hacker-news

I've just written HN Crunch, a little Greasemonkey script for Hacker News which adds a profile picture next to the username of HN members who have their own CrunchBase profile. The script is is open source.

Screenshot:
Hncrunch

Right now, it doesn't have many HN users in it so please help me complete the list in the comments below or in the HN thread by writing the username / CrunchBase URL pair. To try it in action, I suggest you head over to pg's thread list.

Updated list:
  • pg: paul-graham
  • spolsky: joel-spolsky-2
  • a4agarwal: sachin-agarwal
  • techcrunch: michael-arrington
  • epi0Bauqu: gabriel-weinberg
  • AndrewWarner: andrew-warner
  • swombat: daniel-tenner
  • dhh: david-heinemeier-hansson
  • daniel_levine: daniel-levine
  • bkrausz: brian-krausz
  • 'mceachen: matthew-mceachen
  • rgrieselhuber: ray-grieselhuber
  • rdamico: ryan-damico
  • jon_dahl: jon-dahl
  • answerly: joe-fahrner
  • jlm382: jessica-mah
  • brianchesky: brian-chesky
  • billclerico: bill-clerico
  • dhouston: drew-houston
  • danielha: daniel-ha
  • rantfoil: garry-tan
  • petesmithy: pete-smith
  • justin: justin-kan
  • gduffy: greg-duffy
  • spencerfry: spencer-fry
  • thinkcomp: aaron-greenspan
  • jack7890: jack-groetzinger'

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Wed, 24 Feb 2010 13:39:00 -0800 Why we should eradicate "agnosticism" from the dictionary! http://syskall.com/why-we-should-eradicate-agnosticism-from-the http://syskall.com/why-we-should-eradicate-agnosticism-from-the

This is a follow-up to a very interesting thread on HN.

From Wikipedia: Agnosticism is the view that the truth value of certain claims—especially claims about the existence of any deity, but also other religious and metaphysical claims—is unknown or unknowable. ...

Before I start, let me illustrate my point. Assume the following statements are true:

  • We currently live in the Matrix.
  • There is absolutely no interaction between our universe and the Matrix.
  • There is no way to escape the Matrix.
  • The laws of our universe remain unchanged.
  • There is no imaginable experiment that could even subtly hint the existence of the Matrix.

Given those assumptions, you can't prove or disprove the existence of the Matrix, be it through a thought experiment or a physical experiment.

That makes you a Matrix agnostic. In fact, the amount of things we have to be agnostic about is only limited by our collective imagination: it could be that our universe is an "atom" inside a much larger universe, it could be that life is an illusion induced by some sort of dream, etc.

As expected, there are tons of naive counter-arguments to this assertion. Let me quote philwelch, as he said it better than I ever could:

The standard answer is that all of our naive beliefs about the world would be false. You are not actually sitting on a couch, your simulated body-projection is simulated to be sitting on a simulated couch. The very fact we can't tell whether or not we're in the matrix undermines all our knowledge.

The more insightful answer is that even if we're in the matrix, everything about the physical world is still true, there is just a metaphysical fact we are unaware of--namely, that the universe happens to be a simulation. You're still sitting on a couch, and the couch is still made of atoms, and the atoms are still made of subatomic particles and so forth, but it turns out all the subatomic particles are just data structures in the matrix and we didn't know that before. Nothing is undermined.


Let me expand this reasoning a little further:

  • Is there a point in knowing if the Matrix does indeed exist ?
  • Will it change anything about our knowledge of the physical universe ?
  • Will it change the way we live our lives ? 

Answer: No.

Any metaphysical statement that can't be evidenced, even subtly, through physical experiments is simply meaningless. On a side note, it is important to note that the fundamental laws of our universe, which could also be classified as metaphysical statements since they describe the physical - the precise definition of metaphysical, can be determined through experiments and that's what makes them meaningful.

In other words, agnosticism is simply a word that means "can't know the unknowable", which is quite redundant. I'm pretty sure everyone can agree, theists and atheists included, that it is impossible to know the unknowable. You either believe there is a God because you think there is evidence for it - be it through the Bible, the Torah, prophets, miracles, martyrs or this inner connection with God that some call faith -  or you don't if you believe there is no evidence for God. Following that line of thought, agnosticism, as in believing that God is unknowable, equates to atheism, as in believing there is no evidence for God.

In conclusion, I suggest that we eradicate this meaningless word from the dictionary!

I'm looking forward to answer your thoughts and counter-arguments in the comments!

PS: This rant was intentionally extremist as I wanted to make my point as clear as possible. I'm actually a very nuanced person and I have nothing against agnostics. Perhaps the definition of agnosticism should be changed to: "Person who believes there is some evidence for God, but not enough to take a position."

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Sat, 13 Feb 2010 13:08:00 -0800 Project Idea: TL;DR browser add-on http://syskall.com/project-idea-tldr-browser-add-on http://syskall.com/project-idea-tldr-browser-add-on

This is a follow-up to a question I asked on Answers.OnStartups.com. Here's how it goes:

I often find myself reading long blog posts and articles only to find out that I already knew most of what was discussed. Other times, I find out that the topic wasn't really relevant to my interest. Indeed, headlines are often misleading.

That's what lead me to the following idea: a browser add-on that would overlay short and concise TL;DR (Too Long; Didn't Read) summaries over web pages. The system would be community driven and moderated: anyone could add their own summary of the content and the best TL;DR messages would be up voted by the community. Additionally, as suggested by Jason, authors could be allowed to write their own official summary.

My bet is that this system could be valuable to people faced with too much information and too little time. It could be successful in the same way Twitter's 140 characters limit contributed to its success: reducing information overload and increasing signal-to-noise ratio.

As anticipated, there is already a good deal of browser add-ons for annotating web pages, but none of them explicitly promote the usage that I am describing. I will be working on this little add-on in my free time and hope it'll eventually gain enough traction to really become useful. I'm open to constructive criticism and suggestions: just leave your thoughts in the comments !

TL;DR: Community-driven Firefox add-on that overlays short summaries next to long texts.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Sun, 07 Feb 2010 11:30:29 -0800 Project Idea: AJAX without writing a single line of Javascript http://syskall.com/project-idea-ajax-without-writing-a-single-li http://syskall.com/project-idea-ajax-without-writing-a-single-li I had this idea of a Javascript library for rapidly implementing / prototyping AJAX on a web page. Here is how it would work:
  1. User clicks a link on a page.
  2. Javascript requests a server side script through an AJAX request and passes the HREF attribute of the link as a parameter target_url.
  3. The server script DIFFs the target page with the current page and returns a JSON string containing every modifications of the DOM. The format could be as such:
[
   {
       "action" : "delete",
       "path" : "/p[1]"
   },
   {
       "action" : "modify",
       "path" : "/ul[1]/li[1]",
       "node" : {
           "innerHTML" : "modified 1st line",
           "attributes" : {
               "class" : "testClass"
           }
       }
   },
   {
       "action" : "insert",
       "parentPath" : "/ul[1]",
       "siblingPath" : "/li[3]",
       "node" : {
           "tagName" : "li",
           "innerHTML" : "should insert after 2nd item",
           "attributes" : []
       }
   }
]

This would delete the first paragraph, modify the 1st list item in the 1st unordered list and insert a new list item before the 3rd list item in the first unordered list.

A use case of this library could be for a blog with a "Show comments" link. Instead of the browser reloading the entire page with blog comments enabled when clicking the link, the request would be sent asynchronously to the server script which would return the appropriate DOM modifications to display the comments. Of course, this particular example could easily be implemented with trivial Javascript, but my point was to show how it would work in "real life".

Limitations of this technique:

  • innerHTML isn't (yet) a standard
  • Blindly manipulating the DOM might interfere with other Javascript code already present on the page
  • The entire process would have to be faster than actually loading the target page
Benefits of this technique:
  • It could be used to unobtrusively implement AJAX without having to write a single line of Javascript, resulting in a productivity increase.
  • It could possibly be used as a browser add-on to enable faster page rendering. (This idea came from my frustration of having to wait for the whole DOM to be re-rendered by web browsers when clicking links within a site. Often times, a big part of the DOM structure remains the same and yet, your browser has to render everything once again.)
In a nutshell:
  • This technique should be used for productivity boosts and on pages that share a similar layout.
I had a hard time putting this idea into words and I hope I made myself clear. I would appreciate some feedback from fellow developers!

PS: So far, I've done most of the Javascript implementation. If anyone is willing to help for the server script, let me know!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde
Sun, 07 Feb 2010 09:52:00 -0800 Who am I and what you can expect to find here http://syskall.com/who-am-i-and-what-can-you-expect-to-find-here http://syskall.com/who-am-i-and-what-can-you-expect-to-find-here

Hi! I'm Olivier Lalonde, a Software Engineering student at École Polytechnique, Montreal. I've been programming professionally for many years, both as a freelancer and as a full time employee. I've also worked on many small projects of my own, some of which were successful and some others not. Sadly, the most successful so far was an invoicing manager I built during summer when I was 15, which brought me close to 10K$ in revenues, which was a large some at the time. I've also co-founded Wozad, a behavioral advertising network that we decided to dead pool following Google's announcement to get in the behavioral marketing game. My current language of choice is PHP although I've recently started using Ruby which I enjoy so far.

I am an entrepreneur at heart and programmer by profession. Don't get me wrong: I do enjoy programming and solving complex problems very much but consider programming as a tool as opposed to an end in itself.

My interests include: web development and open standards, startups, user experience and innovation. This what I will write about on this blog most of the time.

My current projects are:
Voz Labs: my web development shop.
iRosetta: a StackExchange powered Q&A site for language.
dORM: an ORM for PHP.

You can also find me here:
olalonde @ Hacker News
olalonde @ Answers.OnStartups.com
o_lalonde @ Twitter

E-mail: olalonde@gmail.com

I'm a casual blogger and English isn't my native language. I write this blog first for myself in order to help my limited memory, put some order in my thoughts and practice my written English skills. Don't expect professional journalism from this blog !

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/424868/n516031489_1728504_5735.jpg http://posterous.com/users/3tk57CsrywqR Olivier Lalonde Olivier Olivier Lalonde