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 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 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)
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)
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)

if p.education.kind_of?(Array)
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

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
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)
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

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

elsif p.experience.kind_of?(hCalendar)
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

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 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.


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.

• 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

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