From 94bf56dd024b4fa33b5ae4c80f5091fec0995d1c Mon Sep 17 00:00:00 2001 From: Abdo Roig-Maranges Date: Sun, 10 Feb 2013 11:59:09 +0100 Subject: Support for extracting metadata from version control systems * Makes fsobject aware of vcs. * Makes directory get vcs status data when loading content. * Adds a config option to enable/disable the vcs info feature. --- ranger/fsobject/directory.py | 29 +++++++++++++++++++++++++++++ ranger/fsobject/file.py | 3 ++- ranger/fsobject/fsobject.py | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py index 2aa47a64..fa5db6cf 100644 --- a/ranger/fsobject/directory.py +++ b/ranger/fsobject/directory.py @@ -72,6 +72,8 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware): content_outdated = False content_loaded = False + has_vcschild=False + _cumulative_size_calculated = False sort_dict = { @@ -224,6 +226,10 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware): files = [] disk_usage = 0 + + self.has_vcschild = False + self.load_vcs() + for name in filenames: try: file_lstat = os_lstat(name) @@ -248,10 +254,33 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware): item = File(name, preload=stats, path_is_abs=True) item.load() disk_usage += item.size + + # Load vcs data + if self.settings.vcs_aware: + item.load_vcs() + if item.vcs and item.vcs.vcsname in self.settings.vcs_backends: + self.has_vcschild = True + try: + if self.vcs_outdated or item.vcs_outdated: + item.vcs_outdated = False + item.vcs.get_status() # caches the file status for get_file_status() + item.vcsbranch = item.vcs.get_branch() + item.vcshead = item.vcs.get_info(item.vcs.HEAD) + if item.path == item.vcs.root: + item.vcsremotestatus = item.vcs.get_remote_status() + else: + item.vcsbranch = self.vcsbranch + item.vcshead = self.vcshead + item.vcsfilestatus = item.vcs.get_file_status(item.path) + except: + raise + self.fm.notify("Can not load vcs data on %s" % item.path, bad=True) + files.append(item) self.percent = 100 * len(files) // len(filenames) yield self.disk_usage = disk_usage + self.vcs_outdated = False self.filenames = filenames self.files = files diff --git a/ranger/fsobject/file.py b/ranger/fsobject/file.py index 5831ed3f..8d75e740 100644 --- a/ranger/fsobject/file.py +++ b/ranger/fsobject/file.py @@ -3,6 +3,7 @@ import re from ranger.fsobject import FileSystemObject +from ranger.core.shared import SettingsAware N_FIRST_BYTES = 256 control_characters = set(chr(n) for n in @@ -37,7 +38,7 @@ PREVIEW_WHITELIST = re.compile(r""" $ """, re.VERBOSE | re.IGNORECASE) -class File(FileSystemObject): +class File(FileSystemObject, SettingsAware): is_file = True preview_data = None preview_known = False diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py index 02b32958..c044dbdb 100644 --- a/ranger/fsobject/fsobject.py +++ b/ranger/fsobject/fsobject.py @@ -18,6 +18,7 @@ from ranger.ext.shell_escape import shell_escape from ranger.ext.spawn import spawn from ranger.ext.lazy_property import lazy_property from ranger.ext.human_readable import human_readable +from ranger.vcs import Vcs if hasattr(str, 'maketrans'): maketrans = str.maketrans @@ -67,6 +68,13 @@ class FileSystemObject(FileManagerAware): size = 0 + (vcs, + vcsfilestatus, + vcsremotestatus, + vcsbranch, + vcshead) = (None,) * 5 + + vcs_outdated = False def __init__(self, path, preload=None, path_is_abs=False): if not path_is_abs: @@ -185,6 +193,38 @@ class FileSystemObject(FileManagerAware): return None # it is impossible to get the link destination return self.path + def load_vcs(self): + """ + Reads data regarding the version control system the object is on. + Does not load content specific data. + """ + + vcs = Vcs(self.path) + + # Not under vcs + if vcs.root == None: + return + + # Already know about the right vcs + elif self.vcs and abspath(vcs.root) == abspath(self.vcs.root): + self.vcs.update() + + # Need new Vcs object and self.path is the root + elif self.vcs == None and abspath(vcs.root) == abspath(self.path): + self.vcs = vcs + self.vcs_outdated = True + + # Otherwise, find the root, and try to get the Vcs object from there + else: + rootdir = self.fm.get_directory(vcs.root) + rootdir.load_if_outdated() + + # Get the Vcs object from rootdir + rootdir.load_vcs() + self.vcs = rootdir.vcs + if rootdir.vcs_outdated: + self.vcs_outdated = True + def load(self): """ reads useful information about the filesystem-object from the -- cgit 1.4.1-2-gfad0