class DiasporaFederation::Discovery::HCard
This class provides the means of generating and parsing account data to and from the hCard format. hCard is based on +RFC 2426+ (vCard) which got superseded by +RFC 6350+. There is a draft for a new h-card format specification, that makes use of the new vCard standard.
@note The current implementation contains a huge amount of legacy elements
and classes, that should be removed and cleaned up in later iterations.
@todo This needs some radical restructuring. The generated HTML is not
correctly nested according to the hCard standard and class names are partially wrong. Also, apart from that, it's just ugly.
@example Creating a hCard document from a person hash
hc = HCard.new( guid: "0123456789abcdef", nickname: "user", full_name: "User Name", seed_url: "https://server.example/", photo_large_url: "https://server.example/uploads/l.jpg", photo_medium_url: "https://server.example/uploads/m.jpg", photo_small_url: "https://server.example/uploads/s.jpg", public_key: "-----BEGIN PUBLIC KEY-----\nABCDEF==\n-----END PUBLIC KEY-----", searchable: true, first_name: "User", last_name: "Name" ) html_string = hc.to_html
@example Create a HCard
instance from an hCard document
hc = HCard.from_html(html_string) ... full_name = hc.full_name ...
@see microformats.org/wiki/hCard “hCard 1.0” @see microformats.org/wiki/h-card “h-card” (draft) @see www.ietf.org/rfc/rfc2426.txt “vCard MIME Directory Profile” (obsolete) @see www.ietf.org/rfc/rfc6350.txt “vCard Format Specification”
Constants
- SELECTORS
CSS selectors for finding all the hCard fields
Public Class Methods
Creates a new HCard
instance from the given HTML string @param html_string [String] HTML string @return [HCard] HCard
instance @raise [InvalidData] if the HTML string is invalid or incomplete
# File lib/diaspora_federation/discovery/h_card.rb, line 149 def self.from_html(html_string) doc = parse_html_and_validate(html_string) new( guid: content_from_doc(doc, :uid), nickname: content_from_doc(doc, :nickname), full_name: content_from_doc(doc, :fn), photo_large_url: photo_from_doc(doc, :photo), photo_medium_url: photo_from_doc(doc, :photo_medium), photo_small_url: photo_from_doc(doc, :photo_small), searchable: (content_from_doc(doc, :searchable) == "true"), public_key: content_from_doc(doc, :key), # TODO: remove first_name and last_name! first_name: content_from_doc(doc, :given_name), last_name: content_from_doc(doc, :family_name) ) end
Private Class Methods
# File lib/diaspora_federation/discovery/h_card.rb, line 261 def self.content_from_doc(doc, content_selector) element = element_from_doc(doc, content_selector) element.content if element end
# File lib/diaspora_federation/discovery/h_card.rb, line 257 def self.element_from_doc(doc, selector) doc.at_css(SELECTORS[selector]) end
Make sure some of the most important elements are present in the parsed HTML document. @param [LibXML::XML::Document] doc HTML document @return [Boolean] validation result
# File lib/diaspora_federation/discovery/h_card.rb, line 244 def self.html_document_complete?(doc) !(doc.at_css(SELECTORS[:fn]).nil? || doc.at_css(SELECTORS[:photo]).nil?) end
# File lib/diaspora_federation/discovery/h_card.rb, line 248 def self.parse_html_and_validate(html_string) raise ArgumentError, "hcard html is not a string" unless html_string.instance_of?(String) doc = Nokogiri::HTML::Document.parse(html_string) raise InvalidData, "hcard html incomplete" unless html_document_complete?(doc) doc end
# File lib/diaspora_federation/discovery/h_card.rb, line 266 def self.photo_from_doc(doc, photo_selector) element_from_doc(doc, photo_selector)["src"] end
Public Instance Methods
Create the HTML string from the current HCard
instance @return [String] HTML string
# File lib/diaspora_federation/discovery/h_card.rb, line 121 def to_html builder = create_builder content = builder.doc.at_css("#content_inner") add_simple_property(content, :uid, "uid", @guid) add_simple_property(content, :nickname, "nickname", @nickname) add_simple_property(content, :full_name, "fn", @full_name) add_simple_property(content, :searchable, "searchable", @searchable) add_property(content, :key) do |html| html.pre(@public_key.to_s, class: "key") end # TODO: remove me! ################### add_simple_property(content, :first_name, "given_name", @first_name) add_simple_property(content, :family_name, "family_name", @last_name) ####################################### add_photos(content) builder.doc.to_xhtml(indent: 2, indent_text: " ") end
Private Instance Methods
Calls {HCard#add_property} to add the photos @param container [Nokogiri::XML::Element] parent element @see HCard#add_property
# File lib/diaspora_federation/discovery/h_card.rb, line 226 def add_photos(container) add_property(container, :photo) do |html| html.img(class: "photo avatar", width: "300", height: "300", src: @photo_large_url.to_s) end add_property(container, :photo_medium) do |html| html.img(class: "photo avatar", width: "100", height: "100", src: @photo_medium_url.to_s) end add_property(container, :photo_small) do |html| html.img(class: "photo avatar", width: "50", height: "50", src: @photo_small_url.to_s) end end
Add a property to the hCard document. The element will be added to the given container element and a “definition list” structure will be created around it. A Nokogiri::HTML::Builder instance will be passed to the given block, which should be used to add the element(s) containing the property data.
@param container [Nokogiri::XML::Element] parent element for added property HTML @param name [Symbol] property name @yield [Nokogiri::HTML::Builder] html builder
# File lib/diaspora_federation/discovery/h_card.rb, line 200 def add_property(container, name) Nokogiri::HTML::Builder.with(container) do |html| html.dl(class: "entity_#{name}") { html.dt(name.to_s.capitalize) html.dd { yield html } } end end
Calls {HCard#add_property} for a simple text property @param container [Nokogiri::XML::Element] parent element @param name [Symbol] property name @param class_name [String] HTML class name @param value [#to_s] property value @see HCard#add_property
# File lib/diaspora_federation/discovery/h_card.rb, line 217 def add_simple_property(container, name, class_name, value) add_property(container, name) do |html| html.span(value.to_s, class: class_name) end end
Creates the base HCard
html structure @return [Nokogiri::HTML::Builder] HTML Builder instance
# File lib/diaspora_federation/discovery/h_card.rb, line 172 def create_builder Nokogiri::HTML::Builder.new do |html| html.html { html.head { html.meta(charset: "UTF-8") html.title(@full_name) } html.body { html.div(id: "content") { html.h1(@full_name) html.div(id: "content_inner", class: "entity_profile vcard author") { html.h2("User profile") } } } } end end