Mercurial > mozilla > hg > ProfileManager
view profilemanager/manager.py @ 10:c77e9bef78d6
* update list of public API functions
* further flushing out of profile manager
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Wed, 05 May 2010 17:08:47 -0700 |
parents | b1274abd1206 |
children | 543d08958b67 |
line wrap: on
line source
""" manage Mozilla/Firefox profiles """ import os import shutil import ConfigParser from utils import format_tabular from ConfigParser import SafeConfigParser as ConfigParser # Changes to profiles.ini: # - add a ``backups`` field for each profile: # Backups = /path/to/backup:1273104310 /path/to/other/backup:1273104355 class ProfileNotFound(Exception): """ exception when a profile is specified but is not present in a given .ini file """ class ProfileManager(object): def __init__(self, profiles): """ - profiles: filesystem path to profiles.ini file """ self.profiles = profiles self.profile_dir = os.path.abspath(os.path.dirname(profiles)) ### (public) API def new(self, name): """ generate a new clean profile - name: name of the profile to generate """ raise NotImplementedError def list(self, directories=False): """ lists the profiles available in the config file - directories : display the directories """ profiles = self.profiles_dict() retval = [] for name in sorted(profiles.keys()): values = [name] if directories: values.append(self.path(name)) retval.append(values) return format_tabular(retval) def clone(self, source, dest, hash=True): """ clones the profile `source` and output to `dest` """ source_path = self.path(source) # fs path of the `from` profile # dest: fs path to back up to relative = False if not os.path.isabs(dest): relative = True if not os.path.dirname(dest): dest = '%s.%s' % (self.hash(), dest) dest = os.path.join(self.profile_dir, dest) shutil.copytree(source_path, dest, symlinks=False) # TODO: update profiles.ini def backup(self, profile, dest=None): """ backup the profile - profile: name of the profile to be backed up - dest: name of the destination (optional) """ if dest is None: dest = '%s.%d.bak' % (profile, int(time.time())) self.clone(profile, dest, hash=False) # TODO: add something like # `Backup=$(profile)s.$(datestamp)s.bak` # to self.profiles def backups(self, profile=None): """ list backups for a given profile, or all profiles if the profile is not given; returns a list of backups if profile is given or a dictionary of lists otherwise """ if profile is None: # all profiles retval = {} return retval # TODO def restore(self, profile, date=None, delete=False): """ restore the profile from a backup the most recent backup is used unless `date` is given - date : date to restore from - delete : delete the backup after restoration """ # get the possible backups backups = self.backups(profile) # TODO: check to see if these all exist (print warnings if not) # restore the backup over ``profile`` if delete: # delete the backup # delete the directory # delete the entry from ``profiles.ini`` # if there are no backups, delete the ``backups`` line pass #TODO def merge(self, output, *profiles): """merge a set of profiles (not trivial!)""" raise NotImplementedError ### internal functions def path(self, profile): """returns the path to the profile""" profile = self.profile_dict(profile) if profile.get('isrelative', None) == '1': return os.path.join(self.profile_dir, profile['path']) return profile['path'] def profile_dict(self, profile): """ return option dictionary for a single profile """ parser = ConfigParser() parser.read(self.profiles) for section in parser.sections(): if not parser.has_option(section, 'name'): continue # not a profile if parser.get(section, 'name') == profile: return dict(parser.items(section)) raise ProfileNotFound('Profile %s not found in %s' % (profile, self.profiles)) def profiles_dict(self): """ return nested dict of all profiles """ # XXX assumes profiles have unique names parser = ConfigParser() parser.read(self.profiles) retval = {} for section in parser.sections(): if section == 'General': continue try: name = parser.get(section, 'name') except ConfigParser.NoOptionError: continue retval[name] = self.profile_dict(name) return retval def hash(self): """ generate a random hash for a new profile """ # XXX right now this is completely fake return 'FOO'