From 437c12d9093b09d0ebb90bc6bfe35a8769c31c17 Mon Sep 17 00:00:00 2001 From: David Barnett Date: Sun, 16 May 2010 20:30:59 -0400 Subject: Refactored filetype/preview code; added previews for .zip files (list contained files) --- ranger/fsobject/file.py | 59 ++++++++++++++++++++++++++++++++++ ranger/fsobject/fsobject.py | 9 +++++- ranger/gui/widgets/browsercolumn.py | 64 ++++++------------------------------- 3 files changed, 76 insertions(+), 56 deletions(-) diff --git a/ranger/fsobject/file.py b/ranger/fsobject/file.py index 4618df33..1d25e7d8 100644 --- a/ranger/fsobject/file.py +++ b/ranger/fsobject/file.py @@ -13,11 +13,47 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import re +import stat +import zipfile +from StringIO import StringIO + N_FIRST_BYTES = 20 control_characters = set(chr(n) for n in set(range(0, 9)) | set(range(14, 32))) from ranger.fsobject import FileSystemObject + +# Don't even try to preview files which mach this regular expression: +PREVIEW_BLACKLIST = re.compile(r""" + # look at the extension: + \.( + # one character extensions: + [oa] + # media formats: + | avi | [mj]pe?g | mp\d | og[gmv] | wm[av] | mkv | flv + | png | bmp | vob | wav | mpc | flac | divx? | xcf | pdf + # binary files: + | torrent | class | so | img | py[co] | dmg + # containers: + | iso | rar | 7z | tar | gz | bz2 | tgz + ) + # ignore filetype-independent suffixes: + (\.part|\.bak|~)? + # ignore fully numerical file extensions: + (\.\d+)*? + $ +""", re.VERBOSE | re.IGNORECASE) + +PREVIEW_WHITELIST = re.compile(r""" + \.( + txt | py | c + ) + # ignore filetype-independent suffixes: + (\.part|\.bak|~)? + $ +""", re.VERBOSE | re.IGNORECASE) + class File(FileSystemObject): is_file = True @@ -38,3 +74,26 @@ class File(FileSystemObject): if self.firstbytes and control_characters & set(self.firstbytes): return True return False + + def has_preview(self): + if not (self.is_file \ + and self.accessible \ + and self.stat \ + and not self.is_device \ + and not self.stat.st_mode & stat.S_IFIFO): + return False + + if PREVIEW_WHITELIST.search(self.basename): + return True + if PREVIEW_BLACKLIST.search(self.basename): + return False + if self.extension not in ('zip',) and self.is_binary(): + return False + return True + + def get_preview_source(self): + if self.extension == 'zip': + contents = '\n'.join(zipfile.ZipFile(self.path).namelist()) + return StringIO(contents) + return open(self.path, 'r') + diff --git a/ranger/fsobject/fsobject.py b/ranger/fsobject/fsobject.py index afef48e4..d570d009 100644 --- a/ranger/fsobject/fsobject.py +++ b/ranger/fsobject/fsobject.py @@ -19,7 +19,7 @@ CONTAINER_EXTENSIONS = ('7z', 'ace', 'ar', 'arc', 'bz', 'bz2', 'cab', 'cpio', from os import access, listdir, lstat, readlink, stat from time import time -from os.path import abspath, basename, dirname, realpath +from os.path import abspath, basename, dirname, realpath, splitext, extsep from . import BAD_INFO from ranger.shared import MimeTypeAware, FileManagerAware from ranger.ext.shell_escape import shell_escape @@ -76,6 +76,7 @@ class FileSystemObject(MimeTypeAware, FileManagerAware): self.path = path self.basename = basename(path) self.basename_lower = self.basename.lower() + self.extension = splitext(self.basename)[1].lstrip(extsep) or None self.dirname = dirname(path) self.realpath = self.path self.preload = preload @@ -300,3 +301,9 @@ class FileSystemObject(MimeTypeAware, FileManagerAware): self.load() return True return False + + def get_preview_source(self): + """ + Override this to get a file object for a preview pane, or None for + no preview. + """ diff --git a/ranger/gui/widgets/browsercolumn.py b/ranger/gui/widgets/browsercolumn.py index 1e24e2dd..b8657ae3 100644 --- a/ranger/gui/widgets/browsercolumn.py +++ b/ranger/gui/widgets/browsercolumn.py @@ -14,7 +14,6 @@ # along with this program. If not, see . """The BrowserColumn widget displays the contents of a directory or file.""" -import re import stat from time import time @@ -22,36 +21,6 @@ from . import Widget from .pager import Pager from ranger.fsobject import BAD_INFO -# Don't even try to preview files which mach this regular expression: -PREVIEW_BLACKLIST = re.compile(r""" - # look at the extension: - \.( - # one character extensions: - [oa] - # media formats: - | avi | [mj]pe?g | mp\d | og[gmv] | wm[av] | mkv | flv - | png | bmp | vob | wav | mpc | flac | divx? | xcf | pdf - # binary files: - | torrent | class | so | img | py[co] | dmg - # containers: - | iso | rar | zip | 7z | tar | gz | bz2 | tgz - ) - # ignore filetype-independent suffixes: - (\.part|\.bak|~)? - # ignore fully numerical file extensions: - (\.\d+)*? - $ -""", re.VERBOSE | re.IGNORECASE) - -PREVIEW_WHITELIST = re.compile(r""" - \.( - txt | py | c - ) - # ignore filetype-independent suffixes: - (\.part|\.bak|~)? - $ -""", re.VERBOSE | re.IGNORECASE) - class BrowserColumn(Pager): main_column = False display_infostring = False @@ -123,11 +92,11 @@ class BrowserColumn(Pager): return True def has_preview(self): - if self.target is None: + if self.target is None or self.settings.preview_files == False: return False if self.target.is_file: - if not self._preview_this_file(self.target): + if not self.target.has_preview(): return False if self.target.is_directory: @@ -173,24 +142,6 @@ class BrowserColumn(Pager): self.need_redraw = False self.last_redraw_time = time() - def _preview_this_file(self, target): - if not (target \ - and self.settings.preview_files \ - and target.is_file \ - and target.accessible \ - and target.stat \ - and not target.is_device \ - and not target.stat.st_mode & stat.S_IFIFO): - return False - - if PREVIEW_WHITELIST.search(target.basename): - return True - if PREVIEW_BLACKLIST.search(target.basename): - return False - if target.is_binary(): - return False - return True - def _draw_file(self): """Draw a preview of the file, if the settings allow it""" self.win.move(0, 0) @@ -199,17 +150,20 @@ class BrowserColumn(Pager): Pager.close(self) return - if not self._preview_this_file(self.target): + if self.target is None or not self.target.has_preview(): Pager.close(self) return try: - f = open(self.target.path, 'r') + f = self.target.get_preview_source() except: Pager.close(self) else: - self.set_source(f) - Pager.draw(self) + if f is None: + Pager.close(self) + else: + self.set_source(f) + Pager.draw(self) def _draw_directory(self): """Draw the contents of a directory""" -- cgit 1.4.1-2-gfad0