Bash script for batch running OptiPNG

Optimize all your images with a single command:

$ find . -name '*.png' | xargs optipng -nc -nb -o7 -full

What is OptiPNG?

OptiPNG is a PNG optimizer tool. If you want your website to be faster, you should consider optimizing images.

When I ran the Google PageSpeed tool towards my website, I got a score of 81/100 for Desktop, 61/100 for Mobile. Pretty low, I thought. So I decided to go through the “Consider Fixing” issues, and the first one was – guess what? – optimize images.

Properly formatting and compressing images can save many bytes of data.

OPTIMIZE ALL THE IMAGES!The thing I did immediately next was reading the article that Google suggested: it’s a nice reading on Google Developers about optimizing images. The first recommendation is: Use an image compressor. OptiPNG is one of them.

On the OptiPNG site I realized it works only for one image at a time, so I had the need to write a script that runs the optimizer for all images at the same time.

Luckily enough, after a bit of search, I found a blog post titled Optimize all PNG images recursively, which finally solved my problem. All the credits for the script belong to that blog.

After running the script I got a score of 86/100 for Desktop (before was 81), and 68/100 for Mobile (before was 61), all without loss of quality. Definitely worth a try!


Rails 4: update/synchronize views with database schema after a migration

So you just updated your model and the related database schema, but your views are now obsolete. How to refresh them?

Well, there are a lot of premises to say here. First, there’s no actual way to synchronize your views with your model. The best way is to do it manually, but it’s not the only way. The other way, which I’m going to explain in this post, actually only works if you are willing to scaffold your whole model/view/controller/tests from scratch. This is probably not desirable in most of cases, but I assure you can safely try this path if you are in a early stage of development, or if you are ok with the default (generated) Rails’ views. So, whatever, if you don’t want to rake generate scaffold your_resource again, you can stop reading now.


Oh well, you are still reading :-)

I’ll proceed explaining how to synchronize your views after the migration(s) you have run. Let’s just start from scratch.

A full example

Let’s say we have these two models: Child and Toy.

Child
  • name
  • birth_date
Toy
  • description
  • price
  • child_id

As you might have already guessed, I am going to tie our models with a one-to-many relationship: a child has_many toys, and a toy belongs_to a child.

app/models/child.rb
class Child < ActiveRecord::Base
  has_many :toys
end
app/models/toy.rb
class Toy < ActiveRecord::Base
  belongs_to :child
end

Let's create the application and scaffold these resources:

$ rails new DemoApp && cd DemoApp
$ rails generate scaffold child name birth_date:date

$ rails generate scaffold toy description price:decimal child:references

Run the migrations:

$ rake db:migrate
==  CreateChildren: migrating =================================================
-- create_table(:children)
   -> 0.0014s
==  CreateChildren: migrated (0.0015s) ========================================

==  CreateToys: migrating =====================================================
-- create_table(:toys)
   -> 0.0028s
==  CreateToys: migrated (0.0029s) ============================================

We can now start the server and check that everything went good.

$ rails s
=> Booting WEBrick
=> Rails 4.1.0.beta1 application starting in development on http://0.0.0.0:3000
...
listing children empty

It looks fine, except for one thing: there's no data displayed! Let's add some entries manually.

listing children

Good. Now let's give some toys to our boys:

toy successfully created

Done. But wait a minute: this view looks a bit... crappy, doesn't it? We don't want to see a reference to a child... just his/her name. Even the prices don't look right.

Let's generate the scaffold again, with some corrections.

$ rails g scaffold toy description:string{50} price:decimal{4,2} 
      invoke  active_record
Another migration is already named create_toys: /Users/simo/Projects/DemoApp/db/migrate/20140209145850_create_toys.rb. Use --force to remove the old migration file and replace it.

Fair enough. We must destroy the entire scaffold before recreating it.

$ rails destroy scaffold toy
      invoke  active_record
      remove    db/migrate/20140208224426_create_toys.rb
      remove    app/models/toy.rb
      remove    ...

$ rails generate scaffold toy description:string{50} price:decimal{4,2} child:references
      invoke  active_record
      create    db/migrate/20140209145850_create_toys.rb
      create    app/models/toy.rb
      create    ...

Ok. Let's give a quick look at the generated migration.

class CreateToys < ActiveRecord::Migration
  def change
    create_table :toys do |t|
      t.string :description, limit: 50
      t.decimal :price, precision: 4, scale: 2
      t.references :child, index: true

      t.timestamps
    end
  end
end

It looks right. Let's run it!

$ rake db:migrate
==  CreateToys: migrating =====================================================
-- create_table(:toys)
rake aborted!
An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: table "toys" already exists: CREATE TABLE "toys" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "description" varchar(50), "price" decimal(4,2), "child_id" integer, "created_at" datetime, "updated_at" datetime) /Users/simo/.rvm/gems/ruby-2.0.0-p353/gems/sqlite3-1.3.8/lib/sqlite3/database.rb:91:in `initialize'

Whoops! The table already exists. We should remove it first. Edit the migration:

class CreateToys < ActiveRecord::Migration
  def change
    # This will do the work
    drop_table :toys

    create_table :toys do |t|
      t.string :description, limit: 50
      t.decimal :price, precision: 4, scale: 2
      t.references :child, index: true

      t.timestamps
    end
  end
end

And migrate again:

$ rake db:migrate
==  CreateToys: migrating =====================================================
-- drop_table(:toys)
   -> 0.0107s
-- create_table(:toys)
   -> 0.0109s
==  CreateToys: migrated (0.0220s) ============================================

Ok, we are ready to start the server again and see what changed.

$ rails s
That's it. This is basically the process. It's way too labourious, I know, but the truth is that we just can't efficiently automatize a process like this, because: what if we generate more migrations during the journey? We would have to delete them and recreate again the whole schema by running rails generate scaffold, rake db:reset and rerun the generate again and again... well, that sucks. At this stage we've got the point: it's better to do it manually! Rails gives us tons of helper methods to format prices and get things done, and that's definitely the path to follow.

If you are still not convinced, you can check this question on StackOverflow. Basically, it's almost the same question I had before writing this post. Both the question and the answer are quite old, and in the meantime the Rails Team didn't develop anything that would help us regenerating our views. This probably means we are not supposed to do it, don't you think? However, if your goal is to get focused on the backend without having to deal with the frontend, you can always use a gem like ActiveScaffold. But you have been warned!

I hope you've found this article useful; thoughts are welcome, as always. If you want you can leave a comment below.


Install Sublime Text 3 on Fedora 20

Here’s a simple script to install the latest build of Sublime Text 3 in Fedora.
Should work in many other Linux distros too. See the full gist on GitHub.

It will install the Package Control as well!

Just run this command:

$ curl -L http://git.io/3Wr2CQ | sh

Update 10 March 2014: I made some improvements to the script so I generated a new link.

Update 16 March 2014: The script stopped working because of a 301 redirect. Adding the -L flag solved the issue.


How to set a default message in your exception

Today I was thinking about a way to define custom exceptions with a predefined error message. For example, instead of doing this:

raise MyError, "Something went wrong."

We want to simply do:

raise MyError

This could be useful because if we need to raise that same exception again and again, we don’t have to specify the error message every time.

Well, how can we do that?

I spent all day figuring out the best way, actually doing very bad things – I’ve even attempted to monkey-patch the Kernel module!
So – believe me – it’s not as simple as it appears to be. Or, at least, I thought this until I stumbled across this article.

In short, you just need to override Exception#message.

For example:

class MyError < Exception
  def message
    "a predefined message"
  end
end

raise MyError
# => MyError: a predefined message

Quick note: I’m inheriting from StandardError, not Exception, because extending the Exception class in Ruby is considered really bad. Please don’t inherit from it: see here and here for the reason (in few words it’s because you may catch errors that are not meant to be catched, such as SyntaxError).

Of course you could also create a module with your own exceptions in it:

module CustomError
  class AnError < StandardError
    def message
      "A more specific error"
    end
  end

  class AnotherError < StandardError
    def message
      "just another error"
    end
  end
end

Or even a subclass of your custom error class:

module CustomError
  class Error < StandardError
    def message
      "default error"
    end
  end
  
  class SpecificError < Error
    def message
      "a more specific error"
    end
  end
end

However, this is not very useful. What I find useful, though, is that you can bring shared pieces of information from the base class to the subclasses, which is IMO very desirable in error handling.

Since Exception#message is nothing but an alias of exception.to_s, we can call super to get the superclass' message. For example, this is what I ended up doing:

module CustomError

  class Error < StandardError
    def initialize(msg=nil)
      @message = msg
    end

    def message
      "Message from main class: #{@message}."
    end
  end

  class SpecificError < Error
    def message
      super + " We also got a specific error."
    end
  end
end

And here's the result:

raise CustomError::SpecificError, "fubar"
# => CustomError::SpecificError: Message from main class: fubar. We also got a specific error.

This demonstrates that we can potentially carry whatever information (i.e. instances of objects involved in the error) in order to better handle errors in our applications.

That's it.
As always, please feel free to share your thoughts by commenting below.


View latest file changes in command line using Git

Let’s say you did some changes to several files, but you don’t remember which ones. How do you proceed?

A git status will be enough in most cases, but it just shows which files changed – what if you want to see the actual changes you made?

The answer is:

$ git diff

It shows every line of code you changed and that you haven’t committed yet. Useful, isn’t it?

If you have already committed some code, but not pushed yet, don’t be afraid: you’re still in time to check if everything is good, and a git log will come handy:

$ git log -p

You probably already know the power of git log, but -p makes it even more powerful, because it will also show a patch of what changed in each commit.


Loop through parameters in Bash

Iterating over the arguments in a Bash script is way simpler than you might expect.
See this gist:

In the snippet above, "$@" represents all the parameters. The echo "$i" shall obviously print each argument on a separate line.

It’s always a good idea to wrap parameters within quotes, because you’d never know when a parameter might contain spaces or whatever.


How to load jQuery plugins with RequireJS

RequireJS is a useful script loader library. Even if your site/app isn’t super big, it’s usually a good idea to use RequireJS: it makes your code maintainable.

The problem

Often we need to include external plugins that depend on jQuery. Those plugins usually do expect to find a global jQuery ($) object, and then they just extend it.

Of course not all plugins behave like that, but most of them do, and we must deal with it.

By the way, loading jQuery as a global variable is not really a good idea. Okay, you have namespaces, $.noConflict() and IIFEs and whatever but – hey come on, do you really think you need all this stuff? We can do it better.

The solution

Use RequireJS with jQuery to manage dependencies. More specifically, you can use the shim config to specify dependencies for jQuery plugins that are not AMD modules.

Let’s suppose you need to include 2 jQuery plugins, foo.js and bar.js. Here’s a sample configuration:

requirejs.config({
    shim: {
        foo: {
            deps: ['jquery'],
            exports: 'Foo'
        },
        bar: {
            deps: ['jquery']
        }
    }
});

Then, later, when you need to use that Foo plugin, you can just define a module by doing:

// foo.js
// This defines a module named 'foo'
define(function() {
    
    var Foo = function() {
        this.bar = 'baz';
    }
    return Foo;
});

And require it when you actually want to execute it:

require(['foo'], function(Foo) {
    // this is a callback function, and it's optional.
    // the foo module has already been required and executed.
    // Foo and $ are now loaded.
});

Yeah, it’s that simple.

Want to see a working example? Check out the official one.


How to remove an element from an array

tl;dr version:

myArray.splice(3, 1);

The function above will remove the element at index 3. See docs.


Detailed version:

Let’s say we have a simple array of strings, like this one:

var a = ['foo', 'bar', 'baz'];

We just want to remove that 'bar' element. How can we do this?

For the principle of least surprise, you could expect Array to have a remove function:

a.remove('bar');
>>> ['foo', 'baz']

The bad news? JavaScript does not have such a function.

The good news? We can create it!

But, first of all, let’s see how this is done in the standard way:

a.splice(1, 1);
>>> ['bar']
a
>>> ['foo', 'baz']

What does this splice function do? Simple: it just removes the element at index 1. The first parameter is, indeed, the index, and the second is the number of elements to remove, starting from that index. This is all you need to know about splice. If you’re curious to see what other cool things splice can do, see the MDN documentation.

But what if I don’t know the index?

Oh well, you can get it. Just use indexOf, this way:

a.indexOf('bar');
>>> 1

Please note that Internet Explorer 8 and below versions doesn’t support it (you can use a polyfill, though).


Extending the Array object

This is the function I finally came up with.

// Removes an element from an array.
// String value: the value to search and remove.
// return: an array with the removed element; false otherwise.
Array.prototype.remove = function(value) {
  var idx = this.indexOf(value);
  if (idx != -1) {
      return this.splice(idx, 1); // The second parameter is the number of elements to remove.
  }
  return false;
}

I know some folks out there doesn’t feel comfortable with extending Array, because they say Bad Things™ could happen. However, I think that a remove function is just a lot more easy to use and remember than splice, and honestly I don’t see any drawbacks with this approach; especially if we protect the global Array object, somehow. What do you think?

Full example (from the browser’s console, as usual):

var myArray = ['foo', 'bar', 'baz'];
>>> undefined
myArray.length
>>> 3
myArray.remove('bar');
>>> ["bar"]
myArray
>>> ["foo", "baz"]
myArray.remove('baz');
>>> ["baz"]
myArray
>>> ["foo"]
myArray.length
>>> 1
myArray.remove('qux');
>>> false

Awesome! But… why can’t I just use the delete keyword?

Oh, so you’ve heard of that magical JavaScript keyword too, isn’t it? You can do cool things with it, like:

var a = ['foo', 'bar'];
delete a[1];

And it will Just Work™. By the way it has a flaw: it doesn’t simply remove that element from the array, but it actually replaces it with undefined. Example:

var a = ['foo', 'bar', 'baz'];
>>> undefined
delete a[1];
>>> true
a
>>> ["foo", undefined, "baz"]

Leaving place for undesiderable things, like:

a.length
>>> 3   // it should be 2!

In conclusion, if you don’t care about the drawbacks, you can use the delete keyword; otherwise go with the solution explained above.


How to install Sublime Text 3 on Debian

Sublime Text 3

This little bash script installs Sublime Text 3 (build 3059 released on 17 December 2013) on your Linux machine, with no effort at all.

x64 version:

wget http://c758482.r82.cf2.rackcdn.com/sublime-text_build-3047_amd64.deb
sudo dpkg -i sublime-text_build-3047_amd64.deb

x86 version:

wget http://c758482.r82.cf2.rackcdn.com/sublime-text_build-3047_i386.deb
sudo dpkg -i sublime-text_build-3047_i386.deb

Have fun!


How to put online your WampServer

WampServer LogoOn your Windows machine you run an Apache web server with some PHP websites in there. What if you want to show all of them to your friends, or want to be reachable by the whole Internet? This may sound quite difficult to achieve, but actually it’s fairly straightforward to put online a web server: let’s see how.

Publishing your Website on the Internet

First of all, you need to get your WAMP stack up and running on your local host. I’ll assume you already have a web application hosted on your own PC, and that is reachable by just typing this URL in the address bar:

http://localhost/    # or http://127.0.0.1

Now you should access to your router web interface. Usually it is reachable by navigating to:

http://192.168.1.1

However this may vary, depending on your router model. When in doubt, open the command prompt (cmd), type ipconfig and press enter. You should see something like this:

C:\>ipconfig

Ethernet adapter Local Area Connection:

    Connection-specific DNS Suffix  . :
    IP Address. . . . . . . . . . . . : 192.168.1.27
    Subnet Mask . . . . . . . . . . . : 255.255.255.0
    Default Gateway . . . . . . . . . : 192.168.1.1

Please take note of the IP address: that’s your private address, which uniquely identifies you in your local network. If you try it in your browser, you should be able to see the public contents of your server.

Port Forwarding

In order to be reached by the world, you should tell your gateway where is your web server. All incoming request on port 80 should be redirected to your own private IP address. Even this process may vary; it really depends on your router. By the way, this is what you basically want to do: forward every request on port 80 to 192.168.1.27 (of course you must use your own IP address). But since the router’s web server already keeps the port 80 busy, here’s what you can do:

  • Move the gateway’s web interface to another port;
  • Move your web server to another port.

I’ll pick the last one, since it’s usually easier to do, and the first option is not always possible. So, let’s change the port: open the httpd.conf and find this row:

Listen 80

replace it with:

Listen <port number>

for example:

Listen 8080

And restart the server. Now go to http://localhost:8080 and check that everything went as expected.

Routing the outside web traffic to your own web server

All respectable routers have an advanced section called IP/Port Forwarding: find yours. If you don’t have this, I’m afraid you cannot be reachable by the outside.

Usually you need to add two separate entries: one for TCP and one for UDP packets. Something like this will do the work:

Private IP     Private Port   Type   Public IP/mask   Public Port
192.168.1.27   8080 	      TCP    0.0.0.0/0        8080
192.168.1.27   8080 	      UDP    0.0.0.0/0        8080

Apply the changes and restart your router.

Configuring the server to be reachable by everyone

The last step! Open your httpd.conf and find this line:

ServerName localhost:80

Change it to:

ServerName <your private IP>:80

Example:

ServerName 192.168.1.27:80

Just a quick note: you can jump over the step below. It can be done in an easier way by just clicking on the green WampServer tray icon and choosing “Put Online”.

Also find this line:

Order Deny,Allow
Deny from all
Allow from 127.0.0.1

Change it to:

Order Allow,Deny
Allow from all

Restart your web server. Now just find out what’s your current public IP address and try to go to:

http://<public IP address>:<port>/

i.e.:

http://13.37.223.21:8080/

It should work now! … Or, at least, it worked for me.

Problems? Thoughts? As always, feel free to leave a comment.