'Extract new updates from the local database and send
them to the peer repository (active push)
@param task: the synchronization task (sync_task Row)
@return: tuple (error, mtime), with error=None if successful,
else error=message, and mtime=modification timestamp
of the youngest record sent'

def push(self, task):

    xml = current.xml
    _debug = current.log.debug
    repository = self.repository
    config = repository.config
    resource_name = task.resource_name
    _debug(('S3SyncRepository.push(%s,    %s)' % (repository.url, resource_name)))
    url = ('%s/sync/sync.xml?resource=%s&repository=%s' % (repository.url, resource_name, config.uuid))
    strategy = task.strategy
    if strategy:
        url += ('&strategy=%s' % ','.join(strategy))
    update_policy = task.update_policy
    if update_policy:
        url += ('&update_policy=%s' % update_policy)
    conflict_policy = task.conflict_policy
    if conflict_policy:
        url += ('&conflict_policy=%s' % conflict_policy)
    last_push = task.last_push
    if (last_push and (update_policy not in ('THIS', 'OTHER'))):
        url += ('&msince=%s' % s3_encode_iso_datetime(last_push))
    else:
        last_push = None
    _debug(('...push    to    URL    %s' % url))
    if (task.components is False):
        components = []
    else:
        components = None
    resource = current.s3db.resource(resource_name, components=components, include_deleted=True)
    filters = current.sync.get_filters(task.id)
    data = resource.export_xml(filters=filters, msince=last_push)
    count = (resource.results or 0)
    mtime = resource.muntil
    remote = False
    output = None
    log = repository.log
    if (data and count):
        url_split = url.split('://', 1)
        if (len(url_split) == 2):
            protocol = url_split[0]
        else:
            protocol = 'http'
        req = urllib2.Request(url=url, data=data)
        req.add_header('Content-Type', 'text/xml')
        handlers = []
        proxy = (repository.proxy or config.proxy or None)
        if proxy:
            _debug(('using    proxy=%s' % proxy))
            proxy_handler = urllib2.ProxyHandler({protocol: proxy})
            handlers.append(proxy_handler)
        username = repository.username
        password = repository.password
        if (username and password):
            import base64
            base64string = base64.encodestring(('%s:%s' % (username, password)))[:(-1)]
            req.add_header('Authorization', ('Basic    %s' % base64string))
            passwd_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
            passwd_manager.add_password(realm=None, uri=url, user=username, passwd=password)
            auth_handler = urllib2.HTTPBasicAuthHandler(passwd_manager)
            handlers.append(auth_handler)
        if handlers:
            opener = urllib2.build_opener(*handlers)
            urllib2.install_opener(opener)
        try:
            f = urllib2.urlopen(req)
        except urllib2.HTTPError as e:
            result = log.FATAL
            remote = True
            code = e.code
            message = e.read()
            try:
                message_json = json.loads(message)
                message = message_json.get('message', message)
            except:
                pass
            output = xml.json_message(False, code, message)
        except:
            result = log.FATAL
            code = 400
            message = sys.exc_info()[1]
            output = xml.json_message(False, code, message)
        else:
            result = log.SUCCESS
            message = ('data    sent    successfully    (%s    records)' % count)
    else:
        result = log.WARNING
        message = 'No    data    to    send'
    log.write(repository_id=repository.id, resource_name=task.resource_name, transmission=log.OUT, mode=log.PUSH, action='send', remote=remote, result=result, message=message)
    if (output is not None):
        mtime = None
    return (output, mtime)
