File Coverage

blib/lib/Video/FindEvent/Manual.pm
Criterion Covered Total %
statement 22 24 91.6
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package Video::FindEvent::Manual;
2              
3 2     2   13 use vars qw($VERSION @EXPORT);
  2         5  
  2         176  
4             $VERSION = 0.01;
5             @EXPORT = qw(new configure findevents);
6              
7 2     2   12 use base Video::FindEvent;
  2         3  
  2         1237  
8              
9 2     2   18 use strict;
  2         4  
  2         80  
10              
11 2     2   11 use Video::Event::Manual;
  2         4  
  2         43  
12 2     2   1950 use Term::ReadKey;
  2         27345  
  2         215  
13 2     2   2016 use Time::HiRes qw(gettimeofday tv_interval);
  2         3939  
  2         12  
14 2     2   455 use Data::Dumper;
  2         5  
  2         120  
15 2     2   3551 use XML::Simple;
  0            
  0            
16              
17             $Data::Dumper::Purity = 1;
18             $Data::Dumper::Deepcopy = 1;
19              
20             sub new {
21             my ($class, $args) = @_;
22             my $self = bless {}, ref($class) || $class;
23              
24             foreach my $key (keys %$args) {
25             $self->{$key} = $$args{$key};
26             }
27            
28             $self->configure();
29             return $self;
30             }
31              
32             sub configure {
33             my ($self) = @_;
34             $Data::Dumper::Purity = 1;
35             $Data::Dumper::Deepcopy = 1;
36              
37             my $config = $self->{'config'};
38            
39             if (ref $self->{'config'} ne 'HASH') {
40             $config = XMLin($self->{'config'},
41             keyattr => 'key',
42             forcearray => 0,
43             contentkey => '-command',
44             keeproot => 0,
45             );
46             $config = abusexml($config);
47             }
48             my ($systemkeys, $eventkeys) = getkeys($config);
49             $self->{'eventkeys'} = $eventkeys;
50             $self->{'QUIT'} = $$systemkeys{'quit'};
51             $self->{'UNDO'} = $$systemkeys{'undo'};
52             $self->{'UNDOENDPT'} = $$systemkeys{'undoendpt'};
53             $self->{'TAG'} = $$systemkeys{'tag'};
54             $self->{'TAGEDIT'} = $$systemkeys{'tagedit'};
55             return 1;
56             }
57              
58             sub findevents {
59             my ($self, %args) = @_;
60              
61             #copy over global args from Video::Manip -- ew.
62             foreach my $arg (keys %args) {
63             if (not defined $self->{$arg}) {
64             $self->{$arg} = $args{$arg};
65             }
66             else {
67             print "not redefining argument $arg, $self->{$arg}, as $args{$arg}\n."
68             }
69             }
70              
71             my @events = ();
72             my @openevents = ();
73             my $continue = 1;
74              
75             #XXX this should be global opt
76             my $delay = 0.2; #sleep for 5th of second between busy wait for keypress
77              
78             #plaympeg($MPEGPLAYER, $MPEGPLAYEROPTIONS, $inputmpeg);
79             presskeycont("any");
80             my $intitaltime = [gettimeofday];
81              
82             while ($continue) {
83             sleep($delay);
84             my $key = presskeycont("prompt", \@openevents);
85             my $eventtime = tv_interval($intitaltime);
86            
87             #probability the event happened
88             my $probability = 1;
89              
90            
91             if ($key eq $self->{'QUIT'}) {
92              
93             while (scalar @openevents) {
94             #X this code is pasted below
95             my $event = pop @openevents;
96             my $totaltime = $event->endtime($eventtime,$key);
97             print "ending $event->{'name'} after $totaltime\n";
98             print "endtime here is $event->{'endtime'}\n";
99             }
100            
101             my $event = Video::Event::Manual->new($eventtime, $self->{'eventkeys'}{$key}{'envl'}, $probability, $self->{'eventkeys'}{$key}{'type'}, $self->{'eventkeys'}{$key}{'name'});
102             push @events, $event;
103             $continue = 0;
104             }
105             elsif ($key eq $self->{'UNDO'}) {
106             if (scalar @events) {
107             print "deleted event $events[-1]->{'name'}, $events[-1]->{'time'}\n";
108             if (defined $events[-1]->{'type'}) {
109             pop @openevents if $events[-1]->{'type'} eq 'long';
110             }
111             pop @events;
112             }
113             else { print "no events to delete\n"; }
114             }
115             elsif ($key eq $self->{'UNDOENDPT'}) {
116             if (scalar @events) {
117             if (defined $events[-1]->{'type'}) {
118             if ($events[-1]->{'type'} eq 'long') {
119             push @openevents, $events[-1];
120             }
121             }
122             else {
123             print "endpoint not defined for non-long event; doing nothing\n";
124             }
125             }
126             else { print "no events to delete\n"; }
127             }
128             elsif ($key =~ /[1-9]/ and scalar @openevents) {
129             #XXX this is copied from above
130             my $event = pop @openevents;
131             my $totaltime = $event->endtime($eventtime,$key);
132             print "ending $event->{'name'} at $event->{'endtime'} after $totaltime\n";
133             }
134            
135             elsif (defined $self->{'eventkeys'}{$key}) {
136             my $name = $self->{'eventkeys'}{$key}{'name'};
137             my $event = Video::Event::Manual->new($eventtime, $self->{'eventkeys'}{$key}{'envl'}, $probability, $self->{'eventkeys'}{$key}{'type'}, $self->{'eventkeys'}{$key}{'name'});
138             push @events, $event;
139             print $event->{'name'}." at ".$event->{'time'}."\n";
140             if ($event->{'type'} eq "long") {
141             push @openevents, $event ;
142             }
143             }
144             elsif ($key eq $self->{'TAG'} and scalar @events) {
145             print $events[-1]->gettag();
146             ReadMode 0;
147             my $tag;
148             $tag = ReadLine();
149             chomp($tag);
150             $events[-1]->tag($tag);
151             ReadMode 4;
152             }
153             elsif ($key eq $self->{'TAGEDIT'} and scalar @events) {
154             #XXX edit tag
155             }
156            
157             else { print "unknown event $key\n"; }
158             }
159             $self->{'events'} = \@events;
160              
161             $self->{'algoid'} = 'defaultid' unless $self->{'algoid'};
162             $self->{'progid'} = 99 unless $self->{'progid'};
163              
164             if ($self->{'writefile'} ne '') {
165             my $file = $self->{'writefile'} . ".obj";
166             open FH, ">$file";
167             my $dump = Dumper(\@events);
168             print FH "$dump\n";
169             close FH;
170             return 1;
171             }
172             }
173              
174             sub presskeycont {
175             my ($display, $args) = @_;
176             if ($display eq "any") { print "Press any key to continue.."; }
177             ReadMode 4;
178             if ($display eq "prompt") {
179             foreach my $event (@$args) {
180             print "[$event->{'name'}]";
181             }
182             print "> ";
183             }
184             my $key;
185             while (not defined ($key = ReadKey(-1))) {sleep 0.2}
186             ReadMode 0;
187             if ($display eq "any") { print "\n"; }
188             return $key;
189             }
190              
191              
192             sub plaympeg {
193             my ($player, $options, $file) = @_;
194             my $pid = fork;
195             if (! $pid) {
196             if (! system("$player $options $file")) {
197             printf("Could not open $file with $player\n");
198             }
199             exit(0);
200             }
201             }
202              
203             sub insert {
204             my ($id, $ratings) = @_;
205            
206             my $encoded = encode_base64($ratings);
207            
208             my $dbh = dbconnect();
209             my $sql = "INSERT INTO ratings (id, ratings) values ('$id', '$encoded')";
210             my $sth = $dbh->prepare($sql);
211             $sth->execute() or warn "could not insert into ratings";
212             print "done\n";
213             }
214              
215             sub dbconnect {
216             my $dbname = 'manual';
217             my $username = 'postgres';
218             my $password = '';
219             return DBI->connect("dbi:Pg:dbname=$dbname", $username, $password)
220             or warn $DBI::errstr;
221             return 0;
222             }
223              
224             sub dbdisconnect {
225             my ($dbh) = @_;
226             $dbh->disconnect();
227             }
228              
229              
230             sub abusexml {
231             # pay here for abuse of xml
232             #
233             # points are stored in tags that contain the x value in their name
234             # this is bad xml but gives a nice data structure once we account for
235             # xml not allowing numerical tags
236             #
237             # tags for x values can be prefixed with any non digit characters
238             # (which are still valid xml)
239              
240             my ($xml) = @_;
241             my %hash;
242              
243             foreach my $block (keys %$xml) {
244             %hash = %{$$xml{$block}};
245             foreach my $key (keys %{$$xml{$block}}) {
246              
247             foreach my $pt (keys %{$hash{$key}{'envl'}}) {
248             my $value = $hash{$key}{'envl'}{$pt};
249             delete $hash{$key}{'envl'}{$pt};
250             #match optional (actually, required for valid xml) tag
251             #followed by neg/pos int/float
252             #value cannot be negative -- take abs; this is a feature
253             $pt =~ /[A-Za-z]*(\-?[0-9]*\.?[0-9]*)/;
254             $hash{$key}{'envl'}{$1} = $value;
255            
256             }
257              
258             }
259             }
260             return \%hash;
261             }
262              
263             sub getkeys {
264             my ($keys) = @_;
265             my %systemkeys;
266             my %eventkeys;
267             foreach my $key (keys %$keys) {
268             if ($$keys{$key}{'type'} eq 'system') {
269             $systemkeys{ $$keys{$key}{'name'} } = $key;
270             }
271             else {
272             $eventkeys{ $key } = $$keys{$key};
273             }
274             }
275             if (not defined $systemkeys{'undo'}
276             or not defined $systemkeys{'quit'}
277             or not defined $systemkeys{'delete'}) {
278             configerror();
279             }
280             return (\%systemkeys, \%eventkeys);
281             }
282              
283             sub configerror {
284             die "error in configuration file";
285             }
286              
287             1;