comparison profilemanager/manager.py @ 79:145e111903d2 default tip

add MPL license
author Jeff Hammel <jhammel@mozilla.com>
date Mon, 10 May 2010 13:11:38 -0700
parents e091caa41075
children
comparison
equal deleted inserted replaced
78:553f5783999f 79:145e111903d2
1 # ***** BEGIN LICENSE BLOCK *****
2 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 #
4 # The contents of this file are subject to the Mozilla Public License Version
5 # 1.1 (the "License"); you may not use this file except in compliance with
6 # the License. You may obtain a copy of the License at
7 # http://www.mozilla.org/MPL/
8 #
9 # Software distributed under the License is distributed on an "AS IS" basis,
10 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 # for the specific language governing rights and limitations under the
12 # License.
13 #
14 # The Original Code is mozilla.org code.
15 #
16 # The Initial Developer of the Original Code is
17 # Mozilla.org.
18 # Portions created by the Initial Developer are Copyright (C) 2010
19 # the Initial Developer. All Rights Reserved.
20 #
21 # Contributor(s):
22 # Jeff Hammel <jhammel@mozilla.com> (Original author)
23 #
24 # Alternatively, the contents of this file may be used under the terms of
25 # either of the GNU General Public License Version 2 or later (the "GPL"),
26 # or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 # in which case the provisions of the GPL or the LGPL are applicable instead
28 # of those above. If you wish to allow use of your version of this file only
29 # under the terms of either the GPL or the LGPL, and not to allow others to
30 # use your version of this file under the terms of the MPL, indicate your
31 # decision by deleting the provisions above and replace them with the notice
32 # and other provisions required by the GPL or the LGPL. If you do not delete
33 # the provisions above, a recipient may use your version of this file under
34 # the terms of any one of the MPL, the GPL or the LGPL.
35 #
36 # ***** END LICENSE BLOCK *****
1 """ 37 """
2 manage Mozilla/Firefox profiles 38 manage Mozilla/Firefox profiles
3 """ 39 """
4 40
5 import os 41 import os
70 # TODO: (optionally) pre-populate the directory a la Firefox 106 # TODO: (optionally) pre-populate the directory a la Firefox
71 os.mkdir(path) 107 os.mkdir(path)
72 108
73 # update profiles.ini 109 # update profiles.ini
74 self.add(name, relative and dirname or path, relative) 110 self.add(name, relative and dirname or path, relative)
75 111
76 # return the directory name 112 # return the directory name
77 return path 113 return path
78 114
79 def remove(self, name, delete=True): 115 def remove(self, name, delete=True):
80 """ 116 """
105 clones the profile `source` and output to `dest` 141 clones the profile `source` and output to `dest`
106 - add: add the profile to the profiles.ini file 142 - add: add the profile to the profiles.ini file
107 """ 143 """
108 144
109 # filesystem path of the `from` profile 145 # filesystem path of the `from` profile
110 source_path = self.path(source) 146 source_path = self.path(source)
111 147
112 # dest: fs path to back up to 148 # dest: fs path to back up to
113 relative = False 149 relative = False
114 if os.path.sep in dest: 150 if os.path.sep in dest:
115 if not os.path.isabs(dest): 151 if not os.path.isabs(dest):
161 # ensure backup directory is not already present 197 # ensure backup directory is not already present
162 assert not os.path.exists(dest), "'%s' already exists" 198 assert not os.path.exists(dest), "'%s' already exists"
163 199
164 # copy the files 200 # copy the files
165 self.clone(profile, dest, add=False) 201 self.clone(profile, dest, add=False)
166 202
167 # add backup entry to profiles.ini (colon separated): 203 # add backup entry to profiles.ini (colon separated):
168 # `Backup=$(profile)s.$(datestamp)s.bak` 204 # `Backup=$(profile)s.$(datestamp)s.bak`
169 if parser.has_option(section, 'Backups'): 205 if parser.has_option(section, 'Backups'):
170 backups = '%s:%s' % (parser.get(section, 'Backups'), name) 206 backups = '%s:%s' % (parser.get(section, 'Backups'), name)
171 else: 207 else:
241 277
242 # test for s since epoch 278 # test for s since epoch
243 seconds_snice_epoch = None 279 seconds_snice_epoch = None
244 try: 280 try:
245 seconds_since_epoch = int(date) 281 seconds_since_epoch = int(date)
246 282
247 except ValueError: 283 except ValueError:
248 pass 284 pass
249 if seconds_since_epoch and seconds_since_epoch > time.localtime().tm_year: 285 if seconds_since_epoch and seconds_since_epoch > time.localtime().tm_year:
250 date = seconds_since_epoch 286 date = seconds_since_epoch
251 else: 287 else:
252 date = parse(date) # parse date from string 288 date = parse(date) # parse date from string
253 289
254 if isinstance(date, datetime): 290 if isinstance(date, datetime):
255 # convert to s since epoch 291 # convert to s since epoch
256 date = time.mktime(date.timetuple()) 292 date = time.mktime(date.timetuple())
257 293
258 for backup in backups: 294 for backup in backups:
259 if backup[1] < date: 295 if backup[1] < date:
260 break 296 break
261 else: 297 else:
262 raise NoBackupError("No backups for profile %s in %s earlier than %s" % (profile, self.profiles, orig_date)) 298 raise NoBackupError("No backups for profile %s in %s earlier than %s" % (profile, self.profiles, orig_date))
286 322
287 if delete: # delete the backup 323 if delete: # delete the backup
288 324
289 # delete the directory 325 # delete the directory
290 shutil.rmtree(backup_path) 326 shutil.rmtree(backup_path)
291 327
292 # delete the entry from ``profiles.ini`` 328 # delete the entry from ``profiles.ini``
293 parser = self.parser() 329 parser = self.parser()
294 section = self.section(profile) 330 section = self.section(profile)
295 backups = parser.get(section, 'Backups').split(':') 331 backups = parser.get(section, 'Backups').split(':')
296 backups = [ i for i in backups if i != backup[0] ] 332 backups = [ i for i in backups if i != backup[0] ]
326 362
327 # ensure name is not already present 363 # ensure name is not already present
328 assert profile not in self.profiles_dict(), 'Profile "%s" already in %s' % (name, self.profiles) 364 assert profile not in self.profiles_dict(), 'Profile "%s" already in %s' % (name, self.profiles)
329 parser = self.parser() 365 parser = self.parser()
330 366
331 # find and add the section 367 # find and add the section
332 ctr = 0 368 ctr = 0
333 section = 'Profile%d' % ctr # unsure of this naming convention 369 section = 'Profile%d' % ctr # unsure of this naming convention
334 while section in parser.sections(): 370 while section in parser.sections():
335 ctr += 1 371 ctr += 1
336 section = 'Profile%d' % ctr 372 section = 'Profile%d' % ctr