summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--ranger/fsobject/file.py59
-rw-r--r--ranger/fsobject/fsobject.py9
-rw-r--r--ranger/gui/widgets/browsercolumn.py64
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 <http://www.gnu.org/licenses/>.
 
+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 <http://www.gnu.org/licenses/>.
 
 """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"""
n467' href='#n467'>467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522