diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 2cacb9e86..0ca3f7ad5 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,6 +1,6 @@ module ApplicationHelper - require 'lib/common' - include Diaspora::XMLParser + require 'lib/diaspora/diaspora_parser' + include Diaspora::DiasporaParser def object_path(object) eval("#{object.class.to_s.underscore}_path(object)") end diff --git a/app/models/album.rb b/app/models/album.rb index 7be8069d2..85a8de14f 100644 --- a/app/models/album.rb +++ b/app/models/album.rb @@ -1,5 +1,5 @@ class Album - require 'lib/common' + require 'lib/diaspora/webhooks' include MongoMapper::Document include ROXML include Diaspora::Webhooks diff --git a/app/models/post.rb b/app/models/post.rb index be121fa4c..e31007079 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,5 +1,5 @@ class Post - require 'lib/common' + require 'lib/diaspora/webhooks' include ApplicationHelper include MongoMapper::Document include ROXML diff --git a/app/models/request.rb b/app/models/request.rb index 55e20bbb8..5a81be719 100644 --- a/app/models/request.rb +++ b/app/models/request.rb @@ -1,5 +1,5 @@ class Request - require 'lib/common' + require 'lib/diaspora/webhooks' include MongoMapper::Document include Diaspora::Webhooks include ROXML diff --git a/app/models/user.rb b/app/models/user.rb index e01890dd2..7056ac695 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,5 @@ class User < Person - require 'lib/common' + require 'lib/diaspora/ostatus_parser' include Diaspora::OStatusParser devise :database_authenticatable, :registerable, diff --git a/lib/common.rb b/lib/common.rb deleted file mode 100644 index 73595d3f6..000000000 --- a/lib/common.rb +++ /dev/null @@ -1,305 +0,0 @@ -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 diff --git a/lib/diaspora/common.rb b/lib/diaspora/common.rb new file mode 100644 index 000000000..cda67cacb --- /dev/null +++ b/lib/diaspora/common.rb @@ -0,0 +1,3 @@ +module Diaspora + +end diff --git a/lib/diaspora/diaspora_parser.rb b/lib/diaspora/diaspora_parser.rb new file mode 100644 index 000000000..9220708e7 --- /dev/null +++ b/lib/diaspora/diaspora_parser.rb @@ -0,0 +1,45 @@ +module Diaspora + module DiasporaParser + 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 +end \ No newline at end of file diff --git a/lib/diaspora/ostatus_parser.rb b/lib/diaspora/ostatus_parser.rb new file mode 100644 index 000000000..01bdfdc66 --- /dev/null +++ b/lib/diaspora/ostatus_parser.rb @@ -0,0 +1,80 @@ +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 +end \ No newline at end of file diff --git a/lib/diaspora/webhooks.rb b/lib/diaspora/webhooks.rb new file mode 100644 index 000000000..9c9af0e5d --- /dev/null +++ b/lib/diaspora/webhooks.rb @@ -0,0 +1,180 @@ +module Diaspora + 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 \ No newline at end of file