File Coverage

blib/lib/DMOSS/Plugin/AutoClassify.pm
Criterion Covered Total %
statement 24 76 31.5
branch 0 18 0.0
condition 0 9 0.0
subroutine 8 15 53.3
pod 6 7 85.7
total 38 125 30.4


line stmt bran cond sub pod time code
1             package DMOSS::Plugin::AutoClassify;
2             $DMOSS::Plugin::AutoClassify::VERSION = '0.01_2';
3             # ABSTRACT: DMOSS classification plugin
4 1     1   5 use parent qw/DMOSS::Plugin/;
  1         3  
  1         8  
5 1     1   60 use strict;
  1         2  
  1         30  
6 1     1   51 use warnings;
  1         2  
  1         32  
7              
8 1     1   5 use URI::Find;
  1         1  
  1         59  
9 1     1   4 use File::Slurp qw/read_file/;
  1         2  
  1         37  
10 1     1   4 use HTTP::Request;
  1         1  
  1         158  
11 1     1   6 use LWP::UserAgent;
  1         1  
  1         21  
12 1     1   5 use Data::Dumper;
  1         1  
  1         1674  
13              
14             our @types = qw/_PACKAGE/;
15              
16             # taxonomy
17             my $tax = {
18             'audio video' => {
19             'sound audio' => 1,
20             'video' => 1,
21             },
22             'business enterprise' => {
23             'scheduling' => 1,
24             'office suites' => 1,
25             'e-commerce shopping' => 1,
26             'desktop publisinhg' => 1,
27             'report generators' => 1,
28             'knowledge management' => 1,
29             'enterprise' => 1,
30             'financial' => 1,
31             'todo lists' => 1,
32             'modelling' => 1,
33             'project management' => 1,
34             'time tracking' => 1,
35             'insurance' => 1,
36             },
37             'communications' => {
38             'chat' => 1,
39             'rss feed readers ' => 1,
40             'bbs' => 1,
41             'conferencing' => 1,
42             'email' => 1,
43             'fax' => 1,
44             'fido' => 1,
45             'ham radio' => 1,
46             'usenet news' => 1,
47             'internet phone' => 1,
48             'synchronization' => 1,
49             'streaming' => 1,
50             'telephony' => 1,
51             'file sharing' => 1,
52             },
53             'development' => {
54             'software development' => 1,
55             'database' => 1,
56             'text editors' => 1,
57             'data formats' => 1,
58             },
59             'home education' => {
60             'religion philosophy' => 1,
61             'education' => 1,
62             'printing' => 1,
63             'social sciences' => 1,
64             },
65             'games' => {
66             'hobbies' => 1,
67             'side-scrolling arcade' => 1,
68             'flight simulator' => 1,
69             'sports' => 1,
70             'mmorpg' => 1,
71             'puzzle' => 1,
72             'real time tactical' => 1,
73             'real time strategy' => 1,
74             'first person shooter' => 1,
75             'turn base strategy' => 1,
76             'role-playing' => 1,
77             'card games' => 1,
78             'multi user dungeon' => 1,
79             'console based' => 1,
80             'development framework' => 1,
81             'multiplayer' => 1,
82             'simulation' => 1,
83             'board games' => 1,
84             },
85             'graphics' => {
86             'capture' => 1,
87             'conversion' => 1,
88             'editors' => 1,
89             '3d modeling' => 1,
90             '3d rendering', => 1,
91             'fractals procedural generation' => 1,
92             'viewers' => 1,
93             'image galleries' => 1,
94             'presentation' => 1,
95             'handwriting recognition' => 1,
96             'animation' => 1,
97             },
98             'science engineering' => {
99             'chemistry' => 1,
100             'information analysis' => 1,
101             'interface engine' => 1,
102             'protocol translator' => 1,
103             'physics' => 1,
104             'artificial intelligence' => 1,
105             'astronomy' => 1,
106             'visualization' => 1,
107             'mapping' => 1,
108             'medical' => 1,
109             'mechanical civil engineering' => 1,
110             'human machine interfaces' => 1,
111             'medical physics' => 1,
112             'molecular mechanics' => 1,
113             'quantum computing' => 1,
114             'earth ' => 1,
115             'ecosystem ' => 1,
116             'test measurement' => 1,
117             'molecular' => 1,
118             'building automation' => 1,
119             'simulators' => 1,
120             'robotics' => 1,
121             'scada' => 1,
122             'mathematics' => 1,
123             'linguistics' => 1,
124             'electronic design automation' => 1,
125             'bio-informatics' => 1,
126             },
127             'security utilities' => {
128             'archiving' => 1,
129             'file management' => 1,
130             'power ups' => 1,
131             'terminals' => 1,
132             'security' => 1,
133             'log rotation' => 1,
134             'file transfer protocol' => 1,
135             'capture' => 1,
136             'log analysis' => 1,
137             },
138             'system administration' => {
139             'software distribution' => 1,
140             'benchmark' => 1,
141             'boot' => 1,
142             'clustering' => 1,
143             'file system' => 1,
144             'emedded sustem' => 1,
145             'operation system kernel' => 1,
146             'cron scheduling' => 1,
147             'instalattion' => 1,
148             'logging' => 1,
149             'networking' => 1,
150             'power ups' => 1,
151             'home automation' => 1,
152             'os distribution' => 1,
153             'system shell' => 1,
154             'distributed computing' => 1,
155             'emulators' => 1,
156             'hardware' => 1,
157             'search' => 1,
158             'storage' => 1,
159             }
160             };
161              
162 0     0 1   sub name { 'Auto Classification' }
163              
164             my $TMPDIR = '/tmp'; # FIXME
165             sub process {
166 0     0 1   my ($self, $dmoss, $file) = @_;
167              
168 0           my $corpus = join('/', $TMPDIR, $dmoss->{meta}->{dist}) . '.txt';
169 0 0         unless (-e $corpus) {
170 0           `dmoss-corpus $dmoss->{basedir} > $corpus`
171             }
172 0           my $c = read_file $corpus;
173              
174             # first level
175 0           my $last = 0;
176 0           my $first;
177 0           foreach my $um (keys %$tax) {
178 0           my @words = ();
179 0 0         if ($um =~ m/\s/) { @words = split /\s+/, $um; }
  0            
180 0           else { push @words, $um; }
181              
182 0           foreach (keys %{$tax->{$um}}) {
  0            
183 0           push @words, split /\s+/, $_;
184             }
185              
186 0           my $curr = findAll(@words);
187 0 0         if ($curr > $last) {
188 0           $last = $curr;
189 0           $first = $um
190             }
191             }
192              
193             # second level
194 0           my $second;
195 0           $last = 0;
196 0           foreach my $dois (keys %{$tax->{$first}}) {
  0            
197 0           my @words = ();
198 0 0         if ($dois =~ m/\s/) { @words = split /\s+/, $dois; }
  0            
199 0           else { push @words, $dois; }
200 0           print Dumper \@words;
201              
202 0           my $curr = findAll($c, @words);
203 0           print "curr $curr\n";
204 0 0         if ($curr > $last) {
205 0           $last = $curr;
206 0           $second = $dois;
207             }
208             }
209              
210 0           $dmoss->add_attr('auto_classify', {fst=>$first, snd=>$second});
211             }
212              
213 0     0 1   sub reduce { }
214              
215             sub report {
216 0     0 1   my ($self, $dmoss, $attr) = @_;
217 0 0 0       return unless ($attr->value and keys %{$attr->value});
  0            
218              
219 0           return [ $attr->value->{fst}, $attr->value->{snd} ];
220             }
221              
222             sub report_headers {
223 0     0 1   my ($self, $dmoss) = @_;
224              
225 0           return [ 'Class', 'Sub-class' ];
226             }
227              
228             sub grade {
229 0     0 1   my ($self, $dmoss, $attr) = @_;
230              
231 0 0 0       return 1 if ($attr->value->{fst} and $attr->value->{snd});
232 0 0 0       return 0.5 if ($attr->value->{fst} or $attr->value->{snd});
233 0           return 0;
234             }
235              
236             sub findAll {
237 0     0 0   my ($c, @words) = @_;
238              
239 0           my $found = 0;
240 0           foreach (@words) {
241 0 0         next unless ($_ =~ m/\w/);
242 0           $found++ while ($c =~ m/\b${_}s?\b/ig);
243             }
244              
245 0           return $found;
246             }
247              
248             1;
249              
250             __END__