File Coverage

blib/lib/Mojo/Weixin/Message/Remote/_get_media.pm
Criterion Covered Total %
statement 18 103 17.4
branch 0 90 0.0
condition 0 14 0.0
subroutine 6 8 75.0
pod n/a
total 24 215 11.1


line stmt bran cond sub pod time code
1 1     1   7 use strict;
  1         3  
  1         143  
2 1     1   9 use File::Temp qw/:seekable/;
  1         2  
  1         134  
3 1     1   7 use Mojo::Util ();
  1         2  
  1         14  
4 1     1   5 use File::Basename ();
  1         2  
  1         12  
5 1     1   6 use File::Spec ();
  1         2  
  1         39  
6 1     1   7 use Encode ();
  1         2  
  1         1320  
7             sub Mojo::Weixin::_get_media {
8 0     0     my $self = shift;
9 0           my $msg = shift;
10 0           my $callback = shift;
11              
12 0           my $media_id = (split ":",$msg->media_id)[0];
13 0           my $api;
14             my @query_string;
15 0           my $headers = {};
16 0 0 0       if($msg->media_type eq "image"){
    0          
    0          
    0          
    0          
17 0           $api = 'https://'.$self->domain . '/cgi-bin/mmwebwx-bin/webwxgetmsgimg';
18 0           @query_string = ('' => '',MsgID => $media_id,);
19 0 0         push @query_string,(skey=>Mojo::Util::url_escape($self->skey)) if $self->skey;
20             }
21             elsif($msg->media_type eq "voice"){
22 0           $api = 'https://'.$self->domain . '/cgi-bin/mmwebwx-bin/webwxgetvoice';
23 0           @query_string = (msgid=>$media_id);
24 0 0         push @query_string,(skey=>Mojo::Util::url_escape($self->skey)) if $self->skey;
25             }
26             elsif($msg->media_type eq "video" or $msg->media_type eq "microvideo"){
27 0           $api = 'https://'.$self->domain . '/cgi-bin/mmwebwx-bin/webwxgetvideo';
28 0           @query_string = (msgid=>$media_id);
29 0 0         push @query_string,(skey=>Mojo::Util::url_escape($self->skey)) if $self->skey;
30 0           $headers = {Range => 'bytes=0-'};
31             }
32             elsif($msg->media_type eq "emoticon"){
33 0           $api = 'https://'.$self->domain . '/cgi-bin/mmwebwx-bin/webwxgetmsgimg';
34 0           @query_string = ('' => '',MsgID => $media_id,type=>'big');
35 0 0         push @query_string,(skey=>Mojo::Util::url_escape($self->skey)) if $self->skey;
36             }
37             elsif($msg->media_type eq "file"){
38 0           $api = 'https://file.' . $self->domain . '/cgi-bin/mmwebwx-bin/webwxgetmedia';
39 0   0       @query_string = (
40             sender=>$msg->sender_id,
41             mediaid=>$media_id,
42             filename=>$msg->media_name,
43             fromuser=>$self->wxuin,
44             pass_ticket=>($self->pass_ticket || 'undefined'),
45             webwx_data_ticket=>$self->search_cookie("webwx_data_ticket")
46             );
47             #push @query_string,(skey=>Mojo::Util::url_escape($self->skey)) if $self->skey;
48             }
49             else{
50 0           $self->error("获取media错误:不支持的media类型");
51 0           return;
52             }
53             $self->http_get($self->gen_url($api,@query_string), {Referer=>'https://' . $self->domain .'/'},sub{
54 0     0     my ($data,$ua,$tx) = @_;
55 0 0         if(not defined $data){
56 0           $self->warn("media[ " . $msg->media_id . " ]下载失败");
57 0           return;
58             }
59 0 0         my $mime = $data=~/^GIF8/?"image/gif":$tx->res->headers->content_type;
60 0 0         my $type = $mime=~/^image\/jpe?g/i ? "jpg"
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
61             : $mime=~/^image\/png/i ? "png"
62             : $mime=~/^image\/bmp/i ? "bmp"
63             : $mime=~/^image\/gif/i ? "gif"
64             : $mime=~/^text\/plain/i ? "txt"
65             : $mime=~/^text\/html/i ? "html"
66             : $mime=~/^text\/json/i ? "json"
67             : $mime=~/^application\/json/i ? "json"
68             : $mime=~/^video\/mp4/i ? "mp4"
69             : $mime=~/^audio\/mp3/i ? "mp3"
70             : $mime=~/^audio\/mpeg/i ? "mp3"
71             : $mime=~/^application\/json/i ? "json"
72             : "dat"
73             ;
74 0 0         return unless defined $type;
75 0           $mime=~s/\s*;.*$//g;
76 0 0 0       if($msg->format eq 'media' and $msg->media_type eq 'file'){
77 0 0         if($msg->media_name =~ /^.+?\.([^\.]+)$/ ){
78 0 0         if($1){
79 0           $msg->media_ext($1);
80             #$msg->media_mime("application/octet-stream"); #txt文件这样设置mime不合理
81             }
82             }
83             }
84 0 0         $msg->media_mime($mime) if not defined $msg->media_mime;
85 0 0         $msg->media_ext($type) if not defined $msg->media_ext;
86 0           $msg->media_data($data);
87 0           $msg->media_mtime(time);
88 0           $msg->media_size(length($data));
89              
90 0 0         if($msg->media_size == 0){
91 0 0         $msg->media_path("non-exist-path") if $msg->media_size == 0;
92 0           $msg->media_name(File::Basename::basename($msg->media_path));
93 0 0         $callback->($msg->media_path,$data,$msg) if ref $callback eq "CODE";
94 0           return;
95             }
96 0 0 0       if(defined $self->media_dir and not -d $self->media_dir){
97 0           $self->error("无效的 media_dir: " . $self->media_dir);
98 0           return;
99             }
100 0 0         if($msg->media_type eq 'file'){
101 0           my $media_name = $msg->media_name;
102 0   0       my $media_dir = $self->media_dir // $self->tmpdir;
103              
104 0 0         if($^O eq 'MSWin32'){
105 0           $media_name = Encode::encode("gbk",Encode::decode("utf8",$media_name));
106 0           $media_dir = Encode::encode("gbk",Encode::decode("utf8",$media_dir));
107             }
108 0           my $path = File::Spec->catfile($media_dir,$media_name);
109 0           my $i = 1;
110 0           while( -f $path){
111 0 0         if($i>100){#防止死循环
112 0           my $time = int(time);
113 0           $path =~ s/(\(\d\)|)(?=\.[^\.]+$|$)/($time)/;
114 0           last;
115             }
116 0           $path =~ s/(\(\d\)|)(?=\.[^\.]+$|$)/($i)/;
117 0           $i++;
118             }
119 0           eval{
120 0 0         open(my $fh,">",$path) or die $!;
121 0 0         chmod 0644, $fh if $^O ne 'MSWin32';
122 0           print $fh $data;
123 0           close $fh;
124 0 0         $msg->media_path($^O eq 'MSWin32'?Encode::encode("utf8",Encode::decode("gbk",$path)):$path);
125 0 0         $callback->($path,$data,$msg) if ref $callback eq "CODE";
126             };
127 0 0         $self->error("[ ". __PACKAGE__ . " ] $@") if $@;
128            
129             }
130             else{
131 0           my $t = POSIX::strftime('%Y%m%d%H%M%S',localtime());
132 0           my @opt = (
133             TEMPLATE => "mojo_weixin_media_${t}_XXXX",
134             SUFFIX => "." . $msg->media_ext,
135             UNLINK => 0,
136             );
137 0 0         defined $self->media_dir?(push @opt,(DIR=>$self->media_dir)):(push @opt,(TMPDIR=>1));
138 0           eval{
139 0           my $tmp = File::Temp->new(@opt);
140 0           binmode $tmp;
141 0 0         chmod 0644, $tmp if $^O ne 'MSWin32';
142 0           print $tmp $data;
143 0           close $tmp;
144 0           $msg->media_path($tmp->filename);
145 0 0         $callback->($tmp->filename,$data,$msg) if ref $callback eq "CODE";
146             };
147 0 0         $self->error("[ ". __PACKAGE__ . " ] $@") if $@;
148             }
149 0           });
150             }
151             1;