diff --git a/app/controllers/requests_controller.rb b/app/controllers/requests_controller.rb index d4b2384fc..4c7ed6916 100644 --- a/app/controllers/requests_controller.rb +++ b/app/controllers/requests_controller.rb @@ -25,9 +25,11 @@ class RequestsController < ApplicationController end def create - url = relationship_flow(params[:request][:destination_url])[:friend] + rel_hash = relationship_flow(params[:request][:destination_url]) + + puts rel_hash + @request = current_user.send_request(rel_hash) - @request = current_user.send_friend_request_to(url) unless url.include?('@')|| url == '' if @request flash[:notice] = "a friend request was sent to #{@request.destination_url}" redirect_to requests_url diff --git a/app/helpers/requests_helper.rb b/app/helpers/requests_helper.rb index 617cafd1b..aebc76cce 100644 --- a/app/helpers/requests_helper.rb +++ b/app/helpers/requests_helper.rb @@ -25,7 +25,6 @@ module RequestsHelper def subscription_url(action, profile) if action == :subscribe - pp profile.links profile.links.select{|x| x.rel == 'http://schemas.google.com/g/2010#updates-from'}.first.href elsif action == :friend profile.links.select{|x| x.rel == 'http://joindiaspora.com/seed_location'}.first.href diff --git a/app/models/request.rb b/app/models/request.rb index c3962a0f5..55e20bbb8 100644 --- a/app/models/request.rb +++ b/app/models/request.rb @@ -37,7 +37,7 @@ class Request p.active = true p.save end - + protected diff --git a/app/models/user.rb b/app/models/user.rb index 4c22fcabd..e78978d8a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,4 +1,6 @@ class User < Person + require 'lib/common' + include Diaspora::OStatusParser devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable @@ -75,6 +77,26 @@ class User < Person end end + ####ostatus###### + # + def subscribe_to_pubsub(feed_url) + r = Request.instantiate(:to => feed_url, :from => self) + r.subscribe_to_ostatus(feed_url) + r + end + + + def send_request(rel_hash) + puts rel_hash.inspect + if rel_hash[:friend] + self.send_friend_request_to(rel_hash[:friend]) + elsif rel_hash[:subscribe] + self.subscribe_to_pubsub(rel_hash[:subscribe]) + else + raise "you can't do anything to that url" + end + end + ###Helpers############ def mine?(post) diff --git a/lib/common.rb b/lib/common.rb index 2974371d0..7fd24eb6e 100644 --- a/lib/common.rb +++ b/lib/common.rb @@ -1,6 +1,20 @@ module Diaspora - module XMLParser + module OStatusParser + def self.find_hub(xml) + Nokogiri::HTML(xml).xpath('//link[@rel="hub"]').first.attribute("href").value + end + def self.parse_sender(xml) + puts "you just won the game" + end + + def self.parse_objects(xml) + + 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 @@ -57,8 +71,13 @@ module Diaspora end end + def subscribe_to_ostatus(feed_url) + puts feed_url + @@queue.add_subscription_request(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? diff --git a/lib/message_handler.rb b/lib/message_handler.rb index 641627383..682b846ab 100644 --- a/lib/message_handler.rb +++ b/lib/message_handler.rb @@ -1,5 +1,6 @@ class MessageHandler + NUM_TRIES = 3 TIMEOUT = 5 #seconds @@ -11,14 +12,29 @@ class MessageHandler destinations.each{ |dest| @queue.push(Message.new(:get, dest))} end + def add_subscription_request(feed_url) + @queue.push(Message.new(:ostatus_subscribe, feed_url)) + end def add_post_request(destinations, body) b = CGI::escape( body ) - destinations.each{|dest| @queue.push(Message.new(:post, dest, b))} + destinations.each{|dest| @queue.push(Message.new(:post, dest, :body => b))} end - def add_hub_notification(destination, feed_location) - @queue.push(Message.new(:pubhub, destination, feed_location)) + # pubsubhubbub + def add_hub_notification(hub_url, feed_url) + @queue.push(Message.new(:hub_publish, hub_url, :body => feed_url)) + end + + def add_hub_subscription_request(hub_url, feed_url) + @queue.push(Message.new(:hub_subscribe, hub_url, :body => feed_url)) + end + + + def process_ostatus_subscription(query_object, http) + hub = Diaspora::OStatusParser::find_hub(http.response) + add_hub_subscription_request(hub, query_object.destination) + Diaspora::OStatusParser::parse_sender(http.response) end def process @@ -26,13 +42,23 @@ class MessageHandler case query.type when :post http = EventMachine::HttpRequest.new(query.destination).post :timeout => TIMEOUT, :body =>{:xml => query.body} - http.callback { puts query.destination; process; process} + http.callback { puts query.destination; process; process} when :get http = EventMachine::HttpRequest.new(query.destination).get :timeout => TIMEOUT http.callback {send_to_seed(query, http.response); process} - when :pubhub + + when :ostatus_subscribe + puts query.destination + http = EventMachine::HttpRequest.new(query.destination).get :timeout => TIMEOUT + http.callback { process_ostatus_subscription(query, http); process} + + when :hub_publish http = EventMachine::PubSubHubbub.new(query.destination).publish query.body, :timeout => TIMEOUT http.callback { process} + + when :hub_subscribe + http = EventMachine::PubSubHubbub.new(query.destination).subscribe query.body, User.owner.url, :timeout => TIMEOUT + http.callback { process} else raise "message is not a type I know!" end @@ -56,11 +82,12 @@ class MessageHandler end class Message - attr_accessor :type, :destination, :body, :try_count - def initialize(type, dest, body= nil) + attr_accessor :type, :destination, :body, :callback, :try_count + def initialize(type, dest, opts = {}) @type = type @destination = dest - @body = body + @body = opts[:body] + @callback = opts[:callback] ||= lambda{ process; process } @try_count = 0 end end diff --git a/spec/fixtures/identica_feed.atom b/spec/fixtures/identica_feed.atom new file mode 100644 index 000000000..d590fc1f4 --- /dev/null +++ b/spec/fixtures/identica_feed.atom @@ -0,0 +1,166 @@ + + + StatusNet + http://identi.ca/api/statuses/user_timeline/169966.atom + joindiaspora timeline + Updates from joindiaspora on Identi.ca! + http://avatar.identi.ca/169966-96-20100426170852.png + 2010-07-22T01:00:38+00:00 + + joindiaspora + http://identi.ca/user/169966 + + + + + + + + + http://activitystrea.ms/schema/1.0/person + http://identi.ca/user/169966 + Diaspora + + + + + +joindiaspora +Diaspora +Diaspora is an awesome, distributed, open source social network in the making from some young hackers at NYU + + homepage + http://joindiaspora.com + true + + + + A month of Diaspora in action. First screenshots/video! http://bit.ly/clOFXx + + http://identi.ca/notice/39231942 + 2010-07-02T06:13:11+00:00 + 2010-07-02T06:13:11+00:00 + + + A month of Diaspora in action. First screenshots/video! <a href="http://bit.ly/clOFXx" title="http://www.joindiaspora.com/2010/07/01/one-month-in.html" rel="external">http://bit.ly/clOFXx</a> + + + http://www.reclaimprivacy.org/ check your FB privacy settings, automagically! !whyisntthisbuiltintofacebook :) + + http://identi.ca/notice/32556574 + 2010-05-17T18:18:28+00:00 + 2010-05-17T18:18:28+00:00 + + + <a href="http://www.reclaimprivacy.org/" title="http://www.reclaimprivacy.org/" rel="external">http://www.reclaimprivacy.org/</a> check your FB privacy settings, automagically! !whyisntthisbuiltintofacebook :) + + + @cacheson, should already be there, at http://joindiaspora.com/atom.xml... hopefully that will do the trick... + + http://identi.ca/notice/31824813 + 2010-05-11T14:29:38+00:00 + 2010-05-11T14:29:38+00:00 + + + + @<span class="vcard"><a href="http://identi.ca/user/47185" class="url" title="Chris Acheson"><span class="fn nickname">cacheson</span></a></span>, should already be there, at <a href="http://joindiaspora.com/atom.xml" title="http://joindiaspora.com/atom.xml" rel="external" class="attachment" id="attachment-15490501">http://joindiaspora.com/atom.xml</a>... hopefully that will do the trick... + + + + @elmom, thanks for your support. we are excited to get started. helsinki is awesome, I hope to go back one day! good luck w/hackerspace! + + http://identi.ca/notice/30760606 + 2010-05-02T07:06:02+00:00 + 2010-05-02T07:06:02+00:00 + + + + @<span class="vcard"><a href="http://identi.ca/user/101533" class="url" title="Elmo M&#xE4;ntynen"><span class="fn nickname">elmom</span></a></span>, thanks for your support. we are excited to get started. helsinki is awesome, I hope to go back one day! good luck w/hackerspace! + + + @tieguy, thanks for the great feedback, here is our response: http://bit.ly/aF2Fpl + + http://identi.ca/notice/30549323 + 2010-04-30T06:29:28+00:00 + 2010-04-30T06:29:28+00:00 + + + + @<span class="vcard"><a href="http://identi.ca/user/11" class="url" title="Luis Villa"><span class="fn nickname">tieguy</span></a></span>, thanks for the great feedback, here is our response: <a href="http://bit.ly/aF2Fpl" title="http://joindiaspora.com/2010/04/30/a-response-to-mr-villa.html" rel="external">http://bit.ly/aF2Fpl</a> + + + RT @tieguy @joindiaspora hopefully constructive questions for you: http://ur1.ca/xbvq cc: @mlinksva @rejon @biella@brainbird.net + + http://identi.ca/notice/30154486 + 2010-04-27T06:22:14+00:00 + 2010-04-27T06:22:14+00:00 + + + + RT @<span class="vcard"><a href="http://identi.ca/user/11" class="url" title="Luis Villa"><span class="fn nickname">tieguy</span></a></span> @<span class="vcard"><a href="http://identi.ca/user/169966" class="url" title="Diaspora"><span class="fn nickname">joindiaspora</span></a></span> hopefully constructive questions for you: <a href="http://ur1.ca/xbvq" title="http://tieguy.org/blog/2010/04/27/questions-for-the-diaspora/" rel="external">http://ur1.ca/xbvq</a> cc: @<span class="vcard"><a href="http://identi.ca/user/8" class="url" title="Mike Linksvayer"><span class="fn nickname">mlinksva</span></a></span> @<span class="vcard"><a href="http://identi.ca/user/37" class="url" title="Jon Phillips"><span class="fn nickname">rejon</span></a></span> @<span class="vcard"><a href="http://brainbird.net/biella" class="url"><span class="fn nickname">biella@brainbird.net</span></a></span> + + + @tieguy it's on! ;) we have already thought about much of your comments, but give us a day or two to give you a good response. + + http://identi.ca/notice/30152694 + 2010-04-27T06:04:30+00:00 + 2010-04-27T06:04:30+00:00 + + + + @<span class="vcard"><a href="http://identi.ca/user/11" class="url" title="Luis Villa"><span class="fn nickname">tieguy</span></a></span> it's on! ;) we have already thought about much of your comments, but give us a day or two to give you a good response. + + + @mattkatz00 we really appreciate your kickstarter backing! + + http://identi.ca/notice/30089749 + 2010-04-26T19:32:19+00:00 + 2010-04-26T19:32:19+00:00 + + + @mattkatz00 we really appreciate your kickstarter backing! + + + @danlatorre many thanks for your backing and support! + + http://identi.ca/notice/30089410 + 2010-04-26T19:29:27+00:00 + 2010-04-26T19:29:27+00:00 + + + + @<span class="vcard"><a href="http://identi.ca/user/16365" class="url" title="Daniel Latorre"><span class="fn nickname">danlatorre</span></a></span> many thanks for your backing and support! + + + @adwilliamson thanks for backing diaspora! + + http://identi.ca/notice/30089220 + 2010-04-26T19:27:36+00:00 + 2010-04-26T19:27:36+00:00 + + + @adwilliamson thanks for backing diaspora! + + + @thisisparker many thanks for your kickstarter backing! + + http://identi.ca/notice/30088868 + 2010-04-26T19:23:51+00:00 + 2010-04-26T19:23:51+00:00 + + + + @<span class="vcard"><a href="http://identi.ca/user/27657" class="url" title="Parker Higgins"><span class="fn nickname">thisisparker</span></a></span> many thanks for your kickstarter backing! + + + We'll be building the interface for Diaspora to StatusNet, but for now, this will be from the web! + + http://identi.ca/notice/30074166 + 2010-04-26T17:07:49+00:00 + 2010-04-26T17:07:49+00:00 + + + We'll be building the interface for Diaspora to StatusNet, but for now, this will be from the web! + + + diff --git a/spec/lib/message_handler_spec.rb b/spec/lib/message_handler_spec.rb index 553135b96..0d9a56f4d 100644 --- a/spec/lib/message_handler_spec.rb +++ b/spec/lib/message_handler_spec.rb @@ -131,6 +131,83 @@ describe MessageHandler do end end + + describe 'ostatus_subscribe' do + it 'should be able to add a GET query to the queue with required destinations' do + request = FakeHttpRequest.new(:success) + request.should_receive(:get).exactly(1).times.and_return(request) + request.stub!(:callback).and_return(true) + + EventMachine::HttpRequest.stub!(:new).and_return(request) + + EventMachine.run{ + @handler.add_subscription_request("http://evan.status.net/") + @handler.size.should == 1 + + @handler.process + EventMachine.stop + } + end + + end + + describe 'hub_publish' do + it 'should correctly queue up a pubsubhub publish request' do + destination = "http://identi.ca/hub/" + feed_location = "http://google.com/" + + EventMachine.run { + @handler.add_hub_notification(destination, feed_location) + q = @handler.instance_variable_get(:@queue) + + message = "" + q.pop{|m| message = m} + + message.destination.should == destination + message.body.should == feed_location + + EventMachine.stop + } + end + + it 'should notify the hub about new content' do + request = FakeHttpRequest.new(:success) + request.should_receive(:publish).exactly(1).times.and_return(request) + EventMachine::PubSubHubbub.stub!(:new).and_return(request) + + EventMachine.run { + @handler.add_hub_notification("http://identi.ca/hub", "http://google.com/feed") + @handler.size.should == 1 + @handler.process + @handler.size.should == 0 + EventMachine.stop + } + end + + end + + describe 'hub_subscribe' do + + it 'should process an ostatus subscription' do + request = FakeHttpRequest.new(:success) + + Diaspora::OStatusParser.stub!(:find_hub).and_return("http://hub.google.com") + MessageHandler.stub!(:add_hub_subscription_request).and_return(true) + + Diaspora::OStatusParser.stub!(:parse_sender) + Diaspora::OStatusParser.should_receive(:find_hub) + @handler.should_receive(:add_hub_subscription_request) + Diaspora::OStatusParser.should_receive(:parse_sender) + + g = mock("Message") + g.stub!(:destination).and_return("google") + + @handler.process_ostatus_subscription(g, request) + end + + + end + end class FakeHttpRequest diff --git a/spec/lib/parser_spec.rb b/spec/lib/parser_spec.rb index 697d773c1..46bb23aab 100644 --- a/spec/lib/parser_spec.rb +++ b/spec/lib/parser_spec.rb @@ -1,6 +1,7 @@ require File.dirname(__FILE__) + '/../spec_helper' include ApplicationHelper +include Diaspora::OStatusParser describe "parser in application helper" do before do @@ -59,6 +60,15 @@ describe "parser in application helper" do Post.count.should == 0 end + describe 'ostatus parsing' do + it 'should be able to get the hub of an ostatus feed' do + xml_path = File.dirname(__FILE__) + '/../fixtures/identica_feed.atom' + xml = File.open(xml_path).read + + Diaspora::OStatusParser::find_hub(xml).should == 'http://identi.ca/main/push/hub' + end + + end describe "parsing compliant XML object" do before do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 854cde20b..3ad53ceed 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -41,7 +41,6 @@ describe User do @user.send_friend_request_to( @friend.url ).should be nil end - it 'should be able to give me the terse url for webfinger' do user = Factory.create(:user) user.terse_url.should == 'example.com'