Twitter LinkedIn Github

A Quick Rust tip (Comparing Strings)



I have been learning rust recently and so wanted to start tracking things that I’ve learned.

You can learn a lot more about strings in rust via this explainer but one thing I got hung up on was comparing strings.

There are two types of strings in rust, &str and String. It seems that rust is pretty good about deciding which type you want a "some string" to be, but I was having trouble doing something like this:

    let mut guess = String::new();

    io::stdin().read_line(&mut guess).expect("Failed to read line");
    
    if guess == "Q" {
        println!("Goodbye");
        break;
    }

I was worried that while guess was a String "Q" was a &str. Turns out the issue was with the way the read_line formats the string when reading it. By default there is a newline character at the end of the string so you need to use trim().

    let mut guess = String::new();

    io::stdin().read_line(&mut guess).expect("Failed to read line");
    
    if guess.trim() == "Q" {
        println!("Goodbye");
        break;
    }




Behind the Scenes with nil? and empty?



At their base level the ruby methods nil? and empty? are just contents checks with slightly different focuses. But I thought it would be interesting and maybe even useful to look at how each actually opperates.

Why are you writing this

Mostly just for shits and giggles, and because I was currious about the core implementations of these methods.

nil?

First, let’s take a look at nil?. It is the most simplistic of the three methods and is easy to understand at a source code level. First we should know what the method does. Calling nil? simply checks the object is is called on and returns whether it is of the nil object type or not.

  nil.nil? # => true
  "".nil? # => false
  0.nil? # => false
  [].nil? # => false
  {}.nil? # => false
  NilClass.nil? # => false

If you accept that nil? will only return true if it’s owner is nil, this everything in this result set should make sense. The only thing that might give you pause is NilClass.nil? # => false, but this should be quickly cleared up by seeing that NilClass is the class of the singleton object nil in ruby. This simply means that NilClass can only instantiate to the instance nil, and is only instantiated through the keyword nil.

To implement this functionality, ruby does four things in its source:

  // 1) define a function to return the ruby object false
  static VALUE
  rb_false(VALUE obj)
  {
    return Qfalse;
  }

  // 2) define a function to return the ruby object true
  static VALUE
  rb_true(VALUE obj)
  {
    return Qtrue;
  }

  // 3) define the Object class and assign functionality to the nil? method
  rb_mKernel = rb_define_module("Kernel");
  rb_define_method(rb_mKernel, "nil?", rb_false, 0);

  // 4) define the NilClass and assign functionality to the nil? method
  rb_cNilClass = rb_define_class("NilClass", rb_cObject);
  rb_define_method(rb_cNilClass, "nil?", rb_true, 0);

Most of this is pretty straight forward but there are a few things to make note of. VALUE is a pointer to an object, so it’s use in this code is simply stating that both methods take in an object and return an object. More specifically for the rb_true and rb_false methods they take take in an instance of the base ruby Object class and return an either an instance of TrueClass or FalseClass.

Qfalse and Qtrue are instances of VALUE and represent the singleton objects of the ruby classes TrueClass and FalseClass. This is significant only in that it is useful to note that ruby’s true and false are not the same thing as c’s true and false, although they can be converted.

Next, you’ll probably note the strange method rb_define_module. This function creates a module that is used in this case by the Object class which is defined by rb_cObject = rb_define_class("Object", rb_cBasicObject);. Methods that are core to the Object class and don’t extend to other classes are defined directly on the object class where as methods that do extend are defined on the kernal module.

Lastly rb_define_method takes an class definition, a stringified name for the method being defined, a function pointer to deliver it’s returned value and the number of arguments expected to be passed to the method.

empty?

empty? is a core ruby method, but it is only implemented on certain ruby object types. It is not implemented on the ruby ObjectClass and then extended to all other clases. Instead it is implemented only on classes that can have a lenght or count. First a few examples.

[].empty? # => true
[1].empty? # => false
{}.empty? # => true
{ a: 1 }.empty? # => false
"".empty? # => true
"hello".empty? # => false
:hello.empty? # => false
:"".empty? # => true

Again, going through how these results are generated will give a deeper understanding of what is actually happening when we make even these basic method calls.

First, let’s look at the source codes for the empty? methods.

// String#empty?
static VALUE
rb_str_empty(VALUE str)
{
  if (RSTRING_LEN(str) == 0)
    return Qtrue;
  return Qfalse;
}
//...
rb_define_method(rb_cString, "empty?", rb_str_empty, 0);

This looks relatively familiar to what we saw before with the nil? definition. There’s a little more logic but it’s really not too hard to work through.

First we see that the function takes in a VALUE pointer object and returns a VALUE pointer object. In this case it takes in a pointer to an object that is expected to be a string and returns a the Qtrue or Qfalse VALUE instances. When we look at the logic inside the function we can see that is does exactly what we’d expect it to do. It checks the string’s length using RSTRING_LEN, a custom string length method implemented for ruby, and return Qtrue if that length is 0.

// Array#empty?
static VALUE
rb_ary_empty_p(VALUE ary)
{
  if (RARRAY_LEN(ary) == 0)
    return Qtrue;
  return Qfalse;
}
//...
rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0);

Next, looking at the array empty method we see very similar code. Again, the function takes in and returns VALUE and again it uses a custom string length function, this time RARRAY_LEN to check the length of the object. Again, RARRAY_LEN is simply a wrapper for getting the memory allocated for the array in question. It is worth noting that an empty array in ruby does not coorespond to an empty array in C.

// Hash#empty?
static VALUE
rb_hash_empty_p(VALUE hash)
{
  return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
}
//...
rb_define_method(rb_cHash,"empty?", rb_hash_empty_p, 0);

Again, in the hash version of the function everything looks very similar. However, there is a small diference. This time we aren’t checking that the hash has no length, instead we are actually checking that it is empty. This is simply because it is more expensive to get the length of a hash than it is to get the length of an array. With an array you can simply check how much memory is allocated, where as with a hash you have to actually count the number of entities.

Looking at
// Symbol#empty?
static VALUE
sym_empty(VALUE sym)
{
  return rb_str_empty(rb_id2str(SYM2ID(sym)));
}
//...
rb_define_method(rb_cSymbol, "empty?", sym_empty, 0);

Finally, looking at the function for Symbol#empty? we start to see why it works the way it does. The short answer is that it simply casts the symbol to a string before checking whether it is empty. But this has a few implecations to it. First casting a symbol to a string atomatically increases the memory allocation for the variable. It’s also worth noting that casting a symbol actually requires a chain of function calls. First the symbol’s value must be retrieved from the global symbol table. This is what SYM2ID is doing. Next that value is cast to a string, and finally the strings memory allocations is counted.

In the grand scheme of things none of this is particularly costly, but it is enlightening to see what is actually going on behind the scenes.




The Lesser-Known Contributors Who Are Trying To Make PHP Good Again



Php gets a log of hate, and a lot of that hate is not without merit. But I have recently started adopting some tools at work that make php development a lot more enjoyable, and thought I would share.

1) Composer:

Composer is a pretty great package management system in the style of npm. It provides package management at the project level by providing a autoloader that is compiled on package install. This allows developers the ability to have multiple package versions installed on one machine and have them mapped to the projects they are specified for.

Furthermore, composer allows package maintainers a fresh start from the mess that is the Pear package manager.

A projects dependencies can be set up simply by including a composer.phar file and setting up a composer.json file like so:

  {
    "name": "My-New-Project",

    "require-prod": {
        "doctrine/orm": "2.2.1"
    },
    "require-dev": {
        "doctrine/orm": "2.*"

    "require":{
        "facebook-sdk": "master"
    },

    "repositories": {
        "package": {
            "name": "facebook-sdk",
            "version": "master",
            "source": {
                "url": "https://github.com/facebook/php-sdk.git",
                "type": "git",
                "reference": "master"
        }
    },

  }

2) Phake:

One of the major reasons that ruby and python have become tremendously popular over the past five to ten years is because they provide very easy paths to test drive and maintain high coverage of your code base. The same cannot be said for PHP and its PhpUnit framework.

Phake is a mocking framework that aims to fix a lot of the problems that PhpUnit’s mocking framework introduces.

Simple mocking and stubbing in Phake has far less unnecessarily verbosity. Where a mock in PhpUnit requires this:

  <?php
  $mock = $this->getMockBuilder('MyClass')
      ->disableOriginalConstructor()
      ->setMethods(array('some_method'))
      ->getMock();

  $mock->expects($this->any())
      ->method('some_method')
      ->with('some_value')
      ->will($this->returnValue('something'));
  ?>

Phake only requires this:

  <?php
  $mock = Phake::mock('MyClass');
  Phake::when($mock)
    ->someMethod('expected value')
    ->thenReturn('something');
  ?>

Additionally, Phake provides a more sane solution to running verifies. In phpunit’s verify system you are required to state your verify before you state the code you’re testing. This makes the test much harder to read.

  <?php
  $mock->expects($this->any())
    ->method('some_method')
    ->with('some_value')
    ->will($this->returnValue('something'));

  $tested_class = new TestedClass();
  $tested_class->setMock($mock);
  $tested_class->methodThatCallsMockedMethod('some_value');
  ?>

In Phake you are able to verify after your mock is injected like so:

  <?php
  $mock = Phake::mock('MyClass');
  $mock->someMethod('some_value');

  $tested_class = new TestedClass();
  $tested_class->setMock($mock);

  //verify after calling the code being tested.
  Phake::verify($mock)->someMethod('some_value');
  ?>

3) Php 5.4 Additions:

There are several additions that have been made to php in 5.4 that provide tools that I am use to having access to in other web development environments. Namely, short syntax arrays, method chaining directly from an instantiated object and building a web server on the fly. Try some of these commands out:

  <?php
  //new array syntax
  $my_array = [100, 'a', 299, 'hello', 300, 'world'];

  //chain off object instantiation
  $my_class = new MyClass()->someMethod()->someOtherMethod();

  //instantiate a webserver from the command line
  php -S localhost:8000

  //instantiate a webserver with webroot defined
  php -S localhost:8000 -t /path/to/your/files
  ?>

Php still has its faults and there is likely little that can be done to erase them. But the developers of these new tools deserve some serious recognition for the work they are doing to move a language they love in the right direction.




How I Make Django Easier



Everyone who has worked with Django for any reasonable period of time comes to the realization that starting up a new project can be a pain in the butt if you don’t build some level of automation into the process. After a few times copy and pasting into your <pre>settings.py</pre> most developers decide they can’t handle it any more and write some scripts to take care of the setup process for them.

I thought I would share my setup script, recently modified, and hopefully it will be helpful to those who are still in copy and past land.

First, my basic setup for most django projects I start is as follows:

1) create a new virtual environment with virtualenv

2) install django within the environment and start a new project

3) remove database setup, static media setup and debug settings from the auto generated settings.py file.

4) Add debug_toolbar settings, a dynamic media path, dynamic template_dir path, django_evolution or south and an import of a settings_local.py file to the settings.py file.

5) Create a settings_local.py file that defines local database connection, static media path and debug settings.

6) Modify the urls.py file to handle your static and media directories correctly.

7) Create a new sublime text project containing the new django project.

8) Initialize the django project as a git repo and create a .gitignore file.

9) Create a deploy script to ssh into production and git pull from github.

10) Get started actually building my app

Do this once or twice and you start to understand why many prefer customization over configuration. But if you’re a Django lover like myself you find a way around it.

So I built this quick and dirty script to do all of this for me:

  import subprocess, os, sys, re
  from random import choice
  from git import *
  from django_create import *

  def main():
      #variable declarations
      starting_path = os.getcwd()
      templates_path = os.path.abspath(os.path.dirname(__file__)) + '/templates'
      project_name = sys.argv[1]

      create_virtualenv(project_name)
      create_django_project(project_name, starting_path)
      create_settings_file(project_name, starting_path, templates_path)
      create_secret_key()
      create_local_settings_file(project_name, templates_path)
      create_other_files(project_name, starting_path)
      create_git_repo(project_name, starting_path, templates_path)
      create_deploy_script(project_name, starting_path, templates_path)

  def create_virtualenv(project_name):
      subprocess.call(['virtualenv', project_name])

  def create_django_project(project_name, starting_path):
      os.chdir('/'.join([starting_path, project_name]))
      subprocess.call(['source', 'bin/activate'])
      subprocess.call(['bin/pip', 'install', 'django'])
      subprocess.call(['django-admin.py', 'startproject', project_name])

  def create_settings_file(project_name, starting_path, templates_path):
      print 'Creating custom settings.py file'
      os.chdir(starting_path + '/' + project_name + '/' + project_name)
      settings_file = open('settings.py', 'w')
      settings_template = open(templates_path + '/settings.py')
      settings_file.write(settings_template.read().replace('', project_name))
      settings_file.close()

  def create_secret_key():
      print'Creating secret key'
      settings_contents = open('settings.py', 'r').read()
      fp = open('settings.py', 'w')
      secret_key = ''.join([choice('abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*(-_=+)') for i in range(50)])
      settings_contents = re.sub(r"(?<=SECRET_KEY = ')'", secret_key + "'", settings_contents)
      fp.write(settings_contents)
      fp.close()

  def create_local_settings_file(project_name, templates_path):
      print 'Creating custom settings_local.py file'
      settings_local_file = open('settings_local.py', 'w')
      settings_local_template = open(templates_path + '/settings_local.py')
      settings_local_file.write(settings_local_template.read().replace('', project_name))
      settings_local_file.close()

  def create_other_files(project_name, starting_path):
      print 'Creating Sublime Text project files'
      os.chdir(starting_path + '/' + project_name)
      sublimetext_project = open(project_name + '.sublime-project', 'w').write('{"folders": [{"path": "' + project_name + '"}]}')

  def create_git_repo(project_name, starting_path, templates_path):
      repo = Repo.init(''.join([starting_path, '/', project_name, '/', project_name]))
      git_ignore = open(starting_path + '/' + project_name + '/' + project_name + '/.gitignore', 'w')
      git_ignore_contents = open(templates_path + '/.gitignore').read()
      git_ignore.write(git_ignore_contents)
      git_ignore.close()

  def create_deploy_script(project_name, starting_path, templates_path):
      print 'Creating remote deploy script'
      os.chdir(starting_path + '/' + project_name + '/' + project_name)
      deploy_script = open('deploy.sh', 'w')
      deploy_contents = open(templates_path + '/deploy.sh', 'r').read().replace('', project_name)
      deploy_script.write(deploy_contents)
      deploy_script.close()
      subprocess.call('chmod 700 deploy.sh')

  if __name__ == '__main__':
      main()

This calls to a templates directory that has a settings.py settings_local.py and deploy.sh templates.

A few other things to note: most actions are called as subprocesses directly to the command line rather than using wrapper libraries primarily out of laziness. When replacing the settings file it is important to remember to regenerate the secrete_key. The deploy script is not an integration script. For most of my personal projects I run tests locally and push to github for integration.

If you want to use this script or something similar simply clone https://github.com/DanielNill/django_create and modify as you like.




Node.js Tutorial With Socket.io



Update: this tutorial has been update to run on node 5.0.0 and socket.io 1.3.7. If you have trouble with getting the code to execute, make sure you are running on these versions.

I was shocked to recently discover that there are no great quick tutorial on the basics of using socket.io with node js. While there isn’t a whole lot to it, someone not familiar with node.js and the protocol for WebSockets is left to scrounge for random snippets of code. Trying to parse the protocol of Websockets while learning the socket.io library and the basics of Node.js all at the same time is no easy feat. And even more frustrating, someone new to Node.js is likely interested in trying it out for the features socket.io provide.

So I thought I would take a brief stab at filling this void. Lets get started:

What We Will Cover:

In this tutorial we will cover

Your Basic Server:

There are several modules you can use to initiate a server in Node.js, but they are all pretty much the same. We will use the http library.

    var http = require('http');

    var server = http.createServer();
    server.listen(8001);

With these 3 lines we have a server. You can save this as server.js and run node server.js and you will see your command line ‘stall’ on the process waiting for something to happen on the server. But that’s just it, a server that doesn’t do anything isn’t any fun. So lets have it do something:

    var http = require('http');

    var server = http.createServer(function(request, response){
        response.writeHead(200, {'Content-Type': 'text/html'});
        response.write('hello world');
        response.end();
    });

    server.listen(8001);

With these changes we are now sending something to the client. Save server.js and run node server.js . Still nothing happens, but if we go to http://localhost:8001 we see a page that says “hello world”!

The actions we put inside createServer will be executed each time http://localhost:8001 is loaded. Lets slow down and go through what we did line by line.

var server = http.createServer(function(request, response){});
server.listen(8001);

Here we have created the server just as we had the first time, but now we are passing it an anonymous function that defines what happens with each request to the server and response from the server.

var server = http.createServer(function(request, response){
    //...
});

Here we simply say on every request response interaction with the server we will take some action.

    response.writeHead(200, {'Content-Type': 'text/html'});

Here we define how we are sending data to the client. All elements declared by writeHead are written to the response header. Our writeHead describes the HTTP Code of the response and the content type. The content type can be any of the common MIME types. You can define several other elements found in the HTTP response header, but we won’t worry about that for this tutorial.

response.write('hello world');

This defines the actual contents of our response. More precicely it defines the action of the response. Write says the the contents of the response is “hello world” and upon executing the response the server will append that content to the document being served.

Finally we have

    response.end();

This simply says that we are done defining the response and action and executes them.

Creating The Router:

So now we have very basic server, but it can only server our root domain. Lets fix that. We add the following to server.js.

    var http = require("http");
    var url = require('url');
    var fs = require('fs');

    var server = http.createServer(function(request, response){
        var path = url.parse(request.url).pathname;

        switch(path){
            case '/':
                response.writeHead(200, {'Content-Type': 'text/html'});
                response.write('hello world');
                response.end();
                break;
            case '/socket.html':
                fs.readFile(__dirname + path, function(error, data){
                    if (error){
                        response.writeHead(404);
                        response.write("opps this doesn't exist - 404");
                        response.end();
                    }
                    else{
                        response.writeHead(200, {"Content-Type": "text/html"});
                        response.write(data, "utf8");
                        response.end();
                    }
                });
                break;
            default:
                response.writeHead(404);
                response.write("opps this doesn't exist - 404");
                response.end();
                break;
        }
    });

    server.listen(8001);

If you save this code as server.js you can rerun node server.js when you load http://localhost:8001 into your browser you will see that nothing has changed. We still get “hello world” in the browser. However, we just build a router so now we should be able to go other urls. Looking at the code we just wrote it seems like we should be able to visit http://localhost:8001/socket.html and something should happen. But when we try that we get our 404 message. Lets go through what we added and see why.

var url = require('url');
var fs = require('fs');

Here we have added two new modules, url and fs. url is used to to parse interpret and manipulate urls, you can learn more about it here. fs is used to handle files, you can read about it here.

var path = url.parse(request.url).pathname;

With this line we get the path that follows our root domain. So localhost:8001 will assign ‘/’ to path and localhost:8001/some_other_path will assign ‘some_other_path’ to path. You can test this by adding console.log(path) immediately after this line.

Next we perform a switch case on the path to decide what we want the server to do. If the path is root then we perform our hello world action. If the path is socket.html then the server performs a different action.

fs.readFile(__dirname + path, function(error, data){...});

Here we use the fs module to open the file that is on the path the server recieves. Like most methods in node.js readFile takes a callback function to define its action. This function defines the action we want taken once the file’s contents have been gathered. In this case we are wanting to get the file socket.html. At this point you have probably noticed why we were getting that 404 message, socket.html doesn’t exist!!!

Let’s go through the rest of our changes and then we will solve that problem.

if (error){
    response.writeHead(404);
    response.write("opps this doesn't exist - 404");
}

The first argument we pass to the readFile callback contains the error code if we are unable to open the file (like say it doesn’t exist). The second variable passed is the contents of the file if we are able to open it. So we say that if there is an error opening the file on the path then we return a 404 header and write a message to the returned document.

else{
    response.writeHead(200, {'Content-Type': 'text/html'});
    response.write(data, 'utf8');
}

Here is what we want to happen once we have a readable file. It’s the same as what we do when we route to ‘/’ but instead we write the contents of the document we read and encode it as utf8.

You will also want to note that we still call response.end() at the bottom of our createServer function so that whatever actions are routed to the response object are closed and executed.

Now that we see why we are getting that 404 lets fix it. Lets create a new page where we will use socket.io

Adding Socket.io:

To start with we want to get rid of the 404 error when we visit http://localhost:8001/socket.html so we are going to create a socket.html file.

<html>
  <head></head>
  <body>This is our socket.html file</body>
</html>

Now we save this to the same directory as our server.js file and run node server.js. Now when we go to http://localhost:8001/socket.html we should see a page with “This is our socket.html file”.

That’s great but that’s not really what we’re here for. So let’s get into the real bread and butter, Socket.io!

First we will instantiate socket.io and extend it from our server. We change our server.js file to look like this:

var http = require("http");
var url = require('url');
var fs = require('fs');
var io = require('socket.io');

var server = http.createServer(function(request, response){
    var path = url.parse(request.url).pathname;

    switch(path){
        case '/':
            response.writeHead(200, {'Content-Type': 'text/html'});
            response.write('hello world');
            response.end();
            break;
        case '/socket.html':
            fs.readFile(__dirname + path, function(error, data){
                if (error){
                    response.writeHead(404);
                    response.write("opps this doesn't exist - 404");
                    response.end();
                }
                else{
                    response.writeHead(200, {"Content-Type": "text/html"});
                    response.write(data, "utf8");
                    response.end();
                }
            });
            break;
        default:
            response.writeHead(404);
            response.write("opps this doesn't exist - 404");
            response.end();
            break;
    }
});

server.listen(8001);

io.listen(server);

All we have added here is a require for the socket.io module at the top and the line io.listen(server);. This simply says that when the server is instantiated (note: not connected to) we will open a listener for socket.io. This means that our server will ‘listen’ for pages loaded by the server that have a WebSocket connection instantiated on them.

So lets see what happens when we run node server.js and reload http://localhost:8001/socket.html. Nothing seems to change in the browser but our server is now listening for any websocket connections that may occur.

Now that the server is listening for socket.io connections lets give our socket.html page a WebSockets connection so that the server will actually have something to talk to. To do this we simple change socket.html to:

<html>
  <head>
    <script src="/socket.io/socket.io.js"></script>
  </head>
  <body>
    <script>
      var socket = io.connect();
    </script>
    <div>This is our socket.html file</div>
  </body>
</html>

Here we have added the socket.io.js script and a body script to create the client side socket connection. Now we have a WebSockets connection between the client and our server. Let’s try sending some information from the server to the client through our socket.io connection

Sending Data To The Client:

Now we want to send some data from the server to socket.html. All data transactions in socket.io, like in most of node.js, can be handled with callbacks primarily we will utilize the on method. The on method in simplistic terms is used to map a method name to an annonymous function. Because we are using socket.io the on method simply uses the listener on the websocket connection for the method name and when it is found it executes the mapped annonymous function.

The flip side of the on method is the emit method. The emit method sends the mapped method name to the client or the server. It takes two arguments. The mapped method name and the data to be fed to the annonymous function.

So here is what we add to server.js:

var listener = io.listen(server);
listener.sockets.on('connection', function(socket){
    socket.emit('message', {'message': 'hello world'});
});

All we are saying here is when the listener gets a call for the “connection” action we will perform the function that follows it. When the “connection” action is called we trigger an emit action that will send a “message” action to the client. The “message” action will send the json object {‘message’: ‘hello world’} .

The ‘connection’ action is triggered when io.connection(); is executed on socket.html. Socket.io has several build in mappable actions, but we can also create custom mappable actions as we will see shortly.

To retrieve the emitted “message” action on socket.html we just add an on method listener:

var socket = io.connect();

socket.on('message', function(data){
    console.log(data.message);
});

Now we have an emit on the server side that sends data to the client side. And an on method on the client side that recieves that data and writes it to the browser’s console. Run node server.js again and reload the page. If you open up the javascript console of your browser you will note that “hello world” has been written. Further more, if you check your command line you will note that you have more debug statements from socket.io explaining the transmission and contents of the message.

But we could just as easily produce this content through a normal page load or ajax call. We want the actions transmitted through our socket connection to be continuous. A good example of this is a clock. A clock updates the data it displays literally every second.

So lets do that. In javascript we can create repeatable actions with the setInterval function. setInterval takes an anonymous function and a number of miliseconds as arguments and executes the function every count of the miliseconds. So if you want to print hello world every one second you would simply say

setInterval(function(){
    console.log('hello world');
}, 1000);

So going back to our server.js file we want to emit data for our clock through our socket connection.

io.sockets.on('connection', function(socket){
    //send data to client
    setInterval(function(){
        socket.emit('date', {'date': new Date()});
    }, 1000);
});

We are doing a few things here. First we set up our setInterval method inside our websocket connection callback. We execute the function inside the setInterval every 1000 miliseconds. Then we say

socket.emit('date', {'date': new Date()});

which says that we send JSON with the date to a listener on the client side labeled ‘date’.

So again, when we make our socket connection we repeatidly send JSON with the date to an on listener on the client every 1000 miliseconds.

Now we will update the client to recieve our data.

<html>
  <head>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>  </head>
  <body>
    <script>
      var socket = io.connect();

      socket.on('date', function(data){
        $('#date').text(data.date);
      });
    </script>
    <div id="date"></div>
  </body>
</html>

You will notice we added very little. We added a script to load jquery so that we can easily display the data we are recieving. We added an id to our div so that we can use it with jquery. And we added an on method to recieve our data from the emit method on the server.

Our on method simply says when we recieve an emit action labeled date, we take the data sent by the emit and put it inside our date div.

Try restarting your server and load the page. You should now see the date displayed and being updated every second. Go back to your server.js file and remove the 1000 from the setInterval. Now the date is being updated every milisecond.

Sending Data From the Client To the Server:

Now that we know how to send continuous data from the server to the client all we have left to do is learn how to send continuous data from the client back to the server. You will be happy to know that this process is completely the same as what we just did. So lets say we want to print every letter the user types into a textbox to the server console.

Again we will want to set up an emit function and an on listener. This time the emit will be on the client side and the on listener will be on the server side. We update our socket.html file to look like this:

<html>
<head>
  <script src="/socket.io/socket.io.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.js"></script>
</head>
<body>
  <script>
  var socket = io.connect();
  socket.on('date', function(data){
    $('#date').text(data.date);
  });

  $(document).ready(function(){
    $('#text').keypress(function(e){
      socket.emit('client_data', {'letter': String.fromCharCode(e.charCode)});
    });
  });
  </script>
  <div id="date"></div>
  <textarea id="text"></textarea>
</body>
</html>

Here all we have added is a textarea and an emit event to be triggered every time a key is pressed inside that textarea. String.fromCharCode(e.charCode) takes the character code of the key that triggered the event and converts it back to a string of the character associated with that code number. So if the “a” key triggered the event then our JSON would be {'letter': 'a'}.

Now we will add the on listener to our server.js file:

var listener = io.listen(server);

listener.sockets.on('connection', function(socket){
  //send data to client
  setInterval(function(){
    socket.emit('date', {'date': new Date()});
  }, 1000);

  //recieve client data
  socket.on('client_data', function(data){
    process.stdout.write(data.letter);
  });
});

You will see that here we have added the just a few lines again.

First we added

//recieve client data
socket.on('client_data', function(data){
  process.stdout.write(data.letter);
});

This is our listener for the client_data emit call. When an action triggers this listener we write the letter inside our JSON to the server console. We use process.stdout.write() because it writes to stdout without inserting new line characters like console.log() will.

So restart your server and try everything out. We should now have a clock runing in our browser with data from the server and data being streamed from the browser to the command line when we type in the textarea.

Conclusion:

Hopefully, this has provided a more thorough introductory tutorial for beginners interested in using node.js and socket.io. If you have any questions drop me a line.

You can find the example project here




Adding a WYSIWYG Editor to Django Admin



This will tell you pretty much everything you need to know about adding a WYSIWYG editor or any other javascript based features you may want to your django admin.

For most modern WYSIWYG editors installation is just a matter of adding a few lines of javascript and possibly adding a class or id to the textareas you want effected. This django wiki entry gets you about half the way depending on the editor you want to use, but there are a few other tricks you can use depending on your editor of choice. Here I’ll show the instalation process for Tiny MCE and CKEditor, two of the more popular WYSIWYGs, both of which use different installation methods, to show you the modifications you can make to get most editors working.

###Tiny MCE

Tiny MCE isn’t a great editor and if given the choice I would suggest switching to something else (like CKEditor outlined below). But that’s niether here nor there. It’s very popular, and provides a good example of methods you can use to install javascript plugins in the django admin.

So for Tiny MCE first you want to create a javascript file that has the basic installaiton script, we will call it textarea.js:

tinyMCE.init({
  mode : "textareas",
  theme : "advanced",
  theme_advanced_toolbar_location : "top",
  theme_advanced_toolbar_align : "left",
  plugins : "table, save, advhr, advimage, advlink, emotions, iespell, insertdatetime, preview",
  theme_advanced_buttons1 : "fullscreen, separator, preview, separator, bold, italic, underline, strikethrough, separator, bullist, numlist, outdent, indent, separator, undo, redo, separator, link, unlink, anchor, separator, image, cleanup, help, separator, code",
  auto_cleanup_word : true,
  plugin_insertdate_dateFormat : "%m/%d/%Y",
  plugin_insertdate_timeFormat : "%H:%M:%S",
  extended_valid_elements : "a[name|href|target=_blank|title|onclick], img[class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name], hr[class|width|size|noshade], font[face|size|color|style], span[class|align|style]"
});

You can find the details of setting up your layout here, but the basic thing you need is a javascript file with

tinyMCE.init({mode: "textarea", ...});

Now, the key to adapting this method to installing other WYSIWYG editors is knowing that you can include any javascript file in the django admin. To do this you simply need to add a media subclass to your custom admin model.

class SomeModelAdmin(admin.ModelAdmin):
    class Media:
        js = (
            '/media/tiny_mce/tiny_mce.js',
            '/media/textareas.js',
        )

This will load the resources listed into the /admin/app_name/model_name/. As you can see for Tiny MCE you need to include the textareas.js file we just made and the main Tiny MCE script which I choose to store in my media directory.

For Tiny MCE that is all you need. The WYSIWYG will be included on all textareas in your admin.

###CKEditor

CKEditor is a much nicer editor. It’s primary drawback, however, is its limit documentation. Luckily, because it is a nice editor there are plenty of tutorials for installation online. The primary difference between installation for CKEditor and Tiny MCE is that you cannot assign the plugin to generic textareas like you can Tiny MCE. You must assign the editor by class or id.

But this is not a problem. We just modify the django admin to have a custom class assigned to textareas.

from django import forms

class SomeModelAdmin(admin.ModelAdmin):
    formfield_overrides = { models.TextField: {'widget': forms.Textarea(attrs={'class':'ckeditor'})}, }

    class Media:
        js = ('/media/ckeditor/ckeditor.js',)

Note that we are still including the ckeditor javascript file. But a custom javascript file is not needed unless you want to modify the WYSIWYG’s layout.

So that is pretty much all you need to know. Between those two methods you should be able to add most javascript based plugins to your django admin.




Well That's a Terrible Feature



I recently discovered a really terrible feature now integrated into most modern browsers. The javascript window object is assumed appended to all javascript variables.

What does this mean?

A lot of developers, myself included until recently, probably do not know of this feature. Essentially assuming the window operator means that

window.some_id_name

can be shorted to just

some_id_name

to get any html DOM object. Go ahead, open up Chrome and type ‘test’ in the javascript console. You just got the DOM object of this paragraph. Seem pretty nifty right?

It’s a great feature until you run into an error like the one that led me to discover this. The problem here is that this means that any DOM id you use on a page is now a protected object in javascript (but for some edge cases that I still haven’t fully worked out).

I discovered this feature when I tried doing this:

<input onclick="’comment_reason(“$info[‘comment’]”)’/" type="’button’">
<input id="’comment_reason’/" type="’hidden’">

and

function comment_reason(id){}

I know real daring of me

When run in chrome this trigger gives “Uncaught Type Error: object is not a function”. In firefox it gives the slightly more helpful “function not defined”. After working the error back to the trigger I talked to some other people. Most were as flummoxed as I. That is, until I found someone who had run into the same error and pointed me to the source of the problem.

The comment_reason namespace was already occupied. It was occupied by the comment_reason object or rather the window.comment_reason object that was instantiated when the dom was loaded.

So is this a feature or a bug?

I say that the bugs this causes far out weigh the feature of not having to write window. Further limiting dom naming and imparting those naming restrictions on javascript seems completely unnecessary.

Unfortunately this doesn’t seem to be going away. This stackoverflow entry explains what’s going on somewhat, and it would seem that this has been adopted as a core feature of html5. So for better or for worse it’s here to stay.

If anyone can give a more full explanation of why this is a worthwhile feature I’m all ears.