Mercurial > mozilla > hg > ProfileManager
annotate 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 |
rev | line source |
---|---|
79 | 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 ***** | |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
37 """ |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
38 manage Mozilla/Firefox profiles |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
39 """ |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
40 |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
41 import os |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
42 import shutil |
15
543d08958b67
actually sample 8 random lowercase letters and numbers for the profile hash
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
43 import string |
75 | 44 import sys |
66
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
45 import tempfile |
50 | 46 import time |
9
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
47 import ConfigParser |
65
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
48 from datetime import datetime |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
49 from dateutil.parser import parse |
15
543d08958b67
actually sample 8 random lowercase letters and numbers for the profile hash
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
50 from random import Random |
5
ca57920aa223
adding better formatting for list
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
51 from utils import format_tabular |
ca57920aa223
adding better formatting for list
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
52 from ConfigParser import SafeConfigParser as ConfigParser |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
53 |
10
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
54 # Changes to profiles.ini: |
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
55 # - add a ``backups`` field for each profile: |
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
56 # Backups = /path/to/backup:1273104310 /path/to/other/backup:1273104355 |
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
57 |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
58 class ProfileNotFound(Exception): |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
59 """ |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
60 exception when a profile is specified but is not present in a given |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
61 .ini file |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
62 """ |
47
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
63 def __init__(self, profile, config): |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
64 self.profile = profile |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
65 self.config = config |
57
3b4b87faa2a8
* make options case-sensitive
Jeff Hammel <jhammel@mozilla.com>
parents:
56
diff
changeset
|
66 Exception.__init__(self, |
3b4b87faa2a8
* make options case-sensitive
Jeff Hammel <jhammel@mozilla.com>
parents:
56
diff
changeset
|
67 'Profile %s not found in %s' % (profile, config)) |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
68 |
65
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
69 class NoBackupError(Exception): |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
70 """ |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
71 exception when a sought backup is not found |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
72 """ |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
73 |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
74 class ProfileManager(object): |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
75 |
47
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
76 backups_dir = 'backups' # directory for backups relative to profile_dir |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
77 |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
78 def __init__(self, profiles): |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
79 """ |
4
35dc297efa25
adding listing function and other cleanup
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
80 - profiles: filesystem path to profiles.ini file |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
81 """ |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
82 self.profiles = profiles |
4
35dc297efa25
adding listing function and other cleanup
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
83 self.profile_dir = os.path.abspath(os.path.dirname(profiles)) |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
84 |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
85 ### (public) API |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
86 |
16 | 87 def new(self, name, directory=None, hash=True): |
9
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
88 """ |
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
89 generate a new clean profile |
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
90 - name: name of the profile to generate |
16 | 91 - directory: where to create the profile [DEFAULT: relative to profiles.ini] |
92 - hash: whether to generate a a random hash tag | |
9
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
93 """ |
16 | 94 |
95 # path to the profile directory | |
20 | 96 dirname = name |
97 relative = False | |
16 | 98 if hash: |
18
8e651dd8e9ad
fix two things about hash() usage
Jeff Hammel <jhammel@mozilla.com>
parents:
16
diff
changeset
|
99 dirname = '%s.%s' % (self.hash(), dirname) |
16 | 100 if not directory: |
101 directory = self.profile_dir | |
20 | 102 relative = True |
103 path = os.path.join(directory, dirname) | |
16 | 104 |
105 # create directory | |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
106 # TODO: (optionally) pre-populate the directory a la Firefox |
20 | 107 os.mkdir(path) |
16 | 108 |
19
4a1815f8d146
* stub adding new profile to configuration
Jeff Hammel <jhammel@mozilla.com>
parents:
18
diff
changeset
|
109 # update profiles.ini |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
110 self.add(name, relative and dirname or path, relative) |
79 | 111 |
16 | 112 # return the directory name |
36
a6222b71aab6
return the right thing, finally
Jeff Hammel <jhammel@mozilla.com>
parents:
31
diff
changeset
|
113 return path |
9
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
114 |
19
4a1815f8d146
* stub adding new profile to configuration
Jeff Hammel <jhammel@mozilla.com>
parents:
18
diff
changeset
|
115 def remove(self, name, delete=True): |
4a1815f8d146
* stub adding new profile to configuration
Jeff Hammel <jhammel@mozilla.com>
parents:
18
diff
changeset
|
116 """ |
4a1815f8d146
* stub adding new profile to configuration
Jeff Hammel <jhammel@mozilla.com>
parents:
18
diff
changeset
|
117 remove a profile from profiles.ini |
20 | 118 - delete: delete the profile directory as well |
19
4a1815f8d146
* stub adding new profile to configuration
Jeff Hammel <jhammel@mozilla.com>
parents:
18
diff
changeset
|
119 """ |
37 | 120 parser = self.parser() |
121 section = self.section(name, parser) | |
21
15484adb9758
note what section a a profile is in
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
122 if section is None: |
47
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
123 raise ProfileNotFound(profile, self.profiles) |
22
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
124 if delete: # remove the profile from disk |
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
125 shutil.rmtree(self.path(name)) |
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
126 parser.remove_section(section) |
51
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
127 self.write(parser) |
19
4a1815f8d146
* stub adding new profile to configuration
Jeff Hammel <jhammel@mozilla.com>
parents:
18
diff
changeset
|
128 |
4
35dc297efa25
adding listing function and other cleanup
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
129 def list(self, directories=False): |
35dc297efa25
adding listing function and other cleanup
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
130 """ |
35dc297efa25
adding listing function and other cleanup
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
131 lists the profiles available in the config file |
6
2a3f5cdfd60c
flush out helper functions and list directories
Jeff Hammel <jhammel@mozilla.com>
parents:
5
diff
changeset
|
132 - directories : display the directories |
4
35dc297efa25
adding listing function and other cleanup
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
133 """ |
9
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
134 profiles = self.profiles_dict() |
38 | 135 if not directories: |
136 return sorted(profiles.keys()) | |
137 return dict([(name, self.path(name)) for name in profiles.keys()]) | |
4
35dc297efa25
adding listing function and other cleanup
Jeff Hammel <jhammel@mozilla.com>
parents:
3
diff
changeset
|
138 |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
139 def clone(self, source, dest, add=True): |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
140 """ |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
141 clones the profile `source` and output to `dest` |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
142 - add: add the profile to the profiles.ini file |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
143 """ |
45 | 144 |
145 # filesystem path of the `from` profile | |
79 | 146 source_path = self.path(source) |
7
d3b22d086934
comments for what to do next
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
147 |
8
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
148 # dest: fs path to back up to |
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
149 relative = False |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
150 if os.path.sep in dest: |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
151 if not os.path.isabs(dest): |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
152 dest = os.path.abspath(dest) |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
153 dirname = dest |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
154 name = os.path.basename(dest) |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
155 else: |
46
df1b2e48dddb
handle hashing for clones only if they are added to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
45
diff
changeset
|
156 name = dest |
8
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
157 relative = True |
46
df1b2e48dddb
handle hashing for clones only if they are added to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
45
diff
changeset
|
158 if add: |
df1b2e48dddb
handle hashing for clones only if they are added to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
45
diff
changeset
|
159 dirname = '%s.%s' % (self.hash(), name) |
48
09a2666999fa
* restore profiles.ini to base in tests
Jeff Hammel <jhammel@mozilla.com>
parents:
47
diff
changeset
|
160 dest = os.path.join(self.profile_dir, dirname) |
7
d3b22d086934
comments for what to do next
Jeff Hammel <jhammel@mozilla.com>
parents:
6
diff
changeset
|
161 |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
162 # update profiles.ini |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
163 if add: |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
164 self.add(name, dirname, relative) |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
165 |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
166 # copy the files |
8
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
167 shutil.copytree(source_path, dest, symlinks=False) |
43 | 168 |
169 return dest | |
1
979315ed0816
mucho cleanup on optionparser stuff
Jeff Hammel <jhammel@mozilla.com>
parents:
0
diff
changeset
|
170 |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
171 def backup(self, profile, dest=None): |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
172 """ |
56 | 173 backup a profile |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
174 - profile: name of the profile to be backed up |
56 | 175 - dest: name of the destination; if not given, a default is used |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
176 """ |
47
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
177 |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
178 # get the profile section |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
179 parser = self.parser() |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
180 section = self.section(profile) |
58
ce6a101fb239
check for section; of course profile will not be none
Jeff Hammel <jhammel@mozilla.com>
parents:
57
diff
changeset
|
181 if section is None: |
47
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
182 raise ProfileNotFound(profile, self.profiles) |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
183 |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
184 # determine destination directory |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
185 if dest is None: |
8
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
186 dest = '%s.%d.bak' % (profile, int(time.time())) |
47
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
187 name = dest |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
188 backups_dir = os.path.join(self.profile_dir, self.backups_dir) |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
189 if not os.path.exists(backups_dir): |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
190 os.mkdir(backups_dir) |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
191 dest = os.path.join(backups_dir, dest) |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
192 else: |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
193 if not os.path.isabs(dest): |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
194 dest = os.path.abspath(dest) |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
195 name = dest |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
196 |
77
e091caa41075
add assertion that path doesnt exist already
Jeff Hammel <jhammel@mozilla.com>
parents:
75
diff
changeset
|
197 # ensure backup directory is not already present |
e091caa41075
add assertion that path doesnt exist already
Jeff Hammel <jhammel@mozilla.com>
parents:
75
diff
changeset
|
198 assert not os.path.exists(dest), "'%s' already exists" |
e091caa41075
add assertion that path doesnt exist already
Jeff Hammel <jhammel@mozilla.com>
parents:
75
diff
changeset
|
199 |
47
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
200 # copy the files |
45 | 201 self.clone(profile, dest, add=False) |
79 | 202 |
51
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
203 # add backup entry to profiles.ini (colon separated): |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
204 # `Backup=$(profile)s.$(datestamp)s.bak` |
51
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
205 if parser.has_option(section, 'Backups'): |
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
206 backups = '%s:%s' % (parser.get(section, 'Backups'), name) |
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
207 else: |
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
208 backups = name |
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
209 parser.set(section, 'Backups', backups) |
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
210 self.write(parser) |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
211 |
52
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
212 def backups(self, profile=None, datestamp=None): |
10
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
213 """ |
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
214 list backups for a given profile, or all profiles if the |
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
215 profile is not given; returns a list of backups if |
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
216 profile is given or a dictionary of lists otherwise |
53
c279d2797d45
document datestamp argument
Jeff Hammel <jhammel@mozilla.com>
parents:
52
diff
changeset
|
217 - datestamp: format of date; otherwise, seconds since epoch |
10
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
218 """ |
52
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
219 if profile is None: # all profiles |
10
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
220 retval = {} |
52
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
221 profiles_dict = self.profiles_dict() |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
222 for profile in profiles_dict: |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
223 if 'Backups' in profiles_dict[profile]: |
64
18f16bd1ba6b
finish backups listing function and formatting for it
Jeff Hammel <jhammel@mozilla.com>
parents:
63
diff
changeset
|
224 retval[profile] = self.backups(profile, datestamp) |
10
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
225 return retval |
52
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
226 |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
227 # single profile |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
228 profile_dict = self.profile_dict(profile) |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
229 if 'Backups' not in profile_dict: |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
230 return [] |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
231 backups = profile_dict['Backups'].split(':') |
63 | 232 backups_dirs = [] |
52
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
233 for backup in backups: |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
234 if os.path.isabs(backup): |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
235 backup_dir = backup |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
236 else: |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
237 backup_dir = os.path.join(self.profile_dir, self.backups_dir, backup) |
75 | 238 try: |
239 backups_dirs.append((backup, int(os.path.getmtime(backup_dir)))) | |
240 except OSError: | |
241 print >> sys.stderr, "%s specified in %s, but the directory %s does not exist" % (backup, self.profiles, backup_dir) | |
52
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
242 # TODO: check if the getmtime == the datestamp for relative backups |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
243 |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
244 # sort by reverse datestamp |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
245 backups_dirs.sort(key=lambda x: x[1], reverse=True) |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
246 |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
247 # format to datestamps, if applicable |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
248 if datestamp: |
63 | 249 backups_dirs = [ (i[0], time.strftime(datestamp, |
52
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
250 time.localtime(int(i[1])))) |
63 | 251 for i in backups_dirs ] |
52
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
252 |
85b5fe402ab4
finish backups functionality (to test)
Jeff Hammel <jhammel@mozilla.com>
parents:
51
diff
changeset
|
253 return backups_dirs |
10
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
254 |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
255 def restore(self, profile, date=None, delete=False): |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
256 """ |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
257 restore the profile from a backup |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
258 the most recent backup is used unless `date` is given |
65
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
259 - date : date to restore from (will not delete) |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
260 - delete : delete the backup after restoration |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
261 """ |
8
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
262 |
65
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
263 assert not (date and delete), 'date and delete cannot be used in conjunction' |
73
1cfd259f74cf
finish dated backups, untested
Jeff Hammel <jhammel@mozilla.com>
parents:
71
diff
changeset
|
264 orig_date = date |
65
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
265 |
66
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
266 # get the path to the profile |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
267 path = self.path(profile) |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
268 |
8
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
269 # get the possible backups |
10
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
270 backups = self.backups(profile) |
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
271 # TODO: check to see if these all exist (print warnings if not) |
8
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
272 |
65
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
273 # determine the backup to use |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
274 if date: |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
275 |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
276 if isinstance(date, basestring): |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
277 |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
278 # test for s since epoch |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
279 seconds_snice_epoch = None |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
280 try: |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
281 seconds_since_epoch = int(date) |
79 | 282 |
65
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
283 except ValueError: |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
284 pass |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
285 if seconds_since_epoch and seconds_since_epoch > time.localtime().tm_year: |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
286 date = seconds_since_epoch |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
287 else: |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
288 date = parse(date) # parse date from string |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
289 |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
290 if isinstance(date, datetime): |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
291 # convert to s since epoch |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
292 date = time.mktime(date.timetuple()) |
79 | 293 |
65
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
294 for backup in backups: |
73
1cfd259f74cf
finish dated backups, untested
Jeff Hammel <jhammel@mozilla.com>
parents:
71
diff
changeset
|
295 if backup[1] < date: |
1cfd259f74cf
finish dated backups, untested
Jeff Hammel <jhammel@mozilla.com>
parents:
71
diff
changeset
|
296 break |
1cfd259f74cf
finish dated backups, untested
Jeff Hammel <jhammel@mozilla.com>
parents:
71
diff
changeset
|
297 else: |
1cfd259f74cf
finish dated backups, untested
Jeff Hammel <jhammel@mozilla.com>
parents:
71
diff
changeset
|
298 raise NoBackupError("No backups for profile %s in %s earlier than %s" % (profile, self.profiles, orig_date)) |
65
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
299 else: |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
300 if not backups: |
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
301 raise NoBackupError("No backups for profile %s in %s" % (profile, self.profiles)) |
66
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
302 backup = backups[0] |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
303 |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
304 # determine path of the backup |
67 | 305 if os.path.isabs(backup[0]): |
66
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
306 backup_path = backup |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
307 else: |
69
86b137d49467
use only the path element, not the whole tuple
Jeff Hammel <jhammel@mozilla.com>
parents:
67
diff
changeset
|
308 backup_path = os.path.join(self.profile_dir, self.backups_dir, backup[0]) |
65
1cd3e3c71bff
determine which backup to use from the given date
Jeff Hammel <jhammel@mozilla.com>
parents:
64
diff
changeset
|
309 |
8
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
310 # restore the backup over ``profile`` |
66
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
311 # make a backup copy first to avoid data loss |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
312 tempdir = tempfile.mktemp() |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
313 shutil.move(path, tempdir) |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
314 try: |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
315 shutil.copytree(backup_path, path) |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
316 except Exception, e: |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
317 shutil.rmtree(path) |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
318 shutil.move(tempdir, path) |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
319 raise IOError("Couldn't restore backup: %s" % str(e)) |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
320 shutil.rmtree(tempdir) |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
321 # TODO: (optionally) make a backup of the current profile before restore |
8
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
322 |
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
323 if delete: # delete the backup |
66
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
324 |
10
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
325 # delete the directory |
66
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
326 shutil.rmtree(backup_path) |
79 | 327 |
10
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
328 # delete the entry from ``profiles.ini`` |
66
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
329 parser = self.parser() |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
330 section = self.section(profile) |
70 | 331 backups = parser.get(section, 'Backups').split(':') |
66
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
332 backups = [ i for i in backups if i != backup[0] ] |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
333 parser.set(section, 'Backups', ':'.join(backups)) |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
334 |
10
c77e9bef78d6
* update list of public API functions
Jeff Hammel <jhammel@mozilla.com>
parents:
9
diff
changeset
|
335 # if there are no backups, delete the ``backups`` line |
66
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
336 # and the backups directory |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
337 if not backups: |
71
494ea3c2f578
use correct ConfigParser method
Jeff Hammel <jhammel@mozilla.com>
parents:
70
diff
changeset
|
338 parser.remove_option(section, 'Backups') |
66
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
339 backups_dir = os.path.join(self.profile_dir, self.backups_dir) |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
340 if not os.listdir(backups_dir): |
67dc95a355cc
finish basic restore logic
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
341 shutil.rmtree(backups_dir) |
47
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
342 |
75 | 343 self.write(parser) |
344 | |
74
b6bb59b79525
* return the backed-up profile
Jeff Hammel <jhammel@mozilla.com>
parents:
73
diff
changeset
|
345 # return which backup is restored |
b6bb59b79525
* return the backed-up profile
Jeff Hammel <jhammel@mozilla.com>
parents:
73
diff
changeset
|
346 return backup |
b6bb59b79525
* return the backed-up profile
Jeff Hammel <jhammel@mozilla.com>
parents:
73
diff
changeset
|
347 |
47
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
348 def temporary(self): |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
349 """make a temporary profile""" |
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
350 raise NotImplementedError |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
351 |
5
ca57920aa223
adding better formatting for list
Jeff Hammel <jhammel@mozilla.com>
parents:
4
diff
changeset
|
352 def merge(self, output, *profiles): |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
353 """merge a set of profiles (not trivial!)""" |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
354 raise NotImplementedError |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
355 |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
356 ### internal functions |
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
357 |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
358 def add(self, profile, path, relative=True): |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
359 """ |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
360 add a profile entry to profiles.ini |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
361 """ |
41 | 362 |
363 # ensure name is not already present | |
364 assert profile not in self.profiles_dict(), 'Profile "%s" already in %s' % (name, self.profiles) | |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
365 parser = self.parser() |
41 | 366 |
79 | 367 # find and add the section |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
368 ctr = 0 |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
369 section = 'Profile%d' % ctr # unsure of this naming convention |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
370 while section in parser.sections(): |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
371 ctr += 1 |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
372 section = 'Profile%d' % ctr |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
373 parser.add_section(section) |
41 | 374 |
375 # add metadata | |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
376 parser.set(section, 'Name', profile) |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
377 parser.set(section, 'IsRelative', '%d' % int(relative)) |
42 | 378 parser.set(section, 'Path', path) |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
379 if not ctr: |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
380 parser.set(section, 'Default', '1') |
41 | 381 |
382 # write the file | |
51
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
383 self.write(parser) |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
384 |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
385 def path(self, profile): |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
386 """returns the path to the profile""" |
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
387 profile = self.profile_dict(profile) |
62 | 388 if profile.get('IsRelative', None) == '1': |
389 return os.path.join(self.profile_dir, profile['Path']) | |
390 return profile['Path'] | |
40
34c740d1962d
abstract out adding an entry to profiles.ini
Jeff Hammel <jhammel@mozilla.com>
parents:
39
diff
changeset
|
391 |
22
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
392 def parser(self): |
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
393 """ |
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
394 return a ConfigParser instance appropriate to profiles.ini |
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
395 """ |
25
fc31d3f26755
i seriously need to learn to code
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
396 parser = ConfigParser() |
57
3b4b87faa2a8
* make options case-sensitive
Jeff Hammel <jhammel@mozilla.com>
parents:
56
diff
changeset
|
397 parser.optionxform = str |
25
fc31d3f26755
i seriously need to learn to code
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
398 parser.read(self.profiles) |
fc31d3f26755
i seriously need to learn to code
Jeff Hammel <jhammel@mozilla.com>
parents:
24
diff
changeset
|
399 return parser |
22
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
400 |
51
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
401 def write(self, parser): |
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
402 f = file(self.profiles, 'w') |
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
403 parser.write(f) |
dc9324b52c2a
* add write convenience function
Jeff Hammel <jhammel@mozilla.com>
parents:
50
diff
changeset
|
404 f.close() |
0
7301d534bc6c
initial messy and incomplete strawman prototype for Mozilla (Firefox) profile management
Jeff Hammel <k0scist@gmail.com>
parents:
diff
changeset
|
405 |
22
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
406 def section(self, profile, parser=None): |
20 | 407 """ |
21
15484adb9758
note what section a a profile is in
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
408 returns the name of the section that a profile is in or None |
15484adb9758
note what section a a profile is in
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
409 if not found |
20 | 410 """ |
22
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
411 if parser is None: |
29 | 412 parser = self.parser() |
31 | 413 for section in parser.sections(): |
61
24782e4c70ca
now that we are case sensitive, correct case for getting options
Jeff Hammel <jhammel@mozilla.com>
parents:
59
diff
changeset
|
414 if not parser.has_option(section, 'Name'): |
21
15484adb9758
note what section a a profile is in
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
415 continue # not a profile |
61
24782e4c70ca
now that we are case sensitive, correct case for getting options
Jeff Hammel <jhammel@mozilla.com>
parents:
59
diff
changeset
|
416 if parser.get(section, 'Name') == profile: |
21
15484adb9758
note what section a a profile is in
Jeff Hammel <jhammel@mozilla.com>
parents:
20
diff
changeset
|
417 return section |
20 | 418 |
27
5988a15da3b4
things are being awful; checking in anyway
Jeff Hammel <jhammel@mozilla.com>
parents:
26
diff
changeset
|
419 def profile_dict(self, profile): |
5988a15da3b4
things are being awful; checking in anyway
Jeff Hammel <jhammel@mozilla.com>
parents:
26
diff
changeset
|
420 """ |
5988a15da3b4
things are being awful; checking in anyway
Jeff Hammel <jhammel@mozilla.com>
parents:
26
diff
changeset
|
421 return option dictionary for a single profile |
5988a15da3b4
things are being awful; checking in anyway
Jeff Hammel <jhammel@mozilla.com>
parents:
26
diff
changeset
|
422 """ |
5988a15da3b4
things are being awful; checking in anyway
Jeff Hammel <jhammel@mozilla.com>
parents:
26
diff
changeset
|
423 parser = self.parser() |
5988a15da3b4
things are being awful; checking in anyway
Jeff Hammel <jhammel@mozilla.com>
parents:
26
diff
changeset
|
424 section = self.section(profile, parser) |
5988a15da3b4
things are being awful; checking in anyway
Jeff Hammel <jhammel@mozilla.com>
parents:
26
diff
changeset
|
425 if section is None: |
47
420becb84df7
* move exception string to the exception itself
Jeff Hammel <jhammel@mozilla.com>
parents:
46
diff
changeset
|
426 raise ProfileNotFound(profile, self.profiles) |
27
5988a15da3b4
things are being awful; checking in anyway
Jeff Hammel <jhammel@mozilla.com>
parents:
26
diff
changeset
|
427 return dict(parser.items(section)) |
5988a15da3b4
things are being awful; checking in anyway
Jeff Hammel <jhammel@mozilla.com>
parents:
26
diff
changeset
|
428 |
9
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
429 def profiles_dict(self): |
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
430 """ |
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
431 return nested dict of all profiles |
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
432 """ |
22
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
433 # assumes profiles have unique names |
956f5a4c589a
* restructure utility functions to do less more efficiently
Jeff Hammel <jhammel@mozilla.com>
parents:
21
diff
changeset
|
434 parser = self.parser() |
9
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
435 retval = {} |
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
436 for section in parser.sections(): |
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
437 if section == 'General': |
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
438 continue |
59
ee2777913a9e
check the correct way to see if the option is there
Jeff Hammel <jhammel@mozilla.com>
parents:
58
diff
changeset
|
439 if not parser.has_option(section, 'Name'): |
9
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
440 continue |
61
24782e4c70ca
now that we are case sensitive, correct case for getting options
Jeff Hammel <jhammel@mozilla.com>
parents:
59
diff
changeset
|
441 name = parser.get(section, 'Name') |
9
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
442 retval[name] = self.profile_dict(name) |
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
443 return retval |
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
444 |
8
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
445 def hash(self): |
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
446 """ |
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
447 generate a random hash for a new profile |
7205cb6f5530
various flushing out, deleting old TODOs and making new ones
Jeff Hammel <jhammel@mozilla.com>
parents:
7
diff
changeset
|
448 """ |
15
543d08958b67
actually sample 8 random lowercase letters and numbers for the profile hash
Jeff Hammel <jhammel@mozilla.com>
parents:
10
diff
changeset
|
449 population = string.lowercase + string.digits |
18
8e651dd8e9ad
fix two things about hash() usage
Jeff Hammel <jhammel@mozilla.com>
parents:
16
diff
changeset
|
450 return ''.join(Random().sample(population, 8)) |
9
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
451 |
b1274abd1206
rework API a bit; the "public" methods are becoming a bit specialized to the command line, which was my fear, so I should probably inherit from ProfileManager to do the interface like I should
Jeff Hammel <jhammel@mozilla.com>
parents:
8
diff
changeset
|
452 |