Tuan Anh

container nerd. k8s || GTFO

Pretender - a mock server library

Pretender is a mock server library in the style of Sinon (but built from microlibs. Because javascript) that comes with an express/sinatra style syntax for defining routes and their handlers.

var server = new Pretender(function(){
  this.put('/api/songs/:song_id', function(request){
    return [202, {"Content-Type": "application/json"}, "{}"]
  });
});

Very easy to use for quick prototyping.

link bài gốc

AngularJS diary - Day 4

##Update ng-model of one controller from another

Using $broadcast to broadcast a message (or $emit) and put listener on that message on receiver.

// unrelated controllers -> $rootScope broadcasts
App.controller('Ctrl1', function($rootScope, $scope) {
  $rootScope.$broadcast('msgid', msg);
});

App.controller('Ctrl2', function($scope) {
  $scope.$on('msgid', function(event, msg) {
    console.log(msg);
  });
});

When to use $broadcast and when to use $emit?

  • $broadcast — dispatches the event downwards to all child scopes,

  • $emit — dispatches the event upwards through the scope hierarchy.

In case there is no parent-child relation, use $rootScope to $broadcast.

##Making AJAX call the right way

Use service, factory or providers for that. It’s advised not to make AJAX calls within the controller.

var ExampleService = angular.module("ExampleService", []);
ExampleService.service('ExampleService', function($http) {
  this.my_method = function() {
    var url = 'http://...';
    var req_params = {};
    return $http.post(url, req_params); // a promise
  };
})

// using it
ExampleService.my_method().then(function(result) {
  $scope.my_var = result.data;
});

##Services vs Factory

In most cases, both can be used interchangably.

When you’re using service, Angular instantiates it behind the scenes with the new keyword. Because of that, you’ll add properties to this and the service will return this. When you pass the service into your controller, those properties on this will now be available on that controller through your service. This is why service is most suitable for generic utilities.

factory is useful for for cases like when you don’t want to expose private fields but via public methods instead. Just like a regular class object.


The next bullet on my resume: AngularJS

I started a HTML5 hybrid mobile app project recently. Before I start coding the frontend, I had to decide which client side JavaScript framework I will be using. The choice narrows down between AngularJS (Ionic framework) and Ember.

Of those two, AngularJS is obviously the more popular choice. There’re many frameworks built on AngularJS; thousands of questions on StackOverflow; lots of open-source projects base on AngularJS on GitHub. There are many great frameworks out there but few has gained so much developer mindshare like AngularJS. There’s clearly something about this framework. I mean, take a look at the search trend of AngularJS vs other frameworks.

angularjs search trend vs others

So I decided to take sometimes to evaluate AngularJS first to see what’s all the hypes are about. I downloaded AngularJS; played around; read documents, tutorials and top questions on StackOverflow.

I don’t know much about AngularJS yet but I will start blogging about it as I learn here. These are the few things that I’ve learnt about AngularJS in the last two days.

AngularJS is easy to start with

The thing about AngularJS is it’s very intutive, simple to start and easy to understand if you’re already familiar with MVx pattern. It has a very high WOW factor (data binding for one) at the beginning if you’re coming from, say jQuery. Seeing things like this make people want to explore the framework further. This is one of the main reason that make AngularJS popular, I think.

Single source of truth

Single Source Of Truth (SSOT) refers to the practice of structuring information models and associated schemata such that every data element is stored exactly once

Suppose that you have a toggle button, if you were to use jQuery, you will have to add an active CSS class to style when it’s toggle on; remove it and re-add inactive class when it’s off. If there’s data dependent on it, you will have to manipulate the DOM yourself. Crazy right! The problem is that it may go out of sync (toggle is on but css class is still inactive for example). Plus, the code will be much longer and unnescessary complicated.

AngularJS seperates data from its presentation and offer you data binding. You create a view, bound a field to an attribute in your model. Your data model is now single source of truth. You don’t have to manipulate with the DOM yourself but dealing with the model instead.

$scope

There’s no base model/object in Angular. Whatever you put inside $scope is your model. This is a bit weird coming from OOP language. I wonder how would we share the model outside of the $scope. The data is stucked between your template and $scope. So far, I’ve seen example using $rootScope but it’s like using global variables which I’m against unless really nescessary. factory seems to be the thing I’m looking for. I shall read more documentations about this.

That’s it for today. I will continue once I found more cool stuff worth sharing about Angular.


How to setup rtorrent, rutorrent on Ubuntu

This is a simple and concise tutorial on how to setup a seedbox running rtorrent with rutorrent as webui on Ubuntu OS. I’ve tried to simplify as much as possible to make it easy to understand. It may look a bit lengthy but it’s copy-paste-fu mostly.

Initial server setup

Login to your server and create a new user account, add it to sudo group. Substitute USER_NAME with your desired username.

ssh [email protected]_SERVER_IP_ADDRESS
adduser USER_NAME
gpasswd -a USER_NAME sudo

Setup key authentication

It’s better, less hassle and a lot safer. You should use it.

# at your local machine: gen key and upload it to your vps
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub | ssh [email protected]_SERVER_IP_ADDRESS 'cat >> .ssh/authorized_keys'

You can try logging in your server with the new user. It will not ask you to enter password this time.

Disable root login

Use nano to change PermitRootLogin to no. Ctrl+O to save and Ctrl+X to quit afterward.

nano /etc/ssh/sshd_config
service ssh restart

Setup rtorrent

# install libraries required to build rtorrent
sudo apt-get update
sudo apt-get install subversion build-essential automake libtool libcppunit-dev libcurl3-dev libsigc++-2.0-dev unzip unrar-free curl libncurses-dev libxml2-dev

# download source and install
cd ~
mkdir src
cd src
svn checkout http://xmlrpc-c.svn.sourceforge.net/svnroot/xmlrpc-c/stable xmlrpc
cd xmlrpc
./configure --prefix=/usr --enable-libxml2-backend --disable-libwww-client --disable-wininet-client --disable-abyss-server --disable-cgi-server --disable-cplusplus
make
make install

Install libtorrent

cd ~
wget http://libtorrent.rakshasa.no/downloads/libtorrent-0.13.4.tar.gz
tar xvf libtorrent-0.13.4.tar.gz
cd libtorrent-0.13.4
./autogen.sh
./configure --prefix=/usr
make
make install

Install rtorrent

cd ~ # back to home
wget http://libtorrent.rakshasa.no/downloads/rtorrent-0.9.4.tar.gz
tar xvf rtorrent-0.9.4.tar.gz
cd rtorrent-0.9.4
./autogen.sh
./configure --prefix=/usr --with-xmlrpc-c
make
make install
ldconfig

Create new user to run rtorrent and required folders

useradd -d /home/rtorrent_usr/ rtorrent_usr
mkdir /home/rtorrent_usr
mkdir /home/rtorrent_usr/downloads
mkdir /home/rtorrent_usr/.session
mkdir /home/rtorrent_usr/watch
mkdir /home/rtorrent_usr/.sockets
touch /home/rtorrent_usr/.sockets/rpc-socket
nano /home/rtorrent_usr/.rtorrent.rc
# update permission
chown -R rtorrent_usr:rtorrent_usr /home/rtorrent_usr/
chown -R www-data:www-data /usr/share/nginx/html

For rtorrent config, you can copy the default one and mess around. It’s simple and straight forward. I won’t go into details here.

cp /usr/share/doc/rtorrent/rtorrent.rc ~/.rtorrent.rc

Setup nginx/rutorrent for webui

Install nginx and php5-fpm to run rutorrent

sudo apt-get install nginx php5-fpm php5-cli

By default, your root folder will be at usr/share/nginx/html.

Create a configuration file for rutorrent

nano /etc/nginx/sites-available/rutorrent

Copy and paste the content below

server {
  listen   80;
  listen   [::]:80 default_server ipv6only=on; ## listen for ipv6

  root /usr/share/nginx/html;
  index index.php index.html index.htm;

  server_name localhost;

  location / {
    try_files $uri $uri/ /index.html;
  }

  error_page 500 502 503 504 /50x.html;
  location = /50x.html {
    root /usr/share/nginx/html;
  }

  # php5-fpm
  location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    # With php5-fpm:
    fastcgi_pass unix:/var/run/php5-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
  }
}

Create symlink to sites-enabled and restart nginx

cd /etc/nginx/sites-enabled
ln -s ../sites-available/rutorrent
# restart nginx
service nginx restart

Create a test file to verify php5-fpm is working

nano /usr/share/nginx/html/info.php
# use content below 
<?php
  phpinfo();
?>

Download rutorrent

cd /usr/share/nginx/html
svn checkout http://rutorrent.googlecode.com/svn/trunk/rutorrent
svn checkout http://rutorrent.googlecode.com/svn/trunk/plugins
rm -r rutorrent/plugins
mv plugins rutorrent/

And that’s it. Start rtorrent and things should work as it supposes to. Feel free to ask me any question if you got stuck.

If you’re a casual torrent user like me and still looking for a dead-cheap, torrent-friendly VPS provider, I may recommend you to take a look at RamNode. They provide a $15 per YEAR for 80GB of space and 500GB bandwidth. As long as you don’t do heavy torrenting and public trackers, you should be safe.

Cheers!


Using GitHub issue tracker as comment system for your static blog

Ivan Zuzak wrote about it here. It’s actually a very cool idea. All you need is to create a new repo on GitHub, create an issue for the blog post you want to enable comment and set commentIssueId in your blog post. A JavaScript ajax call will pull comments from GitHub on page load.

If I were to enable comments on my blog, I would defenitely go this route. You already blog like a hacker, you should also comment like one.

I’ve also seen people using Discourse for their website’s comments. The downside is setting up a new VPS and install Discourse(an online discussion software) seems like overkill for this purpose. Also, Discourse is not exactly lightweight. In order to install Discourse, you need a VPS with minimum 1GB of RAM (at least that was when I last tried it). My VPS has mere 128MB of memory, not exactly a beasty machine. The reason I went with static blog is it’s very lightweight. Using Discourse kinda defeat the purpose now, doesn’t it?

If you don’t want to go through all the troubles, you can use Disqus instead.


Resume-driven developer

A resume-driven developer can’t seem to use the same technology, in the same way all over again. When assigned an easy task, he will find ways to over-engineering a solution that will make it less boring. He loves injecting new technology into the current project, often without any upfront with other developers (well, this could be very bad since it may introduces competing UI framework, multiples data access methods, repeated functionalities, etc..). And when asked about it, he wil talk for hours about how horrible the current code/framework in the existing project is.

Does all of that sound familiar to you? If yes, you’re definitely a resume-driven developer.

I have to confess I’m that guy. I’m easy attracted to shiny new, cool technology but I found it hard to find motivation to learn it properly. Working in an actual project helps me learn better with all the challenges and deadline.

Decide what’s the next bullet you want to put on your resume at the end of the project, be it new language, new framework or some responsibilities, request to take that part of the project and make them true.

Resume-driven in itself isn’t bad. It’s actually a sign of a passionate developer. As long as it makes sense to introduce it to the current project without adding too much complexity, it will work. Remember, your code is not for you to read alone. It’s your job to manage the complexity, not to create it.


Shower thought about movie recommedation

Once in awhile, when I see a movie that I like, I go to IMDB and find out who directed it; who are the main actor/actress; what are the others highly rated movies of that director, main actor/actress. Then I will go on systematically watching one film after another. Given that they are good enough to keep me going.

The result is decidedly mixed. It doesn’t always turn out to be good as I want but it works, to a degree.

The thing about movie is that it takes million of dollars to make and it involves many parties. It’s hard for the creator to make the movie the way they indended to make. And I guess it makes sense. Making movie is unlike writing a novel; at least not until technology evolves to make producing movies cheap enough to be an habit like writing novels.

When that happened, recommender system for movies will be a lot easier to implemented and more accurated.


Inline Google fonts to further reduce number of blocking CSS resources

Most major browsers have support for .woff font format for quite awhile now. The number is around 85%+ with IE8 is the most high profile exception. But … who actually cares about IE8 right! Chances are if you are reading my blog, you won’t be using it anyway 1.

Ok, I’m convinced. How do I download and use .woff fonts now?

There is a npm package called webfont-dl which will create a ready-to-use CSS file with .woff fonts inline and other font formats as well as fallback. Including it in your main stylesheet and you’re done. Maybe organize it in a /fonts/ folder and update the font links in the CSS. That’s it.

To install webfont-dl: (nodejs required)

npm install -g webfont-dl

To download the CSS and webfonts:

webfont-dl "http://fonts.googleapis.com/css?family=Crimson+Text:400,400italic|Raleway:500" \
  -o css/font.css
  1. I provide fallbacks for unsupported browser anyway. See how nice I am ;) 


How to burn a bootable ISO file to USB stick on OS X

This method works with *unix ISO files. If you want to create a bootable Windows USB, use Bootcamp Assistant instead.

OS X shipped with dd installed. It’s a little utility to copy/convert from an input (your ISO file) to another output (your USB stick). The process is fairly easy.

Plugin your USB stick. Find where your USB stick is mounted by looking at the name and the size. It looks like /dev/diskX.

diskutil list

To burn the bootable ISO to USB stick, issue the following command. Replace the ISO file name with the path to your ISO file and diskX with the value you noted at the previous step.

sudo dd if=xubuntu-14.10-desktop-amd64.iso of=/dev/diskX

Enter your password, wait for a little while. It may looks like it’s hanging but do not abort. It would take few minutes, depends on the size of the ISO file.

If you find dd too slow, you can try replace /dev/diskX with /dev/rdiskX and add bs=4m option.

sudo dd if=xubuntu-14.10-desktop-amd64.iso of=/dev/rdiskX bs=4m

Contexts is the perfect companion app for Amethyst

⌘-Tab for application switching is a real nuisance. It’s application-based instead of document-based. Example, you have two documents, opened in two windows of an app. ⌘-Tab onlys show 1 entry (the app itself) in the application switcher, which is annoying. You have no way of getting to the window of the document that you want. Instead you will have to right click on the app icon in the dock and select from there.

Contexts is a simple app that solves a lot of problems with builtin ⌘-Tab app switcher.

Switching apps with Contexts

Contexts overrides the system shortcut ⌘-Tab so it will just fit right in.

The usual workflow when you want to switch to an app goes like this: you press ⌘-Tab, take a look at the list and keep pressing Tab until you get to the application you want to switch to. It’s far from idea because you can’t jump straight to the app you want but keep holding ⌘-Tab while checking the list.

Contexts solve this problem by showing a small sidebar with badge number. All you have to do is to press + number1 to switch to the coresponding app.

Another problem is with the Finder app. When I need to open a new Finder window when there isn’t any opened. I will have to ⌘-Tab then Tab to it. Finder will be brought to front without any active window. I then have to press ⌘-N combination to open a new window. So much trouble for a simple operation. Contexts fixes this by openning a new window when there isn’t one.

Switching app by searching

Switching app by searching is by far my favorite feature.

Contexts allows you to search by pressing Ctrl+Space then type app name or document’s title. This is a much improvement over the builtin application switcher. I can now switch app without the need to hold ⌘-Tab, which I found very tiresome.

contexts app os x

I only use ⌘-Tab to quickly switch back to the previous app because Contexts sorts apps by default that way.

Fin

I fell in love with Contexts sometimes ago. Then there was Amethyst. These two apps just complements each other perfectly, making managing app windows a breeze.

If you’ve never tried it, give it a shot. Once you do, you won’t go back. Guaranteed.

  1. I change the combination to Alt+number since it messes up with Chrome tab switching (⌘-number) shortcuts.