1
0
mirror of https://github.com/gryf/fs-uae-wrapper.git synced 2025-12-19 04:20:23 +01:00
Files
fs-uae-wrapper/fs_uae_wrapper/file_archive.py
gryf 19acb789b6 Added wrapper_archiver option
To give user a possibility to choose what archiver he can use another
options was introduced for cd32 and archive wrapper modules. This option
will indicate what archiver should be used for compressing the save
state directories.
2017-01-02 20:08:50 +01:00

175 lines
4.6 KiB
Python

"""
File archive classes
"""
import os
import subprocess
import sys
import re
from fs_uae_wrapper import path
class Archive(object):
"""Base class for archive support"""
ADD = ['a']
EXTRACT = ['x']
ARCH = 'false'
def __init__(self):
self.archiver = path.which(self.ARCH)
self._compess = self.archiver
self._decompess = self.archiver
def create(self, arch_name):
"""
Create archive. Return True on success, False otherwise.
"""
result = subprocess.call([self._compess] + self.ADD + [arch_name, '.'])
if result != 0:
sys.stderr.write("Unable to create archive `%s'\n" % arch_name)
return False
return True
def extract(self, arch_name):
"""
Extract archive. Return True on success, False otherwise.
"""
if not os.path.exists(arch_name):
sys.stderr.write("Archive `%s' doesn't exists.\n" % arch_name)
return False
result = subprocess.call([self._decompess] + self.EXTRACT +
[arch_name])
if result != 0:
sys.stderr.write("Unable to extract archive `%s'\n" % arch_name)
return False
return True
class TarArchive(Archive):
ADD = ['cf']
EXTRACT = ['xf']
ARCH = 'tar'
class TarGzipArchive(TarArchive):
ADD = ['zcf']
class TarBzip2Archive(TarArchive):
ADD = ['jcf']
class TarXzArchive(TarArchive):
ADD = ['Jcf']
class LhaArchive(Archive):
ARCH = 'lha'
class ZipArchive(Archive):
ADD = ['a', '-tzip']
ARCH = ['7z', 'zip']
def __init__(self):
super(ZipArchive, self).__init__()
if self.archiver == 'zip':
self._decompess = path.which('unzip')
ZipArchive.ADD = ['-r']
ZipArchive.EXTRACT = []
class SevenZArchive(Archive):
ARCH = '7z'
class LzxArchive(Archive):
EXTRACT = ['-x']
ARCH = 'unlzx'
@classmethod
def create(self, arch_name):
sys.stderr.write('Cannot create LZX archive. Only extracting is'
'supported\n')
return False
class RarArchive(Archive):
ARCH = ['rar', 'unrar']
def create(self, arch_name):
if self.archiver == 'unrar':
sys.stderr.write('Cannot create RAR archive. Only extracting is'
'supported by unrar.\n')
return False
result = subprocess.call([self._compess] + self.ADD + [arch_name] +
sorted(os.listdir('.')))
if result != 0:
sys.stderr.write("Unable to create archive `%s'\n" % arch_name)
return False
return True
class Archivers(object):
"""Archivers class"""
archivers = [{'arch': TarArchive, 'name': 'tar', 'ext': ['tar']},
{'arch': TarGzipArchive, 'name': 'tgz',
'ext': ['tar.gz', 'tgz']},
{'arch': TarBzip2Archive, 'name': 'tar.bz2',
'ext': ['tar.bz2']},
{'arch': TarXzArchive, 'name': 'tar.xz', 'ext': ['tar.xz']},
{'arch': RarArchive, 'name': 'rar', 'ext': ['rar']},
{'arch': SevenZArchive, 'name': '7z', 'ext': ['7z']},
{'arch': ZipArchive, 'name': 'zip', 'ext': ['zip']},
{'arch': LhaArchive, 'name': 'lha', 'ext': ['lha', 'lzh']},
{'arch': LzxArchive, 'name': 'lzx', 'ext': ['lzx']}]
@classmethod
def get(cls, extension):
"""
Get the archive class or None
"""
for arch in cls.archivers:
if extension in arch['ext']:
return arch['arch']
return None
@classmethod
def get_extension_by_name(cls, name):
"""
Get the first defined extension for the archive format
"""
for arch in cls.archivers:
if name == arch['name']:
return '.' + arch['ext'][0]
return None
def get_archiver(arch_name):
"""Return right class for provided archive file name"""
_, ext = os.path.splitext(arch_name)
re_tar = re.compile('.*(.[tT][aA][rR].[^.]+$)')
result = re_tar.match(arch_name)
if result:
ext = result.groups()[0]
if ext:
ext = ext[1:]
archiver = Archivers.get(ext)
if not archiver:
sys.stderr.write("Unable find archive type for `%s'\n" % arch_name)
return None
archobj = archiver()
if archobj.archiver is None:
sys.stderr.write("Unable find executable for operating on files"
" `*%s'\n" % ext)
return None
return archobj