'Asynchronous task to notify a subscriber about updates,
runs a POST?format=msg request against the subscribed
controller which extracts the data and renders and sends
the notification message (see send()).
@param resource_id: the pr_subscription_resource record ID'

@classmethod
def notify(cls, resource_id):

    _debug = current.log.debug
    _debug(('S3Notifications.notify(resource_id=%s)' % resource_id))
    db = current.db
    s3db = current.s3db
    stable = s3db.pr_subscription
    rtable = db.pr_subscription_resource
    ftable = s3db.pr_filter
    join = stable.on((rtable.subscription_id == stable.id))
    left = ftable.on((ftable.id == stable.filter_id))
    row = db((rtable.id == resource_id)).select(stable.id, stable.pe_id, stable.frequency, stable.notify_on, stable.method, stable.email_format, stable.attachment, rtable.id, rtable.resource, rtable.url, rtable.last_check_time, ftable.query, join=join, left=left).first()
    if (not row):
        return True
    s = getattr(row, 'pr_subscription')
    r = getattr(row, 'pr_subscription_resource')
    f = getattr(row, 'pr_filter')
    auth_token = str(uuid4())
    r.update_record(auth_token=auth_token)
    db.commit()
    settings = current.deployment_settings
    public_url = settings.get_base_public_url()
    lookup_url = ('%s/%s/%s' % (public_url, current.request.application, r.url.lstrip('/')))
    purl = list(urlparse.urlparse(lookup_url))
    last_check_time = s3_encode_iso_datetime(r.last_check_time)
    query = {'subscription': auth_token, 'format': 'msg'}
    if ('upd' in s.notify_on):
        query['~.modified_on__ge'] = last_check_time
    else:
        query['~.created_on__ge'] = last_check_time
    if f.query:
        from s3filter import S3FilterString
        resource = s3db.resource(r.resource)
        fstring = S3FilterString(resource, f.query)
        for (k, v) in fstring.get_vars.iteritems():
            if (v is not None):
                if (k in query):
                    value = query[k]
                    if (type(value) is list):
                        value.append(v)
                    else:
                        query[k] = [value, v]
                else:
                    query[k] = v
        query_nice = s3_unicode(fstring.represent())
    else:
        query_nice = None
    query = urlencode(query)
    if purl[4]:
        query = '&'.join((purl[4], query))
    page_url = urlparse.urlunparse([purl[0], purl[1], purl[2], purl[3], query, purl[5]])
    data = json.dumps({'pe_id': s.pe_id, 'notify_on': s.notify_on, 'method': s.method, 'email_format': s.email_format, 'attachment': s.attachment, 'resource': r.resource, 'last_check_time': last_check_time, 'filter_query': query_nice, 'page_url': lookup_url, 'item_url': None})
    _debug(('Requesting    %s' % page_url))
    req = urllib2.Request(page_url, data=data)
    req.add_header('Content-Type', 'application/json')
    success = False
    try:
        response = json.loads(urllib2.urlopen(req).read())
        message = response['message']
        if (response['status'] == 'success'):
            success = True
    except urllib2.HTTPError as e:
        message = ('HTTP    %s:    %s' % (e.code, e.read()))
    except:
        exc_info = sys.exc_info()[:2]
        message = ('%s:    %s' % (exc_info[0].__name__, exc_info[1]))
    _debug(message)
    intervals = s3db.pr_subscription_check_intervals
    interval = datetime.timedelta(minutes=intervals.get(s.frequency, 0))
    if success:
        last_check_time = datetime.datetime.utcnow()
        next_check_time = (last_check_time + interval)
        r.update_record(auth_token=None, locked=False, last_check_time=last_check_time, next_check_time=next_check_time)
    else:
        r.update_record(auth_token=None, locked=False)
    db.commit()
    return message
