1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import gobject
20 import exceptions, sys, os.path, ConfigParser, re, cPickle
21 import tempfile, types
22 import traceback
23 import errno
24 import time
25 import getpass
26 import subprocess
27
28 try:
29 import util
30 import config
31 import userprofile
32 import dirmonitor
33 import mozilla_bookmarks
34 import debuglog
35 except:
36 from sabayon import util
37 from sabayon import config
38 from sabayon import userprofile
39 from sabayon import dirmonitor
40 from sabayon import mozilla_bookmarks
41 from sabayon import debuglog
42
44 (UNKNOWN,
45 VALID,
46 NOT_FOUND,
47 SYS_ERROR,
48 PARSE_ERROR
49 ) = range(5)
50
51
52 firefox_rel_path = ".mozilla/firefox"
53
54 profiles_ini_rel_path = os.path.join(firefox_rel_path, "profiles.ini")
55
56 sabayon_pref_rel_path = os.path.join(firefox_rel_path, "sabayon-prefs.js")
57 sabayon_mandatory_pref_rel_path = os.path.join(firefox_rel_path, "sabayon-mandatory-prefs.js")
58
59 sabayon_bookmark_rel_path = os.path.join(firefox_rel_path, "sabayon-bookmarks.html")
60 sabayon_mandatory_bookmark_rel_path = os.path.join(firefox_rel_path, "sabayon-mandatory-bookmarks.html")
61
62
63 LOG_OPERATION = 0x00001
64 LOG_CHANGE = 0x00002
65 LOG_IGNORED_CHANGE = 0x00004
66 LOG_APPLY = 0x00008
67 LOG_SYNC = 0x00010
68 LOG_PARSE = 0x00020
69 LOG_PREF = 0x00040
70 LOG_FILE_CONTENTS = 0x00080
71 LOG_DATA = 0x00100
72 LOG_VERBOSE = 0x10000
73
79
80 bookmark_exclude_attrs = [re.compile("^id$"),
81 re.compile("^last_"),
82 re.compile("^add_"),
83
84 ]
85
87 if not exclude:
88 return False
89
90 for regexp in exclude:
91 if regexp.search(attr):
92 return True
93 return False
94
96 (
97 CREATED,
98 DELETED,
99 CHANGED
100 ) = range(3)
101
102 - def __init__ (self, source, delegate, type, key, value, event):
103 userprofile.ProfileChange.__init__ (self, source, delegate)
104
105 assert event == self.CREATED or \
106 event == self.DELETED or \
107 event == self.CHANGED
108
109 self.type = type
110 self.key = key
111 self.value = value
112 self.event = event
113 self.attrs = {}
114
116 self.attrs[attr] = value
117
119 return self.attrs[attr]
120
122 return self.type
123
125 return self.key
126
128 return self.value
129
131 return self.key
132
134 if self.event == self.CREATED:
135 return _("Mozilla key '%s' set to '%s'") % (self.key, self.value)
136 elif self.event == self.DELETED:
137 return _("Mozilla key '%s' unset") % self.key
138 elif self.event == self.CHANGED:
139 return _("Mozilla key '%s' changed to '%s'") % (self.key, self.value)
140 else:
141 raise ValueError
142
143 gobject.type_register(MozillaChange)
144
158
160 return os.path.join(self.home_dir, path)
161
164
166 type = get_type_from_path(path)
167
168 if type == FirefoxProfileFile.TYPE_PREFS:
169 return _("Web browser preferences")
170 elif type == FirefoxProfileFile.TYPE_BOOKMARK:
171 return _("Web browser bookmarks")
172 elif type == FirefoxProfileFile.TYPE_PROFILE_INI:
173 return _("Web browser profile list")
174 else:
175
176 basename = os.path.basename(path)
177
178 if basename.endswith("prefs.js"):
179 return _("Web browser preferences")
180 elif basename.endswith("bookmarks.html"):
181 return _("Web browser bookmarks")
182 else:
183 return path
184
189
193
199
201 if self.ini_file and self.ini_file.is_valid():
202 rel_dir = os.path.dirname(rel_path)
203 for profile in self.ini_file.get_profiles():
204 profile_rel_dir = profile.get_rel_dir()
205 if rel_dir.startswith(profile_rel_dir):
206 return profile
207 return None
208 else:
209 return None
210
212 rel_path = change.get_id()
213 dprint (LOG_CHANGE, "handle_change: rel_path='%s'", rel_path)
214
215
216
217 if self.is_ini_file(rel_path):
218 dprint(LOG_CHANGE, "%s ini file: %s", dirmonitor.event_to_string(change.event), rel_path)
219 self.load_profiles_ini()
220
221
222
223
224 profile = self.is_profile_file(rel_path)
225 if profile:
226 dprint(LOG_CHANGE, "%s profile file: %s", dirmonitor.event_to_string(change.event), rel_path)
227
228 profile_file = profile.add_file(rel_path)
229 profile_file_type = profile_file.get_type()
230
231 if profile_file_type == FirefoxProfileFile.TYPE_PREFS:
232 assert isinstance(profile_file, JavascriptPrefsFile)
233 if change.event == dirmonitor.CREATED or \
234 change.event == dirmonitor.CHANGED:
235 cat_file(profile_file.get_full_path())
236 profile_file.read()
237 profile_file.emit_changes(self.source, self.delegate)
238 return True
239 elif change.event == dirmonitor.DELETED:
240
241 pass
242 else:
243 raise ValueError
244 elif profile_file_type == FirefoxProfileFile.TYPE_BOOKMARK:
245 assert isinstance(profile_file, BookmarksFile)
246 if change.event == dirmonitor.CREATED or \
247 change.event == dirmonitor.CHANGED:
248 profile_file.read()
249 profile_file.emit_changes(self.source, self.delegate)
250 return True
251 elif change.event == dirmonitor.DELETED:
252
253 pass
254 else:
255 raise ValueError
256 elif profile_file_type != FirefoxProfileFile.TYPE_UNKNOWN:
257 if change.event == dirmonitor.CREATED or \
258 change.event == dirmonitor.CHANGED:
259 profile.add_file(rel_path)
260 elif change.event == dirmonitor.DELETED:
261 profile.del_file(rel_path)
262 else:
263 raise ValueError
264 else:
265 return True
266
267
268
269
270 dprint(LOG_IGNORED_CHANGE, "IGNORED: %s", rel_path)
271 return True
272
274 if isinstance(change, MozillaChange):
275 dprint(LOG_CHANGE, "Commiting preference (mandatory = %s) key = %s value = %s event = %s",
276 mandatory, change.key, change.value, change.event)
277
278 if mandatory:
279 self.committed_mandatory_prefs[change.get_key()] = \
280 JavascriptPreference(change.get_type(), change.get_key(), change.get_value())
281 else:
282 self.committed_prefs[change.get_key()] = \
283 JavascriptPreference(change.get_type(), change.get_key(), change.get_value())
284 elif isinstance(change, BookmarkChange):
285 bookmark_path = change.get_bookmark_path()
286 entry = change.get_entry()
287
288 dprint(LOG_CHANGE, "Commiting bookmark (mandatory = %s) path = %s url = %s event = %s",
289 mandatory, entry.path_as_string(), entry.get_url(), change.event)
290
291 if mandatory:
292 self.committed_mandatory_bookmarks.add_path_entry(entry.path(), entry)
293 else:
294 self.committed_bookmarks.add_path_entry(entry.path(), entry)
295
296
305
307 """Stop monitoring for configuration changes."""
308 dprint(LOG_OPERATION, "stop_monitoring:")
309
311 """Ensure that all committed changes are saved to disk."""
312
313 dprint(LOG_SYNC, "sync_changes: home_dir = %s", self.home_dir)
314 ini = self.ini_file
315 if ini.is_valid():
316 default_profile = ini.get_default_profile()
317
318 self.source.storage.add(ini.get_rel_path(), self.home_dir, self.name,
319 {"file_type" : FirefoxProfileFile.TYPE_PROFILE_INI})
320
321 if len(self.committed_prefs) > 0:
322 pref_rel_path = sabayon_pref_rel_path
323 dprint(LOG_SYNC, "sync_changes: storing committed_prefs to %s", pref_rel_path)
324 pref_file = JavascriptPrefsFile(self.home_dir, pref_rel_path)
325 pref_file.set_prefs(self.committed_prefs)
326 pref_file.write()
327 self.source.storage.add(pref_rel_path, self.home_dir, self.name,
328 {"file_type" : FirefoxProfileFile.TYPE_PREFS,
329 "mandatory" : False})
330
331 if len(self.committed_mandatory_prefs) > 0:
332 pref_rel_path = sabayon_mandatory_pref_rel_path
333 dprint(LOG_SYNC, "sync_changes: storing mandatory committed_prefs to %s", pref_rel_path)
334 pref_file = JavascriptPrefsFile(self.home_dir, pref_rel_path)
335 pref_file.set_prefs(self.committed_mandatory_prefs)
336 pref_file.write()
337 self.source.storage.add(pref_rel_path, self.home_dir, self.name,
338 {"file_type" : FirefoxProfileFile.TYPE_PREFS,
339 "mandatory" : True})
340
341 if len(self.committed_bookmarks.entries) > 0:
342 bookmark_rel_path = sabayon_bookmark_rel_path
343 dprint(LOG_SYNC, "sync_changes: storing committed_bookmarks to %s", bookmark_rel_path)
344 bookmark_file = BookmarksFile(self.home_dir, bookmark_rel_path)
345 bookmark_file.set_root(self.committed_bookmarks)
346 bookmark_file.write(exclude_attrs=bookmark_exclude_attrs)
347 self.source.storage.add(bookmark_rel_path, self.home_dir, self.name,
348 {"file_type" : FirefoxProfileFile.TYPE_BOOKMARK,
349 "mandatory" : False})
350
351 if len(self.committed_mandatory_bookmarks.entries) > 0:
352 bookmark_rel_path = sabayon_mandatory_bookmark_rel_path
353 dprint(LOG_SYNC, "sync_changes: storing mandatory committed_bookmarks to %s", bookmark_rel_path)
354 bookmark_file = BookmarksFile(self.home_dir, bookmark_rel_path)
355 bookmark_file.set_root(self.committed_mandatory_bookmarks)
356 bookmark_file.write(exclude_attrs=bookmark_exclude_attrs)
357 self.source.storage.add(bookmark_rel_path, self.home_dir, self.name,
358 {"file_type" : FirefoxProfileFile.TYPE_BOOKMARK,
359 "mandatory" : True})
360
362
363 pass
364
365 - def apply(self, is_sabayon_session):
366 ini_files = []
367 pref_files = []
368 bookmark_files = []
369 other_files = []
370
371 dprint(LOG_APPLY, "apply: home_dir = %s", self.home_dir)
372 storage_contents = self.source.storage.list(self.name)
373
374 for source, path in storage_contents:
375 attributes = self.source.storage.get_attributes(path)
376 file_type = attributes.get("file_type", None)
377 if file_type != None:
378 file_type = int(file_type)
379 else:
380 file_type = get_type_from_path(path)
381
382 if file_type == FirefoxProfileFile.TYPE_PROFILE_INI:
383 ini_files.append(path)
384 elif file_type == FirefoxProfileFile.TYPE_PREFS:
385 pref_files.append(path)
386 elif file_type == FirefoxProfileFile.TYPE_BOOKMARK:
387 bookmark_files.append(path)
388 elif file_type == FirefoxProfileFile.TYPE_UNKNOWN:
389 other_files.append(path)
390 else:
391 raise ValueError
392
393 dprint(LOG_APPLY, "apply: ini_files=%s pref_files=%s bookmark_files=%s other_files=%s",
394 ini_files, pref_files, bookmark_files, other_files)
395
396 def which_firefox ():
397 path = os.environ['PATH']
398 paths = path.split(os.pathsep)
399 for p in paths:
400 f = os.path.join (p, "firefox")
401 if os.path.exists (f):
402 return f
403 else:
404 return None
405
406
407
408
409
410 self.load_profiles_ini()
411 if not self.ini_file.is_valid():
412 dprint(LOG_APPLY, "apply: no valid ini file, extracting %s", profiles_ini_rel_path)
413 if profiles_ini_rel_path in ini_files:
414 self.source.storage.extract(profiles_ini_rel_path, self.home_dir, True)
415 self.load_profiles_ini()
416 else:
417 dprint(LOG_APPLY, "apply: but there isn't an ini file in the profile. Creating new profile.")
418 firefoxpath = which_firefox ()
419 if firefoxpath:
420 subprocess.call ([firefoxpath, "-createProfile", getpass.getuser ()])
421 self.load_profiles_ini()
422
423
424 for profile in self.ini_file.get_profiles():
425
426 profile_rel_dir = profile.get_rel_dir()
427 bogusbookmarks = os.path.join(profile_rel_dir, "bookmarks.html")
428 if os.path.exists (bogusbookmarks):
429 dprint (LOG_APPLY, "apply: Remove bogus file %s, see Mozilla Bug #333479.", bogusbookmarks)
430 os.remove (bogusbookmarks)
431
432 else:
433 dprint (APPLY, "apply: Firefox not found in PATH. Unable to create new profile.")
434
435
436 if sabayon_pref_rel_path in pref_files:
437 dprint(LOG_APPLY, "extracting %s", sabayon_pref_rel_path)
438 self.source.storage.extract(sabayon_pref_rel_path, self.home_dir, True)
439 apply_pref = JavascriptPrefsFile(self.home_dir, sabayon_pref_rel_path)
440 apply_pref.read()
441 else:
442 apply_pref = None
443
444 if sabayon_mandatory_pref_rel_path in pref_files:
445 dprint(LOG_APPLY, "extracting %s", sabayon_mandatory_pref_rel_path)
446 self.source.storage.extract(sabayon_mandatory_pref_rel_path, self.home_dir, True)
447 mandatory_apply_pref = JavascriptPrefsFile(self.home_dir, sabayon_mandatory_pref_rel_path)
448 mandatory_apply_pref.read()
449 else:
450 mandatory_apply_pref = None
451
452
453
454 if sabayon_bookmark_rel_path in bookmark_files:
455 dprint(LOG_APPLY, "extracting %s", sabayon_bookmark_rel_path)
456 self.source.storage.extract(sabayon_bookmark_rel_path, self.home_dir, True)
457 apply_bookmark = BookmarksFile(self.home_dir, sabayon_bookmark_rel_path)
458 apply_bookmark.read()
459 else:
460 apply_bookmark = None
461
462 if sabayon_mandatory_bookmark_rel_path in bookmark_files:
463 dprint(LOG_APPLY, "extracting %s", sabayon_mandatory_bookmark_rel_path)
464 self.source.storage.extract(sabayon_mandatory_bookmark_rel_path, self.home_dir, True)
465 mandatory_apply_bookmark = BookmarksFile(self.home_dir, sabayon_mandatory_bookmark_rel_path)
466 mandatory_apply_bookmark.read()
467 else:
468 mandatory_apply_bookmark = None
469
470
471
472
473
474
475 for profile in self.ini_file.get_profiles():
476 dprint(LOG_APPLY, "apply: applying to profile %s", profile.attrs)
477 profile_rel_dir = profile.get_rel_dir()
478
479
480 target_pref_rel_path = os.path.join(profile_rel_dir, "prefs.js")
481 target_pref = JavascriptPrefsFile(self.home_dir, target_pref_rel_path)
482 target_pref.read()
483
484 if apply_pref:
485 mandatory = False
486 dprint(LOG_APPLY, "apply: applying src profile %s to target profile %s, mandatory=%s",
487 sabayon_pref_rel_path, target_pref_rel_path, mandatory)
488 target_pref.merge(apply_pref, mandatory)
489
490 if mandatory_apply_pref:
491 mandatory = True
492 dprint(LOG_APPLY, "apply: applying src profile %s to target profile %s, mandatory=%s",
493 sabayon_pref_rel_path, target_pref_rel_path, mandatory)
494 target_pref.merge(mandatory_apply_pref, mandatory)
495
496 if apply_pref or mandatory_apply_pref:
497 target_pref.write()
498
499
500 target_bookmark_rel_path = os.path.join(profile_rel_dir, "bookmarks.html")
501 target_bookmark = BookmarksFile(self.home_dir, target_bookmark_rel_path)
502 target_bookmark.read()
503
504 if apply_bookmark:
505 mandatory = False
506 dprint(LOG_APPLY, "apply: applying src profile %s to target profile %s, mandatory=%s",
507 sabayon_bookmark_rel_path, target_bookmark_rel_path, mandatory)
508 target_bookmark.merge(apply_bookmark, mandatory)
509
510 if mandatory_apply_bookmark:
511 mandatory = True
512 dprint(LOG_APPLY, "apply: applying src profile %s to target profile %s, mandatory=%s",
513 sabayon_bookmark_rel_path, target_bookmark_rel_path, mandatory)
514 target_bookmark.merge(mandatory_apply_bookmark, mandatory)
515
516 if apply_bookmark or mandatory_apply_bookmark:
517 target_bookmark.write()
518
519
520 for path in other_files:
521 attributes = self.source.storage.get_attributes(path)
522 mandatory = attributes.get("mandatory", False)
523 dprint(LOG_APPLY, "apply: extracting other file %s, mandatory=%s", path, mandatory)
524 self.source.storage.extract(path, self.home_dir, mandatory)
525
526 dprint(LOG_APPLY, "apply: finished")
527
530
531
532
533
534
535
536
537
538
539
540
541
542 pref_re = re.compile("(pref|user_pref|lock_pref)\s*\(\s*\"([^,\"]+)\s*\"\s*,\s*(.+?)\)\s*;\s*$", re.MULTILINE)
543
544
545
548 self.filename = filename
550 return _("File Not Found (%s)") % self.filename
551
554 self.problem = problem
556 return self.problem
557
558
559
560
562 (TYPE_UNKNOWN,
563 TYPE_PROFILE_INI,
564 TYPE_PREFS,
565 TYPE_BOOKMARK
566 ) = range(4)
567
568 - def __init__(self, home_dir, rel_path):
569 self.home_dir = home_dir
570 self.rel_path = rel_path
571 self.attrs = {}
572 self.file_type = get_type_from_path(rel_path)
573
575 return os.path.join(self.home_dir, self.rel_path)
576
578 return self.rel_path
579
590
592 return self.file_type
593
594
595
598 self.type = type
599 self.key = key
600 self.value = value
601
603 if self.type == other.type and \
604 self.key == other.key and \
605 self.value == other.value:
606 return True
607 else:
608 return False
609
611 return self.type
612
614 return self.key
615
617 return self.value
618
619
620
622 - def __init__(self, home_dir, rel_path):
628
631
632 - def write(self, full_path=None):
633 if not full_path:
634 full_path = self.get_full_path()
635 dir = os.path.dirname(full_path)
636 if not os.path.exists(dir):
637 os.makedirs(dir)
638 dprint(LOG_OPERATION, "JavascriptPrefsFile: writing file (%s)", full_path)
639 fd = open(full_path, "w")
640 fd.write('''
641 # Mozilla User Preferences
642
643 /*
644 * Do not edit this file.
645 * Created by %s, version %s
646 */
647
648 ''' % (config.PACKAGE, config.VERSION))
649
650 keys = self.prefs.keys()
651 keys.sort()
652 for key in keys:
653 pref = self.prefs[key]
654 fd.write("%s(\"%s\", %s);\n" %
655 (pref.get_type(), pref.get_key(), pref.get_value()))
656
657 fd.close()
658
659
660 - def merge(self, src, mandatory):
668
669
670 - def read(self, full_path = None):
693
694
711
712 emit_changes(_add.items(), MozillaChange.CREATED)
713 emit_changes(_del.items(), MozillaChange.DELETED)
714 emit_changes(_mod.items(), MozillaChange.CHANGED)
715
716
717
719 def not_in_string (regexp):
720 double = '\\"(?:\\\\.|[^\"\\\\])*\\"'
721 single = "\\'(?:\\\\.|[^\"\\\\])*\\'"
722 return "(" + double + "|" + single + ")(?:" + regexp + ")"
723 def match (matchobj):
724 return matchobj.group(1)
725
726
727 slash_comment_re = re.compile(not_in_string ("//.*$"), re.MULTILINE)
728 hash_comment_re = re.compile(not_in_string ("#.*$"), re.MULTILINE)
729 c_comment_re = re.compile(not_in_string ("/\*.*?\*/"), re.MULTILINE | re.DOTALL)
730
731 self.filebuf = slash_comment_re.sub(match, self.filebuf)
732 self.filebuf = hash_comment_re.sub(match, self.filebuf)
733 self.filebuf = c_comment_re.sub(match, self.filebuf)
734
736 start = 0;
737 self.prefs = {}
738
739 while 1:
740 match = pref_re.search(self.filebuf, start)
741 if match:
742 type = match.group(1)
743 key = match.group(2)
744 value = match.group(3)
745 dprint(LOG_PARSE, "(%d:%d) key='%s' value='%s'", match.start(), match.end(), key, value)
746 self.prefs[key] = JavascriptPreference(type, key, value)
747 start = match.end()
748 else:
749 break
750
752 self.prefs = prefs.copy()
753
755 return self.prefs.copy()
756
758 keys = self.prefs.keys()
759 keys.sort()
760 for key in keys:
761 dprint(LOG_VERBOSE, "%s=%s", key, self.prefs[key])
762
763
764
765
767 - def __init__(self, section, home_dir, rel_dir):
768 self.section = section
769 self.home_dir = home_dir
770 self.rel_dir = rel_dir
771 self.attrs = {}
772 self.files = {}
773
775 self.attrs[attr] = value
776
778 return self.attrs[attr]
779
782
785
788
791
808
810 if rel_path in self.files:
811 del self.files[rel_path]
812
814 return [ file
815 for file in self.files.values() if file.get_type() == type ]
816
817
818
819
821 - def __init__(self, home_dir, rel_path):
822 self.file_state = file_state.UNKNOWN
823 self.default_profile = None
824 self.profiles = {}
825 self.ini = ConfigParser.ConfigParser()
826 self.home_dir = home_dir
827 self.rel_path = rel_path
828 self.rel_dir = os.path.dirname(rel_path)
829
832
834 return os.path.join(self.home_dir, path)
835
837 return self.rel_dir
838
840 return self.rel_path
841
844
846 dprint(LOG_OPERATION, "FirefoxProfilesIni.load_profiles()")
847 for profile in self.get_profiles():
848 profile_rel_dir = profile.get_rel_dir()
849
850 pref_rel_path = os.path.join(profile_rel_dir, "prefs.js")
851 dprint(LOG_OPERATION, "FirefoxProfilesIni.load_profiles() pref=%s", pref_rel_path)
852 profile_file = profile.add_file(pref_rel_path)
853 profile_file.read()
854
855 bookmark_rel_path = os.path.join(profile_rel_dir, "bookmarks.html")
856 dprint(LOG_OPERATION, "FirefoxProfilesIni.load_profiles() bookmark=%s", bookmark_rel_path)
857 profile_file = profile.add_file(bookmark_rel_path)
858 profile_file.read()
859
860
861
880
882 profile_re = re.compile("^Profile(\d+)$")
883
884 self.default_profile = None
885 self.profiles = {}
886 last_profile = None
887
888 for section in self.ini.sections():
889 dprint(LOG_PARSE, "parse_sections() section=%s", section)
890 match = profile_re.match(section)
891 if match:
892 try:
893 default_profile = self.ini.get(section, "default")
894 except ConfigParser.NoOptionError:
895 default_profile = None
896
897 name = self.ini.get(section, "Name")
898 if name in self.profiles:
899 raise BadIniFileError(_("duplicate name(%(name)s) in section %(section)s") %
900 (name, section))
901 profile = FirefoxProfile(section, self.home_dir, self.rel_dir)
902 self.profiles[name] = profile
903 for (key, value) in self.ini.items(section):
904 profile.set_attr(key, value)
905
906 if default_profile:
907 if self.default_profile:
908 raise BadIniFileError(_("redundant default in section %s") %
909 section)
910 self.default_profile = profile
911
912 last_profile = profile
913
914 if self.default_profile == None and len(self.profiles) == 1:
915
916
917
918
919 self.default_profile = last_profile
920 dprint(LOG_OPERATION, "defaulting profile to the only choice")
921
922
924 if not self.default_profile:
925 raise BadIniFileError(_("no default profile"))
926 return self.default_profile
927
929 if as_rel_dir:
930 return [ profile.get_rel_dir()
931 for profile in self.profiles.values() ]
932 else:
933 return self.profiles.values()
934
935
936
938 (
939 CREATED,
940 DELETED,
941 CHANGED
942 ) = range(3)
943
944 - def __init__ (self, source, delegate, entry, event):
954
956 self.attrs[attr] = value
957
959 return self.attrs[attr]
960
963
964 - def get_entry(self):
965 return self.entry
966
969
972
974 url = self.get_url()
975 bookmark_path = self.get_bookmark_path()
976
977 if self.event == self.CREATED:
978
979 if url:
980 return _("Mozilla bookmark created '%s' -> '%s'") % (bookmark_path, url)
981 else:
982 return _("Mozilla bookmark folder created '%s'") % (bookmark_path)
983 elif self.event == self.DELETED:
984 if url:
985 return _("Mozilla bookmark deleted '%s'") % (bookmark_path)
986 else:
987 return _("Mozilla bookmark folder deleted '%s'") % (bookmark_path)
988 elif self.event == self.CHANGED:
989 if url:
990 return _("Mozilla bookmark changed '%s' '%s'") % (bookmark_path, url)
991 else:
992 return _("Mozilla bookmark folder changed '%s'") % (bookmark_path)
993
994 else:
995 raise ValueError
996
997 gobject.type_register(BookmarkChange)
998
999
1000
1002 - def __init__(self, home_dir, rel_path):
1012
1014 return os.path.join(self.home_dir, self.rel_path)
1015
1017 return self.rel_path
1018
1020 return self.root
1021
1023 self.root = root
1024 self.parser.set_root(self.root)
1025
1047
1048 - def write(self, full_path=None, exclude_attrs=None):
1049 if not full_path:
1050 full_path = self.get_full_path()
1051 dir = os.path.dirname(full_path)
1052 if not os.path.exists(dir):
1053 os.makedirs(dir)
1054 dprint(LOG_OPERATION, "MozillaBookmark: writing file (%s)", full_path)
1055 fd = open(full_path, "w")
1056 fd.write('''
1057 <!DOCTYPE NETSCAPE-Bookmark-file-1>
1058 <!-- This is an automatically generated file. (Created by %s, version %s)
1059 It will be read and overwritten.
1060 DO NOT EDIT! -->
1061 <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
1062 <TITLE>Bookmarks</TITLE>
1063 <H1 LAST_MODIFIED="%.0f">Bookmarks</H1>
1064
1065 <DL><p>
1066 ''' % (config.PACKAGE, config.VERSION, time.time()))
1067
1068 def visit(entry, type, path, data):
1069 indent = " "
1070 level = len(path)
1071
1072 if type == mozilla_bookmarks.TYPE_FOLDER:
1073 fd.write("%s<DT><H3" % (indent*level))
1074 for attr, value in entry.attrs.items():
1075 if not filter_attr(attr, exclude_attrs):
1076 fd.write(" %s=\"%s\"" % (attr, value))
1077 fd.write(">%s</H3>\n" % (entry.name))
1078 fd.write("%s<DL><p>\n" % (indent*level))
1079 elif type == mozilla_bookmarks.TYPE_BOOKMARK:
1080 fd.write("%s<DT><A" % (indent*level))
1081 for attr, value in entry.attrs.items():
1082 if not filter_attr(attr, exclude_attrs):
1083 fd.write(" %s=\"%s\"" % (attr, value))
1084 fd.write(">%s</A>\n" % (entry.name))
1085 elif type == mozilla_bookmarks.TYPE_FOLDER_END:
1086 fd.write("%s</DL><p>\n" % (indent*level))
1087 else:
1088 raise ValueError
1089
1090 self.root.traverse(visit)
1091 fd.close()
1092
1094 result = {}
1095
1096 def visit(entry, type, path, data):
1097 bookmark_path = entry.path_as_string()
1098 result[bookmark_path] = entry
1099
1100 root.traverse(visit)
1101 return result
1102
1119
1120 emit_changes(_add.items(), BookmarkChange.CREATED)
1121 emit_changes(_del.items(), BookmarkChange.DELETED)
1122 emit_changes(_mod.items(), BookmarkChange.CHANGED)
1123
1124
1125 - def merge(self, src, mandatory):
1132
1133 src.root.traverse(visit)
1134
1135
1136
1137
1149
1157
1158
1159
1160
1161
1162
1163
1164
1166 test_prefs = {'foo':'"bar"', 'uno':'1'}
1167
1168 dprint(LOG_OPERATION, "In mozillaprofile tests")
1169