File Coverage

blib/lib/ZConf/Runner.pm
Criterion Covered Total %
statement 21 541 3.8
branch 0 192 0.0
condition 0 6 0.0
subroutine 7 25 28.0
pod 18 18 100.0
total 46 782 5.8


line stmt bran cond sub pod time code
1             package ZConf::Runner;
2              
3 3     3   42501 use warnings;
  3         6  
  3         96  
4 3     3   16 use strict;
  3         5  
  3         103  
5 3     3   3135 use File::MimeInfo::Magic;
  3         64748  
  3         253  
6 3     3   5443 use File::MimeInfo::Applications;
  3         41956  
  3         316  
7 3     3   6917 use ZConf;
  3         809900  
  3         142  
8 3     3   4216 use String::ShellQuote;
  3         5435  
  3         8819  
9              
10             =head1 NAME
11              
12             ZConf::Runner - Run a file using a choosen methode, desktop entry or mimetype.
13              
14             =head1 VERSION
15              
16             Version 2.1.4
17              
18             =cut
19              
20             our $VERSION = '2.1.4';
21              
22             =head1 SYNOPSIS
23              
24             The purpose of this module is to figure out what to do with an object based
25             on it's mimetype. Currently only files are supported.
26              
27             use ZConf::Runner;
28              
29             my $zcr=ZConf::Runner->new();
30             if($zcr->{error}){
31             print "Error!\n";
32             }
33              
34             =head1 METHODS
35              
36             =head2 new
37              
38             This initializes it.
39              
40             One arguement is taken and that is a hash value.
41              
42             =head3 hash values
43              
44             =head4 zconf
45              
46             This is a zconf object to use instead of initiating a new one.
47              
48             my $zcr=ZConf::Runner->new();
49             if($zcr->{error}){
50             print "Error!\n";
51             }
52              
53             =cut
54              
55             sub new{
56 0     0 1   my %args;
57 0 0         if(defined($_[1])){
58 0           %args= %{$_[1]};
  0            
59             }
60 0           my $function='new';
61              
62 0           my $self={error=>undef, errorString=>undef, module=>'ZConf-Runner', perror=>undef};
63 0           bless $self;
64              
65 0 0         if (!defined($args{zconf})) {
66             #creates the ZConf object
67 0           $self->{zconf}=ZConf->new(%{$args{zconfargs}});
  0            
68 0 0         if(defined($self->{zconf}->{error})){
69 0           $self->{error}=1;
70 0           $self->{perror}=1;
71 0           $self->{errorString}="Could not initiate ZConf. It failed with '"
72             .$self->{zconf}->{error}."', '".
73             $self->{zconf}->{errorString}."'";
74 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
75 0           return $self;
76             }
77             }else {
78 0           $self->{zconf}=$args{zconf};
79             }
80              
81             #make sure it exists
82 0           my $returned = $self->{zconf}->configExists('runner');
83             #if we can't do this we definitely can't continue
84 0 0         if ($self->{zconf}->{error}) {
85 0           $self->{error}=2;
86 0           $self->{perror}=1;
87 0           $self->{errorString}='Could not verify if "runner" exists or not. ZConf error="'.
88             $self->{zconf}->{error}.'" ZConf errorString="'.
89             $self->{zconf}->{errorString}.'"';
90 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
91 0           return $self;
92             }
93              
94             #create the config if it has not been initialized yet.
95 0 0         if (!$returned) {
96 0           $self->{zconf}->createConfig('runner');
97 0 0         if ($self->{zconf}->{error}) {
98 0           $self->{error}=3;
99 0           $self->{perror}=1;
100 0           $self->{errorString}='Could not create the ZConf config "runner". ZConf error with "'.
101             $self->{zconf}->{error}.'" ZConf errorString="'.
102             $self->{zconf}->{errorString}.'"';
103 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
104 0           return $self;
105             }
106             }
107              
108             #create the new set if needed
109 0           $returned=$self->{zconf}->defaultSetExists('runner');
110 0 0         if (!$returned) {
111             #
112 0           $self->{zconf}->writeSetFromHash({config=>'runner'}, {});
113 0 0         if ($self->{zconf}->{error}) {
114 0           $self->{error}=2;
115 0           $self->{perror}=1;
116 0           $self->{errorString}='ZConf error. error="'.$self->{zconf}->{error}.'" '.
117             ' errorString="'.$self->{zconf}->{errorString}.'"';
118 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
119 0           return $self;
120             }
121             }
122              
123             #
124 0           $self->{zconf}->read({config=>'runner'});
125 0 0         if ($self->{zconf}->{error}) {
126 0           $self->{error}=2;
127 0           $self->{perror}=1;
128 0           $self->{errorString}='ZConf error. error="'.$self->{zconf}->{error}.'" '.
129             ' errorString="'.$self->{zconf}->{errorString}.'"';
130 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
131 0           return $self;
132             }
133            
134 0           return $self;
135             }
136              
137             =head2 actionIsSetup
138              
139             This checks to see if a specific action is setup for a mimetype.
140              
141             Two arguements are accepted. The first is the mimetype. The
142             second is the action.
143              
144             my $mimetype='image/jpeg';
145             my $returned=$zcr->actionIsSetup($mimetype, 'edit');
146             if($zcr->{error}){
147             print "Error!\n";
148             if($zcr->{error} eq '7'){
149             print "Mimetype is not setup.\n";
150             }
151             }
152             if($returned){
153             print $mimtetype." is configured already";
154             }
155              
156             =cut
157              
158             sub actionIsSetup{
159 0     0 1   my $self=$_[0];
160 0           my $mimetype=$_[1];
161 0           my $action=$_[2];
162 0           my $function='acionIsSetup';
163              
164             #blanks any previous errors
165 0           $self->errorBlank;
166 0 0         if ($self->{error}) {
167 0           return undef;
168             }
169              
170             #makes sure a mimetype to check for is specified.
171 0 0         if (!defined($mimetype)) {
172 0           $self->{error}=4;
173 0           $self->{errorString}='No mimetype specified';
174 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
175 0           return undef;
176             }
177              
178             #makes sure a action to check for is specified.
179 0 0         if (!defined($action)) {
180 0           $self->{error}=4;
181 0           $self->{errorString}='No action specified';
182 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
183 0           return undef;
184             }
185              
186 0 0         if (!$self->validActionName($action)) {
187 0           $self->{error}=5;
188 0           $self->{errorString}='"'.$action.'" is not a valid action name';
189 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
190             }
191              
192             #check to make sure the mimetype is setup
193 0           my $returned=$self->mimetypeIsSetup($mimetype);
194             #return if it errored
195 0 0         if ($self->{error}) {
196 0           warn('ZConf-Runner actionIsSetup: mimetypeIsSetup errored');
197 0           return undef;
198             }
199              
200             #return if it if the mimetype is not setup
201 0 0         if (!$returned) {
202 0           $self->{error}=7;
203 0           $self->{errorString}='"'.$mimetype.'" is not setup';
204 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
205 0           return undef;
206             }
207              
208             #gets the list of actions
209 0           my @actions=$self->listActions($mimetype);
210             #return if the previous funtion errored
211 0 0         if ($self->{error}) {
212 0           warn('ZConf-Runner actionIsSetup: listActions failed');
213 0           return undef;
214             }
215              
216             #runs through the list and return true if it is found
217 0           my $int=0;
218 0           while (defined($actions[$int])) {
219             #if it is found it is setup and thus return true
220 0 0         if ($actions[$int] eq $action) {
221 0           return 1;
222             }
223              
224 0           $int++;
225             }
226              
227             #if we get here, it has not been found
228 0           return undef;
229            
230             }
231              
232             =head2 ask
233              
234             This is creates a Curses::UI asking what to do.
235              
236             The first agruement is the action to be performed. The
237             second is the file it is to be performed on. The third
238             is an optional hash. It's accepted keys are as below.
239              
240             my $returned=$zcr->ask('view', '/tmp/test.rdf', {useX=>0});
241             if($zcr->{error}){
242             print "Error!\n";
243             }else{
244             if($returned){
245             print "Action setup.\n";
246             }
247             }
248              
249             =cut
250              
251             sub ask{
252 0     0 1   my $self=$_[0];
253 0           my $action=$_[1];
254 0           my $object=$_[2];
255 0           my %args;
256 0 0         if (defined($_[3])) {
257 0           %args= %{$_[3]};
  0            
258             }
259 0           my $function='ask';
260              
261             #blanks any previous errors
262 0           $self->errorBlank;
263 0 0         if ($self->{error}) {
264 0           return undef;
265             }
266              
267             #gets the mimetype for the object
268 0           my $mimetype=mimetype($object);
269              
270             #this makes sure we got a mimetype
271 0 0         if (!defined($mimetype)) {
272 0           $self->{error}=12;
273 0           $self->{errorString}='Could not determime the mimetype for "'.$object.'"';
274 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
275 0           return undef;;
276             }
277              
278             #figures out if it should use X or not if it is not set
279 0 0         if (!defined($args{useX})) {
280 0           $args{useX}=$self->Xavailable();
281             }else {
282             #if it is already set to true, see if it can be used
283 0 0         if ($args{useX}) {
284 0           $args{useX}=$self->Xavailable();
285             }
286             }
287              
288 0           my $terminal='xterm -rv -e ';
289             #if the enviromental variable 'TERMINAL' is set, use
290 0 0         if(defined($ENV{TERMINAL})){
291 0           $terminal=$ENV{TERMINAL};
292             }
293              
294             #escapes it for executing it
295 0           my $eAction=$action;
296 0           $eAction=~s/\"/\\\"/g;
297 0           my $eObject=$object;
298 0           $eObject=~s/\"/\\\"/g;
299              
300 0           my $askcommand='perl -e \'use ZConf::Runner; my $zcr=ZConf::Runner->new(); '.
301             '$zcr->askGUI("'.$eAction.'", "'.$eObject.'");\'';
302              
303 0 0         if ($args{useX}) {
304 0           system($terminal.' '.$askcommand);
305 0 0         if ($? == -1) {
306 0           $self->{error}=15;
307 0           $self->{errorString}="Failed to '".$terminal.' '.$askcommand."'";
308 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
309 0           return undef;
310             }
311              
312             #we reread it to get any changes
313 0           $self->{zconf}->read({config=>'runner'});
314 0 0         if ($self->{zconf}->{error}) {
315 0           warn('ZConf-Runner ask:2: ZConf errored with "'.$self->{zconf}->{error}.
316             '" when trying to reread the ZConf config "runner". errorString="'.
317             $self->{zconf}->{errorString}.'"');
318 0           return undef;
319             }
320              
321 0           my $returned=$self->actionIsSetup($mimetype, $action);
322 0 0         if ($self->{error}) {
323 0           warn('ZConf-Runner ask: actionIsSetup("'.$mimetype.'", "'
324             .$action.'") failed');
325 0           return undef;
326             }
327              
328             #we just assume yes was pushed right now as it is impossible to get
329             #the exit status from something executed using xterm
330 0           return $returned;
331             }else {
332 0           system($askcommand);
333 0           my $exitcode=$? >> 8;
334 0 0         if ($? == -1) {
335 0           $self->{error}=15;
336 0           $self->{errorString}="Failed to '".$askcommand."'";
337 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
338 0           return undef;
339             }
340              
341             #if Quit was selected, just return undef, but don't error
342 0 0         if ($exitcode == 14) {
343 0           return undef;
344             }
345              
346             #if ok was selected and it added with out issue
347 0 0         if ($exitcode == 15) {
348 0           return 1;
349             }
350              
351             #if we get here, it means we errored
352 0           $self->{error}=16;
353 0           $self->{errorString}="'".$askcommand."' failed with a exit of '".$exitcode."'";
354 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
355 0           return undef;
356             }
357              
358             }
359              
360             =head2 do
361              
362             This runs takes an file and runs it.
363              
364             The first agruement is the action to be performed.
365              
366             The second is the file it is to be performed on.
367              
368             The third is an optional hash. It's accepted keys are as below.
369              
370             =head3 args hash
371              
372             still needs implemented
373              
374             =head4 exec
375              
376             If this is set to true, exec is used instead of system.
377              
378             =head4 ask
379              
380             If this is set to true, it will
381              
382             =cut
383              
384             sub do{
385 0     0 1   my $self=$_[0];
386 0           my $action=$_[1];
387             #I am calling this variable object as I could not choose a name.
388             #Right now I am just doing files, but I plan to implement URL handling
389             #at some point in time.
390 0           my $object=$_[2];
391 0           my %args;
392 0 0         if (defined($_[3])) {
393 0           %args= %{$_[3]};
  0            
394             }
395 0           my $function='do';
396              
397             #blanks any previous errors
398 0           $self->errorBlank;
399 0 0         if ($self->{error}) {
400 0           return undef;
401             }
402              
403             #makes sure a object to operate on is specified.
404 0 0         if (!defined($object)) {
405 0           $self->{error}=4;
406 0           $self->{errorString}='No object specified';
407 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
408 0           return undef;
409             }
410              
411             #if ask is not defined, set it to ask be default
412 0 0         if (!defined($args{ask})) {
413 0           $args{ask}=1;
414             }
415              
416             #set it to use system instead of exec by default
417 0 0         if (!defined($args{exec})) {
418 0           $args{exec}=0;
419             }
420              
421             #makes sure an action is specified.
422 0 0         if (!defined($action)) {
423 0           $self->{error}=4;
424 0           $self->{errorString}='No action specified';
425 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
426 0           return undef;
427             }
428              
429             #gets the mimetype for the object
430 0           my $mimetype=mimetype($object);
431              
432             #this makes sure we got a mimetype
433 0 0         if (!defined($mimetype)) {
434 0           $self->{error}=12;
435 0           $self->{errorString}='Could not determime the mimetype for "'.$object.'"';
436 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
437 0           return undef;
438             }
439              
440 0           my $returned=$self->validAction($mimetype, $action);
441 0 0         if ($self->{error}) {
442             #if it is set to ask,
443 0 0         if (!$args{ask}) {
444 0           warn('ZConf-Runner do:12: validAction("'.$mimetype.'", "'.$action.'") errored');
445 0           return undef;
446             }
447 3     3   1380 use ZConf::Runner::GUI;
  3         24  
  3         22416  
448 0           $self->errorBlank;
449 0           my $zcrg=ZConf::Runner::GUI->new({zcrunner=>$self, zconf=>$self->{zconf}});
450 0 0         if ($zcrg->{error}){
451 0           my $error='ZConf::Runner::GUI->new errored. error="'.
452             $zcrg->{error}.'" errorString="'.$zcrg->{errorString}.'"';
453 0           $self->{error}=18;
454 0           $self->{errorString}=$error;
455 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
456 0           return undef;
457             }
458 0           $returned=$zcrg->ask({object=>$object, action=>$action});
459 0 0         if (!$returned) {
460 0           warn('ZConf-Runner do: $zcrg->ask({ action=>"'.$action.'", object=>"'.$object.
461             '" }) failed or user quit it');
462 0           return undef;
463             }
464             }
465              
466             #this is the base name for the the variables
467 0           my $baseVar='mimetypes/'.$mimetype.'/'.$action.'/';
468              
469             #gets the variables for the action
470 0           my %vars=$self->{zconf}->regexVarGet('runner', '^'.$baseVar);
471 0 0         if($self->{zconf}->{error}){
472 0           $self->{error}=1;
473 0           $self->{errorString}='ZConf error when doing regexVarGet for "^'.$baseVar
474             .'". ZConf error="'.$self->{zconf}->{error}.'" '.
475             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
476 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
477 0           return undef;
478             }
479              
480 0           my $type=$vars{$baseVar.'type'};
481 0           my $do=$vars{$baseVar.'do'};
482              
483             #
484 0 0         if ($type eq 'exec') {
485             #make the object safe to exchange with %f
486 0           my $sobject=shell_quote($object);
487              
488             #replace %f with the file
489 0           $do=~s/\%f/$sobject/g;
490              
491 0           print "\n\n".$do."\n\n";
492            
493 0 0         if($args{exec}){
494 0           exec($do);
495             }else {
496 0           system($do);
497             }
498 0           return 1;
499             }
500              
501             #
502 0 0         if ($type eq 'desktop') {
503             #verify it is a good desktop entry
504 0 0         if (!$self->validDesktopEntry($do)) {
505 0           $self->{error}=13;
506 0           $self->{errorString}='$entry->lookup("'.$do.'") failed';
507 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
508 0           return undef;
509             }
510              
511             #We trust this should work as the check above worked.
512 0           my $entry = File::DesktopEntry->new($do);
513              
514 0           $entry->system($object);
515             }
516 0           return 1;
517             }
518              
519             =head2 getAction
520              
521             This fetches an action for a mimetype and returns the do and type
522             as an hash.
523              
524             The are two required arguements. The first is the mimetype and the
525             second is the action.
526              
527             my %action=$zcr->getAction('application/vnd.oasis.opendocument.text', 'view');
528             if($zcr->{error}){
529             print "Error!\n";
530             }else{
531             print "do: '".$action{do}."'\n".
532             "type: '".$action{type}."'\n";
533             }
534              
535             =cut
536              
537             sub getAction{
538 0     0 1   my $self=$_[0];
539 0           my $mimetype=$_[1];
540 0           my $action=$_[2];
541 0           my $function='getAction';
542              
543 0           $self->errorBlank;
544 0 0         if ($self->{error}) {
545 0           return undef;
546             }
547              
548              
549 0 0         if (!defined($self->validAction($mimetype, $action))) {
550             #we don't need to set any errors or etc here as validAction will
551 0           warn('ZConf-Runner getAction: validAction errored errored.');
552 0           return undef;
553             }
554              
555             #this is the base name for the the variables
556 0           my $baseVar='mimetypes/'.$mimetype.'/'.$action.'/';
557              
558             #We don't need to check the error here as it will be fine if validAction
559             #uses this exact same function and will error on it.
560             #gets the variables for it
561 0           my %vars=$self->{zconf}->regexVarGet('runner', '^'.$baseVar);
562              
563             #
564 0           my %returnH;
565 0           $returnH{do}=$vars{$baseVar.'do'};
566 0           $returnH{type}=$vars{$baseVar.'type'};
567              
568 0           return %returnH;
569             }
570              
571             =head2 getSet
572              
573             This gets what the current set is.
574              
575             my $set=$zcr->getSet;
576             if($zcr->{error}){
577             print "Error!\n";
578             }
579              
580             =cut
581              
582             sub getSet{
583 0     0 1   my $self=$_[0];
584 0           my $function='getSet';
585              
586 0           $self->errorBlank;
587 0 0         if ($self->{error}) {
588 0           return undef;
589             }
590              
591 0           my $set=$self->{zconf}->getSet('runner');
592 0 0         if($self->{zconf}->{error}){
593 0           $self->{error}=2;
594 0           $self->{errorString}='ZConf error getting the loaded set the config "runner".'.
595             ' ZConf error="'.$self->{zconf}->{error}.'" '.
596             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
597 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
598 0           return undef;
599             }
600              
601 0           return $set;
602             }
603              
604             =head2 listActions
605              
606             This gets a list of actions for a specific mimetype.
607              
608             There is one required arguement and it is the mimetype.
609              
610             my @actions=$zcr->listActions('application/vnd.oasis.opendocument.text');
611             if($zcr->{error}){
612             print "Error!\n";
613             }
614              
615             =cut
616              
617             sub listActions{
618 0     0 1   my $self=$_[0];
619 0           my $mimetype=$_[1];
620 0           my $function='listActions';
621              
622             #blanks any previous errors
623 0           $self->errorBlank;
624 0 0         if ($self->{error}) {
625 0           return undef;
626             }
627              
628             #makes sure a type to check for is specified.
629 0 0         if (!defined($mimetype)) {
630 0           $self->{error}=4;
631 0           $self->{errorString}='No mimetype specified to get actions for.';
632 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
633 0           return undef;
634             }
635              
636             #makes sure the mimetype is setup
637 0           my $returned=$self->mimetypeIsSetup($mimetype);
638 0 0         if ($self->{error}) {
639 0           warn('ZConf-Runner listActions: mimetypeIsSetup("'.$mimetype.'") errored');
640 0           return undef;
641             }
642              
643             #error if the mimetype is not setup
644 0 0         if (!$returned) {
645 0           $self->{error}=7;
646 0           $self->{errorString}='Mimetype "'.$mimetype.'" is not setup';
647 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
648 0           return undef;
649             }
650              
651             #finds any thing under 'mimetypes/'.$mimetype.'/'
652 0           my @actionSearch=$self->{zconf}->regexVarSearch('runner', '^mimetypes/'.$mimetype.'/');
653 0 0         if($self->{zconf}->{error}){
654 0           $self->{error}=1;
655 0           $self->{errorString}=' ZConf error when searching for vars matching'.
656             ' "^mimetypes/". ZConf error="'.$self->{zconf}->{error}.'" '.
657             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
658 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
659 0           return undef;
660             }
661              
662             #
663 0           my $int=0;
664             #the types are stored as an hash
665 0           my %actions;
666 0           while (defined($actionSearch[$int])) {
667             #splits the ZConf string apart
668 0           my @actionA=split(/\//, $actionSearch[$int]);
669             #puts the split back together
670             #0='mimtetypes'
671             #1=type
672             #2=subtype
673             #3=action
674             #4='do' or 'type'
675 0           my $action=$actionA[3];
676              
677 0           $actions{$action}=$action;
678            
679 0           $int++;
680             }
681              
682             #returns an array of the hash keys
683 0           return keys(%actions);
684             }
685              
686             =head2 listMimetypes
687              
688             This fetches a list of currently setup mimetypes.
689              
690             The are no arguements for this.
691              
692             my @mimetypes=$zcr->listMimetypes();
693             if($zcr->{error}){
694             print "Error!\n";
695             }
696              
697             =cut
698              
699             sub listMimetypes{
700 0     0 1   my $self=$_[0];
701 0           my $function='listMimetypes';
702              
703             #blanks any previous errors
704 0           $self->errorBlank;
705 0 0         if ($self->{error}) {
706 0           return undef;
707             }
708              
709             #
710 0           my @mimetypes=$self->{zconf}->regexVarSearch('runner', '^mimetypes/');
711 0 0         if($self->{zconf}->{error}){
712 0           $self->{error}=1;
713 0           $self->{errorString}=' ZConf error when searching for vars matching'.
714             ' "^mimetypes/". ZConf error="'.$self->{zconf}->{error}.'" '.
715             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
716 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
717 0           return undef;
718             }
719              
720             #
721 0           my $mimetypesInt=0;
722             #the types are stored as an hash
723 0           my %mimehash;
724 0           while (defined($mimetypes[$mimetypesInt])) {
725             #splits the ZConf string apart
726 0           my @mtA=split(/\//, $mimetypes[$mimetypesInt]);
727             #puts the split back together
728             #0='mimtetypes'
729             #1=type
730             #2=subtype
731             #3=action
732             #4='do' or 'type'
733 0           my $mt=$mtA[1].'/'.$mtA[2];
734              
735 0           $mimehash{$mt}=$mt;
736            
737 0           $mimetypesInt++;
738             }
739              
740             #returns an array of the hash keys
741 0           return keys(%mimehash);
742             }
743              
744             =head2 listSets
745              
746             This lists the available sets.
747              
748             my @sets=$zcr->listSets;
749             if($zcr->{error}){
750             print "Error!";
751             }
752              
753             =cut
754              
755             sub listSets{
756 0     0 1   my $self=$_[0];
757 0           my $function='listSets';
758              
759             #blanks any previous errors
760 0           $self->errorBlank;
761 0 0         if ($self->{error}) {
762 0           return undef;
763             }
764              
765 0           my @sets=$self->{zconf}->getAvailableSets('runner');
766 0 0         if($self->{zconf}->{error}){
767 0           $self->{error}=2;
768 0           $self->{errorString}='ZConf error listing sets for the config "runner".'.
769             ' ZConf error="'.$self->{zconf}->{error}.'" '.
770             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
771 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
772 0           return undef;
773             }
774              
775 0           return @sets;
776             }
777              
778             =head2 newRunner
779              
780             This creates a new runner. The only required arguement
781             is an hash. Please see the section below for the required
782             hash values.
783              
784             =head3 hash args
785              
786             =head4 mimetype
787              
788             This is the mimetype for the new runner.
789              
790             =head4 action
791              
792             This action that will be done.
793              
794             =head4 type
795              
796             This is either 'exec' or 'desktop'.
797              
798             =head4 do
799              
800             If the 'exec' is specified as the type the specified program is used to run it. '%f' will
801             be replaced by the filename when it is ran.
802              
803             If the 'desktop' is specified as the type 'File::MimeInfo::Applications' is used to run it.
804              
805             $zcr->newRunner({mimetye=>'application/pdf', action=>'view', type=>'exec', do=>'xpdf %f'})
806             if($zcr->{error}){
807             print "Error!\n";
808             }
809              
810             =cut
811              
812             sub newRunner{
813 0     0 1   my $self=$_[0];
814 0           my %args;
815 0 0         if(defined($_[1])){
816 0           %args= %{$_[1]};
  0            
817             }
818 0           my $function='newRunner';
819              
820             #blanks any previous errors
821 0           $self->errorBlank;
822 0 0         if ($self->{error}) {
823 0           return undef;
824             }
825              
826             #the required arguements
827 0           my @reqArgs=('mimetype', 'action', 'type', 'do');
828              
829             #makes sure they are all defined
830 0           my $reqArgsInt=0;
831 0           while (defined($reqArgs[$reqArgsInt])) {
832             #error if it is not defined
833 0 0         if (!defined($args{$reqArgs[$reqArgsInt]})) {
834 0           warn('ZConf-Runner newRunner:4: The arg "'.
835             $reqArgs[$reqArgsInt].'" is not defined.');
836 0           $self->{error}=4;
837 0           $self->{errorString}='The arg "'.$reqArgs[$reqArgsInt].'" is not defined.';
838 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
839 0           return undef;
840             }
841              
842 0           $reqArgsInt++;
843             }
844              
845             #make type is a legit value
846 0 0 0       if ((!$args{type} eq 'desktop') && (!$args{type} eq 'exec')) {
847 0           $self->{error}=6;
848 0           $self->{errorString}='Type is not equal to "desktop" or "exec"';
849 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
850 0           return undef;
851             }
852              
853             #makes sure that the action is a valid name
854 0 0         if (!$self->validActionName($args{action})) {
855 0           $self->{error}=5;
856 0           $self->{errorString}='"'.$args{action}.'" is not a valid name';
857 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
858 0           return undef;
859             }
860              
861             #sets the type
862 0           $self->{zconf}->setVar('runner', 'mimetypes/'.$args{mimetype}.'/'.
863             $args{action}.'/type', $args{type});
864 0 0         if($self->{zconf}->{error}){
865 0           $self->{error}=1;
866 0           $self->{errorString}='ZConf error when writing the config "runner".'.
867             ' ZConf error="'.$self->{zconf}->{error}.'" '.
868             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
869 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
870 0           return undef;
871             }
872              
873             #sets the do
874 0           $self->{zconf}->setVar('runner', 'mimetypes/'.$args{mimetype}.'/'.
875             $args{action}.'/do', $args{do});
876 0 0         if($self->{zconf}->{error}){
877 0           $self->{error}=1;
878 0           $self->{errorString}='ZConf error when writing the config "runner".'.
879             ' ZConf error="'.$self->{zconf}->{error}.'" '.
880             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
881 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
882 0           return undef;
883             }
884              
885             #writes it
886 0           $self->{zconf}->writeSetFromLoadedConfig({config=>'runner'});
887 0 0         if($self->{zconf}->{error}){
888 0           $self->{error}=1;
889 0           $self->{errorString}='ZConf error when writing the config "runner".'.
890             ' ZConf error="'.$self->{zconf}->{error}.'" '.
891             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
892 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
893 0           return undef;
894             }
895              
896              
897 0           return 1;
898             }
899              
900             =head2 mimetypeIsSetup
901              
902             This checks if a mimetype has been setup already. One arguement
903             is accepted. It is a string containing the name of mimetype.
904              
905             my $mimetype='image/jpeg';
906             my $returned=$zcr->mimetypeIsSetup($mimetype);
907             if($zcr->{error}){
908             print "Error!\n";
909             }
910             if($returned){
911             print $mimtetype." is configured already";
912             }
913              
914             =cut
915              
916             sub mimetypeIsSetup{
917 0     0 1   my $self=$_[0];
918 0           my $mimetype=$_[1];
919 0           my $function='mimetypeIsSetup';
920              
921             #blanks any previous errors
922 0           $self->errorBlank;
923 0 0         if ($self->{error}) {
924 0           return undef;
925             }
926              
927             #makes sure a type to check for is specified.
928 0 0         if (!defined($mimetype)) {
929 0           $self->{error}=4;
930 0           $self->{errorString}='No mimetype specified';
931 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
932 0           return undef;
933             }
934              
935             #gets the list of mimetypes
936 0           my @mimetypes=$self->listMimetypes();
937             #return if the previous funtion errored
938 0 0         if ($self->{error}) {
939 0           warn('ZConf-Runner mimetypeIsSetup: listMimetypes failed');
940 0           return undef;
941             }
942              
943             #runs through the list and return true if it is found
944 0           my $int=0;
945 0           while (defined($mimetypes[$int])) {
946             #if it is found it is setup and thus return true
947 0 0         if ($mimetypes[$int] eq $mimetype) {
948 0           return 1;
949             }
950              
951 0           $int++;
952             }
953              
954             #if we get here, it has not been found
955 0           return undef;
956             }
957              
958             =head2 readSet
959              
960             This reads a specific set. If the set specified
961             is undef, the default set is read.
962              
963             #read the default set
964             $zcr->readSet();
965             if($zcr->{error}){
966             print "Error!\n";
967             }
968              
969             #read the set 'someSet'
970             $zcr->readSet('someSet');
971             if($zcr->{error}){
972             print "Error!\n";
973             }
974              
975             =cut
976              
977             sub readSet{
978 0     0 1   my $self=$_[0];
979 0           my $set=$_[1];
980 0           my $function='readSet';
981            
982             #blanks any previous errors
983 0           $self->errorBlank;
984 0 0         if ($self->{error}) {
985 0           return undef;
986             }
987              
988 0           $self->{zconf}->read({config=>'runner', set=>$set});
989 0 0         if ($self->{zconf}->{error}) {
990 0           $self->{error}=2;
991 0           $self->{errorString}='ZConf error reading the config "runner".'.
992             ' ZConf error="'.$self->{zconf}->{error}.'" '.
993             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
994 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
995 0           return undef;
996             }
997              
998 0           return 1;
999             }
1000              
1001             =head2 removeAction
1002              
1003             This removes an action for a mimetype.
1004              
1005             Two arguements are required. The first is the mimetype and
1006             the second is the action.
1007              
1008             $zcr->removeAction('application/pdf', 'view');
1009             if($self->{error}){
1010             print "Error!\n";
1011             }
1012              
1013             =cut
1014              
1015             sub removeAction{
1016 0     0 1   my $self=$_[0];
1017 0           my $mimetype=$_[1];
1018 0           my $action=$_[2];
1019 0           my $function='removeAction';
1020              
1021             #blanks any previous errors
1022 0           $self->errorBlank;
1023 0 0         if ($self->{error}) {
1024 0           return undef;
1025             }
1026              
1027             #makes sure a mimetype to check for is specified.
1028 0 0         if (!defined($mimetype)) {
1029 0           $self->{error}=4;
1030 0           $self->{errorString}='No mimetype specified';
1031 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1032 0           return undef;
1033             }
1034              
1035             #makes sure a action to check for is specified.
1036 0 0         if (!defined($action)) {
1037 0           $self->{error}=4;
1038 0           $self->{errorString}='No action specified';
1039 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1040 0           return undef;
1041             }
1042              
1043             #this is the base name for the the variables
1044 0           my $baseVar='mimetypes/'.$mimetype.'/'.$action.'/';
1045              
1046             #We don't need to check the error here as it will be fine if validAction
1047             #uses this exact same function and will error on it.
1048             #gets the variables for it
1049 0           my %vars=$self->{zconf}->regexVarDel('runner', '^'.$baseVar);
1050 0 0         if ($self->{zconf}->{error}) {
1051 0           $self->{error}=2;
1052 0           $self->{errorString}='ZConf error for '.
1053             '$self->{zconf}->regexVarDel("runner", "^'.$baseVar.'). '.
1054             ' ZConf error="'.$self->{zconf}->{error}.'" '.
1055             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
1056 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1057 0           return undef;
1058             }
1059              
1060             #writes it
1061 0           $self->{zconf}->writeSetFromLoadedConfig({config=>'runner'});
1062 0 0         if($self->{zconf}->{error}){
1063 0           $self->{error}=2;
1064 0           $self->{errorString}='ZConf error when writing the config "runner".'.
1065             ' ZConf error="'.$self->{zconf}->{error}.'" '.
1066             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
1067 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1068 0           return undef;
1069             }
1070              
1071 0           return 1;
1072             }
1073              
1074             =head2 validAction
1075              
1076             This makes sure an action is valid. See the error code
1077             for the reason it is not valid.
1078              
1079             $zcr->validAction('application/pdf', 'view');
1080             if($self->{error}){
1081             print 'Error:'.$self->{error}.': Action is not valid';
1082             }
1083              
1084             =cut
1085              
1086             sub validAction{
1087 0     0 1   my $self=$_[0];
1088 0           my $mimetype=$_[1];
1089 0           my $action=$_[2];
1090 0           my $function='validAction';
1091              
1092             #blanks any previous errors
1093 0           $self->errorBlank;
1094 0 0         if ($self->{error}) {
1095 0           return undef;
1096             }
1097              
1098             #makes sure a mimetype to check for is specified.
1099 0 0         if (!defined($mimetype)) {
1100 0           $self->{error}=4;
1101 0           $self->{errorString}='No mimetype specified';
1102 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1103 0           return undef;
1104             }
1105              
1106             #makes sure a action to check for is specified.
1107 0 0         if (!defined($action)) {
1108 0           $self->{error}=4;
1109 0           $self->{errorString}='No action specified';
1110 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1111 0           return undef;
1112             }
1113              
1114             #we don't need to check if the mimetype is setup as the following will do it as well
1115             #check if the action is setup
1116 0           my $returned=$self->actionIsSetup($mimetype, $action);
1117 0 0         if ($self->{error}) {
1118 0           warn('ZConf-Runner validAction: actionIsSetup("'.$mimetype.'","'.$action.'") errored');
1119 0           return undef;
1120             }
1121              
1122             #if it is false then the action is not setup
1123 0 0         if (!$returned) {
1124 0           $self->{error}=8;
1125 0           $self->{errorString}='"'.$action.'" is not configured';
1126 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1127 0           return undef;
1128             }
1129              
1130             #this is the base name for the the variables
1131 0           my $baseVar='mimetypes/'.$mimetype.'/'.$action.'/';
1132              
1133             #gets the variables for it
1134 0           my %vars=$self->{zconf}->regexVarGet('runner', '^'.$baseVar);
1135 0 0         if($self->{zconf}->{error}){
1136 0           $self->{error}=1;
1137 0           $self->{errorString}='ZConf error when doing regexVarGet for "^'.$baseVar
1138             .'". ZConf error="'.$self->{zconf}->{error}.'" '.
1139             'ZConf error string="'.$self->{zconf}->{errorString}.'"';
1140 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1141 0           return undef;
1142             }
1143              
1144             #makes sure type is defined
1145 0 0         if (!defined($vars{$baseVar.'type'})) {
1146 0           $self->{error}=9;
1147 0           $self->{errorString}='"'.$baseVar.'type" is not defined';
1148 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1149 0           return undef;
1150             }
1151              
1152             #make sure type is a valid value
1153 0 0 0       if (($vars{$baseVar.'type'} ne 'exec') &&
1154             ($vars{$baseVar.'type'} ne 'desktop')) {
1155 0           $self->{error}=10;
1156 0           $self->{errorString}='"'.$baseVar.'type" is not a valid type';
1157 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1158 0           return undef;
1159             }
1160              
1161             #makes sure type is defined
1162 0 0         if (!defined($vars{$baseVar.'do'})) {
1163 0           $self->{error}=11;
1164 0           $self->{errorString}='"'.$baseVar.'do" is not defined';
1165 0           warn($self->{module}.' '.$function.':'.$self->{error}.': '.$self->{errorString});
1166 0           return undef;
1167             }
1168              
1169 0           return 1;
1170             }
1171              
1172             =head2 validActionName
1173              
1174             This makes sure that the action name is valid.
1175              
1176             There is no reason to ever check $zcr->{error} with
1177             this as this function will not set it. It just returns
1178             a boolean value.
1179              
1180             if($zcr->validActionName('some/test')){
1181             print "Error\n";
1182             }
1183              
1184             =cut
1185              
1186             sub validActionName{
1187 0     0 1   my $self=$_[0];
1188 0           my $name=$_[1];
1189 0           my $function='validActionName';
1190              
1191 0           $self->errorBlank;
1192 0 0         if ($self->{error}) {
1193 0           return undef;
1194             }
1195              
1196             #Makes sure it does not contain any forward slashes.
1197 0 0         if ($name =~ /\//) {
1198 0           return undef;
1199             }
1200              
1201             #Makes sure it does not begin with any spaces.
1202 0 0         if ($name =~ /^ /) {
1203 0           return undef;
1204             }
1205              
1206             #Makes sure it does not end with any spaces.
1207 0 0         if ($name =~ / $/) {
1208 0           return undef;
1209             }
1210              
1211 0           return 1;
1212             }
1213              
1214             =head2 validDesktopEntry
1215              
1216             This checks to see if a desktop entry is valid. One value is accept
1217             and that is file id name.
1218              
1219             There is no reason to ever check $zcr->{error} with
1220             this as this function will not set it. It just returns
1221             a boolean value.
1222              
1223             if($zcr->validDesktopEntry('xemacs')){
1224             print "xeamcs is not a valid desktop entry\n";
1225             }
1226              
1227             =cut
1228              
1229             sub validDesktopEntry{
1230 0     0 1   my $self=$_[0];
1231 0           my $app=$_[1];
1232 0           my $function='validDesktopEntry';
1233              
1234 0           $self->errorBlank;
1235 0 0         if ($self->{error}) {
1236 0           return undef;
1237             }
1238              
1239             #we don't pass any thing to new to prevent it from erroring...
1240             #File::DesktopEntry is buggy and will exit upon a failure in the new function...
1241             #fragging annoying...
1242 0           my $entry = File::DesktopEntry->new();
1243              
1244             #If it is defined it the entry exists.
1245 0           my $returned=$entry->lookup($app);
1246              
1247             #if it is defined, then an entry exists
1248 0 0         if (defined($returned)) {
1249 0           return 1
1250             }
1251              
1252 0           return undef;
1253             }
1254              
1255             =head2 Xavailable
1256              
1257             This checks if X is available. This is checked for by trying to run
1258             'xhost > /dev/null' and is assumed if a non-zero exit code is returned
1259             then it failed and thus X is not available.
1260              
1261             There is no reason to ever check $zcr->{error} with
1262             this as this function will not set it. It just returns
1263             a boolean value.
1264              
1265             if($zcr->Xavailable()){
1266             print "X is available\n";
1267             }
1268              
1269             =cut
1270              
1271             sub Xavailable{
1272 0     0 1   my $self=$_[0];
1273 0           my $function='Xavailable';
1274              
1275 0           $self->errorBlank;
1276 0 0         if ($self->{error}) {
1277 0           return undef;
1278             }
1279              
1280             #exists non-zero if it fails
1281 0           system('xhost > /dev/null');
1282             #if xhost exits with a non-zero then X is not available
1283 0           my $exitcode=$? >> 8;
1284 0 0         if ($exitcode ne '0'){
1285 0           return undef;
1286             }
1287              
1288 0           return 1;
1289             }
1290              
1291             =head2 errorBlank
1292              
1293             This blanks the error storage and is only meant for internal usage.
1294              
1295             It does the following.
1296              
1297             $self->{error}=undef;
1298             $self->{errorString}="";
1299              
1300             =cut
1301              
1302             #blanks the error flags
1303             sub errorBlank{
1304 0     0 1   my $self=$_[0];
1305 0           my $function='errorBlank';
1306              
1307 0 0         if ($self->{perror}) {
1308 0           warn($self->{error}.' '.$function.': A permanent error is set. error="'.
1309             $self->{error}.'" errorString="'.$self->{errorSting}.'"');
1310 0           return undef;
1311             }
1312              
1313 0           $self->{error}=undef;
1314 0           $self->{errorString}="";
1315              
1316 0           return 1;
1317             }
1318              
1319             =head1 ERROR CODES
1320              
1321             The error code is contianed in $zcr->{error} and a extended description can be
1322             found in $zcr->{errorString}. If any module ever sets $zcr->{perror} then the error
1323             is permanent and none of the methods are usable.
1324              
1325             =head2 1
1326              
1327             Could not initialize ZConf.
1328              
1329             =head2 2
1330              
1331             ZConf error.
1332              
1333             =head2 3
1334              
1335             Failed to create the ZConf config 'runner'.
1336              
1337             =head2 4
1338              
1339             Missing function arguements.
1340              
1341             =head2 5
1342              
1343             Invalid action name.
1344              
1345             =head2 6
1346              
1347             Invalid type.
1348              
1349             =head2 7
1350              
1351             Mimetype not configured.
1352              
1353             =head2 8
1354              
1355             Action is not configured.
1356              
1357             =head2 9
1358              
1359             Missing type for an action.
1360              
1361             =head2 10
1362              
1363             Invalid action for an type.
1364              
1365             =head2 11
1366              
1367             'do' is not defined for the action.
1368              
1369             =head2 12
1370              
1371             Could not determine mimetype.
1372              
1373             =head2 13
1374              
1375             Desktop entry does not appear to be valid. It could not be found by 'lookup' in
1376             'File::DesktopEntry'.
1377              
1378             =head2 14
1379              
1380             No desktop entry specified or none exists for this mimetype.
1381              
1382             =head2 15
1383              
1384             Curses::UI start problem
1385              
1386             =head2 16
1387              
1388             Curses::UI failed in some manner.
1389              
1390             =head1 EXIT CODES
1391              
1392             =head2 14
1393              
1394             Quit selected.
1395              
1396             =head2 15
1397              
1398             The OK has been selected and the new runner has been added.
1399              
1400             =head2 16
1401              
1402             Error Code 14 happened when OK was selected.
1403              
1404             =head2 17
1405              
1406             'newRunner' errored.
1407              
1408             =head2 18
1409              
1410             Ask errored.
1411              
1412             =head1 AUTHOR
1413              
1414             Zane C. Bowers, C<< >>
1415              
1416             =head1 BUGS
1417              
1418             Please report any bugs or feature requests to C, or through
1419             the web interface at L. I will be notified, and then you'll
1420             automatically be notified of progress on your bug as I make changes.
1421              
1422              
1423              
1424              
1425             =head1 SUPPORT
1426              
1427             You can find documentation for this module with the perldoc command.
1428              
1429             perldoc ZConf::Runner
1430              
1431              
1432             You can also look for information at:
1433              
1434             =over 4
1435              
1436             =item * RT: CPAN's request tracker
1437              
1438             L
1439              
1440             =item * AnnoCPAN: Annotated CPAN documentation
1441              
1442             L
1443              
1444             =item * CPAN Ratings
1445              
1446             L
1447              
1448             =item * Search CPAN
1449              
1450             L
1451              
1452             =back
1453              
1454              
1455             =head1 ACKNOWLEDGEMENTS
1456              
1457              
1458             =head1 COPYRIGHT & LICENSE
1459              
1460             Copyright 2008 Zane C. Bowers, all rights reserved.
1461              
1462             This program is free software; you can redistribute it and/or modify it
1463             under the same terms as Perl itself.
1464              
1465              
1466             =cut
1467              
1468             1; # End of ZConf::Runner