diff options
-rw-r--r-- | ranger/__init__.py | 2 | ||||
-rw-r--r-- | ranger/container/settingobject.py | 1 | ||||
-rw-r--r-- | ranger/core/actions.py | 5 | ||||
-rw-r--r-- | ranger/defaults/apps.py | 44 | ||||
-rw-r--r-- | ranger/defaults/options.py | 6 | ||||
-rw-r--r-- | ranger/defaults/rc.conf | 3 | ||||
-rw-r--r-- | ranger/ext/human_readable.py | 24 | ||||
-rw-r--r-- | ranger/fsobject/directory.py | 48 | ||||
-rw-r--r-- | ranger/fsobject/fsobject.py | 3 | ||||
-rw-r--r-- | ranger/gui/widgets/statusbar.py | 8 |
10 files changed, 112 insertions, 32 deletions
diff --git a/ranger/__init__.py b/ranger/__init__.py index df413a2c..df759dc8 100644 --- a/ranger/__init__.py +++ b/ranger/__init__.py @@ -36,7 +36,7 @@ TIME_BEFORE_FILE_BECOMES_GARBAGE = 1200 MACRO_DELIMITER = '%' LOGFILE = '/tmp/ranger_errorlog' USAGE = '%prog [options] [path/filename]' -STABLE = True +STABLE = False # If the environment variable XDG_CONFIG_HOME is non-empty, CONFDIR is ignored # and the configuration directory will be $XDG_CONFIG_HOME/ranger instead. diff --git a/ranger/container/settingobject.py b/ranger/container/settingobject.py index 5c24d663..51c12c6e 100644 --- a/ranger/container/settingobject.py +++ b/ranger/container/settingobject.py @@ -19,6 +19,7 @@ from ranger.core.shared import FileManagerAware ALLOWED_SETTINGS = { 'autosave_bookmarks': bool, + 'autoupdate_cumulative_size': bool, 'collapse_preview': bool, 'colorscheme_overlay': (type(None), type(lambda:0)), 'colorscheme': str, diff --git a/ranger/core/actions.py b/ranger/core/actions.py index c8922734..5364f391 100644 --- a/ranger/core/actions.py +++ b/ranger/core/actions.py @@ -87,6 +87,11 @@ class Actions(FileManagerAware, EnvironmentAware, SettingsAware): self.notify("Aborting: " + item.get_description()) self.loader.remove(index=0) + def get_cumulative_size(self): + for f in self.env.get_selection() or (): + f.look_up_cumulative_size() + self.ui.redraw_main_column() + def redraw_window(self): """Redraw the window""" self.ui.redraw_window() diff --git a/ranger/defaults/apps.py b/ranger/defaults/apps.py index 3ec6bff2..a53e2c8b 100644 --- a/ranger/defaults/apps.py +++ b/ranger/defaults/apps.py @@ -97,23 +97,35 @@ class CustomApplications(Applications): if f.extension is not None: if f.extension in ('pdf', ): - return self.either(c, 'evince', 'zathura', 'apvlv') + return self.either(c, 'evince', 'zathura', 'apvlv', 'okular') if f.extension == 'djvu': return self.either(c, 'evince') - if f.extension in ('xml', ): + if f.extension in ('xml', 'csv'): return self.either(c, 'editor') + if f.extension in ('html', 'htm', 'xhtml') or f.extension == 'swf': + c.flags += 'd' + handler = self.either(c, + 'luakit', 'uzbl', 'vimprobable', 'vimprobable2', 'jumanji', + 'firefox', 'seamonkey', 'iceweasel', 'opera', + 'surf', 'midori', 'epiphany', 'konqueror') + # Only return if some program was found: + if handler: + return handler if f.extension in ('html', 'htm', 'xhtml'): - return self.either(c, 'firefox', 'opera', 'jumanji', - 'luakit', 'elinks', 'lynx') - if f.extension == 'swf': - return self.either(c, 'firefox', 'opera', 'jumanji', 'luakit') + # These browsers can't handle flash, so they're not called above. + c.flags += 'D' + return self.either(c, 'elinks', 'links', 'links2', 'lynx', 'w3m') if f.extension == 'nes': return self.either(c, 'fceux') if f.extension in ('swc', 'smc', 'sfc'): return self.either(c, 'zsnes') - if f.extension in ('odt', 'ods', 'odp', 'odf', 'odg', - 'doc', 'xls'): - return self.either(c, 'libreoffice', 'soffice', 'ooffice') + if f.extension == 'doc': + return self.either(c, 'abiword', 'libreoffice', + 'soffice', 'ooffice') + if f.extension in ('odt', 'ods', 'odp', 'odf', 'odg', 'sxc', + 'stc', 'xls', 'xlsx', 'xlt', 'xlw', 'gnm', 'gnumeric'): + return self.either(c, 'gnumeric', 'kspread', + 'libreoffice', 'soffice', 'ooffice') if f.mimetype is not None: if INTERPRETED_LANGUAGES.match(f.mimetype): @@ -125,8 +137,8 @@ class CustomApplications(Applications): if f.video or f.audio: if f.video: c.flags += 'd' - return self.either(c, 'mplayer2', 'mplayer', 'smplayer', 'vlc', - 'totem') + return self.either(c, 'smplayer', 'gmplayer', 'mplayer2', + 'mplayer', 'vlc', 'totem') if f.image: if c.mode in (11, 12, 13, 14): @@ -281,8 +293,14 @@ class CustomApplications(Applications): CustomApplications.generic('fceux', 'wine', 'zsnes', deps=['X']) # Add those which should only run in X AND should be detached/forked here: -CustomApplications.generic('opera', 'firefox', 'apvlv', 'evince', - 'zathura', 'gimp', 'mirage', 'eog', 'jumanji', +CustomApplications.generic( + 'luakit', 'uzbl', 'vimprobable', 'vimprobable2', 'jumanji', + 'firefox', 'seamonkey', 'iceweasel', 'opera', + 'surf', 'midori', 'epiphany', 'konqueror', + 'evince', 'zathura', 'apvlv', 'okular', + 'eog', 'mirage', 'gimp', + 'libreoffice', 'soffice', 'ooffice', 'gnumeric', 'kspread', 'abiword', + 'gmplayer', 'smplayer', 'vlc', flags='d', deps=['X']) # What filetypes are recognized as scripts for interpreted languages? diff --git a/ranger/defaults/options.py b/ranger/defaults/options.py index 3b44d4f6..92b9ada9 100644 --- a/ranger/defaults/options.py +++ b/ranger/defaults/options.py @@ -104,6 +104,12 @@ padding_right = True # When false, bookmarks are saved when ranger is exited. autosave_bookmarks = True +# You can display the "real" cumulative size of directories by using the +# command :get_cumulative_size or typing "dc". The size is expensive to +# calculate and will not be updated automatically. You can choose +# to update it automatically though by turning on this option: +autoupdate_cumulative_size = False + # Makes sense for screen readers: show_cursor = False diff --git a/ranger/defaults/rc.conf b/ranger/defaults/rc.conf index a9e64622..b8106663 100644 --- a/ranger/defaults/rc.conf +++ b/ranger/defaults/rc.conf @@ -216,6 +216,8 @@ map oC chain set sort=ctime; set sort_reverse=True map oA chain set sort=atime; set sort_reverse=True map oT chain set sort="type"; set sort_reverse=True +map dc get_cumulative_size + # Settings map zc toggle_option collapse_preview map zd toggle_option sort_directories_first @@ -226,6 +228,7 @@ map zm toggle_option mouse_enabled map zp toggle_option preview_files map zP toggle_option preview_directories map zs toggle_option sort_case_insensitive +map zu toggle_option autoupdate_cumulative_size map zv toggle_option use_preview_script map zf console filter diff --git a/ranger/ext/human_readable.py b/ranger/ext/human_readable.py index 9cdce409..c5bd2aac 100644 --- a/ranger/ext/human_readable.py +++ b/ranger/ext/human_readable.py @@ -13,7 +13,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -def human_readable(byte, seperator=' '): +def human_readable(byte, separator=' '): """ Convert a large number of bytes to an easily readable format. @@ -27,27 +27,27 @@ def human_readable(byte, seperator=' '): if byte <= 0: return '0' if byte < 2**10: - return '%d%sB' % (byte, seperator) + return '%d%sB' % (byte, separator) if byte < 2**10 * 999: - return '%.3g%sK' % (byte / 2**10.0, seperator) + return '%.3g%sK' % (byte / 2**10.0, separator) if byte < 2**20: - return '%.4g%sK' % (byte / 2**10.0, seperator) + return '%.4g%sK' % (byte / 2**10.0, separator) if byte < 2**20 * 999: - return '%.3g%sM' % (byte / 2**20.0, seperator) + return '%.3g%sM' % (byte / 2**20.0, separator) if byte < 2**30: - return '%.4g%sM' % (byte / 2**20.0, seperator) + return '%.4g%sM' % (byte / 2**20.0, separator) if byte < 2**30 * 999: - return '%.3g%sG' % (byte / 2**30.0, seperator) + return '%.3g%sG' % (byte / 2**30.0, separator) if byte < 2**40: - return '%.4g%sG' % (byte / 2**30.0, seperator) + return '%.4g%sG' % (byte / 2**30.0, separator) if byte < 2**40 * 999: - return '%.3g%sT' % (byte / 2**40.0, seperator) + return '%.3g%sT' % (byte / 2**40.0, separator) if byte < 2**50: - return '%.4g%sT' % (byte / 2**40.0, seperator) + return '%.4g%sT' % (byte / 2**40.0, separator) if byte < 2**50 * 999: - return '%.3g%sP' % (byte / 2**50.0, seperator) + return '%.3g%sP' % (byte / 2**50.0, separator) if byte < 2**60: - return '%.4g%sP' % (byte / 2**50.0, seperator) + return '%.4g%sP' % (byte / 2**50.0, separator) return '>9000' if __name__ == '__main__': diff --git a/ranger/fsobject/directory.py b/ranger/fsobject/directory.py index b3a35a0a..bc09b080 100644 --- a/ranger/fsobject/directory.py +++ b/ranger/fsobject/directory.py @@ -25,6 +25,7 @@ from ranger.fsobject import File, FileSystemObject from ranger.core.shared import SettingsAware from ranger.ext.accumulator import Accumulator from ranger.ext.lazy_property import lazy_property +from ranger.ext.human_readable import human_readable def sort_by_basename(path): """returns path.basename (for sorting)""" @@ -79,6 +80,8 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware): content_outdated = False content_loaded = False + _cumulative_size_calculated = False + sort_dict = { 'basename': sort_by_basename, 'natural': sort_naturally, @@ -185,8 +188,25 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware): hidden_filter = not self.settings.show_hidden \ and self.settings.hidden_filter filelist = os.listdir(mypath) - self.size = len(filelist) - self.infostring = ' %d' % self.size + + if self._cumulative_size_calculated: + # If self.content_loaded is true, this is not the first + # time loading. So I can't really be sure if the + # size has changed and I'll add a "?". + if self.content_loaded: + if self.fm.settings.autoupdate_cumulative_size: + self.look_up_cumulative_size() + else: + self.infostring = ' %s' % human_readable( + self.size, separator='? ') + else: + self.infostring = ' %s' % human_readable(self.size) + else: + self.size = len(filelist) + self.infostring = ' %d' % self.size + if self.is_link: + self.infostring = '->' + self.infostring + filenames = [mypath + (mypath == '/' and fname or '/' + fname)\ for fname in filelist if accept_file( fname, mypath, hidden_filter, self.filter)] @@ -327,6 +347,30 @@ class Directory(FileSystemObject, Accumulator, Loadable, SettingsAware): else: self.correct_pointer() + def _get_cumulative_size(self): + if self.size == 0: + return 0 + cum = 0 + realpath = os.path.realpath + for dirpath, dirnames, filenames in os.walk(self.path, + onerror=lambda _: None): + for file in filenames: + try: + if dirpath == self.path: + stat = os_stat(realpath(dirpath + "/" + file)) + else: + stat = os_stat(dirpath + "/" + file) + cum += stat.st_size + except: + pass + return cum + + def look_up_cumulative_size(self): + self._cumulative_size_calculated = True + self.size = self._get_cumulative_size() + self.infostring = ('-> ' if self.is_link else ' ') + \ + human_readable(self.size) + @lazy_property def size(self): try: diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py index d74b21c1..51e49808 100644 --- a/ranger/fsobject/fsobject.py +++ b/ranger/fsobject/fsobject.py @@ -117,6 +117,9 @@ class FileSystemObject(FileManagerAware): def use(self): """Used in garbage-collecting. Override in Directory""" + def look_up_cumulative_size(self): + pass # normal files have no cumulative size + def set_mimetype(self): """assign attributes such as self.video according to the mimetype""" basename = self.basename diff --git a/ranger/gui/widgets/statusbar.py b/ranger/gui/widgets/statusbar.py index 1e2e2520..b7a238da 100644 --- a/ranger/gui/widgets/statusbar.py +++ b/ranger/gui/widgets/statusbar.py @@ -231,17 +231,17 @@ class StatusBar(Widget): if target.marked_items: if len(target.marked_items) == len(target.files): - right.add(human_readable(target.disk_usage, seperator='')) + right.add(human_readable(target.disk_usage, separator='')) else: right.add(human_readable(sum(f.size \ for f in target.marked_items \ - if f.is_file), seperator='')) + if f.is_file), separator='')) right.add("/" + str(len(target.marked_items))) else: - right.add(human_readable(target.disk_usage, seperator='') + + right.add(human_readable(target.disk_usage, separator='') + " sum, ") right.add(human_readable(self.env.get_free_space( \ - target.mount_path), seperator='') + " free") + target.mount_path), separator='') + " free") right.add(" ", "space") if target.marked_items: |