Merge lp:~adreeve/backintime/samba_access into lp:backintime/1.0
- samba_access
- Merge into release-1.0
Status: | Needs review |
---|---|
Proposed branch: | lp:~adreeve/backintime/samba_access |
Merge into: | lp:backintime/1.0 |
Diff against target: |
1000 lines (+586/-73) 10 files modified
common/config.py (+107/-1) common/debian_specific/control (+1/-1) common/network.py (+105/-0) common/snapshots.py (+41/-10) common/tools.py (+1/-3) gnome/app.py (+10/-2) gnome/settingsdialog.glade (+160/-35) gnome/settingsdialog.py (+79/-15) kde4/app.py (+4/-0) kde4/settingsdialog.py (+78/-6) |
To merge this branch: | bzr merge lp:~adreeve/backintime/samba_access |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Back In Time Team | Pending | ||
Review via email: mp+22283@code.launchpad.net |
Commit message
Description of the change
Adds support for backing up to network shares. It currently implements samba shares but more protocols can be added by specifying commands to mount and unmount the share. This can be configured in both the Gnome and KDE GUIs.
- 724. By Adam Reeve
-
Fix problems when updating snapshot locations to new version when using samba access.
- 725. By Adam Reeve
-
Merge from trunk
- 726. By Adam Reeve
-
Merge from trunk
Unmerged revisions
- 726. By Adam Reeve
-
Merge from trunk
- 725. By Adam Reeve
-
Merge from trunk
- 724. By Adam Reeve
-
Fix problems when updating snapshot locations to new version when using samba access.
- 723. By Adam Reeve
-
Removed all my vim modelines
- 722. By Adam Reeve
-
Changed mount commands to use full path as otherwise get a command not found error when running as a cron job
- 721. By Adam Reeve
-
Work on KDE interface for network access
- 720. By Adam Reeve
-
Fixed crash when config file doesn't exist
- 719. By Adam Reeve
-
Work on samba access, GTK interface should be finished now
- 718. By Adam Reeve
-
Merged changes in trunk
- 717. By Adam Reeve
-
Work on gnome interface for network shares
Preview Diff
1 | === modified file 'common/config.py' | |||
2 | --- common/config.py 2010-04-01 17:57:51 +0000 | |||
3 | +++ common/config.py 2010-04-16 06:46:25 +0000 | |||
4 | @@ -22,10 +22,12 @@ | |||
5 | 22 | import gettext | 22 | import gettext |
6 | 23 | import socket | 23 | import socket |
7 | 24 | import random | 24 | import random |
8 | 25 | import re | ||
9 | 25 | 26 | ||
10 | 26 | import configfile | 27 | import configfile |
11 | 27 | import tools | 28 | import tools |
12 | 28 | import logger | 29 | import logger |
13 | 30 | import network | ||
14 | 29 | 31 | ||
15 | 30 | _=gettext.gettext | 32 | _=gettext.gettext |
16 | 31 | 33 | ||
17 | @@ -175,10 +177,41 @@ | |||
18 | 175 | self.remove_profile_key( 'snapshots.include_folders', profile_id ) | 177 | self.remove_profile_key( 'snapshots.include_folders', profile_id ) |
19 | 176 | self.remove_profile_key( 'snapshots.exclude_patterns', profile_id ) | 178 | self.remove_profile_key( 'snapshots.exclude_patterns', profile_id ) |
20 | 177 | 179 | ||
22 | 178 | self.set_int_value( 'config.version', self.CONFIG_VERSION ) | 180 | # make sure config version is set |
23 | 181 | self.set_int_value( 'config.version', self.CONFIG_VERSION ) | ||
24 | 182 | |||
25 | 183 | # mount required network shares | ||
26 | 184 | self.mount_shares() | ||
27 | 185 | |||
28 | 186 | def mount_shares( self, profile=None ): | ||
29 | 187 | self.network_mounts = {} | ||
30 | 188 | if profile is None: | ||
31 | 189 | profiles = self.get_profiles() | ||
32 | 190 | else: | ||
33 | 191 | profiles = [profile] | ||
34 | 192 | for profile_id in profiles: | ||
35 | 193 | if (self.get_snapshot_access_mode(profile_id) in network.NETWORK_ACCESS_MODES): | ||
36 | 194 | # mount network share now if the snapshots are stored on a network share | ||
37 | 195 | path = self.get_profile_str_value('snapshots.network_path','',profile_id) | ||
38 | 196 | protocol = self.get_snapshot_access_mode(profile_id) | ||
39 | 197 | username = self.get_profile_str_value('snapshots.username','',profile_id) | ||
40 | 198 | password = network.password_decode(self.get_profile_str_value('snapshots.password','',profile_id)) | ||
41 | 199 | self.network_mounts[profile_id] = network.NetworkMount(path,protocol,username,password) | ||
42 | 200 | |||
43 | 201 | def unmount_shares( self ): | ||
44 | 202 | for mount in self.network_mounts.values(): | ||
45 | 203 | mount.unmount() | ||
46 | 204 | self.network_mounts.clear() | ||
47 | 205 | |||
48 | 206 | def update_shares( self ): | ||
49 | 207 | self.unmount_shares() | ||
50 | 208 | self.mount_shares() | ||
51 | 179 | 209 | ||
52 | 180 | def save( self ): | 210 | def save( self ): |
53 | 181 | configfile.ConfigFile.save( self, self._LOCAL_CONFIG_PATH ) | 211 | configfile.ConfigFile.save( self, self._LOCAL_CONFIG_PATH ) |
54 | 212 | # make sure no other users can read the config file | ||
55 | 213 | # as it may contain encoded passwords for network shares | ||
56 | 214 | os.chmod(self._LOCAL_CONFIG_PATH,0600) | ||
57 | 182 | 215 | ||
58 | 183 | def check_config( self ): | 216 | def check_config( self ): |
59 | 184 | profiles = self.get_profiles() | 217 | profiles = self.get_profiles() |
60 | @@ -252,8 +285,27 @@ | |||
61 | 252 | return user | 285 | return user |
62 | 253 | 286 | ||
63 | 254 | def get_snapshots_path( self, profile_id = None ): | 287 | def get_snapshots_path( self, profile_id = None ): |
64 | 288 | if (self.get_snapshot_access_mode(profile_id) in network.NETWORK_ACCESS_MODES): | ||
65 | 289 | if profile_id is None: | ||
66 | 290 | profile_id = self.get_current_profile() | ||
67 | 291 | if profile_id not in self.network_mounts.keys(): | ||
68 | 292 | self.mount_shares(profile_id) | ||
69 | 293 | return self.network_mounts[profile_id].path() | ||
70 | 294 | else: | ||
71 | 295 | return self.get_snapshots_local_path( profile_id ) | ||
72 | 296 | |||
73 | 297 | def get_snapshots_local_path( self, profile_id = None ): | ||
74 | 255 | return self.get_profile_str_value( 'snapshots.path', '', profile_id ) | 298 | return self.get_profile_str_value( 'snapshots.path', '', profile_id ) |
75 | 256 | 299 | ||
76 | 300 | def get_snapshots_username( self, profile_id = None ): | ||
77 | 301 | return self.get_profile_str_value( 'snapshots.username', '', profile_id ) | ||
78 | 302 | |||
79 | 303 | def get_snapshots_password( self, profile_id = None ): | ||
80 | 304 | return network.password_decode(self.get_profile_str_value( 'snapshots.password', '', profile_id )) | ||
81 | 305 | |||
82 | 306 | def get_snapshots_network_path( self, profile_id = None ): | ||
83 | 307 | return self.get_profile_str_value( 'snapshots.network_path', '', profile_id ) | ||
84 | 308 | |||
85 | 257 | def get_snapshots_full_path( self, profile_id = None, version = None ): | 309 | def get_snapshots_full_path( self, profile_id = None, version = None ): |
86 | 258 | '''Returns the full path for the snapshots: .../backintime/machine/user/profile_id/''' | 310 | '''Returns the full path for the snapshots: .../backintime/machine/user/profile_id/''' |
87 | 259 | if version is None: | 311 | if version is None: |
88 | @@ -304,6 +356,54 @@ | |||
89 | 304 | 356 | ||
90 | 305 | os.rmdir( check_path ) | 357 | os.rmdir( check_path ) |
91 | 306 | self.set_profile_str_value( 'snapshots.path', value, profile_id ) | 358 | self.set_profile_str_value( 'snapshots.path', value, profile_id ) |
92 | 359 | self.set_profile_int_value( 'snapshots.access', network.LOCAL, profile_id ) | ||
93 | 360 | return True | ||
94 | 361 | |||
95 | 362 | def set_snapshots_network_details( self, location, protocol, username, password, profile_id = None ): | ||
96 | 363 | """Sets network access details and checks that they work""" | ||
97 | 364 | # remove anything like smb: at the start | ||
98 | 365 | match = re.compile(r"^([a-zA-Z]+:)?(//)?(.+)$").match(location) | ||
99 | 366 | if not match: # only occurs if location is empty | ||
100 | 367 | self.notify_error( _( 'Invalid network location, %s' ) % location ) | ||
101 | 368 | return False | ||
102 | 369 | location = "//"+match.group(3) | ||
103 | 370 | |||
104 | 371 | if profile_id == None: | ||
105 | 372 | profile_id = self.get_current_profile() | ||
106 | 373 | |||
107 | 374 | test_mount = network.NetworkMount(location, protocol, username, password) | ||
108 | 375 | if not test_mount.mounted(): | ||
109 | 376 | test_mount.unmount() #removes directory | ||
110 | 377 | self.notify_error( _( 'Can\'t mount network share: %s\nAre you sure you sure your settings are correct?' % location ) ) | ||
111 | 378 | return False | ||
112 | 379 | |||
113 | 380 | #Initialize the snapshots folder | ||
114 | 381 | print "Check snapshot mount: %s" % location | ||
115 | 382 | machine = socket.gethostname() | ||
116 | 383 | user = self.get_user() | ||
117 | 384 | full_path = os.path.join( test_mount.path(), 'backintime', machine, user, profile_id ) | ||
118 | 385 | if not os.path.isdir( full_path ): | ||
119 | 386 | print "Create folder: %s" % full_path | ||
120 | 387 | tools.make_dirs( full_path ) | ||
121 | 388 | if not os.path.isdir( full_path ): | ||
122 | 389 | self.notify_error( _( 'Can\'t write to: %s\nAre you sure you have write access ?' % location ) ) | ||
123 | 390 | return False | ||
124 | 391 | |||
125 | 392 | #Test write access for the folder | ||
126 | 393 | check_path = os.path.join( full_path, 'check' ) | ||
127 | 394 | tools.make_dirs( check_path ) | ||
128 | 395 | if not os.path.isdir( check_path ): | ||
129 | 396 | self.notify_error( _( 'Can\'t write to: %s\nAre you sure you have write access ?' % full_path.replace(test_mount.path(),location) ) ) | ||
130 | 397 | return False | ||
131 | 398 | os.rmdir( check_path ) | ||
132 | 399 | |||
133 | 400 | test_mount.unmount() | ||
134 | 401 | |||
135 | 402 | encoded_pw = network.password_encode(password) | ||
136 | 403 | self.set_profile_int_value( 'snapshots.access', protocol, profile_id ) | ||
137 | 404 | self.set_profile_str_value( 'snapshots.network_path', location, profile_id ) | ||
138 | 405 | self.set_profile_str_value( 'snapshots.username', username, profile_id ) | ||
139 | 406 | self.set_profile_str_value( 'snapshots.password', encoded_pw, profile_id ) | ||
140 | 307 | return True | 407 | return True |
141 | 308 | 408 | ||
142 | 309 | def get_other_folders_paths( self, profile_id = None ): | 409 | def get_other_folders_paths( self, profile_id = None ): |
143 | @@ -418,6 +518,12 @@ | |||
144 | 418 | def get_tag( self, profile_id = None ): | 518 | def get_tag( self, profile_id = None ): |
145 | 419 | return self.get_profile_str_value( 'snapshots.tag', str(random.randint(100, 999)), profile_id ) | 519 | return self.get_profile_str_value( 'snapshots.tag', str(random.randint(100, 999)), profile_id ) |
146 | 420 | 520 | ||
147 | 521 | def get_snapshot_access_mode( self, profile_id = None ): | ||
148 | 522 | return self.get_profile_int_value( 'snapshots.access', network.LOCAL, profile_id ) | ||
149 | 523 | |||
150 | 524 | def set_snapshot_access_mode( self, value, profile_id = None ): | ||
151 | 525 | self.set_profile_int_value( 'snapshots.access', value, profile_id ) | ||
152 | 526 | |||
153 | 421 | def get_automatic_backup_mode( self, profile_id = None ): | 527 | def get_automatic_backup_mode( self, profile_id = None ): |
154 | 422 | return self.get_profile_int_value( 'snapshots.automatic_backup_mode', self.NONE, profile_id ) | 528 | return self.get_profile_int_value( 'snapshots.automatic_backup_mode', self.NONE, profile_id ) |
155 | 423 | 529 | ||
156 | 424 | 530 | ||
157 | === modified file 'common/debian_specific/control' | |||
158 | --- common/debian_specific/control 2010-04-01 17:57:51 +0000 | |||
159 | +++ common/debian_specific/control 2010-04-16 06:46:25 +0000 | |||
160 | @@ -7,7 +7,7 @@ | |||
161 | 7 | Homepage: http://backintime.le-web.org | 7 | Homepage: http://backintime.le-web.org |
162 | 8 | Architecture: all | 8 | Architecture: all |
163 | 9 | Depends: python, rsync, cron | 9 | Depends: python, rsync, cron |
165 | 10 | Recommends: powermgmt-base | 10 | Recommends: powermgmt-base, smbfs |
166 | 11 | Conflicts: backintime | 11 | Conflicts: backintime |
167 | 12 | Replaces: backintime | 12 | Replaces: backintime |
168 | 13 | Description: Simple backup system (common) | 13 | Description: Simple backup system (common) |
169 | 14 | 14 | ||
170 | === added file 'common/network.py' | |||
171 | --- common/network.py 1970-01-01 00:00:00 +0000 | |||
172 | +++ common/network.py 2010-04-16 06:46:25 +0000 | |||
173 | @@ -0,0 +1,105 @@ | |||
174 | 1 | # Back In Time | ||
175 | 2 | # Copyright (C) 2008-2009 Oprea Dan, Bart de Koning, Richard Bailey | ||
176 | 3 | # | ||
177 | 4 | # This program is free software; you can redistribute it and/or modify | ||
178 | 5 | # it under the terms of the GNU General Public License as published by | ||
179 | 6 | # the Free Software Foundation; either version 2 of the License, or | ||
180 | 7 | # (at your option) any later version. | ||
181 | 8 | # | ||
182 | 9 | # This program is distributed in the hope that it will be useful, | ||
183 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
184 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
185 | 12 | # GNU General Public License for more details. | ||
186 | 13 | # | ||
187 | 14 | # You should have received a copy of the GNU General Public License along | ||
188 | 15 | # with this program; if not, write to the Free Software Foundation, Inc., | ||
189 | 16 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
190 | 17 | |||
191 | 18 | import os.path | ||
192 | 19 | import os | ||
193 | 20 | import tempfile | ||
194 | 21 | import base64 | ||
195 | 22 | import gettext | ||
196 | 23 | |||
197 | 24 | import tools | ||
198 | 25 | |||
199 | 26 | _=gettext.gettext | ||
200 | 27 | |||
201 | 28 | LOCAL = 0 | ||
202 | 29 | SAMBA = 1 | ||
203 | 30 | |||
204 | 31 | NETWORK_ACCESS_MODES = [SAMBA] | ||
205 | 32 | |||
206 | 33 | SNAPSHOT_ACCESS = { | ||
207 | 34 | LOCAL : _('Local folder'), | ||
208 | 35 | SAMBA : _('Windows network share (Samba)') | ||
209 | 36 | } | ||
210 | 37 | |||
211 | 38 | def password_encode(password): | ||
212 | 39 | """encode a password using base64 but remove extra | ||
213 | 40 | equals signs from the end so they can be stored | ||
214 | 41 | in the config file""" | ||
215 | 42 | # this is not secure at all but means that the password | ||
216 | 43 | # isn't human readable in the config file. A more secure | ||
217 | 44 | # alternative would be to use the python keyring module | ||
218 | 45 | # to store the password using the KDE or Gnome keyring manager | ||
219 | 46 | # but this isn't available in most distros yet | ||
220 | 47 | return base64.urlsafe_b64encode(password).strip("=") | ||
221 | 48 | |||
222 | 49 | def password_decode(password): | ||
223 | 50 | """return the base64 decoded password and pad with equals | ||
224 | 51 | signs first so that the string is a multiple of 4 long""" | ||
225 | 52 | return base64.urlsafe_b64decode(password+'='*(4-len(password)%4)) | ||
226 | 53 | |||
227 | 54 | class NetworkMount: | ||
228 | 55 | def __init__( self, location, protocol, username="", password="" ): | ||
229 | 56 | self.location = location | ||
230 | 57 | self.username = username | ||
231 | 58 | self.password = password | ||
232 | 59 | supported_protocols = [SAMBA] | ||
233 | 60 | if protocol in supported_protocols: | ||
234 | 61 | self.protocol = protocol | ||
235 | 62 | else: | ||
236 | 63 | raise RuntimeError, "Unsupported network protocol, "+protocol | ||
237 | 64 | self.mount() | ||
238 | 65 | |||
239 | 66 | def __del__( self ): | ||
240 | 67 | self.unmount() | ||
241 | 68 | |||
242 | 69 | def mount( self ): | ||
243 | 70 | self.mount_dir = tempfile.mkdtemp(prefix="backintime_mount_") | ||
244 | 71 | # need to use full paths to mount and unmount commands so that they work in cron | ||
245 | 72 | if (self.protocol == SAMBA): | ||
246 | 73 | cmd = "/sbin/mount.cifs "+self.location+" "+self.mount_dir | ||
247 | 74 | if (self.username != "" and self.password != ""): | ||
248 | 75 | cmd += " -o username="+self.username+",password="+self.password | ||
249 | 76 | ret = _execute(cmd) | ||
250 | 77 | if (ret != 0): | ||
251 | 78 | print "Error mounting network share "+self.location | ||
252 | 79 | |||
253 | 80 | def unmount( self ): | ||
254 | 81 | """Unmount a network share and delete the mount directory. | ||
255 | 82 | You can't rely on python to delete the NetworkMount object so | ||
256 | 83 | this should be called manually when finished with a network share""" | ||
257 | 84 | if self.mounted(): | ||
258 | 85 | if (self.protocol == SAMBA): | ||
259 | 86 | cmd = "/sbin/umount.cifs "+self.mount_dir | ||
260 | 87 | _execute(cmd) | ||
261 | 88 | if os.path.isdir(self.mount_dir): | ||
262 | 89 | os.rmdir(self.mount_dir) | ||
263 | 90 | |||
264 | 91 | def path( self ): | ||
265 | 92 | return self.mount_dir | ||
266 | 93 | |||
267 | 94 | def mounted( self ): | ||
268 | 95 | if not os.path.isdir(self.mount_dir): | ||
269 | 96 | return False | ||
270 | 97 | ret = _execute("mountpoint "+self.mount_dir) | ||
271 | 98 | if (ret == 0): | ||
272 | 99 | return True | ||
273 | 100 | else: | ||
274 | 101 | return False | ||
275 | 102 | |||
276 | 103 | def _execute( cmd ): | ||
277 | 104 | ret_val = os.system( cmd ) | ||
278 | 105 | return ret_val | ||
279 | 0 | 106 | ||
280 | === modified file 'common/snapshots.py' | |||
281 | --- common/snapshots.py 2010-03-29 14:27:12 +0000 | |||
282 | +++ common/snapshots.py 2010-04-16 06:46:25 +0000 | |||
283 | @@ -34,6 +34,7 @@ | |||
284 | 34 | import applicationinstance | 34 | import applicationinstance |
285 | 35 | import tools | 35 | import tools |
286 | 36 | import pluginmanager | 36 | import pluginmanager |
287 | 37 | import network | ||
288 | 37 | 38 | ||
289 | 38 | 39 | ||
290 | 39 | _=gettext.gettext | 40 | _=gettext.gettext |
291 | @@ -514,26 +515,45 @@ | |||
292 | 514 | #print answer_same | 515 | #print answer_same |
293 | 515 | profile_id = profiles[0] | 516 | profile_id = profiles[0] |
294 | 516 | #print profile_id | 517 | #print profile_id |
297 | 517 | #old_folder = self.get_snapshots_path( profile_id ) | 518 | main_snapshot_access = self.config.get_snapshot_access_mode(profile_id) |
298 | 518 | #print old_folder | 519 | if main_snapshot_access in network.NETWORK_ACCESS_MODES: |
299 | 520 | main_network_path=self.config.get_snapshots_network_path(profile_id) | ||
300 | 521 | main_username=self.config.get_snapshots_username(profile_id) | ||
301 | 522 | main_password=self.config.get_snapshots_password(profile_id) | ||
302 | 523 | |||
303 | 519 | main_folder = self.config.get_snapshots_path( profile_id ) | 524 | main_folder = self.config.get_snapshots_path( profile_id ) |
305 | 520 | old_snapshots_paths=[] | 525 | old_snapshots_paths = [] |
306 | 526 | old_snapshot_access = [] | ||
307 | 527 | old_network_path = {} | ||
308 | 528 | old_username = {} | ||
309 | 529 | old_password = {} | ||
310 | 521 | counter = 0 | 530 | counter = 0 |
311 | 522 | success = [] | 531 | success = [] |
312 | 523 | 532 | ||
313 | 524 | for profile_id in profiles: | 533 | for profile_id in profiles: |
314 | 525 | #print counter | 534 | #print counter |
315 | 535 | old_snapshot_access.append(self.config.get_snapshot_access_mode(profile_id)) | ||
316 | 536 | if old_snapshot_access[counter] in network.NETWORK_ACCESS_MODES: | ||
317 | 537 | old_network_path[counter] = self.config.get_snapshots_network_path(profile_id) | ||
318 | 538 | old_username[counter] = self.config.get_snapshots_username(profile_id) | ||
319 | 539 | old_password[counter] = self.config.get_snapshots_password(profile_id) | ||
320 | 526 | old_snapshots_paths.append( self.config.get_snapshots_path( profile_id ) ) | 540 | old_snapshots_paths.append( self.config.get_snapshots_path( profile_id ) ) |
321 | 527 | #print old_snapshots_paths | 541 | #print old_snapshots_paths |
322 | 528 | old_folder = os.path.join( self.config.get_snapshots_path( profile_id ), 'backintime' ) | 542 | old_folder = os.path.join( self.config.get_snapshots_path( profile_id ), 'backintime' ) |
323 | 529 | #print old_folder | 543 | #print old_folder |
324 | 530 | if profile_id != "1" and answer_same == True: | 544 | if profile_id != "1" and answer_same == True: |
325 | 531 | #print 'profile_id != 1, answer = True' | 545 | #print 'profile_id != 1, answer = True' |
327 | 532 | self.config.set_snapshots_path( main_folder, profile_id ) | 546 | if main_snapshot_access in network.NETWORK_ACCESS_MODES: |
328 | 547 | self.config.set_snapshots_network_details( main_network_path, main_snapshot_access, main_username, main_password, profile_id ) | ||
329 | 548 | else: | ||
330 | 549 | self.config.set_snapshots_path( main_folder, profile_id ) | ||
331 | 533 | logger.info( 'Folder of profile %s is set to %s' %( profile_id, main_folder ) ) | 550 | logger.info( 'Folder of profile %s is set to %s' %( profile_id, main_folder ) ) |
332 | 534 | else: | 551 | else: |
335 | 535 | self.config.set_snapshots_path( self.config.get_snapshots_path( profile_id ), profile_id ) | 552 | if old_snapshot_access[counter] in network.NETWORK_ACCESS_MODES: |
336 | 536 | logger.info( 'Folder of profile %s is set to %s' %( profile_id, main_folder ) ) | 553 | self.config.set_snapshots_network_details( old_network_path[counter], old_snapshot_access[counter], old_username[counter], old_password[counter], profile_id ) |
337 | 554 | else: | ||
338 | 555 | self.config.set_snapshots_path( self.config.get_snapshots_path( profile_id ), profile_id ) | ||
339 | 556 | logger.info( 'Folder of profile %s is set to %s' %( profile_id, old_folder ) ) | ||
340 | 537 | new_folder = self.config.get_snapshots_full_path( profile_id ) | 557 | new_folder = self.config.get_snapshots_full_path( profile_id ) |
341 | 538 | #print new_folder | 558 | #print new_folder |
342 | 539 | #snapshots_to_move = tools.get_snapshots_list_in_folder( old_folder ) | 559 | #snapshots_to_move = tools.get_snapshots_list_in_folder( old_folder ) |
343 | @@ -560,7 +580,10 @@ | |||
344 | 560 | success.append( False ) | 580 | success.append( False ) |
345 | 561 | # restore | 581 | # restore |
346 | 562 | logger.info( 'Restore former settings' ) | 582 | logger.info( 'Restore former settings' ) |
348 | 563 | self.config.set_snapshots_path( old_snapshots_paths[counter], profile_id ) | 583 | if old_snapshot_access[counter] in network.NETWORK_ACCESS_MODES: |
349 | 584 | self.config.set_snapshots_network_details( old_network_path[counter], old_snapshot_access[counter], old_username[counter], old_password[counter], profile_id ) | ||
350 | 585 | else: | ||
351 | 586 | self.config.set_snapshots_path( old_snapshots_paths[counter], profile_id ) | ||
352 | 564 | #print self.get_snapshots_path( profile_id ) | 587 | #print self.get_snapshots_path( profile_id ) |
353 | 565 | self.config.error_handler( _('Former settings of profile %s are restored.\nBackinTime cannot continue taking new snapshots.\n\nYou can manually move the snapshots, \nif you are done restart BackinTime to proceed' %profile_id ) ) | 588 | self.config.error_handler( _('Former settings of profile %s are restored.\nBackinTime cannot continue taking new snapshots.\n\nYou can manually move the snapshots, \nif you are done restart BackinTime to proceed' %profile_id ) ) |
354 | 566 | 589 | ||
355 | @@ -584,9 +607,16 @@ | |||
356 | 584 | if answer_continue == True: | 607 | if answer_continue == True: |
357 | 585 | #self.set_update_other_folders( False ) | 608 | #self.set_update_other_folders( False ) |
358 | 586 | for profile_id in profiles: | 609 | for profile_id in profiles: |
362 | 587 | old_folder = self.config.get_snapshots_path( profile_id ) | 610 | old_snapshot_access = self.config.get_snapshot_access_mode(profile_id) |
363 | 588 | self.config.set_snapshots_path( old_folder, profile_id ) | 611 | if old_snapshot_access in network.NETWORK_ACCESS_MODES: |
364 | 589 | logger.info( 'Folder of profile %s is set to %s' %( profile_id, self.get_snapshots_path( profile_id ) ) ) | 612 | old_network_path = self.config.get_snapshots_network_path(profile_id) |
365 | 613 | old_username = self.config.get_snapshots_username(profile_id) | ||
366 | 614 | old_password = self.config.get_snapshots_password(profile_id) | ||
367 | 615 | self.config.set_snapshots_network_details( old_network_path, old_snapshot_access, old_username, old_password, profile_id ) | ||
368 | 616 | else: | ||
369 | 617 | old_folder = self.config.get_snapshots_path( profile_id ) | ||
370 | 618 | self.config.set_snapshots_path( old_folder, profile_id ) | ||
371 | 619 | logger.info( 'Folder of profile %s is set to %s' %( profile_id, self.get_snapshot_path( profile_id ) ) ) | ||
372 | 590 | 620 | ||
373 | 591 | logger.info( 'BackinTime will be able to make new snapshots again!' ) | 621 | logger.info( 'BackinTime will be able to make new snapshots again!' ) |
374 | 592 | self.config.error_handler( _('BackinTime will continue taking snapshots again as scheduled' ) ) | 622 | self.config.error_handler( _('BackinTime will continue taking snapshots again as scheduled' ) ) |
375 | @@ -1276,4 +1306,5 @@ | |||
376 | 1276 | config = config.Config() | 1306 | config = config.Config() |
377 | 1277 | snapshots = Snapshots( config ) | 1307 | snapshots = Snapshots( config ) |
378 | 1278 | snapshots.take_snapshot() | 1308 | snapshots.take_snapshot() |
379 | 1309 | config.unmount_shares() | ||
380 | 1279 | 1310 | ||
381 | 1280 | 1311 | ||
382 | === modified file 'common/tools.py' | |||
383 | --- common/tools.py 2010-02-14 13:47:14 +0000 | |||
384 | +++ common/tools.py 2010-04-16 06:46:25 +0000 | |||
385 | @@ -21,12 +21,10 @@ | |||
386 | 21 | import sys | 21 | import sys |
387 | 22 | import subprocess | 22 | import subprocess |
388 | 23 | 23 | ||
389 | 24 | |||
390 | 25 | ON_AC = 0 | 24 | ON_AC = 0 |
391 | 26 | ON_BATTERY = 1 | 25 | ON_BATTERY = 1 |
392 | 27 | POWER_ERROR = 255 | 26 | POWER_ERROR = 255 |
393 | 28 | 27 | ||
394 | 29 | |||
395 | 30 | def get_backintime_path( path ): | 28 | def get_backintime_path( path ): |
396 | 31 | return os.path.join( os.path.dirname( os.path.abspath( os.path.dirname( __file__ ) ) ), path ) | 29 | return os.path.join( os.path.dirname( os.path.abspath( os.path.dirname( __file__ ) ) ), path ) |
397 | 32 | 30 | ||
398 | @@ -268,7 +266,7 @@ | |||
399 | 268 | return False | 266 | return False |
400 | 269 | 267 | ||
401 | 270 | 268 | ||
403 | 271 | def _execute( cmd, callback = None, user_data = None ): | 269 | def _execute( cmd, callback = None, user_data = None): |
404 | 272 | ret_val = 0 | 270 | ret_val = 0 |
405 | 273 | 271 | ||
406 | 274 | if callback is None: | 272 | if callback is None: |
407 | 275 | 273 | ||
408 | === modified file 'gnome/app.py' | |||
409 | --- gnome/app.py 2010-03-23 09:34:13 +0000 | |||
410 | +++ gnome/app.py 2010-04-16 06:46:25 +0000 | |||
411 | @@ -452,6 +452,7 @@ | |||
412 | 452 | #fill lists | 452 | #fill lists |
413 | 453 | selected_file = None | 453 | selected_file = None |
414 | 454 | show_snapshots = False | 454 | show_snapshots = False |
415 | 455 | self.config.update_shares() | ||
416 | 455 | if init: | 456 | if init: |
417 | 456 | self.folder_path, selected_file, show_snapshots = self.get_startup_folder_and_file() | 457 | self.folder_path, selected_file, show_snapshots = self.get_startup_folder_and_file() |
418 | 457 | self.snapshot_id = '/' | 458 | self.snapshot_id = '/' |
419 | @@ -925,12 +926,17 @@ | |||
420 | 925 | self.on_help() | 926 | self.on_help() |
421 | 926 | 927 | ||
422 | 927 | def on_btn_settings_clicked( self, button ): | 928 | def on_btn_settings_clicked( self, button ): |
424 | 928 | snapshots_path = self.config.get_snapshots_path() | 929 | snapshots_local_path = self.config.get_snapshots_local_path() |
425 | 930 | snapshots_network_path = self.config.get_snapshots_network_path() | ||
426 | 931 | snapshots_access = self.config.get_snapshot_access_mode() | ||
427 | 929 | include_folders = self.config.get_include() | 932 | include_folders = self.config.get_include() |
428 | 930 | 933 | ||
429 | 931 | settingsdialog.SettingsDialog( self.config, self.snapshots, self ).run() | 934 | settingsdialog.SettingsDialog( self.config, self.snapshots, self ).run() |
430 | 932 | 935 | ||
432 | 933 | if snapshots_path != self.config.get_snapshots_path() or include_folders != self.config.get_include(): | 936 | if (snapshots_local_path != self.config.get_snapshots_local_path() or |
433 | 937 | snapshots_network_path != self.config.get_snapshots_network_path() or | ||
434 | 938 | snapshots_access != self.config.get_snapshot_access_mode() or | ||
435 | 939 | include_folders != self.config.get_include()): | ||
436 | 934 | self.update_all( False ) | 940 | self.update_all( False ) |
437 | 935 | self.update_profiles() | 941 | self.update_profiles() |
438 | 936 | 942 | ||
439 | @@ -1173,5 +1179,7 @@ | |||
440 | 1173 | gtk.main() | 1179 | gtk.main() |
441 | 1174 | logger.closelog() | 1180 | logger.closelog() |
442 | 1175 | 1181 | ||
443 | 1182 | cfg.unmount_shares() | ||
444 | 1183 | |||
445 | 1176 | app_instance.exit_application() | 1184 | app_instance.exit_application() |
446 | 1177 | 1185 | ||
447 | 1178 | 1186 | ||
448 | === modified file 'gnome/settingsdialog.glade' | |||
449 | --- gnome/settingsdialog.glade 2010-03-05 20:41:59 +0000 | |||
450 | +++ gnome/settingsdialog.glade 2010-04-16 06:46:25 +0000 | |||
451 | @@ -123,42 +123,167 @@ | |||
452 | 123 | <property name="label_xalign">0</property> | 123 | <property name="label_xalign">0</property> |
453 | 124 | <property name="shadow_type">none</property> | 124 | <property name="shadow_type">none</property> |
454 | 125 | <child> | 125 | <child> |
456 | 126 | <object class="GtkAlignment" id="alignment1"> | 126 | <object class="GtkVBox" id="vbox1"> |
457 | 127 | <property name="visible">True</property> | 127 | <property name="visible">True</property> |
492 | 128 | <property name="left_padding">12</property> | 128 | <property name="orientation">vertical</property> |
493 | 129 | <child> | 129 | <property name="spacing">3</property> |
494 | 130 | <object class="GtkHBox" id="hbox4"> | 130 | <child> |
495 | 131 | <property name="visible">True</property> | 131 | <object class="GtkAlignment" id="alignment3"> |
496 | 132 | <child> | 132 | <property name="visible">True</property> |
497 | 133 | <object class="GtkEntry" id="edit_where"> | 133 | <property name="left_padding">12</property> |
498 | 134 | <property name="visible">True</property> | 134 | <child> |
499 | 135 | <property name="can_focus">True</property> | 135 | <object class="GtkHBox" id="hbox8"> |
500 | 136 | <property name="editable">False</property> | 136 | <property name="visible">True</property> |
501 | 137 | <property name="invisible_char">●</property> | 137 | <property name="homogeneous">True</property> |
502 | 138 | </object> | 138 | <child> |
503 | 139 | <packing> | 139 | <object class="GtkComboBox" id="cb_snapshot_access"> |
504 | 140 | <property name="position">0</property> | 140 | <property name="visible">True</property> |
505 | 141 | </packing> | 141 | <signal name="changed" handler="on_cb_snapshot_access_changed"/> |
506 | 142 | </child> | 142 | </object> |
507 | 143 | <child> | 143 | <packing> |
508 | 144 | <object class="GtkButton" id="btn_where"> | 144 | <property name="position">0</property> |
509 | 145 | <property name="visible">True</property> | 145 | </packing> |
510 | 146 | <property name="can_focus">True</property> | 146 | </child> |
511 | 147 | <property name="receives_default">True</property> | 147 | </object> |
512 | 148 | <signal name="clicked" handler="on_btn_where_clicked"/> | 148 | </child> |
513 | 149 | <child> | 149 | </object> |
514 | 150 | <object class="GtkImage" id="image1"> | 150 | <packing> |
515 | 151 | <property name="visible">True</property> | 151 | <property name="position">0</property> |
516 | 152 | <property name="stock">gtk-directory</property> | 152 | </packing> |
517 | 153 | </object> | 153 | </child> |
518 | 154 | </child> | 154 | <child> |
519 | 155 | </object> | 155 | <object class="GtkAlignment" id="alignment_where"> |
520 | 156 | <packing> | 156 | <property name="visible">True</property> |
521 | 157 | <property name="expand">False</property> | 157 | <property name="left_padding">12</property> |
522 | 158 | <property name="position">1</property> | 158 | <child> |
523 | 159 | </packing> | 159 | <object class="GtkHBox" id="hbox4"> |
524 | 160 | </child> | 160 | <property name="visible">True</property> |
525 | 161 | </object> | 161 | <child> |
526 | 162 | <object class="GtkEntry" id="edit_where"> | ||
527 | 163 | <property name="visible">True</property> | ||
528 | 164 | <property name="can_focus">True</property> | ||
529 | 165 | <property name="editable">False</property> | ||
530 | 166 | <property name="invisible_char">•</property> | ||
531 | 167 | </object> | ||
532 | 168 | <packing> | ||
533 | 169 | <property name="position">0</property> | ||
534 | 170 | </packing> | ||
535 | 171 | </child> | ||
536 | 172 | <child> | ||
537 | 173 | <object class="GtkButton" id="btn_where"> | ||
538 | 174 | <property name="visible">True</property> | ||
539 | 175 | <property name="can_focus">True</property> | ||
540 | 176 | <property name="receives_default">True</property> | ||
541 | 177 | <signal name="clicked" handler="on_btn_where_clicked"/> | ||
542 | 178 | <child> | ||
543 | 179 | <object class="GtkImage" id="image1"> | ||
544 | 180 | <property name="visible">True</property> | ||
545 | 181 | <property name="stock">gtk-directory</property> | ||
546 | 182 | </object> | ||
547 | 183 | </child> | ||
548 | 184 | </object> | ||
549 | 185 | <packing> | ||
550 | 186 | <property name="expand">False</property> | ||
551 | 187 | <property name="position">1</property> | ||
552 | 188 | </packing> | ||
553 | 189 | </child> | ||
554 | 190 | </object> | ||
555 | 191 | </child> | ||
556 | 192 | </object> | ||
557 | 193 | <packing> | ||
558 | 194 | <property name="position">1</property> | ||
559 | 195 | </packing> | ||
560 | 196 | </child> | ||
561 | 197 | <child> | ||
562 | 198 | <object class="GtkAlignment" id="alignment_network"> | ||
563 | 199 | <property name="left_padding">12</property> | ||
564 | 200 | <child> | ||
565 | 201 | <object class="GtkTable" id="table1"> | ||
566 | 202 | <property name="visible">True</property> | ||
567 | 203 | <property name="n_rows">3</property> | ||
568 | 204 | <property name="n_columns">2</property> | ||
569 | 205 | <property name="column_spacing">25</property> | ||
570 | 206 | <child> | ||
571 | 207 | <object class="GtkEntry" id="edit_where_network"> | ||
572 | 208 | <property name="visible">True</property> | ||
573 | 209 | <property name="can_focus">True</property> | ||
574 | 210 | <property name="invisible_char">•</property> | ||
575 | 211 | <property name="caps_lock_warning">False</property> | ||
576 | 212 | </object> | ||
577 | 213 | <packing> | ||
578 | 214 | <property name="left_attach">1</property> | ||
579 | 215 | <property name="right_attach">2</property> | ||
580 | 216 | </packing> | ||
581 | 217 | </child> | ||
582 | 218 | <child> | ||
583 | 219 | <object class="GtkLabel" id="label7"> | ||
584 | 220 | <property name="visible">True</property> | ||
585 | 221 | <property name="xalign">0</property> | ||
586 | 222 | <property name="label" translatable="yes">Network location</property> | ||
587 | 223 | </object> | ||
588 | 224 | <packing> | ||
589 | 225 | <property name="x_options">GTK_FILL</property> | ||
590 | 226 | </packing> | ||
591 | 227 | </child> | ||
592 | 228 | <child> | ||
593 | 229 | <object class="GtkLabel" id="label8"> | ||
594 | 230 | <property name="visible">True</property> | ||
595 | 231 | <property name="xalign">0</property> | ||
596 | 232 | <property name="label" translatable="yes">Username</property> | ||
597 | 233 | </object> | ||
598 | 234 | <packing> | ||
599 | 235 | <property name="top_attach">1</property> | ||
600 | 236 | <property name="bottom_attach">2</property> | ||
601 | 237 | <property name="x_options">GTK_FILL</property> | ||
602 | 238 | </packing> | ||
603 | 239 | </child> | ||
604 | 240 | <child> | ||
605 | 241 | <object class="GtkEntry" id="edit_username"> | ||
606 | 242 | <property name="visible">True</property> | ||
607 | 243 | <property name="can_focus">True</property> | ||
608 | 244 | <property name="invisible_char">•</property> | ||
609 | 245 | <property name="caps_lock_warning">False</property> | ||
610 | 246 | </object> | ||
611 | 247 | <packing> | ||
612 | 248 | <property name="left_attach">1</property> | ||
613 | 249 | <property name="right_attach">2</property> | ||
614 | 250 | <property name="top_attach">1</property> | ||
615 | 251 | <property name="bottom_attach">2</property> | ||
616 | 252 | </packing> | ||
617 | 253 | </child> | ||
618 | 254 | <child> | ||
619 | 255 | <object class="GtkLabel" id="label9"> | ||
620 | 256 | <property name="visible">True</property> | ||
621 | 257 | <property name="xalign">0</property> | ||
622 | 258 | <property name="label" translatable="yes">Password</property> | ||
623 | 259 | </object> | ||
624 | 260 | <packing> | ||
625 | 261 | <property name="top_attach">2</property> | ||
626 | 262 | <property name="bottom_attach">3</property> | ||
627 | 263 | <property name="x_options">GTK_FILL</property> | ||
628 | 264 | <property name="y_options">GTK_FILL</property> | ||
629 | 265 | </packing> | ||
630 | 266 | </child> | ||
631 | 267 | <child> | ||
632 | 268 | <object class="GtkEntry" id="edit_password"> | ||
633 | 269 | <property name="visible">True</property> | ||
634 | 270 | <property name="can_focus">True</property> | ||
635 | 271 | <property name="visibility">False</property> | ||
636 | 272 | <property name="invisible_char">•</property> | ||
637 | 273 | </object> | ||
638 | 274 | <packing> | ||
639 | 275 | <property name="left_attach">1</property> | ||
640 | 276 | <property name="right_attach">2</property> | ||
641 | 277 | <property name="top_attach">2</property> | ||
642 | 278 | <property name="bottom_attach">3</property> | ||
643 | 279 | </packing> | ||
644 | 280 | </child> | ||
645 | 281 | </object> | ||
646 | 282 | </child> | ||
647 | 283 | </object> | ||
648 | 284 | <packing> | ||
649 | 285 | <property name="position">2</property> | ||
650 | 286 | </packing> | ||
651 | 162 | </child> | 287 | </child> |
652 | 163 | </object> | 288 | </object> |
653 | 164 | </child> | 289 | </child> |
654 | 165 | 290 | ||
655 | === modified file 'gnome/settingsdialog.py' | |||
656 | --- gnome/settingsdialog.py 2010-03-05 20:41:59 +0000 | |||
657 | +++ gnome/settingsdialog.py 2010-04-16 06:46:25 +0000 | |||
658 | @@ -30,6 +30,7 @@ | |||
659 | 30 | import config | 30 | import config |
660 | 31 | import messagebox | 31 | import messagebox |
661 | 32 | import tools | 32 | import tools |
662 | 33 | import network | ||
663 | 33 | 34 | ||
664 | 34 | 35 | ||
665 | 35 | _=gettext.gettext | 36 | _=gettext.gettext |
666 | @@ -74,6 +75,7 @@ | |||
667 | 74 | 'on_combo_profiles_changed': self.on_combo_profiles_changed, | 75 | 'on_combo_profiles_changed': self.on_combo_profiles_changed, |
668 | 75 | 'on_btn_where_clicked': self.on_btn_where_clicked, | 76 | 'on_btn_where_clicked': self.on_btn_where_clicked, |
669 | 76 | 'on_cb_backup_mode_changed': self.on_cb_backup_mode_changed, | 77 | 'on_cb_backup_mode_changed': self.on_cb_backup_mode_changed, |
670 | 78 | 'on_cb_snapshot_access_changed': self.on_cb_snapshot_access_changed, | ||
671 | 77 | } | 79 | } |
672 | 78 | 80 | ||
673 | 79 | builder.connect_signals(signals) | 81 | builder.connect_signals(signals) |
674 | @@ -102,6 +104,19 @@ | |||
675 | 102 | #self.fcb_where = get( 'fcb_where' ) | 104 | #self.fcb_where = get( 'fcb_where' ) |
676 | 103 | #self.fcb_where.set_show_hidden( self.parent.show_hidden_files ) | 105 | #self.fcb_where.set_show_hidden( self.parent.show_hidden_files ) |
677 | 104 | self.edit_where = get( 'edit_where' ) | 106 | self.edit_where = get( 'edit_where' ) |
678 | 107 | |||
679 | 108 | #snapshot location access | ||
680 | 109 | self.store_snapshot_access_mode = gtk.ListStore( str, int ) | ||
681 | 110 | map = network.SNAPSHOT_ACCESS | ||
682 | 111 | self.rev_snapshot_access_modes = {} | ||
683 | 112 | keys = map.keys() | ||
684 | 113 | keys.sort() | ||
685 | 114 | for key in keys: | ||
686 | 115 | self.rev_snapshot_access_modes[ map[key] ] = key | ||
687 | 116 | self.store_snapshot_access_mode.append( [ map[key], key ] ) | ||
688 | 117 | self.edit_where_network = get( 'edit_where_network' ) | ||
689 | 118 | self.edit_username = get( 'edit_username' ) | ||
690 | 119 | self.edit_password = get( 'edit_password' ) | ||
691 | 105 | 120 | ||
692 | 106 | #automatic backup mode store | 121 | #automatic backup mode store |
693 | 107 | self.store_backup_mode = gtk.ListStore( str, int ) | 122 | self.store_backup_mode = gtk.ListStore( str, int ) |
694 | @@ -165,6 +180,18 @@ | |||
695 | 165 | 180 | ||
696 | 166 | self.store_exclude = gtk.ListStore( str, str ) | 181 | self.store_exclude = gtk.ListStore( str, str ) |
697 | 167 | self.list_exclude.set_model( self.store_exclude ) | 182 | self.list_exclude.set_model( self.store_exclude ) |
698 | 183 | |||
699 | 184 | #setup snapshot access mode | ||
700 | 185 | self.cb_snapshot_access = get( 'cb_snapshot_access' ) | ||
701 | 186 | self.cb_snapshot_access.set_model( self.store_snapshot_access_mode) | ||
702 | 187 | |||
703 | 188 | self.cb_snapshot_access.clear() | ||
704 | 189 | renderer = gtk.CellRendererText() | ||
705 | 190 | self.cb_snapshot_access.pack_start( renderer, True ) | ||
706 | 191 | self.cb_snapshot_access.add_attribute( renderer, 'text', 0 ) | ||
707 | 192 | |||
708 | 193 | self.alignment_where = get( 'alignment_where' ) | ||
709 | 194 | self.alignment_network = get( 'alignment_network' ) | ||
710 | 168 | 195 | ||
711 | 169 | #setup automatic backup mode | 196 | #setup automatic backup mode |
712 | 170 | self.cb_backup_mode = get( 'cb_backup_mode' ) | 197 | self.cb_backup_mode = get( 'cb_backup_mode' ) |
713 | @@ -306,6 +333,17 @@ | |||
714 | 306 | self.profile_id = profile_id | 333 | self.profile_id = profile_id |
715 | 307 | 334 | ||
716 | 308 | self.update_profile() | 335 | self.update_profile() |
717 | 336 | |||
718 | 337 | def on_cb_snapshot_access_changed( self, *params ): | ||
719 | 338 | iter = self.cb_snapshot_access.get_active_iter() | ||
720 | 339 | access = self.store_snapshot_access_mode.get_value( iter, 1 ) | ||
721 | 340 | |||
722 | 341 | if access in network.NETWORK_ACCESS_MODES: | ||
723 | 342 | self.alignment_where.hide() | ||
724 | 343 | self.alignment_network.show() | ||
725 | 344 | else: | ||
726 | 345 | self.alignment_where.show() | ||
727 | 346 | self.alignment_network.hide() | ||
728 | 309 | 347 | ||
729 | 310 | def update_profiles( self ): | 348 | def update_profiles( self ): |
730 | 311 | self.disable_combo_changed = True | 349 | self.disable_combo_changed = True |
731 | @@ -335,7 +373,12 @@ | |||
732 | 335 | 373 | ||
733 | 336 | #set current folder | 374 | #set current folder |
734 | 337 | #self.fcb_where.set_filename( self.config.get_snapshots_path() ) | 375 | #self.fcb_where.set_filename( self.config.get_snapshots_path() ) |
736 | 338 | self.edit_where.set_text( self.config.get_snapshots_path( self.profile_id ) ) | 376 | self.edit_where.set_text( self.config.get_snapshots_local_path( self.profile_id ) ) |
737 | 377 | |||
738 | 378 | #setup network paths | ||
739 | 379 | self.edit_where_network.set_text( self.config.get_snapshots_network_path( self.profile_id ) ) | ||
740 | 380 | self.edit_username.set_text( self.config.get_snapshots_username( self.profile_id ) ) | ||
741 | 381 | self.edit_password.set_text( self.config.get_snapshots_password( self.profile_id ) ) | ||
742 | 339 | 382 | ||
743 | 340 | #per directory schedule | 383 | #per directory schedule |
744 | 341 | #self.cb_per_directory_schedule.set_active( self.config.get_per_directory_schedule() ) | 384 | #self.cb_per_directory_schedule.set_active( self.config.get_per_directory_schedule() ) |
745 | @@ -358,6 +401,17 @@ | |||
746 | 358 | if len( exclude_patterns ) > 0: | 401 | if len( exclude_patterns ) > 0: |
747 | 359 | for exclude_pattern in exclude_patterns: | 402 | for exclude_pattern in exclude_patterns: |
748 | 360 | self.store_exclude.append( [exclude_pattern, gtk.STOCK_DELETE] ) | 403 | self.store_exclude.append( [exclude_pattern, gtk.STOCK_DELETE] ) |
749 | 404 | |||
750 | 405 | #setup snapshot access mode | ||
751 | 406 | i = 0 | ||
752 | 407 | iter = self.store_snapshot_access_mode.get_iter_first() | ||
753 | 408 | default_mode = self.config.get_snapshot_access_mode( self.profile_id ) | ||
754 | 409 | while not iter is None: | ||
755 | 410 | if self.store_snapshot_access_mode.get_value( iter, 1 ) == default_mode: | ||
756 | 411 | self.cb_snapshot_access.set_active( i ) | ||
757 | 412 | break | ||
758 | 413 | iter = self.store_snapshot_access_mode.iter_next( iter ) | ||
759 | 414 | i = i + 1 | ||
760 | 361 | 415 | ||
761 | 362 | #setup automatic backup mode | 416 | #setup automatic backup mode |
762 | 363 | i = 0 | 417 | i = 0 |
763 | @@ -443,13 +497,26 @@ | |||
764 | 443 | 497 | ||
765 | 444 | def save_profile( self ): | 498 | def save_profile( self ): |
766 | 445 | #profile_id = self.config.get_current_profile() | 499 | #profile_id = self.config.get_current_profile() |
774 | 446 | #snapshots path | 500 | |
775 | 447 | snapshots_path = self.edit_where.get_text() | 501 | iter = self.cb_snapshot_access.get_active_iter() |
776 | 448 | 502 | access = self.store_snapshot_access_mode.get_value( iter, 1 ) | |
777 | 449 | #hack | 503 | if access in network.NETWORK_ACCESS_MODES: |
778 | 450 | if snapshots_path.startswith( '//' ): | 504 | network_path = self.edit_where_network.get_text() |
779 | 451 | snapshots_path = snapshots_path[ 1 : ] | 505 | username = self.edit_username.get_text() |
780 | 452 | 506 | password = self.edit_password.get_text() | |
781 | 507 | if not self.config.set_snapshots_network_details(network_path,access,username,password): | ||
782 | 508 | return False | ||
783 | 509 | self.config.update_shares() | ||
784 | 510 | else: | ||
785 | 511 | #snapshots path | ||
786 | 512 | snapshots_path = self.edit_where.get_text() | ||
787 | 513 | #hack | ||
788 | 514 | if snapshots_path.startswith( '//' ): | ||
789 | 515 | snapshots_path = snapshots_path[ 1 : ] | ||
790 | 516 | #ok let's save to config | ||
791 | 517 | if not self.config.set_snapshots_path( snapshots_path, self.profile_id ): | ||
792 | 518 | return False | ||
793 | 519 | |||
794 | 453 | #include list | 520 | #include list |
795 | 454 | include_list = [] | 521 | include_list = [] |
796 | 455 | iter = self.store_include.get_iter_first() | 522 | iter = self.store_include.get_iter_first() |
797 | @@ -471,12 +538,6 @@ | |||
798 | 471 | #if len( self.config.get_snapshots_path() ) > 0 and self.config.get_snapshots_path() != snapshots_path: | 538 | #if len( self.config.get_snapshots_path() ) > 0 and self.config.get_snapshots_path() != snapshots_path: |
799 | 472 | # if gtk.RESPONSE_YES != messagebox.show_question( self.dialog, self.config, _('Are you sure you want to change snapshots folder ?') ): | 539 | # if gtk.RESPONSE_YES != messagebox.show_question( self.dialog, self.config, _('Are you sure you want to change snapshots folder ?') ): |
800 | 473 | # return False | 540 | # return False |
801 | 474 | |||
802 | 475 | #ok let's save to config | ||
803 | 476 | self.config.set_snapshots_path( snapshots_path, self.profile_id ) | ||
804 | 477 | #if not msg is None: | ||
805 | 478 | # messagebox.show_error( self.dialog, self.config, msg ) | ||
806 | 479 | # return False | ||
807 | 480 | 541 | ||
808 | 481 | self.config.set_include( include_list, self.profile_id ) | 542 | self.config.set_include( include_list, self.profile_id ) |
809 | 482 | self.config.set_exclude( exclude_list, self.profile_id ) | 543 | self.config.set_exclude( exclude_list, self.profile_id ) |
810 | @@ -509,6 +570,8 @@ | |||
811 | 509 | self.config.set_run_ionice_from_cron_enabled( self.cb_run_ionice_from_cron.get_active(), self.profile_id ) | 570 | self.config.set_run_ionice_from_cron_enabled( self.cb_run_ionice_from_cron.get_active(), self.profile_id ) |
812 | 510 | self.config.set_run_ionice_from_user_enabled( self.cb_run_ionice_from_user.get_active(), self.profile_id ) | 571 | self.config.set_run_ionice_from_user_enabled( self.cb_run_ionice_from_user.get_active(), self.profile_id ) |
813 | 511 | self.config.set_no_on_battery_enabled( self.cb_no_on_battery.get_active(), self.profile_id ) | 572 | self.config.set_no_on_battery_enabled( self.cb_no_on_battery.get_active(), self.profile_id ) |
814 | 573 | |||
815 | 574 | return True | ||
816 | 512 | 575 | ||
817 | 513 | def update_remove_old_backups( self, button ): | 576 | def update_remove_old_backups( self, button ): |
818 | 514 | enabled = self.cb_remove_old_backup.get_active() | 577 | enabled = self.cb_remove_old_backup.get_active() |
819 | @@ -687,7 +750,8 @@ | |||
820 | 687 | self.dialog.destroy() | 750 | self.dialog.destroy() |
821 | 688 | 751 | ||
822 | 689 | def validate( self ): | 752 | def validate( self ): |
824 | 690 | self.save_profile() | 753 | if not self.save_profile(): |
825 | 754 | return False | ||
826 | 691 | 755 | ||
827 | 692 | if not self.config.check_config(): | 756 | if not self.config.check_config(): |
828 | 693 | return False | 757 | return False |
829 | 694 | 758 | ||
830 | === modified file 'kde4/app.py' | |||
831 | --- kde4/app.py 2010-04-01 17:57:51 +0000 | |||
832 | +++ kde4/app.py 2010-04-16 06:46:25 +0000 | |||
833 | @@ -389,6 +389,8 @@ | |||
834 | 389 | 389 | ||
835 | 390 | self.disable_profile_changed = False | 390 | self.disable_profile_changed = False |
836 | 391 | 391 | ||
837 | 392 | self.config.update_shares() | ||
838 | 393 | |||
839 | 392 | def update_profile( self ): | 394 | def update_profile( self ): |
840 | 393 | self.update_time_line() | 395 | self.update_time_line() |
841 | 394 | self.update_places() | 396 | self.update_places() |
842 | @@ -1098,5 +1100,7 @@ | |||
843 | 1098 | 1100 | ||
844 | 1099 | logger.closelog() | 1101 | logger.closelog() |
845 | 1100 | 1102 | ||
846 | 1103 | cfg.unmount_shares() | ||
847 | 1104 | |||
848 | 1101 | app_instance.exit_application() | 1105 | app_instance.exit_application() |
849 | 1102 | 1106 | ||
850 | 1103 | 1107 | ||
851 | === modified file 'kde4/settingsdialog.py' | |||
852 | --- kde4/settingsdialog.py 2010-03-05 20:41:59 +0000 | |||
853 | +++ kde4/settingsdialog.py 2010-04-16 06:46:25 +0000 | |||
854 | @@ -32,6 +32,7 @@ | |||
855 | 32 | import config | 32 | import config |
856 | 33 | import tools | 33 | import tools |
857 | 34 | import kde4tools | 34 | import kde4tools |
858 | 35 | import network | ||
859 | 35 | 36 | ||
860 | 36 | 37 | ||
861 | 37 | _=gettext.gettext | 38 | _=gettext.gettext |
862 | @@ -108,8 +109,15 @@ | |||
863 | 108 | group_box.setTitle( QString.fromUtf8( _( 'Where to save snapshots' ) ) ) | 109 | group_box.setTitle( QString.fromUtf8( _( 'Where to save snapshots' ) ) ) |
864 | 109 | layout.addWidget( group_box ) | 110 | layout.addWidget( group_box ) |
865 | 110 | 111 | ||
868 | 111 | hlayout = QHBoxLayout( group_box ) | 112 | vlayout = QVBoxLayout( group_box ) |
869 | 112 | 113 | ||
870 | 114 | self.combo_snapshot_access = KComboBox( self ) | ||
871 | 115 | vlayout.addWidget(self.combo_snapshot_access) | ||
872 | 116 | self.fill_combo( self.combo_snapshot_access, network.SNAPSHOT_ACCESS ) | ||
873 | 117 | QObject.connect( self.combo_snapshot_access, SIGNAL('currentIndexChanged(int)'), self.current_snapshot_access_changed ) | ||
874 | 118 | |||
875 | 119 | # - In a local folder | ||
876 | 120 | hlayout = QHBoxLayout() | ||
877 | 113 | self.edit_snapshots_path = KLineEdit( self ) | 121 | self.edit_snapshots_path = KLineEdit( self ) |
878 | 114 | self.edit_snapshots_path.setReadOnly( True ) | 122 | self.edit_snapshots_path.setReadOnly( True ) |
879 | 115 | hlayout.addWidget( self.edit_snapshots_path ) | 123 | hlayout.addWidget( self.edit_snapshots_path ) |
880 | @@ -118,6 +126,38 @@ | |||
881 | 118 | hlayout.addWidget( self.btn_snapshots_path ) | 126 | hlayout.addWidget( self.btn_snapshots_path ) |
882 | 119 | QObject.connect( self.btn_snapshots_path, SIGNAL('clicked()'), self.on_btn_snapshots_path_clicked ) | 127 | QObject.connect( self.btn_snapshots_path, SIGNAL('clicked()'), self.on_btn_snapshots_path_clicked ) |
883 | 120 | 128 | ||
884 | 129 | self.local_path_widgets = [self.edit_snapshots_path, self.btn_snapshots_path] | ||
885 | 130 | |||
886 | 131 | vlayout.addLayout(hlayout) | ||
887 | 132 | |||
888 | 133 | # - Over the network | ||
889 | 134 | glayout = QGridLayout() | ||
890 | 135 | self.edit_snapshots_network_path = KLineEdit( self ) | ||
891 | 136 | self.label_snapshots_network_path = QLabel(QString.fromUtf8( _( 'Network location')), self ) | ||
892 | 137 | self.label_snapshots_network_path.setBuddy(self.edit_snapshots_network_path) | ||
893 | 138 | glayout.addWidget(self.label_snapshots_network_path,0,0) | ||
894 | 139 | glayout.addWidget(self.edit_snapshots_network_path,0,1) | ||
895 | 140 | |||
896 | 141 | self.edit_snapshots_username = KLineEdit( self ) | ||
897 | 142 | self.label_snapshots_username = QLabel(QString.fromUtf8( _( 'Username')), self ) | ||
898 | 143 | self.label_snapshots_username.setBuddy(self.edit_snapshots_username) | ||
899 | 144 | glayout.addWidget(self.label_snapshots_username,1,0) | ||
900 | 145 | glayout.addWidget(self.edit_snapshots_username,1,1) | ||
901 | 146 | |||
902 | 147 | self.edit_snapshots_password = KLineEdit( self ) | ||
903 | 148 | self.edit_snapshots_password.setEchoMode(KLineEdit.EchoMode(KLineEdit.Password)) | ||
904 | 149 | self.label_snapshots_password = QLabel(QString.fromUtf8( _( 'Password')), self ) | ||
905 | 150 | self.label_snapshots_password.setBuddy(self.edit_snapshots_password) | ||
906 | 151 | glayout.addWidget(self.label_snapshots_password,2,0) | ||
907 | 152 | glayout.addWidget(self.edit_snapshots_password,2,1) | ||
908 | 153 | |||
909 | 154 | self.network_widgets = [self.edit_snapshots_network_path, self.label_snapshots_network_path, | ||
910 | 155 | self.edit_snapshots_username, self.label_snapshots_username, | ||
911 | 156 | self.edit_snapshots_password, self.label_snapshots_password] | ||
912 | 157 | |||
913 | 158 | glayout.setHorizontalSpacing(35) | ||
914 | 159 | vlayout.addLayout(glayout) | ||
915 | 160 | |||
916 | 121 | #Schedule | 161 | #Schedule |
917 | 122 | group_box = QGroupBox( self ) | 162 | group_box = QGroupBox( self ) |
918 | 123 | self.global_schedule_group_box = group_box | 163 | self.global_schedule_group_box = group_box |
919 | @@ -130,7 +170,7 @@ | |||
920 | 130 | hlayout.addWidget( self.combo_automatic_snapshots, 2 ) | 170 | hlayout.addWidget( self.combo_automatic_snapshots, 2 ) |
921 | 131 | self.fill_combo( self.combo_automatic_snapshots, self.config.AUTOMATIC_BACKUP_MODES ) | 171 | self.fill_combo( self.combo_automatic_snapshots, self.config.AUTOMATIC_BACKUP_MODES ) |
922 | 132 | 172 | ||
924 | 133 | hlayout_time = QHBoxLayout( group_box ) | 173 | hlayout_time = QHBoxLayout() |
925 | 134 | hlayout.addLayout( hlayout_time ) | 174 | hlayout.addLayout( hlayout_time ) |
926 | 135 | 175 | ||
927 | 136 | self.lbl_automatic_snapshots_time = QLabel( QString.fromUtf8( _( 'Hour:' ) ), self ) | 176 | self.lbl_automatic_snapshots_time = QLabel( QString.fromUtf8( _( 'Hour:' ) ), self ) |
928 | @@ -356,6 +396,17 @@ | |||
929 | 356 | def current_automatic_snapshot_changed( self, index ): | 396 | def current_automatic_snapshot_changed( self, index ): |
930 | 357 | backup_mode = self.combo_automatic_snapshots.itemData( index ).toInt()[0] | 397 | backup_mode = self.combo_automatic_snapshots.itemData( index ).toInt()[0] |
931 | 358 | self.update_automatic_snapshot_time( backup_mode ) | 398 | self.update_automatic_snapshot_time( backup_mode ) |
932 | 399 | |||
933 | 400 | def update_snapshot_access_mode( self, access_mode ): | ||
934 | 401 | network_access = (access_mode in network.NETWORK_ACCESS_MODES) | ||
935 | 402 | for widget in self.local_path_widgets: | ||
936 | 403 | widget.setVisible(not network_access) | ||
937 | 404 | for widget in self.network_widgets: | ||
938 | 405 | widget.setVisible(network_access) | ||
939 | 406 | |||
940 | 407 | def current_snapshot_access_changed( self, index ): | ||
941 | 408 | access = self.combo_snapshot_access.itemData( index ).toInt()[0] | ||
942 | 409 | self.update_snapshot_access_mode( access ) | ||
943 | 359 | 410 | ||
944 | 360 | def current_profile_changed( self, index ): | 411 | def current_profile_changed( self, index ): |
945 | 361 | if self.disable_profile_changed: | 412 | if self.disable_profile_changed: |
946 | @@ -395,7 +446,15 @@ | |||
947 | 395 | self.btn_remove_profile.setEnabled( True ) | 446 | self.btn_remove_profile.setEnabled( True ) |
948 | 396 | 447 | ||
949 | 397 | #TAB: General | 448 | #TAB: General |
951 | 398 | self.edit_snapshots_path.setText( QString.fromUtf8( self.config.get_snapshots_path() ) ) | 449 | self.set_combo_value( self.combo_snapshot_access, self.config.get_snapshot_access_mode() ) |
952 | 450 | self.update_snapshot_access_mode( self.config.get_snapshot_access_mode() ) | ||
953 | 451 | |||
954 | 452 | self.edit_snapshots_path.setText( QString.fromUtf8( self.config.get_snapshots_local_path() ) ) | ||
955 | 453 | |||
956 | 454 | self.edit_snapshots_network_path.setText( QString.fromUtf8( self.config.get_snapshots_network_path() )) | ||
957 | 455 | self.edit_snapshots_username.setText( QString.fromUtf8( self.config.get_snapshots_username() )) | ||
958 | 456 | self.edit_snapshots_password.setText( QString.fromUtf8( self.config.get_snapshots_password() )) | ||
959 | 457 | |||
960 | 399 | self.set_combo_value( self.combo_automatic_snapshots, self.config.get_automatic_backup_mode() ) | 458 | self.set_combo_value( self.combo_automatic_snapshots, self.config.get_automatic_backup_mode() ) |
961 | 400 | self.set_combo_value( self.combo_automatic_snapshots_time, self.config.get_automatic_backup_time() ) | 459 | self.set_combo_value( self.combo_automatic_snapshots_time, self.config.get_automatic_backup_time() ) |
962 | 401 | self.update_automatic_snapshot_time( self.config.get_automatic_backup_mode() ) | 460 | self.update_automatic_snapshot_time( self.config.get_automatic_backup_mode() ) |
963 | @@ -450,7 +509,17 @@ | |||
964 | 450 | 509 | ||
965 | 451 | def save_profile( self ): | 510 | def save_profile( self ): |
966 | 452 | #snapshots path | 511 | #snapshots path |
968 | 453 | self.config.set_snapshots_path( str( self.edit_snapshots_path.text().toUtf8() ) ) | 512 | access = self.combo_snapshot_access.itemData( self.combo_snapshot_access.currentIndex() ).toInt()[0] |
969 | 513 | if access in network.NETWORK_ACCESS_MODES: | ||
970 | 514 | network_path = str( self.edit_snapshots_network_path.text().toUtf8() ) | ||
971 | 515 | username = str( self.edit_snapshots_username.text().toUtf8() ) | ||
972 | 516 | password = str( self.edit_snapshots_password.text().toUtf8() ) | ||
973 | 517 | if not self.config.set_snapshots_network_details(network_path,access,username,password): | ||
974 | 518 | return False | ||
975 | 519 | self.config.update_shares() | ||
976 | 520 | else: | ||
977 | 521 | if not self.config.set_snapshots_path( str( self.edit_snapshots_path.text().toUtf8() ) ): | ||
978 | 522 | return False | ||
979 | 454 | 523 | ||
980 | 455 | #include list | 524 | #include list |
981 | 456 | include_list = [] | 525 | include_list = [] |
982 | @@ -495,6 +564,8 @@ | |||
983 | 495 | self.config.set_run_ionice_from_user_enabled( self.cb_run_ionice_from_user.isChecked() ) | 564 | self.config.set_run_ionice_from_user_enabled( self.cb_run_ionice_from_user.isChecked() ) |
984 | 496 | self.config.set_no_on_battery_enabled( self.cb_no_on_battery.isChecked() ) | 565 | self.config.set_no_on_battery_enabled( self.cb_no_on_battery.isChecked() ) |
985 | 497 | 566 | ||
986 | 567 | return True | ||
987 | 568 | |||
988 | 498 | def error_handler( self, message ): | 569 | def error_handler( self, message ): |
989 | 499 | KMessageBox.error( self, QString.fromUtf8( message ) ) | 570 | KMessageBox.error( self, QString.fromUtf8( message ) ) |
990 | 500 | 571 | ||
991 | @@ -594,7 +665,8 @@ | |||
992 | 594 | break | 665 | break |
993 | 595 | 666 | ||
994 | 596 | def validate( self ): | 667 | def validate( self ): |
996 | 597 | self.save_profile() | 668 | if not self.save_profile(): |
997 | 669 | return False | ||
998 | 598 | 670 | ||
999 | 599 | if not self.config.check_config(): | 671 | if not self.config.check_config(): |
1000 | 600 | return False | 672 | return False |