mirror of
https://github.com/gryf/fs-uae-wrapper.git
synced 2025-12-19 04:20:23 +01:00
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.
175 lines
4.6 KiB
Python
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
|