comparison MoinMoin/items/__init__.py @ 255:76a4e3cc8705

add +download view for just downloading a revision with forced content-disposition: attachment minor code cleanups, removed MimeType.content_disposition as it did not match send_file api, replaced it by a as_attachment method. removed duplicate get_item list entry. removed unused content_disposition argument from wikiutil.file_headers.
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sat, 25 Jun 2011 11:23:51 +0200
parents 91330de48b9c
children 02888ad76719
comparison
equal deleted inserted replaced
254:91330de48b9c 255:76a4e3cc8705
631 ('application/x-gtar', 'TGZ'), 631 ('application/x-gtar', 'TGZ'),
632 ('application/octet-stream', 'binary file'), 632 ('application/octet-stream', 'binary file'),
633 ]), 633 ]),
634 ] 634 ]
635 635
636 def do_get(self): 636 def do_get(self, force_attachment=False):
637 abort(404) 637 abort(404)
638 638
639 def _convert(self): 639 def _convert(self):
640 abort(404) 640 abort(404)
641 641
741 741
742 def _convert(self): 742 def _convert(self):
743 return _("Impossible to convert the data to the contenttype: %(contenttype)s", 743 return _("Impossible to convert the data to the contenttype: %(contenttype)s",
744 contenttype=request.values.get('contenttype')) 744 contenttype=request.values.get('contenttype'))
745 745
746 def do_get(self): 746 def do_get(self, force_attachment=False):
747 hash = self.rev.get(HASH_ALGORITHM) 747 hash = self.rev.get(HASH_ALGORITHM)
748 if is_resource_modified(request.environ, hash): # use hash as etag 748 if is_resource_modified(request.environ, hash): # use hash as etag
749 return self._do_get_modified(hash) 749 return self._do_get_modified(hash, force_attachment=force_attachment)
750 else: 750 else:
751 return Response(status=304) 751 return Response(status=304)
752 752
753 def _do_get_modified(self, hash): 753 def _do_get_modified(self, hash, force_attachment=False):
754 member = request.values.get('member') 754 member = request.values.get('member')
755 return self._do_get(hash, member) 755 return self._do_get(hash, member, force_attachment=force_attachment)
756 756
757 def _do_get(self, hash, member=None): 757 def _do_get(self, hash, member=None, force_attachment=False):
758 filename = None
759 if member: # content = file contained within a archive item revision 758 if member: # content = file contained within a archive item revision
760 path, filename = os.path.split(member) 759 path, filename = os.path.split(member)
761 mt = MimeType(filename=filename) 760 mt = MimeType(filename=filename)
762 content_disposition = mt.content_disposition(app.cfg)
763 content_type = mt.content_type()
764 content_length = None 761 content_length = None
765 file_to_send = self.get_member(member) 762 file_to_send = self.get_member(member)
766 else: # content = item revision 763 else: # content = item revision
767 rev = self.rev 764 rev = self.rev
765 filename = rev.item.name
768 try: 766 try:
769 mimestr = rev[CONTENTTYPE] 767 mimestr = rev[CONTENTTYPE]
770 except KeyError: 768 except KeyError:
771 mt = MimeType(filename=rev.item.name) 769 mt = MimeType(filename=filename)
772 else: 770 else:
773 mt = MimeType(mimestr=mimestr) 771 mt = MimeType(mimestr=mimestr)
774 content_disposition = mt.content_disposition(app.cfg)
775 content_type = mt.content_type()
776 content_length = rev[SIZE] 772 content_length = rev[SIZE]
777 file_to_send = rev 773 file_to_send = rev
778 774 content_type = mt.content_type()
779 # TODO: handle content_disposition is not None 775 as_attachment = force_attachment or mt.as_attachment(app.cfg)
780 # Important: empty filename keeps flask from trying to autodetect filename,
781 # as this would not work for us, because our file's are not necessarily fs files.
782 return send_file(file=file_to_send, 776 return send_file(file=file_to_send,
783 mimetype=content_type, 777 mimetype=content_type,
784 as_attachment=False, attachment_filename=filename, 778 as_attachment=as_attachment, attachment_filename=filename,
785 cache_timeout=10, # wiki data can change rapidly 779 cache_timeout=10, # wiki data can change rapidly
786 add_etags=True, etag=hash, conditional=True) 780 add_etags=True, etag=hash, conditional=True)
787 781
788 item_registry.register(Binary._factory, Type('*/*')) 782 item_registry.register(Binary._factory, Type('*/*'))
789 783
997 image.save(outfile, output_type) 991 image.save(outfile, output_type)
998 data = outfile.getvalue() 992 data = outfile.getvalue()
999 outfile.close() 993 outfile.close()
1000 return content_type, data 994 return content_type, data
1001 995
1002 def _do_get_modified(self, hash): 996 def _do_get_modified(self, hash, force_attachment=False):
1003 try: 997 try:
1004 width = int(request.values.get('w')) 998 width = int(request.values.get('w'))
1005 except (TypeError, ValueError): 999 except (TypeError, ValueError):
1006 width = None 1000 width = None
1007 try: 1001 try:
1031 else: 1025 else:
1032 # XXX TODO check ACL behaviour 1026 # XXX TODO check ACL behaviour
1033 headers, data = c 1027 headers, data = c
1034 return Response(data, headers=headers) 1028 return Response(data, headers=headers)
1035 else: 1029 else:
1036 return self._do_get(hash) 1030 return self._do_get(hash, force_attachment=force_attachment)
1037 1031
1038 def _render_data_diff(self, oldrev, newrev): 1032 def _render_data_diff(self, oldrev, newrev):
1039 if PIL is None: 1033 if PIL is None:
1040 # no PIL, we can't do anything, we just call the base class method 1034 # no PIL, we can't do anything, we just call the base class method
1041 return super(TransformableBitmapImage, self)._render_data_diff(oldrev, newrev) 1035 return super(TransformableBitmapImage, self)._render_data_diff(oldrev, newrev)
1291 tree = ET.ElementTree(doc) 1285 tree = ET.ElementTree(doc)
1292 tree.write(file_to_send, namespaces=output_namespaces) 1286 tree.write(file_to_send, namespaces=output_namespaces)
1293 1287
1294 # We determine the different parameters for the reply 1288 # We determine the different parameters for the reply
1295 mt = MimeType(mimestr='application/docbook+xml;charset=utf-8') 1289 mt = MimeType(mimestr='application/docbook+xml;charset=utf-8')
1296 content_disposition = mt.content_disposition(app.cfg)
1297 content_type = mt.content_type() 1290 content_type = mt.content_type()
1291 as_attachment = mt.as_attachment(app.cfg)
1298 # After creation of the StringIO, we are at the end of the file 1292 # After creation of the StringIO, we are at the end of the file
1299 # so position is the size the file. 1293 # so position is the size the file.
1300 # and then we should move it back at the beginning of the file 1294 # and then we should move it back at the beginning of the file
1301 content_length = file_to_send.tell() 1295 content_length = file_to_send.tell()
1302 file_to_send.seek(0) 1296 file_to_send.seek(0)
1303 # Important: empty filename keeps flask from trying to autodetect filename, 1297 # Important: empty filename keeps flask from trying to autodetect filename,
1304 # as this would not work for us, because our file's are not necessarily fs files. 1298 # as this would not work for us, because our file's are not necessarily fs files.
1305 return send_file(file=file_to_send, 1299 return send_file(file=file_to_send,
1306 mimetype=content_type, 1300 mimetype=content_type,
1307 as_attachment=False, attachment_filename=None, 1301 as_attachment=as_attachment, attachment_filename=None,
1308 cache_timeout=10, # wiki data can change rapidly 1302 cache_timeout=10, # wiki data can change rapidly
1309 add_etags=False, etag=None, conditional=True) 1303 add_etags=False, etag=None, conditional=True)
1310 1304
1311 item_registry.register(DocBook._factory, Type('application/docbook+xml')) 1305 item_registry.register(DocBook._factory, Type('application/docbook+xml'))
1312 1306