A Web App for Identity Search - part 3

Posted on Wednesday, June 03, 2009 by Anuj Mehta

Now for parsing the response obtained from the LinkedIn ruby gem we need to have a good understanding of microformats.

Microformats

Microformats are set of simple, open data formats built upon existing standards for markup and data. They add structure and semantics to web publishing by adding metadata and other attributes to existing (X) HTML elements. There are several types of Microformats like rel-home, rel-tag, rel-me, XFN, hCard, hCalendar, hResume etc. LinkedIn stores all the profiles in hResume format hence we will focus on it.

hResume
hResume is a microformat for publishing resume’s and CV’s. It is a compound microformat as it utilizes 3 other microformats: rel-tag, hCard and hCalendar. Below is the structure of hResume and its subordinate microformats.





In our case hCard is used for representing contact information of a person while the hCalendar is generally used for representing event information. In our case hCalendar is used for representing educational background and the professional experience information. Like for ex for educational background the ‘summary’ can be something like brief details of the course while the start and end will have start and end date of the course. Below is the code snippet for retrieving information from hResume



first_name = params[:first_name]
@title = "Details of " + first_name
last_name = params[:last_name]
org = params[:org]
locality = params[:locality]
@linkedin = Linkedin.new
people = @linkedin.find({:given_name => first_name, :family_name => last_name,
:org => org, :locality => locality})

@people_array = Array.new
people.each { |p|
person_obj = Person.new
person_obj.summary = p.summary if p.properties.include?(SUMMARY)
person_obj.skills = p.skills if p.properties.include?(SKILLS)

if p.contact.properties.include?(URL)
person_obj.init_snapshot_url_hash
et = EasyThumb.new('ed65ca5fb868192ce9837456c8908bca', '4201')
if p.contact.url.kind_of?(Array)
p.contact.url.each { |site_name|
temp_url = et.build_url(:url => site_name , :size => :medium2, :cache => 1)
person_obj.add_url_to_snapshot_hash(site_name, temp_url)
}
else
site_name = p.contact.url
temp_url = et.build_url(:url => site_name , :size => :medium2, :cache => 1)
person_obj.add_url_to_snapshot_hash(site_name, temp_url)
end
end

if p.education.kind_of?(Array)
person_obj.init_edu_obj_arry
p.education.each { |klass|
temp_edu_obj = Person::Education.new
temp_edu_obj.summary = klass.summary unless klass.summary.nil?

if klass.dtstart.kind_of?(String)
temp_edu_obj.start_year = klass.dtstart
elsif klass.dtstart.kind_of?(Time)
temp_edu_obj.start_year = klass.dtstart.year
end

if klass.dtend.kind_of?(String)
temp_edu_obj.end_year = klass.dtend
elsif klass.dtend.kind_of?(Time)
temp_edu_obj.end_year = klass.dtend.year
end
person_obj.add_element_to_edu_obj_array(temp_edu_obj)
}
else
person_obj.init_edu_obj
person_obj.set_edu_summary p.education.summary unless p.education.summary.nil?
person_obj.set_edu_start_year p.education.dtstart.year unless p.education.dtstart.nil?
person_obj.set_edu_end_year p.education.dtend.year unless p.education.dtend.nil?
end if p.properties.include?(EDUCATION)

if p.experience.kind_of?(Array)
person_obj.init_exp_obj_array
p.experience.each { |exp|
temp_exp_obj = Person::Experience.new
temp_exp_obj.description = exp.description unless exp.description.nil?
temp_exp_obj.summary = exp.summary unless exp.summary.nil?

if exp.dtstart.kind_of?(Time)
temp_exp_obj.start_year = exp.dtstart.year
elsif exp.dtstart.kind_of?(String)
temp_exp_obj.start_year = exp.dtstart
end

if exp.dtend.kind_of?(Time)
temp_exp_obj.end_year = exp.dtend.year
elsif exp.dtend.kind_of?(String)
temp_exp_obj.end_year = exp.dtend
end

person_obj.add_element_to_exp_obj_array(temp_exp_obj)
}
elsif p.experience.kind_of?(hCalendar)
person_obj.init_exp_obj
person_obj.set_exp_summary = p.experience.summary unless p.experience.nil?
person_obj.set_exp_description = p.experience.description unless p.experience.nil?

if p.experience.dtstart.kind_of?(Time)
person_obj.set_exp_start_year = p.experience.dtstart.year
elsif p.experience.dtstart.kind_of?(String)
person_obj.set_exp_start_year = p.experience.dtstart
end

if p.experience.dtend.kind_of?(Time)
person_obj.set_exp_end_year = p.experience.dtend.year
elsif p.experience.dtend.kind_of?(String)
person_obj.set_exp_end_year = p.experience.dtend
end
end if p.properties.include?(EXPERIENCE)
@people_array << person_obj
} if people.kind_of?(Array)


Getting the current snapshot of website dynamically

The application shows the current snapshot of the website’s of the person in question so that user can glance over the information and if he interested he can click on the snapshot which will take them to that website. For getting this snapshot we had used the WebThumb Web Service.

Limitations

1. The application is highly dependent on one site i.e. LinkedIn which is not correct. In future I plan to search from other social networking sites. For which we can use Open Social API which provides a common API for accessing a number of social networking sites.
2. There is a lot of scope in improving the GUI. It can be made Rich.

References
• http://en.wikipedia.org/wiki/Semantic_Web
• Introduction to Semantic Web http://www.w3.org/2008/Talks/0924-Vienna-IH/Slides.pdf
• Microformats http://microformats.org/
• Getting semantic with microformats http://www.ablognotlimited.com/articles/getting-semantic-with-microformats-introduction/
• Yahoo BOSS API http://developer.yahoo.com/search/boss/
• WebThumb http://webthumb.bluga.net/home
• Writing a LinkedIn API library using Yahoo! BOSS web search http://developer.yahoo.net/blog/archives/2008/10/boss_is_the_gre.html
• Open Social http://www.opensocial.org/


Related Post
Part1
Part2

0 Responses to "A Web App for Identity Search - part 3":