jubjub 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.mdown +42 -6
- data/lib/jubjub/connection/xmpp_gateway/muc.rb +4 -20
- data/lib/jubjub/connection/xmpp_gateway/pubsub.rb +194 -13
- data/lib/jubjub/data_form.rb +30 -0
- data/lib/jubjub/muc.rb +4 -93
- data/lib/jubjub/muc/collection.rb +55 -0
- data/lib/jubjub/muc/configuration.rb +5 -0
- data/lib/jubjub/muc/muc.rb +37 -0
- data/lib/jubjub/pubsub.rb +8 -201
- data/lib/jubjub/pubsub/affiliation.rb +83 -0
- data/lib/jubjub/pubsub/affiliation_collection.rb +38 -0
- data/lib/jubjub/pubsub/collection.rb +68 -0
- data/lib/jubjub/pubsub/configuration.rb +5 -0
- data/lib/jubjub/pubsub/item.rb +35 -0
- data/lib/jubjub/pubsub/item_collection.rb +35 -0
- data/lib/jubjub/pubsub/pubsub.rb +66 -0
- data/lib/jubjub/pubsub/subscription.rb +24 -0
- data/lib/jubjub/user.rb +2 -2
- data/spec/connection/xmpp_gateway_muc_spec.rb +3 -3
- data/spec/connection/xmpp_gateway_pubsub_spec.rb +167 -11
- data/spec/fixtures/dataform_1.xml +65 -0
- data/spec/fixtures/vcr_cassettes/pubsub_default_configuration.yml +118 -0
- data/spec/fixtures/vcr_cassettes/pubsub_modify_affiliations.yml +275 -0
- data/spec/fixtures/vcr_cassettes/pubsub_purge.yml +68 -0
- data/spec/fixtures/vcr_cassettes/pubsub_retrieve_affiliations.yml +99 -0
- data/spec/mixins/user_spec.rb +8 -8
- data/spec/models/muc_collection_spec.rb +17 -12
- data/spec/models/muc_configuration_spec.rb +1 -1
- data/spec/models/pubsub_affiliation_collection_spec.rb +86 -0
- data/spec/models/pubsub_affiliation_spec.rb +244 -0
- data/spec/models/pubsub_collection_spec.rb +50 -18
- data/spec/models/pubsub_item_collection_spec.rb +12 -12
- data/spec/models/pubsub_item_spec.rb +9 -2
- data/spec/models/pubsub_spec.rb +27 -2
- data/spec/models/pubsub_subscription_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/support/helpers.rb +7 -0
- data/spec/support/shared_examples.rb +30 -0
- metadata +46 -19
    
        data/README.mdown
    CHANGED
    
    | @@ -97,17 +97,22 @@ Examples | |
| 97 97 | 
             
                node = u.pubsub.create('node_1')
         | 
| 98 98 | 
             
                => #<Jubjub::Pubsub:0x101f3bae0 @service="pubsub.jabber.org" @node="node_1">
         | 
| 99 99 |  | 
| 100 | 
            +
                # Create a pubsub node with a custom configuration
         | 
| 101 | 
            +
                u.pubsub.create('node_2'){|c|
         | 
| 102 | 
            +
                  c['pubsub#title'] = "Node 2" 
         | 
| 103 | 
            +
                }
         | 
| 104 | 
            +
                
         | 
| 100 105 | 
             
                # Subscribe to node
         | 
| 101 106 | 
             
                subscription = node.subscribe
         | 
| 102 | 
            -
                => #<Jubjub:: | 
| 107 | 
            +
                => #<Jubjub::Pubsub::Subscription:0x101effd60 @service="pubsub.jabber.org" @node="node_1" @subscriber="theozaurus@jabber.org" @subid="5129CD7935528" @subscription="subscribed">
         | 
| 103 108 |  | 
| 104 109 | 
             
                # Subscribe to something else
         | 
| 105 110 | 
             
                u.pubsub.subscribe('new_thing')
         | 
| 106 | 
            -
                => #<Jubjub:: | 
| 111 | 
            +
                => #<Jubjub::Pubsub::Subscription:0x101effd60 @service="pubsub.jabber.org" @node="new_thing" @subscriber="theozaurus@jabber.org" @subid="5129CD7935528" @subscription="subscribed">
         | 
| 107 112 |  | 
| 108 113 | 
             
                # Publish to a node
         | 
| 109 114 | 
             
                item = u.pubsub['node_1'].publish(Jubjub::DataForm.new({:foo => {:type => 'boolean', :value => 'bar'}}))
         | 
| 110 | 
            -
                => #<Jubjub:: | 
| 115 | 
            +
                => #<Jubjub::Pubsub::Item:0x101f2e9f8 @jid="pubsub.jabber.org" @node="node_1" @item_id="519DCAA72FFD6" @data="<x xmlns=\"jabber:x:data\" type=\"submit\">\n  <field var=\"foo\">\n    <value>false</value>\n  </field>\n</x>"> 
         | 
| 111 116 |  | 
| 112 117 | 
             
                # Retract an item from a node
         | 
| 113 118 | 
             
                item.retract
         | 
| @@ -120,13 +125,45 @@ Examples | |
| 120 125 | 
             
                # List items on a node
         | 
| 121 126 | 
             
                u.pubsub['node_1'].items
         | 
| 122 127 | 
             
                => [
         | 
| 123 | 
            -
                  #<Jubjub:: | 
| 128 | 
            +
                  #<Jubjub::Pubsub::Item:0x101f7bd48 @jid="pubsub.jabber.org" @node="node_1" @item_id="519DCAA72FFD6" @data="...">,
         | 
| 124 129 | 
             
                  ...
         | 
| 125 130 | 
             
                ]
         | 
| 126 131 |  | 
| 127 132 | 
             
                # Retrieve an item from a node
         | 
| 128 133 | 
             
                u.pubsub['node_1'].items['519DCAA72FFD6']
         | 
| 129 | 
            -
                => #<Jubjub:: | 
| 134 | 
            +
                => #<Jubjub::Pubsub::Item:0x101f7bd48 @jid="pubsub.jabber.org" @node="node_1" @item_id="519DCAA72FFD6" @data="...">
         | 
| 135 | 
            +
                
         | 
| 136 | 
            +
                # Retrieve affiliations from a node
         | 
| 137 | 
            +
                u.pubsub['node_1'].affiliations
         | 
| 138 | 
            +
                => [
         | 
| 139 | 
            +
                  #<Jubjub::Pubsub::Affiliation:0x101f52830 @pubsub_jid="pubsub.jabber.org" @pubsub_node="node_1" @jid="theozaurus@jabber.org" @affiliation="owner">
         | 
| 140 | 
            +
                  ...
         | 
| 141 | 
            +
                ]
         | 
| 142 | 
            +
                
         | 
| 143 | 
            +
                # Search affiliations
         | 
| 144 | 
            +
                u.pubsub['node_1'].affiliations['theozaurus@jabber.org']
         | 
| 145 | 
            +
                => #<Jubjub::Pubsub::Affiliation:0x101f52830 @pubsub_jid="pubsub.jabber.org" @pubsub_node="node_1" @jid="theozaurus@jabber.org" @affiliation="owner">
         | 
| 146 | 
            +
                
         | 
| 147 | 
            +
                # Test affiliations
         | 
| 148 | 
            +
                u.pubsub['node_1'].affiliations['theozaurus@jabber.org'].owner?
         | 
| 149 | 
            +
                => true
         | 
| 150 | 
            +
                u.pubsub['node_1'].affiliations['theozaurus@jabber.org'].publisher?
         | 
| 151 | 
            +
                => false
         | 
| 152 | 
            +
                
         | 
| 153 | 
            +
                # Set affiliation
         | 
| 154 | 
            +
                u.pubsub['node_1'].affiliations['theozaurus@jabber.org'].set_publisher
         | 
| 155 | 
            +
                => true
         | 
| 156 | 
            +
                # or
         | 
| 157 | 
            +
                u.pubsub['node_1'].affiliations['theozaurus@jabber.org'].set('publisher')
         | 
| 158 | 
            +
                => true
         | 
| 159 | 
            +
                    
         | 
| 160 | 
            +
                # Purge a node
         | 
| 161 | 
            +
                node.purge
         | 
| 162 | 
            +
                => true
         | 
| 163 | 
            +
                
         | 
| 164 | 
            +
                # Or
         | 
| 165 | 
            +
                u.pubsub.purge('node_1')
         | 
| 166 | 
            +
                => true
         | 
| 130 167 |  | 
| 131 168 | 
             
                # Unsubscribe
         | 
| 132 169 | 
             
                subscription.unsubscribe
         | 
| @@ -149,7 +186,6 @@ TODO | |
| 149 186 |  | 
| 150 187 | 
             
             - Error handling
         | 
| 151 188 | 
             
             - MUC user role and affiliation control
         | 
| 152 | 
            -
             - Pubsub configuration
         | 
| 153 189 | 
             
             - Service discovery
         | 
| 154 190 | 
             
             - Operations that are not IQ based, such as rosters and two way messaging
         | 
| 155 191 | 
             
             - Other backends (for servers that are evented)
         | 
| @@ -33,7 +33,7 @@ module Jubjub | |
| 33 33 | 
             
                    #     to='crone1@shakespeare.lit/desktop'
         | 
| 34 34 | 
             
                    #     type='result'/>
         | 
| 35 35 | 
             
                    #
         | 
| 36 | 
            -
                    def create(full_jid, configuration = Jubjub:: | 
| 36 | 
            +
                    def create(full_jid, configuration = Jubjub::Muc::Configuration.new)
         | 
| 37 37 | 
             
                      room_jid = Jubjub::Jid.new full_jid.node, full_jid.domain
         | 
| 38 38 |  | 
| 39 39 | 
             
                      request = Nokogiri::XML::Builder.new do |xml|
         | 
| @@ -217,27 +217,11 @@ module Jubjub | |
| 217 217 | 
             
                        request.to_xml
         | 
| 218 218 | 
             
                      ).xpath(
         | 
| 219 219 | 
             
                        # Get fields
         | 
| 220 | 
            -
                        "//iq[@type='result']/muc_owner:query/x_data:x[@type='form'] | 
| 220 | 
            +
                        "//iq[@type='result']/muc_owner:query/x_data:x[@type='form']",
         | 
| 221 221 | 
             
                        namespaces
         | 
| 222 | 
            -
                      ) | 
| 223 | 
            -
                        # Build MucConfiguration parameters
         | 
| 224 | 
            -
                        hash = {}
         | 
| 225 | 
            -
                        hash[:type]  = field.attr 'type'
         | 
| 226 | 
            -
                        hash[:label] = field.attr 'label'
         | 
| 227 | 
            -
                        
         | 
| 228 | 
            -
                        value = field.xpath('x_data:value', namespaces)
         | 
| 229 | 
            -
                        hash[:value] = hash[:type].match(/\-multi$/) ? value.map{|e| e.content } : value.text
         | 
| 230 | 
            -
                        
         | 
| 231 | 
            -
                        options = field.xpath('x_data:option', namespaces).map{|o|
         | 
| 232 | 
            -
                          { :label => o.attr('label'), :value => o.xpath('x_data:value', namespaces).text }
         | 
| 233 | 
            -
                        }
         | 
| 234 | 
            -
                        hash[:options] = options if options.any?
         | 
| 235 | 
            -
                        
         | 
| 236 | 
            -
                        result[field.attr 'var'] = hash
         | 
| 237 | 
            -
                        result
         | 
| 238 | 
            -
                      }
         | 
| 222 | 
            +
                      )
         | 
| 239 223 |  | 
| 240 | 
            -
                      Jubjub:: | 
| 224 | 
            +
                      Jubjub::Muc::Configuration.new response if response
         | 
| 241 225 | 
             
                    end
         | 
| 242 226 |  | 
| 243 227 | 
             
                    # http://xmpp.org/extensions/xep-0045.html#destroyroom
         | 
| @@ -55,13 +55,22 @@ module Jubjub | |
| 55 55 | 
             
                      }
         | 
| 56 56 | 
             
                    end
         | 
| 57 57 |  | 
| 58 | 
            -
                    # http://xmpp.org/extensions/xep-0060.html#owner-create
         | 
| 58 | 
            +
                    # http://xmpp.org/extensions/xep-0060.html#owner-create-and-configure
         | 
| 59 59 | 
             
                    # <iq type='set'
         | 
| 60 60 | 
             
                    #     from='hamlet@denmark.lit/elsinore'
         | 
| 61 61 | 
             
                    #     to='pubsub.shakespeare.lit'
         | 
| 62 62 | 
             
                    #     id='create1'>
         | 
| 63 63 | 
             
                    #   <pubsub xmlns='http://jabber.org/protocol/pubsub'>
         | 
| 64 64 | 
             
                    #     <create node='princely_musings'/>
         | 
| 65 | 
            +
                    #     <configure>
         | 
| 66 | 
            +
                    #       <x xmlns='jabber:x:data' type='submit'>
         | 
| 67 | 
            +
                    #         <field var='FORM_TYPE' type='hidden'>
         | 
| 68 | 
            +
                    #           <value>http://jabber.org/protocol/pubsub#node_config</value>
         | 
| 69 | 
            +
                    #         </field>
         | 
| 70 | 
            +
                    #         <field var='pubsub#title'><value>Princely Musings (Atom)</value></field>
         | 
| 71 | 
            +
                    #         ...
         | 
| 72 | 
            +
                    #       </x>
         | 
| 73 | 
            +
                    #     </configure>
         | 
| 65 74 | 
             
                    #   </pubsub>
         | 
| 66 75 | 
             
                    # </iq>
         | 
| 67 76 | 
             
                    # 
         | 
| @@ -69,16 +78,17 @@ module Jubjub | |
| 69 78 | 
             
                    # <iq type='result'
         | 
| 70 79 | 
             
                    #     from='pubsub.shakespeare.lit'
         | 
| 71 80 | 
             
                    #     to='hamlet@denmark.lit/elsinore'
         | 
| 72 | 
            -
                    #     id=' | 
| 73 | 
            -
                     | 
| 74 | 
            -
                    #       <create node='25e3d37dabbab9541f7523321421edc5bfeb2dae'/>
         | 
| 75 | 
            -
                    #     </pubsub>
         | 
| 76 | 
            -
                    # </iq>
         | 
| 77 | 
            -
                    def create(jid, node)          
         | 
| 81 | 
            +
                    #     id='create1'/>
         | 
| 82 | 
            +
                    def create(jid, node, configuration = nil)
         | 
| 78 83 | 
             
                      request = Nokogiri::XML::Builder.new do |xml|
         | 
| 79 84 | 
             
                        xml.iq_(:to => jid, :type => 'set') {
         | 
| 80 85 | 
             
                          xml.pubsub_('xmlns' => namespaces['pubsub']) {
         | 
| 81 86 | 
             
                            xml.create_('node' => node)
         | 
| 87 | 
            +
                            if configuration 
         | 
| 88 | 
            +
                              xml.configure_{
         | 
| 89 | 
            +
                                configuration.to_builder(xml.parent)
         | 
| 90 | 
            +
                              }
         | 
| 91 | 
            +
                            end
         | 
| 82 92 | 
             
                          }
         | 
| 83 93 | 
             
                        }
         | 
| 84 94 | 
             
                      end
         | 
| @@ -88,12 +98,64 @@ module Jubjub | |
| 88 98 | 
             
                        request.to_xml
         | 
| 89 99 | 
             
                      ).xpath(
         | 
| 90 100 | 
             
                        # Pull out required parts
         | 
| 91 | 
            -
                        '//iq[@type="result"] | 
| 92 | 
            -
                        namespaces
         | 
| 101 | 
            +
                        '//iq[@type="result"]'
         | 
| 93 102 | 
             
                      ).any?
         | 
| 94 103 | 
             
                      Jubjub::Pubsub.new jid, node, @connection if success
         | 
| 95 104 | 
             
                    end
         | 
| 96 105 |  | 
| 106 | 
            +
                    # http://xmpp.org/extensions/xep-0060.html#owner-configure
         | 
| 107 | 
            +
                    # <iq type='get'
         | 
| 108 | 
            +
                    #     from='hamlet@denmark.lit/elsinore'
         | 
| 109 | 
            +
                    #     to='pubsub.shakespeare.lit'
         | 
| 110 | 
            +
                    #     id='config1'>
         | 
| 111 | 
            +
                    #   <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
         | 
| 112 | 
            +
                    #     <configure node='princely_musings'/>
         | 
| 113 | 
            +
                    #   </pubsub>
         | 
| 114 | 
            +
                    # </iq>
         | 
| 115 | 
            +
                    # 
         | 
| 116 | 
            +
                    # Expected
         | 
| 117 | 
            +
                    # <iq type='result'
         | 
| 118 | 
            +
                    #     from='pubsub.shakespeare.lit'
         | 
| 119 | 
            +
                    #     to='hamlet@denmark.lit/elsinore'
         | 
| 120 | 
            +
                    #     id='config1'>
         | 
| 121 | 
            +
                    #   <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
         | 
| 122 | 
            +
                    #     <configure node='princely_musings'>
         | 
| 123 | 
            +
                    #       <x xmlns='jabber:x:data' type='form'>
         | 
| 124 | 
            +
                    #         <field var='FORM_TYPE' type='hidden'>
         | 
| 125 | 
            +
                    #           <value>http://jabber.org/protocol/pubsub#node_config</value>
         | 
| 126 | 
            +
                    #         </field>
         | 
| 127 | 
            +
                    #         <field var='pubsub#title' type='text-single'
         | 
| 128 | 
            +
                    #                label='A friendly name for the node'/>
         | 
| 129 | 
            +
                    #         <field var='pubsub#deliver_notifications' type='boolean'
         | 
| 130 | 
            +
                    #                label='Whether to deliver event notifications'>
         | 
| 131 | 
            +
                    #           <value>true</value>
         | 
| 132 | 
            +
                    #         </field>
         | 
| 133 | 
            +
                    #         ...
         | 
| 134 | 
            +
                    #       </x>
         | 
| 135 | 
            +
                    #     </configure>
         | 
| 136 | 
            +
                    #   </pubsub>
         | 
| 137 | 
            +
                    # </iq>
         | 
| 138 | 
            +
                    def default_configuration(jid)          
         | 
| 139 | 
            +
                      request = Nokogiri::XML::Builder.new do |xml|
         | 
| 140 | 
            +
                        xml.iq_(:to => jid, :type => 'get') {
         | 
| 141 | 
            +
                          xml.pubsub_('xmlns' => namespaces['pubsub_owner']) {
         | 
| 142 | 
            +
                            xml.default_
         | 
| 143 | 
            +
                          }
         | 
| 144 | 
            +
                        }
         | 
| 145 | 
            +
                      end
         | 
| 146 | 
            +
                      
         | 
| 147 | 
            +
                      response = write(
         | 
| 148 | 
            +
                        # Request default node configuration
         | 
| 149 | 
            +
                        request.to_xml
         | 
| 150 | 
            +
                      ).xpath(
         | 
| 151 | 
            +
                        # Get fields
         | 
| 152 | 
            +
                        "//iq[@type='result']/pubsub_owner:pubsub/pubsub_owner:default/x_data:x[@type='form']",
         | 
| 153 | 
            +
                        namespaces
         | 
| 154 | 
            +
                      )
         | 
| 155 | 
            +
                      
         | 
| 156 | 
            +
                      Jubjub::Pubsub::Configuration.new response if response
         | 
| 157 | 
            +
                    end
         | 
| 158 | 
            +
                    
         | 
| 97 159 | 
             
                    # http://xmpp.org/extensions/xep-0060.html#owner-delete
         | 
| 98 160 | 
             
                    # <iq type='set'
         | 
| 99 161 | 
             
                    #     from='hamlet@denmark.lit/elsinore'
         | 
| @@ -130,6 +192,38 @@ module Jubjub | |
| 130 192 | 
             
                      ).any?
         | 
| 131 193 | 
             
                    end
         | 
| 132 194 |  | 
| 195 | 
            +
                    # http://xmpp.org/extensions/xep-0060.html#owner-purge
         | 
| 196 | 
            +
                    # <iq type='set'
         | 
| 197 | 
            +
                    #     from='hamlet@denmark.lit/elsinore'
         | 
| 198 | 
            +
                    #     to='pubsub.shakespeare.lit'
         | 
| 199 | 
            +
                    #     id='purge1'>
         | 
| 200 | 
            +
                    #   <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
         | 
| 201 | 
            +
                    #     <purge node='princely_musings'/>
         | 
| 202 | 
            +
                    #   </pubsub>
         | 
| 203 | 
            +
                    # </iq>
         | 
| 204 | 
            +
                    #
         | 
| 205 | 
            +
                    # Expected
         | 
| 206 | 
            +
                    # <iq type='result'
         | 
| 207 | 
            +
                    #     from='pubsub.shakespeare.lit'
         | 
| 208 | 
            +
                    #     id='purge1'/>
         | 
| 209 | 
            +
                    def purge(jid,node)
         | 
| 210 | 
            +
                      request = Nokogiri::XML::Builder.new do |xml|
         | 
| 211 | 
            +
                        xml.iq_(:to => jid, :type => 'set') {
         | 
| 212 | 
            +
                          xml.pubsub_('xmlns' => namespaces['pubsub_owner']) {
         | 
| 213 | 
            +
                            xml.purge_('node' => node)
         | 
| 214 | 
            +
                          }
         | 
| 215 | 
            +
                        }
         | 
| 216 | 
            +
                      end
         | 
| 217 | 
            +
                      
         | 
| 218 | 
            +
                      success = write(
         | 
| 219 | 
            +
                        # Generate stanza
         | 
| 220 | 
            +
                        request.to_xml
         | 
| 221 | 
            +
                      ).xpath(
         | 
| 222 | 
            +
                        # Pull out required parts
         | 
| 223 | 
            +
                        '//iq[@type="result"]'
         | 
| 224 | 
            +
                      ).any?
         | 
| 225 | 
            +
                    end
         | 
| 226 | 
            +
                    
         | 
| 133 227 | 
             
                    # http://xmpp.org/extensions/xep-0060.html#subscriber-subscribe
         | 
| 134 228 | 
             
                    # <iq type='set'
         | 
| 135 229 | 
             
                    #     from='francisco@denmark.lit/barracks'
         | 
| @@ -176,7 +270,7 @@ module Jubjub | |
| 176 270 | 
             
                        subscriber   = Jubjub::Jid.new(result.first.attr('jid'))
         | 
| 177 271 | 
             
                        subid        = result.first.attr('subid') 
         | 
| 178 272 | 
             
                        subscription = result.first.attr('subscription')
         | 
| 179 | 
            -
                        Jubjub:: | 
| 273 | 
            +
                        Jubjub::Pubsub::Subscription.new jid, node, subscriber, subid, subscription, @connection
         | 
| 180 274 | 
             
                      end
         | 
| 181 275 | 
             
                    end
         | 
| 182 276 |  | 
| @@ -274,7 +368,7 @@ module Jubjub | |
| 274 368 | 
             
                      if result.any?
         | 
| 275 369 | 
             
                        item_id = result.first.attr('id')
         | 
| 276 370 | 
             
                        data = request.doc.xpath("//pubsub:item/*", namespaces).to_s
         | 
| 277 | 
            -
                        Jubjub:: | 
| 371 | 
            +
                        Jubjub::Pubsub::Item.new jid, node, item_id, data, @connection
         | 
| 278 372 | 
             
                      end
         | 
| 279 373 | 
             
                    end
         | 
| 280 374 |  | 
| @@ -366,10 +460,96 @@ module Jubjub | |
| 366 460 | 
             
                      ).map{|item|
         | 
| 367 461 | 
             
                        item_id = item.attr('id')
         | 
| 368 462 | 
             
                        data = item.xpath('./*').to_xml
         | 
| 369 | 
            -
                        Jubjub:: | 
| 463 | 
            +
                        Jubjub::Pubsub::Item.new jid, node, item_id, data, @connection
         | 
| 464 | 
            +
                      }
         | 
| 465 | 
            +
                    end
         | 
| 466 | 
            +
                    
         | 
| 467 | 
            +
                    
         | 
| 468 | 
            +
                    # http://xmpp.org/extensions/xep-0060.html#owner-affiliations
         | 
| 469 | 
            +
                    # <iq type='get'
         | 
| 470 | 
            +
                    #     from='hamlet@denmark.lit/elsinore'
         | 
| 471 | 
            +
                    #     to='pubsub.shakespeare.lit'
         | 
| 472 | 
            +
                    #     id='ent1'>
         | 
| 473 | 
            +
                    #   <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
         | 
| 474 | 
            +
                    #     <affiliations node='princely_musings'/>
         | 
| 475 | 
            +
                    #   </pubsub>
         | 
| 476 | 
            +
                    # </iq>
         | 
| 477 | 
            +
                    # 
         | 
| 478 | 
            +
                    # Expected
         | 
| 479 | 
            +
                    # <iq type='result'
         | 
| 480 | 
            +
                    #     from='pubsub.shakespeare.lit'
         | 
| 481 | 
            +
                    #     to='hamlet@denmark.lit/elsinore'
         | 
| 482 | 
            +
                    #     id='ent1'>
         | 
| 483 | 
            +
                    #   <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
         | 
| 484 | 
            +
                    #     <affiliations node='princely_musings'>
         | 
| 485 | 
            +
                    #       <affiliation jid='hamlet@denmark.lit' affiliation='owner'/>
         | 
| 486 | 
            +
                    #       <affiliation jid='polonius@denmark.lit' affiliation='outcast'/>
         | 
| 487 | 
            +
                    #     </affiliations>
         | 
| 488 | 
            +
                    #   </pubsub>
         | 
| 489 | 
            +
                    # </iq>
         | 
| 490 | 
            +
                    def retrieve_affiliations(pubsub_jid, pubsub_node)
         | 
| 491 | 
            +
                      request = Nokogiri::XML::Builder.new do |xml|
         | 
| 492 | 
            +
                        xml.iq_(:to => pubsub_jid, :type => 'get') {
         | 
| 493 | 
            +
                          xml.pubsub_(:xmlns => namespaces['pubsub_owner']){
         | 
| 494 | 
            +
                            xml.affiliations_(:node => pubsub_node)
         | 
| 495 | 
            +
                          }
         | 
| 496 | 
            +
                        }
         | 
| 497 | 
            +
                      end
         | 
| 498 | 
            +
                      
         | 
| 499 | 
            +
                      write(
         | 
| 500 | 
            +
                        # Generate stanza
         | 
| 501 | 
            +
                        request.to_xml
         | 
| 502 | 
            +
                      ).xpath(
         | 
| 503 | 
            +
                        # Pull out required parts
         | 
| 504 | 
            +
                        '//iq[@type="result"]/pubsub_owner:pubsub/pubsub_owner:affiliations/pubsub_owner:affiliation',
         | 
| 505 | 
            +
                        namespaces
         | 
| 506 | 
            +
                      ).map{|affiliation|
         | 
| 507 | 
            +
                        jid = Jubjub::Jid.new affiliation.attr('jid')
         | 
| 508 | 
            +
                        affiliation = affiliation.attr('affiliation')
         | 
| 509 | 
            +
                        Jubjub::Pubsub::Affiliation.new pubsub_jid, pubsub_node, jid, affiliation, @connection
         | 
| 370 510 | 
             
                      }
         | 
| 371 511 | 
             
                    end
         | 
| 372 512 |  | 
| 513 | 
            +
                    # http://xmpp.org/extensions/xep-0060.html#owner-affiliations-modify
         | 
| 514 | 
            +
                    # <iq type='set'
         | 
| 515 | 
            +
                    #     from='hamlet@denmark.lit/elsinore'
         | 
| 516 | 
            +
                    #     to='pubsub.shakespeare.lit'
         | 
| 517 | 
            +
                    #     id='ent2'>
         | 
| 518 | 
            +
                    #   <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
         | 
| 519 | 
            +
                    #     <affiliations node='princely_musings'>
         | 
| 520 | 
            +
                    #       <affiliation jid='bard@shakespeare.lit' affiliation='publisher'/>
         | 
| 521 | 
            +
                    #     </affiliations>
         | 
| 522 | 
            +
                    #   </pubsub>
         | 
| 523 | 
            +
                    # </iq>
         | 
| 524 | 
            +
                    # 
         | 
| 525 | 
            +
                    # Expected
         | 
| 526 | 
            +
                    # <iq type='result'
         | 
| 527 | 
            +
                    #     from='pubsub.shakespeare.lit'
         | 
| 528 | 
            +
                    #     id='ent2'/>
         | 
| 529 | 
            +
                    def modify_affiliations(pubsub_jid, pubsub_node, *affiliations)
         | 
| 530 | 
            +
                      affiliations = [affiliations].flatten
         | 
| 531 | 
            +
                      
         | 
| 532 | 
            +
                      request = Nokogiri::XML::Builder.new do |xml|
         | 
| 533 | 
            +
                        xml.iq_(:to => pubsub_jid, :type => 'set') {
         | 
| 534 | 
            +
                          xml.pubsub_(:xmlns => namespaces['pubsub_owner']){
         | 
| 535 | 
            +
                            xml.affiliations_(:node => pubsub_node){
         | 
| 536 | 
            +
                              affiliations.each {|a|
         | 
| 537 | 
            +
                                xml.affiliation_(:jid => a.jid, :affiliation => a.affiliation)
         | 
| 538 | 
            +
                              }
         | 
| 539 | 
            +
                            }
         | 
| 540 | 
            +
                          }
         | 
| 541 | 
            +
                        }
         | 
| 542 | 
            +
                      end
         | 
| 543 | 
            +
                      
         | 
| 544 | 
            +
                      write(
         | 
| 545 | 
            +
                        # Generate stanza
         | 
| 546 | 
            +
                        request.to_xml
         | 
| 547 | 
            +
                      ).xpath(
         | 
| 548 | 
            +
                        # Pull out required parts
         | 
| 549 | 
            +
                        '//iq[@type="result"]'
         | 
| 550 | 
            +
                      ).any?
         | 
| 551 | 
            +
                    end
         | 
| 552 | 
            +
                    
         | 
| 373 553 | 
             
                  private
         | 
| 374 554 |  | 
| 375 555 | 
             
                    def subscriber
         | 
| @@ -384,7 +564,8 @@ module Jubjub | |
| 384 564 | 
             
                      {
         | 
| 385 565 | 
             
                        'disco_items'  => 'http://jabber.org/protocol/disco#items',
         | 
| 386 566 | 
             
                        'pubsub'       => 'http://jabber.org/protocol/pubsub',
         | 
| 387 | 
            -
                        'pubsub_owner' => 'http://jabber.org/protocol/pubsub#owner'
         | 
| 567 | 
            +
                        'pubsub_owner' => 'http://jabber.org/protocol/pubsub#owner',
         | 
| 568 | 
            +
                        'x_data'       => 'jabber:x:data'
         | 
| 388 569 | 
             
                      }
         | 
| 389 570 | 
             
                    end
         | 
| 390 571 |  | 
    
        data/lib/jubjub/data_form.rb
    CHANGED
    
    | @@ -6,6 +6,8 @@ module Jubjub | |
| 6 6 | 
             
                attr_reader :fields
         | 
| 7 7 |  | 
| 8 8 | 
             
                def initialize(config={})
         | 
| 9 | 
            +
                  config = convert_xml config if config.respond_to? :xpath
         | 
| 10 | 
            +
             | 
| 9 11 | 
             
                  check_config config
         | 
| 10 12 |  | 
| 11 13 | 
             
                  @fields = config
         | 
| @@ -85,6 +87,34 @@ module Jubjub | |
| 85 87 | 
             
                    ) if mystery_arguments.any?
         | 
| 86 88 | 
             
                  end
         | 
| 87 89 | 
             
                end
         | 
| 90 | 
            +
                
         | 
| 91 | 
            +
                def convert_xml(config)
         | 
| 92 | 
            +
                  config.xpath(
         | 
| 93 | 
            +
                    # Get fields
         | 
| 94 | 
            +
                    "//x_data:x[@type='form']/x_data:field",
         | 
| 95 | 
            +
                    namespaces
         | 
| 96 | 
            +
                  ).inject({}){|result,field|
         | 
| 97 | 
            +
                    # Build parameters
         | 
| 98 | 
            +
                    hash = {}
         | 
| 99 | 
            +
                    hash[:type]  = field.attr 'type'
         | 
| 100 | 
            +
                    hash[:label] = field.attr 'label'
         | 
| 101 | 
            +
                    
         | 
| 102 | 
            +
                    value = field.xpath('x_data:value', namespaces)
         | 
| 103 | 
            +
                    hash[:value] = hash[:type].match(/\-multi$/) ? value.map{|e| e.content } : value.text
         | 
| 104 | 
            +
                    
         | 
| 105 | 
            +
                    options = field.xpath('x_data:option', namespaces).map{|o|
         | 
| 106 | 
            +
                      { :label => o.attr('label'), :value => o.xpath('x_data:value', namespaces).text }
         | 
| 107 | 
            +
                    }
         | 
| 108 | 
            +
                    hash[:options] = options if options.any?
         | 
| 109 | 
            +
                    
         | 
| 110 | 
            +
                    result[field.attr 'var'] = hash unless hash[:type] == 'fixed'
         | 
| 111 | 
            +
                    result
         | 
| 112 | 
            +
                  }
         | 
| 113 | 
            +
                end
         | 
| 114 | 
            +
                
         | 
| 115 | 
            +
                def namespaces
         | 
| 116 | 
            +
                  { 'x_data' => 'jabber:x:data' }
         | 
| 117 | 
            +
                end
         | 
| 88 118 |  | 
| 89 119 | 
             
              end
         | 
| 90 120 |  | 
    
        data/lib/jubjub/muc.rb
    CHANGED
    
    | @@ -1,93 +1,4 @@ | |
| 1 | 
            -
            require  | 
| 2 | 
            -
             | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
                
         | 
| 6 | 
            -
                attr_reader :jid, :name
         | 
| 7 | 
            -
                
         | 
| 8 | 
            -
                def initialize(jid, name = nil, connection = nil)
         | 
| 9 | 
            -
                  @jid = Jubjub::Jid.new(jid)
         | 
| 10 | 
            -
                  @name = name
         | 
| 11 | 
            -
                  @connection = connection
         | 
| 12 | 
            -
                end 
         | 
| 13 | 
            -
                
         | 
| 14 | 
            -
                def exit(nick = nil)
         | 
| 15 | 
            -
                  full_jid = Jubjub::Jid.new @jid.node, @jid.domain, nick || @connection.jid.node
         | 
| 16 | 
            -
                  
         | 
| 17 | 
            -
                  @connection.muc.exit(full_jid)
         | 
| 18 | 
            -
                  self
         | 
| 19 | 
            -
                end
         | 
| 20 | 
            -
                
         | 
| 21 | 
            -
                def destroy
         | 
| 22 | 
            -
                  @connection.muc.destroy(@jid)
         | 
| 23 | 
            -
                end
         | 
| 24 | 
            -
                
         | 
| 25 | 
            -
                # Hide the connection details and show jid as string for compactness
         | 
| 26 | 
            -
                def inspect
         | 
| 27 | 
            -
                  obj_id = "%x" % (object_id << 1)
         | 
| 28 | 
            -
                  "#<#{self.class}:0x#{obj_id} @jid=\"#{@jid}\" @name=#{@name.inspect}>"
         | 
| 29 | 
            -
                end
         | 
| 30 | 
            -
                
         | 
| 31 | 
            -
              end
         | 
| 32 | 
            -
              
         | 
| 33 | 
            -
              # Uses proxy pattern for syntax sugar
         | 
| 34 | 
            -
              # and delaying expensive operations until
         | 
| 35 | 
            -
              # required
         | 
| 36 | 
            -
              class MucCollection
         | 
| 37 | 
            -
                 
         | 
| 38 | 
            -
                attr_reader :jid
         | 
| 39 | 
            -
                 
         | 
| 40 | 
            -
                def initialize(jid, connection)
         | 
| 41 | 
            -
                  @jid = Jubjub::Jid.new(jid)
         | 
| 42 | 
            -
                  @connection = connection
         | 
| 43 | 
            -
                end
         | 
| 44 | 
            -
                
         | 
| 45 | 
            -
                def create(node, nick = nil, &block)
         | 
| 46 | 
            -
                  full_jid = Jubjub::Jid.new node, @jid.domain, nick || @connection.jid.node
         | 
| 47 | 
            -
             | 
| 48 | 
            -
                  if block_given?
         | 
| 49 | 
            -
                    # Reserved room
         | 
| 50 | 
            -
                    config = @connection.muc.configuration full_jid
         | 
| 51 | 
            -
                    yield config
         | 
| 52 | 
            -
                    @connection.muc.create full_jid, config
         | 
| 53 | 
            -
                  else
         | 
| 54 | 
            -
                    # Instant room
         | 
| 55 | 
            -
                    result = @connection.muc.create full_jid
         | 
| 56 | 
            -
                  end
         | 
| 57 | 
            -
                  
         | 
| 58 | 
            -
                end
         | 
| 59 | 
            -
                
         | 
| 60 | 
            -
                def [](jid_node_num)
         | 
| 61 | 
            -
                  case jid_node_num
         | 
| 62 | 
            -
                  when Fixnum
         | 
| 63 | 
            -
                    list[jid_node_num]
         | 
| 64 | 
            -
                  when Jubjub::Jid
         | 
| 65 | 
            -
                    list.find{|m| m.jid == jid_node_num }
         | 
| 66 | 
            -
                  else
         | 
| 67 | 
            -
                    j = Jubjub::Jid.new jid_node_num, jid.domain
         | 
| 68 | 
            -
                    list.find{|m| m.jid == j }        
         | 
| 69 | 
            -
                  end
         | 
| 70 | 
            -
                end
         | 
| 71 | 
            -
                
         | 
| 72 | 
            -
                # Hint that methods are actually applied to list using method_missing
         | 
| 73 | 
            -
                def inspect
         | 
| 74 | 
            -
                  list.inspect
         | 
| 75 | 
            -
                end
         | 
| 76 | 
            -
                
         | 
| 77 | 
            -
              private
         | 
| 78 | 
            -
              
         | 
| 79 | 
            -
                def method_missing(name, *args, &block)
         | 
| 80 | 
            -
                  list.send(name, *args, &block)
         | 
| 81 | 
            -
                end
         | 
| 82 | 
            -
                  
         | 
| 83 | 
            -
                def list
         | 
| 84 | 
            -
                  @list ||= @connection.muc.list @jid
         | 
| 85 | 
            -
                end
         | 
| 86 | 
            -
                
         | 
| 87 | 
            -
              end
         | 
| 88 | 
            -
              
         | 
| 89 | 
            -
              class MucConfiguration < DataForm
         | 
| 90 | 
            -
                
         | 
| 91 | 
            -
              end
         | 
| 92 | 
            -
              
         | 
| 93 | 
            -
            end
         | 
| 1 | 
            +
            require "jubjub/connection/xmpp_gateway/muc"
         | 
| 2 | 
            +
            require 'jubjub/muc/muc'
         | 
| 3 | 
            +
            require 'jubjub/muc/collection'
         | 
| 4 | 
            +
            require 'jubjub/muc/configuration'
         |