def uploadBlobField(self, clazz, file=b'', filename=''): try: file = file.read() except: pass f = None if isinstance(file,six.string_types): f = re.findall('^data:(.*?);base64,([\s\S]*)$',file) if f: mt = f[0][0] file = base64.b64decode(f[0][1]) else: mt, enc = standard.guess_content_type(filename,file) if clazz in [_globals.DT_IMAGE, 'image'] or mt.startswith('image'): clazz = MyImage elif clazz in [_globals.DT_FILE, 'file']: clazz = MyFile # blob = clazz( id='', title='', file='') blob = clazz( id='', title='', file=standard.pybytes('','utf-8')) blob.update_data(file, content_type=mt, size=len(file)) blob.aq_parent = self blob.mediadbfile = None blob.filename = standard.pystr(_fileutil.extractFilename( filename, undoable=True)) # Check size. if self is not None: maxlength_prop = 'ZMS.input.%s.maxlength'%['file','image'][isinstance(blob,MyImage)] maxlength = self.getConfProperty(maxlength_prop, '') if len(maxlength) > 0: size = blob.get_size() if size > int(maxlength): raise zExceptions.Forbidden('size=%i > %s=%i' %(size, maxlength_prop, int(maxlength))) return blob
def toXml(self, sender=None, base_path='', data2hex=True): """ Serialize this file to xml-string. @param sender: the sender-node @type sender: C{zmsobject.ZMSObject=None} @param base_path: the base-path @type base_path: C{str=''} @param data2hex: convert data inline to hex, otherwise saved to file in base-path @type data2hex: C{Bool=True} @return: the xml-string @rtype: C{str} """ data = '' objtype = '' filename = _fileutil.getOSPath(_fileutil.extractFilename(getattr(self, 'filename', ''))) content_type = getattr(self, 'content_type', '') if data2hex: if content_type.startswith('text/') or content_type in ['application/css','application/javascript','image/svg']: data = '<![CDATA[%s]]>'%standard.pystr(self.getData(sender),'utf-8') else: data = standard.bin2hex(standard.pybytes(self.getData(sender))) objtype = ' type="file"' else: filename = self.getFilename() filename = getLangFilename(sender, filename, self.lang) filename = '%s%s'%(base_path, filename) xml = '\n<data' xml += ' content_type="%s"'%content_type xml += ' filename="%s"'%filename xml += objtype + '>' + data xml += '</data>' return xml
def getLangStr(self, key, lang=None): """ Returns language-string for current content-language. """ lang_str = self._getLangStr(key, lang) if six.PY2: lang_str = standard.pybytes(lang_str, 'utf-8') return lang_str
def addFile(container, id, title, data, content_type=None): """ Add File to container. """ if content_type is None: if type(data) is str: data = standard.pybytes(data,'utf-8') content_type, enc = standard.guess_content_type(id, data) container.manage_addFile(id=id, title=title, file=data, content_type=content_type) ob = getattr( container, id) return ob
def createBlobField(self, objtype, file=b''): if standard.is_bytes(file): blob = uploadBlobField( self, objtype, file) elif isinstance(file, dict): data = file.get( 'data', '') if standard.is_str(data): data = standard.pybytes(data,'utf-8') data = standard.PyBytesIO( data) blob = uploadBlobField( self, objtype, data, file.get('filename', '')) if file.get('content_type'): blob.content_type = file.get('content_type') else: blob = uploadBlobField( self, objtype, file, file.filename) return blob
def validateInlineLinkObj(self, text): if not int(self.getConfProperty('ZReferableItem.validateLinkObj', 1)): return text text = standard.pybytes(text) for pq in [('<a(.*?)>', 'href'), ('<img(.*?)>', 'src')]: p = pq[0] q = pq[1] r = re.compile(p) for f in r.findall(text): d = dict(re.findall('\\s(.*?)="(.*?)"', f)) if 'data-id' in d: old = p.replace('(.*?)', f) url = d['data-id'] ild = getInternalLinkDict(self, url) for k in ild: d[{'data-url': q}.get(k, k)] = ild[k] new = p.replace( '(.*?)', ' '.join([''] + [ '%s="%s"' % (x, standard.pybytes(d[x])) for x in d ])) if old != new: text = text.replace(old, new) return text
def OnEndElement(self, sTagName): """ XmlAttrBuilder.OnEndElement """ # -- TAG-STACK tag = self.dTagStack.pop() name = standard.unencode(tag['name']) attrs = standard.unencode(tag['attrs']) cdata = standard.unencode(tag['cdata']) # Hack for nested CDATA cdata = re.compile(r'\<\!\{CDATA\{(.*?)\}\}\>').sub(r'<![CDATA[\1]]>',cdata) if name != sTagName: raise ParseError("Unmatching end tag (" + str(sTagName) + ") expected (" + str(name) + ")") # -- DATA if sTagName in ['data']: filename = attrs.get('filename') content_type = attrs.get('content_type') try: data = standard.hex2bin(cdata) except: data = standard.pybytes(cdata,'utf-8') file = {'data':data, 'filename':filename, 'content_type':content_type} objtype = attrs.get('type') item = _blobfields.createBlobField(None, objtype, file) for key in attrs: value = attrs.get(key) setattr(item, key, value) self.dValueStack.pop() self.dValueStack.append(item) # -- ITEM elif sTagName in ['item']: if tag['dValueStack'] < len(self.dValueStack): item = self.dValueStack.pop() else: item = cdata item = getXmlTypeSaveValue(item, attrs) value = self.dValueStack.pop() if isinstance(value, dict): key = attrs.get('key') value[key] = item if isinstance(value, list): value.append(item) self.dValueStack.append(value)
def manage_pasteObjs(self, REQUEST, RESPONSE=None): """ CopySupport.manage_pasteObjs """ id_prefix = REQUEST.get('id_prefix', 'e') standard.writeBlock(self, "[CopySupport.manage_pasteObjs]") t0 = time.time() # Analyze request cb_copy_data = self._get_cb_copy_data(cb_copy_data=None, REQUEST=REQUEST) op = cb_copy_data[0] cp = (op, cb_copy_data[1]) cp = _cb_encode(cp) ids = [self._get_id(x.getId()) for x in self._get_obs(cp)] oblist = self._get_obs(cp) # Paste objects. action = ['Copy', 'Move'][op == OP_MOVE] standard.triggerEvent(self, 'before%sObjsEvt' % action) self.manage_pasteObjects(cb_copy_data=None, REQUEST=REQUEST) standard.triggerEvent(self, 'after%sObjsEvt' % action) # Sort order (I). self._set_sort_ids(ids=ids, op=op, REQUEST=REQUEST) # Move objects. if op == OP_MOVE: normalize_ids_after_move(self, id_prefix=id_prefix, ids=ids) # Copy objects. else: normalize_ids_after_copy(self, id_prefix=id_prefix, ids=ids) # Sort order (II). self.normalizeSortIds() # Return with message. if RESPONSE is not None: message = standard.pybytes(self.getZMILangStr('MSG_PASTED')) message += ' (in ' + str(int( (time.time() - t0) * 100.0) / 100.0) + ' secs.)' RESPONSE.redirect('manage_main?lang=%s&manage_tabs_message=%s' % (REQUEST['lang'], standard.url_quote(message)))
def toXml(self, value, indentlevel=0, xhtml=False, encoding='utf-8'): xml = [] if value is not None: # Image if isinstance(value, _blobfields.MyImage): xml.append('\n' + indentlevel * INDENTSTR + value.toXml(self)) # File elif isinstance(value, _blobfields.MyFile): xml.append('\n' + indentlevel * INDENTSTR + value.toXml(self)) # File (Zope-native) elif isinstance(value, File): tagname = 'data' content_type = value.content_type xml.append('\n' + indentlevel * INDENTSTR) xml.append('<%s' % tagname) xml.append(' content_type="%s"' % content_type) xml.append(' filename="%s"' % value.title) xml.append(' type="file"') xml.append('>') data = zopeutil.readData(value) if content_type.startswith('text/') or content_type in ['application/css','application/javascript','image/svg']: try: data = standard.pystr(data,'utf-8') except: pass cdata = None # Ensure CDATA is valid. try: cdata = '<![CDATA[%s]]>'%data p = pyexpat.ParserCreate() rv = p.Parse('<?xml version="1.0" encoding="utf-8"?><%s>%s</%s>'%(tagname,cdata,tagname), 1) # Otherwise use binary encoding. except: cdata = standard.bin2hex(standard.pybytes(data)) xml.append(cdata) xml.append('</%s>' % tagname) # Dictionaries elif isinstance(value, dict): keys = sorted(value) xml.append('\n' + indentlevel * INDENTSTR) xml.append('<dictionary>') indentstr = '\n' + (indentlevel + 1) * INDENTSTR for x in keys: k = ' key="%s"' % x xv = value[x] tv = getXmlType(xv) sv = toXml(self, xv, indentlevel + 2, xhtml, encoding) xml.append(indentstr) xml.append('<item%s%s>' % (k, tv)) xml.append(sv) if sv.find('\n') >= 0: xml.append(indentstr) xml.append('</item>') xml.append('\n' + indentlevel * INDENTSTR) xml.append('</dictionary>') # Lists elif isinstance(value, list): xml.append('\n' + indentlevel * INDENTSTR) xml.append('<list>') indentstr = '\n' + (indentlevel + 1) * INDENTSTR for xv in value: k = '' tv = getXmlType(xv) sv = toXml(self, xv, indentlevel + 2, xhtml, encoding) xml.append(indentstr) xml.append('<item%s%s>' % (k, tv)) xml.append(sv) if sv.startswith('\n'): xml.append(indentstr) xml.append('</item>') xml.append('\n' + indentlevel * INDENTSTR) xml.append('</list>') # Tuples (DateTime) elif isinstance(value, tuple) or isinstance(value, time.struct_time) or isinstance(value, DateTime): try: s_value = self.getLangFmtDate(value, 'eng', 'DATETIME_FMT') if len(s_value) > 0: xml.append('\n' + indentlevel * INDENTSTR) xml.append(toCdata(self, s_value, -1)) except: pass # Numbers elif isinstance(value, int) or isinstance(value, float): xml.append(value) else: # Zope-Objects try: meta_type = value.meta_type except: meta_type = None if meta_type is not None: value = zopeutil.readData(value) if value: xml.append(toCdata(self, value, xhtml)) # Return xml. return ''.join([standard.pystr(x) for x in xml])
def xmlOnUnknownEndTag(self, sTagName): # -- TAG-STACK tag = self.dTagStack.pop() skip = len([x for x in self.oCurrNode.dTagStack if x.get('skip')]) > 0 name = standard.unencode(tag['name']) if name != sTagName: return 0 # don't accept any unknown tag attrs = standard.unencode(tag['attrs']) cdata = standard.unencode(tag['cdata']) # -- ITEM (DICTIONARY|LIST) -- #---------------------------- if sTagName in ['dict', 'dictionary']: pass elif sTagName == 'list': pass elif sTagName == 'item': item = cdata if tag['dValueStack'] < len(self.dValueStack): item = self.dValueStack.pop() else: item = cdata item = getXmlTypeSaveValue(item, attrs) value = self.dValueStack.pop() if isinstance(value, dict): key = attrs.get('key') value[key] = item if isinstance(value, list): value.append(item) self.dValueStack.append(value) # -- DATA (IMAGE|FILE) -- #----------------------- elif sTagName == 'data': value = attrs if cdata is not None and len(cdata) > 0: filename = attrs.get('filename') content_type = attrs.get('content_type') try: data = standard.hex2bin(cdata) except: data = standard.pybytes(cdata,'utf-8') value['data'] = data self.dValueStack.append(value) # -- LANGUAGE -- #-------------- elif sTagName == 'lang': lang = attrs.get('id', self.getPrimaryLanguage()) if len(self.dValueStack) == 1: item = cdata else: item = self.dValueStack.pop() values = self.dValueStack.pop() values[lang] = item self.dValueStack.append(values) # -- OBJECT-ATTRIBUTES -- #----------------------- elif sTagName in self.getObjAttrs(): if not skip: obj_attr = self.getObjAttr(sTagName) # -- DATATYPE datatype = obj_attr['datatype_key'] # -- Multi-Language Attributes. if obj_attr['multilang']: item = self.dValueStack.pop() if item is not None: if not isinstance(item, dict): item = {self.getPrimaryLanguage():item} for s_lang in item: value = item[s_lang] # Data if datatype in _globals.DT_BLOBS: if isinstance(value, dict) and len(value.keys()) > 0: ob = _blobfields.createBlobField(self, datatype) for key in value: setattr(ob, key, value[key]) xmlInitObjProperty(self, sTagName, ob, s_lang) # Others else: # -- Init Properties. xmlInitObjProperty(self, sTagName, value, s_lang) else: # -- Complex Attributes (Blob|Dictionary|List). value = None if len(self.dValueStack) > 0: value = self.dValueStack.pop() if value is not None and \ (datatype in _globals.DT_BLOBS or \ datatype == _globals.DT_LIST or \ datatype == _globals.DT_DICT): # Data if datatype in _globals.DT_BLOBS: if isinstance(value, dict) and len(value.keys()) > 0: ob = _blobfields.createBlobField(self, datatype) for key in value: setattr(ob, key, value[key]) xmlInitObjProperty(self, sTagName, ob) # Others else: if self.getType() == 'ZMSRecordSet': if isinstance(value, list): for item in value: if isinstance(item, dict): for key in item: item_obj_attr = self.getObjAttr(key) item_datatype = item_obj_attr['datatype_key'] if item_datatype in _globals.DT_BLOBS: item_data = item[ key] if isinstance(item_data, dict): blob = _blobfields.createBlobField(self, item_datatype, item_data) blob.on_setobjattr() item[ key] = blob # -- Convert multilingual to monolingual attributes. if obj_attr['multilang'] == 0 and \ isinstance(value, dict) and \ len(value.keys()) == 1 and \ value.keys()[0] == self.getPrimaryLanguage(): value = value[value.keys()[0]] xmlInitObjProperty(self, sTagName, value) if len(self.dValueStack) > 0: raise "Items on self.dValueStack=%s" % self.dValueStack # -- Simple Attributes (String, Integer, etc.) else: if value is not None: standard.writeBlock(self, "[xmlOnUnknownEndTag]: WARNING - Skip %s" % sTagName) value = cdata # -- OPTIONS if 'options' in obj_attr: options = obj_attr['options'] if isinstance(options, list): try: i = options.index(int(value)) if i % 2 == 1: value = options[i - 1] except: try: i = options.index(value) if i % 2 == 1: value = options[i - 1] except: pass xmlInitObjProperty(self, sTagName, value) # Clear value stack. self.dValueStack.clear() # -- OTHERS -- #------------ else: value = None if len(self.dTagStack): value = self.dTagStack.pop() if value is None: value = {'cdata':''} cdata = value.get('cdata', '') cdata += '<' + tag['name'] for attr_name in attrs: attr_value = attrs.get(attr_name) cdata += ' ' + attr_name + '="' + attr_value + '"' cdata += '>' + tag['cdata'] cdata += '</' + tag['name'] + '>' value['cdata'] = cdata self.dTagStack.append(value) return 1 # accept matching end tag
def __str__(self): return standard.pybytes(self.getData()) ################################################################################
def br_quote(text, subtag, REQUEST): if len(subtag) == 0: return text if standard.is_str(text): text = standard.pybytes(text) rtn = '' qcr = '' qtab = ' ' * 6 if standard.isManagementInterface(REQUEST): if 'format' not in REQUEST: qcr = '<span class="unicode">↵</span>' qtab = '<span class="unicode">→</span>' + ' ' * 5 if subtag == 'br': tmp = [] for s in text.split('<%s>' % subtag): while len(s) > 0 and ord(s[0]) in [10, 13]: s = s[1:] if len(tmp) > 0: tmp.append('\n') tmp.append(s) text = ''.join(tmp) # handle nested lists ts = text.split('\n') ll = [] c = 0 for line in ts: if line.find('\t* ') >= 0 or line.find('\t# ') >= 0: i = 0 while i < len(line) and line[i] == '\t': i += 1 if line[i] in ['*', '#']: level = i # open nested lists if level > len(ll): if line[i] == '*': rtn += '<ul>' * (level - len(ll)) ll.extend(['ul'] * (level - len(ll))) elif line[i] == '#': rtn += '<ol>' * (level - len(ll)) ll.extend(['ol'] * (level - len(ll))) # close nested lists elif level < len(ll): for li in range(len(ll) - level): rtn += '</%s>' % ll[-1] ll = ll[0:-1] rtn += '<li>%s</li>' % line[i + 2:] continue # close nested lists if len(ll) > 0: level = 0 for li in range(len(ll) - level): rtn += '</%s>' % ll[-1] ll = ll[0:-1] # handle leading whitespaces and tabs i = 0 while i < len(line) and line[i] in [' ', '\t']: if line[i] == ' ': rtn += ' ' elif line[i] == '\t': rtn += qtab i += 1 rtn += '\n' line = line[i:].strip() if subtag == 'br': rtn += line + qcr if c < len(ts): rtn += '<%s />' % subtag elif len(line) > 0: rtn += '<%s' % subtag rtn += '>' rtn += line + qcr rtn += '</%s>' % subtag c += 1 # close nested lists if len(ll) > 0: level = 0 for li in range(len(ll) - level): rtn += '</%s>' % ll[-1] ll = ll[0:-1] return rtn