Mercurial > moin > 2.0
comparison MoinMoin/items/content.py @ 1649:5dc142ab43d2
Keep itemtype and contenttype in Item and Content subclasses.
Class decorators named @register are provided as helpers in items and
items.content modules.
author | Cheer Xiao <xiaqqaix@gmail.com> |
---|---|
date | Wed, 08 Aug 2012 22:51:16 +0800 |
parents | 1a2c53092ea1 |
children | fa66e4447d63 |
comparison
equal
deleted
inserted
replaced
1648:1a2c53092ea1 | 1649:5dc142ab43d2 |
---|---|
98 """ | 98 """ |
99 return self._register(self.Entry(factory, content_type, priority)) | 99 return self._register(self.Entry(factory, content_type, priority)) |
100 | 100 |
101 | 101 |
102 content_registry = RegistryContent() | 102 content_registry = RegistryContent() |
103 | |
104 def register(cls): | |
105 content_registry.register(cls._factory, Type(cls.contenttype)) | |
106 return cls | |
103 | 107 |
104 | 108 |
105 def conv_serialize(doc, namespaces, method='polyglot'): | 109 def conv_serialize(doc, namespaces, method='polyglot'): |
106 out = array('u') | 110 out = array('u') |
107 flaskg.clock.start('conv_serialize') | 111 flaskg.clock.start('conv_serialize') |
239 query = And(terms) | 243 query = And(terms) |
240 revs = flaskg.storage.search(query, sortedby=NAME_EXACT, limit=None) | 244 revs = flaskg.storage.search(query, sortedby=NAME_EXACT, limit=None) |
241 return [rev.meta[NAME] for rev in revs] | 245 return [rev.meta[NAME] for rev in revs] |
242 | 246 |
243 | 247 |
248 @register | |
244 class NonExistentContent(Content): | 249 class NonExistentContent(Content): |
245 """Dummy Content to use with NonExistent.""" | 250 """Dummy Content to use with NonExistent.""" |
251 contenttype = 'application/x-nonexistent' | |
252 | |
246 def do_get(self, force_attachment=False, mimetype=None): | 253 def do_get(self, force_attachment=False, mimetype=None): |
247 abort(404) | 254 abort(404) |
248 | 255 |
249 def _convert(self, doc): | 256 def _convert(self, doc): |
250 abort(404) | 257 abort(404) |
251 | 258 |
252 | 259 |
253 content_registry.register(NonExistentContent._factory, Type('application/x-nonexistent')) | 260 @register |
254 | |
255 | |
256 class Binary(Content): | 261 class Binary(Content): |
257 """ An arbitrary binary item, fallback class for every item mimetype. """ | 262 """ An arbitrary binary item, fallback class for every item mimetype. """ |
263 contenttype = '*/*' | |
258 | 264 |
259 # XXX reads item rev data into memory! | 265 # XXX reads item rev data into memory! |
260 def get_data(self): | 266 def get_data(self): |
261 if self.rev is not None: | 267 if self.rev is not None: |
262 return self.rev.data.read() | 268 return self.rev.data.read() |
339 return send_file(file=file_to_send, | 345 return send_file(file=file_to_send, |
340 mimetype=content_type, | 346 mimetype=content_type, |
341 as_attachment=as_attachment, attachment_filename=filename, | 347 as_attachment=as_attachment, attachment_filename=filename, |
342 cache_timeout=10, # wiki data can change rapidly | 348 cache_timeout=10, # wiki data can change rapidly |
343 add_etags=True, etag=hash, conditional=True) | 349 add_etags=True, etag=hash, conditional=True) |
344 | |
345 content_registry.register(Binary._factory, Type('*/*')) | |
346 | 350 |
347 | 351 |
348 class RenderableBinary(Binary): | 352 class RenderableBinary(Binary): |
349 """ Base class for some binary stuff that renders with a object tag. """ | 353 """ Base class for some binary stuff that renders with a object tag. """ |
350 | 354 |
419 self.item._save(meta, data, name=self.name, action=u'SAVE', comment='') | 423 self.item._save(meta, data, name=self.name, action=u'SAVE', comment='') |
420 data.close() | 424 data.close() |
421 os.remove(temp_fname) | 425 os.remove(temp_fname) |
422 | 426 |
423 | 427 |
428 @register | |
424 class ApplicationXTar(TarMixin, Application): | 429 class ApplicationXTar(TarMixin, Application): |
425 """ | 430 """ |
426 Tar items | 431 Tar items |
427 """ | 432 """ |
428 | 433 contenttype = 'application/x-tar' |
429 content_registry.register(ApplicationXTar._factory, Type('application/x-tar')) | 434 |
430 content_registry.register(ApplicationXTar._factory, Type('application/x-gtar')) | 435 |
436 @register | |
437 class ApplicationXGTar(ApplicationXTar): | |
438 """ | |
439 Compressed tar items | |
440 """ | |
441 contenttype = 'application/x-gtar' | |
431 | 442 |
432 | 443 |
433 class ZipMixin(object): | 444 class ZipMixin(object): |
434 """ | 445 """ |
435 ZipMixin offers additional functionality for zip-like items to list and | 446 ZipMixin offers additional functionality for zip-like items to list and |
455 | 466 |
456 def put_member(self, name, content, content_length, expected_members): | 467 def put_member(self, name, content, content_length, expected_members): |
457 raise NotImplementedError | 468 raise NotImplementedError |
458 | 469 |
459 | 470 |
471 @register | |
460 class ApplicationZip(ZipMixin, Application): | 472 class ApplicationZip(ZipMixin, Application): |
461 """ | 473 """ |
462 Zip items | 474 Zip items |
463 """ | 475 """ |
464 | 476 contenttype = 'application/zip' |
465 content_registry.register(ApplicationZip._factory, Type('application/zip')) | 477 |
466 | 478 |
467 | 479 @register |
468 class PDF(Application): | 480 class PDF(Application): |
469 """ PDF """ | 481 """ PDF """ |
470 | 482 contenttype = 'application/pdf' |
471 content_registry.register(PDF._factory, Type('application/pdf')) | 483 |
472 | 484 |
473 | 485 @register |
474 class Video(Binary): | 486 class Video(Binary): |
475 """ Base class for video/* """ | 487 """ Base class for video/* """ |
476 | 488 contenttype = 'video/*' |
477 content_registry.register(Video._factory, Type('video/*')) | 489 |
478 | 490 |
479 | 491 @register |
480 class Audio(Binary): | 492 class Audio(Binary): |
481 """ Base class for audio/* """ | 493 """ Base class for audio/* """ |
482 | 494 contenttype = 'audio/*' |
483 content_registry.register(Audio._factory, Type('audio/*')) | 495 |
484 | 496 |
485 | 497 @register |
486 class Image(Binary): | 498 class Image(Binary): |
487 """ Base class for image/* """ | 499 """ Base class for image/* """ |
488 | 500 contenttype = 'image/*' |
489 content_registry.register(Image._factory, Type('image/*')) | |
490 | 501 |
491 | 502 |
492 class RenderableImage(RenderableBinary): | 503 class RenderableImage(RenderableBinary): |
493 """ Base class for renderable Image mimetypes """ | 504 """ Base class for renderable Image mimetypes """ |
494 | 505 |
495 | 506 |
507 @register | |
496 class SvgImage(RenderableImage): | 508 class SvgImage(RenderableImage): |
497 """ SVG images use <object> tag mechanism from RenderableBinary base class """ | 509 """ SVG images use <object> tag mechanism from RenderableBinary base class """ |
498 | 510 contenttype = 'image/svg+xml' |
499 content_registry.register(SvgImage._factory, Type('image/svg+xml')) | |
500 | 511 |
501 | 512 |
502 class RenderableBitmapImage(RenderableImage): | 513 class RenderableBitmapImage(RenderableImage): |
503 """ PNG/JPEG/GIF images use <img> tag (better browser support than <object>) """ | 514 """ PNG/JPEG/GIF images use <img> tag (better browser support than <object>) """ |
504 # if mimetype is also transformable, please register in TransformableImage ONLY! | 515 # if mimetype is also transformable, please register in TransformableImage ONLY! |
655 return Response(data, headers=headers) | 666 return Response(data, headers=headers) |
656 | 667 |
657 def _render_data_diff_text(self, oldrev, newrev): | 668 def _render_data_diff_text(self, oldrev, newrev): |
658 return super(TransformableBitmapImage, self)._render_data_diff_text(oldrev, newrev) | 669 return super(TransformableBitmapImage, self)._render_data_diff_text(oldrev, newrev) |
659 | 670 |
660 content_registry.register(TransformableBitmapImage._factory, Type('image/png')) | 671 |
661 content_registry.register(TransformableBitmapImage._factory, Type('image/jpeg')) | 672 @register |
662 content_registry.register(TransformableBitmapImage._factory, Type('image/gif')) | 673 class PNG(TransformableBitmapImage): |
663 | 674 """ PNG image. """ |
664 | 675 contenttype = 'image/png' |
676 | |
677 | |
678 @register | |
679 class JPEG(TransformableBitmapImage): | |
680 """ JPEG image. """ | |
681 contenttype = 'image/jpeg' | |
682 | |
683 | |
684 @register | |
685 class GIF(TransformableBitmapImage): | |
686 """ GIF image. """ | |
687 contenttype = 'image/gif' | |
688 | |
689 | |
690 @register | |
665 class Text(Binary): | 691 class Text(Binary): |
666 """ Base class for text/* """ | 692 """ Base class for text/* """ |
693 contenttype = 'text/*' | |
667 | 694 |
668 class ModifyForm(Binary.ModifyForm): | 695 class ModifyForm(Binary.ModifyForm): |
669 template = 'modify_text.html' | 696 template = 'modify_text.html' |
670 data_text = String.using(strip=False, optional=True).with_properties(placeholder=L_("Type your text here")) | 697 data_text = String.using(strip=False, optional=True).with_properties(placeholder=L_("Type your text here")) |
671 rows = ROWS_DATA | 698 rows = ROWS_DATA |
744 # TODO: Real output format | 771 # TODO: Real output format |
745 html_conv = reg.get(type_moin_document, Type('application/x-xhtml-moin-page')) | 772 html_conv = reg.get(type_moin_document, Type('application/x-xhtml-moin-page')) |
746 doc = html_conv(doc) | 773 doc = html_conv(doc) |
747 return conv_serialize(doc, {html.namespace: ''}) | 774 return conv_serialize(doc, {html.namespace: ''}) |
748 | 775 |
749 content_registry.register(Text._factory, Type('text/*')) | |
750 | |
751 | 776 |
752 class MarkupItem(Text): | 777 class MarkupItem(Text): |
753 """ | 778 """ |
754 some kind of item with markup | 779 some kind of item with markup |
755 (internal links and transcluded items) | 780 (internal links and transcluded items) |
756 """ | 781 """ |
757 | 782 |
758 | 783 |
784 @register | |
759 class MoinWiki(MarkupItem): | 785 class MoinWiki(MarkupItem): |
760 """ MoinMoin wiki markup """ | 786 """ MoinMoin wiki markup """ |
761 | 787 contenttype = 'text/x.moin.wiki' |
762 content_registry.register(MoinWiki._factory, Type('text/x.moin.wiki')) | 788 |
763 | 789 |
764 | 790 @register |
765 class CreoleWiki(MarkupItem): | 791 class CreoleWiki(MarkupItem): |
766 """ Creole wiki markup """ | 792 """ Creole wiki markup """ |
767 | 793 contenttype = 'text/x.moin.creole' |
768 content_registry.register(CreoleWiki._factory, Type('text/x.moin.creole')) | 794 |
769 | 795 |
770 | 796 @register |
771 class MediaWiki(MarkupItem): | 797 class MediaWiki(MarkupItem): |
772 """ MediaWiki markup """ | 798 """ MediaWiki markup """ |
773 | 799 contenttype = 'text/x-mediawiki' |
774 content_registry.register(MediaWiki._factory, Type('text/x-mediawiki')) | 800 |
775 | 801 |
776 | 802 @register |
777 class ReST(MarkupItem): | 803 class ReST(MarkupItem): |
778 """ ReStructured Text markup """ | 804 """ ReStructured Text markup """ |
779 | 805 contenttype = 'text/x-rst' |
780 content_registry.register(ReST._factory, Type('text/x-rst')) | 806 |
781 | 807 |
782 | 808 @register |
783 class HTML(Text): | 809 class HTML(Text): |
784 """ | 810 """ |
785 HTML markup | 811 HTML markup |
786 | 812 |
787 Note: As we use html_in converter to convert this to DOM and later some | 813 Note: As we use html_in converter to convert this to DOM and later some |
788 output converterter to produce output format (e.g. html_out for html | 814 output converterter to produce output format (e.g. html_out for html |
789 output), all(?) unsafe stuff will get lost. | 815 output), all(?) unsafe stuff will get lost. |
790 | 816 |
791 Note: If raw revision data is accessed, unsafe stuff might be present! | 817 Note: If raw revision data is accessed, unsafe stuff might be present! |
792 """ | 818 """ |
819 contenttype = 'text/html' | |
820 | |
793 class ModifyForm(Text.ModifyForm): | 821 class ModifyForm(Text.ModifyForm): |
794 template = "modify_text_html.html" | 822 template = "modify_text_html.html" |
795 | 823 |
796 content_registry.register(HTML._factory, Type('text/html')) | 824 |
797 | 825 @register |
798 | |
799 class DocBook(MarkupItem): | 826 class DocBook(MarkupItem): |
800 """ DocBook Document """ | 827 """ DocBook Document """ |
828 contenttype = 'application/docbook+xml' | |
829 | |
801 def _convert(self, doc): | 830 def _convert(self, doc): |
802 from emeraldtree import ElementTree as ET | 831 from emeraldtree import ElementTree as ET |
803 from MoinMoin.converter import default_registry as reg | 832 from MoinMoin.converter import default_registry as reg |
804 | 833 |
805 doc = self._expand_document(doc) | 834 doc = self._expand_document(doc) |
839 mimetype=content_type, | 868 mimetype=content_type, |
840 as_attachment=as_attachment, attachment_filename=None, | 869 as_attachment=as_attachment, attachment_filename=None, |
841 cache_timeout=10, # wiki data can change rapidly | 870 cache_timeout=10, # wiki data can change rapidly |
842 add_etags=False, etag=None, conditional=True) | 871 add_etags=False, etag=None, conditional=True) |
843 | 872 |
844 content_registry.register(DocBook._factory, Type('application/docbook+xml')) | |
845 | |
846 | 873 |
847 class Draw(TarMixin, Image): | 874 class Draw(TarMixin, Image): |
848 """ | 875 """ |
849 Base class for *Draw that use special Java/Javascript applets to modify and store data in a tar file. | 876 Base class for *Draw that use special Java/Javascript applets to modify and store data in a tar file. |
850 """ | 877 """ |
854 | 881 |
855 def handle_post(): | 882 def handle_post(): |
856 raise NotImplementedError | 883 raise NotImplementedError |
857 | 884 |
858 | 885 |
886 @register | |
859 class TWikiDraw(Draw): | 887 class TWikiDraw(Draw): |
860 """ | 888 """ |
861 drawings by TWikiDraw applet. It creates three files which are stored as tar file. | 889 drawings by TWikiDraw applet. It creates three files which are stored as tar file. |
862 """ | 890 """ |
891 contenttype = 'application/x-twikidraw' | |
863 | 892 |
864 class ModifyForm(Draw.ModifyForm): | 893 class ModifyForm(Draw.ModifyForm): |
865 template = "modify_twikidraw.html" | 894 template = "modify_twikidraw.html" |
866 help = "" | 895 help = "" |
867 | 896 |
914 | 943 |
915 return Markup(image_map + u'<img src="{0}" alt="{1}" usemap="#{2}" />'.format(png_url, title, mapid)) | 944 return Markup(image_map + u'<img src="{0}" alt="{1}" usemap="#{2}" />'.format(png_url, title, mapid)) |
916 else: | 945 else: |
917 return Markup(u'<img src="{0}" alt="{1}" />'.format(png_url, title)) | 946 return Markup(u'<img src="{0}" alt="{1}" />'.format(png_url, title)) |
918 | 947 |
919 content_registry.register(TWikiDraw._factory, Type('application/x-twikidraw')) | 948 |
920 | 949 @register |
921 | |
922 class AnyWikiDraw(Draw): | 950 class AnyWikiDraw(Draw): |
923 """ | 951 """ |
924 drawings by AnyWikiDraw applet. It creates three files which are stored as tar file. | 952 drawings by AnyWikiDraw applet. It creates three files which are stored as tar file. |
925 """ | 953 """ |
954 contenttype = 'application/x-anywikidraw' | |
926 | 955 |
927 class ModifyForm(Draw.ModifyForm): | 956 class ModifyForm(Draw.ModifyForm): |
928 template = "modify_anywikidraw.html" | 957 template = "modify_anywikidraw.html" |
929 help = "" | 958 help = "" |
930 def _load(self, item): | 959 def _load(self, item): |
983 title = _('Clickable drawing: %(filename)s', filename=self.name) | 1012 title = _('Clickable drawing: %(filename)s', filename=self.name) |
984 return Markup(image_map + u'<img src="{0}" alt="{1}" usemap="#{2}" />'.format(png_url, title, mapid)) | 1013 return Markup(image_map + u'<img src="{0}" alt="{1}" usemap="#{2}" />'.format(png_url, title, mapid)) |
985 else: | 1014 else: |
986 return Markup(u'<img src="{0}" alt="{1}" />'.format(png_url, title)) | 1015 return Markup(u'<img src="{0}" alt="{1}" />'.format(png_url, title)) |
987 | 1016 |
988 content_registry.register(AnyWikiDraw._factory, Type('application/x-anywikidraw')) | 1017 |
989 | 1018 @register |
990 | |
991 class SvgDraw(Draw): | 1019 class SvgDraw(Draw): |
992 """ drawings by svg-edit. It creates two files (svg, png) which are stored as tar file. """ | 1020 """ drawings by svg-edit. It creates two files (svg, png) which are stored as tar file. """ |
1021 contenttype = 'application/x-svgdraw' | |
993 | 1022 |
994 class ModifyForm(Draw.ModifyForm): | 1023 class ModifyForm(Draw.ModifyForm): |
995 template = "modify_svg-edit.html" | 1024 template = "modify_svg-edit.html" |
996 help = "" | 1025 help = "" |
997 | 1026 |
1014 # of items and also rendering them with the code in base class could work | 1043 # of items and also rendering them with the code in base class could work |
1015 item_name = self.name | 1044 item_name = self.name |
1016 drawing_url = url_for('frontend.get_item', item_name=item_name, member='drawing.svg', rev=self.rev.revid) | 1045 drawing_url = url_for('frontend.get_item', item_name=item_name, member='drawing.svg', rev=self.rev.revid) |
1017 png_url = url_for('frontend.get_item', item_name=item_name, member='drawing.png', rev=self.rev.revid) | 1046 png_url = url_for('frontend.get_item', item_name=item_name, member='drawing.png', rev=self.rev.revid) |
1018 return Markup(u'<img src="{0}" alt="{1}" />'.format(png_url, drawing_url)) | 1047 return Markup(u'<img src="{0}" alt="{1}" />'.format(png_url, drawing_url)) |
1019 | |
1020 content_registry.register(SvgDraw._factory, Type('application/x-svgdraw')) |