File Coverage

lib/Bookmarks/Opera.pm
Criterion Covered Total %
statement 9 90 10.0
branch 0 62 0.0
condition 0 26 0.0
subroutine 3 6 50.0
pod 2 2 100.0
total 14 186 7.5


line stmt bran cond sub pod time code
1             # Opera-specific bookmarks parser and producer
2              
3             package Bookmarks::Opera;
4              
5 5     5   53 use strict;
  5         9  
  5         204  
6 5     5   30 use warnings;
  5         18  
  5         175  
7 5     5   28 use base 'Bookmarks::Parser';
  5         8  
  5         7015  
8              
9             # Last updated, September 2011,
10             # Opera Hotlist version 21
11             my @op_bookmark_fields = (
12             "ACTIVE",
13             "CREATED",
14             "DELETABLE",
15             "DESCRIPTION",
16             "DISPLAY URL",
17             "ICONFILE",
18             "ID",
19             "IN PANEL",
20             "MOVE_IS_COPY",
21             "NAME",
22             "ON PERSONALBAR",
23             "PANEL_POS",
24             "PARTNERID",
25             "PERSONALBAR_POS",
26             "SEPARATOR_ALLOWED",
27             "SHORT NAME",
28             "TARGET",
29             "TRASH FOLDER",
30             "UNIQUEID",
31             "URL",
32             "VISITED",
33             );
34              
35             my %op_bookmark_fields = map {
36             # No qr{}x, field names contain significant whitespace
37             $_ => qr{^\s+$_=(.*)}
38             } @op_bookmark_fields;
39              
40             sub _parse_file
41             {
42 0     0     my ($self, $filename) = @_;
43              
44 0 0         return undef if(!-e $filename);
45              
46 0           my $fh;
47 0           my $curitem = {};
48 0           my $curfolder = {};
49 0 0         open $fh, "<$filename" or die "Can't open $filename ($!)";
50              
51 0           while (my $line = <$fh>)
52             {
53             # chomp $line;
54 0           $line =~ s/[\r\n]//g;
55 0 0         next if($line =~ /^Opera Hotlist version/);
56 0 0         next if($line =~ /^Options:/);
57              
58 0 0         if ($line =~ m{^ \s* $}x)
59             {
60 0 0         if($curitem->{start})
61             {
62 0           delete $curitem->{start};
63 0           $curitem->{parent} = $curfolder->{id};
64 0           $self->add_bookmark($curitem, $curfolder->{id});
65 0 0         if($curitem->{type} eq 'folder')
66             {
67 0           $curfolder = $curitem;
68             }
69 0           $curitem = {};
70             }
71             }
72 0 0         if($line eq '-')
73             {
74 0           $curfolder = $self->{_items}{$curfolder->{parent}};
75             # ($curfolder) = grep { $_->{id} eq $curfolder->{parent} }
76             # @{$self->{_items}};
77             }
78 0 0         if($line =~/^#(FOLDER|URL)/)
79             {
80 0           $curitem->{start} = 1;
81 0           $curitem->{type} = lc($1);
82             }
83 0 0         if($curitem->{start})
84             {
85 0           for my $key (keys %op_bookmark_fields) {
86 0           my $re = $op_bookmark_fields{$key};
87 0 0         if ($line =~ $re) {
88 0           my $value = $1;
89 0           my $nicename = lc $key;
90 0           $nicename =~ s{\s}{_}g;
91 0           $nicename =~ s{iconfile}{icon};
92 0           $curitem->{$nicename} = $value;
93             }
94             }
95             }
96             }
97              
98             # Deal with last element if there's no closing empty line
99 0 0         if ($curitem->{start})
100             {
101 0           delete $curitem->{start};
102 0           $curitem->{parent} = $curfolder->{id};
103 0           $self->add_bookmark($curitem, $curfolder->{id});
104 0 0         $curfolder = $curitem if $curitem->{type} eq 'folder';
105 0           $curitem = {};
106             }
107              
108 0           close($fh);
109 0           return $self;
110             }
111              
112             sub get_header_as_string
113             {
114 0     0 1   my ($self) = @_;
115              
116 0           my $header = << "HEADER";
117             Opera Hotlist version 2.0
118             Options: encoding = utf8, version=21
119              
120             HEADER
121              
122 0           return $header;
123             }
124              
125             {
126             my $folorder = 0;
127              
128             sub get_item_as_string
129             {
130 0     0 1   my ($self, $item) = @_;
131              
132 0 0 0       if(!defined $item->{id} || !$self->{_items}{$item->{id}})
133             {
134 0           warn "No such item in get_item_as_string";
135 0           return;
136             }
137              
138 0           my $string = '';
139 0   0       my ($id, $url, $name, $visited, $created, $modified, $icon, $desc, $expand, $trash, $order) =
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
140             ($item->{id} || 0,
141             $item->{url} || '',
142             $item->{name} || '',
143             $item->{visited} || 0,
144             $item->{created} || time(),
145             $item->{modified} || 0,
146             $item->{icon} || '',
147             $item->{description} || '',
148             $item->{expanded} || '',
149             $item->{trash} || '',
150             $item->{order} || undef);
151              
152 0 0         if($item->{type} eq 'folder')
    0          
153             {
154 0 0         if(!defined($order))
155             {
156 0           $folorder = 0;
157             }
158 0           $string .= "#FOLDER\n";
159 0           $string .= " ID=$id\n";
160 0           $string .= " NAME=$name\n";
161 0           $string .= " CREATED=$created\n";
162 0 0         $string .= " TRASH FOLDER=$trash\n" if($trash);
163 0 0         $string .= " VISITED=$visited\n" if($visited);
164 0 0         $string .= " EXPANDED=$expand\n" if($expand);
165 0 0         $string .= " DESCRIPTION=$desc\n" if($desc);
166 0 0         $string .= " ICONFILE=$icon\n" if($icon);
167 0 0         $string .= " ORDER=$order\n" if(defined $order);
168 0           $string .= "\n";
169              
170 0           $string .= $self->get_item_as_string($self->{_items}{$_})
171 0           foreach (@{$item->{children}});
172 0           $string .= "-\n";
173             }
174             elsif($item->{type} eq 'url')
175             {
176 0 0         if(!defined($order))
177             {
178 0           $order = $folorder++;
179             }
180              
181 0           $string .= "#URL\n";
182 0           $string .= " ID=$id\n";
183 0           $string .= " NAME=$name\n";
184 0 0         $string .= " URL=$url\n" if($url);
185 0           $string .= " CREATED=$created\n";
186 0 0         $string .= " TRASH FOLDER=$trash\n" if($trash);
187 0 0         $string .= " VISITED=$visited\n" if($visited);
188 0 0         $string .= " EXPANDED=$expand\n" if($expand);
189 0 0         $string .= " DESCRIPTION=$desc\n" if($desc);
190 0 0         $string .= " ICONFILE=$icon\n" if($icon);
191 0 0         $string .= " ORDER=$order\n" if(defined $order);
192 0           $string .= "\n";
193             }
194              
195 0           return $string;
196             }
197             }
198              
199             1;
200              
201             __END__