[kupfer: 6/27] archiveinside: Make the extraction more general for any type



commit 610741d0b47083c71557f34bc6de0969e8e7416c
Author: Ulrik Sverdrup <ulrik sverdrup gmail com>
Date:   Fri Jan 22 18:29:53 2010 +0100

    archiveinside: Make the extraction more general for any type

 kupfer/plugin/archiveinside.py |   44 ++++++++++++++++++++++++++++++++-------
 1 files changed, 36 insertions(+), 8 deletions(-)
---
diff --git a/kupfer/plugin/archiveinside.py b/kupfer/plugin/archiveinside.py
index 944e550..b15f0c1 100644
--- a/kupfer/plugin/archiveinside.py
+++ b/kupfer/plugin/archiveinside.py
@@ -17,6 +17,7 @@ import hashlib
 import os
 import shutil
 import tarfile
+import zipfile
 
 from kupfer.objects import Source, FileLeaf
 from kupfer.obj.sources import DirectorySource
@@ -31,14 +32,35 @@ MAX_ARCHIVE_BYTE_SIZE = 15 * 1024**2
 # archive files
 VERY_LONG_TIME_S = 3600*24*365
 
+UNARCHIVE_COMPAT = {}
+UNARCHIVE_FUNC = {}
+
+def extractor(name, extensions, predicate):
+	def decorator(func):
+		UNARCHIVE_COMPAT[name] = (extensions, predicate)
+		UNARCHIVE_FUNC[name] = func
+		return func
+	return decorator
+
+ extractor("tar", (".tar", ".tar.gz", ".tgz", ".tar.bz2"), tarfile.is_tarfile)
+def extract_tarfile(filepath, destpath):
+	zf = tarfile.TarFile.open(filepath, 'r')
+	zf.extractall(path=destpath)
+
+
+ extractor("zip", (".zip", ), zipfile.is_zipfile)
+def extract_zipfile(filepath, destpath):
+	raise NotImplementedError
+
 
 class ArchiveContent (Source):
 	unarchived_files = []
 	end_timer = scheduler.Timer(True)
 
-	def __init__(self, fileleaf):
+	def __init__(self, fileleaf, unarchive_func):
 		Source.__init__(self, _("Content of %s") % fileleaf)
 		self.path = fileleaf.object
+		self.unarchiver = unarchive_func
 
 	def repr_key(self):
 		return self.path
@@ -51,8 +73,7 @@ class ArchiveContent (Source):
 		fileid = hashlib.sha1("%s%s" % (self.path, mtime)).hexdigest()
 		pth = os.path.join("/tmp", "kupfer-%s-%s" % (root, fileid, ))
 		if not os.path.exists(pth):
-			zf = tarfile.TarFile.gzopen(self.path)
-			zf.extractall(path=pth)
+			self.unarchiver(self.path, pth)
 			self.unarchived_files.append(pth)
 			self.end_timer.set(VERY_LONG_TIME_S, self.clean_up_unarchived_files)
 		files = list(DirectorySource(pth, show_hidden=True).get_leaves())
@@ -69,11 +90,18 @@ class ArchiveContent (Source):
 
 	@classmethod
 	def decorate_item(cls, leaf):
-		root, ext = os.path.splitext(leaf.object)
-		if leaf.object.lower().endswith(".tar.gz"):
-			byte_size = os.stat(leaf.object).st_size
-			if byte_size < MAX_ARCHIVE_BYTE_SIZE:
-				return cls(leaf)
+		basename = os.path.basename(leaf.object).lower()
+		for extractor, (extensions, predicate) in UNARCHIVE_COMPAT.iteritems():
+			if any(basename.endswith(ext) for ext in extensions):
+				if predicate(leaf.object):
+					return cls._source_for_path(leaf, extractor)
+
+
+	@classmethod
+	def _source_for_path(cls, leaf, extractor):
+		byte_size = os.stat(leaf.object).st_size
+		if byte_size < MAX_ARCHIVE_BYTE_SIZE:
+			return cls(leaf, UNARCHIVE_FUNC[extractor])
 		return None
 
 	@classmethod



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]