comparison MoinMoin/items/content.py @ 1900:d4a382f781c9

deduplicated and refactored drawing item code moved image map reading and data rendering for png with optional map to a common base class post handling was almost identical code for AWD and TWD, moved to common base class removed some unused variables, some minor cleanups (this all is a preparation for transforming this code into a dom converter)
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Mon, 24 Dec 2012 03:45:30 +0100
parents 2b4bcb80d644
children 77d7c15299c9
comparison
equal deleted inserted replaced
1899:f38a893334b5 1900:d4a382f781c9
1026 1026
1027 def handle_post(self): 1027 def handle_post(self):
1028 raise NotImplementedError 1028 raise NotImplementedError
1029 1029
1030 1030
1031 @register 1031 class DrawPNGMap(Draw):
1032 class TWikiDraw(Draw): 1032 """
1033 """ 1033 Base class for drawings that have a png with click map
1034 drawings by TWikiDraw applet. It creates three files which are stored as tar file. 1034 """
1035 """ 1035 def _read_map(self):
1036 contenttype = 'application/x-twikidraw'
1037 display_name = 'TDRAW'
1038
1039 class ModifyForm(Draw.ModifyForm):
1040 template = "modify_twikidraw.html"
1041 help = ""
1042
1043 def handle_post(self):
1044 # called from modify UI/POST
1045 file_upload = request.files.get('filepath')
1046 filename = request.form['filename']
1047 basepath, basename = os.path.split(filename)
1048 basename, ext = os.path.splitext(basename)
1049
1050 filecontent = file_upload.stream
1051 content_length = None
1052 if ext == '.draw': # TWikiDraw POSTs this first
1053 filecontent = filecontent.read() # read file completely into memory
1054 filecontent = filecontent.replace("\r", "")
1055 elif ext == '.map':
1056 filecontent = filecontent.read() # read file completely into memory
1057 filecontent = filecontent.strip()
1058 elif ext == '.png':
1059 #content_length = file_upload.content_length
1060 # XXX gives -1 for wsgiref, gives 0 for werkzeug :(
1061 # If this is fixed, we could use the file obj, without reading it into memory completely:
1062 filecontent = filecontent.read()
1063
1064 self.put_member('drawing' + ext, filecontent, content_length,
1065 expected_members=set(['drawing.draw', 'drawing.map', 'drawing.png']))
1066
1067 def _render_data(self):
1068 # TODO: this could be a converter -> dom, then transcluding this kind
1069 # of items and also rendering them with the code in base class could work
1070 item_name = self.name
1071 drawing_url = url_for('frontend.get_item', item_name=item_name, member='drawing.draw', rev=self.rev.revid)
1072 png_url = url_for('frontend.get_item', item_name=item_name, member='drawing.png', rev=self.rev.revid)
1073 title = _('Edit drawing %(filename)s (opens in new window)', filename=item_name)
1074
1075 mapfile = self.get_member('drawing.map') 1036 mapfile = self.get_member('drawing.map')
1076 try: 1037 try:
1077 image_map = mapfile.read() 1038 image_map = mapfile.read()
1078 mapfile.close() 1039 mapfile.close()
1079 except (IOError, OSError): 1040 except (IOError, OSError):
1080 image_map = '' 1041 image_map = ''
1042 return image_map
1043
1044 def _transform_map(self, image_map, title):
1045 raise NotImplementedError
1046
1047 def _render_data(self):
1048 # TODO: this could be a converter -> dom, then transcluding this kind
1049 # of items and also rendering them with the code in base class could work
1050 png_url = url_for('frontend.get_item', item_name=self.name, member='drawing.png', rev=self.rev.revid)
1051 title = _('Edit drawing %(filename)s (opens in new window)', filename=self.name)
1052 image_map = self._read_map()
1081 if image_map: 1053 if image_map:
1082 # we have a image map. inline it and add a map ref to the img tag 1054 mapid, image_map = self._transform_map(image_map, title)
1083 mapid = 'ImageMapOf' + item_name 1055 title = _('Clickable drawing: %(filename)s', filename=self.name)
1084 image_map = image_map.replace('%MAPNAME%', mapid)
1085 # add alt and title tags to areas
1086 image_map = re.sub(r'href\s*=\s*"((?!%TWIKIDRAW%).+?)"', r'href="\1" alt="\1" title="\1"', image_map)
1087 image_map = image_map.replace('%TWIKIDRAW%"', '{0}" alt="{1}" title="{2}"'.format((drawing_url, title, title)))
1088 title = _('Clickable drawing: %(filename)s', filename=item_name)
1089
1090 return Markup(image_map + u'<img src="{0}" alt="{1}" usemap="#{2}" />'.format(png_url, title, mapid)) 1056 return Markup(image_map + u'<img src="{0}" alt="{1}" usemap="#{2}" />'.format(png_url, title, mapid))
1091 else: 1057 else:
1092 return Markup(u'<img src="{0}" alt="{1}" />'.format(png_url, title)) 1058 return Markup(u'<img src="{0}" alt="{1}" />'.format(png_url, title))
1093 1059
1094 1060
1095 @register 1061 class DrawAWDTWDBase(DrawPNGMap):
1096 class AnyWikiDraw(Draw): 1062 """
1097 """ 1063 Shared code between TWikiDraw and AnyWikiDraw
1098 drawings by AnyWikiDraw applet. It creates three files which are stored as tar file. 1064 """
1099 """ 1065 _expected_members = set()
1100 contenttype = 'application/x-anywikidraw'
1101 display_name = 'ADRAW'
1102
1103 class ModifyForm(Draw.ModifyForm):
1104 template = "modify_anywikidraw.html"
1105 help = ""
1106 def _load(self, item):
1107 super(AnyWikiDraw.ModifyForm, self)._load(item)
1108 try:
1109 drawing_exists = 'drawing.svg' in item.list_members()
1110 except tarfile.TarError: # item doesn't exist yet
1111 drawing_exists = False
1112 self.drawing_exists = drawing_exists
1113 1066
1114 def handle_post(self): 1067 def handle_post(self):
1115 # called from modify UI/POST 1068 # called from modify UI/POST
1116 file_upload = request.files.get('filepath') 1069 file_upload = request.files.get('filepath')
1117 filename = request.form['filename'] 1070 filename = request.form['filename']
1118 basepath, basename = os.path.split(filename) 1071 basepath, basename = os.path.split(filename)
1119 basename, ext = os.path.splitext(basename) 1072 basename, ext = os.path.splitext(basename)
1120 filecontent = file_upload.stream 1073 filecontent = file_upload.stream
1121 content_length = None 1074 content_length = None
1122 if ext == '.svg': 1075 if ext in ['.svg', '.draw', ]: # handle AWD (svg) and TWD (draw)
1123 filecontent = filecontent.read() # read file completely into memory 1076 filecontent = filecontent.read() # read file completely into memory
1124 filecontent = filecontent.replace("\r", "") 1077 filecontent = filecontent.replace("\r", "")
1125 elif ext == '.map': 1078 elif ext == '.map':
1126 filecontent = filecontent.read() # read file completely into memory 1079 filecontent = filecontent.read() # read file completely into memory
1127 filecontent = filecontent.strip() 1080 filecontent = filecontent.strip()
1129 #content_length = file_upload.content_length 1082 #content_length = file_upload.content_length
1130 # XXX gives -1 for wsgiref, gives 0 for werkzeug :( 1083 # XXX gives -1 for wsgiref, gives 0 for werkzeug :(
1131 # If this is fixed, we could use the file obj, without reading it into memory completely: 1084 # If this is fixed, we could use the file obj, without reading it into memory completely:
1132 filecontent = filecontent.read() 1085 filecontent = filecontent.read()
1133 self.put_member('drawing' + ext, filecontent, content_length, 1086 self.put_member('drawing' + ext, filecontent, content_length,
1134 expected_members=set(['drawing.svg', 'drawing.map', 'drawing.png'])) 1087 expected_members=self._expected_members)
1135 1088
1136 def _render_data(self): 1089
1137 # TODO: this could be a converter -> dom, then transcluding this kind 1090 @register
1138 # of items and also rendering them with the code in base class could work 1091 class TWikiDraw(DrawAWDTWDBase):
1139 item_name = self.name 1092 """
1140 drawing_url = url_for('frontend.get_item', item_name=item_name, member='drawing.svg', rev=self.rev.revid) 1093 drawings by TWikiDraw applet. It creates three files which are stored as tar file.
1141 png_url = url_for('frontend.get_item', item_name=item_name, member='drawing.png', rev=self.rev.revid) 1094 """
1142 title = _('Edit drawing %(filename)s (opens in new window)', filename=self.name) 1095 contenttype = 'application/x-twikidraw'
1143 1096 display_name = 'TDRAW'
1144 mapfile = self.get_member('drawing.map') 1097 _expected_members = set(['drawing.draw', 'drawing.map', 'drawing.png'])
1145 try: 1098
1146 image_map = mapfile.read() 1099 class ModifyForm(Draw.ModifyForm):
1147 mapfile.close() 1100 template = "modify_twikidraw.html"
1148 except (IOError, OSError): 1101 help = ""
1149 image_map = '' 1102
1150 if image_map: 1103 def _transform_map(self, image_map, title):
1151 # ToDo mapid must become uniq 1104 mapid = 'ImageMapOf' + self.name # TODO: make it unique
1152 # we have a image map. inline it and add a map ref to the img tag 1105 image_map = image_map.replace('%MAPNAME%', mapid)
1153 # we have also to set a unique ID 1106 # add alt and title tags to areas
1154 mapid = 'ImageMapOf' + self.name 1107 image_map = re.sub(r'href\s*=\s*"((?!%TWIKIDRAW%).+?)"',
1155 image_map = image_map.replace(u'id="drawing.svg"', '') 1108 r'href="\1" alt="\1" title="\1"', image_map)
1156 image_map = image_map.replace(u'name="drawing.svg"', u'name="{0}"'.format(mapid)) 1109 drawing_url = url_for('frontend.get_item', item_name=self.name, member='drawing.draw', rev=self.rev.revid)
1157 # unxml, because 4.01 concrete will not validate /> 1110 image_map = image_map.replace('%TWIKIDRAW%"', '{0}" alt="{1}" title="{2}"'.format(drawing_url, title, title))
1158 image_map = image_map.replace(u'/>', u'>') 1111 return mapid, image_map
1159 title = _('Clickable drawing: %(filename)s', filename=self.name) 1112
1160 return Markup(image_map + u'<img src="{0}" alt="{1}" usemap="#{2}" />'.format(png_url, title, mapid)) 1113
1161 else: 1114 @register
1162 return Markup(u'<img src="{0}" alt="{1}" />'.format(png_url, title)) 1115 class AnyWikiDraw(DrawAWDTWDBase):
1116 """
1117 drawings by AnyWikiDraw applet. It creates three files which are stored as tar file.
1118 """
1119 contenttype = 'application/x-anywikidraw'
1120 display_name = 'ADRAW'
1121 _expected_members = set(['drawing.svg', 'drawing.map', 'drawing.png'])
1122
1123 class ModifyForm(Draw.ModifyForm):
1124 template = "modify_anywikidraw.html"
1125 help = ""
1126 def _load(self, item):
1127 super(AnyWikiDraw.ModifyForm, self)._load(item)
1128 try:
1129 drawing_exists = 'drawing.svg' in item.list_members()
1130 except tarfile.TarError: # item doesn't exist yet
1131 drawing_exists = False
1132 self.drawing_exists = drawing_exists
1133
1134 def _transform_map(self, image_map, title):
1135 #drawing_url = url_for('frontend.get_item', item_name=self.name, member='drawing.svg', rev=self.rev.revid)
1136 mapid = 'ImageMapOf' + self.name # TODO: make it unique
1137 image_map = image_map.replace(u'id="drawing.svg"', '')
1138 image_map = image_map.replace(u'name="drawing.svg"', u'name="{0}"'.format(mapid))
1139 # unxml, because 4.01 concrete will not validate />
1140 image_map = image_map.replace(u'/>', u'>')
1141 return mapid, image_map
1163 1142
1164 1143
1165 @register 1144 @register
1166 class SvgDraw(Draw): 1145 class SvgDraw(Draw):
1167 """ drawings by svg-edit. It creates two files (svg, png) which are stored as tar file. """ 1146 """ drawings by svg-edit. It creates two files (svg, png) which are stored as tar file. """
1174 1153
1175 def handle_post(self): 1154 def handle_post(self):
1176 # called from modify UI/POST 1155 # called from modify UI/POST
1177 png_upload = request.values.get('png_data') 1156 png_upload = request.values.get('png_data')
1178 svg_upload = request.values.get('filepath') 1157 svg_upload = request.values.get('filepath')
1179 filename = request.form['filename']
1180 png_content = png_upload.decode('base_64') 1158 png_content = png_upload.decode('base_64')
1181 png_content = base64.urlsafe_b64decode(png_content.split(',')[1]) 1159 png_content = base64.urlsafe_b64decode(png_content.split(',')[1])
1182 svg_content = svg_upload.decode('base_64') 1160 svg_content = svg_upload.decode('base_64')
1183 content_length = None 1161 content_length = None
1184 self.put_member("drawing.svg", svg_content, content_length, 1162 self.put_member("drawing.svg", svg_content, content_length,
1187 expected_members=set(['drawing.svg', 'drawing.png'])) 1165 expected_members=set(['drawing.svg', 'drawing.png']))
1188 1166
1189 def _render_data(self): 1167 def _render_data(self):
1190 # TODO: this could be a converter -> dom, then transcluding this kind 1168 # TODO: this could be a converter -> dom, then transcluding this kind
1191 # of items and also rendering them with the code in base class could work 1169 # of items and also rendering them with the code in base class could work
1192 item_name = self.name 1170 drawing_url = url_for('frontend.get_item', item_name=self.name, member='drawing.svg', rev=self.rev.revid)
1193 drawing_url = url_for('frontend.get_item', item_name=item_name, member='drawing.svg', rev=self.rev.revid) 1171 png_url = url_for('frontend.get_item', item_name=self.name, member='drawing.png', rev=self.rev.revid)
1194 png_url = url_for('frontend.get_item', item_name=item_name, member='drawing.png', rev=self.rev.revid)
1195 return Markup(u'<img src="{0}" alt="{1}" />'.format(png_url, drawing_url)) 1172 return Markup(u'<img src="{0}" alt="{1}" />'.format(png_url, drawing_url))