File Coverage

lib/Sorauta/Cache/HTTP/Request/Image.pm
Criterion Covered Total %
statement 3 3 100.0
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 4 4 100.0


line stmt bran cond sub pod time code
1             #============================================
2             # 画像キャッシュプログラム(BASIC認証突破)
3             # -------------------------------------------
4             # アクセサ
5             # cache_path String 画像のキャッシュディレクトリ
6             # ex)/Library/WebServer/Documents/cache/
7             # log_path String 画像キャッシュ生成ログ保存ディレクトリ
8             # ex)/Library/WebServer/Documents/cache_log/
9             # url String 画像URL
10             # ex)http://example.com/example.jpg
11             # check Integer 画像の更新を確認するか
12             # 0 ... 確認しない(デフォルト)
13             # 1 ... 確認する
14             # render Integer 取得画像を表示するか
15             # 0 ... 表示しない
16             # 1 ... 表示する(デフォルト)
17             # debug Integer デバッグモード
18             # 0 ... ログ表示しない(デフォルト)
19             # 1 ... ログ表示する
20             # logger Integer ログ保存するか
21             # 0 ... ログ保存しない(デフォルト)
22             # 1 ... ログ保存する
23             #
24             # file_name String キャッシュ画像のファイル名
25             # 一部replaceされてるので画像URLそのままのファイル名ではないので.
26             # file_path String キャッシュ画像の保存先
27             # めんどくさいので用意
28             #============================================
29             package Sorauta::Cache::HTTP::Request::Image;
30 1     1   23702 use base qw/Class::Accessor::Fast/;
  1         2  
  1         755  
31            
32             use 5.012003;
33             use strict;
34             use warnings;
35             use utf8;
36             use CGI::Carp qw/fatalsToBrowser/;
37             use Data::Dumper;
38             use LWP::UserAgent;
39             use Sorauta::Utility;
40            
41             our $VERSION = '0.01';
42            
43             # 許可するMIME一覧
44             our %CONTENT_TYPE_LIST = (
45             jpg => 'image/jpg',
46             gif => 'image/gif',
47             png => 'image/png',
48             mov => 'video/quicktime',
49             f4v => 'video/f4v',
50             flv => 'video/x-flv',
51             );
52            
53             __PACKAGE__->mk_accessors(
54             qw/cache_path log_path url check render debug logger file_name file_path/);
55            
56             #==========================================
57             # ファイル取得の取得、保存を実行
58             # req:
59             # res:
60             #==========================================
61             sub execute {
62             my $self = shift;
63            
64             # must be defined accessors
65             if (!$self->cache_path || !$self->url) {
66             die 'must be define accessor cache_path(/var/www/cache/), url(http://example.com/example.jpg)';
67             }
68            
69             # set default params
70             unless (length $self->render) {
71             $self->render(1);
72             }
73             $self->file_name('');
74             $self->file_path('');
75            
76             # replace system character
77             my $file_name = $self->url;
78             $file_name =~ s/:/_/g;
79             $file_name =~ s/\//__/g;
80             $file_name =~ s/&/--/g;
81             $self->file_name($file_name);
82            
83             # set file_path
84             $self->file_path(cat($self->cache_path, $self->file_name));
85            
86             # exists cache file
87             if (-e $self->file_path) {
88             # check update request
89             if ($self->check) {
90             $self->get();
91             }
92            
93             if ($self->render) {
94             $self->show($self->file_name);
95             }
96             }
97             else {
98             $self->get();
99             }
100            
101             return 1;
102             }
103            
104             #==========================================
105             # 画像を取得
106             # req:
107             # res:
108             #==========================================
109             sub get {
110             my $self = shift;
111            
112             my $is_binary = 1;
113             my $res = get_from_http($self->url);
114             unless ($res->headers->content_type =~ /text/) {
115             # 既にキャッシュファイルが存在する場合
116             if (-e $self->file_path) {
117             my $last_local_modified = (stat $self->file_path)[9];
118             my $last_web_modified = get_epoch_from_formated_http(
119             $res->headers->{'last-modified'});
120            
121             # logger
122             if ($self->logger) {
123             $self->add_log('[exists]'.$self->file_name);
124             }
125            
126             # debug
127             if ($self->debug) {
128             warn("last_local_modified:". $last_local_modified. $/);
129             warn("last_web_modified:". $last_web_modified. $/);
130             }
131            
132             # 日付が変わっていれば保存
133             if ($last_local_modified != $last_web_modified) {
134             save_file($self->file_path, $res->content, $is_binary);
135             }
136             }
137             # 新規取得時
138             else {
139             save_file($self->file_path, $res->content, $is_binary);
140            
141             # logger
142             if ($self->logger) {
143             $self->add_log('[new]'.$self->file_name);
144             }
145            
146             # ファイル更新日を変える
147             my $last_web_modified = get_epoch_from_formated_http(
148             $res->headers->{'last-modified'});
149             utime(time,
150             $last_web_modified,
151             ($self->file_path));
152             }
153             }
154            
155             # show binary image
156             if ($self->render) {
157             unless ($res->headers->content_type =~ /text/) {
158             print 'content-type:', $res->headers->content_type, $/, $/;
159             print $res->content;
160             }
161             else {
162             my $msg = 'couldn\'t reach url: '.$self->url;
163            
164             print 'content-type:text/plain;', $/, $/;
165             print $msg;
166            
167             warn $msg;
168             }
169             }
170             }
171            
172             #==========================================
173             # 保存した画像を表示
174             # req:
175             # file_name: ファイル名
176             # res:
177             #==========================================
178             sub show {
179             my($self, $file_name) = @_;
180             my $content_type = 'application/octet-stream';
181            
182             # extract content-type
183             my($suffix) = (split(/\./, $file_name))[-1];
184             if (exists($CONTENT_TYPE_LIST{$suffix})) {
185             $content_type = $CONTENT_TYPE_LIST{$suffix};
186             }
187             if ($self->debug) {
188             warn $self->file_path.', content-type:'.$content_type.', suffix:'.$suffix;
189             }
190            
191             # show binary image
192             open(my $F, $self->file_path) or die 'Can\'t open: '.$!;
193             binmode($F);
194             print "content-type:", $content_type, $/, $/;
195             while (my $line = <$F>) {
196             print $line;
197             }
198             close $F;
199             }
200            
201             #==========================================
202             # ログ保存
203             # req:
204             # txt: 保存メッセージ
205             # res:
206             #==========================================
207             sub add_log {
208             my($self, $txt) = @_;
209             my $today = get_date(time);
210             my $log_file = sprintf("%04d%02d%02d_log.txt", $today->{year}, $today->{month}, $today->{day});
211             my $date = sprintf("[%02d:%02d:%02d]", $today->{hour}, $today->{min}, $today->{sec});
212            
213             open my $F, '>>', cat($self->log_path, $log_file);
214             print $F $date, $txt, $/;
215             close $F;
216             }
217            
218             1;
219            
220             __END__