comparison MoinMoin/items/__init__.py @ 969:5bf6d7a2ffcf

Convert all %r, %s, %x, %d, %i, %o to new Format String Syntax
author Vedran Mileti? <rivanvx@gmail.com>
date Sun, 16 Oct 2011 02:26:35 +0200
parents 2d201ed2ab7d
children 6dd0b0755b6a 8621c3e273a1
comparison
equal deleted inserted replaced
968:26bd2c7936f9 969:5bf6d7a2ffcf
109 return other.content_type.issupertype(self.content_type) 109 return other.content_type.issupertype(self.content_type)
110 return False 110 return False
111 return NotImplemented 111 return NotImplemented
112 112
113 def __repr__(self): 113 def __repr__(self):
114 return '<%s: %s, prio %d [%r]>' % (self.__class__.__name__, 114 return '<{0}: {1}, prio {2} [{3!r}]>' % (self.__class__.__name__,
115 self.content_type, 115 self.content_type,
116 self.priority, 116 self.priority,
117 self.factory) 117 self.factory)
118 118
119 def get(self, name, content_type, **kw): 119 def get(self, name, content_type, **kw):
175 if item is None: 175 if item is None:
176 item = flaskg.storage[name] 176 item = flaskg.storage[name]
177 else: 177 else:
178 name = item.name 178 name = item.name
179 if not item: # except NoSuchItemError: 179 if not item: # except NoSuchItemError:
180 logging.debug("No such item: %r" % name) 180 logging.debug("No such item: {0!r}".format(name))
181 item = DummyItem(name) 181 item = DummyItem(name)
182 rev = DummyRev(item, contenttype) 182 rev = DummyRev(item, contenttype)
183 logging.debug("Item %r, created dummy revision with contenttype %r" % (name, contenttype)) 183 logging.debug("Item {0!r}, created dummy revision with contenttype {1!r}".format(name, contenttype))
184 else: 184 else:
185 logging.debug("Got item: %r" % name) 185 logging.debug("Got item: {0!r}".format(name))
186 try: 186 try:
187 rev = item.get_revision(rev_id) 187 rev = item.get_revision(rev_id)
188 contenttype = u'application/octet-stream' # it exists 188 contenttype = u'application/octet-stream' # it exists
189 except KeyError: # NoSuchRevisionError: 189 except KeyError: # NoSuchRevisionError:
190 try: 190 try:
191 rev = item.get_revision(CURRENT) # fall back to current revision 191 rev = item.get_revision(CURRENT) # fall back to current revision
192 # XXX add some message about invalid revision 192 # XXX add some message about invalid revision
193 except KeyError: # NoSuchRevisionError: 193 except KeyError: # NoSuchRevisionError:
194 logging.debug("Item %r has no revisions." % name) 194 logging.debug("Item {0!r} has no revisions.".format(name))
195 rev = DummyRev(item, contenttype) 195 rev = DummyRev(item, contenttype)
196 logging.debug("Item %r, created dummy revision with contenttype %r" % (name, contenttype)) 196 logging.debug("Item {0!r}, created dummy revision with contenttype {1!r}".format(name, contenttype))
197 logging.debug("Got item %r, revision: %r" % (name, rev_id)) 197 logging.debug("Got item {0!r}, revision: {1!r}".format(name, rev_id))
198 contenttype = rev.meta.get(CONTENTTYPE) or contenttype # use contenttype in case our metadata does not provide CONTENTTYPE 198 contenttype = rev.meta.get(CONTENTTYPE) or contenttype # use contenttype in case our metadata does not provide CONTENTTYPE
199 logging.debug("Item %r, got contenttype %r from revision meta" % (name, contenttype)) 199 logging.debug("Item {0!r}, got contenttype {1!r} from revision meta".format(name, contenttype))
200 #logging.debug("Item %r, rev meta dict: %r" % (name, dict(rev.meta))) 200 #logging.debug("Item %r, rev meta dict: %r" % (name, dict(rev.meta)))
201 201
202 item = item_registry.get(name, Type(contenttype), rev=rev) 202 item = item_registry.get(name, Type(contenttype), rev=rev)
203 logging.debug("ItemClass %r handles %r" % (item.__class__, contenttype)) 203 logging.debug("ItemClass {0!r} handles {1!r}".format(item.__class__, contenttype))
204 return item 204 return item
205 205
206 def __init__(self, name, rev=None, contenttype=None): 206 def __init__(self, name, rev=None, contenttype=None):
207 self.name = name 207 self.name = name
208 self.rev = rev 208 self.rev = rev
236 # FROM_mimetype --> DOM 236 # FROM_mimetype --> DOM
237 # if so we perform the transformation, otherwise we don't 237 # if so we perform the transformation, otherwise we don't
238 from MoinMoin.converter import default_registry as reg 238 from MoinMoin.converter import default_registry as reg
239 input_conv = reg.get(Type(self.contenttype), type_moin_document) 239 input_conv = reg.get(Type(self.contenttype), type_moin_document)
240 if not input_conv: 240 if not input_conv:
241 raise TypeError("We cannot handle the conversion from %s to the DOM tree" % self.contenttype) 241 raise TypeError("We cannot handle the conversion from {0} to the DOM tree".format(self.contenttype))
242 smiley_conv = reg.get(type_moin_document, type_moin_document, 242 smiley_conv = reg.get(type_moin_document, type_moin_document,
243 icon='smiley') 243 icon='smiley')
244 244
245 # We can process the conversion 245 # We can process the conversion
246 links = Iri(scheme='wiki', authority='', path='/' + self.name) 246 links = Iri(scheme='wiki', authority='', path='/' + self.name)
371 written += len(buf) 371 written += len(buf)
372 elif isinstance(content, str): 372 elif isinstance(content, str):
373 new_rev.data.write(content) 373 new_rev.data.write(content)
374 written += len(content) 374 written += len(content)
375 else: 375 else:
376 raise StorageError("unsupported content object: %r" % content) 376 raise StorageError("unsupported content object: {0!r}".format(content))
377 return written 377 return written
378 378
379 def _rename(self, name, comment, action): 379 def _rename(self, name, comment, action):
380 self._save(self.meta, self.data, name=name, action=action, comment=comment) 380 self._save(self.meta, self.data, name=name, action=action, comment=comment)
381 381
390 delete this item 390 delete this item
391 """ 391 """
392 trash_prefix = u'Trash/' # XXX move to config 392 trash_prefix = u'Trash/' # XXX move to config
393 now = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime()) 393 now = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime())
394 # make trash name unique by including timestamp: 394 # make trash name unique by including timestamp:
395 trashname = u'%s%s (%s UTC)' % (trash_prefix, self.name, now) 395 trashname = u'{0}{1} ({2} UTC)'.format(trash_prefix, self.name, now)
396 return self._rename(trashname, comment, action=u'TRASH') 396 return self._rename(trashname, comment, action=u'TRASH')
397 397
398 def revert(self): 398 def revert(self):
399 # called from revert UI/POST 399 # called from revert UI/POST
400 comment = request.form.get('comment') 400 comment = request.form.get('comment')
555 else: 555 else:
556 selected_contenttypes = all_contenttypes 556 selected_contenttypes = all_contenttypes
557 557
558 unknown_item_group = "unknown items" 558 unknown_item_group = "unknown items"
559 if startswith: 559 if startswith:
560 startswith = (u'%s' % startswith, u'%s' % startswith.swapcase()) 560 startswith = (u'{0}'.format(startswith), u'{0}'.format(startswith.swapcase()))
561 if not selected_groups or unknown_item_group in selected_groups: 561 if not selected_groups or unknown_item_group in selected_groups:
562 index = [(fullname, relname, contenttype) 562 index = [(fullname, relname, contenttype)
563 for fullname, relname, contenttype in index 563 for fullname, relname, contenttype in index
564 if u'/' not in relname 564 if u'/' not in relname
565 and relname.startswith(startswith) 565 and relname.startswith(startswith)
594 detailed_index = [] 594 detailed_index = []
595 all_item_index = self.get_index() 595 all_item_index = self.get_index()
596 all_item_text = "\n".join(item_info[1] for item_info in all_item_index) 596 all_item_text = "\n".join(item_info[1] for item_info in all_item_index)
597 for fullname, relname, contenttype in index: 597 for fullname, relname, contenttype in index:
598 hassubitem = False 598 hassubitem = False
599 subitem_name_re = u"^%s/[^/]+$" % re.escape(relname) 599 subitem_name_re = u"^{0}/[^/]+$".format(re.escape(relname))
600 regex = re.compile(subitem_name_re, re.UNICODE|re.M) 600 regex = re.compile(subitem_name_re, re.UNICODE|re.M)
601 if regex.search(all_item_text): 601 if regex.search(all_item_text):
602 hassubitem = True 602 hassubitem = True
603 detailed_index.append((fullname, relname, contenttype, hassubitem)) 603 detailed_index.append((fullname, relname, contenttype, hassubitem))
604 return detailed_index 604 return detailed_index
652 else: 652 else:
653 return '' 653 return ''
654 data = property(fget=get_data) 654 data = property(fget=get_data)
655 655
656 def _render_meta(self): 656 def _render_meta(self):
657 return "<pre>%s</pre>" % escape(self.meta_dict_to_text(self.meta, use_filter=False)) 657 return "<pre>{0}</pre>".format(escape(self.meta_dict_to_text(self.meta, use_filter=False)))
658 658
659 def get_templates(self, contenttype=None): 659 def get_templates(self, contenttype=None):
660 """ create a list of templates (for some specific contenttype) """ 660 """ create a list of templates (for some specific contenttype) """
661 terms = [Term(WIKINAME, app.cfg.interwikiname), Term(TAGS, u'template')] 661 terms = [Term(WIKINAME, app.cfg.interwikiname), Term(TAGS, u'template')]
662 if contenttype is not None: 662 if contenttype is not None:
798 :param content: the data to store into the tar file (str or file-like) 798 :param content: the data to store into the tar file (str or file-like)
799 :param content_length: byte-length of content (for str, None can be given) 799 :param content_length: byte-length of content (for str, None can be given)
800 :param expected_members: set of expected member file names 800 :param expected_members: set of expected member file names
801 """ 801 """
802 if not name in expected_members: 802 if not name in expected_members:
803 raise StorageError("tried to add unexpected member %r to container item %r" % (name, self.name)) 803 raise StorageError("tried to add unexpected member {0!r} to container item {1!r}".format(name, self.name))
804 if isinstance(name, unicode): 804 if isinstance(name, unicode):
805 name = name.encode('utf-8') 805 name = name.encode('utf-8')
806 temp_fname = os.path.join(tempfile.gettempdir(), 'TarContainer_' + 806 temp_fname = os.path.join(tempfile.gettempdir(), 'TarContainer_' +
807 cache_key(usage='TarContainer', name=self.name)) 807 cache_key(usage='TarContainer', name=self.name))
808 tf = tarfile.TarFile(temp_fname, mode='a') 808 tf = tarfile.TarFile(temp_fname, mode='a')
810 if isinstance(content, str): 810 if isinstance(content, str):
811 if content_length is None: 811 if content_length is None:
812 content_length = len(content) 812 content_length = len(content)
813 content = StringIO(content) # we need a file obj 813 content = StringIO(content) # we need a file obj
814 elif not hasattr(content, 'read'): 814 elif not hasattr(content, 'read'):
815 logging.error("unsupported content object: %r" % content) 815 logging.error("unsupported content object: {0!r}".format(content))
816 raise StorageError("unsupported content object: %r" % content) 816 raise StorageError("unsupported content object: {0!r}".format(content))
817 assert content_length >= 0 # we don't want -1 interpreted as 4G-1 817 assert content_length >= 0 # we don't want -1 interpreted as 4G-1
818 ti.size = content_length 818 ti.size = content_length
819 tf.addfile(ti, content) 819 tf.addfile(ti, content)
820 tf_members = set(tf.getnames()) 820 tf_members = set(tf.getnames())
821 tf.close() 821 tf.close()
822 if tf_members - expected_members: 822 if tf_members - expected_members:
823 msg = "found unexpected members in container item %r" % self.name 823 msg = "found unexpected members in container item {0!r}".format(self.name)
824 logging.error(msg) 824 logging.error(msg)
825 os.remove(temp_fname) 825 os.remove(temp_fname)
826 raise StorageError(msg) 826 raise StorageError(msg)
827 if tf_members == expected_members: 827 if tf_members == expected_members:
828 # everything we expected has been added to the tar file, save the container as revision 828 # everything we expected has been added to the tar file, save the container as revision
933 elif content_type == 'image/png': 933 elif content_type == 'image/png':
934 output_type = 'PNG' 934 output_type = 'PNG'
935 elif content_type == 'image/gif': 935 elif content_type == 'image/gif':
936 output_type = 'GIF' 936 output_type = 'GIF'
937 else: 937 else:
938 raise ValueError("content_type %r not supported" % content_type) 938 raise ValueError("content_type {0!r} not supported".format(content_type))
939 939
940 # revision obj has read() seek() tell(), thus this works: 940 # revision obj has read() seek() tell(), thus this works:
941 image = PILImage.open(self.rev.data) 941 image = PILImage.open(self.rev.data)
942 image.load() 942 image.load()
943 943
1012 def _render_data_diff(self, oldrev, newrev): 1012 def _render_data_diff(self, oldrev, newrev):
1013 if PIL is None: 1013 if PIL is None:
1014 # no PIL, we can't do anything, we just call the base class method 1014 # no PIL, we can't do anything, we just call the base class method
1015 return super(TransformableBitmapImage, self)._render_data_diff(oldrev, newrev) 1015 return super(TransformableBitmapImage, self)._render_data_diff(oldrev, newrev)
1016 url = url_for('frontend.diffraw', item_name=self.name, rev1=oldrev.revid, rev2=newrev.revid) 1016 url = url_for('frontend.diffraw', item_name=self.name, rev1=oldrev.revid, rev2=newrev.revid)
1017 return Markup('<img src="%s" />' % escape(url)) 1017 return Markup('<img src="{0}" />'.format(escape(url)))
1018 1018
1019 def _render_data_diff_raw(self, oldrev, newrev): 1019 def _render_data_diff_raw(self, oldrev, newrev):
1020 hash_name = HASH_ALGORITHM 1020 hash_name = HASH_ALGORITHM
1021 cid = cache_key(usage="ImageDiff", 1021 cid = cache_key(usage="ImageDiff",
1022 hash_name=hash_name, 1022 hash_name=hash_name,
1033 elif content_type == 'image/png': 1033 elif content_type == 'image/png':
1034 output_type = 'PNG' 1034 output_type = 'PNG'
1035 elif content_type == 'image/gif': 1035 elif content_type == 'image/gif':
1036 output_type = 'GIF' 1036 output_type = 'GIF'
1037 else: 1037 else:
1038 raise ValueError("content_type %r not supported" % content_type) 1038 raise ValueError("content_type {0!r} not supported".format(content_type))
1039 1039
1040 try: 1040 try:
1041 oldimage = PILImage.open(oldrev) 1041 oldimage = PILImage.open(oldrev)
1042 newimage = PILImage.open(newrev) 1042 newimage = PILImage.open(newrev)
1043 oldimage.load() 1043 oldimage.load()
1048 data = outfile.getvalue() 1048 data = outfile.getvalue()
1049 outfile.close() 1049 outfile.close()
1050 headers = wikiutil.file_headers(content_type=content_type, content_length=len(data)) 1050 headers = wikiutil.file_headers(content_type=content_type, content_length=len(data))
1051 app.cache.set(cid, (headers, data)) 1051 app.cache.set(cid, (headers, data))
1052 except (IOError, ValueError) as err: 1052 except (IOError, ValueError) as err:
1053 logging.exception("error during PILdiff: %s", err.message) 1053 logging.exception("error during PILdiff: {0}".format(err.message))
1054 abort(404) # TODO render user friendly error image 1054 abort(404) # TODO render user friendly error image
1055 else: 1055 else:
1056 # XXX TODO check ACL behaviour 1056 # XXX TODO check ACL behaviour
1057 headers, data = c 1057 headers, data = c
1058 return Response(data, headers=headers) 1058 return Response(data, headers=headers)
1333 # we have a image map. inline it and add a map ref to the img tag 1333 # we have a image map. inline it and add a map ref to the img tag
1334 mapid = 'ImageMapOf' + item_name 1334 mapid = 'ImageMapOf' + item_name
1335 image_map = image_map.replace('%MAPNAME%', mapid) 1335 image_map = image_map.replace('%MAPNAME%', mapid)
1336 # add alt and title tags to areas 1336 # add alt and title tags to areas
1337 image_map = re.sub(r'href\s*=\s*"((?!%TWIKIDRAW%).+?)"', r'href="\1" alt="\1" title="\1"', image_map) 1337 image_map = re.sub(r'href\s*=\s*"((?!%TWIKIDRAW%).+?)"', r'href="\1" alt="\1" title="\1"', image_map)
1338 image_map = image_map.replace('%TWIKIDRAW%"', '%s" alt="%s" title="%s"' % (drawing_url, title, title)) 1338 image_map = image_map.replace('%TWIKIDRAW%"', '{0}" alt="{1}" title="{2}"'.format((drawing_url, title, title)))
1339 title = _('Clickable drawing: %(filename)s', filename=item_name) 1339 title = _('Clickable drawing: %(filename)s', filename=item_name)
1340 1340
1341 return Markup(image_map + '<img src="%s" alt="%s" usemap="#%s" />' % (png_url, title, mapid)) 1341 return Markup(image_map + '<img src="{0}" alt="{1}" usemap="#{2}" />'.format(png_url, title, mapid))
1342 else: 1342 else:
1343 return Markup('<img src="%s" alt="%s" />' % (png_url, title)) 1343 return Markup('<img src="{0}" alt="{1}" />'.format(png_url, title))
1344 1344
1345 item_registry.register(TWikiDraw._factory, Type('application/x-twikidraw')) 1345 item_registry.register(TWikiDraw._factory, Type('application/x-twikidraw'))
1346 1346
1347 1347
1348 class AnyWikiDraw(TarMixin, Image): 1348 class AnyWikiDraw(TarMixin, Image):
1428 # ToDo mapid must become uniq 1428 # ToDo mapid must become uniq
1429 # we have a image map. inline it and add a map ref to the img tag 1429 # we have a image map. inline it and add a map ref to the img tag
1430 # we have also to set a unique ID 1430 # we have also to set a unique ID
1431 mapid = 'ImageMapOf' + self.name 1431 mapid = 'ImageMapOf' + self.name
1432 image_map = image_map.replace(u'id="drawing.svg"', '') 1432 image_map = image_map.replace(u'id="drawing.svg"', '')
1433 image_map = image_map.replace(u'name="drawing.svg"', u'name="%s"' % mapid) 1433 image_map = image_map.replace(u'name="drawing.svg"', u'name="{0}"'.format(mapid))
1434 # unxml, because 4.01 concrete will not validate /> 1434 # unxml, because 4.01 concrete will not validate />
1435 image_map = image_map.replace(u'/>', u'>') 1435 image_map = image_map.replace(u'/>', u'>')
1436 title = _('Clickable drawing: %(filename)s', filename=self.name) 1436 title = _('Clickable drawing: %(filename)s', filename=self.name)
1437 return Markup(image_map + '<img src="%s" alt="%s" usemap="#%s" />' % (png_url, title, mapid)) 1437 return Markup(image_map + '<img src="{0}" alt="{1}" usemap="#{2}" />'.format(png_url, title, mapid))
1438 else: 1438 else:
1439 return Markup('<img src="%s" alt="%s" />' % (png_url, title)) 1439 return Markup('<img src="{0}" alt="{1}" />'.format(png_url, title))
1440 1440
1441 item_registry.register(AnyWikiDraw._factory, Type('application/x-anywikidraw')) 1441 item_registry.register(AnyWikiDraw._factory, Type('application/x-anywikidraw'))
1442 1442
1443 1443
1444 class SvgDraw(TarMixin, Image): 1444 class SvgDraw(TarMixin, Image):
1495 # TODO: this could be a converter -> dom, then transcluding this kind 1495 # TODO: this could be a converter -> dom, then transcluding this kind
1496 # of items and also rendering them with the code in base class could work 1496 # of items and also rendering them with the code in base class could work
1497 item_name = self.name 1497 item_name = self.name
1498 drawing_url = url_for('frontend.get_item', item_name=item_name, member='drawing.svg') 1498 drawing_url = url_for('frontend.get_item', item_name=item_name, member='drawing.svg')
1499 png_url = url_for('frontend.get_item', item_name=item_name, member='drawing.png') 1499 png_url = url_for('frontend.get_item', item_name=item_name, member='drawing.png')
1500 return Markup('<img src="%s" alt="%s" />' % (png_url, drawing_url)) 1500 return Markup('<img src="{0}" alt="{1}" />'.format(png_url, drawing_url))
1501 1501
1502 item_registry.register(SvgDraw._factory, Type('application/x-svgdraw')) 1502 item_registry.register(SvgDraw._factory, Type('application/x-svgdraw'))
1503 1503