File Coverage

blib/lib/Sman/Util.pm
Criterion Covered Total %
statement 30 123 24.3
branch 0 38 0.0
condition 0 7 0.0
subroutine 10 19 52.6
pod 0 9 0.0
total 40 196 20.4


line stmt bran cond sub pod time code
1             ################################
2             package Sman::Util;
3 1     1   1246 use Sman; # for VERSION
  1         2  
  1         25  
4              
5             #$Id: Util.pm,v 1.45 2008/06/03 15:38:48 joshr Exp $
6              
7 1     1   6 use strict;
  1         2  
  1         27  
8 1     1   5 use warnings;
  1         1  
  1         31  
9 1     1   5 use Config; # to get perl version string
  1         1  
  1         36  
10 1     1   1308 use File::Temp; # used in RunCommand()
  1         23834  
  1         132  
11              
12             our $VERSION = '1.03_002';
13             our $SMAN_DATA_VERSION = "1.4"; # this is only relevant to Sman
14              
15             # TODO: FIX THIS, to do... what?
16 1     1   925 use lib '/usr/local/lib/swish-e/perl'; # for source installs, so we can find SWISH::DefaultHighlight.pm
  1         776  
  1         6  
17 1     1   178 use lib '/usr/libexec/swish-e/perl/'; # for rpm installs, so we can find SWISH::DefaultHighlight.pm
  1         2  
  1         4  
18 1     1   131 use lib '/sw/lib/swish-e/perl'; # for fink-installed SWISH::DefaultHightlight. TODO: cleanup.
  1         4  
  1         6  
19              
20             # this checks if the SWISH::API is recent enough to have
21             # the features we use. returns 1 if yes, 0 otherwise
22             sub CheckSwisheVersion {
23             #eval { # wrap the version check in an EVAL in case of failure
24             # require SWISH::API;
25             # no strict 'vars';
26             # use vars qw( $SWISH::API::VERSION );
27             # unless ($SWISH::API::VERSION && $SWISH::API::VERSION >= 0.03) {
28             # $@ = "Can't run: need SWISH::API >= 0.03\n";
29             # return 0;
30             # }
31             #};
32 0     0 0   my $class = "SWISH::API";
33 0           eval "require $class"; # if the class exists, this should load it
34            
35 0 0         if ($@) {
36 0           warn "$0: Can't load $class\n";
37 0           return 0;
38             }
39              
40 1     1   191 no strict 'vars';
  1         3  
  1         34  
41 1     1   6 use vars qw( $SWISH::API::VERSION );
  1         2  
  1         1928  
42 0 0 0       unless ($SWISH::API::VERSION && $SWISH::API::VERSION >= 0.03) {
43             # PAUSE namespace indexer complains about the line above:
44             # " The PAUSE indexer was not able to parse the following line
45             # in that file: C< unless ($SWISH::API::VERSION &&
46             # $SWISH::API::VERSION >= 0.03) { > Note: the indexer is
47             # running in a Safe compartement and cannot provide the full
48             # functionality of perl in the VERSION line. It is trying
49             # hard, but sometime it fails. As a workaround, please
50             # consider writing a proper META.yml that contains a
51             # 'provides' attribute (currently only supported by
52             # Module::Build) or contact the CPAN admins to investigate
53             # (yet another) workaround against "Safe" limitations.) "
54              
55             # I don't understand why the namespace indexer needs to parse (run) this function
56              
57 0           warn "$0: Can't run: need SWISH::API >= 0.03\n";
58 0           $@ = "Can't run: need SWISH::API >= 0.03\n"; # SET $@ for caller, if they check
59 0           return 0;
60             }
61 0           return 1; # it's OK
62             }
63              
64             sub MakeXML { # output xml version of hash
65 0     0 0   my $metas = shift;
66 0           my $xml = join ("",
67 0           map { "<$_>\n" . XMLEscape($metas->{$_}) . "\n\n" }
68             keys %$metas);
69 0           my $pre = qq{\n\n};
70 0           return qq{$pre\n$xml\n\n};
71             }
72              
73             sub XMLEscape {
74 0 0   0 0   return "" unless defined($_[0]);
75 0           my $v = shift;
76 0           $v =~ s/&/&/g;
77 0           $v =~ s/
78 0           $v =~ s/>/>/g;
79 0           return $v;
80             }
81             sub ReadFile {
82 0     0 0   my $file = shift;
83 0           local( $/, *FFF ); # $/ is set to undef
84 0 0 0       open(FFF, "$file") || warn "Couldn't open $file: $!" && return "";
85 0           my $content = ; # file slurped at once
86 0 0         close(FFF) || warn "Error closing $file: $!";
87 0           return $content;
88             }
89             sub WriteFile {
90 0     0 0   my ($file, $contentref) = @_;
91 0 0 0       open(FFF, ">" . "$file") || warn "Couldn't open $file: $!" && return 0;
92 0           print FFF $$contentref;
93 0 0         close(FFF) || warn "Error closing $file: $!";
94 0           return $contentref;
95             }
96              
97             # RunCommand's block, to encapsulate @tmpfiles.
98             {
99             my @tmpfiles = ();
100             # given a command and optional tmpdir, returns (stdout, stderr, $?)
101             # uses the shell underneath
102             sub RunCommand {
103 0     0 0   my ($cmd, $tmpdir, $should_be_undef) = @_;
104 0 0         die "$0: Internal Error: Sman::Util::RunCommand called with three arguments\n"
105             if $should_be_undef;
106 0 0         $tmpdir = "/tmp" unless defined $tmpdir;
107 0           my ($out, $err) = ("", "");
108 0           my $r = sprintf("%04d", rand(9999));
109 0           my ($ofh, $outfile) = File::Temp::tempfile( "cmd-out.XXXXX", DIR => $tmpdir);
110 0           my ($efh, $errfile) = File::Temp::tempfile( "cmd-err.XXXXX", DIR => $tmpdir);
111             # use two temporary filenames
112 0           my $torun = "$cmd 1>$outfile 2>$errfile";
113 0           push(@tmpfiles, $outfile, $errfile); # in case of SIG
114             #print "RUNNING $torun\n";
115 0           system($torun);
116 0 0         if ($?) {
117 0           my $exit = $? >> 8;
118 0           my $signal = $? & 127;
119 0           my $dumped = $? & 128;
120              
121 0           $err .= "** ERROR: $torun\n";
122 0           $err .= "exitvalue $exit";
123 0 0         $err .= ", got signal $signal" if $signal;
124 0 0         $err .= ", dumped core" if $dumped;
125 0           $err .= "\n";
126             }
127 0           my $dollarquestionmark = $?;
128            
129 0           $out .= ReadFile($outfile);
130 0           $err .= ReadFile($errfile);
131              
132 0 0         unlink($errfile) || warn "$0: couldn't unlink $errfile: $!";
133 0           pop(@tmpfiles);
134 0 0         unlink($outfile) || warn "$0: couldn't unlink $outfile: $!";
135 0           pop(@tmpfiles);
136              
137 0           return ($out, $err, $dollarquestionmark);
138             }
139             END { # hopefully this will get triggered
140             # if RunCommand throws an exception
141             for my $tmpfile (@tmpfiles) {
142             unlink($tmpfile) || warn "** Couldn't unlink tmp file $tmpfile";
143             }
144             }
145             }
146              
147             sub GetIndexDescriptionString {
148 0     0 0   my ($index) = @_;
149 0           my $indexmodtime = (stat( "$index.prop" ))[9];
150 0 0         return sprintf("Using index %s, %s\n",
151             $index, $indexmodtime ? "updated " . scalar(localtime( $indexmodtime ) ) : "(index not found)" );
152             }
153              
154             sub GetVersionString {
155 0     0 0   my ($prog, $swishecmd) = @_;
156 0           require SWISH::API; # for $VERSION
157 0           require Sman; # for $VERSION
158 0           my $str = "$prog $Sman::Util::VERSION, using SWISH::API $SWISH::API::VERSION";
159 0 0         if ($swishecmd) {
160 0           my $cmd = $swishecmd . " -V";
161 0           my @lines = `$cmd`;
162 0 0         if (defined($lines[0])) {
163 0           chomp($lines[0]);
164 0 0         ($lines[0] =~ / ([\d.]+)/) && ($lines[0] = "Swish-e $1");
165 0           $str .= ", $lines[0]";
166             }
167             }
168 0           $str .= ", and perl $Config{version}";
169 0           return $str;
170             }
171              
172              
173             sub ExtractSummary {
174 0     0 0   require SWISH::DefaultHighlight; # defer till now, so sman -V doesn't need SWISH::API
175 0           my %header = (
176             wordcharacters => q{0123456789abcdefghijklmnopqrstuvwxyz});
177             #q{ªµºÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß} .
178             #q{àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ});
179 0           my %highlight = (
180             show_words => 4, # Number of "swish words" words to show around highlighted word
181             max_words => 10, # If no words are found to highlighted then show this many words
182             occurrences => 4, # Limit number of occurrences of highlighted words
183             highlight_on => '*', # highlighting code
184             highlight_off => '*',
185             );
186              
187 0           my ($str, $termsref, $prefix, $width) = @_;
188 0           my $sho = new SWISH::DefaultHighlight( \%highlight, \%header );
189             #my $sho = new SWISH::SimpleHighlight( \%highlight, \%header );
190 0           my @phrases;
191 0           for my $t (@$termsref) {
192 0           my @list = ($t);
193 0           push(@phrases, \@list);
194             }
195 0           $sho->highlight(\$str, \@phrases, 'swishdescription');
196 0           $str =~ s/"/'/g;
197 0           $str =~ s/>/>/g;
198 0           $str =~ s/</
199 0           $str =~ s/^\s+//;
200 0           $str =~ s/\s+$//;
201 0           $str = $prefix . $str;
202 0 0         $str = substr($str, 0, $width-3) . "..." if length($str) > $width;
203 0           return $str;
204             }
205              
206              
207             1;
208              
209             =head1 NAME
210              
211             Sman::Util - Utility functions for Sman
212              
213             =head1 SYNOPSIS
214              
215             Sman::Util currently provides the following functions:
216              
217             # XMLEscape escapes XML
218             my $str = Sman::Util::XMLEscape("a-fun#y&%$TRiñg");
219            
220             # MakeXML makes XML from a simple hash of names->strings
221             my $xml = Sman::Util::MakeXML(\%somehash);
222            
223             # ReadFile reads the contents of a file and returns it as a scalar
224             my $content = Sman::Util::ReadFile("filename");
225            
226             # RunCommand uses the shell to capture stdout and stderr and $?
227             # Pass command and tempdir to save its temp files in.
228             # tmpdir defaults to '/tmp'
229             my ($out, $err, $dollarquestionmark) = Sman::Util::RunCommand("ls -l", "/tmp");
230              
231             # GetVersionString gives you a version string like
232             # 'sman v0.8.3 using SWISH::API v0.01 and Swish-e v2.4.0'
233             # pass program name and the Swish-e command path
234             my $vstr = Sman::Util::GetVersionString('prog', '/usr/local/bin/swish-e');
235            
236             =head1 DESCRIPTION
237              
238             This module implements utility functions for sman-update and sman
239              
240             =head1 AUTHOR
241              
242             Copyright Josh Rabinowitz 2004-2005
243              
244             =head1 SEE ALSO
245              
246             L, L
247              
248             =cut
249