File Coverage

blib/lib/Mozilla/Prefs/Simple.pm
Criterion Covered Total %
statement 21 92 22.8
branch 0 12 0.0
condition 0 4 0.0
subroutine 7 19 36.8
pod 10 10 100.0
total 38 137 27.7


line stmt bran cond sub pod time code
1             package Mozilla::Prefs::Simple;
2              
3 1     1   27314 use warnings;
  1         3  
  1         38  
4 1     1   6 use strict;
  1         2  
  1         38  
5              
6 1     1   6 use Carp;
  1         5  
  1         78  
7 1     1   1013 use File::Copy;
  1         6117  
  1         89  
8 1     1   1081 use IO::File;
  1         12931  
  1         174  
9 1     1   1266 use Regexp::Common qw( balanced );
  1         3257  
  1         5  
10 1     1   3322 use Tie::Hash::Sorted 0.10;
  1         3976  
  1         13  
11              
12             our $VERSION = '0.01';
13              
14             =head1 NAME
15              
16             Mozilla::Prefs::Simple - Manipulate Mozilla preferences
17              
18             =head1 SYNOPSIS
19              
20             use Mozilla::Prefs::Simple;
21              
22             my $p = new Mozilla::Prefs::Simple('prefs.js');
23              
24             $p->set_pref("browser.blink_allowed", "true");
25             $p->set_pref("general.useragent.locale", "\"en-US\"");
26              
27             if ($p->get_pref("mailnews.reply_header_type") == 2) {
28             ...
29             }
30              
31             $p->save_file('prefs.js');
32              
33             =head1 DESCRIPTION
34              
35             This is a no-frills module for reading and writing Mozilla preference
36             files.
37              
38             =begin readme
39              
40             More details can be found in the module documentation.
41              
42             =end readme
43              
44             =for readme stop
45              
46             =head1 METHODS
47              
48             =over
49              
50             =cut
51              
52             =item new
53              
54             Create a new preferences object.
55              
56             my $p = new Mozilla::Prefs::Simple();
57              
58             my $p = new Mozilla::Prefs::Simple('prefs.js');
59              
60             =cut
61              
62             sub new {
63 0   0 0 1   my $class = shift || __PACKAGE__;
64              
65 0           my $self = {
66             "_strip_comments" => 1,
67             "_backup_original" => 1,
68             };
69 0           bless $self, $class;
70              
71 0           $self->clear;
72 0 0         if (@_) {
73 0           my $file = shift;
74 0           $self->load_file($file);
75             }
76              
77 0           return $self;
78             }
79              
80             =item clear
81              
82             $p->clear;
83              
84             Erase the existing preferences. Called by L method.
85              
86             =cut
87              
88             sub clear {
89 0     0 1   my $self = shift;
90 0           delete $self->{_prefs};
91              
92 0           tie my %prefs, 'Tie::Hash::Sorted';
93 0           $self->{_prefs} = \%prefs;
94             }
95              
96              
97             sub _parse_line {
98 0     0     my $self = shift;
99 0           my $line = shift;
100              
101 0 0         if ($line =~ /\buser_pref($RE{balanced}{-parens=>'()'})/) {
102 0           my $pref = $1;
103 0 0         if ($pref =~ /^\(\"(.+)\"\s*\,\s*(.*)\)$/) {
104 0           return ($1, $2);
105             }
106             else {
107 0           croak "Unable to parse line: $line";
108             }
109             }
110             else {
111 0           croak $line;
112             }
113             }
114              
115             sub _read_file {
116 0     0     my $self = shift;
117 0           my $file = shift;
118              
119 0           my $fh = new IO::File;
120 0           open ($fh, "< $file");
121              
122 0           my $data = "";
123 0           while (<$fh>) {
124 0           $data .= $_;
125             }
126              
127 0           close $fh;
128              
129 0 0         if ($self->{_strip_comments}) {
130             # TODO - comment parsing that does not strip URLs
131             # Regexp::Common mistakes URLs for comments
132             }
133             else {
134 0           croak "Preserving comments is unsupported";
135             }
136              
137 0           return $data;
138             }
139              
140             =item load_file
141              
142             $p->load_file('prefs.js');
143              
144             Loads a preferences file.
145              
146             If preferences are already set, they will be overwritten or merged with
147             the ones in the file.
148              
149             =cut
150              
151             sub load_file {
152 0     0 1   my $self = shift;
153 0           my $file = shift;
154              
155 0           foreach my $line (split /\;\s*\n/, $self->_read_file($file)) {
156 0           my ($key, $value) = $self->_parse_line($line);
157 0           $self->set_pref($key, $value);
158             }
159             }
160              
161             =item set_pref
162              
163             =item set_pref_q
164              
165             $p->set_pref("some.bool", "true");
166              
167             $p->set_pref("some.int", 12345);
168              
169             $p->set_pref("some.string", "\"value\"");
170              
171             Sets the values of preferences.
172              
173             Note that the values are JavaScript terms, so if you are setting a
174             string value, then it should be enclosed in quotes. To make this less
175             annoying, you can use the L method, which adds quotes
176             for you:
177              
178             $p->set_pref_q("some.string", "value");
179              
180             =cut
181              
182             sub set_pref {
183 0     0 1   my $self = shift;
184 0           my $key = shift;
185 0           my $value = shift;
186 0           $self->{_prefs}->{$key} = "$value";
187             }
188              
189             sub set_pref_q {
190 0     0 1   my $self = shift;
191 0           my $key = shift;
192 0           my $value = shift;
193 0           $self->{_prefs}->{$key} = "\"$value\"";
194             }
195              
196             =item get_pref
197              
198             my $val = $p->get_pref("some.pref");
199              
200             Returns the value of a preference.
201              
202             =cut
203              
204             sub get_pref {
205 0     0 1   my $self = shift;
206 0           my $key = shift;
207 0           return $self->{_prefs}->{$key};
208             }
209              
210             =item has_pref
211              
212             if ($p->has_pref("some.pref")) {
213             ...
214             }
215              
216             Checks for the existence of a preference.
217              
218             =cut
219              
220             sub has_pref {
221 0     0 1   my $self = shift;
222 0           my $key = shift;
223 0           return exists $self->{_prefs}->{$key};
224             }
225              
226             =item print_pref
227              
228             $p->print_pref("some.pref", $fh);
229              
230             Prints the JavaScript preference line to C<$fh>.
231              
232             =cut
233              
234             sub print_pref {
235 0     0 1   my $self = shift;
236 0           my $key = shift;
237 0           my $value = $self->get_pref($key);
238 0           my $fh = shift;
239 0           print $fh "user_pref(\"$key\", $value);\n";
240             }
241              
242             =item print_prefs
243              
244             $p->print_prefs($fh);
245              
246             Prints out all of the preferences to the filehandle.
247             If no filehandle is given, C is assumed.
248             =cut
249              
250             sub print_prefs {
251 0     0 1   my $self = shift;
252 0   0       my $fh = shift || \*STDOUT;
253 0           while (my ($key, $value) = each %{$self->{_prefs}}) {
  0            
254 0           $self->print_pref($key, $fh);
255             }
256             }
257              
258             =item save_file
259              
260             $p->save_file('prefs.js');
261              
262             Saves the preferences to the given filename.
263              
264             If the file exists, a backup copy is made of the original.
265              
266             =cut
267              
268             sub save_file {
269 0     0 1   my $self = shift;
270 0           my $file = shift;
271              
272 0 0         if (-e $file) {
273 0 0         if ($self->{_backup_original}) {
274             # TODO - if syscopy present (Perl 5.10), use that instead
275 0           move($file, "$file.backup");
276             }
277             else {
278 0           carp "Overwriting file $file";
279             }
280             }
281              
282 0           my $fh = new IO::File;
283 0           open($fh, ">$file");
284              
285             # print $fh "
286             #
287             # /* Do not edit this file.
288             # *
289             # * If you make changes to this file while the application is running,
290             # * the changes will be overwritten when the application exits.
291             # *
292             # * To make a manual change to preferences, you can visit the URL about:config
293             # * For more information, see http://www.mozilla.org/unix/customizing.html#prefs
294             # */
295             # ";
296              
297 0           print $fh "\n/* Generated by " .
298             __PACKAGE__ . " on " . localtime() . " */\n\n";
299              
300 0           $self->print_prefs($fh);
301              
302 0           close $fh;
303             }
304              
305             =back
306              
307             =head1 CAVEATS
308              
309             This module does very little to validate data. When using it, make sure
310             that you backup your preferences beforehand.
311              
312             The current version does not parse JavaScript comments. In theory, a
313             user-preference that occurs inside a comment will not be ignored.
314             In practice, applications like Firefox and Thunderbird do not save
315             preferences in comments, so this should not be a problem.
316              
317             =for readme continue
318              
319             =head1 AUTHOR
320              
321             Robert Rothenberg, C<< >>
322              
323             =head1 BUGS
324              
325             Please report bugs to
326             L.
327              
328             =head1 COPYRIGHT & LICENSE
329              
330             Copyright 2008 Robert Rothenberg, all rights reserved.
331              
332             This program is free software; you can redistribute it and/or modify it
333             under the same terms as Perl itself.
334              
335              
336             =cut
337              
338             1; # End of Mozilla::Prefs::Simple