'Pull updates from this repository
@param task: the task Row
@param onconflict: synchronization conflict resolver
@return: tuple (error, mtime), with error=None if successful,
else error=message, and mtime=modification timestamp
of the youngest record received'

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

    repository = self.repository
    resource_name = task.resource_name
    current.log.debug(('S3SyncWrike.pull(%s,    %s)' % (repository.url, resource_name)))
    xml = current.xml
    log = repository.log
    last_pull = task.last_pull
    if (last_pull and (task.update_policy not in ('THIS', 'OTHER'))):
        msince = s3_encode_iso_datetime(last_pull)
    else:
        msince = None
    root = etree.Element('wrike-data')
    (accounts, error) = self.fetch_accounts(root)
    if (accounts is not None):
        error = None
        def log_fetch_error(action, account_name, message):
            '    Helper    to    log    non-fatal    errors    during    fetch    '
            action = ("%s    for    account    '%s'" % (action, account_name))
            log.write(repository_id=repository.id, resource_name=resource_name, transmission=log.OUT, mode=log.PULL, action=action, remote=True, result=log.ERROR, message=message)
            return
        for (account_id, account_data) in accounts.items():
            (account_name, root_folder_id, recycle_bin_id) = account_data
            (response, message) = self.fetch_folders(root, account_id)
            if (response is None):
                log_fetch_error('fetch    folders', account_name, message)
                continue
            (response, message) = self.fetch_tasks(root, root_folder_id, msince=msince)
            if (response is None):
                log_fetch_error('fetch    active    tasks', account_name, message)
            (response, message) = self.fetch_tasks(root, recycle_bin_id, msince=msince, deleted=True)
            if (response is None):
                log_fetch_error('fetch    deleted    tasks', account_name, message)
    if error:
        result = log.FATAL
        remote = True
        message = error
        output = xml.json_message(False, 400, error)
    elif len(root):
        result = log.SUCCESS
        remote = False
        message = None
        output = None
        tree = etree.ElementTree(root)
        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', 'wrike', '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
        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:
            success = False
            result = log.FATAL
            message = sys.exc_info()[1]
            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.WARNING
        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)
    current.log.debug(('S3SyncWrike.pull    import    %s:    %s' % (result, message)))
    return (output, mtime)
