em-xmpp 0.0.10 → 0.0.11

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.
@@ -56,6 +56,7 @@ module EM::Xmpp
56
56
  @pass = nil
57
57
  @handler = Routine.new self
58
58
  send_stanza presence_stanza()
59
+ framework_ready if respond_to? :framework_ready
59
60
  ready
60
61
  end
61
62
 
@@ -2,7 +2,10 @@
2
2
  require 'em-xmpp/jid'
3
3
  require 'em-xmpp/entity'
4
4
  require 'em-xmpp/namespaces'
5
+ require 'base64'
6
+ require 'digest/sha1'
5
7
  require 'time'
8
+ require 'date'
6
9
  require 'ostruct'
7
10
 
8
11
  module EM::Xmpp
@@ -243,6 +246,14 @@ module EM::Xmpp
243
246
  end
244
247
  end
245
248
 
249
+ module Attention
250
+ include Message
251
+ def attention_node
252
+ xpath('//xmlns:attention',{'xmlns' => EM::Xmpp::Namespaces::Attention}).first
253
+ end
254
+ end
255
+
256
+
246
257
  module Iq
247
258
  include IncomingStanza
248
259
  def reply_default_params
@@ -296,6 +307,8 @@ module EM::Xmpp
296
307
  name = read_attr(x, 'name')
297
308
  Identity.new name, cat, type
298
309
  end
310
+ else
311
+ []
299
312
  end
300
313
  end
301
314
  def features
@@ -315,6 +328,10 @@ module EM::Xmpp
315
328
  def query_node
316
329
  xpath('//xmlns:query',{'xmlns' => DiscoverItems}).first
317
330
  end
331
+ def node
332
+ n = query_node
333
+ read_attr(n, 'node') if n
334
+ end
318
335
  def item_nodes
319
336
  xpath('//xmlns:item',{'xmlns' => DiscoverItems})
320
337
  end
@@ -329,29 +346,36 @@ module EM::Xmpp
329
346
  end
330
347
 
331
348
  module Command
349
+ include Iq
332
350
  def command_node
333
351
  xpath('//xmlns:command',{'xmlns' => Commands}).first
334
352
  end
335
353
 
336
- %w{node sessionid action}.each do |word|
354
+ %w{node sessionid}.each do |word|
337
355
  define_method word do
338
356
  n = command_node
339
357
  read_attr(n, word) if n
340
358
  end
341
359
  end
342
360
 
361
+ def action
362
+ n = command_node
363
+ read_attr(n, 'action') || 'execute'
364
+ end
365
+
343
366
  def previous?
344
367
  action == 'prev'
345
368
  end
346
369
  end
347
370
 
348
371
  module Dataforms
349
- Form = Struct.new(:type, :fields)
350
- Field = Struct.new(:var, :type, :values) do
372
+ Form = Struct.new(:type, :fields, :title, :instructions)
373
+ Field = Struct.new(:var, :type, :label, :values, :options) do
351
374
  def value
352
375
  values.first
353
376
  end
354
377
  end
378
+ Option = Struct.new(:label, :value)
355
379
 
356
380
  def x_form_nodes
357
381
  xpath('//xmlns:x',{'xmlns' => Namespaces::DataForms})
@@ -359,19 +383,38 @@ module EM::Xmpp
359
383
 
360
384
  def x_forms
361
385
  x_form_nodes.map do |form|
386
+ instruction_node = form.xpath('xmlns:instructions',{'xmlns' => Namespaces::DataForms}).first
387
+ title_node = form.xpath('xmlns:title',{'xmlns' => Namespaces::DataForms}).first
388
+
389
+ instr = instruction_node.content if instruction_node
390
+ title = title_node.content if instruction_node
391
+
362
392
  form_type = read_attr(form, 'type')
363
393
  field_nodes = form.xpath('xmlns:field',{'xmlns' => Namespaces::DataForms})
364
394
  fields = field_nodes.map do |field|
365
395
  var = read_attr(field, 'var')
366
396
  type = read_attr(field, 'type')
367
- value_nodes = field.xpath('//xmlns:value',{'xmlns' => Namespaces::DataForms})
397
+ label = read_attr(field, 'label')
398
+ option_nodes = field.xpath('.//xmlns:option',{'xmlns' => Namespaces::DataForms})
399
+ options = option_nodes.map do |opt|
400
+ opt_label = read_attr(opt, 'label')
401
+ opt_value_nodes = opt.xpath('.//xmlns:value',{'xmlns' => Namespaces::DataForms})
402
+ opt_value = opt_value_nodes.map(&:content).first
403
+
404
+ Option.new(opt_label, opt_value)
405
+ end
406
+ value_nodes = field.xpath('./xmlns:value',{'xmlns' => Namespaces::DataForms})
368
407
  values = value_nodes.map(&:content)
369
408
 
370
- Field.new(var,type,values)
409
+ Field.new(var,type,label,values,options)
371
410
  end
372
- Form.new form_type, fields
411
+ Form.new form_type, fields, title, instr
373
412
  end
374
413
  end
414
+
415
+ def form
416
+ x_forms.first
417
+ end
375
418
  end
376
419
 
377
420
  module Capabilities
@@ -388,6 +431,7 @@ module EM::Xmpp
388
431
  end
389
432
 
390
433
  module Roster
434
+ include Contexts::Iq
391
435
  def query_node
392
436
  xpath('//xmlns:query',{'xmlns' => EM::Xmpp::Namespaces::Roster}).first
393
437
  end
@@ -544,35 +588,35 @@ module EM::Xmpp
544
588
 
545
589
  module Mood
546
590
  DefinedMoods = %w{afraid amazed angry amorous annoyed anxious aroused
547
- ashamed bored brave calm cautious cold confident confused contemplative
548
- contented cranky crazy creative curious dejected depressed disappointed
549
- disgusted dismayed distracted embarrassed envious excited flirtatious
550
- frustrated grumpy guilty happy hopeful hot humbled humiliated hungry hurt
551
- impressed in_awe in_love indignant interested intoxicated invincible jealous
552
- lonely lucky mean moody nervous neutral offended outraged playful proud relaxed
553
- relieved remorseful restless sad sarcastic serious shocked shy sick sleepy
554
- spontaneous stressed strong surprised thankful thirsty tired undefined weak
555
- worried}.freeze
556
-
557
- def mood_node
558
- xpath('//xmlns:mood',{'xmlns' => Namespaces::Mood}).first
559
- end
560
- def mood_name_node
561
- n = mood_node
562
- n.children.find{|c| DefinedMoods.include?(c.name)} if n
563
- end
564
- def mood_text_node
565
- n = mood_node
566
- n.children.find{|c| c.name == 'text'}
567
- end
568
- def mood
569
- n = mood_name_node
570
- n.name if n
571
- end
572
- def mood
573
- n = mood_text_node
574
- n.content if n
575
- end
591
+ ashamed bored brave calm cautious cold confident confused contemplative
592
+ contented cranky crazy creative curious dejected depressed disappointed
593
+ disgusted dismayed distracted embarrassed envious excited flirtatious
594
+ frustrated grumpy guilty happy hopeful hot humbled humiliated hungry hurt
595
+ impressed in_awe in_love indignant interested intoxicated invincible jealous
596
+ lonely lucky mean moody nervous neutral offended outraged playful proud relaxed
597
+ relieved remorseful restless sad sarcastic serious shocked shy sick sleepy
598
+ spontaneous stressed strong surprised thankful thirsty tired undefined weak
599
+ worried}.freeze
600
+
601
+ def mood_node
602
+ xpath('//xmlns:mood',{'xmlns' => Namespaces::Mood}).first
603
+ end
604
+ def mood_name_node
605
+ n = mood_node
606
+ n.children.find{|c| DefinedMoods.include?(c.name)} if n
607
+ end
608
+ def mood_text_node
609
+ n = mood_node
610
+ n.children.find{|c| c.name == 'text'}
611
+ end
612
+ def mood
613
+ n = mood_name_node
614
+ n.name if n
615
+ end
616
+ def mood
617
+ n = mood_text_node
618
+ n.content if n
619
+ end
576
620
  end
577
621
 
578
622
  module Bytestreams
@@ -620,15 +664,33 @@ end
620
664
  end
621
665
  end
622
666
 
667
+ module Featurenegotiation
668
+ include Dataforms
669
+ def feature_node
670
+ xpath('//xmlns:feature',{'xmnls' => Namespaces::FeatureNeg})
671
+ end
672
+ end
673
+
623
674
  module Streaminitiation
624
675
  include Iq
625
- include Dataforms
676
+ include Featurenegotiation
626
677
  def si_node
627
678
  xpath('//xmlns:si',{'xmlns' => Namespaces::StreamInitiation}).first
628
679
  end
629
680
  def file_node
630
681
  xpath('//xmlns:file',{'xmlns' => Namespaces::FileTransfer}).first
631
682
  end
683
+ def range_node
684
+ xpath('//xmlns:range',{'xmlns' => Namespaces::FileTransfer}).first
685
+ end
686
+ def range_length
687
+ n = range_node
688
+ read_attr(n, 'length') {|x| Integer(x)} if n
689
+ end
690
+ def range_offset
691
+ n = range_node
692
+ read_attr(n, 'offset') {|x| Integer(x)} if n
693
+ end
632
694
  def mime_type
633
695
  n = si_node
634
696
  read_attr(n, 'mime-type') if n
@@ -657,7 +719,6 @@ end
657
719
  n = file_node
658
720
  n.children.find{|n| n.name == 'range'} if n
659
721
  end
660
- # TODO: range on requests
661
722
  def description
662
723
  n = file_node
663
724
  if n
@@ -674,8 +735,335 @@ end
674
735
  end
675
736
  end
676
737
 
738
+ module Bob
739
+ include Iq
740
+ Item = Struct.new(:jid, :data, :mime, :max_age) do
741
+ def sha1
742
+ Digest::SHA1.hexdigest data
743
+ end
744
+ def cid
745
+ "sha1+#{sha1}@#{jid}"
746
+ end
747
+ def b64
748
+ Base64.strict_encode64 data
749
+ end
750
+ end
751
+
752
+ def reply(item,*args)
753
+ ref = "cid:#{item.cid}"
754
+ params = {}
755
+ params['max-age'] = item.max_age if item.max_age
756
+ super(*args) do |xml|
757
+ xml.data({:xmlns => EM::Xmpp::Namespaces::BoB, :cid => ref, :type => item.mime}.merge(params), item.b64)
758
+ yield xml if block_given?
759
+ end
760
+ end
761
+
762
+ def data_node
763
+ xpath('//xmlns:data',{'xmlns' => Namespaces::BoB}).first
764
+ end
765
+ def cid
766
+ n = data_node
767
+ read_attr(n, 'cid') if n
768
+ end
769
+ def max_age
770
+ n = data_node
771
+ read_attr(n, 'max-age'){|x| Integer(x)} if n
772
+ end
773
+ def mime_type
774
+ n = data_node
775
+ read_attr(n, 'type') if n
776
+ end
777
+ def raw_data
778
+ n = data_node
779
+ n.content if n
780
+ end
781
+ def data
782
+ Base64.strict_decode raw_data if raw_data
783
+ end
784
+ end
785
+
786
+ module Ibb
787
+ include IncomingStanza
788
+ def open_node
789
+ xpath('//xmlns:open',{'xmlns' => Namespaces::IBB}).first
790
+ end
791
+ def data_node
792
+ xpath('//xmlns:data',{'xmlns' => Namespaces::IBB}).first
793
+ end
794
+ def close_node
795
+ xpath('//xmlns:close',{'xmlns' => Namespaces::IBB}).first
796
+ end
797
+ def block_size
798
+ n = open_node
799
+ read_attr(n,'block-size'){|x| Integer(x)} if n
800
+ end
801
+ def sid
802
+ n = open_node || data_node || close_node
803
+ read_attr(n,'sid') if n
804
+ end
805
+ def seq
806
+ n = data_node
807
+ read_attr(n,'seq') if n
808
+ end
809
+ def stanza_type
810
+ n = open_node
811
+ read_attr(n,'stanza') if n
812
+ end
813
+ def data
814
+ n = data_node
815
+ n.content if n
816
+ end
817
+ end
818
+
819
+ module PubsubMain
820
+ include IncomingStanza
821
+ Subscription = Struct.new(:jid, :node, :subscription, :sub_id, :expiry)
822
+ Affiliation = Struct.new(:jid, :node, :affiliation)
823
+ Item = Struct.new(:node, :item_id, :payload, :publisher)
824
+ Retraction = Struct.new(:node, :item_id)
825
+ Deletion = Struct.new(:node, :redirect)
826
+ Configuration= Struct.new(:node, :config)
827
+ Purge = Struct.new(:node)
828
+
829
+ def service
830
+ from.jid
831
+ end
832
+ end
833
+
834
+ module Pubsubevent
835
+ include PubsubMain
836
+
837
+ def node_id
838
+ ret = nil
839
+ n = event_node
840
+ ret = read_attr(n, 'node') if n
841
+ unless ret
842
+ n = items_node
843
+ ret = read_attr(n, 'node') if n
844
+ end
845
+ ret
846
+ end
847
+
848
+ def event_node
849
+ xpath('//xmlns:event',{'xmlns' => EM::Xmpp::Namespaces::PubSubEvent}).first
850
+ end
851
+ def items_node
852
+ n = event_node
853
+ if n
854
+ n.xpath('.//xmlns:items',{'xmlns' => EM::Xmpp::Namespaces::PubSubEvent}).first
855
+ end
856
+ end
857
+ def items
858
+ node = items_node
859
+ if node
860
+ node_id = read_attr(node, 'node')
861
+ node.xpath(".//xmlns:item",{'xmlns' => EM::Xmpp::Namespaces::PubSubEvent}).map do |n|
862
+ item_id = read_attr n, 'id'
863
+ publisher = read_attr n, 'publisher'
864
+ Item.new(node_id, item_id, n.children, publisher)
865
+ end
866
+ else
867
+ []
868
+ end
869
+ end
870
+ def retractions
871
+ node = items_node
872
+ if node
873
+ node_id = read_attr(node, 'node')
874
+ node.xpath(".//xmlns:retract",{'xmlns' => EM::Xmpp::Namespaces::PubSubEvent}).map do |n|
875
+ item_id = read_attr n, 'id'
876
+ Retraction.new(node_id, item_id)
877
+ end
878
+ else
879
+ []
880
+ end
881
+ end
882
+
883
+ def purge_node
884
+ n = event_node
885
+ if n
886
+ n.xpath('//xmlns:purge',{'xmlns' => EM::Xmpp::Namespaces::PubSubEvent}).first
887
+ end
888
+ end
889
+
890
+ def purge
891
+ node = purge_node
892
+ if node
893
+ node_id = read_attr(node, 'node')
894
+ Purge.new(node_id) if node
895
+ end
896
+ end
897
+
898
+ def configuration_node
899
+ n = event_node
900
+ if n
901
+ n.xpath('//xmlns:configuration',{'xmlns' => EM::Xmpp::Namespaces::PubSubEvent}).first
902
+ end
903
+ end
904
+
905
+ def configuration
906
+ node = configuration_node
907
+ if node
908
+ node_id = read_attr(node, 'node')
909
+ Configuration.new(node_id, node.children)
910
+ end
911
+ end
912
+
913
+ def deletion_node
914
+ n = event_node
915
+ if n
916
+ n.xpath('//xmlns:delete',{'xmlns' => EM::Xmpp::Namespaces::PubSubEvent}).first
917
+ end
918
+ end
919
+
920
+ def deletion
921
+ node = deletion_node
922
+ if node
923
+ node_id = read_attr(node, 'node')
924
+ r = node.xpath('//xmlns:redirect',{'xmlns' => EM::Xmpp::Namespaces::PubSubEvent}).first
925
+ uri = read_attr(r, 'uri') if r
926
+ Deletion.new(node_id, uri)
927
+ end
928
+ end
929
+ end
930
+
931
+ module Pubsub
932
+ include PubsubMain
933
+ def pubsub_node
934
+ xpath('//xmlns:pubsub',{'xmlns' => EM::Xmpp::Namespaces::PubSub}).first
935
+ end
936
+ def publish_node
937
+ xpath('//xmlns:publish',{'xmlns' => EM::Xmpp::Namespaces::PubSub}).first
938
+ end
939
+ def subscriptions_container_node
940
+ n = pubsub_node
941
+ if n
942
+ n.xpath('//xmlns:subscriptions',{'xmlns' => EM::Xmpp::Namespaces::PubSub}).first
943
+ end
944
+ end
945
+ def subscriptions
946
+ node = subscriptions_container_node || pubsub_node
947
+ if node
948
+ node.xpath('//xmlns:subscription',{'xmlns' => EM::Xmpp::Namespaces::PubSub}).map do |n|
949
+ node_id = read_attr n, 'node'
950
+ jid = read_attr(n,'jid') {|x| connection.entity x}
951
+ sub = read_attr(n,'subscription')
952
+ sub_id = read_attr(n,'subid')
953
+ expiry = read_attr(n,'expiry'){|x| Date.parse x}
954
+ Subscription.new(jid,node_id,sub,sub_id,expiry)
955
+ end
956
+ else
957
+ []
958
+ end
959
+ end
960
+
961
+ def affiliations_container_node
962
+ n = pubsub_node
963
+ if n
964
+ n.xpath('//xmlns:affiliations',{'xmlns' => EM::Xmpp::Namespaces::PubSub}).first
965
+ end
966
+ end
967
+ def affiliations
968
+ node = affiliations_container_node
969
+ if node
970
+ node.xpath('//xmlns:affiliation',{'xmlns' => EM::Xmpp::Namespaces::PubSub}).map do |n|
971
+ node_id = read_attr n, 'node'
972
+ aff = read_attr(n,'affiliation')
973
+ Affiliation.new(to,node_id,aff)
974
+ end
975
+ else
976
+ []
977
+ end
978
+ end
979
+
980
+ def items_container_node
981
+ n = pubsub_node
982
+ if n
983
+ n.xpath('//xmlns:items',{'xmlns' => EM::Xmpp::Namespaces::PubSub}).first
984
+ end
985
+ end
986
+
987
+ def items
988
+ node = items_container_node || publish_node
989
+ if node
990
+ item_node = read_attr node, 'node'
991
+ node.xpath('//xmlns:item',{'xmlns' => EM::Xmpp::Namespaces::PubSub}).map do |n|
992
+ item_id = read_attr n, 'id'
993
+ Item.new(item_node,item_id,n.children.first,nil)
994
+ end
995
+ else
996
+ []
997
+ end
998
+ end
999
+
1000
+ def creation_node
1001
+ n = pubsub_node
1002
+ if n
1003
+ n.xpath('//xmlns:create',{'xmlns' => EM::Xmpp::Namespaces::PubSub}).first
1004
+ end
1005
+ end
1006
+
1007
+ def created_node
1008
+ n = creation_node
1009
+ read_attr(n, 'node') if n
1010
+ end
1011
+ end
1012
+
1013
+
1014
+ module Pubsubowner
1015
+ include PubsubMain
1016
+ def pubsub_node
1017
+ xpath('//xmlns:pubsub',{'xmlns' => EM::Xmpp::Namespaces::PubSubOwner}).first
1018
+ end
1019
+ def publish_node
1020
+ xpath('//xmlns:publish',{'xmlns' => EM::Xmpp::Namespaces::PubSubOwner}).first
1021
+ end
1022
+ def subscriptions_container_node
1023
+ n = pubsub_node
1024
+ if n
1025
+ n.xpath('//xmlns:subscriptions',{'xmlns' => EM::Xmpp::Namespaces::PubSubOwner}).first
1026
+ end
1027
+ end
1028
+ def subscriptions
1029
+ node = subscriptions_container_node
1030
+ node_id = read_attr node, 'node'
1031
+ if node
1032
+ node.xpath('//xmlns:subscription',{'xmlns' => EM::Xmpp::Namespaces::PubSubOwner}).map do |n|
1033
+ jid = read_attr(n,'jid') {|x| connection.entity x}
1034
+ sub = read_attr(n,'subscription')
1035
+ sub_id = read_attr(n,'subid')
1036
+ expiry = read_attr(n,'expiry'){|x| Date.parse x}
1037
+ Subscription.new(jid,node_id,sub,sub_id,expiry)
1038
+ end
1039
+ else
1040
+ []
1041
+ end
1042
+ end
1043
+
1044
+ def affiliations_container_node
1045
+ n = pubsub_node
1046
+ if n
1047
+ n.xpath('//xmlns:affiliations',{'xmlns' => EM::Xmpp::Namespaces::PubSubOwner}).first
1048
+ end
1049
+ end
1050
+ def affiliations
1051
+ node = affiliations_container_node
1052
+ if node
1053
+ node_id = read_attr(node, 'node')
1054
+ node.xpath('//xmlns:affiliation',{'xmlns' => EM::Xmpp::Namespaces::PubSubOwner}).map do |n|
1055
+ jid = read_attr(n, 'jid') {|x| connection.entity x}
1056
+ aff = read_attr(n,'affiliation')
1057
+ Affiliation.new(jid,node_id,aff)
1058
+ end
1059
+ else
1060
+ []
1061
+ end
1062
+ end
1063
+ end
1064
+
677
1065
  module Mucuser
678
- def x_nodstreaminitiation
1066
+ def x_node
679
1067
  xpath('//xmlns:x',{'xmlns' => EM::Xmpp::Namespaces::MucUser}).first
680
1068
  end
681
1069
 
@@ -752,6 +1140,9 @@ end
752
1140
  class Message < Bit
753
1141
  include Contexts::Message
754
1142
  end
1143
+ class Attention < Bit
1144
+ include Contexts::Attention
1145
+ end
755
1146
  class Iq < Bit
756
1147
  include Contexts::Iq
757
1148
  end
@@ -797,6 +1188,21 @@ end
797
1188
  class Streaminitiation < Bit
798
1189
  include Contexts::Streaminitiation
799
1190
  end
1191
+ class Bob < Bit
1192
+ include Contexts::Bob
1193
+ end
1194
+ class Ibb < Bit
1195
+ include Contexts::Ibb
1196
+ end
1197
+ class Pubsub < Bit
1198
+ include Contexts::Pubsub
1199
+ end
1200
+ class Pubsubowner < Bit
1201
+ include Contexts::Pubsubowner
1202
+ end
1203
+ class Pubsubevent < Bit
1204
+ include Contexts::Pubsubevent
1205
+ end
800
1206
  class Mucuser < Bit
801
1207
  include Contexts::Mucuser
802
1208
  end