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   33 use strict;
  5         6  
  5         163  
6 5     5   19 use warnings;
  5         5  
  5         135  
7 5     5   18 use base 'Bookmarks::Parser';
  5         9  
  5         3745  
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              
37             # No qr{}x, field names contain significant whitespace
38             $_ => qr{^\s+$_=(.*)}
39             } @op_bookmark_fields;
40              
41             sub _parse_file {
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 0 0         if ($curitem->{start}) {
60 0           delete $curitem->{start};
61 0           $curitem->{parent} = $curfolder->{id};
62 0           $self->add_bookmark($curitem, $curfolder->{id});
63 0 0         if ($curitem->{type} eq 'folder') {
64 0           $curfolder = $curitem;
65             }
66 0           $curitem = {};
67             }
68             }
69 0 0         if ($line eq '-') {
70 0           $curfolder = $self->{_items}{ $curfolder->{parent} };
71              
72             # ($curfolder) = grep { $_->{id} eq $curfolder->{parent} }
73             # @{$self->{_items}};
74             }
75 0 0         if ($line =~ /^#(FOLDER|URL)/) {
76 0           $curitem->{start} = 1;
77 0           $curitem->{type} = lc($1);
78             }
79 0 0         if ($curitem->{start}) {
80 0           for my $key (keys %op_bookmark_fields) {
81 0           my $re = $op_bookmark_fields{$key};
82 0 0         if ($line =~ $re) {
83 0           my $value = $1;
84 0           my $nicename = lc $key;
85 0           $nicename =~ s{\s}{_}g;
86 0           $nicename =~ s{iconfile}{icon};
87 0           $curitem->{$nicename} = $value;
88             }
89             }
90             }
91             }
92              
93             # Deal with last element if there's no closing empty line
94 0 0         if ($curitem->{start}) {
95 0           delete $curitem->{start};
96 0           $curitem->{parent} = $curfolder->{id};
97 0           $self->add_bookmark($curitem, $curfolder->{id});
98 0 0         $curfolder = $curitem if $curitem->{type} eq 'folder';
99 0           $curitem = {};
100             }
101              
102 0           close($fh);
103 0           return $self;
104             }
105              
106             sub get_header_as_string {
107 0     0 1   my ($self) = @_;
108              
109 0           my $header = << "HEADER";
110             Opera Hotlist version 2.0
111             Options: encoding = utf8, version=21
112              
113             HEADER
114              
115 0           return $header;
116             }
117              
118             {
119             my $folorder = 0;
120              
121             sub get_item_as_string {
122 0     0 1   my ($self, $item) = @_;
123              
124 0 0 0       if (!defined $item->{id} || !$self->{_items}{ $item->{id} }) {
125 0           warn "No such item in get_item_as_string";
126 0           return;
127             }
128              
129 0           my $string = '';
130 0   0       my ($id, $url, $name, $visited, $created, $modified, $icon, $desc,
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
      0        
131             $expand, $trash, $order) = (
132             $item->{id} || 0,
133             $item->{url} || '',
134             $item->{name} || '',
135             $item->{visited} || 0,
136             $item->{created} || time(),
137             $item->{modified} || 0,
138             $item->{icon} || '',
139             $item->{description} || '',
140             $item->{expanded} || '',
141             $item->{trash} || '',
142             $item->{order} || undef
143             );
144              
145 0 0         if ($item->{type} eq 'folder') {
    0          
146 0 0         if (!defined($order)) {
147 0           $folorder = 0;
148             }
149 0           $string .= "#FOLDER\n";
150 0           $string .= " ID=$id\n";
151 0           $string .= " NAME=$name\n";
152 0           $string .= " CREATED=$created\n";
153 0 0         $string .= " TRASH FOLDER=$trash\n" if ($trash);
154 0 0         $string .= " VISITED=$visited\n" if ($visited);
155 0 0         $string .= " EXPANDED=$expand\n" if ($expand);
156 0 0         $string .= " DESCRIPTION=$desc\n" if ($desc);
157 0 0         $string .= " ICONFILE=$icon\n" if ($icon);
158 0 0         $string .= " ORDER=$order\n" if (defined $order);
159 0           $string .= "\n";
160              
161 0           $string .= $self->get_item_as_string($self->{_items}{$_})
162 0           foreach (@{ $item->{children} });
163 0           $string .= "-\n";
164             }
165             elsif ($item->{type} eq 'url') {
166 0 0         if (!defined($order)) {
167 0           $order = $folorder++;
168             }
169              
170 0           $string .= "#URL\n";
171 0           $string .= " ID=$id\n";
172 0           $string .= " NAME=$name\n";
173 0 0         $string .= " URL=$url\n" if ($url);
174 0           $string .= " CREATED=$created\n";
175 0 0         $string .= " TRASH FOLDER=$trash\n" if ($trash);
176 0 0         $string .= " VISITED=$visited\n" if ($visited);
177 0 0         $string .= " EXPANDED=$expand\n" if ($expand);
178 0 0         $string .= " DESCRIPTION=$desc\n" if ($desc);
179 0 0         $string .= " ICONFILE=$icon\n" if ($icon);
180 0 0         $string .= " ORDER=$order\n" if (defined $order);
181 0           $string .= "\n";
182             }
183              
184 0           return $string;
185             }
186             }
187              
188             1;
189              
190             __END__