'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):

    repository = self.repository
    resource_name = task.resource_name
    log = repository.log
    remote = False
    output = None
    current.log.debug(('S3SyncRepository.push(%s,    %s)' % (repository.url, resource_name)))
    resource = current.s3db.resource(resource_name)
    filters = current.sync.get_filters(task.id)
    table = resource.table
    tablename = resource.tablename
    if filters:
        queries = S3URLQuery.parse(resource, filters[tablename])
        [resource.add_filter(q) for a in queries for q in queries[a]]
    msince = task.last_push
    if msince:
        strategy = task.strategy
        created = ('create' in strategy)
        updated = ('update' in strategy)
        if (created and updated):
            mtime_filter = (table.modified_on > msince)
        elif created:
            mtime_filter = (table.created_on > msince)
        elif updated:
            mtime_filter = ((table.created_on <= msince) & (table.modified_on > msince))
        else:
            mtime_filter = None
        if mtime_filter:
            resource.add_filter(mtime_filter)
    mtime = resource.muntil
    resource_ids = resource.get_id()
    if (resource_ids is None):
        message = 'No    Changes    since    last    push'
        result = log.WARNING
    else:
        settings = current.deployment_settings
        placeholders = {'systemname': settings.get_system_name(), 'systemname_short': settings.get_system_name_short(), 'resource': resource_name, 'public_url': settings.get_base_public_url()}
        from string import Template
        filename = resource.get_config('upload_filename')
        if (not filename):
            filename = settings.get_sync_upload_filename()
        filename = Template(filename).safe_substitute(s='%(systemname_short)s', r='%(resource)s')
        filename = (filename % placeholders)
        representation = task.representation
        filename = ('%s.%s' % (filename, representation))
        remote = True
        import ftplib
        ftp_connection = self.ftp_connection
        if task.multiple_file:
            if (type(resource_ids) is not list):
                resource_ids = [resource_ids]
            for resource_id in resource_ids:
                resource.clear_query()
                resource.add_filter((FS('id') == resource_id))
                data = self._get_data(resource, representation)
                try:
                    ftp_connection.storbinary(('STOR    %s' % filename), StringIO(data))
                except ftplib.error_perm:
                    message = sys.exc_info()[1]
                    result = log.ERROR
                    output = message
                else:
                    message = 'FTP    Transfer    Successful'
                    result = log.SUCCESS
                current.log.debug(message)
        else:
            data = self._get_data(resource, representation)
            try:
                ftp_connection.storbinary(('STOR    %s' % filename), StringIO(data))
            except ftplib.error_perm:
                message = sys.exc_info()[1]
                result = log.ERROR
                output = message
            else:
                message = 'FTP    Transfer    Successful'
                result = log.SUCCESS
            current.log.debug(message)
        ftp_connection.quit()
    log.write(repository_id=repository.id, resource_name=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)
