module Diaspora module OStatusParser def self.find_hub(xml) xml = Nokogiri::HTML(xml) if xml.is_a? String xml.xpath('//link[@rel="hub"]').first.attribute("href").value end def self.process(xml) doc = Nokogiri::HTML(xml) author_hash = parse_author(doc) author_hash[:hub] = find_hub(doc) entry_hash = parse_entry(doc) author = Author.instantiate(author_hash) author.ostatus_posts.create(entry_hash) unless entry_hash[:message] == 0 end def self.parse_author(doc) doc = Nokogiri::HTML(doc) if doc.is_a? String author = {} author[:service] = parse_service(doc) author[:feed_url] = parse_feed_url(doc) author[:avatar_thumbnail] = parse_avatar_thumbnail(doc) author[:username] = parse_username(doc) author[:profile_url] = parse_profile_url(doc) author end def self.parse_entry(doc) doc = Nokogiri::HTML(doc) if doc.is_a? String entry = {} entry[:message] = parse_message(doc) entry[:permalink] = parse_permalink(doc) entry[:published_at] = parse_published_at(doc) entry[:updated_at] = parse_updated_at(doc) entry end ##author### def self.parse_service(doc) doc.xpath('//generator').each{|x| return x.inner_html} end def self.parse_feed_url(doc) doc.xpath('//id').each{|x| return x.inner_html} end def self.parse_avatar_thumbnail(doc) doc.xpath('//logo').each{|x| return x.inner_html} end def self.parse_username(doc) doc.xpath('//author/name').each{|x| return x.inner_html} end def self.parse_profile_url(doc) doc.xpath('//author/uri').each{|x| return x.inner_html} end #entry## def self.parse_message(doc) doc.xpath('//entry/title').each{|x| return x.inner_html} end def self.parse_permalink(doc) doc.xpath('//entry/id').each{|x| return x.inner_html} end def self.parse_published_at(doc) doc.xpath('//entry/published').each{|x| return x.inner_html} end def self.parse_updated_at(doc) doc.xpath('//entry/updated').each{|x| return x.inner_html} end end module XMLParser def parse_owner_from_xml(xml) doc = Nokogiri::XML(xml) { |cfg| cfg.noblanks } email = doc.xpath("//person/email").text.to_s Person.where(:email => email).first end def parse_body_contents_from_xml(xml) doc = Nokogiri::XML(xml) { |cfg| cfg.noblanks } doc.xpath("/XML/posts/post") end def parse_objects_from_xml(xml) objects = [] body = parse_body_contents_from_xml(xml) body.children.each do |post| begin object = post.name.camelize.constantize.from_xml post.to_s object.person = parse_owner_from_xml post.to_s if object.respond_to? :person objects << object rescue Rails.logger.info "Not a real type: #{object.to_s}" end end objects end def store_objects_from_xml(xml) objects = parse_objects_from_xml(xml) objects.each do |p| Rails.logger.info("Receiving object:\n#{p.inspect}") if p.is_a? Retraction p.perform elsif p.is_a? Request User.owner.receive_friend_request(p) #This line checks if the sender was in the database, among other things? elsif p.respond_to?(:person) && !(p.person.nil?) && !(p.person.is_a? User) #WTF Rails.logger.info("Saving object with success: #{p.save}") end #p.save if p.respond_to?(:person) && !(p.person == nil) #WTF end end end module Webhooks def self.included(klass) klass.class_eval do include ROXML require 'message_handler' @@queue = MessageHandler.new def notify_people if self.person_id == User.owner.id push_to(people_with_permissions) end end def subscribe_to_ostatus(feed_url) @@queue.add_subscription_request(feed_url) @@queue.process end def unsubscribe_from_ostatus(feed_url) @@queue.add_hub_unsubscribe_request(self.destination_url, self.callback_url+'hubbub', feed_url) @@queue.process end def push_to(recipients) @@queue.add_hub_notification(APP_CONFIG[:pubsub_server], User.owner.url + self.class.to_s.pluralize.underscore + '.atom') unless recipients.empty? recipients.map!{|x| x = x.url + "receive/"} xml = self.class.build_xml_for([self]) Rails.logger.info("Adding xml for #{self} to message queue to #{recipients}") @@queue.add_post_request( recipients, xml ) end @@queue.process end def push_to_url(url) hook_url = url + "receive/" xml = self.class.build_xml_for([self]) Rails.logger.info("Adding xml for #{self} to message queue to #{url}") @@queue.add_post_request( [hook_url], xml ) @@queue.process end def prep_webhook "#{self.to_xml.to_s}" end def people_with_permissions Person.friends.all end def self.build_xml_for(posts) xml = "" xml += "\n " posts.each {|x| xml << x.prep_webhook} xml += "" xml += "" end end end end module XML def self.generate(opts= {}) xml = Generate::headers(opts[:current_url]) xml << Generate::author xml << Generate::endpoints xml << Generate::subject xml << Generate::entries(opts[:objects]) xml << Generate::footer end module Generate def self.headers(current_url) #this is retarded @@user = User.owner <<-XML Diaspora #{current_url} Stream its a stream #{Time.now.xmlschema} XML end def self.author <<-XML #{@@user.real_name} #{@@user.url} XML end def self.endpoints <<-XML XML end def self.subject <<-XML http://activitystrea.ms/schema/1.0/person #{@@user.url} #{@@user.real_name} XML end def self.entries(objects) xml = "" if objects.respond_to? :each objects.each {|x| xml << self.entry(x)} else xml << self.entry(objects) end xml end def self.entry(object) eval "#{object.class}_build_entry(object)" end def self.StatusMessage_build_entry(status_message) <<-XML http://activitystrea.ms/schema/1.0/post #{status_message.message} #{@@user.url}status_messages/#{status_message.id} #{status_message.created_at.xmlschema} #{status_message.updated_at.xmlschema} XML end def self.Bookmark_build_entry(bookmark) <<-XML http://activitystrea.ms/schema/1.0/post #{bookmark.title} #{@@user.url}bookmarks/#{bookmark.id} #{bookmark.created_at.xmlschema} #{bookmark.updated_at.xmlschema} XML end def self.Blog_build_entry(blog) <<-XML http://activitystrea.ms/schema/1.0/post #{blog.title} #{blog.body} #{@@user.url}blogs/#{blog.id} #{blog.created_at.xmlschema} #{blog.updated_at.xmlschema} XML end def self.footer <<-XML.strip XML end end end end