def get_html_diff(self, oldVer, newVer): # --=mpj17=-- # The sequence of characters from the browser is in UTF-8. # (If it is not I will leap from this hell-hole of # electronics and punch you on the nose.) This has to be # decoded from UTF-8 (a sequence of bytes) into a Unicode # string (a great and wondrous thing). This string must # then be encoded into ASCII (a sequence of bytes), but # this time replacing the weird characters with XML # character entities. assert oldVer assert newVer ovt = [t.encode('ascii', 'xmlcharrefreplace') for t in to_unicode_or_bust(oldVer.content).split('\n')] d = self.get_version_description(oldVer) ovDesc = d.encode('ascii', 'xmlcharrefreplace') nvt = [t.encode('ascii', 'xmlcharrefreplace') for t in to_unicode_or_bust(newVer.content).split('\n')] d = self.get_version_description(newVer) nvDesc = d.encode('ascii', 'xmlcharrefreplace') htmlDiffer = difflib.HtmlDiff(tabsize=2) retval = htmlDiffer.make_table(ovt, nvt, ovDesc, nvDesc) assert retval return retval
def get_html_diff(self, oldVer, newVer): # --=mpj17=-- # The sequence of characters from the browser is in UTF-8. # (If it is not I will leap from this hell-hole of # electronics and punch you on the nose.) This has to be # decoded from UTF-8 (a sequence of bytes) into a Unicode # string (a great and wondrous thing). This string must # then be encoded into ASCII (a sequence of bytes), but # this time replacing the weird characters with XML # character entities. assert oldVer assert newVer ovt = [ t.encode('ascii', 'xmlcharrefreplace') for t in to_unicode_or_bust(oldVer.content).split('\n') ] d = self.get_version_description(oldVer) ovDesc = d.encode('ascii', 'xmlcharrefreplace') nvt = [ t.encode('ascii', 'xmlcharrefreplace') for t in to_unicode_or_bust(newVer.content).split('\n') ] d = self.get_version_description(newVer) nvDesc = d.encode('ascii', 'xmlcharrefreplace') htmlDiffer = difflib.HtmlDiff(tabsize=2) retval = htmlDiffer.make_table(ovt, nvt, ovDesc, nvDesc) assert retval return retval
def next(self): row = self.reader.next() retval = { to_unicode_or_bust(k): to_unicode_or_bust(v) for k, v in row.items() } return retval
def files_metadata(self, postId): """Retrieve the metadata of all files associated with a post :param str post_id: The identifier of a post :returns: The files for the post, or and empty list (``[]``) :rtype: list The dictionary representing the each file contains the following ================== ======== ============================= Key Type Note ================== ======== ============================= ``file_id`` str File identifier ``file_name`` Unicode File name ``date`` DateTime The date the file was created ``mime_type`` Unicode The MIME type of the file ``file_size`` int The size of the file in bytes ================== ======== ============================= """ ft = self.fileTable statement = ft.select() statement.append_whereclause(ft.c.post_id == postId) session = getSession() r = session.execute(statement) retval = [{ 'file_id': row['file_id'], 'file_name': to_unicode_or_bust(row['file_name']), 'date': row['date'], 'mime_type': to_unicode_or_bust(row['mime_type']), 'file_size': row['file_size'], } for row in r] return retval
def get_text_diff(oldVer, newVer): # Note we have to convert the text to Unicode, from UTF-8 ovt = to_unicode_or_bust(oldVer.content).split('\n') nvt = to_unicode_or_bust(newVer.content).split('\n') d = difflib.unified_diff(ovt, nvt, oldVer.id, newVer.id) retval = '\n'.join(d).encode('utf-8') # And convert it back to utf-8, so we can Base64 encode it. return retval
def get_text_diff(oldVer, newVer): # Note we have to convert the text to Unicode, from UTF-8 ovt = to_unicode_or_bust(oldVer.content).split('\n') nvt = to_unicode_or_bust(newVer.content).split('\n') d = difflib.unified_diff(ovt, nvt, oldVer.id, newVer.id) retval = '\n'.join(d).encode('utf-8') # And convert it back to utf-8, so we can Base64 encode it. return retval
def __unicode__(self): m = 'Notification "{0}" created for {1} ({2}) on {3} ({4})' retval = m.format(to_unicode_or_bust(self.instanceDatum), to_unicode_or_bust(self.userInfo.name), to_unicode_or_bust(self.userInfo.id), to_unicode_or_bust(self.siteInfo.name), to_unicode_or_bust(self.siteInfo.id)) assert type(retval) == unicode return retval
def create_term(g): n = u'{0}: {1}' name = n.format(to_unicode_or_bust(g.name), to_unicode_or_bust(g.get_property('description', ''))) retval = SimpleTerm(g.id, g.id, name) assert retval assert ITitledTokenizedTerm in providedBy(retval) assert retval.token == retval.value assert retval.token == g.id return retval
def create_term(g): n = u'{0}: {1}' name = n.format(to_unicode_or_bust(g.name), to_unicode_or_bust(g.get_property('description', ''))) retval = SimpleTerm(g.id, g.id, name) assert retval assert ITitledTokenizedTerm in providedBy(retval) assert retval.token == retval.value assert retval.token == g.id return retval
def event_id_from_data(userInfo, instanceUserInfo, siteInfo, code, instanceDatum, supplementaryDatum): iD = instanceDatum if instanceDatum else '' sD = supplementaryDatum if supplementaryDatum else '' e = '{}-{} {}-{} {}-{} {} {} {} {}'.format( to_unicode_or_bust(userInfo.name), userInfo.id, to_unicode_or_bust(instanceUserInfo.name), instanceUserInfo.id, to_unicode_or_bust(siteInfo.name), siteInfo.id, datetime.now(UTC), code, to_unicode_or_bust(iD), to_unicode_or_bust(sD)) r = e.encode(ascii, ignore) retval = to_id(r) return retval
def set_data(self, data): assert self.folder assert self.form_fields assert self.versionForChange assert self.auditor assert data nvId = new_version_id() while nvId in self.folder.objectIds(): nvId = new_version_id() newVersion = new_version(self.folder, nvId) fields = self.form_fields.omit('id', 'parentVersion', 'editor', 'creationDate') form.applyChanges(newVersion, fields, data) newVersion.parentVersion = to_ascii(self.versionForChange.id) userInfo = createObject('groupserver.LoggedInUser', self.folder) newVersion.editor = to_unicode_or_bust(userInfo.id) i, s = self.get_auditDatums(self.versionForChange, newVersion) self.auditor.info(EDIT_CONTENT, i, s) # Handle publishing here if data['published']: self.folder.published_revision = newVersion.id self.status = '%s %s' % \ ('Published' if data['published'] else 'Changed', data['title']) assert self.status
def from_header_from_address(self, address): '''Ensure we have a pretty address for the :mailheader:`From` header :param str address: The address. :returns: An email header, with the display-name and the email address ``address``. :rtype: str :raises ValueError: if a user cannot be found for the ``address`` If the ``address`` is supplied then it is assumed to be the address of a **user**, and the display name will be set to the name of the user. Otherwise the support email-address will be returned, with the display name set to ``${siteName} Support``.''' if address: name = '' u = self.context.acl_users.get_userByEmail(address) if u: userInfo = IGSUserInfo(u) name = userInfo.name retval = self.get_addr_line(name, address) else: msg = 'Cannot find a user for the address <{0}>'.format(address) raise ValueError(msg) else: # not(address) n = _('site-support', '${siteName} Support', mapping={'siteName': to_unicode_or_bust(self.siteInfo.name)}) name = translate(n) email = self.siteInfo.get_support_email() retval = self.get_addr_line(name, email) assert retval return retval
def get_content(self): # Zope Five cannot handle Unicode everywhere yet. So we # ensure that we hand back ASCII, with XML character # references replacing the Unicode characters. utext = self.dataTemplate() retval = to_unicode_or_bust(utext) return retval
def listTitle(self): '''The title of the list :returns: The title of the list :rtype: unicode The title of the list is defined as * The ``short_name`` of the group, or if that is not set + The ``shortName`` of the group, or if that is not set = The ``title`` of the mailing list, or if that is not set - The ``title`` of the group, or if that is not set o The ID of the group.''' t = (self.groupInfo.get_property('short_name', None) or self.groupInfo.get_property('shortName', None) or self.listInfo.mlist.getProperty('title', None) or self.groupInfo.get_property('title', None) or self.groupInfo.id) retval = to_unicode_or_bust(t) return retval
def get_content(self): # Zope Five cannot handle Unicode everywhere yet. So we # ensure that we hand back ASCII, with XML character # references replacing the Unicode characters. utext = self.dataTemplate() retval = to_unicode_or_bust(utext) return retval
def from_header_from_address(self, address): '''Ensure we have a pretty address for the :mailheader:`From` header :param str address: The address. :returns: An email header, with the display-name and the email address ``address``. :rtype: str :raises ValueError: if a user cannot be found for the ``address`` If the ``address`` is supplied then it is assumed to be the address of a **user**, and the display name will be set to the name of the user. Otherwise the support email-address will be returned, with the display name set to ``${siteName} Support``.''' if address: name = '' u = self.context.acl_users.get_userByEmail(address) if u: userInfo = IGSUserInfo(u) name = userInfo.name retval = self.get_addr_line(name, address) else: msg = 'Cannot find a user for the address <{0}>'.format( address) raise ValueError(msg) else: # not(address) n = _('site-support', '${siteName} Support', mapping={'siteName': to_unicode_or_bust(self.siteInfo.name)}) name = translate(n) email = self.siteInfo.get_support_email() retval = self.get_addr_line(name, email) assert retval return retval
def __call__(self, *args, **kw): '''Render the page, and then run it through :mod:`premailer` :param list args: The arguments to the page. :param dict kw: The keyword-arguments to the page. This method calls the __call__ of the super-class with the ``args`` and ``kw``. If the output is HTML it: * Turns the HTML ``<style>`` elements into ``style`` attributtes by calling :func:`premailer.transform`, and * Removes the unused HTML ``<style>`` elements. This allows the HTML to be rendered consistently in email-clients.''' orig = super(SiteEmail, self).__call__(*args, **kw) if orig[0] == '<': # --=mpj17=-- This is probabily markup, so tidy it some. premailer = Premailer( orig, preserve_internal_links=True, keep_style_tags=False, remove_classes=False, strip_important=False, disable_validation=True) premailed = premailer.transform() enlongened = self.fix_color_codes(premailed) retval = to_unicode_or_bust(enlongened) if retval[:9] != '<!DOCTYPE': retval = '<!DOCTYPE html>\n' + retval else: # --=mpj17=-- This is probabily plain-text, so just return it. retval = orig return retval
def set_data(self, data): assert self.folder assert self.form_fields assert self.versionForChange assert self.auditor assert data nvId = new_version_id() while nvId in self.folder.objectIds(): nvId = new_version_id() newVersion = new_version(self.folder, nvId) fields = self.form_fields.omit('id', 'parentVersion', 'editor', 'creationDate') form.applyChanges(newVersion, fields, data) newVersion.parentVersion = to_ascii(self.versionForChange.id) userInfo = createObject('groupserver.LoggedInUser', self.folder) newVersion.editor = to_unicode_or_bust(userInfo.id) i, s = self.get_auditDatums(self.versionForChange, newVersion) self.auditor.info(EDIT_CONTENT, i, s) # Handle publishing here if data['published']: self.folder.published_revision = newVersion.id self.status = '%s %s' % \ ('Published' if data['published'] else 'Changed', data['title']) assert self.status
def __init__(self, context, request): super(Change, self).__init__(context, request) enforce_schema(context, ISiteIntro) if type(context.introduction) == str: # If the introduction-text is a string then convert it to a Unicode object s = to_unicode_or_bust(context.introduction) context.introduction = s self.form_fields['introduction'].custom_widget = wym_editor_widget
def indexable_content(self, escape=True): """ Returns the content as bare as possible for indexing. Trim to 3kB -- this means we don't index the _whole_ document necessarily, but then we probably don't blow our DB out either. """ c = getattr(self.aq_explicit, 'content_type', '') converters = self.converters.get(c, (None, None)) if converters[0]: data, encoding = converters[0].convert(self.data) if encoding != 'UTF-8': data = to_unicode_or_bust(data) else: data = self.data[:5000] data = XWFUtils.convertTextToAscii(data) try: data = to_unicode_or_bust(data) except: data = u'' data = data[:3000] new_data = [] for word in data.split(): if len(word) > 15 or len(word) < 3: continue skip = False for letter in word: if letter not in string.letters: skip = True break if not skip: new_data.append(word) data = ' '.join(new_data) if escape: return cgi.escape(data) return data
def indexable_content(self, escape=True): """ Returns the content as bare as possible for indexing. Trim to 3kB -- this means we don't index the _whole_ document necessarily, but then we probably don't blow our DB out either. """ c = getattr(self.aq_explicit, 'content_type', '') converters = self.converters.get(c, (None, None)) if converters[0]: data, encoding = converters[0].convert(self.data) if encoding != 'UTF-8': data = to_unicode_or_bust(data) else: data = self.data[:5000] data = XWFUtils.convertTextToAscii(data) try: data = to_unicode_or_bust(data) except: data = u'' data = data[:3000] new_data = [] for word in data.split(): if len(word) > 15 or len(word) < 3: continue skip = False for letter in word: if letter not in string.letters: skip = True break if not skip: new_data.append(word) data = ' '.join(new_data) if escape: return cgi.escape(data) return data
def get_property(self, prop, default=None): if self.siteObj is None: m = 'Site instance does not exist:\n Context {0}\n ID {1}' msg = m.format(self.context, self.id) raise ValueError(msg) retval = self.siteObj.getProperty(prop, default) if isinstance(retval, str): retval = to_unicode_or_bust(retval) return retval
def get_property(self, prop, default=None): if self.siteObj is None: m = 'Site instance does not exist:\n Context {0}\n ID {1}' msg = m.format(self.context, self.id) raise ValueError(msg) retval = self.siteObj.getProperty(prop, default) if isinstance(retval, str): retval = to_unicode_or_bust(retval) return retval
def groupInfo_to_anchor(groupInfo): if not groupInfo: raise ValueError('groupInfo required') if groupInfo.group_exists(): retval = '<a href="{gi.url}" class="group">{gi.url}</a>'.format(gi=groupInfo) else: retval = to_unicode_or_bust(groupInfo.groupId) if not retval: retval = '{Unknown group}' return retval
def handle_set(self, action, data): if self.requestCount > self.request24hrlimit: self.status = _('request-quota-hit', 'The request for contact has not been sent because you ' 'have exceeded your daily limit of contact requests.') else: message = to_unicode_or_bust(data.get('message', '')) self.audit(message) self.request_contact(message) self.status = _('request-success', 'Your request has been sent to ${name}.', mapping={'name': self.userInfo.name})
def modify_header(self, *args): '''Generate the content for the :mailheader:`Sender` header. :returns: The *mailbox* of the group (a display-name and an angle-address). :rtype: str''' name = to_unicode_or_bust(self.groupInfo.name) h = Header(name, UTF8) headerName = h.encode() addr = self.listInfo.get_property('mailto') retval = formataddr((headerName, addr)) return retval
def groupInfo_to_anchor(groupInfo): if not groupInfo: raise ValueError('groupInfo required') if groupInfo.group_exists(): retval = '<a href="{gi.url}" class="group">{gi.url}</a>'.format( gi=groupInfo) else: retval = to_unicode_or_bust(groupInfo.groupId) if not retval: retval = '{Unknown group}' return retval
def update_data(self, data, content_type, size): """ """ if not data: # still index self.index_object() return passed, virus_name = DataVirusCheckAdapter(data).process() if not passed: log.warn('found virus %s, rejecting file' % virus_name) raise XWFFileError('found virus %s, rejecting file' % virus_name) # this isn't necessarily an error, on init we get called without data base_files_dir = self._base_files_dir self.size = size self.set_modificationTime() if base_files_dir: fileId = os.path.join(base_files_dir, self.getId()) f = file(fileId, 'wb+') if hasattr(data, '__class__') and data.__class__ is Pdata: while data is not None: f.write(data.data) data = data.next else: f.write(data) f.close() # fix the title title = to_unicode_or_bust(self.title) title = removePathsFromFilenames(title) self.title = title if content_type is not None: self.content_type = content_type else: mtypes = MimeTypes() mime_type = mtypes.guess_type(title) if mime_type: self.content_type = mime_type self.ZCacheable_invalidate() self.ZCacheable_set(None) self.http__refreshEtag() # index ourselves into the catalog self.index_object()
def update_data(self, data, content_type, size): """ """ if not data: # still index self.index_object() return passed, virus_name = DataVirusCheckAdapter(data).process() if not passed: log.warn('found virus %s, rejecting file' % virus_name) raise XWFFileError('found virus %s, rejecting file' % virus_name) # this isn't necessarily an error, on init we get called without data base_files_dir = self._base_files_dir self.size = size self.set_modificationTime() if base_files_dir: fileId = os.path.join(base_files_dir, self.getId()) f = file(fileId, 'wb+') if hasattr(data, '__class__') and data.__class__ is Pdata: while data is not None: f.write(data.data) data = data.next else: f.write(data) f.close() # fix the title title = to_unicode_or_bust(self.title) title = removePathsFromFilenames(title) self.title = title if content_type is not None: self.content_type = content_type else: mtypes = MimeTypes() mime_type = mtypes.guess_type(title) if mime_type: self.content_type = mime_type self.ZCacheable_invalidate() self.ZCacheable_set(None) self.http__refreshEtag() # index ourselves into the catalog self.index_object()
def modify_header(self, *args): '''Generate the content for the :mailheader:`List-Subscribe` header. :returns: A ``mailto`` URL with the group-address and the :mailheader:`Subject` set to ``Subscribe``. :rtype: unicode''' name = to_unicode_or_bust(self.groupInfo.name) desc = 'Join {0}'.format(name) emailAddr = self.listInfo.get_property('mailto') addr = 'mailto:{0}?subject=Subscribe'.format(emailAddr) retval = formataddr((desc, addr)) return retval
def get_addr_line(name, addr): '''Get the address line :param str name: The display-name in the address. :param str addr: The actual email address. :returns: A correctly formatted mail header. :rtype: str''' # --=mpj17=-- In Python 3 just using formataddr, sans the Header, # will work. This method should be removed. unicodeName = to_unicode_or_bust(name) headerName = Header(unicodeName, UTF8) encodedName = headerName.encode() retval = formataddr((encodedName, addr)) return retval
def get_addr_line(name, addr): '''Get the address line :param str name: The display-name in the address. :param str addr: The actual email address. :returns: A correctly formatted mail header. :rtype: str''' # --=mpj17=-- In Python 3 just using formataddr, sans the Header, # will work. This method should be removed. unicodeName = to_unicode_or_bust(name) headerName = Header(unicodeName, UTF8) encodedName = headerName.encode() retval = formataddr((encodedName, addr)) return retval
def files_metadata(self, post_id): """ Retrieve the metadata of all files associated with this post. Returns: [{'file_id': ID, 'mime_type': String, 'file_name': String, 'file_size': Int}] or []""" ft = self.fileTable statement = ft.select() statement.append_whereclause(ft.c.post_id == post_id) session = getSession() r = session.execute(statement) retval = [] if r.rowcount: retval = [{ 'file_id': row['file_id'], 'file_name': to_unicode_or_bust(row['file_name']), 'date': row['date'], 'mime_type': to_unicode_or_bust(row['mime_type']), 'file_size': row['file_size'] } for row in r] return retval
def __unicode__(self): r = 'Message of {0} characters being sent to the address <{1}> of '\ '{2} ({3}) on {4} ({5})' retval = r.format(to_unicode_or_bust(self.instanceDatum), to_unicode_or_bust(self.supplementaryDatum), to_unicode_or_bust(self.userInfo.name), to_unicode_or_bust(self.userInfo.id), to_unicode_or_bust(self.siteInfo.name), to_unicode_or_bust(self.siteInfo.id)) assert type(retval) == unicode return retval
def info(self, code, adminInfo, groupInfo=None, instanceDatum='', supplementaryDatum=''): d = now() eventId = to_id(to_unicode_or_bust(adminInfo.id) + unicode(d) + unicode(SystemRandom().randint(0, 1024)) + to_unicode_or_bust(adminInfo.name) + to_unicode_or_bust(self.siteInfo.id) + to_unicode_or_bust(self.siteInfo.name) + to_unicode_or_bust(code) + to_unicode_or_bust(instanceDatum) + to_unicode_or_bust(supplementaryDatum)) e = self.factory(self.context, eventId, code, d, adminInfo, None, self.siteInfo, groupInfo, instanceDatum, supplementaryDatum, SUBSYSTEM) self.queries.store(e) log.info(e)
def topic_search_keyword(self, searchTokens, site_id, group_ids=None, limit=12, offset=0, use_cache=True, hidden=False): """ Search for the search text in the content and subject-lines of topics.""" if group_ids is None: group_ids = [] tt = self.topicTable tkt = self.topicKeywordsTable pt = self.postTable cols = [tt.c.topic_id, tt.c.last_post_id, tt.c.first_post_id, tt.c.group_id, tt.c.site_id, tkt.c.keywords, tt.c.original_subject, tt.c.last_post_date, tt.c.num_posts, sa.select([pt.c.user_id], tt.c.last_post_id == pt.c.post_id).as_scalar().label('user_id')] statement = sa.select(cols, limit=limit, offset=offset, order_by=sa.desc(tt.c.last_post_date)) statement.append_whereclause(tkt.c.topic_id == tt.c.topic_id) statement = self.add_standard_where_clauses(statement, self.topicTable, site_id, group_ids, False) statement = self.__add_topic_keyword_search_where_clauses(statement, searchTokens) session = getSession() r = session.execute(statement) retval = [] for x in r: retval.append({'topic_id': x['topic_id'], 'last_post_id': x['last_post_id'], 'first_post_id': x['first_post_id'], 'group_id': x['group_id'], 'site_id': x['site_id'], 'subject': x['original_subject'], 'keywords': [to_unicode_or_bust(k) for k in x['keywords']], 'last_post_date': x['last_post_date'], 'last_post_user_id': x['user_id'], 'num_posts': x['num_posts']}) return retval
def name(self): r = self.get_name() retval = to_unicode_or_bust(r) return retval
def name(self): r = self.get_name() retval = to_unicode_or_bust(r) return retval
def next(self): row = self.reader.next() retval = {to_unicode_or_bust(k): to_unicode_or_bust(v) for k, v in row.items()} return retval
def get_site_term(self, siteId): site = getattr(self.content, siteId) siteInfo = createObject('groupserver.SiteInfo', site) retval = SimpleTerm(siteInfo, siteInfo.id, to_unicode_or_bust(siteInfo.name)) return retval
def test_utf8_to_unicode(self): testText = b'Word association football \342\232\275' r = to_unicode_or_bust(testText) self.assertEqual('Word association football \u26BD', r)
def test_ascii_to_unicode(self): testText = b'Word association football' r = to_unicode_or_bust(testText) self.assertEqual('Word association football', r)
def test_unicode_to_unicode(self): testText = 'Word association football \u26BD' r = to_unicode_or_bust(testText) self.assertEqual(type(testText), type(r))
def test_utf8_to_unicode(self): testText = b'Word association football \342\232\275' r = to_unicode_or_bust(testText) self.assertEqual('Word association football \u26BD', r)
def test_ascii_to_unicode(self): testText = b'Word association football' r = to_unicode_or_bust(testText) self.assertEqual('Word association football', r)
def test_unicode_to_unicode(self): testText = 'Word association football \u26BD' r = to_unicode_or_bust(testText) self.assertEqual(type(testText), type(r))
def _encryptPassword(self, pw): # we need to override the default, because if we encrypt with SSHA # we have trouble when we do the wire protocol upw = to_unicode_or_bust(pw) utf8pw = upw.encode('utf-8', 'ignore') return AuthEncoding.pw_encrypt(utf8pw, 'SHA')
def set_content(self, data): IGSContentPageVersion['content'].bind(self).validate(data) d = to_unicode_or_bust(data) self.dataTemplate.write(d)
def _encryptPassword(self, pw): # we need to override the default, because if we encrypt with SSHA # we have trouble when we do the wire protocol upw = to_unicode_or_bust(pw) utf8pw = upw.encode('utf-8', 'ignore') return AuthEncoding.pw_encrypt(utf8pw, 'SHA')
def __init__(self, message): self.originalMessage = to_unicode_or_bust(message)
def set_search_text(self, t): s = to_unicode_or_bust(t) if not isinstance(s, unicode): s = '' self.searchText = s
def get_site_term(self, siteId): site = getattr(self.content, siteId) siteInfo = createObject('groupserver.SiteInfo', site) retval = SimpleTerm(siteInfo, siteInfo.id, to_unicode_or_bust(siteInfo.name)) return retval
def indexable_summary(self): """ Return a summary for indexing in the catalog. """ description = to_unicode_or_bust(self.getProperty('description', u'')) return description
def set_content(self, data): IGSContentPageVersion['content'].bind(self).validate(data) d = to_unicode_or_bust(data) self.dataTemplate.write(d)
def title(self): retval = self.config.getProperty('siteTitle', self.name) if isinstance(retval, str): retval = to_unicode_or_bust(retval) return retval