'Fetch updates from the peer repository and import them
into the local database (active pull)
@param task: the synchronization task (sync_task Row)
@param onconflict: callback for automatic conflict resolution
@return: tuple (error, mtime), with error=None if successful,
else error=message, and mtime=modification timestamp
of the youngest record sent'

def pull(self, task, onconflict=None):

    xml = current.xml
    _debug = current.log.debug
    repository = self.repository
    log = repository.log
    resource_name = task.resource_name
    _debug(('S3SyncCiviCRM.pull(%s,    %s)' % (repository.url, resource_name)))
    mtime = None
    message = ''
    remote = False
    if (resource_name not in self.RESOURCE):
        result = log.FATAL
        message = ('Resource    type    %s    currently    not    supported    for    CiviCRM    synchronization' % resource_name)
        output = xml.json_message(False, 400, message)
    else:
        args = Storage(self.RESOURCE[resource_name])
        args['q'] += '/get'
        (tree, error) = self._send_request(method='GET', **args)
        if error:
            result = log.FATAL
            remote = True
            message = error
            output = xml.json_message(False, 400, error)
        elif len(tree.getroot()):
            result = log.SUCCESS
            remote = False
            strategy = task.strategy
            update_policy = task.update_policy
            conflict_policy = task.conflict_policy
            folder = current.request.folder
            import os
            stylesheet = os.path.join(folder, 'static', 'formats', 'ccrm', 'import.xsl')
            import urlparse
            hostname = urlparse.urlsplit(repository.url).hostname
            resource = current.s3db.resource(resource_name)
            if onconflict:
                onconflict_callback = (lambda item: onconflict(item, repository, resource))
            else:
                onconflict_callback = None
            count = 0
            success = True
            try:
                success = resource.import_xml(tree, stylesheet=stylesheet, ignore_errors=True, strategy=strategy, update_policy=update_policy, conflict_policy=conflict_policy, last_sync=task.last_pull, onconflict=onconflict_callback, site=hostname)
                count = resource.import_count
            except IOError as e:
                result = log.FATAL
                message = ('%s' % e)
                output = xml.json_message(False, 400, message)
            mtime = resource.mtime
            if (resource.error_tree is not None):
                result = log.WARNING
                message = ('%s' % resource.error)
                for element in resource.error_tree.findall('resource'):
                    for field in element.findall('data[@error]'):
                        error_msg = field.get('error', None)
                        if error_msg:
                            msg = ('(UID:    %s)    %s.%s=%s:    %s' % (element.get('uuid', None), element.get('name', None), field.get('field', None), field.get('value', field.text), field.get('error', None)))
                            message = ('%s,    %s' % (message, msg))
            if (not success):
                result = log.FATAL
                if (not message):
                    message = ('%s' % resource.error)
                output = xml.json_message(False, 400, message)
                mtime = None
            elif (not message):
                message = ('Data    imported    successfully    (%s    records)' % count)
                output = None
        else:
            result = log.ERROR
            remote = True
            message = 'No    data    received    from    peer'
            output = None
    log.write(repository_id=repository.id, resource_name=resource_name, transmission=log.OUT, mode=log.PULL, action=None, remote=remote, result=result, message=message)
    _debug(('S3SyncCiviCRM.pull    import    %s:    %s' % (result, message)))
    return (output, mtime)
