Tuesday, April 12, 2011

SHARE - Client OS Detection

    <%= request.env['HTTP_USER_AGENT'] %>
    <%= request.env['HTTP_USER_AGENT'] =~ /Linux/ %>
    <%= request.env['HTTP_USER_AGENT'] =~ /Windows/ %>
    <%= request.env['HTTP_USER_AGENT'] =~ /Mac/ %>
    <%= request.env['HTTP_USER_AGENT'] =~ /iPhone/ %>

SHARE - How to get mp3 information (id3v1 and id3v2 tags) using ruby-mp3info

how to install gem
    gem install ruby-mp3info
how to use
    require "mp3info"
    begin
      mp3=Mp3Info.open(file_full_path)
      mp3.tag.title
      puts mp3.tag.artist  
      puts mp3.tag.album
    rescue Exception => e
      puts e.inspect
    end
for more information you can see here
http://ruby-mp3info.rubyforge.org/

SHARE - How to get image information using RMagick

    require 'RMagick'
    include Magick
    begin
      image=Image.read(pic_full_path).first
      image.filename #filename
      image.filesize #filesize
      image.columns #width
      image.page.width #width
      image.rows #height
      image.page.height #height
    rescue Exception => e
      puts e.inspect
    end

Friday, February 11, 2011

SHARE - TruliaMap integration

One of my client want add TruliaMap to one page for each his community site.
Each community have info about country, state/province, city, zipcode/postal code.

We can use this info for search it on google map.

What you need to make it work are latitude, langitude and zipcode for the place we want to search

add this to your controller

require 'open-uri'
require 'openssl'

url = "http://maps.googleapis.com/maps/api/geocode/xml?address=#{((community.name.to_s+' ')+(community.city.name.to_s+' ' if community.city)+(community.state.code.to_s+' ' if community.state)+(community.zipcode.zip.to_s if community.zipcode)).gsub(' ', '+')}&sensor=true"
xml = open(url).read
hash = Hash.from_xml(xml)
if hash['GeocodeResponse'] and hash['GeocodeResponse']['result'] and hash['GeocodeResponse']['result']['geometry'] and hash['GeocodeResponse']['result']['geometry']['location']
@lat= hash['GeocodeResponse']['result']['geometry']['location']['lat'] if hash['GeocodeResponse']['result']['geometry']['location']['lat']
@lng= hash['GeocodeResponse']['result']['geometry']['location']['lng'] if hash['GeocodeResponse']['result']['geometry']['location']['lng']
end


add this to your view

<div class='show-safety'>
<br/>
<div id="truliamap" style="font-family:arial,verdana;text-align:center; width:350px; height:380px; background-color:B5CF5A;">
<!--<div id="truliamap_header" style="color:;font-weight:bold;font-size:14px;padding:1px;height:16px;">Distinctive Properties</div>-->
<p style="margin:0px;padding:0px;line-height:0px;">
<iframe style="border:none; padding:0px; width:340px; height:329px;" frameborder="0" width="340" height="329" scrolling="no"
src="http://truliamap.trulia.com/truliamapapi/?a=5fa9ac&u=fd63b6&sid=&cv=&v=map&d=source&lat=<%= @lat -%>&lng=<%= @lng -%>&s=large&r=&city=&state=&uid=&zip=<%= community.zipcode.zip.to_s -%>">your browser not compatible</iframe>
</p>
<div style="margin-left:5px;margin-right:5px;text-align:left;font-size:11px;">
<div style="float:left;width:100px;">
<a id="map_signup" href="http://www.trulia.com/tools/map/" target="_blank" style="color:;">Get your own TruliaMap</a></div>
<div id="map_logo" style="float:right;width:79px;cursor:pointer;">
<a href="http://www.trulia.com/" target="_blank">
<img name="mmlogo" id="mmlogo" style="padding:0px; margin:0px;border-width:0px;" src="http://static.trulia-cdn.com/images/map/mm/logo-grn.gif" border="0" alt="Real Estate Search">
</a>
</div>
</div>
</div>
</div>

You can generate the code here http://www.trulia.com/tools/map/

SHARE - How to calculate how much brighness from color

My client ask me about how to make text black or white color base on background color for that text.

example:

- background color black, color of text is white
- background color white, color of text is black
- background color yellow, color of text is black
- background color dark-purple, color of text is white

I think I need to calculate how much brighness from background color that used.

After googling I found this formula for calculating brighness.

brightness = sqrt( .241 R2 + .691 G2 + .068 B2 )

R = red color (decimal)
G = green color (decimal)
B = blue color (decimal)

example:
   
background color : EA0516, text color : FFFFFF
backgorund color : FFFF00, text color : 000000

on my model

class model

def self.calculate_brightness(color) #format color on hex without #, example FFFFFF
r = color[0..1].hex
g = color[2..3].hex
b = color[4..5].hex
value = Math.sqrt(r * r * 0.241 + g * g * 0.691 + b * b * 0.068)
(value < 130 ? 'FFFFFF' : '000000')
end

end

You can see more information here
http://alienryderflex.com/hsp.html
http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx

SHARE - How to embed font from swf file using Font Loader

You can download Fontloader [here](http://etcs.ru/pre/FontLoaderDemo/srcview/FontLoaderDemo.zip)

You can see demo [here](http://etcs.ru/pre/FontLoaderDemo/)

FontLoader can embed all your font automatically.

It better then my last post about embed font on flash.


on your action script

package{

import flash.net.URLLoader;
import flash.net.URLRequest;

import ru.etcs.utils.FontLoader;

public class Main extends Sprite {

private const _loader:FontLoader = new FontLoader();

public function Main(){

this._loader.addEventListener(Event.COMPLETE, this.handler_complete);
this._loader.load(new URLRequest("Arial.swf"), true);

}

private function handler_complete(event:Event):void {

if(this._loader.fonts.length>0){
trace('FONTS');
var fonts:Array = this._loader.fonts;
for each (var font:Font in fonts) {
trace('--------------------------------------');
trace(font);
trace(font.fontName);
trace('--------------------------------------');
}
}
}

}

}

SHARE - Event handler for page refresh and back button


<input type="hidden" id="refreshed" value="no"/>
<script type="text/javascript">
onload=function(){
var e=document.getElementById("refreshed");
if(getCookie('location_url')==location.href){
e.value="no";
}
setTimeout('setCookie(\'location_url\',location.href);', 100)
if(e.value=="no"){ //page loaded on the first time
e.value="yes";
}else{ //page refreshed or back to this page
e.value="no";
//run your code for the event here
e.value="yes";
}
}
onkeypress=function(event){ //page refreshed
if(event.keyCode==116){
var e=document.getElementById("refreshed");
e.value="no";
}
}
onkeydown=function(event){ //page refreshed
if(event.ctrlKey && event.keyCode == 82){
var e=document.getElementById("refreshed");
e.value="no";
}
}
</script>

SHARE - How to embed font from 2 files swf

on your action script

package{
public class Main extends Sprite {
private var fontFace:FontControl;

public function Main(){
envFontFace = new FontControl();
envFontFace.addEventListener(FontControl.COMPLETE, loadFont);
envFontFace.load("Arial.swf", "Aller.swf",
[{font:'Arial', id:'Arial'}, {font:'Aller', id:'Aller'}])
}
}
}


add this to FontControl.as

package{
import flash.display.Loader;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.EventDispatcher;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.text.Font;

public class FontControl extends EventDispatcher
{
public static const COMPLETE:String = "font_load_complete";
public static const ERROR:String = "font_load_error";
public static var FONTS:Array;

private var _loaderENV:Loader;
private var _loaderINV:Loader;
private var _domainENV:ApplicationDomain;
private var _domainINV:ApplicationDomain;

private var fileLoaded:int;

public function FontControl() {
}
public function load(envPath:String, invPath:String, fontArr:Array):void
{
FONTS = fontArr;
fileLoaded = 0;
_loaderENV = new Loader();
_loaderENV.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, _ioErrHdlr);
_loaderENV.contentLoaderInfo.addEventListener(Event.COMPLETE, _loadComplete);
_loaderENV.load(new URLRequest(envPath));

_loaderINV = new Loader();
_loaderINV.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, _ioErrHdlr);
_loaderINV.contentLoaderInfo.addEventListener(Event.COMPLETE, _loadComplete);
_loaderINV.load(new URLRequest(invPath));
}

private function _loadComplete(e:Event):void
{
fileLoaded = fileLoaded + 1 ;
if(fileLoaded == 2){
_domainENV = _loaderENV.contentLoaderInfo.applicationDomain;
_domainINV = _loaderINV.contentLoaderInfo.applicationDomain;
_registerFonts();
var embeddedFonts:Array = Font.enumerateFonts(false);
}
}

private function _registerFonts():void
{
for (var i:uint = 0; FONTS[i]; i++)
{
if(i==0){
if(_domainENV.hasDefinition(FONTS[i].id)){
Font.registerFont(_domainENV.getDefinition(FONTS[i].id) as Class);
}
if(_domainENV.hasDefinition(FONTS[i].id+'Bold')){
Font.registerFont(_domainENV.getDefinition(FONTS[i].id+'Bold') as Class);
}
if(_domainENV.hasDefinition(FONTS[i].id+'BoldItalic')){
Font.registerFont(_domainENV.getDefinition(FONTS[i].id+'BoldItalic') as Class);
}
if(_domainENV.hasDefinition(FONTS[i].id+'Italic')){
Font.registerFont(_domainENV.getDefinition(FONTS[i].id+'Italic') as Class);
}
}
if(i==1){
if(_domainINV.hasDefinition(FONTS[i].id)){
Font.registerFont(_domainINV.getDefinition(FONTS[i].id) as Class);
}
if(_domainINV.hasDefinition(FONTS[i].id+'Bold')){
Font.registerFont(_domainINV.getDefinition(FONTS[i].id+'Bold') as Class);
}
if(_domainINV.hasDefinition(FONTS[i].id+'BoldItalic')){
Font.registerFont(_domainINV.getDefinition(FONTS[i].id+'BoldItalic') as Class);
}
if(_domainINV.hasDefinition(FONTS[i].id+'Italic')){
Font.registerFont(_domainINV.getDefinition(FONTS[i].id+'Italic') as Class);
}
}
}
dispatchEvent(new Event(COMPLETE));
}

private function _ioErrHdlr(e:IOErrorEvent):void
{
trace(e);
dispatchEvent(new Event(ERROR));
}
}
}

SHARE - How to achieve cross browser font-face support

@font-face browser support

Webkit/Safari

* since version 3.1
* font formats:
o TrueType/OpenType TT (.ttf)
o OpenType PS (.otf)
o SafariMobile (iPhone/iPad)
+ only SVG Fonts until iOS 4.1
+ TrueType/OpenType since iOS 4.2
* More info: http://webkit.org/blog/124/downloadable-fonts/

Opera

* since
Opera 10: http://www.opera.com/browser/ and Opera Mobile 9.7
* font formats:
o TrueType/OpenType TT (.ttf)
o OpenType PS (.otf)
o SVG (.svg)
* More info: http://dev.opera.com/articles/view/seven-web-fonts-showcases/


Internet Explorer

* since IE 4
* font formats:
o Embedded OpenType (EOT) created by Microsoft's WEFT tool
o WOFF since IE9
* More info: http://www.microsoft.com/typography/web/embedding/default.aspx

Mozilla/Firefox

* since Firefox 3.5
* font formats
o TrueType/OpenType TT (.ttf)
o OpenType PS (.otf)
o WOFF (since Firefox 3.6)


Google Chrome

* In Chrome 4.0 stable release. As of January 25th, 2010
* In Chrome 3.0, you could run the executable with a command line switch of: --enable-remote-font
* More details on chrome and @font-face here
* font formats
o TrueType/OpenType TT (.ttf)
o OpenType PS (.otf)
o WOFF since version 6

Netscape

* since version 4, discontinued since Netscape Navigator 6
* font formats:
o Portable Font Resource (.pfr)
* more info: http://en.wikipedia.org/wiki/TrueDoc

For more detail you can see here
http://webfonts.info/wiki/index.php?title=@font-face_browser_support


So base on that information we need some font type for @font-face to work

* eot for ie
* ttf or otf
* woff (optional)
* svg for mobile device


on my css

@font-face {
font-family: 'Arial';
src: url('../fonts/arial-webfont.eot');
src: local('☺'),
url('../fonts/arial-webfont.woff') format('woff'),
url('../fonts/arial-webfont.ttf') format('truetype'),
url('../fonts/arial-webfont.svg#webfontOVtGScWg') format('svg');
font-weight: normal;
font-style: normal;
}

to generate eot type we need WEFT http://www.microsoft.com/typography/WEFT.mspx


for simpleness we can generate it using font-face generator by squirrel.com

http://www.fontsquirrel.com/fontface/generator


for more detail you can see here


http://blog.themeforest.net/tutorials/how-to-achieve-cross-browser-font-face-support/
http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/
http://randsco.com/index.php/2009/07/04/p680

SHARE - How to get content from Outside.in

Outside.in is the leading provider of hyperlocal news and information. Outside.in show consumers neighborhood news and information from local bloggers, journalists and mainstream media on hundreds of trusted news sites across the Outside.in Network including CNN.com as well as www.outside.in


We can get the stories using this example. I add this on LocalNews class.

class LocalNews < ActiveRecord::Base

@key = 'f889ntmabe5mjqr9dzd2a7ce'
@secret = 'yZM6nU4zGR'

require 'open-uri'
require 'openssl'
require 'md5'

def self.generate_key
"dev_key=#{@key}&sig=#{MD5.new(@key + @secret + Time.now.to_i.to_s).hexdigest}"
end

def self.generate_url_from_zipcode(zipcode, oi_key, limit)
'http://hyperlocal-api.outside.in/v1.1/zipcodes/'+zipcode.to_s+'/stories?'+oi_key+(limit.nil? ? '' : '&limit='+limit.to_s)
end

def self.get_content(zipcode, limit=20)
oi_key = generate_key
url = generate_url_from_zipcode(zipcode, oi_key, limit)
open_url = open(url) rescue nil
return '' if open_url.nil?
json = open_url.read

contents = JSON.parse(json)
end
end


We can get stories using command like this

LocalNews.get_content(12345)


We can limit our stories to some number using command like this

It'll get 5 stories.

LocalNews.get_content(12345, 5)


I use Json to parse the stories.

SHARE - How to know file that generated using background job already created or not

Sometimes we need to know file that generated using background job already created or not.

We can check that file already exist, readable and created using this method.

We can use this to check file already exist or not

File.exist?(file_path)
#true if file exist
#false if not exist



We can use this to check file readable or not

File.readable?(file_path)
#true if file readable
#false if not readable


We need this to check file already finish created or not

File.zero?(file_path)
#true if file exist but not yet finish created
#false if file exist and already created