PageRenderTime 93ms CodeModel.GetById 84ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/boto-2.5.2/boto/ecs/item.py

#
Python | 153 lines | 130 code | 3 blank | 20 comment | 0 complexity | e825992e527903ed6882146ba070a84f MD5 | raw file
  1# Copyright (c) 2010 Chris Moyer http://coredumped.org/
  2#
  3# Permission is hereby granted, free of charge, to any person obtaining a
  4# copy of this software and associated documentation files (the
  5# "Software"), to deal in the Software without restriction, including
  6# without limitation the rights to use, copy, modify, merge, publish, dis-
  7# tribute, sublicense, and/or sell copies of the Software, and to permit
  8# persons to whom the Software is furnished to do so, subject to the fol-
  9# lowing conditions:
 10#
 11# The above copyright notice and this permission notice shall be included
 12# in all copies or substantial portions of the Software.
 13#
 14# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 15# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
 16# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
 17# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
 18# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 19# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 20# IN THE SOFTWARE.
 21
 22
 23import xml.sax
 24import cgi
 25from StringIO import StringIO
 26
 27class ResponseGroup(xml.sax.ContentHandler):
 28    """A Generic "Response Group", which can
 29    be anything from the entire list of Items to 
 30    specific response elements within an item"""
 31
 32    def __init__(self, connection=None, nodename=None):
 33        """Initialize this Item"""
 34        self._connection = connection
 35        self._nodename = nodename
 36        self._nodepath = []
 37        self._curobj = None
 38        self._xml = StringIO()
 39
 40    def __repr__(self):
 41        return '<%s: %s>' % (self.__class__.__name__, self.__dict__)
 42
 43    #
 44    # Attribute Functions
 45    #
 46    def get(self, name):
 47        return self.__dict__.get(name)
 48    
 49    def set(self, name, value):
 50        self.__dict__[name] = value
 51
 52    def to_xml(self):
 53        return "<%s>%s</%s>" % (self._nodename, self._xml.getvalue(), self._nodename)
 54
 55    #
 56    # XML Parser functions
 57    #
 58    def startElement(self, name, attrs, connection):
 59        self._xml.write("<%s>" % name)
 60        self._nodepath.append(name)
 61        if len(self._nodepath) == 1:
 62            obj = ResponseGroup(self._connection)
 63            self.set(name, obj)
 64            self._curobj = obj
 65        elif self._curobj:
 66            self._curobj.startElement(name, attrs, connection)
 67        return None
 68
 69    def endElement(self, name, value, connection):
 70        self._xml.write("%s</%s>" % (cgi.escape(value).replace("&amp;amp;", "&amp;"), name))
 71        if len(self._nodepath) == 0:
 72            return
 73        obj = None
 74        curval = self.get(name)
 75        if len(self._nodepath) == 1:
 76            if value or not curval:
 77                self.set(name, value)
 78            if self._curobj:
 79                self._curobj = None
 80        #elif len(self._nodepath) == 2:
 81            #self._curobj = None
 82        elif self._curobj:
 83            self._curobj.endElement(name, value, connection)
 84        self._nodepath.pop()
 85        return None
 86
 87
 88class Item(ResponseGroup):
 89    """A single Item"""
 90
 91    def __init__(self, connection=None):
 92        """Initialize this Item"""
 93        ResponseGroup.__init__(self, connection, "Item")
 94
 95class ItemSet(ResponseGroup):
 96    """A special ResponseGroup that has built-in paging, and
 97    only creates new Items on the "Item" tag"""
 98
 99    def __init__(self, connection, action, params, page=0):
100        ResponseGroup.__init__(self, connection, "Items")
101        self.objs = []
102        self.iter = None
103        self.page = page
104        self.action = action
105        self.params = params
106        self.curItem = None
107        self.total_results = 0
108        self.total_pages = 0
109
110    def startElement(self, name, attrs, connection):
111        if name == "Item":
112            self.curItem = Item(self._connection)
113        elif self.curItem != None:
114            self.curItem.startElement(name, attrs, connection)
115        return None
116
117    def endElement(self, name, value, connection):
118        if name == 'TotalResults':
119            self.total_results = value
120        elif name == 'TotalPages':
121            self.total_pages = value
122        elif name == "Item":
123            self.objs.append(self.curItem)
124            self._xml.write(self.curItem.to_xml())
125            self.curItem = None
126        elif self.curItem != None:
127            self.curItem.endElement(name, value, connection)
128        return None
129
130    def next(self):
131        """Special paging functionality"""
132        if self.iter == None:
133            self.iter = iter(self.objs)
134        try:
135            return self.iter.next()
136        except StopIteration:
137            self.iter = None
138            self.objs = []
139            if int(self.page) < int(self.total_pages):
140                self.page += 1
141                self._connection.get_response(self.action, self.params, self.page, self)
142                return self.next()
143            else:
144                raise
145
146    def __iter__(self):
147        return self
148
149    def to_xml(self):
150        """Override to first fetch everything"""
151        for item in self:
152            pass
153        return ResponseGroup.to_xml(self)