def _log_cb(changed_paths, revision, author, datestr, message, pool, retval=revs): date = _datestr_to_date(datestr) action_map = { 'D' : vclib.DELETED, 'A' : vclib.ADDED, 'R' : vclib.REPLACED, 'M' : vclib.MODIFIED, } paths = (changed_paths or {}).keys() paths.sort(lambda a, b: _compare_paths(a, b)) changes = [] found_readable = found_unreadable = 0 for path in paths: pathtype = None change = changed_paths[path] action = action_map.get(change.action, vclib.MODIFIED) ### Wrong, diddily wrong wrong wrong. Can you say, ### "Manufacturing data left and right because it hurts to ### figure out the right stuff?" if change.copyfrom_path and change.copyfrom_rev: is_copy = 1 base_path = change.copyfrom_path base_rev = change.copyfrom_rev elif action == vclib.ADDED or action == vclib.REPLACED: is_copy = 0 base_path = base_rev = None else: is_copy = 0 base_path = path base_rev = revision - 1 ### Check authz rules (we lie about the path type) parts = _path_parts(path) if vclib.check_path_access(self, parts, vclib.FILE, revision): if is_copy and base_path and (base_path != path): parts = _path_parts(base_path) if vclib.check_path_access(self, parts, vclib.FILE, base_rev): is_copy = 0 base_path = None base_rev = None changes.append(SVNChangedPath(path, revision, pathtype, base_path, base_rev, action, is_copy, 0, 0)) found_readable = 1 else: found_unreadable = 1 if found_unreadable: message = None if not found_readable: author = None date = None revs.append([date, author, message, changes])
def _get_dirents(self, path, rev): """Return a 2-type of dirents and locks, possibly reading/writing from a local cache of that information. This functions performs authz checks, stripping out unreadable dirents.""" dir_url = self._geturl(path) path_parts = _path_parts(path) if path: key = str(rev) + '/' + path else: key = str(rev) # Ensure that the cache gets filled... dirents_locks = self._dirent_cache.get(key) if not dirents_locks: tmp_dirents, locks = list_directory(dir_url, _rev2optrev(rev), _rev2optrev(rev), 0, self.ctx) dirents = {} for name, dirent in tmp_dirents.items(): dirent_parts = path_parts + [name] kind = dirent.kind if (kind == core.svn_node_dir or kind == core.svn_node_file) \ and vclib.check_path_access(self, dirent_parts, kind == core.svn_node_dir \ and vclib.DIR or vclib.FILE, rev): lh_rev, c_rev = self._get_last_history_rev(dirent_parts, rev) dirent.created_rev = lh_rev dirents[name] = dirent dirents_locks = [dirents, locks] self._dirent_cache[key] = dirents_locks # ...then return the goodies from the cache. return dirents_locks[0], dirents_locks[1]
def _get_dirents(self, path, rev): """Return a 2-type of dirents and locks, possibly reading/writing from a local cache of that information. This functions performs authz checks, stripping out unreadable dirents.""" dir_url = self._geturl(path) path_parts = _path_parts(path) if path: key = str(rev) + '/' + path else: key = str(rev) # Ensure that the cache gets filled... dirents_locks = self._dirent_cache.get(key) if not dirents_locks: tmp_dirents, locks = list_directory(dir_url, _rev2optrev(rev), _rev2optrev(rev), 0, self.ctx) dirents = {} for name, dirent in tmp_dirents.items(): dirent_parts = path_parts + [name] kind = dirent.kind if (kind == core.svn_node_dir or kind == core.svn_node_file) \ and vclib.check_path_access(self, dirent_parts, kind == core.svn_node_dir \ and vclib.DIR or vclib.FILE, rev): lh_rev, c_rev = self._get_last_history_rev( dirent_parts, rev) dirent.created_rev = lh_rev dirents[name] = dirent dirents_locks = [dirents, locks] self._dirent_cache[key] = dirents_locks # ...then return the goodies from the cache. return dirents_locks[0], dirents_locks[1]
def created_rev(self, path, rev): # NOTE: We can't use svn_client_propget here because the # interfaces in that layer strip out the properties not meant for # human consumption (such as svn:entry:committed-rev, which we are # using here to get the created revision of PATH@REV). kind = ra.svn_ra_check_path(self.ra_session, path, rev) if kind == core.svn_node_none: raise vclib.ItemNotFound(_path_parts(path)) elif kind == core.svn_node_dir: props = get_directory_props(self.ra_session, path, rev) elif kind == core.svn_node_file: fetched_rev, props = ra.svn_ra_get_file(self.ra_session, path, rev, None) return int(props.get(core.SVN_PROP_ENTRY_COMMITTED_REV, SVN_INVALID_REVNUM))
def created_rev(self, path, rev): # NOTE: We can't use svn_client_propget here because the # interfaces in that layer strip out the properties not meant for # human consumption (such as svn:entry:committed-rev, which we are # using here to get the created revision of PATH@REV). kind = ra.svn_ra_check_path(self.ra_session, path, rev) if kind == core.svn_node_none: raise vclib.ItemNotFound(_path_parts(path)) elif kind == core.svn_node_dir: props = get_directory_props(self.ra_session, path, rev) elif kind == core.svn_node_file: fetched_rev, props = ra.svn_ra_get_file(self.ra_session, path, rev, None) return int( props.get(core.SVN_PROP_ENTRY_COMMITTED_REV, SVN_INVALID_REVNUM))
def created_rev(self, path, rev): lh_rev, c_rev = self._get_last_history_rev(_path_parts(path), rev) return lh_rev
def _log_cb(log_entry, pool, retval=revs): # If Subversion happens to call us more than once, we choose not # to care. if retval: return revision = log_entry.revision msg, author, date, revprops = _split_revprops(log_entry.revprops) action_map = { 'D': vclib.DELETED, 'A': vclib.ADDED, 'R': vclib.REPLACED, 'M': vclib.MODIFIED, } # Easy out: if we won't use the changed-path info, just return a # changes-less tuple. if not need_changes: return revs.append([date, author, msg, revprops, None]) # Subversion 1.5 and earlier didn't offer the 'changed_paths2' # hash, and in Subversion 1.6, it's offered but broken. try: changed_paths = log_entry.changed_paths2 paths = (changed_paths or {}).keys() except: changed_paths = log_entry.changed_paths paths = (changed_paths or {}).keys() paths.sort(lambda a, b: _compare_paths(a, b)) # If we get this far, our caller needs changed-paths, or we need # them for authz-related sanitization. changes = [] found_readable = found_unreadable = 0 for path in paths: change = changed_paths[path] # svn_log_changed_path_t (which we might get instead of the # svn_log_changed_path2_t we'd prefer) doesn't have the # 'node_kind' member. pathtype = None if hasattr(change, 'node_kind'): if change.node_kind == core.svn_node_dir: pathtype = vclib.DIR elif change.node_kind == core.svn_node_file: pathtype = vclib.FILE # svn_log_changed_path2_t only has the 'text_modified' and # 'props_modified' bits in Subversion 1.7 and beyond. And # svn_log_changed_path_t is without. text_modified = props_modified = 0 if hasattr(change, 'text_modified'): if change.text_modified == core.svn_tristate_true: text_modified = 1 if hasattr(change, 'props_modified'): if change.props_modified == core.svn_tristate_true: props_modified = 1 # Wrong, diddily wrong wrong wrong. Can you say, # "Manufacturing data left and right because it hurts to # figure out the right stuff?" action = action_map.get(change.action, vclib.MODIFIED) if change.copyfrom_path and change.copyfrom_rev: is_copy = 1 base_path = change.copyfrom_path base_rev = change.copyfrom_rev elif action == vclib.ADDED or action == vclib.REPLACED: is_copy = 0 base_path = base_rev = None else: is_copy = 0 base_path = path base_rev = revision - 1 # Check authz rules (sadly, we have to lie about the path type) parts = _path_parts(path) if vclib.check_path_access(self, parts, vclib.FILE, revision): if is_copy and base_path and (base_path != path): parts = _path_parts(base_path) if not vclib.check_path_access(self, parts, vclib.FILE, base_rev): is_copy = 0 base_path = None base_rev = None found_unreadable = 1 changes.append( SVNChangedPath(path, revision, pathtype, base_path, base_rev, action, is_copy, text_modified, props_modified)) found_readable = 1 else: found_unreadable = 1 # If our caller doesn't want changed-path stuff, and we have # the info we need to make an authz determination already, # quit this loop and get on with it. if (not include_changed_paths ) and found_unreadable and found_readable: break # Filter unreadable information. if found_unreadable: msg = None if not found_readable: author = None date = None # Drop unrequested changes. if not include_changed_paths: changes = None # Add this revision information to the "return" array. retval.append([date, author, msg, revprops, changes])
def _access_checker(check_path, check_rev): return vclib.check_path_access(self, _path_parts(check_path), path_type, check_rev)
return self.youngest def get_location(self, path, rev, old_rev): try: results = ra.get_locations(self.ra_session, path, rev, [old_rev]) except core.SubversionException, e: _fix_subversion_exception(e) if e.apr_err == core.SVN_ERR_FS_NOT_FOUND: raise vclib.ItemNotFound(path) raise try: old_path = results[old_rev] except KeyError: raise vclib.ItemNotFound(path) old_path = _cleanup_path(old_path) old_path_parts = _path_parts(old_path) # Check access (lying about path types) if not vclib.check_path_access(self, old_path_parts, vclib.FILE, old_rev): raise vclib.ItemNotFound(path) return old_path def created_rev(self, path, rev): lh_rev, c_rev = self._get_last_history_rev(_path_parts(path), rev) return lh_rev def last_rev(self, path, peg_revision, limit_revision=None): """Given PATH, known to exist in PEG_REVISION, find the youngest revision older than, or equal to, LIMIT_REVISION in which path exists. Return that revision, and the path at which PATH exists in that revision."""
def _log_cb(log_entry, pool, retval=revs): # If Subversion happens to call us more than once, we choose not # to care. if retval: return revision = log_entry.revision msg, author, date, revprops = _split_revprops(log_entry.revprops) action_map = { 'D' : vclib.DELETED, 'A' : vclib.ADDED, 'R' : vclib.REPLACED, 'M' : vclib.MODIFIED, } # Easy out: if we won't use the changed-path info, just return a # changes-less tuple. if not need_changes: return revs.append([date, author, msg, revprops, None]) # Subversion 1.5 and earlier didn't offer the 'changed_paths2' # hash, and in Subversion 1.6, it's offered but broken. try: changed_paths = log_entry.changed_paths2 paths = (changed_paths or {}).keys() except: changed_paths = log_entry.changed_paths paths = (changed_paths or {}).keys() paths.sort(lambda a, b: _compare_paths(a, b)) # If we get this far, our caller needs changed-paths, or we need # them for authz-related sanitization. changes = [] found_readable = found_unreadable = 0 for path in paths: change = changed_paths[path] # svn_log_changed_path_t (which we might get instead of the # svn_log_changed_path2_t we'd prefer) doesn't have the # 'node_kind' member. pathtype = None if hasattr(change, 'node_kind'): if change.node_kind == core.svn_node_dir: pathtype = vclib.DIR elif change.node_kind == core.svn_node_file: pathtype = vclib.FILE # svn_log_changed_path2_t only has the 'text_modified' and # 'props_modified' bits in Subversion 1.7 and beyond. And # svn_log_changed_path_t is without. text_modified = props_modified = 0 if hasattr(change, 'text_modified'): if change.text_modified == core.svn_tristate_true: text_modified = 1 if hasattr(change, 'props_modified'): if change.props_modified == core.svn_tristate_true: props_modified = 1 # Wrong, diddily wrong wrong wrong. Can you say, # "Manufacturing data left and right because it hurts to # figure out the right stuff?" action = action_map.get(change.action, vclib.MODIFIED) if change.copyfrom_path and change.copyfrom_rev: is_copy = 1 base_path = change.copyfrom_path base_rev = change.copyfrom_rev elif action == vclib.ADDED or action == vclib.REPLACED: is_copy = 0 base_path = base_rev = None else: is_copy = 0 base_path = path base_rev = revision - 1 # Check authz rules (sadly, we have to lie about the path type) parts = _path_parts(path) if vclib.check_path_access(self, parts, vclib.FILE, revision): if is_copy and base_path and (base_path != path): parts = _path_parts(base_path) if not vclib.check_path_access(self, parts, vclib.FILE, base_rev): is_copy = 0 base_path = None base_rev = None found_unreadable = 1 changes.append(SVNChangedPath(path, revision, pathtype, base_path, base_rev, action, is_copy, text_modified, props_modified)) found_readable = 1 else: found_unreadable = 1 # If our caller doesn't want changed-path stuff, and we have # the info we need to make an authz determination already, # quit this loop and get on with it. if (not include_changed_paths) and found_unreadable and found_readable: break # Filter unreadable information. if found_unreadable: msg = None if not found_readable: author = None date = None # Drop unrequested changes. if not include_changed_paths: changes = None # Add this revision information to the "return" array. retval.append([date, author, msg, revprops, changes])
def _log_cb(log_entry, pool, retval=revs): ### Subversion 1.5 and earlier didn't offer the 'changed_paths2' ### hash, and in Subversion 1.6, it's offered but broken. try: changed_paths = log_entry.changed_paths2 paths = (changed_paths or {}).keys() except: changed_paths = log_entry.changed_paths paths = (changed_paths or {}).keys() paths.sort(lambda a, b: _compare_paths(a, b)) revision = log_entry.revision msg, author, date, revprops = _split_revprops(log_entry.revprops) action_map = { 'D': vclib.DELETED, 'A': vclib.ADDED, 'R': vclib.REPLACED, 'M': vclib.MODIFIED, } changes = [] found_readable = found_unreadable = 0 for path in paths: change = changed_paths[path] ### svn_log_changed_path_t (which we might get instead of the ### svn_log_changed_path2_t we'd prefer) doesn't have the ### 'node_kind' member. pathtype = None if hasattr(change, 'node_kind'): if change.node_kind == core.svn_node_dir: pathtype = vclib.DIR elif change.node_kind == core.svn_node_file: pathtype = vclib.FILE ### svn_log_changed_path2_t only has the 'text_modified' and ### 'props_modified' bits in Subversion 1.7 and beyond. And ### svn_log_changed_path_t is without. text_modified = props_modified = 0 if hasattr(change, 'text_modified'): if change.text_modified == core.svn_tristate_true: text_modified = 1 if hasattr(change, 'props_modified'): if change.props_modified == core.svn_tristate_true: props_modified = 1 ### Wrong, diddily wrong wrong wrong. Can you say, ### "Manufacturing data left and right because it hurts to ### figure out the right stuff?" action = action_map.get(change.action, vclib.MODIFIED) if change.copyfrom_path and change.copyfrom_rev: is_copy = 1 base_path = change.copyfrom_path base_rev = change.copyfrom_rev elif action == vclib.ADDED or action == vclib.REPLACED: is_copy = 0 base_path = base_rev = None else: is_copy = 0 base_path = path base_rev = revision - 1 ### Check authz rules (we lie about the path type) parts = _path_parts(path) if vclib.check_path_access(self, parts, vclib.FILE, revision): if is_copy and base_path and (base_path != path): parts = _path_parts(base_path) if vclib.check_path_access(self, parts, vclib.FILE, base_rev): is_copy = 0 base_path = None base_rev = None changes.append( SVNChangedPath(path, revision, pathtype, base_path, base_rev, action, is_copy, text_modified, props_modified)) found_readable = 1 else: found_unreadable = 1 if found_unreadable: msg = None if not found_readable: author = None date = None revs.append([date, author, msg, revprops, changes])
def _log_cb(log_entry, pool, retval=revs): ### Subversion 1.5 and earlier didn't offer the 'changed_paths2' ### hash, and in Subversion 1.6, it's offered but broken. try: changed_paths = log_entry.changed_paths2 paths = (changed_paths or {}).keys() except: changed_paths = log_entry.changed_paths paths = (changed_paths or {}).keys() paths.sort(lambda a, b: _compare_paths(a, b)) revision = log_entry.revision msg, author, date, revprops = _split_revprops(log_entry.revprops) action_map = { 'D' : vclib.DELETED, 'A' : vclib.ADDED, 'R' : vclib.REPLACED, 'M' : vclib.MODIFIED, } changes = [] found_readable = found_unreadable = 0 for path in paths: change = changed_paths[path] ### svn_log_changed_path_t (which we might get instead of the ### svn_log_changed_path2_t we'd prefer) doesn't have the ### 'node_kind' member. pathtype = None if hasattr(change, 'node_kind'): if change.node_kind == core.svn_node_dir: pathtype = vclib.DIR elif change.node_kind == core.svn_node_file: pathtype = vclib.FILE ### svn_log_changed_path2_t only has the 'text_modified' and ### 'props_modified' bits in Subversion 1.7 and beyond. And ### svn_log_changed_path_t is without. text_modified = props_modified = 0 if hasattr(change, 'text_modified'): if change.text_modified == core.svn_tristate_true: text_modified = 1 if hasattr(change, 'props_modified'): if change.props_modified == core.svn_tristate_true: props_modified = 1 ### Wrong, diddily wrong wrong wrong. Can you say, ### "Manufacturing data left and right because it hurts to ### figure out the right stuff?" action = action_map.get(change.action, vclib.MODIFIED) if change.copyfrom_path and change.copyfrom_rev: is_copy = 1 base_path = change.copyfrom_path base_rev = change.copyfrom_rev elif action == vclib.ADDED or action == vclib.REPLACED: is_copy = 0 base_path = base_rev = None else: is_copy = 0 base_path = path base_rev = revision - 1 ### Check authz rules (we lie about the path type) parts = _path_parts(path) if vclib.check_path_access(self, parts, vclib.FILE, revision): if is_copy and base_path and (base_path != path): parts = _path_parts(base_path) if vclib.check_path_access(self, parts, vclib.FILE, base_rev): is_copy = 0 base_path = None base_rev = None changes.append(SVNChangedPath(path, revision, pathtype, base_path, base_rev, action, is_copy, text_modified, props_modified)) found_readable = 1 else: found_unreadable = 1 if found_unreadable: msg = None if not found_readable: author = None date = None revs.append([date, author, msg, revprops, changes])