def comment_transform_message(self): """Returns the description that shows up above the comment text, dependent on the text_transform setting and the comment moderation workflow in the discussion control panel. """ context = aq_inner(self.context) registry = queryUtility(IRegistry) settings = registry.forInterface(IDiscussionSettings, check=False) # text transform setting if settings.text_transform == 'text/x-web-intelligent': message = translate(Message(COMMENT_DESCRIPTION_INTELLIGENT_TEXT), context=self.request) elif settings.text_transform == 'text/x-web-markdown': message = translate(Message(COMMENT_DESCRIPTION_MARKDOWN), context=self.request) else: message = translate(Message(COMMENT_DESCRIPTION_PLAIN_TEXT), context=self.request) # comment workflow wftool = getToolByName(context, 'portal_workflow', None) workflow_chain = wftool.getChainForPortalType('Discussion Item') if workflow_chain: comment_workflow = workflow_chain[0] comment_workflow = wftool[comment_workflow] # check if the current workflow implements a pending state. If this # is true comments are moderated if 'pending' in comment_workflow.states: message = message + ' ' + \ translate(Message(COMMENT_DESCRIPTION_MODERATION_ENABLED), context=self.request) return message
def Title(self): # The title of the comment. if self.title: return self.title if not self.author_name: author_name = translate( Message(_( u'label_anonymous', default=u'Anonymous', ), ), ) else: author_name = self.author_name # Fetch the content object (the parent of the comment is the # conversation, the parent of the conversation is the content object). content = aq_base(self.__parent__.__parent__) title = translate( Message(COMMENT_TITLE, mapping={ 'author_name': safe_unicode(author_name), 'content': safe_unicode(content.Title()) })) return title
def elementToValue(field, element, default=_marker): """Read the contents of an element that is assumed to represent a value allowable by the given field. If converter is given, it should be an IToUnicode instance. If not, the field will be adapted to this interface to obtain a converter. """ value = default if IDict.providedBy(field): key_converter = IFromUnicode(field.key_type) value = OrderedDict() for child in element.iterchildren(tag=etree.Element): if noNS(child.tag.lower()) != 'element': continue parseinfo.stack.append(child) key_text = child.attrib.get('key', None) if key_text is None: k = None else: k = key_converter.fromUnicode(unicode(key_text)) value[k] = elementToValue(field.value_type, child) parseinfo.stack.pop() value = fieldTypecast(field, value) elif ICollection.providedBy(field): value = [] for child in element.iterchildren(tag=etree.Element): if noNS(child.tag.lower()) != 'element': continue parseinfo.stack.append(child) v = elementToValue(field.value_type, child) value.append(v) parseinfo.stack.pop() value = fieldTypecast(field, value) # Unicode else: text = element.text if text is None: value = field.missing_value else: converter = IFromUnicode(field) value = converter.fromUnicode(unicode(text)) # handle i18n if isinstance(value, unicode) and parseinfo.i18n_domain is not None: translate_attr = ns('translate', I18N_NAMESPACE) domain_attr = ns('domain', I18N_NAMESPACE) msgid = element.attrib.get(translate_attr) domain = element.attrib.get(domain_attr, parseinfo.i18n_domain) if msgid: value = Message(msgid, domain=domain, default=value) elif translate_attr in element.attrib: value = Message(value, domain=domain) return value
def Title(self): if self.title and self.i18n_domain: try: return Message(self.title.decode('utf8'), self.i18n_domain) except UnicodeDecodeError: return Message(self.title.decode('latin-1'), self.i18n_domain) else: return self.title or self.getId()
def Description(self): if self.description and self.i18n_domain: try: return Message(self.description.decode('utf8'), self.i18n_domain) except UnicodeDecodeError: return Message(self.description.decode('latin-1'), self.i18n_domain) else: return self.description
def __call__(self, context): context = getattr(context, 'context', context) ltool = getToolByName(context, 'portal_languages') supported = dict(ltool.listSupportedLanguages()) translated = context.getTranslationLanguages() # List all languages not already translated languages = [lang for lang in supported if lang not in translated] items = [(l, supported[l]) for l in languages] items.sort(key=sort_key) items = [SimpleTerm(i[0], i[0], i[1].decode('utf-8')) for i in items] if self.incl_neutral: neutral = SimpleTerm( "neutral", "neutral", _("label_neutral", default=u"Neutral"), ) items.insert(0, neutral) if self.incl_nochange: nochange = SimpleTerm( "nochange", "nochange", Message( "label_no_change", domain="plone", default=u"No change", ), ) items.insert(0, nochange) return SimpleVocabulary(items)
def notify_moderator(obj, event): """Tell the moderator when a comment needs attention. This method sends an email to the moderator if comment moderation a new comment has been added that needs to be approved. The moderator_notification setting has to be enabled in the discussion control panel. Configure the moderator e-mail address in the discussion control panel. If no moderator is configured but moderator notifications are turned on, the site admin email (from the mail control panel) will be used. """ # Check if moderator notification is enabled registry = queryUtility(IRegistry) settings = registry.forInterface(IDiscussionSettings, check=False) if not settings.moderator_notification_enabled: return # Get informations that are necessary to send an email mail_host = getToolByName(obj, 'MailHost') portal_url = getToolByName(obj, 'portal_url') portal = portal_url.getPortalObject() sender = portal.getProperty('email_from_address') if settings.moderator_email: mto = settings.moderator_email else: mto = sender # Check if a sender address is available if not sender: return conversation = aq_parent(obj) content_object = aq_parent(conversation) # Compose email subject = translate(_(u"A comment has been posted."), context=obj.REQUEST) message = translate(Message(MAIL_NOTIFICATION_MESSAGE_MODERATOR, mapping={ 'title': safe_unicode(content_object.title), 'link': content_object.absolute_url() + '/view#' + obj.id, 'text': obj.text, 'link_approve': obj.absolute_url() + '/@@moderate-publish-comment', 'link_delete': obj.absolute_url() + '/@@moderate-delete-comment', }), context=obj.REQUEST) # Send email try: mail_host.send(message, mto, sender, subject, charset='utf-8') except SMTPException, e: logger.error('SMTP exception (%s) while trying to send an ' + 'email notification to the comment moderator ' + '(from %s to %s, message: %s)', e, sender, mto, message)
def _update(self): context = self.context width = int(self._registry.get('%s.width' % self.name, 675)) height = int(self._registry.get('%s.height' % self.name, 380)) if hasImage(context): imageField = context.Schema()['image'] size = imageField.getSize(context) self.status = size == (width, height) else: self.status = False size = (0, 0) if self.status: self.description = _(u"Image field content has correct size.") else: symptom_description = _( u"Wrong size : image is " u"${actual_width} by ${actual_height} pixels. " u"It should be ${width} by ${height} pixels.") self.description = Message(symptom_description, mapping={ 'actual_width': size[0], 'actual_height': size[1], 'width': width, 'height': height })
def __addentry(self, msg, default=None, lineno=None, isdocstring=0): if lineno is None: lineno = self.__lineno if default is not None: default = unicode(default) msg = Message(msg, default=default) if msg in self.__messages: messages = list(self.__messages.keys()) idx = messages.index(msg) existing_msg = messages[idx] if msg.default != existing_msg.default: references = '\n'.join([ location[0] + ':' + str(location[1]) for location in self.__messages[msg].keys() ]) # XXX this does not appear to have any test coverage # the actual warnings are emitted by zope.tal sys.stderr.write( "Warning: msgid '%s' in %s already exists " "with a different default (bad: %s, should be: %s)\n" "The references for the existent value are:\n%s\n" % (msg, self.__curfile + ':' + str(lineno), msg.default, existing_msg.default, references)) entry = (self.__curfile, lineno) self.__messages.setdefault(msg, {})[entry] = isdocstring
def getInfoData(self): """ Get the data needed to create an ActionInfo. """ category_path = [] lazy_keys = [] lazy_map = {} lazy_map['id'] = self.getId() parent = aq_parent(self) while parent is not None and parent.getId() != 'portal_actions': category_path.append(parent.getId()) parent = aq_parent(parent) lazy_map['category'] = '/'.join(category_path[::-1]) for id, val in self.propertyItems(): if id.endswith('_expr'): id = id[:-5] if val: val = getattr(self, '%s_expr_object' % id) lazy_keys.append(id) elif id == 'available': val = True elif id == 'i18n_domain': continue elif self.i18n_domain and id in ('title', 'description'): val = Message(val, self.i18n_domain) lazy_map[id] = val return (lazy_map, lazy_keys)
def enumConfiglets(self, group=None): portal = getToolByName(self, 'portal_url').getPortalObject() context = createExprContext(self, portal, self) res = [] for a in self.listActions(): verified = 0 for permission in a.permissions: if _checkPermission(permission, portal): verified = 1 if verified and a.category == group and a.testCondition(context) \ and a.visible: res.append(a.getAction(context)) # Translate the title for sorting if getattr(self, 'REQUEST', None) is not None: for a in res: title = a['title'] if not isinstance(title, Message): title = Message(title, domain='plone') a['title'] = translate(title, context=self.REQUEST) def _title(v): return v['title'] res.sort(key=_title) return res
def long_date(self): date = self.date parts = {} parts['day'] = date.strftime('%d') parts['month'] = self.month() parts['year'] = date.strftime('%Y') return self.context.translate( Message(_(u'long_date_agenda'), mapping=parts))
def _update(self): id = self.context.getId() copy = re.compile('^copy[0-9]*_of') match = copy.match(id) self.status = not bool(match) if match: symptom_description = _(u"Id starts with '${start}'.") self.description = Message(symptom_description, mapping={'start': match.group()})
def Description(self): """ Textual description of the class of objects (intended for display in a "constructor list"). """ if self.description and self.i18n_domain: return Message(self.description, self.i18n_domain) else: return self.description
def __addentry(self, msg, default=None, lineno=None, isdocstring=0): if lineno is None: lineno = self.__lineno if default is not None: default = unicode(default) msg = Message(msg, default=default) entry = (self.__curfile, lineno) self.__messages.setdefault(msg, {})[entry] = isdocstring
def Title(self): title = _('label_archive_list_archive_view', u'${list} archive for ${date}') title = Message(title, mapping={ u'list': self.listTitle(), u'date': self.context.title, }) return title
def translate( self, msgid, domain=None, mapping=None, default=None, # Position is not part of the ITALExpressionEngine # interface position=None): if default is not None: default = normalize(default) if msgid == default: default = None msgid = Message(msgid, default=default) if domain not in self.catalog: self.catalog[domain] = {} domain = self.catalog[domain] if msgid not in domain: domain[msgid] = [] else: msgids = list(domain) idx = msgids.index(msgid) existing_msgid = msgids[idx] if msgid.default != existing_msgid.default: references = '\n'.join([ location[0] + ':' + str(location[1]) for location in domain[msgid] ]) # Note: a lot of encode calls here are needed so # Python 3 does not break. warnings.warn( "Warning: msgid '%s' in %s already exists " "with a different default (bad: %s, should be: %s)\n" "The references for the existent value are:\n%s\n" % (msgid.encode('utf-8'), self.file.encode('utf-8') + ':'.encode('utf-8') + str(position).encode('utf-8'), msgid.default.encode('utf-8'), existing_msgid.default.encode('utf-8'), references.encode('utf-8'))) domain[msgid].append((self.file, position)) return 'x'
def _initConfiglets(self, node): controlpanel = self.context default_domain = "plone" if node.nodeName == 'object': domain = str(node.getAttribute('i18n:domain')) if domain: default_domain = domain for child in node.childNodes: if child.nodeName != 'configlet': continue domain = str(child.getAttribute('i18n:domain')) if not domain: domain = default_domain action_id = str(child.getAttribute('action_id')) # Remove previous action with same id and category. controlpanel.unregisterConfiglet(action_id) remove = str(child.getAttribute('remove')) if remove.lower() == 'true': continue title = Message(str(child.getAttribute('title')), domain=domain) url_expr = str(child.getAttribute('url_expr')) condition_expr = str(child.getAttribute('condition_expr')) icon_expr = str(child.getAttribute('icon_expr')) category = str(child.getAttribute('category')) visible = str(child.getAttribute('visible')) appId = str(child.getAttribute('appId')) if visible.lower() == 'true': visible = 1 else: visible = 0 permission = '' for permNode in child.childNodes: if permNode.nodeName == 'permission': for textNode in permNode.childNodes: if textNode.nodeName != '#text' or \ not textNode.nodeValue.strip(): continue permission = str(textNode.nodeValue) break # only one permission is allowed if permission: break controlpanel.registerConfiglet(id=action_id, name=title, action=url_expr, appId=appId, condition=condition_expr, category=category, permission=permission, visible=visible, icon_expr=icon_expr)
class IFaqBlockSchema(ITextBlockSchema): """Faq block for simplelayout """ title = schema.TextLine(title=Message(u'label_title', domain='ftw.simplelayout', default=u'Title'), required=True) form.omitted('show_title') form.order_before(title='*')
def _update(self): id = self.context.getId() self.status = not len(str(id)) > self.maximum if not self.status: self.status = False symptom_description = _( u"Id is too long. " u"It should have at most ${maximum} characters.") self.description = Message(symptom_description, mapping={'maximum': self.maximum})
def set(self, value): try: old_value = super(FieldDataManager, self).get() except (AttributeError, ForbiddenAttribute): old_value = None if isinstance(old_value, Message): value = Message(unicode(old_value), domain=old_value.domain, default=value, mapping=old_value.mapping) super(FieldDataManager, self).set(value)
def manager_mod(self, user_email, user_name): user_name = nonascii_username(user_email, user_name) subject = _("Membership awaiting approval") body = default_email_text.manager_mod mapping = { 'fullname': user_name, 'listname': self.context.title, 'mod_url': self.context.absolute_url() + '/moderation', } body = Message(body, mapping=mapping) self.send_to_managers(translate(subject), translate(body))
def Title(self): """ Return the "human readable" type name (note that it may not map exactly to the 'portal_type', e.g., for l10n/i18n or where a single content class is being used twice, under different names. """ if self.title and self.i18n_domain: return Message(self.title, self.i18n_domain) else: return self.title or self.getId()
def user_mem_mod_already_pending(self, user_email, user_name): user_name = nonascii_username(user_email, user_name) subject = _("Membership approval already pending") body = default_email_text.user_mem_mod_already_pending mapping = { 'fullname': user_name, 'listname': self.context.title, 'listmanager': self.context.manager_email, } body = Message(body, mapping=mapping) self.context.sendCommandRequestMail(user_email, translate(subject), translate(body))
def user_denied(self, user_email, user_name): user_name = nonascii_username(user_email, user_name) subject = _("Membership denied") body = default_email_text.user_denied mapping = { 'fullname': user_name, 'listname': self.context.title, 'listmanager': self.context.manager_email, } body = Message(body, mapping=mapping) self.context.sendCommandRequestMail(user_email, translate(subject), translate(body))
def user_post_mod_notification(self, user_email, user_name): user_name = nonascii_username(user_email, user_name) subject = _("Message pending moderation") body = default_email_text.user_post_mod_notification mapping = { 'fullname': user_name, 'listname': self.context.title, 'listmanager': self.context.manager_email, } body = Message(body, mapping=mapping) self.context.sendCommandRequestMail(user_email, translate(subject), translate(body))
def processTranslatableProperty(self, chrs): if not (self.isInTag('field') and self.isInTag('values')): return name = self._stack[-1][1] if name not in TRANSLATABLE_PROPERTIES: return assert self._field_name is not None message_id = Message(chrs, self._i18n_domain) if not self._catalog.has_key(message_id): self._catalog[message_id] = [] number = self._locator.getLineNumber() self._catalog[message_id].append((self._filepath, number))
def user_unsubscribe_confirm(self, user_email, user_name): user_name = nonascii_username(user_email, user_name) subject = _("Unsubscription confirmed") body = default_email_text.user_unsubscribe_confirm mapping = { 'fullname': user_name, 'listname': self.context.title, 'listmanager': self.context.manager_email, } body = Message(body, mapping=mapping) self.context.sendCommandRequestMail(user_email, translate(subject), translate(body))
def Title(self): """The title of the comment. """ if self.title: return self.title if not self.creator: creator = translate(Message(_(u"label_anonymous", default=u"Anonymous"))) else: creator = self.creator creator = creator # Fetch the content object (the parent of the comment is the # conversation, the parent of the conversation is the content object). content = aq_base(self.__parent__.__parent__) title = translate( Message(COMMENT_TITLE, mapping={'creator': creator, 'content': safe_unicode(content.Title())})) return title
def startElementNS(self, name, qname, attrs): self.enterTag(name, attrs) if not self.isInTag('metadata_set'): raise NonMetadataXMLError if self.isInTag('field_values') and self.isInTag('value'): for name in TRANSLATABLE_PROPERTIES: if self.hasAttrValue('key', name): message_id = Message(self.getAttrValue('value'), self._i18n_domain) if not self._catalog.has_key(message_id): self._catalog[message_id] = [] number = self._locator.getLineNumber() self._catalog[message_id].append((self._filepath, number))
def translate(self, msgid, domain=None, mapping=None, default=None, # Position is not part of the ITALExpressionEngine # interface position=None): if default is not None: default = normalize(default) if msgid == default: default = None msgid = Message(msgid, default=default) if domain not in self.catalog: self.catalog[domain] = {} domain = self.catalog[domain] if msgid not in domain: domain[msgid] = [] else: msgids = list(domain) idx = msgids.index(msgid) existing_msgid = msgids[idx] if msgid.default != existing_msgid.default: references = '\n'.join([location[0]+':'+str(location[1]) for location in domain[msgid]]) # Note: a lot of encode calls here are needed so # Python 3 does not break. warnings.warn( "Warning: msgid '%s' in %s already exists " "with a different default (bad: %s, should be: %s)\n" "The references for the existent value are:\n%s\n" % (msgid.encode('utf-8'), self.file.encode('utf-8') + ':'.encode('utf-8') + str(position).encode('utf-8'), msgid.default.encode('utf-8'), existing_msgid.default.encode('utf-8'), references.encode('utf-8'))) domain[msgid].append((self.file, position)) return 'x'