@@ -668,14 +668,114 @@ def setVar(self,val):
668
668
""" Set 'var' attribute value of this field. """
669
669
return self .setAttr ('var' ,val )
670
670
671
+ class DataReported (Node ):
672
+ """ This class is used in the DataForm class to describe the 'reported data field' data items which are used in
673
+ 'multiple item form results' (as described in XEP-0004).
674
+ Represents the fields that will be returned from a search. This information is useful when
675
+ you try to use the jabber:iq:search namespace to return dynamic form information.
676
+ """
677
+ def __init__ (self ,node = None ):
678
+ """ Create new empty 'reported data' field. However, note that, according XEP-0004:
679
+ * It MUST contain one or more DataFields.
680
+ * Contained DataFields SHOULD possess a 'type' and 'label' attribute in addition to 'var' attribute
681
+ * Contained DataFields SHOULD NOT contain a <value/> element.
682
+ Alternatively other XML object can be passed in as the 'node' parameted to replicate it as a new
683
+ dataitem.
684
+ """
685
+ Node .__init__ (self ,'reported' ,node = node )
686
+ if node :
687
+ newkids = []
688
+ for n in self .getChildren ():
689
+ if n .getName ()== 'field' : newkids .append (DataField (node = n ))
690
+ else : newkids .append (n )
691
+ self .kids = newkids
692
+ def getField (self ,name ):
693
+ """ Return the datafield object with name 'name' (if exists). """
694
+ return self .getTag ('field' ,attrs = {'var' :name })
695
+ def setField (self ,name ,typ = None ,label = None ):
696
+ """ Create if nessessary or get the existing datafield object with name 'name' and return it.
697
+ If created, attributes 'type' and 'label' are applied to new datafield."""
698
+ f = self .getField (name )
699
+ if f : return f
700
+ return self .addChild (node = DataField (name ,None ,typ ,0 ,label ))
701
+ def asDict (self ):
702
+ """ Represent dataitem as simple dictionary mapping of datafield names to their values."""
703
+ ret = {}
704
+ for field in self .getTags ('field' ):
705
+ name = field .getAttr ('var' )
706
+ typ = field .getType ()
707
+ if isinstance (typ ,(str ,unicode )) and typ [- 6 :]== '-multi' :
708
+ val = []
709
+ for i in field .getTags ('value' ): val .append (i .getData ())
710
+ else : val = field .getTagData ('value' )
711
+ ret [name ]= val
712
+ if self .getTag ('instructions' ): ret ['instructions' ]= self .getInstructions ()
713
+ return ret
714
+ def __getitem__ (self ,name ):
715
+ """ Simple dictionary interface for getting datafields values by their names."""
716
+ item = self .getField (name )
717
+ if item : return item .getValue ()
718
+ raise IndexError ('No such field' )
719
+ def __setitem__ (self ,name ,val ):
720
+ """ Simple dictionary interface for setting datafields values by their names."""
721
+ return self .setField (name ).setValue (val )
722
+
723
+ class DataItem (Node ):
724
+ """ This class is used in the DataForm class to describe data items which are used in 'multiple
725
+ item form results' (as described in XEP-0004).
726
+ """
727
+ def __init__ (self ,node = None ):
728
+ """ Create new empty data item. However, note that, according XEP-0004, DataItem MUST contain ALL
729
+ DataFields described in DataReported.
730
+ Alternatively other XML object can be passed in as the 'node' parameted to replicate it as a new
731
+ dataitem.
732
+ """
733
+ Node .__init__ (self ,'item' ,node = node )
734
+ if node :
735
+ newkids = []
736
+ for n in self .getChildren ():
737
+ if n .getName ()== 'field' : newkids .append (DataField (node = n ))
738
+ else : newkids .append (n )
739
+ self .kids = newkids
740
+ def getField (self ,name ):
741
+ """ Return the datafield object with name 'name' (if exists). """
742
+ return self .getTag ('field' ,attrs = {'var' :name })
743
+ def setField (self ,name ):
744
+ """ Create if nessessary or get the existing datafield object with name 'name' and return it. """
745
+ f = self .getField (name )
746
+ if f : return f
747
+ return self .addChild (node = DataField (name ))
748
+ def asDict (self ):
749
+ """ Represent dataitem as simple dictionary mapping of datafield names to their values."""
750
+ ret = {}
751
+ for field in self .getTags ('field' ):
752
+ name = field .getAttr ('var' )
753
+ typ = field .getType ()
754
+ if isinstance (typ ,(str ,unicode )) and typ [- 6 :]== '-multi' :
755
+ val = []
756
+ for i in field .getTags ('value' ): val .append (i .getData ())
757
+ else : val = field .getTagData ('value' )
758
+ ret [name ]= val
759
+ if self .getTag ('instructions' ): ret ['instructions' ]= self .getInstructions ()
760
+ return ret
761
+ def __getitem__ (self ,name ):
762
+ """ Simple dictionary interface for getting datafields values by their names."""
763
+ item = self .getField (name )
764
+ if item : return item .getValue ()
765
+ raise IndexError ('No such field' )
766
+ def __setitem__ (self ,name ,val ):
767
+ """ Simple dictionary interface for setting datafields values by their names."""
768
+ return self .setField (name ).setValue (val )
769
+
671
770
class DataForm (Node ):
672
771
""" DataForm class. Used for manipulating dataforms in XMPP.
673
772
Relevant XEPs: 0004, 0068, 0122.
674
773
Can be used in disco, pub-sub and many other applications."""
675
774
def __init__ (self , typ = None , data = [], title = None , node = None ):
676
775
"""
677
- Create new dataform of type 'typ'. 'data' is the list of DataField
678
- instances that this dataform contains, 'title' - the title string.
776
+ Create new dataform of type 'typ'; 'data' is the list of DataReported,
777
+ DataItem and DataField instances that this dataform contains; 'title'
778
+ is the title string.
679
779
You can specify the 'node' argument as the other node to be used as
680
780
base for constructing this dataform.
681
781
@@ -690,7 +790,9 @@ def __init__(self, typ=None, data=[], title=None, node=None):
690
790
if node :
691
791
newkids = []
692
792
for n in self .getChildren ():
693
- if n .getName ()== 'field' : newkids .append (DataField (node = n ))
793
+ if n .getName ()== 'field' : newkids .append (DataField (node = n ))
794
+ elif n .getName ()== 'item' : newkids .append (DataItem (node = n ))
795
+ elif n .getName ()== 'reported' : newkids .append (DataReported (node = n ))
694
796
else : newkids .append (n )
695
797
self .kids = newkids
696
798
if typ : self .setType (typ )
@@ -703,6 +805,8 @@ def __init__(self, typ=None, data=[], title=None, node=None):
703
805
for child in data :
704
806
if type (child ) in [type ('' ),type (u'' )]: self .addInstructions (child )
705
807
elif child .__class__ .__name__ == 'DataField' : self .kids .append (child )
808
+ elif child .__class__ .__name__ == 'DataItem' : self .kids .append (child )
809
+ elif child .__class__ .__name__ == 'DataReported' : self .kids .append (child )
706
810
else : self .kids .append (DataField (node = child ))
707
811
def getType (self ):
708
812
""" Return the type of dataform. """
0 commit comments