def removeSubscriber(self, subscriber): charset = self.ploneCharset() subscriber_email = subscriber.email.strip() url_service = self.absolute_url() url_register = "%s/NewsletterTheme_subscribeForm" % url_service # Make and send the unsubscribe mail mailMsg=email.Message.Message() mailMsg["To"]=subscriber_email mailMsg["From"]=self.authorEmail mailMsg["Subject"]=str(Header(safe_unicode(self.removeNoticeMailSubject), 'utf8')) mailMsg["Date"]=email.Utils.formatdate(localtime=1) mailMsg["Message-ID"]=email.Utils.make_msgid() mailMsg["Mime-version"]="1.0" bodyText = self.removeNoticeTemplate % {'url_service': url_service, 'url_register':url_register} mailMsg["Content-type"]="text/plain" mailMsg.set_payload(safe_unicode(bodyText).encode(charset), charset) mailMsg.epilogue="\n" # To ensure that message ends with newline try: self.sendmail(self.authorEmail, subscriber_email, mailMsg, subject = mailMsg['subject']) except: log("Could not send a PloneGazzette unsubscribe message to %s, removing subscriber anyway." % subscriber_email) parent = aq_parent(subscriber) parent.manage_delObjects([subscriber.id])
def _copyDocument(self, target_folder_obj, source_brain): """ Copy utility """ # TODO: transferLog fuellen und DB Eintraege loeschen # print source_brain.getId source_obj = source_brain.getObject() # determine parent folder for copy p = parent(source_obj) # if source_obj.getId() == 'ifinprojection.2012-08-08.4378013443': # p._delOb('ifinprojection.2012-08-08.4378013443') # return cb_copy_data = p.manage_copyObjects(source_obj.getId()) result = target_folder_obj.manage_pasteObjects(cb_copy_data) # Now do some repairs if len(result) == 1: new_id = result[0]['new_id'] copied_obj = target_folder_obj._getOb(new_id) mdate = source_obj.modified() copied_obj.scenarios = [] wf_state = source_brain.review_state wftool = getToolByName(self, 'portal_workflow') # print wf_state, wftool.getInfoFor(copied_obj, 'review_state') if wf_state == "published" and wftool.getInfoFor(copied_obj, 'review_state') != 'published': wftool.doActionFor(copied_obj, 'publish') copied_obj.setModificationDate(mdate) events = source_obj.doc_extension(TRANSFERS_APP).transferEvents() copied_obj.transferLog = str(events) copied_obj.reindexObject() copied_obj.reindexObjectSecurity() else: log("Could not archive %s" % source_obj.absolute_url())
def __call__(self): om = IOrderManagement(self.context) tid = self.request.get('TID','') order = getattr(om.orders,tid,None) log("\n%s\n%s\n%s" % (order, tid, self.request.get('STATUS'))) if order and self.request.get('STATUS') in ['RESERVED','BILLED']: # Set order to payed (Mails will be sent) wftool = getToolByName(self.context, "portal_workflow") # We need a new security manager here, because this transaction # should usually just be allowed by a Manager except here. old_sm = getSecurityManager() tmp_user = UnrestrictedUser( old_sm.getUser().getId(), '', ['Manager'], '' ) portal = getToolByName(self.context, 'portal_url').getPortalObject() tmp_user = tmp_user.__of__(portal.acl_users) newSecurityManager(None, tmp_user) try: # set to pending (send emails) wftool.doActionFor(order, "submit") # set to payed wftool.doActionFor(order, "pay_not_sent") except Exception, msg: self.status = msg # Reset security manager setSecurityManager(old_sm)
def contentEdit(self, obj, **kwargs): # Encapsulates how the editing of content occurs. try: self.editMetadata(obj, **kwargs) except AttributeError, msg: log('Failure editing metadata at: %s.\n%s\n' % (obj.absolute_url(), msg))
def removed(obj, event): log("SRTextBlock removed: %s" % str(obj)) sr_cat = getToolByName(obj, "sr_catalog") op = event.oldParent id = event.oldName path = "/".join(op.getPhysicalPath()) + "/" + id sr_cat.uncatalog_object(path)
def workflowHistory(self, complete=True): """Return workflow history of this context. Taken from plone_scripts/getWorkflowHistory.py """ context = aq_inner(self.context) # check if the current user has the proper permissions # if not (_checkPermission('Request review', context) or # _checkPermission('Review portal content', context)): # return [] workflow = getToolByName(context, 'portal_workflow') membership = getToolByName(context, 'portal_membership') review_history = [] try: # get total history # import pdb # pdb.set_trace() review_history = workflow.getInfoFor(context, 'review_history') if not complete: # filter out automatic transitions. review_history = [r for r in review_history if r['action']] else: review_history = list(review_history) portal_type = context.portal_type anon = _p(u'label_anonymous_user', default=u'Anonymous User') for r in review_history: r['type'] = 'workflow' r['transition_title'] = workflow.getTitleForTransitionOnType( r['action'], portal_type) or _p("Create") r['state_title'] = workflow.getTitleForStateOnType( r['review_state'], portal_type) actorid = r['actor'] r['actorid'] = actorid if actorid is None: # action performed by an anonymous user r['actor'] = {'username': anon, 'fullname': anon} r['actor_home'] = '' else: r['actor'] = membership.getMemberInfo(actorid) if r['actor'] is not None: r['actor_home'] = self.navigation_root_url + '/author/' + actorid else: # member info is not available # the user was probably deleted r['actor_home'] = '' review_history.reverse() except WorkflowException: log('plone.app.layout.viewlets.content: ' '%s has no associated workflow' % context.absolute_url(), severity=logging.DEBUG) return review_history
def contributeur(self,auteur): context = aq_inner(self.context) parent = context.aq_parent log( context.contributor) if auteur in parent.keys(): return parent[auteur] return None
def workflowHistory(self, complete=True): """Return workflow history of this context. Taken from plone_scripts/getWorkflowHistory.py """ context = aq_inner(self.context) # check if the current user has the proper permissions # if not (_checkPermission('Request review', context) or # _checkPermission('Review portal content', context)): # return [] workflow = getToolByName(context, "portal_workflow") membership = getToolByName(context, "portal_membership") review_history = [] try: # get total history # import pdb # pdb.set_trace() review_history = workflow.getInfoFor(context, "review_history") if not complete: # filter out automatic transitions. review_history = [r for r in review_history if r["action"]] else: review_history = list(review_history) portal_type = context.portal_type anon = _p(u"label_anonymous_user", default=u"Anonymous User") for r in review_history: r["type"] = "workflow" r["transition_title"] = workflow.getTitleForTransitionOnType(r["action"], portal_type) or _p("Create") r["state_title"] = workflow.getTitleForStateOnType(r["review_state"], portal_type) actorid = r["actor"] r["actorid"] = actorid if actorid is None: # action performed by an anonymous user r["actor"] = {"username": anon, "fullname": anon} r["actor_home"] = "" else: r["actor"] = membership.getMemberInfo(actorid) if r["actor"] is not None: r["actor_home"] = self.navigation_root_url + "/author/" + actorid else: # member info is not available # the user was probably deleted r["actor_home"] = "" review_history.reverse() except WorkflowException: log( "plone.app.layout.viewlets.content: " "%s has no associated workflow" % context.absolute_url(), severity=logging.DEBUG, ) return review_history
def workflowHistory(self, complete=True): """Return workflow history of this context. Taken from plone_scripts/getWorkflowHistory.py """ context = aq_inner(self.context) # check if the current user has the proper permissions if not (_checkPermission('Request review', context) or _checkPermission('Review portal content', context)): return [] workflow = getToolByName(context, 'portal_workflow') membership = getToolByName(context, 'portal_membership') review_history = [] try: # get total history review_history = workflow.getInfoFor(context, 'review_history') if not complete: # filter out automatic transitions. review_history = [r for r in review_history if r['action']] else: review_history = list(review_history) portal_type = context.portal_type anon = _(u'label_anonymous_user', default=u'Anonymous User') for r in review_history: r['type'] = 'workflow' r['transition_title'] = workflow.getTitleForTransitionOnType( r['action'], portal_type) or _("Create") r['state_title'] = workflow.getTitleForStateOnType( r['review_state'], portal_type) actorid = r['actor'] r['actorid'] = actorid if actorid is None: # action performed by an anonymous user r['actor'] = {'username': anon, 'fullname': anon} r['actor_home'] = '' else: r['actor'] = membership.getMemberInfo(actorid) if r['actor'] is not None: r['actor_home'] = self.navigation_root_url + \ '/author/' + actorid else: # member info is not available # the user was probably deleted r['actor_home'] = '' review_history.reverse() except WorkflowException: log('plone.app.layout.viewlets.content: ' '%s has no associated workflow' % context.absolute_url(), severity=logging.DEBUG) return review_history
def uninstallVarious(context): if context.readDataFile('plonesocial.suite_uninstall.txt') is None: return site = context.getSite() site.layout = "folder_listing" site.default_page = "folder_listing" log("Uninstalled plonesocial.suite")
def objekteImportieren(self, typ, importfile, request, context=None): """ """ try: meldung, status = imports.genericImportFromCSV(self, importfile, typ, request, context=context) log("Daten importiert.") return meldung, status except "Exception", e: log_exc("Daten konnten nicht importiert werden: %s" % importfile) return [ str(e) ], False
def contentEdit(self, obj, **kwargs): # Encapsulates how the editing of content occurs. try: self.editMetadata(obj, **kwargs) except AttributeError as msg: log('Failure editing metadata at: %s.\n%s\n' % (obj.absolute_url(), msg)) if kwargs.get('id', None) is not None: self._renameObject(obj, id=kwargs['id'].strip()) self._makeTransactionNote(obj)
def auteurs(self): context = aq_inner(self.context) parent = context.aq_parent catalog = getToolByName(self.context, 'portal_catalog') log( 'parent path : ' + parent.absolute_url()) return catalog(object_provides=[IAuteur.__identifier__], path={'query': '/'.join(parent.getPhysicalPath()), 'depth': 1}, sort_on='sortable_title')
def createActions(self): """ """ log("Creating Collaboration Folder") placeful_wf = getToolByName(self, 'portal_placeful_workflow') try: self.manage_addProduct['CMFPlacefulWorkflow'].manage_addWorkflowPolicyConfig() except BadRequest, e: log_exc(e)
def delete_handler(object, event): """ Called when an undeleteable object is removed. Only allowed for Managers. """ log("Deleting protected object " + object.getId()) try: if not object.isAdmin(): raise Unauthorized except Exception, e: log_exc(e)
def subtrackers(self): """Return a catalog search result of issues to show """ context = aq_inner(self.context) catalog = getToolByName(context, 'portal_catalog') log( "context's physical path : " + '/'.join(context.getPhysicalPath())) log( "all subtrackers") return catalog(object_provides=[ITracker.__identifier__], path={'query': '/'.join(context.getPhysicalPath()), 'depth': 1}, sort_on='sortable_title')
def authors(self, projectPath): """Return a catalog search result of authors from a project """ context = aq_inner(self.context) catalog = getToolByName(self.context, 'portal_catalog') log( 'authors : ' + projectPath) cat = catalog(object_provides=[IAuteur.__identifier__], path={'query': projectPath, 'depth': 2}, sort_on='sortable_title') return cat
def created(obj, event=None): # Initialize all channel settings in the database. # For all document types shared between the two ESDs # set the default to "publish" log("TransferFolder created: %s" % str(obj)) if not obj.isArchive(): setupChannel(obj, delete=True) # Also, if the permissions include read access, # set the local Reader role for the members of # the sending ESD if obj.permLevel == 'read/write': obj.grantReadAccess()
def send_mail(self, body,to_addr,from_addr,subject): # # Method to bypass Zope's security. # For case of comment/trackback post by anonymous user # try: self.MailHost.send(body, to_addr, from_addr, subject) except Exception,e: self.MailHost.send(body.encode('utf-8'), to_addr, from_addr, subject.encode('utf-8')) log( 'COREBlog2/send_mail: ' 'Some exception occured, %s' % e )
def updated(obj, event=None): # Actually, a transfer folder should never allow a change of ESD. # But the permission level could have been changed. So we adapt # the read permissions for the sending ESD accordingly. log("TransferFolder updated: %s" % str(obj)) if not obj.isArchive(): setupChannel(obj, delete=False) if obj.permLevel == 'read/write': obj.grantReadAccess() else: obj.revokeReadAccess()
def setReviewer(tracker, event): log( "=== Default Reviewer Role Attribution ===") acl_users = getToolByName(tracker, 'acl_users') mail_host = getToolByName(tracker, 'MailHost') portal_url = getToolByName(tracker, 'portal_url') parent = tracker.aq_inner.aq_parent log( parent.__name__ + "parent local roles : " +str(parent.get_local_roles()) + "\naq_parent'parent local roles : " + str(parent.aq_parent.get_local_roles()) + "\ntracker's aq_parent local roles : " + str(tracker.aq_parent.get_local_roles())) users_with_the_role = [] if parent.Type() == "Tracker": log( "Testing parent's reviewers") users_roles = parent.get_local_roles() print users_roles users_with_the_role = [x[0] for x in users_roles if 'Reviewer' in x[1]] for member in users_with_the_role: print member #Add local roles to a group if IRoleManager.providedBy(tracker): for member in users_with_the_role: log( "adding roles (Reviewer) to " + member) tracker.manage_addLocalRoles(member, ['Reviewer']) return
def updated(obj, event=None): # Actually, a transfer folder should never allow a change of ESD. # But the permission level could have been changed. So we adapt # the read permissions for the sending ESD accordingly. log("DocType updated: %s" % str(obj)) mpath = "/" if shasattr(obj, "dpSearchPath", acquire=True): mpath = obj.dpSearchPath() docs = queryForObjects(obj, path=mpath,docType=obj.getId()) for doc in docs: try: doc.getObject().reindexObject() except: pass
def removeGroup(projet, event): acl_users = getToolByName(projet, 'acl_users') mail_host = getToolByName(projet, 'MailHost') portal_url = getToolByName(projet, 'portal_url') portal = portal_url.getPortalObject() sender = portal.getProperty('email_from_address') gr = portal.portal_groups group_id = projet.id if group_id in gr.getGroupIds(): gr.removeGroup(group_id) log("Group %s removed"%group_id) return
def extractCredentials( self, request ): """ Extract credentials from cookie or 'request'. """ #log( 'extractCredentials') alsoProvides(request, IDisableCSRFProtection) creds = {} session = request.SESSION username = None tokenTool = getToolByName(self, 'onetimetoken_storage') ob = session.get(self.session_var) if ob is not None and isinstance(ob, UsernameStorage): username = ob._getUsername() #log( "session username: %s" % username ) if username is None: loginCode = request.get('logincode') if not loginCode: return None # not authenticated try: username = tokenTool.verifyToken(loginCode) except: log( "Error, token tool refused token: %s" % sys.exc_info()[0] ) if not username: return None # not authenticated #log( "token username: %s" % username ) userstorage = UsernameStorage() userstorage._setUsername(username) session[self.session_var] = userstorage creds['remote_host'] = request.get('REMOTE_HOST', '') try: creds['remote_address'] = request.getClientAddr() except AttributeError: creds['remote_address'] = request.get('REMOTE_ADDR', '') creds['login'] = username # log( "returning username: %s" % username ) return creds
def deleted(obj, event=None): # Delete all channel settings from the database. log("TransferFolder deleted: %s" % str(obj)) if not obj.isArchive(): esd_from_uid=obj.sendingESD tf_uid=obj.UID() old = Channel.get_by(esd_from_uid=esd_from_uid, tf_uid=tf_uid) permissions = obj.permissions() for perm in permissions: __session__.delete(perm) __session__.flush() if old: __session__.delete(old) __session__.flush() # Revoke any read access obj.revokeReadAccess()
def extractCredentials(self, request): """ Extract credentials from cookie or 'request'. """ #log( 'extractCredentials') creds = {} session = request.SESSION username = None tokenTool = getToolByName(self, 'onetimetoken_storage') ob = session.get(self.session_var) if ob is not None and isinstance(ob, UsernameStorage): username = ob._getUsername() #log( "session username: %s" % username ) if username is None: loginCode = request.get('logincode') if not loginCode: return None # not authenticated try: username = tokenTool.verifyToken(loginCode) except: log("Error, token tool refused token: %s" % sys.exc_info()[0]) if not username: return None # not authenticated #log( "token username: %s" % username ) userstorage = UsernameStorage() userstorage._setUsername(username) session[self.session_var] = userstorage creds['remote_host'] = request.get('REMOTE_HOST', '') try: creds['remote_address'] = request.getClientAddr() except AttributeError: creds['remote_address'] = request.get('REMOTE_ADDR', '') creds['login'] = username # log( "returning username: %s" % username ) return creds
def updated(obj, event=None): log("SRModule updated: %s" % str(obj)) # TODO: # read text, find all image links, replace with data URLs # find all html snippet links (marked with a css class), replace with html content. html = obj.text and obj.text.output or '' if html: urltool = getToolByName(obj, "portal_url") portal = urltool.getPortalObject() portalbase = portal.absolute_url() base = obj.absolute_url() + "/" soup = BeautifulSoup(html) # first we handle all images for img in soup.findAll('img'): print img src = img['src'] if src.startswith("data"): continue # src might be relative absolute_src = join(base, src) # We convert the result of a request to the uri to a data URI new_uri = fetch_resources(portalbase, absolute_src) if new_uri: # and replace the original one img['src'] = new_uri for span in soup.findAll("span", {'class':'snippet'}): for anchor in span.findAll("a"): # print anchor href = anchor['href'] if '..' in href: href = href.replace('/..','') absolute_href = join(base, href) html_data = fetch_resources(portalbase, absolute_href, resource_type="html") if html_data: ext_soup = BeautifulSoup(html_data) body = ext_soup.find('body') body = None if body: anchor.replaceWith(body) else: anchor.replaceWith(ext_soup) # finally we replace the html of the module with the manipulated version new_html = str(soup) obj.text = RichTextValue(safe_unicode(new_html), 'text/html', 'text/html')
def createActions(self): """ """ if shasattr(self, "myGroupFolder", acquire=True): log("Creating Private Info Folder") placeful_wf = getToolByName(self, 'portal_placeful_workflow') try: self.manage_addProduct['CMFPlacefulWorkflow'].manage_addWorkflowPolicyConfig() except BadRequest, e: log_exc(e) config = placeful_wf.getWorkflowPolicyConfig(self) placefulWfName = 'dp-private-infofolder' config.setPolicyIn(policy=placefulWfName, update_security=False) config.setPolicyBelow(policy=placefulWfName, update_security=False) self.reindexObject() self.updateSecurity() self.reindexObjectSecurity()
def __call__(self, context): acl_users = getToolByName(context, 'acl_users') parent = context.aq_inner.aq_parent log("context : " + context.__name__ + " parent : " + parent.__name__) users_roles = context.get_local_roles() users_with_the_role = [x[0] for x in users_roles if self.role_name in x[1]] terms = [] terms.append(SimpleVocabulary.createTerm('', str(''), '')) if users_with_the_role is not None: for member_id in users_with_the_role: log( member_id) user = acl_users.getUserById(member_id) if user is not None: member_name = user.getProperty('fullname') or member_id terms.append(SimpleVocabulary.createTerm(member_id, str(member_id), member_name)) return SimpleVocabulary(terms)
def uninstall(self, reinstall=False): if reinstall: return "Uninstall profile skipped" setup_tool = getToolByName(self, 'portal_setup') # setup_tool.runAllImportStepsFromProfile('profile-collective.chimpfeed:uninstall', # ignore_dependencies=True) # Remove utilities when really uninstalled sm = self.getSiteManager() try: my_utility = getUtility(IApiUtility) sm.unregisterUtility(my_utility, IApiUtility) del my_utility except ComponentLookupError: pass adapters = sm.utilities._adapters for x in adapters[0].keys(): if x.__module__.find("collective.chimpfeed") != -1: print "deleting %s" % x del adapters[0][x] sm.utilities._adapters = adapters subscribers = sm.utilities._subscribers for x in subscribers[0].keys(): if x.__module__.find("collective.chimpfeed") != -1: print "deleting %s" % x del subscribers[0][x] sm.utilities._subscribers = subscribers provided = sm.utilities._provided for x in provided.keys(): if x.__module__.find("collective.chimpfeed") != -1: print "deleting %s" % x del provided[x] sm.utilities._provided = provided transaction.commit() self.getPhysicalRoot()._p_jar.sync() log("Uninstalled collective.chimpfeed IApiUtility") return "Ran all uninstall steps."
def retract(self): """See IWorkflowedWeblogEntry. """ if not self.isPublished(): # do nothing if the entry has already been private return wf_tool = getToolByName(self, 'portal_workflow') try: wf_tool.doActionFor(self, 'retract') except WorkflowException: state = wf_tool.getInfoFor(self, 'review_state') workflow = wf_tool.getWorkflowsFor(self)[0].id objectPath = "/".join(self.getPhysicalPath()) log("WeblogEntry.retract failed, most probable because the current " "state '%s' of workflow '%s' of entry '%s' does not define a " "transition 'retract'. To solve this either use another workflow, " "adapt the workflow, or restrain from using this method for now. " "Sorry." % (state, workflow, objectPath)) raise self.setPublicationDate(None) self.reindexObject()
def issues(self, wf_state='all'): """Return a catalog search result of issues to show """ context = aq_inner(self.context) log("context : " + str(context)) log("self.context : " + str(self.context)) catalog = getToolByName(context, 'portal_catalog') log( "context's physical path : " + '/'.join(context.getPhysicalPath())) log(wf_state + " state chosen") if wf_state == 'all': log( "all issues") return catalog(object_provides=[IIssue.__identifier__], path={'query': '/'.join(context.getPhysicalPath()), 'depth': 1}, sort_on="modified", sort_order="reverse") aq = catalog(object_provides=[IIssue.__identifier__], review_state=wf_state, path={'query': '/'.join(context.getPhysicalPath()), 'depth': 1}, sort_on='deadline') #return catalog.evalAdvancedQuery(aq, (('deadline', 'asc'), ('effective', 'asc'))) return aq
def publish(self, pubdate=None): """See IWorkflowedWeblogEntry. """ if self.isPublished(): # do nothing if the entry has already been published return # XXX Need to be able to handle std library datetime objects for pubdate if pubdate is None: pubdate = DateTime() self.setPublicationDate(pubdate) wf_tool = getToolByName(self, 'portal_workflow') try: wf_tool.doActionFor(self, 'publish') except WorkflowException: state = wf_tool.getInfoFor(self, 'review_state') workflow = wf_tool.getWorkflowsFor(self)[0].id objectPath = "/".join(self.getPhysicalPath()) log("WeblogEntry.publish failed, most probable because the current " "state '%s' of workflow '%s' of entry '%s' does not define a " "transition 'publish'. To solve this either use another workflow, " "adapt the workflow, or restrain from using this method for now. " "Sorry." % (state, workflow, objectPath)) raise self.reindexObject()
def ulocalized_time(time, long_format=None, time_only=False, context=None, domain='plonelocales', formatstring_domain='plonelocales', request=None, target_language=None): """Unicode aware localized time method (l10n), extended from CMFPlone The ONLY change versus CMFPlone is the extra parameter `formatstring_domain`. This allows us to define a different date_format_long in ploneintranet, while still being able to use the default translations provided by plonelocales, e.g. for the month names. """ if time_only: msgid = 'time_format' elif long_format: msgid = 'date_format_long' else: msgid = 'date_format_short' # NOTE: this requires the presence of three msgids inside the translation # catalog date_format_long, date_format_short, and time_format # These msgids are translated using interpolation. # The variables used here are the same as used in the strftime # formating. # Supported are: # %A, %a, %B, %b, %H, %I, %m, %d, %M, %p, %S, %Y, %y, %Z # Each used as variable in the msgstr without the %. # For example: "${A} ${d}. ${B} ${Y}, ${H}:${M} ${Z}" # Each language dependend part is translated itself as well. # From http://docs.python.org/lib/module-time.html # # %a Locale's abbreviated weekday name. # %A Locale's full weekday name. # %b Locale's abbreviated month name. # %B Locale's full month name. # %d Day of the month as a decimal number [01,31]. # %H Hour (24-hour clock) as a decimal number [00,23]. # %I Hour (12-hour clock) as a decimal number [01,12]. # %m Month as a decimal number [01,12]. # %M Minute as a decimal number [00,59]. # %p Locale's equivalent of either AM or PM. # %S Second as a decimal number [00,61]. # %y Year without century as a decimal number [00,99]. # %Y Year with century as a decimal number. # %Z Time zone name (no characters if no time zone exists). mapping = {} # convert to DateTime instances. Either a date string or # a DateTime instance needs to be passed. if not IDateTime.providedBy(time): try: time = DateTime(time) except: log('Failed to convert %s to a DateTime object' % time, severity=logging.DEBUG) return None if context is None: # when without context, we cannot do very much. return time.ISO8601() if request is None: request = aq_acquire(context, 'REQUEST') # 1. if our Enabled flag in the configuration registry is set, # the format string there should override the translation machinery formatstring = get_formatstring_from_registry(msgid) if formatstring is not None: return time.strftime(formatstring) # 2. the normal case: translation machinery, # that is the ".../LC_MESSAGES/plonelocales.po" files # XXX: here, we pass `formatstring_domain` instead of `domain` formatstring = translate(msgid, formatstring_domain, mapping, request, target_language=target_language) # 3. if both failed, fall back to hardcoded ISO style if formatstring == msgid: if msgid == 'date_format_long': formatstring = '%Y-%m-%d %H:%M' # 2038-01-19 03:14 elif msgid == 'date_format_short': formatstring = '%Y-%m-%d' # 2038-01-19 elif msgid == 'time_format': formatstring = '%H:%M' # 03:14 else: formatstring = '[INTERNAL ERROR]' return time.strftime(formatstring) # get the format elements used in the formatstring formatelements = _interp_regex.findall(formatstring) # reformat the ${foo} to foo formatelements = [el[2:-1] for el in formatelements] # add used elements to mapping elements = [e for e in formatelements if e in datetime_formatvariables] # add weekday name, abbr. weekday name, month name, abbr month name week_included = True month_included = True name_elements = [e for e in formatelements if e in name_formatvariables] if not ('a' in name_elements or 'A' in name_elements): week_included = False if not ('b' in name_elements or 'B' in name_elements): month_included = False for key in elements: mapping[key] = time.strftime('%' + key) if week_included: weekday = int(time.strftime('%w')) # weekday, sunday = 0 if 'a' in name_elements: mapping['a'] = weekdayname_msgid_abbr(weekday) if 'A' in name_elements: mapping['A'] = weekdayname_msgid(weekday) if month_included: monthday = int(time.strftime('%m')) # month, january = 1 if 'b' in name_elements: mapping['b'] = monthname_msgid_abbr(monthday) if 'B' in name_elements: mapping['B'] = monthname_msgid(monthday) # translate translateable elements # Note: Here, the normal `domain` is used for key in name_elements: mapping[key] = translate(mapping[key], domain, context=request, default=mapping[key], target_language=target_language) # translate the time string # XXX: here, we pass `formatstring_domain` instead of `domain` return translate(msgid, formatstring_domain, mapping, request, target_language=target_language)
def sendNotificationEmail(self, addresses, subject, rstText): """ Send a notification email to the list of addresses XXX Note to self [maurits]: look at this blog post from Marius Gedminas, titled "Sending Unicode emails in Python": http://mg.pov.lt/blog/unicode-emails-in-python.html """ if not self.getSendNotificationEmailsTo() or not addresses: return portal_url = getToolByName(self, 'portal_url') plone_utils = getToolByName(self, 'plone_utils') portal = portal_url.getPortalObject() mailHost = plone_utils.getMailHost() charset = portal.getProperty('email_charset', '') if not charset: charset = plone_utils.getSiteEncoding() from_address = portal.getProperty('email_from_address', '') if not from_address: log('Cannot send notification email: email sender address not set') return from_name = portal.getProperty('email_from_name', '') mfrom = formataddr((from_name, from_address)) if parseaddr(mfrom)[1] != from_address: # formataddr probably got confused by special characters. mfrom = from_address email_msg = MIMEMultipart('alternative') email_msg.epilogue = '' # Translate the body text ts = getGlobalTranslationService() rstText = ts.translate('Poi', rstText, context=self) # We must choose the body charset manually for body_charset in 'US-ASCII', charset, 'UTF-8': try: rstText = rstText.encode(body_charset) except UnicodeError: pass else: break textPart = MIMEText(rstText, 'plain', body_charset) email_msg.attach(textPart) htmlPart = MIMEText(renderHTML(rstText, charset=body_charset), 'html', body_charset) email_msg.attach(htmlPart) # Make the subject unicode and translate it too. subject = safe_unicode(subject, charset) subject = ts.translate('Poi', subject, context=self) for address in addresses: address = safe_unicode(address, charset) if not address: # E-mail address may not be known, for example in case # of LDAP users. See: # http://plone.org/products/poi/issues/213 continue try: # Note that charset is only used for the headers, not # for the body text as that is a Message/MIMEText already. mailHost.secureSend(message=email_msg, mto=address, mfrom=mfrom, subject=subject, charset=charset) except (socket.error, SMTPException), exc: log_exc(('Could not send email from %s to %s regarding issue ' 'in tracker %s\ntext is:\n%s\n') % (mfrom, address, self.absolute_url(), email_msg)) log_exc("Reason: %s: %r" % (exc.__class__.__name__, str(exc))) except:
def workflowHistory(self, complete=True): """Return workflow history of this context, for all workflows in its chain. Taken from plone_scripts/getWorkflowHistory.py """ context = aq_inner(self.context) # Since switching to DCWorkflow's getInfoFor, we rely on its # permission checks. #if not (_checkPermission('Request review', context) or # _checkPermission('Review portal content', context)): # return [] wf_tool = getToolByName(context, 'portal_workflow') membership = getToolByName(context, 'portal_membership') workflows = wf_tool.getWorkflowsFor(self.context) review_history = [] try: # get total history for wf in workflows: wf_review_history = wf.getInfoFor(context, 'review_history', []) # Add in the state_var, to find the title and use in template for item in wf_review_history: item['state_var'] = wf.state_var review_history.extend(wf_review_history) if not complete: # filter out automatic transitions. review_history = [r for r in review_history if r['action']] else: review_history = list(review_history) portal_type = context.portal_type anon = _(u'label_anonymous_user', default=u'Anonymous User') for r in review_history: r['type'] = 'workflow' r['transition_title'] = wf_tool.getTitleForTransitionOnType( r['action'], portal_type) or _("Create") r['state_title'] = wf_tool.getTitleForStateOnType( r[r['state_var']], portal_type) actorid = r['actor'] r['actorid'] = actorid if actorid is None: # action performed by an anonymous user r['actor'] = {'username': anon, 'fullname': anon} r['actor_home'] = '' else: r['actor'] = membership.getMemberInfo(actorid) if r['actor'] is not None: r['actor_home'] = self.navigation_root_url + '/author/' + actorid else: # member info is not available # the user was probably deleted r['actor_home'] = '' review_history.reverse() except WorkflowException: log('plone.app.layout.viewlets.content: ' '%s has no associated workflow' % context.absolute_url(), severity=logging.DEBUG) return review_history
def ulocalized_time(time, formatstring, request, target_language=None): """time localization method copied from Products.CMFPlone.i18nl10n. The method was modified to allow for a custom formatstring in the normal python format. From http://docs.python.org/lib/module-time.html %a Locale's abbreviated weekday name. %A Locale's full weekday name. %b Locale's abbreviated month name. %B Locale's full month name. %d Day of the month as a decimal number [01,31]. %H Hour (24-hour clock) as a decimal number [00,23]. %I Hour (12-hour clock) as a decimal number [01,12]. %m Month as a decimal number [01,12]. %M Minute as a decimal number [00,59]. %p Locale's equivalent of either AM or PM. %S Second as a decimal number [00,61]. %y Year without century as a decimal number [00,99]. %Y Year with century as a decimal number. %Z Time zone name (no characters if no time zone exists). """ domain = 'plonelocales' # map to a message string, to make easier reuse of original # method and _interp_regex. formatstring = format_string_to_message_string(formatstring) mapping = {} # convert to DateTime instances. Either a date string or # a DateTime instance needs to be passed. if not IDateTime.providedBy(time): try: time = DateTime(time) except Exception: log('Failed to convert %s to a DateTime object' % time, severity=logging.DEBUG) return None # get the format elements used in the formatstring formatelements = _interp_regex.findall(formatstring) # reformat the ${foo} to foo formatelements = [el[2:-1] for el in formatelements] # add used elements to mapping elements = [e for e in formatelements if e in datetime_formatvariables] # add weekday name, abbr. weekday name, month name, abbr month name week_included = True month_included = True name_elements = [e for e in formatelements if e in name_formatvariables] if not ('a' in name_elements or 'A' in name_elements): week_included = False if not ('b' in name_elements or 'B' in name_elements): month_included = False for key in elements: mapping[key] = time.strftime('%' + key) if week_included: weekday = int(time.strftime('%w')) # weekday, sunday = 0 if 'a' in name_elements: mapping['a'] = weekdayname_msgid_abbr(weekday) if 'A' in name_elements: mapping['A'] = weekdayname_msgid(weekday) if month_included: monthday = int(time.strftime('%m')) # month, january = 1 if 'b' in name_elements: mapping['b'] = monthname_msgid_abbr(monthday) if 'B' in name_elements: mapping['B'] = monthname_msgid(monthday) # translate translateable elements for key in name_elements: mapping[key] = translate(mapping[key], domain, context=request, default=mapping[key], target_language=target_language) # translate the time string return formatstring.replace("${", "{").format(**mapping)
elements = {} for k in ('blog_name','title','excerpt','url','excerpt'): if form.has_key(k): elements[k] = REQUEST.form[k] else: elements[k] = '' elements['post_ip'] = REQUEST.getClientAddr() elements['entry_url'] = context.absolute_url() msgbody = msgbody % (elements) msgsubject = context.translate('trackback_notify_title') mgsheader = """To: %s From: %s Mime-Version: 1.0 Content-Type: text/plain; Charset=utf-8 """ % (to_addr,from_addr) cbtool.send_mail(mgsheader+msgbody, to_addr, from_addr, msgsubject) except Exception,e: log( 'COREBlog2/tbping: ' 'Some exception occured, %s' % e ) entry.addTrackback2Entry(title=title,url=url,\ blog_name=blog_name,excerpt=excerpt) return context.tbping_result(client=context,REQUEST=REQUEST,\ error_code=0,message='Thanks :-)') except: return context.tbping_result(client=context,REQUEST=REQUEST,\ error_code=1,message='Error occured!')
def factory_Assessment(self): """factory""" type_name = 'Assessment' create = self.REQUEST.form.get('create_in_latest_spec') if create == 'true': latest = IGetVersions(self).latest_version() if latest.UID() != self.UID(): return latest.factory_Assessment() #drop with error if no PolicyQuestions are created if not self.objectValues('PolicyQuestion'): raise ValueError("You need to create first a Policy Question") #create a version if we already have an Assessment assessments = self.objectValues(type_name) if assessments: #NOTE: we assume the latest object is the last one original = assessments[-1] ast = createVersion(original) return { 'obj': ast, 'subview': '@@edit_aggregated', 'direct_edit': True } #we want to make this assessment a version of a previous assessment #if this Specification is already versioned, so we try get a versionId version_id = None spec_versions = IGetVersions(self).versions() for spec in spec_versions: asts = spec.objectValues("Assessment") if asts: original = asts[0] version_id = IVersionControl(original).versionId break #if there are no other assessments in this version set we look for #other IndicatorFactSheet objects with same indicator code to #get the versionId if not version_id: brains = [] codes = self.get_codes() cat = getToolByName(self, 'portal_catalog') for code in codes[1::2]: brains = cat.searchResults({ 'portal_type': 'IndicatorFactSheet', 'get_codes': code }) if brains: break if brains: version_id = IVersionControl(brains[0].getObject()).versionId #create a new Assessment from scratch #id = self.generateUniqueId(type_name) aid = make_id('assessment', self.objectIds()) new_id = self.invokeFactory(type_name=type_name, id=aid, base_impl=True, title=self.translate( msgid='label-newly-created-type', domain='indicators', default="Newly created ${type_name}", mapping={'type_name': type_name}, )) ast = self[new_id] if version_id: IVersionControl(ast).setVersionId(version_id) #create assessment parts for each policy question for pq in self.objectValues("PolicyQuestion"): aid = ast.invokeFactory( type_name="AssessmentPart", id=ast.generateUniqueId("AssessmentPart"), ) ap = ast[aid] ap.setRelatedItems(pq) try: ap.reindexObject() except AttributeError: log("#ZZZ: this happens when executed from test") ast.reindexObject() notify(ObjectInitializedEvent(ast)) return { 'obj': ast, 'subview': '@@edit_aggregated', 'direct_edit': True }
def removeUtility(portal): currency_data = getUtility(ICurrencyData) portal.getSiteManager().unregisterUtility(currency_data) del currency_data transaction.commit() log("Uninstalled CurrencyData")