Example #1
0
    def sendEmail(self, addresses, subject, text):
        """
        Send an e-mail message to the specified list of addresses.
        """

        if not addresses:
            return

        portal_url  = getToolByName(self, 'portal_url')
        #plone_utils = getToolByName(self, 'plone_utils')

        portal      = portal_url.getPortalObject()
        fromAddress = portal.getProperty('email_from_address', None)

        #mailHost    = plone_utils.getMailHost()
        #charset     = plone_utils.getSiteEncoding()
        mailHost = getToolByName(portal, 'MailHost') #self.MailHost
        charset = portal.getProperty('email_charset', 'UTF-8')


        if fromAddress is None:
            LOG.error('Cannot send email: address or name is %s' % fromAddress)
            return

        try:
            if (type(text) == unicode):
                msg = MIMEText(text.encode(charset), 'plain', charset)
            else:
                msg = MIMEText(text, 'plain', charset)
        except Exception, e:
            LOG.error('Cannot send notification email: %s' % e)
            return
    def sendEmail(self, addresses, subject, text):
        """
        Send an e-mail message to the specified list of addresses.
        """

        if not addresses:
            return

        portal_url = getToolByName(self, 'portal_url')
        #plone_utils = getToolByName(self, 'plone_utils')

        portal = portal_url.getPortalObject()
        fromAddress = portal.getProperty('email_from_address', None)

        #mailHost    = plone_utils.getMailHost()
        #charset     = plone_utils.getSiteEncoding()
        mailHost = getToolByName(portal, 'MailHost')  #self.MailHost
        charset = portal.getProperty('email_charset', 'UTF-8')

        if fromAddress is None:
            LOG.error('Cannot send email: address or name is %s' % fromAddress)
            return

        try:
            if (type(text) == unicode):
                msg = MIMEText(text.encode(charset), 'plain', charset)
            else:
                msg = MIMEText(text, 'plain', charset)
        except Exception, e:
            LOG.error('Cannot send notification email: %s' % e)
            return
Example #3
0
        # This is a hack to suppress deprecation messages about send()
        # in SecureMailHost; the proposed alternative, secureSend(),
        # sucks.
        mailHost._v_send = 1
        
        for address in addresses:
            if address:
                try:
                    LOG.info("Sending email to %r" % address)

                    msg['To'] = address
                    
                    mailHost.send(msg.as_string())
                    
                except ConflictError, ce:
                    LOG.error('Failed sending email: %s' % ce)
                    raise
                except Exception, e:
                    LOG.error('Failed sending email from %s to %s' % 
                              (fromAddress, address))
                    LOG.error("Reason: %s: %r" % (e.__class__.__name__, str(e)))
            # end if
        # end for


    #security.declarePrivate('pathQuote')
    def pathQuote(self, string=''):
        """
        Returns a string which is save to use as a filename.

        @param string some string
class ECABTool(UniqueObject, BaseContent, BrowserDefaultMixin):
    """
    """
    security = ClassSecurityInfo()
    implements(IECABTool)
    meta_type = 'ECABTool'
    plone_tool = True
    _at_rename_after_creation = True

    schema = ECABTool_schema

    def __init__(self, id=None):
        """
        Tool-constructors have no id argument, the id is fixed
        """
        BaseContent.__init__(self, 'ecab_utils')
        self.setTitle('')

    def at_post_edit_script(self):
        """
        Tool should not appear in portal_catalog
        """
        self.unindexObject()

    # -- Methods --------------------------------------------------------------
    #security.declarePrivate('getWfStates')
    def getWfStates(self, wfName=config.ECA_WORKFLOW_ID):
        """
        @return a list containing all state keys in assignment's workflow
        """
        wtool = self.portal_workflow
        return wtool.getWorkflowById(wfName).states.keys()

    #security.declarePublic('getWfStatesDisplayList')
    def getWfStatesDisplayList(self, wfName=config.ECA_WORKFLOW_ID):
        """
        @return a DisplayList containing all state keys and state titles in 
                assignment's workflow
        """
        #LOG.info('xxx: getWfStatesDisplayList')

        dl = DisplayList(())

        wtool = self.portal_workflow
        wf = wtool.getWorkflowById(wfName)
        stateKeys = self.getWfStates(wfName)

        for key in stateKeys:
            dl.add(key, wf.states[key].title)

        #return dl.sortedByValue()
        return dl

    #security.declarePrivate('getWfTransitions')
    def getWfTransitions(self, wfName=config.ECA_WORKFLOW_ID):
        """
        @return all transitions for the given workflow
        """

        result = {}

        wtool = self.portal_workflow
        wf = wtool.getWorkflowById(wfName)

        for tid in wf.transitions.keys():
            tdef = wf.transitions.get(tid, None)
            if tdef is not None and \
               tdef.trigger_type == TRIGGER_USER_ACTION and \
               tdef.actbox_name and \
               not result.has_key(tdef.id):
                result[tdef.id] = {
                    'id': tdef.id,
                    'title': tdef.title,
                    'title_or_id': tdef.title_or_id(),
                    'description': tdef.description,
                    'name': tdef.actbox_name
                }

        return tuple(result.values())

    #security.declarePrivate('getWfTransitionsDisplayList')
    def getWfTransitionsDisplayList(self, wfName=config.ECA_WORKFLOW_ID):
        """
        @return a DisplayList containing all transition keys and titles in 
                assignment's workflow
        """
        dl = DisplayList(())

        #wtool = self.portal_workflow
        #wf = wtool.getWorkflowById(wfName)

        for transition in self.getWfTransitions():
            # FIXME: not sure if this works with the result
            # from getWfTransitions
            dl.add(transition.id, transition.actbox_name)

        return dl.sortedByValue()

    #security.declarePublic('localizeNumber')
    def localizeNumber(self, format, value):
        """
        A simple method for localized formatting of decimal numbers,
        similar to locale.format().
        """

        #LOG.info('format: %s' % format)
        #LOG.info('value: %s' % value)

        if not value: return None

        result = format % value
        fields = result.split(".")
        decimalSeparator = self.translate(msgid='decimal_separator',
                                          domain=config.I18N_DOMAIN,
                                          default='.')
        if len(fields) == 2:
            result = fields[0] + decimalSeparator + fields[1]
        elif len(fields) == 1:
            result = fields[0]
        else:
            raise ValueError, "Too many decimal points in result string"

        return result

    #security.declarePublic('getFullNameById')
    def getFullNameById(self, id):
        """
        Returns the full name of a user by the given ID.  If full name is
        devided into given and last name, we return it in the format
        Doo, John; otherwise we will return 'fullname' as provided by Plone. 
        """
        #LOG.debug('Here we are in ECABTool#getFullNameById')

        mtool = self.portal_membership
        member = mtool.getMemberById(id)
        error = False

        if not member:
            return id

        try:
            sn = member.getProperty('sn', None)
            givenName = member.getProperty('givenName', None)

        except:
            error = True

        #LOG.info('xdebug: sn, givenName: %s, %s' % (type(sn), type(givenName)))
        #LOG.info('xdebug: sn, givenName: %s, %s' % (sn, givenName))

        if error or (not sn) or (not givenName):
            fullname = member.getProperty('fullname', '')

            if fullname == '':
                return id
            else:
                return fullname

            #if fullname.find(' ') == -1:
            #    return fullname
            #
            #sn = fullname[fullname.rfind(' ') + 1:]
            #givenName = fullname[0:fullname.find(' ')]

        else:
            #return sn + ', ' + givenName
            # print 'givenName, sn: %s, %s' % (givenName, sn, )
            return '%s, %s' % (sn, givenName)

    security.declarePublic('getUserPropertyById')

    def getUserPropertyById(self, userId, property, fallback=None):
        """
        @return: Value for 'property' or None
        """

        #LOG.info('xdebug: %s, %s, %s' % (userId, property, fallback, ))

        membership = getToolByName(self, 'portal_membership')
        member = membership.getMemberById(userId)

        try:
            return member.getProperty(property, fallback)
        except:
            return fallback

    #security.declarePublic('testAssignmentBoxType')
    def testAssignmentBoxType(self, item=None):
        """
        Returns True if item has an attribut 'isAssignmentBoxType' or - in case
        item is a catalog brain- index 'isAssignmentBoxType' is True
        """

        #LOG.debug('Here we are in ECABTool#testAssignmentBoxType: %s' % item)

        result = None

        if (item and hasattr(item, 'isAssignmentBoxType')):
            result = item.isAssignmentBoxType

            # dirty hack
            if repr(result) == 'Missing.Value':
                result = False

        else:
            result = False

        #LOG.info('result: %s' % repr(result))

        return result

    #security.declarePublic('isGrader')
    def isGrader(self, item, id=None):
        """
        Returns True if the user given by id has permission to grade the
        assignment given by item; otherwise False.

        If id is None, the check will be done for the current user.

        @param item an assignment
        @param id a user id
        """
        mtool = self.portal_membership

        if not id:
            member = mtool.getAuthenticatedMember()
        else:
            member = mtool.getMemberById(id)

        return member.checkPermission(config.GradeAssignments, item)

    #security.declarePublic('getStatesToShow')
    def getStatesToShow(self, showSuperseded=False, state=None):
        """
        Returns a list of state names which will be used as a filter
        for showing assignments.
        """

        # FIXME: states are static names but they shoul better be taken from
        #        workflow_tool for the given object
        result = (
            'submitted',
            'pending',
            'accepted',
            'rejected',
            'graded',
        )

        if state is not None:
            if type(state) not in [tuple, list]:
                state = (state, )
            result = [s for s in state if s in result]

        if showSuperseded:
            result += ('superseded', )

        return result

    #security.declarePublic('findAssignments')
    def findAssignments(self, context, id):
        """
        """
        ct = getToolByName(self, 'portal_catalog')
        ntp = getToolByName(self, 'portal_properties').navtree_properties
        currentPath = None
        query = {}

        if context == self:
            currentPath = getToolByName(self, 'portal_url').getPortalPath()
            query['path'] = {
                'query': currentPath,
                'depth': ntp.getProperty('sitemapDepth', 2)
            }
        else:
            currentPath = '/'.join(context.getPhysicalPath())
            query['path'] = {'query': currentPath, 'navtree': 1}

        query['portal_type'] = ('ECAssignment', )
        #rawresult = ct(**query)
        rawresult = ct(path=currentPath,
                       portal_type='ECAssignment',
                       Creator=id)
        return rawresult

    #security.declarePublic('calculateMean')
    def calculateMean(self, list):
        """
        """
        try:
            stats = Statistics(map((float), list))
        #except Exception, e:
        #    LOG.warn("calculateMean: %s: %s" % (sys.exc_info()[0], e))
        except:
            return None

        return stats.mean

    #security.declarePublic('calculateMedian')
    def calculateMedian(self, list):
        """
        """
        try:
            stats = Statistics(map((float), list))
        #except Exception, e:
        #    LOG.warn("calculateMedian: %s: %s" % (sys.exc_info()[0], e))
        except:
            return None

        return stats.median

    #security.declarePublic('normalizeURL')
    def normalizeURL(self, url):
        """
        Takes a URL (as returned by absolute_url(), for example) and
        replaces the hostname with the actual, fully-qualified
        hostname.
        """
        url_parts = urlsplit(url)
        hostpart = url_parts[1]
        port = ''

        if hostpart.find(':') != -1:
            (hostname, port) = split(hostpart, ':')
        else:
            hostname = hostpart

        if hostname == 'localhost' or hostname == '127.0.0.1':
            hostname = getfqdn(gethostname())
        else:
            hostname = getfqdn(hostname)

        if port:
            hostpart = join((hostname, port), ':')

        url = urlunsplit((url_parts[0], hostpart, \
                          url_parts[2], url_parts[3], url_parts[4]))
        return url

    #security.declarePublic('urlencode')
    def urlencode(self, *args, **kwargs):
        """
        """
        return urllib.urlencode(*args, **kwargs)

    #security.declarePublic('parseQueryString')
    def parseQueryString(self, *args, **kwargs):
        """
        """
        return cgi.parse_qs(*args, **kwargs)

    #security.declarePrivate('sendEmail')
    def sendEmail(self, addresses, subject, text):
        """
        Send an e-mail message to the specified list of addresses.
        """

        if not addresses:
            return

        portal_url = getToolByName(self, 'portal_url')
        #plone_utils = getToolByName(self, 'plone_utils')

        portal = portal_url.getPortalObject()
        fromAddress = portal.getProperty('email_from_address', None)

        #mailHost    = plone_utils.getMailHost()
        #charset     = plone_utils.getSiteEncoding()
        mailHost = getToolByName(portal, 'MailHost')  #self.MailHost
        charset = portal.getProperty('email_charset', 'UTF-8')

        if fromAddress is None:
            LOG.error('Cannot send email: address or name is %s' % fromAddress)
            return

        try:
            if (type(text) == unicode):
                msg = MIMEText(text.encode(charset), 'plain', charset)
            else:
                msg = MIMEText(text, 'plain', charset)
        except Exception, e:
            LOG.error('Cannot send notification email: %s' % e)
            return

        try:
            if (type(subject) == unicode):
                subjHeader = Header(subject.encode(charset), charset)
            else:
                subjHeader = Header(subject, charset)
        except Exception, e:
            LOG.error('Cannot send notification email: %s' % e)
            return
        # This is a hack to suppress deprecation messages about send()
        # in SecureMailHost; the proposed alternative, secureSend(),
        # sucks.
        mailHost._v_send = 1

        for address in addresses:
            if address:
                try:
                    LOG.info("Sending email to %r" % address)

                    msg['To'] = address

                    mailHost.send(msg.as_string())

                except ConflictError, ce:
                    LOG.error('Failed sending email: %s' % ce)
                    raise
                except Exception, e:
                    LOG.error('Failed sending email from %s to %s' %
                              (fromAddress, address))
                    LOG.error("Reason: %s: %r" %
                              (e.__class__.__name__, str(e)))
            # end if
        # end for

    #security.declarePrivate('pathQuote')
    def pathQuote(self, string=''):
        """
        Returns a string which is save to use as a filename.

        @param string some string