File Coverage

blib/lib/Treex/Core/Resource.pm
Criterion Covered Total %
statement 29 68 42.6
branch 0 24 0.0
condition 0 6 0.0
subroutine 10 11 90.9
pod 1 1 100.0
total 40 110 36.3


line stmt bran cond sub pod time code
1             package Treex::Core::Resource;
2             $Treex::Core::Resource::VERSION = '2.20160630';
3 28     28   37448 use strict;
  28         68  
  28         765  
4 28     28   143 use warnings;
  28         62  
  28         760  
5              
6 28     28   533 use 5.010;
  28         97  
7              
8             #use Moose;
9             #use Treex::Core::Common;
10 28     28   10993 use LWP::Simple; #TODO rewrite using LWP:UserAgent to show progress
  28         1206912  
  28         219  
11 28     28   8903 use File::Path 2.08 qw(make_path);
  28         729  
  28         1508  
12 28     28   186 use File::Spec;
  28         66  
  28         641  
13 28     28   508 use Treex::Core::Log;
  28         65  
  28         1744  
14 28     28   806 use Treex::Core::Config;
  28         74  
  28         715  
15              
16 28     28   146 use Exporter 'import';
  28         67  
  28         706  
17 28     28   151 use vars qw(@EXPORT_OK);
  28         99  
  28         13121  
18             @EXPORT_OK = qw(require_file_from_share);
19              
20             sub require_file_from_share {
21 0     0 1   my ( $path_to_file, $who_wants_it, $make_executable, $skip_download ) = @_;
22            
23             # The following three cases are handled first
24             # ./relative_path
25             # ../relative_path
26             # /absolute_path
27             # These files are not searched within Treex Share.
28 0 0         if ($path_to_file =~ m|^[.]{0,2}/|) {
29 0           log_debug("Looking for absolute or relative path $path_to_file\n");
30 0 0         return $path_to_file if -e $path_to_file;
31 0           my $file = File::Spec->rel2abs($path_to_file);
32 0           log_fatal "Cannot find '$path_to_file'.\nNote that it starts with '/' or '.', so it is not searched for within Treex Share.\nFile '$file' does not exist.\n";
33             }
34              
35 0           my $writable; #will store first writable directory found
36             SEARCH:
37 0           foreach my $resource_dir ( Treex::Core::Config->resource_path() ) {
38 0 0         next if (!$resource_dir);
39 0           my $file = File::Spec->catfile( $resource_dir, $path_to_file );
40 0           log_debug("Trying $file\n");
41 0 0         if ( -e $file ) {
42 0           log_debug("Found $file\n");
43 0           return $file;
44             }
45 0 0         if ( !defined $writable ) {
46 0 0         if ( !-e $resource_dir ) {
47 0           make_path($resource_dir);
48             }
49 0 0 0       if ( -d $resource_dir && -w $resource_dir ) {
50 0           $writable = $resource_dir;
51 0           log_debug("Found writable directory: $writable");
52             }
53             }
54             }
55 0 0         $who_wants_it = defined $who_wants_it ? " by $who_wants_it" : '';
56 0           log_info("Shared file '$path_to_file' is missing$who_wants_it.");
57 0 0         log_fatal("Cannot find writable directory for downloading from share") if !defined $writable;
58              
59 0           my $file = "$writable/$path_to_file";
60              
61             # first ensure that the directory exists
62 0           my $directory = $file;
63 0           $directory =~ s/[^\/]*$//;
64 0           File::Path::mkpath($directory);
65            
66             # skip download, just return the path, the caller block will handle the download itself
67 0 0         if ($skip_download){
68 0           log_warn("File $file does not exist, auto-download skipped.");
69 0           return $file;
70             }
71              
72 0           my $url = Treex::Core::Config->share_url() . "/$path_to_file";
73 0           log_info("Trying to download $url");
74              
75             # downloading the file using LWP::Simple
76 0           my $response_code = getstore( $url, $file );
77              
78 0 0         if ( $response_code == 200 ) {
79 0           log_info("Successfully downloaded to $file");
80             }
81             else {
82 0           log_fatal(
83             "Error when trying to download "
84             . "$url and to store it as $file ($response_code)\n"
85             );
86             }
87              
88             # TODO: better solution
89 0 0 0       if ( $file =~ /installed_tools/ || $make_executable ) {
90 0           chmod 0755, $file;
91             }
92 0           return $file;
93             }
94              
95             1;
96              
97             __END__
98              
99              
100             =encoding utf-8
101              
102             =head1 NAME
103              
104             Treex::Core::Resource - Access to shared resources
105              
106             =head1 VERSION
107              
108             version 2.20160630
109              
110             =head1 SYNOPSIS
111              
112             use Treex::Core::Resource qw(require_file_from_share);
113             my $path = require_file_from_share('relative/path/to/file/within/Treex/Share');
114             open my $MODEL, '<', $path or log_fatal($!);
115              
116             # or
117             my $path = require_file_from_share('./relative/path/from/the/current/directory');
118             my $path = require_file_from_share('/absolute/path');
119              
120             =head1 DESCRIPTION
121              
122             This module provides access to shared resources (e.g. models). First it tries to locate it on local computer.
123             If not found, download from server (L<http://ufallab.ms.mff.cuni.cz/>).
124             If the path starts with "." or "/" it is searched in the local file system (and not in Treex Share).
125              
126             =head1 SUBROUTINES
127              
128             =over
129              
130             =item require_file_from_share($path_to_file, $who_wants_it, $make_executable, $skip_download)
131              
132             Try to locate file in local resource paths, if not found, try to download it and stores it to first writable path.
133             Obtains paths from L<Treex::Core::Config-E<gt>resource_path()|Treex::Core::Config/resource_path>
134             Returns path to file.
135              
136             If C<$make_executable> is true, execute rights are set on the downloaded file.
137              
138             If C<$skip_download> is true, automatic download is skipped and only the path tho the file or the first
139             writable path is returned. The caller block must check the existence of the file and handle the download
140             itself (useful for downloading and unpacking of larger archives).
141              
142             =back
143              
144             =head1 AUTHOR
145              
146             ZdenÄ›k Žabokrtský <zabokrtsky@ufal.mff.cuni.cz>
147              
148             Tomáš Kraut <kraut@ufal.mff.cuni.cz>
149              
150             Martin Popel <popel@ufal.mff.cuni.cz>
151              
152             =head1 COPYRIGHT AND LICENSE
153              
154             Copyright © 2011,2015 by Institute of Formal and Applied Linguistics, Charles University in Prague
155              
156             This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.