Mar 31, 2011

Ruby cannot find installed gems

Problem

When we run any ruby file with ruby command, it won't be able to find all installed gems.

Solution

Add require 'rubygems' at the top of the file

Mar 30, 2011

Setting up multiple IP addresses on a single NIC (Linux)

Copied from: http://linuxhelp.blogspot.com/2005/05/setting-up-multiple-ip-addresses-on.html
(I just copy it in case it got lost)

In linux, you can bind multiple IP addresses on a single NIC. This is usually done in case you are using your linux machine as a web server and is hosting multiple domains and you want to bind each domain to a unique IP address. This is how it is done.

Let us assume that you already have a NIC which is bound with a static IP address. Then you will have a file called /etc/sysconfig/network-scripts/ifcfg-eth0 .My ifcfg-eth0 file has the following entries:


# File: ifcfg-eth0
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.1
NETMASK=255.255.255.0
BROADCAST=192.168.0.255
NETWORK=192.168.0.0
HWADDR=00:80:48:34:C2:84


Now to bind another IP address to the same NIC, I create a copy of the above file ifcfg-eth0 and name it as ifcfg-eth0:1


cd /etc/sysconfig/networking-scripts
cp ifcfg-eth0 ifcfg-eth0:1


Now just change the values of the DEVICE and IPADDR in the file as follows:


# File: ifcfg-eth0:1
DEVICE=eth0:1
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.5
NETMASK=255.255.255.0
BROADCAST=192.168.0.255
NETWORK=192.168.0.0
HWADDR=00:80:48:34:C2:84


And lastly, restart the networking service. If you are using RedHat, then it is as simple as :



service network restart

Facebook app to don't show scrollbar at all

In facebook app setting, just set the IFrame scrollbar option.

That's it.

Mar 28, 2011

Ruby has a weird mechanism of escaping a single quote and a double quote

Just don't try to escape a single quote. It's super complicated.

With a double quote, it is a little bit easier. Here's the cheat sheet:


'test " test'.gsub('"', '\\"')
# we got 'test \\\" test'

'test " test'.gsub('"', '"')
# we got 'test \" test'


Amazing, huh ?

How to make a slided page

In order to make a slided page. We need to have a frame with these minimal settings;



...



Inside of the frame, you need a span that contains the whole panel:




....




And each page is a span with these settings:


display:inline-block; // it will align on the same line
vertical-align:top; // it will align on the top
white-space:normal; // override white-space property because, in firefox, a child inherits white-space from its parent.


That makes:











In order to slide a page, we modify margin-left of the inner_frame

Mouseover-capturing trick when a span has children

Problem


The problem occurs when a span has children but you want to capture mouseover event over the span

Solution


The most elegant solution is to
1. add position:relative to the span
2. add a child span





3. Attach all events to the newly added child span instead.

It will be on top; if it doesn't, add z-index.

Mar 23, 2011

Navigate away with a link before finish Ajax request (jQuery)

And it'll produce an error.

Anyway, there is a way to detect whether the failure comes from navigating away or other causes.


$.ajax({
type: "POST",
url: '/test',
cache: false,
data: {

},
success: function(data){

},
error: function(req, status, e){
if (req.status == 0) return;
alert('Cannot connect to the server. Please try again later.');
}
});


On the line 12 is the trick

Mar 22, 2011

Encode URL and HTML using Javascript

We use native function of Javascript:


encodeURIComponent("http://www.yahoo.com");
// We'll get "http%3A%2F%2Fwww.yahoo.com"

Encode URL and HTML with Ruby

We simply use:


require 'cgi'
CGI.escape("http://www.yahoo.com")

Mar 21, 2011

Rails Critical Section through MySQL

The Problem

We have problem with agreeing with a comment in Squeks. If the same user agrees on the same comment at the same time, then 2 identical records of comment_agree will be created.

Therefore, we need some kind of critical section in order to prevent that situation.

The Solution

We use Named Lock provided by MySQL. You can use these two statements:


SELECT GET_LOCK('lock1',10);
SELECT RELEASE_LOCK('lock1');


Anyway, it's more convenient to build a class in order to deal with this:


class Lock
def self.lock(name)
return ActiveRecord::Base.connection.execute("SELECT GET_LOCK('#name}',60);").fetch_row[0]
end

def self.release(name)
ActiveRecord::Base.connection.execute("SELECT RELEASE_LOCK('#{name}');")
end

def initialize(*name)
@lock_name = Lock.generate_name(name)
end

def synchronize(&block)

Lock.lock(@lock_name) rescue (raise "Getting Lock #{@lock_name} timeout")

block.call()

while true
Lock.release(@lock_name) rescue next
break
end

end

private
def self.generate_name(names)
names.map{ |t| t.to_s}.join('--')
end
end

Welcome to whoWish knowledge-based system

This blog is for keeping programming techniques or installation techniques.

It is embedded with code snippet feature. For example:

// Comment
public class Testing {
public Testing() {
}

public void Method() {
/* Another Comment
on multiple lines */
int x = 9;
}
}



$(real_obj).blur(function()
{
if ($(real_obj).val() == "")
{
$(default_obj).show();
$(real_obj).hide();
}
});



user = $facebook
user = get_facebook_info(params[:user_id]) if params[:user_id]

So what else I need to have?

This is what I have:
- Good IDE
- Automated deployment
- Source Control
- Project Management for communication
- Logging practice

We needs:
- Knowledge-based system

And what else?

Mar 19, 2011

Current log viewer

We use LogExpert, which is free and has a nice highlight feature.

But I haven't tested it extensively in order to test if it can handle high-load of information or not.

It also has a tail feature.

So this tool is ok.

Best Web-based hosted project management tools

I have tried several project management tools. I have found out that Wrike is the best one (at least, for me). These are the PM tools that I have tried:

1. Basecamp - It's nice, but a task cannot be attached with files, and it does not have bug reports area.
2. 5pm - The UI is so uncomfortable and it does not have bug reports area.
3. AceProject - This one is not-well-designed. It's very difficult to use.
4. ProjectPlace - Too expensive. It's 1 person for 27 dollars per month per project.
5. CentralDesktop - a task cannot be attached with files

Wrike has everything:
- A task can be attached with files
- You can create any folder and any sub-folder. This means that I can create a sub-folder 'bugs' under any project.
- You can have as many folders as you want because Wrike charges according to number of users
- UI is generally good. It is easy to add task and assign to people.

And I feel like I start acting like a real CTO ...

Logging Best Pratice (Draft #0)

There are 5 levels of logging to utilize: DEBUG, INFO, WARNING, ERROR, and FATAL.

DEBUG
We should log these 4 entities:

1. Entry point of a method with parameters
2. Exit point of a method with returned values
3. the condition of a if-else and which branch it results in
4. every iteration of a loop with critical data

INFO
The general purpose of INFO level is to provide contextual information.

For example, you should log when a user logs in and also log the result of logging in. (Please also provide parameters information and results if it does not incur too much CPU cost).


WARNING
We should log some event as a warning when there is something wrong but it is not the code's fault.

For example,
1. user calls for a non-existing entity (the id is invalid).
2. Invalid status or unexpected status.
3. User is not logged and he/she is not supposed to have access to this method.

The general purpose of WARNING level is to reveal security problems.

ERROR
We should log all exceptions thrown in try-catch blocks. Please do include traces in the log.

FATAL
At FATAL level, we only log when the server is going to crash. I cannot think of any event that we have to log right now.

Besides, the server automatically logs errors for us when a fatal error occurs.

Mar 16, 2011

Log4r + Rails

There is only one way to integrate log4r with Rails.

If you do the following, you will encounter a very strange error, which is raised from "render :partial" because it cannot find outputters.

config.logger = Log4r::Logger.new("Application Log")
console_format = Log4r::PatternFormatter.new(:pattern => "%l:\t %m")
config.logger.add Log4r::StdoutOutputter.new('console', :formatter=>console_format)

file_format = Log4r::PatternFormatter.new(:pattern => "[ %d ] %l\t %m")
config.logger.add Log4r::FileOutputter.new('fileOutputter', :filename => RAILS_ROOT+"/log/"+RAILS_ENV+".log", :trunc => false, :formatter=>file_format)

config.log_level = :debug

SO DON'T DO THAT

Instead, please do this:

1. In environment.rb, put in this line:

... require File.join(File.dirname(__FILE__), 'boot')

require File.expand_path(File.dirname(__FILE__) + "/logger")

Rails::Initializer.run do |config| ...

2. Create logger.rb in config folder with these lines:

--------------------------

# Configure logging.
# We use various outputters, so require them, otherwise config chokes
require 'log4r'
require 'log4r/yamlconfigurator'
require 'log4r/outputter/fileoutputter'
require 'log4r/outputter/datefileoutputter'
require 'log4r/outputter/emailoutputter'


cfg = Log4r::YamlConfigurator
cfg['RAILS_ROOT'] = RAILS_ROOT
cfg['RAILS_ENV'] = RAILS_ENV

# load the YAML file with this
cfg.load_yaml_file("#{RAILS_ROOT}/config/log4r.yaml")
RAILS_DEFAULT_LOGGER = Log4r::Logger['default']
RAILS_DEFAULT_LOGGER.level = (RAILS_ENV == 'development' ? Log4r::DEBUG : Log4r::INFO)

if RAILS_ENV == 'test'
Log4r::Outputter['stderr'].level = Log4r::OFF
RAILS_DEFAULT_LOGGER.add( Log4r::Outputter['stderr_test'] )
end

if RAILS_ENV == 'production'
Log4r::Outputter['standardlog'].level = Log4r::OFF
Log4r::Outputter['stderr'].level = Log4r::OFF
else
Log4r::Outputter['email'].level = Log4r::OFF
end


--------------------------

3. Create log4r.yaml in config folder with these lines:


--------------------------

# *** YAML2LOG4R ***
log4r_config:
# define all loggers ...
loggers:
- name : default
level : DEBUG
additive : 'false'
trace : 'true'
outputters:
- stderr
- datefilelog
- standardlog
- email

# define all outputters (incl. formatters)
outputters:
- type : StderrOutputter
name : stderr
level : WARN
#only_at :
# - INFO
# - WARN
# - FATAL
formatter:
date_pattern: '%y%m%d %H:%M:%S'
#pattern : '%d %l: %m '
pattern : "[%l] %d :: %m"
type : PatternFormatter

- type : StderrOutputter
name : stderr_test
level : ERROR
formatter:
date_pattern: '%y%m%d %H:%M:%S'
# Added 'M' and 't' here - they are slow, but we're not calling unless we need to
pattern : "[%l] %d :: %M :: %t"
type : PatternFormatter

- type : DateFileOutputter
name : datefilelog
level : DEBUG
date_pattern: '%Y%m%d'
trunc : 'false'
dirname : "#{RAILS_ROOT}/log"
formatter :
date_pattern: '%y%m%d %H:%M:%S'
#pattern : '%d %l: %m '
pattern : "[%l] %d :: %m"
type : PatternFormatter

- type : FileOutputter
name : standardlog
level : DEBUG
trunc : 'false'
filename : "#{RAILS_ROOT}/log/#{RAILS_ENV}.log"
formatter :
date_pattern: '%y%m%d %H:%M:%S'
pattern : "[%l] %d :: %m"
type : PatternFormatter

- type : EmailOutputter
name : email
level : ERROR
server : smtp.example.com
port : '25'
#domain : smtp.example.com
authtype : none
#authtype : basic
#acct : dansketcher
#passwd : passwd
subject : 'Application Error'
from : error-handler-person@example.com
to : error-handler-person@example.com
immediate_at: "FATAL, ERROR"
formatfirst : 'true'
formatter :
date_pattern: '%y%m%d %H:%M:%S'
# Added 'M' and 't' here - they are slow, but we're not calling unless we need to
pattern : "[%l] %d :: %M :: %t"
type : PatternFormatter


--------------------------

Done !

Mar 14, 2011

Facebook Connect with redirect_uri problem

It's obvious that redirect_uri cannot contain the '?' (question mark) character.