"""
FtpCube
Copyright (C) Michael Gilfix
This file is part of FtpCube.
You should have received a file COPYING containing license terms
along with this program; if not, write to Michael Gilfix
(mgilfix@eecs.tufts.edu) for a copy.
This version of FtpCube is open source; you can redistribute it and/or
modify it under the terms listed in the file COPYING.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
"""
import os
import exceptions
extensions = { }
def registerExtensions(ext_list, arch_type):
"""Registers the extensions in the specified list with the archive type handler."""
global extensions
for ext in ext_list:
extensions[ext] = arch_type
def getRegisteredExtensions():
"""Returns a dictionary of registered extensions.
Registered extensions should be of the form: '.<ext>'. The dictionary provides a
mapping between an extension type and the handler module that can process that type.
Handler modules implement the 'archtypes.archhandler.ArchiveHandler' interface."""
global extensions
return extensions
# Try to register the archive types
import archtypes
for export in archtypes.__all__:
module = archtypes.__dict__[export]
registerExtensions(module.getExtensions(), module.getHandlerClass())
class ArchiveException(exceptions.Exception):
"""Archive processing exception."""
pass
class Archiver:
"""Archive manager class.
This class provides a means of processing all registered/supported archive extensions.
Each archive handler implementation is placed into the 'archtypes' package. Such
handlers should be exposed via the '__all__' export list and imported into the module
namespace. This allows for automatic loading.
The archive manager can be queried to determine whether an extension is supported.
A supported extension can then be unpacked, and its list of files displayed to the
user. A progress bar is created within a parent window to indicate the progress of
displaying the files. The use of a progress bar may have some consequences for really
large files, where discovering the number of files within the archive may be costly.
This depends on the archive handler implementation and API used to process archive
files."""
def __init__(self, parent):
"""Creates a new archive manager and associates the archive manager with the parent
window object."""
if __debug__:
print "Creating archive manager object."
self.parent = parent
self.extensions = getRegisteredExtensions()
if __debug__:
print "The archiver has the following registered extensions:"
for ext in self.extensions.keys():
print "\t%s : %s" %(ext, repr(self.extensions[ext]))
def findSupportedHandler(self, path):
"""Finds the an archive handler for the specified file.
The search finds the longest matching extension and returns that handler.
For example, '.tar.gz' will match before '.gz'. If no extension is registered,
then None is returned."""
filename = os.path.basename(path).lower()
ext = None
for i in range(len(filename)):
if filename[i] == '.' and self.extensions.has_key(filename[i:]):
ext = filename[i:]
break
return ext
def getExtHandler(self, ext):
"""Gets the archive handler for the specified extension."""
try:
return self.extensions[ext]
except KeyError:
return None
def getStatus(self, path):
"""Returns a string indicating the validity of the handler archive.
This string can be displayed to the user indicating whether the archive is valid."""
ext = self.findSupportedHandler(path)
handler = self.getExtHandler(ext)
if handler:
try:
inst = handler(path=path)
if inst.isValid():
return _("Ok")
else:
return _("Invalid")
except:
return _("Error")
else:
return _("Unknown")
def getType(self, path):
"""Returns a user printable string indicating the type of archive file at the
specified path."""
ext = self.findSupportedHandler(path)
handler = self.getExtHandler(ext)
desc = _("Unknown")
if handler:
try:
inst = handler(path=path)
desc = inst.getDescription()
except:
pass
return desc
def unpack(self, path, location):
"""Unpacked the archive at the specified path into the specified location.
A list of unpacked files is returned upon successful unpacking of the archive.
If the archive cannot be unpacked successfully, then an ArchiveException is
raised."""
ext = self.findSupportedHandler(path)
handler = self.getExtHandler(ext)
file_list = None
if handler:
try:
inst = handler(path=path, parent=self.parent)
file_list = inst.unpack(location)
except Exception, strerror:
raise ArchiveException, strerror
return file_list
|