File Coverage

blib/lib/P2P/pDonkey/Meta_v04.pm
Criterion Covered Total %
statement 75 95 78.9
branch 17 32 53.1
condition 6 9 66.6
subroutine 10 11 90.9
pod 0 5 0.0
total 108 152 71.0


line stmt bran cond sub pod time code
1             # P2P::pDonkey::Meta_v04.pm
2             #
3             # Copyright (c) 2003-2004 Alexey klimkin .
4             # All rights reserved.
5             # This program is free software; you can redistribute it and/or
6             # modify it under the same terms as Perl itself.
7             #
8             package P2P::pDonkey::Meta_v04;
9              
10 2     2   12580 use 5.006;
  2         9  
  2         81  
11 2     2   10 use strict;
  2         4  
  2         66  
12 2     2   11 use warnings;
  2         5  
  2         254  
13              
14             require Exporter;
15              
16             our $VERSION = '0.05';
17              
18             our @ISA = qw(Exporter);
19              
20             our %EXPORT_TAGS =
21             ( 'all' => [ qw(
22             unpackFileInfo_v04 packFileInfo_v04 makeFileInfo_v04
23             unpackFileInfoList_v04 packFileInfoList_v04
24             ) ]
25             );
26              
27             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
28              
29             our @EXPORT = qw(
30            
31             );
32              
33 2     2   10 use File::Glob ':glob';
  2         3  
  2         460  
34 2     2   12 use File::Basename;
  2         3  
  2         171  
35 2     2   773 use P2P::pDonkey::Meta ':all';
  2         5  
  2         3719  
36              
37             my $debug = 0;
38              
39             sub unpackFileInfo_v04 {
40 3     3 0 11 my (%res, $metas, %tags, @gaps);
41 3 50       21 defined($res{Date} = &unpackD) or return;
42 3 50       12 defined($res{Hash} = &unpackHash) or return;
43 3 50       10 $res{Parts} = &unpackHashList or return;
44 3 50       19 $metas = &unpackMetaList or return;
45              
46 3         19 tie %tags, "Tie::IxHash";
47 3         44 foreach my $meta (@$metas) {
48 22 100 100     301 if ($meta->{Type} == TT_GAPSTART || $meta->{Type} == TT_GAPEND) {
49 6         13 push @gaps, $meta->{Value};
50             } else {
51 16         71 $tags{$meta->{Name}} = $meta;
52             }
53             }
54 3         128 $res{Gaps} = [sort {$a <=> $b} @gaps];
  9         16  
55 3         8 $res{Meta} = \%tags;
56 3         21 return \%res;
57             }
58              
59             sub packFileInfo_v04 {
60 2     2 0 8 my ($d) = @_;
61 2         3 my ($res, $metas);
62 2         9 $res = packD($d->{Date}) . packHash($d->{Hash}) . packHashList($d->{Parts});
63 2         9 $metas = MetaListU2MetaList($d->{Meta});
64 2 50 66     105 if ($d->{Gaps} and @{$d->{Gaps}}) {
  1         7  
65 0         0 my $gaps = $d->{Gaps};
66 0         0 my $ngaps = @$gaps / 2;
67 0         0 for (my ($i, $n) = (0, 0); $i < $ngaps; $i += 2, $n++) {
68 0         0 push @$metas, makeMeta(TT_GAPSTART, $gaps->[$i], $n);
69             }
70 0         0 for (my ($i, $n) = (0, 0); $i < $ngaps; $i += 2, $n++) {
71 0         0 push @$metas, makeMeta(TT_GAPEND, $gaps->[$i+1], $i);
72             }
73             }
74 2         7 $res .= packMetaList($metas);
75 2         8 return $res;
76             }
77              
78             sub unpackFileInfoList_v04 {
79 1     1 0 2 my ($nres, @res, $info);
80 1 50       4 defined($nres = &unpackD) or return;
81 1         3 @res = ();
82 1         5 while ($nres--) {
83 1 50       12 $info = &unpackFileInfo_v04 or return;
84 1         4 push @res, $info;
85             }
86 1         4 return \@res;
87             }
88              
89             sub packFileInfoList_v04 {
90 0     0 0 0 my ($l) = @_;
91 0         0 my ($res, $info);
92 0         0 $res = packD(scalar @$l);;
93 0         0 foreach $info (@$l) {
94 0         0 $res .= packFileInfo_v04($info);
95             }
96 0         0 return $res;
97             }
98              
99             sub makeFileInfo_v04 {
100 1     1 0 9 my ($path) = @_;
101 1         2 my ($base, $ext);
102 0         0 my ($context, %meta, $hash, $type);
103              
104 1         51 $path = bsd_glob($path, GLOB_TILDE);
105 1         274 print $path, "\n";
106              
107 1 50 33     31 (-e $path && -r _) or return;
108              
109 1 50       7 print "Making info for $path\n" if $debug;
110              
111             # my $vinfo = Video::Info->new(-file => $path);
112             # if ($vinfo->type()) {
113             # print $vinfo->filename, "\n";
114             # print $vinfo->filesize(), "\n";
115             # print $vinfo->type(), "\n";
116             # print $vinfo->duration(), "\n";
117             # print $vinfo->minutes(), "\n";
118             # print $vinfo->MMSS(), "\n";
119             # print $vinfo->geometry(), "\n";
120             # print $vinfo->title(), "\n";
121             # print $vinfo->author(), "\n";
122             # print $vinfo->copyright(), "\n";
123             # print $vinfo->description(), "\n";
124             # print $vinfo->rating(), "\n";
125             # print $vinfo->packets(), "\n";
126             # }
127              
128 1         75 ($base, undef, $ext) = fileparse($path, '\..*');
129 1 50       10 $ext = unpack('xa*', $ext) if $ext; # skip first '.'
130 1 50       4 if ($ext) {
131 1         9 my %ft = qw(mp3 Audio avi Video gif Image iso Pro doc Doc);
132 1         5 $type = $ft{lc $ext};
133             }
134              
135 1         2 my ($size, $date);
136 1         8 $size = (stat _)[7];
137 1         3 $date = (stat _)[9];
138              
139 1         11 tie %meta, "Tie::IxHash";
140 1         24 $meta{Name} = makeMeta(TT_NAME, "$base.$ext");
141 1         26 $meta{Size} = makeMeta(TT_SIZE, $size);
142 1 50       14 $meta{Type} = makeMeta(TT_TYPE, $type) if $type;
143 1 50       13 $meta{Format} = makeMeta(TT_FORMAT, $ext) if $ext;
144              
145 1 50       45 open(HANDLE, $path) or return;
146 1         4 binmode(HANDLE);
147              
148 1         15 $context = new Digest::MD4;
149              
150 1         2 my @parts = ();
151 1 50       20 if ($size > SZ_FILEPART) {
152 0         0 seek(HANDLE, 0, 0);
153 0         0 my ($nparts, $part);
154 0         0 $nparts = ceil($size / SZ_FILEPART);
155 0         0 for (my $i = 0; $i < $nparts; $i++) {
156 0         0 read(HANDLE, $part, SZ_FILEPART);
157 0         0 push @parts, md4_hex($part);
158 0         0 $context->add($part);
159             }
160             } else {
161 1         47 $context->addfile(\*HANDLE);
162             }
163 1         6 $hash = $context->hexdigest;
164            
165 1         13 close HANDLE;
166              
167 1         14 return {Date => $date, Hash => $hash, Parts => \@parts, Meta => \%meta, Path => $path};
168             }
169              
170             1;