Saturday, September 3, 2011

Find an installed Ruby Gem contents folder

 #!/usr/bin/env ruby  

def find_path gem_name
`gem list #{gem_name}` =~ /(.*)\s\((.*)\)/
version = $2.split(",")[0]
"#{Gem.default_dir}/gems/#{gem_name}-#{version}"
end
puts find_path ARGV[0]

Thursday, July 7, 2011

CouchDB with Jsonp

Download jquery.jsonp.js and ejs.js.

Templates "list.ejs"

 <ul>  
<% $.each(list, function(i, element) {%>
<li><%=element%></li>
<% }); %>
</ul>


test.html

 <!DOCTYPE html>  
<html>
<head>
<title>CouchDB Demo</title>
<%= stylesheet_link_tag 'jquery-ui', 'develop_demo' %>
<%= javascript_include_tag :defaults, 'jquery.couch', 'jquery.jsonp-2.1.4.min', 'ejs' %>
<%= csrf_meta_tag %>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
var url_all_dbs = "http://127.0.0.1:5984/_all_dbs";
function all_dbs() {
$.jsonp({
url: url_all_dbs + "?callback=?",
success: function(data) {
render_all_dbs(data);
}
});
}
function render_all_dbs(data) {
var template = new EJS({url: '/templates/list.ejs'})
var div_html = template.render({list: data});
$("#couch_all_dbs").html(div_html);
};
all_dbs();
});
</script>
</head>
<body>
<h1>Development Test</h1>
<div id="content">
Content...
<h1>all_dbs</h1>
<div id="couch_all_dbs"></div>
</div>
</body>
</html>

Thursday, March 24, 2011

HTML Audio Tag with Duration

Here is the code ..


 <html>  
<header>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
<script>
$(document).ready(function(){
var audioElement = document.getElementById('audio');
audioElement.addEventListener("durationchange", function() {
var duration_div = document.getElementById('duration');
var duration = parseInt(audioElement.duration);
var min = parseInt(duration / 60);
var sec = duration % 60;
var str = "" + min + ":" + sec;
duration_div.innerHTML = str;
}, true);
audioElement.addEventListener("timeupdate", function() {
var current_div = document.getElementById('current');
var cur_time = parseInt(audioElement.currentTime);
var min = parseInt(cur_time / 60);
var sec = cur_time % 60;
var str = "" + min + ":" + sec;
current_div.innerHTML = str;
}, true);
});
</script>
</header>
<body>
<audio id="audio" controls preload="auto" autobuffer>
<source src="test.mp3" />
</audio>
<span id="current"></span> / <span id="duration"></span>
</body>
</html>

Sunday, February 27, 2011

Ruby's mDNS (dnssd)

I'd like to have Zero conf services. So, I was looking for those Discovery libraries and found this.. Let's try

Here is the service side.

 require 'dnssd'  
domains = []
enumerator = DNSSD.enumerate_domains do |reply|
domains << reply.domain
next if reply.flags.more_coming?
puts "Found domains:\n#{domains.join "\n"}"
break
end
DNSSD.register 'agent', '_agent._tcp', nil, 6464
puts "registered agent at 6464"
loop do
sleep 1
puts "agent running.."
end


And here is the client side..

 require 'dnssd'  
browser = DNSSD::Service.new
puts "Browsing for Agent service"
browser.browse '_agent._tcp' do |reply|
puts "Time: #{Time.new.to_f} reply: #{reply.fullname}"
puts reply
break
end



3. Asynchronous Browse and Resolve

 require 'dnssd'  
require 'socket'
browser = DNSSD::Service.new
puts "Browsing for Agent service"
# Make it Asynchronous ..
Thread.new do
browser.browse '_agent._tcp' do |reply|
puts "Time: #{Time.new.to_f} reply: #{reply.fullname}"
puts reply.inspect
puts reply.service_name
target = nil
resolver = DNSSD::Service.new
resolver.resolve reply do |r|
target = r.target
puts "#{r.name} on #{r.target}:#{r.port}"
# puts "\t#{r.text_record.inspect}" unless r.text_record.empty?
break unless r.flags.more_coming?
end
resolver.stop
puts "target: #{target}"
addrinfo = Socket.getaddrinfo target, nil, Socket::AF_INET
puts "Addresses for #{target}"
addrinfo.each do |addr|
puts addr.inspect
end
break
end
end
sleep 1



Enjoy!

Friday, February 25, 2011

Fix EventMachine::PeriodicTimer

EventMachine::PeriodicTimer doesn't give an accurate timing. For example, if I add a periodic timer with 1 second interval, in my Mac, it looks like this.

1. the test code.

 require 'eventmachine'  
puts 'Start'
EM.run do
EM::add_periodic_timer 1.0 do
puts "time: #{Time.new.to_f.round(1)}"
end
end


2. output in my MacBook Pro.
 time: 1298620726.9  
time: 1298620728.0
time: 1298620729.1
time: 1298620730.1
time: 1298620731.2
time: 1298620732.3
time: 1298620733.4
time: 1298620734.5
time: 1298620735.5
time: 1298620736.6
time: 1298620737.7
time: 1298620738.8
time: 1298620739.9
time: 1298620741.0
time: 1298620742.0
time: 1298620743.1
time: 1298620744.2
time: 1298620745.3
time: 1298620746.4
time: 1298620747.4
time: 1298620748.5
time: 1298620749.6


As you can see, it drifted 100ms every time. Which is not very good when you want to do some job every 1 second. You might omit some seconds. So, with using the same method that I used for the Periodic ruby service, I made a change to PeriodicTimer. It looks like this.

 # Override PeriodicTimer  
module EventMachine
class PeriodicTimer
alias :old_initialize :initialize
def initialize interval, callback=nil, &block
# Added two additional instance variables to compensate difference.
@start = Time.now
@fixed_interval = interval
old_initialize interval, callback, &block
end
alias :old_schedule :schedule
def schedule
# print "Started at #{@start}..: "
compensation = (Time.now - @start) % @fixed_interval
@interval = @fixed_interval - compensation
# Schedule
old_schedule
end
end
end


So, here is the result (this is not that accurate like the simple ruby service, but reasonably useable.

 time: 1298620683.4  
time: 1298620684.4
time: 1298620685.4
time: 1298620686.4
time: 1298620687.4
time: 1298620688.4
time: 1298620689.4
time: 1298620690.4
time: 1298620691.3
time: 1298620692.3
time: 1298620693.4
time: 1298620694.4
time: 1298620695.4
time: 1298620696.4
time: 1298620697.4
time: 1298620698.4
time: 1298620699.4


That's it. :-)

Thursday, February 24, 2011

Ruby - Periodic Process

Ruby's sleep is not very accurate and Eventmachine's timer is also not very good. So, If you need to process one periodic job with some interval, this approach might be helpful. There is a compensation for sleep and you just need to define your process.

Here is the Service class.

 class Service  
def initialize
@interval = 1.0
@start_time = Time.now
end
def start
# Update the start-time
@start_time = Time.now
# run loop
loop do
t_start = Time.now
# process the job
process
elapsed = Time.now - t_start
if elapsed > @interval
puts "Error: Job is bigger than Interval.. #{elapsed}"
end
# apply some compensation.
compensation = (Time.now - @start_time) % @interval
sleep (@interval - compensation)
end
end
def process
raise NotImplementedError
end
end


And then, define your jobs in process method.

 class MyService < Service   
def initialize
super
@interval = 2.0
end
def process
puts "time: #{Time.now.to_f.round(3)}"
# do the random job .. it takes upto 1.5 seconds.
sleep rand(150) * 0.01
end
end


Try to run it..

 service = MyService.new  
service.start



And you will get a very accurate intervals

 time: 1298615010.271  
time: 1298615011.271
time: 1298615012.271
time: 1298615013.271
time: 1298615014.271
time: 1298615015.271
time: 1298615016.271
time: 1298615017.271
time: 1298615018.271
time: 1298615019.271
time: 1298615020.271
time: 1298615021.271
time: 1298615022.271
time: 1298615023.271
time: 1298615024.271
time: 1298615025.271
time: 1298615026.271
time: 1298615027.271
time: 1298615028.271
time: 1298615029.271
time: 1298615030.271
time: 1298615031.271
time: 1298615032.271
time: 1298615033.271
time: 1298615034.271
time: 1298615035.271
time: 1298615036.271
time: 1298615037.271
time: 1298615038.271
time: 1298615039.271
time: 1298615040.271
time: 1298615041.271
time: 1298615042.271


Next time, will try to fix Eventmachine timer..

Sunday, February 13, 2011

NodeJS - HTTP Request

1. GET

 var http = require('http');  
// GET.
var options = {
host: 'localhost',
port: 3000,
path: '/user/suwanny'
};
var req = http.get(options, function(res) {
console.log("Got response: " + res.statusCode);
res.on('data', function(chunk) {
console.log("Body: " + chunk);
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
});


2. POST

 // POST.   
var http = require('http');
var options = {
host: 'localhost',
port: 3000,
path: '/load/debug',
method: 'POST'
};
var req = http.request(options, function(res) {
console.log("Got response: " + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.on('data', function(chunk) {
console.log("Body: \n" + chunk);
});
});
req.end();

NodeJS - Socket.IO

1. ex_socketio.js

 var express = require('express'),   
server = express.createServer(),
io = require('socket.io');
server.configure(function(){
server.use(express.logger());
server.use(express.staticProvider(__dirname + '/www/public'));
});
server.listen(3000);
// socket.io
var socket = io.listen(server),
buffer = [];
socket.on('connection', function(client){
client.send({buffer: buffer});
client.broadcast({announcement: client.sessionId + ' connected'});
// new client is here!
client.on('message', function(message){
client.send({ message: "got your message: " + message});
client.broadcast({ message: client.sessionId + " sent message: " + message});
});
client.on('disconnect', function(){
client.broadcast({announcement: client.sessionId + ' disconnected'});
});
});


2. www/public/index.html

 <html>  
<head>
<title> Test </title>
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<h1> Hello NodeJS </h1>
<p> This is a static folder </p>
<p id="ann">empty now</p>
<p id="chat">empty now</p>
<script>
var socket = new io.Socket(null, {port: 3000});
socket.connect();
socket.on("message", function(obj) {
console.dir(obj);
if('buffer' in obj) {
document.getElementById('chat').innerHTML = '';
}
else {
if('announcement' in obj)
document.getElementById('ann').innerHTML = obj.announcement;
else
document.getElementById('chat').innerHTML = obj.message;
}
});
socket.send("this is the test message");
</script>
</body>
</html>

NodeJS - Express

This is an example which uses Express and Ejs with many configuration.
Here is the full guide http://expressjs.com/guide.html

1. Static files ..
 app.use(express.staticProvider(__dirname + '/www/public')); 


2. View files (EJS)
      app.set('views', __dirname + '/www/views');  
app.set('view engine', 'ejs');


layout.ejs

 <html> 
<head><title>EJS Layout</title></head>
<body>
<%- body %>
</body>
</html>


hello.js
 <h1>Hello</h1> 
<h2><%= api %></h2>


3. nodejs application

 // Production: NODE_ENV=production node ex_express.js 
// Development: NODE_ENV=development node ex_express.js
var express = require('express'),
app = express.createServer();
app.configure(function(){
app.use(express.logger());
app.use(express.methodOverride());
app.use(express.bodyDecoder());
app.use(app.router);
app.use(express.staticProvider(__dirname + '/www/public'));
app.set('views', __dirname + '/www/views');
app.set('view engine', 'ejs');
});
app.configure('development', function(){
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
});
app.configure('production', function(){
app.use(express.errorHandler());
});
// Application.
app.get('/user/:id', function(req, res) {
res.render('hello.ejs', {locals: {"api": "user"}});
});
app.post('/load/:mode', function(req, res) {
// console.dir(req);
var body = "<h1>Load</h1>";
body += req.params.mode + "\n"
body += req.param("workers") + "\n"
res.send(body);
});
app.listen(3000);
console.log("Public Dir: " + __dirname + '/public');
console.log("Service Started at " + 3000);

NodeJS- Useful Modules

1. express (RESTful routing, http://expressjs.com/ )
http://expressjs.com/guide.html

High performance, high class web development for Node.js

 var express = require('express');
var app = express.createServer();
app.get('/', function(req, res){
res.send('Hello World');
});
app.listen(3000);

Features
  • Robust routing
  • Redirection helpers
  • Dynamic view helpers
  • Application level view options
  • Content negotiation
  • Focus on high performance
  • View rendering and partials support
  • Environment based configuration
  • Session based flash notifications
  • Built on Connect
  • Executable for generating applications quickly
  • High test coverage




2. socket.io (Websocket)
http://soohwan.blogspot.com/2011/02/nodejs-socketio.html

3. couch_client (CouchDB)

4. node_redis (redis)

5. mDNS/Zeroconf/Bonjour (https://github.com/agnat/node_mdns)
Hmm unfortunately this is not useable in my Appliance, so I gave up to use this even though I need this feature.

 npm install mdns 



Service Discovery

node_mdns – service discovery for node.js
node_mdns adds support for multicast DNS service discovery, also known as zeroconf or bonjour to node.js. It provides an object-oriented interface to announce and browse services on the local network.

Internally, it uses the mDNSResponder API which is available on all major platforms.

On Linux and other systems using the avahi daemon the avahi dns_sd compat library and its header files are required.

 var mdns = require('mdns'); 
// Browser.
var browser = mdns.createBrowser('http');
browser.on('serviceUp', function(info, flags) {
console.log("up");
console.dir(info);
});
browser.on('serviceDown', function(info, flags) {
console.log("down");
console.dir(info);
});
browser.on('serviceChanged', function(info, flags) {
console.log("changed");
console.dir(info);
});
browser.start();
// Advertisement.
// mdns.createAdvertisement('http', 4321).start();


6. msgpack (gave up because it is hard to compile in my centos/mac)
A space-efficient object serialization library for NodeJS

Saturday, February 12, 2011

NodeJS- Routing / Redis

This is an example for multiple listening ports.

 var http = require('http');  
var connect = require('connect');
http.createServer(function(request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World from 8124\n');
}).listen(8124);
var server = connect.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello World from 3000');
}).listen(3000);
console.log('Server running at http://127.0.0.1:8124 & 3000');


2. Redis Example

 var redis = require('redis'),  
redis_client = redis.createClient();
redis_client.on('error', function(err) {
console.log("Error: " + err);
});
redis_client.set("Hello", "World", redis.print);
redis_client.hset("Hash", "field1", "value1", redis.print);
redis_client.hset(["Hash", "field2", "value2"], redis.print);
redis_client.hkeys("Hash", function(err, replies) {
console.log(replies.length + " replies:");
replies.forEach(function(reply, i) {
console.log(" " + i + ": " + reply);
});
// redis_client.quit();
});
var instruction = {
"id": "test1",
"musl": [ "1.mus", "2.mus", "3.mus"],
"hosts": {
"host_0": "a1",
"host_1": "a2"
}
};

/// --> this is not supported. (no nested object.)
redis_client.hmset("Inst1", instruction);


redis_client.hgetall("Inst1", function(err, obj) {
console.dir(obj);
});
var str_instruction = JSON.stringify(instruction);
console.log("str: " + str_instruction);
redis_client.set("instruction", str_instruction);
redis_client.get("instruction", function(err, value) {
console.log("get: " + value);
console.dir(JSON.parse(value));
});
// Publish/Subscribe
redis_client.on('message', function(channel, message) {
console.log("client1 channel " + channel + ": " + message);
});
redis_client.subscribe('testengine');


3. Redis PubSub Example

 var redis = require("redis"),  
client1 = redis.createClient(), client2 = redis.createClient(),
msg_count = 0;
client1.on("subscribe", function (channel, count) {
client2.publish("a nice channel", "I am sending a message.");
client2.publish("a nice channel", "I am sending a second message.");
client2.publish("a nice channel", "I am sending my last message.");
});
client1.on("message", function (channel, message) {
console.log("client1 channel " + channel + ": " + message);
msg_count += 1;
if (msg_count === 3) {
client1.unsubscribe();
client1.end();
client2.end();
}
});
client1.incr("did a thing");
client1.subscribe("a nice channel");

Thursday, February 10, 2011

A Simple Bash script to see the login information.

This is the script.

 #!/bin/bash  
for user in `ls -al /home | awk '{ print $9 }'`
do
echo $user
last -f /var/log/wtmp.1 -1 $user | head -1
last -1 $user | head -1
done


And, this is the output.

 bxxxx  
bxxxx pts/0 wireless1x............ Thu Jan 27 15:56 - 16:06 (00:09)
bxxxx pts/0 wireless1x-15-20 Tue Feb 1 11:44 - 12:19 (00:35)

Tuesday, February 8, 2011

CouchDB - Practice 01

With Curl

 curl http://127.0.0.1:5984/  
curl -X GET http://127.0.0.1:5984/_all_dbs
curl -X PUT http://127.0.0.1:5984/baseball
curl -X PUT http://127.0.0.1:5984/plankton
curl -X DELETE http://127.0.0.1:5984/plankton

Monday, February 7, 2011

Javascript MVC

This a practice to use Javascript MVC.

1. Download javascriptmvc from http://www.javascriptmvc.com/.

2. Move/Unzip and cd to your jmvc folder

3. Updates every sub libraries.
  ./js documentjs/update
./js funcunit/update
./js jquery/update
./js steal/update


4. Generates your app
 ./js jquery/generate/app cookbook
cookbook/cookbook.css
cookbook/cookbook.html
cookbook/cookbook.js
cookbook/controllers
cookbook/docs
cookbook/fixtures
cookbook/funcunit.html
cookbook/models
cookbook/qunit.html
cookbook/resources
cookbook/scripts
cookbook/scripts/build.html
cookbook/scripts/build.js
cookbook/scripts/clean.js
cookbook/scripts/docs.js
cookbook/test
cookbook/test/funcunit
cookbook/test/funcunit/cookbook_test.js
cookbook/test/funcunit/funcunit.js
cookbook/test/qunit
cookbook/test/qunit/cookbook_test.js
cookbook/test/qunit/qunit.js
cookbook/views


5. Make a Create-Read-Update-Delete (CRUD) scaffold.
 $ ./js jquery/generate/scaffold Cookbook.Models.Recipe 
cookbook/controllers
cookbook/controllers/recipe_controller.js
cookbook/fixtures
cookbook/fixtures/recipes.json.get
cookbook/models
cookbook/models/recipe.js
cookbook/test
cookbook/test/funcunit
cookbook/test/funcunit/recipe_controller_test.js
cookbook/test/qunit
cookbook/test/qunit/recipe_test.js
cookbook/views
cookbook/views/recipe
cookbook/views/recipe/edit.ejs
cookbook/views/recipe/init.ejs
cookbook/views/recipe/list.ejs
cookbook/views/recipe/show.ejs

Here's what each part does:

recipe_controller.js
Cookbook.Controllers.Recipe, like all Controllers, respond to events such as click and manipulate the DOM.
edit.ejs,init.ejs,list.ejs,show.ejs
Views are JavaScript templates for easily creating HTML.
recipe_controller_test.js
Tests the CRUD functionality of the user interface.
recipe.js
Cookbook.Models.Recipe model performs AJAX requests by manipulating services.
recipes.get
Fixtures simulate AJAX responses. This fixture responds to GET '/recipes'.
recipe_test.js
A unit test that tests Recipe model.


6. Including Scripts
After generating the scaffolding files, you must steal them in your application file. Open cookbook/cookbook.js and modify the code to steal your recipe controller and model as follows:
 steal.plugins(    
'jquery/controller',
'jquery/controller/subscribe',
'jquery/view/ejs',
'jquery/controller/view',
'jquery/model',
'jquery/dom/fixture',
'jquery/dom/form_params')
.css('cookbook')
.resources()
.models('recipe')
.controllers('recipe')
.views();

cookbook/test/qunit/qunits.js
 steal  
.plugins("funcunit/qunit", "cookbook")
.then("cookbook_test","recipe_test")

cookbook/test/funcunit/funcunit.js
 steal  
.plugins("funcunit")
.then("cookbook_test","recipe_controller_test")


7. That's it. open cookbook/cookbook.html

Thursday, February 3, 2011

CSS tutorial

Syntax

Two main parts:
- A selector
- Declarations

 selector   declarations   
h1 {color: blue; font-size:12px; }
p {color:red;text-align:center;}



Selectors

1. ID selector
The id selector uses the id attribute of the HTML element, and is defined with a "#". The style rule below will be applied to the element with id="para1":

 #para1  
{
text-align:center;
color:red;
}


2. Class Selector

The class selector is used to specify a style for a group of elements. Unlike the id selector, the class selector is most often used on several elements. This allows you to set a particular style for any HTML elements with the same class. The class selector uses the HTML class attribute, and is defined with a "."

Wednesday, February 2, 2011

Studying jQuery

I'm reading Essential JavaScript & jQuery Design Patterns by Addy Osmani. He and many other gurus mentioned about "A Pattern Language". Should I read the book? It was published in 1977. Sounds old, but still referred. It means it's kind of Bible and people are interested "Pattern". I don't know how they are related. There is the main and most important book, "Design Patterns: Elements of Reusable Object-Oriented Software", which introduced and made "Design Patterns" popular to the world. It defines 23 core Object-Oriented design patterns.

Addy talked about Design Patterns in jQuery and Javascript. Here are Lists.

jQuery
  • Lazy Initialization
  • Composite
  • Wrapper
  • Facade
  • Observer
  • Iterator
  • Strategy
  • Proxy
  • Builder
  • Prototype
  • Flyweight

Javascript
  • Creational
  • Constructor
  • Singleton
  • Module
  • Revealing Module
  • Prototype
  • DRY
  • Facade
  • Factory
  • Decorator
What is a pattern?
A: A pattern is a reusable solution that can be applied to commonly occurring problems in software design. There are three main benefits from Design Patterns.

1. Patterns are proven solutions.
2. Patterns can be easily re-used.
3. Patterns can be expressive.

However, Patterns are NOT an exact solution. It provides an idea and prototype. It can be building blocks and you can customize it for your project.

"Reusing patterns assists in preventing minor issues that can cause major problems in the application development process". - So, you can focus on your problem more. These days nobody starts from the scratch unless it is required.

"Patterns can provide generalized solutions which are documented in a fashion that doesn't require them to be tied to a specific problem."

"Certain patterns can actually decrease the overall file-size footprint of your code by avoiding repetition." - DRY (Don't Repeat Yourself)

A Good Pattern does these.
- Solves a particular problem.
- The solution to this problem cannot be obvious.
- The concept described must have been proven.
- It must describe a relationship.

Here is the rule of three for a valid pattern.
1. Fitness of purpose. - How?
2. Usefulness. - Why?
3. Applicability. - Wide?

----

The structure of a design pattern.

A design pattern must have a
  • Pattern Name and a description
  • Context outline
  • Problem Statement
  • Solution
  • Design
  • Implementation
  • Illustrations.
  • Examples
  • Co-requisites
  • Relations
  • Known usage
  • Discussions
Writing Design Patterns
  • Bare in mind practicability
  • Ensure that you draw upon best practices.
  • Your design patterns should be transparent to the user.
  • Remember that originality is not key in pattern design.
  • Know the differences between patterns and design.
  • Your pattern needs to have a strong set of examples.