'Method to retrieve updates for a subscription, render the
notification message and send it - responds to POST?format=msg
requests to the respective resource.
@param r: the S3Request
@param resource: the S3Resource'

@classmethod
def send(cls, r, resource):

    _debug = current.log.debug
    _debug('S3Notifications.send()')
    json_message = current.xml.json_message
    source = r.body
    source.seek(0)
    data = source.read()
    subscription = json.loads(data)
    notify_on = subscription['notify_on']
    methods = subscription['method']
    if ((not notify_on) or (not methods)):
        return json_message(message='No    notifications    configured    for    this    subscription')
    pe_id = subscription['pe_id']
    if (not pe_id):
        r.unauthorised()
    fields = resource.list_fields(key='notify_fields')
    if ('created_on' not in fields):
        fields.append('created_on')
    data = resource.select(fields, represent=True, raw_data=True)
    rows = data['rows']
    numrows = len(rows)
    if (not numrows):
        return json_message(message='No    records    found')
    get_config = resource.get_config
    settings = current.deployment_settings
    page_url = subscription['page_url']
    crud_strings = current.response.s3.crud_strings.get(resource.tablename)
    if crud_strings:
        resource_name = crud_strings.title_list
    else:
        resource_name = string.capwords(resource.name, '_')
    last_check_time = s3_decode_iso_datetime(subscription['last_check_time'])
    email_format = subscription['email_format']
    if (not email_format):
        email_format = settings.get_msg_notify_email_format()
    filter_query = subscription.get('filter_query')
    meta_data = {'systemname': settings.get_system_name(), 'systemname_short': settings.get_system_name_short(), 'resource': resource_name, 'page_url': page_url, 'notify_on': notify_on, 'last_check_time': last_check_time, 'filter_query': filter_query, 'total_rows': numrows}
    renderer = get_config('notify_renderer')
    if (not renderer):
        renderer = settings.get_msg_notify_renderer()
    if (not renderer):
        renderer = cls._render
    contents = {}
    if ((email_format == 'html') and ('EMAIL' in methods)):
        contents['html'] = renderer(resource, data, meta_data, 'html')
        contents['default'] = contents['html']
    if ((email_format != 'html') or ('EMAIL' not in methods) or (len(methods) > 1)):
        contents['text'] = renderer(resource, data, meta_data, 'text')
        contents['default'] = contents['text']
    subject = get_config('notify_subject')
    if (not subject):
        subject = settings.get_msg_notify_subject()
    if callable(subject):
        subject = subject(resource, data, meta_data)
    from string import Template
    subject = Template(subject).safe_substitute(S='%(systemname)s', s='%(systemname_short)s', r='%(resource)s')
    subject = (subject % meta_data)
    attachment = subscription.get('attachment', False)
    document_ids = None
    if attachment:
        attachment_fnc = settings.get_msg_notify_attachment()
        if attachment_fnc:
            document_ids = attachment_fnc(resource, data, meta_data)
    join = (lambda *f: os.path.join(current.request.folder, *f))
    def get_template(path, filenames):
        for fn in filenames:
            filepath = join(path, fn)
            if os.path.exists(filepath):
                try:
                    return open(filepath, 'rb')
                except:
                    pass
        return None
    themes = settings.get_template()
    prefix = resource.get_config('notify_template', 'notify')
    send = current.msg.send_by_pe_id
    success = False
    errors = []
    for method in methods:
        error = None
        template = None
        filenames = [('%s_%s.html' % (prefix, method.lower()))]
        if ((method == 'EMAIL') and email_format):
            filenames.insert(0, ('%s_email_%s.html' % (prefix, email_format)))
        if (themes != 'default'):
            location = settings.get_template_location()
            if (not isinstance(themes, (tuple, list))):
                themes = (themes,)
            for theme in themes[::(-1)]:
                path = join(location, 'templates', theme, 'views', 'msg')
                template = get_template(path, filenames)
                if (template is not None):
                    break
        if (template is None):
            path = join('views', 'msg')
            template = get_template(path, filenames)
        if (template is None):
            template = StringIO(s3_str(current.T('New    updates    are    available.')))
        if ((method == 'EMAIL') and (email_format == 'html')):
            output = contents['html']
        else:
            output = contents['text']
        try:
            message = current.response.render(template, output)
        except:
            exc_info = sys.exc_info()[:2]
            error = ('%s:    %s' % (exc_info[0].__name__, exc_info[1]))
            errors.append(error)
            continue
        if (not message):
            continue
        try:
            sent = send(pe_id, subject=s3_truncate(subject, 78), message=message, contact_method=method, system_generated=True, document_ids=document_ids)
        except:
            exc_info = sys.exc_info()[:2]
            error = ('%s:    %s' % (exc_info[0].__name__, exc_info[1]))
            sent = False
        if sent:
            success = True
        else:
            if (not error):
                error = current.session.error
                if isinstance(error, list):
                    error = '/'.join(error)
            if error:
                errors.append(error)
    if errors:
        message = ',    '.join(errors)
    else:
        message = 'Success'
    return json_message(success=success, statuscode=(200 if success else 403), message=message)
