mirror of https://github.com/fmartingr/iosfu.git
198 lines
4.9 KiB
Python
198 lines
4.9 KiB
Python
from __future__ import with_statement
|
|
|
|
from os import listdir
|
|
from os.path import join as join_paths, basename, isdir, isfile
|
|
from plistlib import readPlist
|
|
|
|
from biplist import readPlist as readBinaryPlist
|
|
|
|
from .conf import BACKUPS_PATH, BACKUP_DEFAULT_SETTINGS
|
|
from iosfu import utils
|
|
|
|
|
|
class BackupManager(object):
|
|
# Path to backups
|
|
path = None
|
|
|
|
# Backups loaded
|
|
backups = {}
|
|
|
|
def __init__(self, path=BACKUPS_PATH):
|
|
self.path = path
|
|
|
|
def lookup(self):
|
|
"""
|
|
Look for backup folders on PATH
|
|
"""
|
|
folders = listdir(self.path)
|
|
for dirname in folders:
|
|
path = join_paths(self.path, dirname)
|
|
if isdir(path):
|
|
backup = Backup(path)
|
|
self.backups[backup.id] = backup
|
|
|
|
def get(self, backup_id):
|
|
if backup_id in self.backups and self.backups[backup_id].valid:
|
|
return self.backups[backup_id]
|
|
else:
|
|
raise Exception('Backup not registered')
|
|
|
|
|
|
class Backup(object):
|
|
"""
|
|
Backup object
|
|
"""
|
|
# Backup id
|
|
id = None
|
|
|
|
# Backup path
|
|
path = None
|
|
|
|
# Files
|
|
files = []
|
|
|
|
# bool if its valid -> self.init_check()
|
|
valid = True
|
|
|
|
# Required files to mark as valid
|
|
_required_files = [
|
|
'Info.plist', 'Manifest.mbdb', 'Manifest.plist', 'Status.plist'
|
|
]
|
|
|
|
# File handlers to call methods
|
|
_file_handlers = {
|
|
'.plist': '_read_plist'
|
|
}
|
|
|
|
_plist = {}
|
|
|
|
# Data
|
|
_data_file = None
|
|
_data = {}
|
|
|
|
def __init__(self, path):
|
|
self.path = path
|
|
self.get_info()
|
|
self._data_file = self.get_data_file()
|
|
self.init_check()
|
|
self.read_data_file()
|
|
|
|
@property
|
|
def name(self):
|
|
name = self.data('name') or self.id
|
|
return name
|
|
|
|
def get_data_file(self):
|
|
return "{}.iosfu".format(self.path)
|
|
|
|
def read_data_file(self):
|
|
try:
|
|
handler = open(self._data_file)
|
|
except (OSError, IOError):
|
|
# Create default config file if non-existant
|
|
handler = open(self._data_file, 'w+')
|
|
handler.write(utils.serialize(BACKUP_DEFAULT_SETTINGS))
|
|
handler.seek(0)
|
|
finally:
|
|
with handler as f:
|
|
data_file = f.read()
|
|
|
|
self._data = utils.deserialize(data_file)
|
|
handler.close()
|
|
|
|
def get_info(self):
|
|
"""
|
|
Get all the basic info for the backup
|
|
"""
|
|
self.id = basename(self.path)
|
|
|
|
# Check all files
|
|
for filename in listdir(self.path):
|
|
if isfile(join_paths(self.path, filename)):
|
|
self.files.append(filename)
|
|
|
|
# Check handlers
|
|
for match in self._file_handlers.keys():
|
|
if match in filename:
|
|
handler = getattr(self, self._file_handlers[match])
|
|
handler(filename)
|
|
|
|
def init_check(self):
|
|
"""
|
|
Check if the needed stuff are there to consider this a backup
|
|
"""
|
|
for required_file in self._required_files:
|
|
# Check if required files are there
|
|
# FIXME Sometimes it doesn't work :?
|
|
if required_file not in self.files:
|
|
self.valid = False
|
|
|
|
def exists(self, filename):
|
|
"""
|
|
Check if the given file exists
|
|
"""
|
|
return filename in self.files
|
|
|
|
def get_file(self, filename, handler=False):
|
|
"""
|
|
Returns given file path
|
|
- handler (bool) - Returns handler instead of path
|
|
"""
|
|
result = None
|
|
if self.exists(filename):
|
|
file_path = join_paths(self.path, filename)
|
|
if handler:
|
|
result = open(file_path, 'rb')
|
|
else:
|
|
result = file_path
|
|
return result
|
|
|
|
#
|
|
# File handlers
|
|
#
|
|
def _read_plist(self, filename):
|
|
"""
|
|
Handler for .plist files
|
|
Reads them and stores on self._plist for plugin access
|
|
"""
|
|
file_path = self.get_file(filename)
|
|
try:
|
|
self._plist[filename] = readPlist(file_path)
|
|
except:
|
|
# Is binaryPlist?
|
|
try:
|
|
self._plist[filename] = readBinaryPlist(file_path)
|
|
except:
|
|
# What is it?
|
|
pass
|
|
|
|
#
|
|
# Backup data file
|
|
#
|
|
def data(self, key, value=None):
|
|
result = value
|
|
if value:
|
|
self._data[key] = value
|
|
elif key in self._data:
|
|
result = self._data[key]
|
|
|
|
return result
|
|
|
|
def cache(self, key, value=None):
|
|
result = value
|
|
if value:
|
|
self._data['cache'][key] = value
|
|
elif key in self._data['cache']:
|
|
result = self._data['cache'][key]
|
|
|
|
return result
|
|
|
|
def clear_cache(self):
|
|
self._data['cache'] = {}
|
|
self.write_data_file()
|
|
|
|
def write_data_file(self):
|
|
handler = open(self._data_file, 'w+')
|
|
handler.write(utils.serialize(self._data))
|
|
handler.close()
|