1
'''firefox apport hook draft
3
/usr/share/apport/package-hooks/firefox-2.py
5
Appends to apport's firefox default report: the files pluginreg.dat and
6
profiles.ini, and also a summary of all the extensions loaded on each firefox
7
profile (the summary is the extension's name, it's version, and the id)
8
obtained by parsing each extension's install.rdf file.
10
Copyright (c) 2007: Hilario J. Montoliu <hmontoliu@gmail.com>
12
This program is free software; you can redistribute it and/or modify it
13
under the terms of the GNU General Public License as published by the
14
Free Software Foundation; either version 2 of the License, or (at your
15
option) any later version. See http://www.gnu.org/copyleft/gpl.html for
16
the full text of the license.
23
from xml.dom import minidom
25
def extensions_ini_parser(extensions_ini_file):
26
'''parses profile's extensions.ini file and returns a tuple:
27
((global extensions, local extensions), (global theme, local theme))'''
28
parser = ConfigParser.ConfigParser()
29
parser.read(extensions_ini_file)
31
for section in parser.sections():
32
section_global, section_local, my_ext = [], [], ''
33
for extension in parser.options(section):
34
my_ext = parser.get(section, extension)
35
if '/usr/lib/firefox/extensions' in my_ext:
36
section_global.append((my_ext))
38
section_local.append((my_ext))
39
ext_ini_d[section] = (section_global, section_local)
40
return (ext_ini_d['ExtensionDirs'], ext_ini_d['ThemeDirs'])
42
def install_ini_parser(extension_path):
43
'''parses each extension's install.rdf and returns string:
44
extension name, its version and the id.'''
45
rdf_file = os.path.join(extension_path, 'install.rdf')
46
refs_dict = {'em:version': '', 'em:id': '', 'em:name': ''}
47
parse_err = '%s (Not Parsed)\n' % extension_path
48
dom_doc = minidom.parse(rdf_file)
49
for key in refs_dict.keys():
52
document_ref = dom_doc.getElementsByTagName('RDF:Description')[0].attributes
53
this_key = document_ref[key].value
56
document_ref = dom_doc.getElementsByTagName('Description')[0].attributes
57
this_key = document_ref[key].value
60
this_key = dom_doc.getElementsByTagName(key)[0].childNodes[0].data
63
try: # avoid problems with encodings.
64
print >> cStringIO.StringIO(), this_key
65
refs_dict[key] = this_key
66
except UnicodeEncodeError:
67
refs_dict[key] = repr(this_key)
68
return '''%(em:name)s (version: %(em:version)s) -\tid: %(em:id)s''' % refs_dict
70
def extension_summary_helper(extension_list, section_name, alt_output = 1):
71
'''does some output proccessing for extensionSummary'''
73
if len(extension_list) > 0:
74
str += ''' %s:\n''' % section_name
75
for extension in extension_list:
76
str += ''' %s\n''' % install_ini_parser(extension)
78
if alt_output == 1: # if 0, don't output anything
79
str += ''' No %s in this Profile.\n''' % section_name
84
config_dir = os.path.join(os.environ['HOME'], '.mozilla', 'firefox')
86
# append pluginreg.dat file:
87
pluginreg_dat = os.path.join(config_dir,'pluginreg.dat')
88
if os.path.exists(pluginreg_dat):
89
report['pluginreg.dat'] = open(pluginreg_dat).read()
91
# append profiles.ini file & parse it:
92
profiles_ini = os.path.join(config_dir,'profiles.ini')
93
if os.path.exists(profiles_ini):
94
report['profiles.ini'] = open(profiles_ini).read()
96
profiles_d = {} # { profile_name : [ profile_path, is_default ] }
97
profile_parser = ConfigParser.ConfigParser()
98
profile_parser.read(profiles_ini)
99
for section in profile_parser.sections():
100
if profile_parser.has_option(section, 'Name') and profile_parser.has_option(section, 'Path'):
101
if profile_parser.has_option(section, 'Default'):
102
is_default = profile_parser.get(section, 'Default')
105
profiles_d[profile_parser.get(section, 'Name')] = (os.path.join(config_dir, profile_parser.get(section, 'Path')), is_default)
107
# summarize the extensions loaded on each profile (either global and local):
108
extensions_dict, themes_dict, extension_summary = {}, {}, ''
109
for profile_name in profiles_d.keys():
110
profile_path, is_default = profiles_d[profile_name]
111
extensions_ini = os.path.join(profile_path, 'extensions.ini')
112
if os.path.exists(extensions_ini):
113
# attach each profile's extensions.ini too (not enabled).
114
#report['extensions.ini (profile: %s)' % profile_name ] = open(extensions_ini).read()
115
(extensions_dict['global_extensions'], extensions_dict['local_extensions']),\
116
(themes_dict['global_theme'], themes_dict['local_theme']) = extensions_ini_parser(extensions_ini)
118
if is_default == '1': is_default_str = ''' (The Default):'''
119
else: is_default_str = ''':'''
120
extension_summary += '''Profile "%s"%s\n\n''' % (profile_name, is_default_str)
121
extension_summary += extension_summary_helper(extensions_dict['global_extensions'], 'Global Extensions')
122
extension_summary += extension_summary_helper(extensions_dict['local_extensions'], 'Local Extensions')
123
extension_summary += extension_summary_helper(themes_dict['global_theme'], 'Global Theme', 0)
124
extension_summary += extension_summary_helper(themes_dict['local_theme'], 'Local Theme', 0)
125
buffer = cStringIO.StringIO() # it's needed for propper apport attachments
126
print >> buffer, extension_summary
128
report['ExtensionSummary'] = buffer.read()
129
# debug (comment on production)
133
# (uncomment the 'return report' at add_report())
134
if __name__ == "__main__":
137
for key in report.keys(): print '''%s:\n''' % key, report[key]