~malept/pyexiv2/0.2-build-mt

« back to all changes in this revision

Viewing changes to src/pyexiv2/xmp.py

  • Committer: Olivier Tilloy
  • Date: 2010-01-20 23:14:45 UTC
  • mfrom: (253.1.5 lazy_values)
  • Revision ID: olivier@tilloy.net-20100120231445-mpyy0a4v0a30vjaw
Lazy value computation.
Values are computed from the raw values only when requested.

Show diffs side-by-side

added added

removed removed

Lines of Context:
107
107
        self.metadata = None
108
108
        self._raw_value = None
109
109
        self._value = None
 
110
        self._value_cookie = False
110
111
        if value is not None:
111
112
            self._set_value(value)
112
113
 
152
153
        return self._raw_value
153
154
 
154
155
    def _set_raw_value(self, value):
 
156
        type = self._tag._getExiv2Type()
 
157
        if type == 'XmpText':
 
158
            self._tag._setTextValue(value)
 
159
        elif type in ('XmpAlt', 'XmpBag', 'XmpSeq'):
 
160
            self._tag._setArrayValue(value)
 
161
        elif type == 'LangAlt':
 
162
            self._tag._setLangAltValue(value)
 
163
 
 
164
        if self.metadata is not None:
 
165
            self.metadata._set_xmp_tag_value(self.key, value)
155
166
        self._raw_value = value
 
167
        self._value_cookie = True
 
168
 
 
169
    raw_value = property(fget=_get_raw_value, fset=_set_raw_value,
 
170
                         doc='The raw value of the tag as a [list of] ' \
 
171
                             'string(s).')
 
172
 
 
173
    def _compute_value(self):
 
174
        # Lazy computation of the value from the raw value
156
175
        if self.type.startswith(('seq', 'bag', 'alt')):
157
176
            type = self.type[4:]
158
177
            if type.lower().startswith('closed choice of'):
159
178
                type = type[17:]
160
 
            self._value = map(lambda x: self._convert_to_python(x, type), value)
 
179
            self._value = map(lambda x: self._convert_to_python(x, type), self._raw_value)
161
180
        elif self.type == 'Lang Alt':
162
181
            self._value = {}
163
 
            for k, v in value.iteritems():
 
182
            for k, v in self._raw_value.iteritems():
164
183
                try:
165
184
                    self._value[unicode(k, 'utf-8')] = unicode(v, 'utf-8')
166
185
                except TypeError:
167
 
                    raise XmpValueError(value, type)
 
186
                    raise XmpValueError(self._raw_value, type)
168
187
        elif self.type.lower().startswith('closed choice of'):
169
 
            self._value = self._convert_to_python(value, self.type[17:])
 
188
            self._value = self._convert_to_python(self._raw_value, self.type[17:])
170
189
        elif self.type == '':
171
 
            self._value = value
 
190
            self._value = self._raw_value
172
191
        else:
173
 
            self._value = self._convert_to_python(value, self.type)
 
192
            self._value = self._convert_to_python(self._raw_value, self.type)
174
193
 
175
 
    raw_value = property(fget=_get_raw_value, fset=_set_raw_value,
176
 
                         doc='The raw value of the tag as a [list of] ' \
177
 
                             'string(s).')
 
194
        self._value_cookie = False
178
195
 
179
196
    def _get_value(self):
 
197
        if self._value_cookie:
 
198
            self._compute_value()
180
199
        return self._value
181
200
 
182
201
    def _set_value(self, value):
185
204
            stype = self.type
186
205
            if stype.lower().startswith('closed choice of'):
187
206
                stype = stype[17:]
188
 
            self._raw_value = self._convert_to_string(value, stype)
189
 
            self._tag._setTextValue(self._raw_value)
 
207
            self.raw_value = self._convert_to_string(value, stype)
190
208
        elif type in ('XmpAlt', 'XmpBag', 'XmpSeq'):
191
209
            stype = self.type[4:]
192
210
            if stype.lower().startswith('closed choice of'):
193
211
                stype = stype[17:]
194
 
            self._raw_value = map(lambda x: self._convert_to_string(x, stype), value)
195
 
            self._tag._setArrayValue(self._raw_value)
 
212
            self.raw_value = map(lambda x: self._convert_to_string(x, stype), value)
196
213
        elif type == 'LangAlt':
197
 
            self._raw_value = {}
 
214
            raw_value = {}
198
215
            for k, v in value.iteritems():
199
216
                try:
200
 
                    self._raw_value[k.encode('utf-8')] = v.encode('utf-8')
 
217
                    raw_value[k.encode('utf-8')] = v.encode('utf-8')
201
218
                except TypeError:
202
219
                    raise XmpValueError(value, type)
203
 
            self._tag._setLangAltValue(self._raw_value)
204
 
 
205
 
        if self.metadata is not None:
206
 
            self.metadata._set_xmp_tag_value(self.key, self._raw_value)
 
220
            self.raw_value = raw_value
207
221
 
208
222
        self._value = value
 
223
        self._value_cookie = False
209
224
 
210
225
    value = property(fget=_get_value, fset=_set_value,
211
226
                     doc='The value of the tag as a [list of] python ' \
425
440
 
426
441
    def __str__(self):
427
442
        """
428
 
        Return a string representation of the value.
429
 
 
430
 
        @rtype: C{str}
431
 
        """
432
 
        type = self._tag._getExiv2Type()
433
 
        if type == 'XmpText':
434
 
            stype = self.type
435
 
            if stype.lower().startswith('closed choice of'):
436
 
                stype = stype[17:]
437
 
            return self._convert_to_string(self._value, stype)
438
 
        elif type in ('XmpAlt', 'XmpBag', 'XmpSeq'):
439
 
            stype = self.type[4:]
440
 
            if stype.lower().startswith('closed choice of'):
441
 
                stype = stype[17:]
442
 
            values = map(lambda x: self._convert_to_string(x, stype), self._value)
443
 
            return ', '.join(values)
444
 
        elif type == 'LangAlt':
445
 
            values = []
446
 
            for k, v in self._value.iteritems():
447
 
                try:
448
 
                    values.append('lang="%s" %s' % (k.encode('utf-8'), v.encode('utf-8')))
449
 
                except TypeError:
450
 
                    raise XmpValueError(self._value, type)
451
 
            return ', '.join(values)
452
 
 
453
 
    def __repr__(self):
454
 
        """
455
443
        Return a string representation of the XMP tag for debugging purposes.
456
444
 
457
445
        @rtype: C{str}
458
446
        """
459
447
        left = '%s [%s]' % (self.key, self.type)
460
 
        if self._value is None:
 
448
        if self._raw_value is None:
461
449
            right = '(No value)'
462
450
        else:
463
 
             right = str(self)
 
451
             right = self._raw_value
464
452
        return '<%s = %s>' % (left, right)
465
453