# Type: Silent # Category: Extra # Description: Saves history about user's online/away times # Author: Andriy Lesyuk # TODO: check this! new Orangutan::Context( onstatus => sub { my ($context, $user, $type, $status) = @_; my $created = 0; my $presence = $user->GetField('presence'); if (!$presence) { $presence = [ ]; $created = 1; } my $time = new Orangutan::Date; if (!$user->IsWorkDay($time)) { if ((scalar @{$presence} == 0) || (scalar @{$presence->[$#{$presence}]} == 3)) { return; } } my $previous = $user->GetStatus; if (!defined($status)) { if ((scalar @{$presence} > 0) && (scalar @{$presence->[$#{$presence}]} == 2)) { if ($presence->[$#{$presence}][0] eq 'online') { if (($time->Date - $presence->[$#{$presence}][1]) < 900) { if ((scalar @{$presence} > 1) && (scalar @{$presence->[$#{$presence}-1]} == 3) && ($presence->[$#{$presence}-1][0] eq 'online')) { if (($presence->[$#{$presence}][1] - $presence->[$#{$presence}-1][2]) < 900) { $presence->[$#{$presence}-1][2] = $time->Date; } if ($user->GetField('debug_presence')) { # FIXME: remove my $start = new Orangutan::Date($presence->[$#{$presence}][1]); my $duration = $time->Date - $start->Date; $main::users->TellCreator( sprintf("User %s went offline - removing short online period (%02d:%02d - %02d:%02d = %d:%02d).", $user->GetJabberUserID, $start->GetTime, $time->GetTime, int($duration / 3600), int(($duration % 3600) / 60)) ); } pop(@{$presence}); } } else { if ((scalar @{$presence} > 2) && (scalar @{$presence->[$#{$presence}-1]} == 3) && (scalar @{$presence->[$#{$presence}-2]} == 3) && ($presence->[$#{$presence}-1][0] eq 'away') && ($presence->[$#{$presence}-2][0] eq 'online') && (($presence->[$#{$presence}-1][2] - $presence->[$#{$presence}-1][1]) < 900)) { if ($user->GetField('debug_presence')) { # FIXME: remove my $start = new Orangutan::Date($presence->[$#{$presence}-1][1]); my $end = new Orangutan::Date($presence->[$#{$presence}-1][2]); my $duration = $end->Date - $start->Date; my $online = new Orangutan::Date($presence->[$#{$presence}-2][1]); my $lasting = $time->Date - $online->Date; $main::users->TellCreator( sprintf("User %s went offline - removing short away period (%02d:%02d - %02d:%02d = %d:%02d), ". "prolonging last online period (starting at %02d:%02d and lasting %d:%02d).", $user->GetJabberUserID, $start->GetTime, $end->GetTime, int($duration / 3600), int(($duration % 3600) / 60), $online->GetTime, int($lasting / 3600), int(($lasting % 3600) / 60)) ); } splice(@{$presence}, -2); } $presence->[$#{$presence}][2] = $time->Date; } } elsif ($presence->[$#{$presence}][0] eq 'away') { if ($user->GetField('debug_presence')) { # FIXME: remove my $start = new Orangutan::Date($presence->[$#{$presence}][1]); my $duration = $time->Date - $start->Date; $main::users->TellCreator( sprintf("User %s went offline - removing away period (%02d:%02d - %02d:%02d = %d:%02d).", $user->GetJabberUserID, $start->GetTime, $time->GetTime, int($duration / 3600), int(($duration % 3600) / 60)) ); } pop(@{$presence}); } } } elsif ($status eq 'online') { if (defined($previous)) { if ((scalar @{$presence} > 0) && (scalar @{$presence->[$#{$presence}]} == 2) && ($presence->[$#{$presence}][0] eq 'away')) { $presence->[$#{$presence}][2] = $time->Date; push(@{$presence}, [ 'online', $time->Date ]); } else { push(@{$presence}, [ 'online', $time->Date ]); } } else { push(@{$presence}, [ 'online', $time->Date ]); } } elsif ($status eq 'away') { if (defined($previous)) { if ((scalar @{$presence} > 0) && (scalar @{$presence->[$#{$presence}]} == 2) && ($presence->[$#{$presence}][0] eq 'online')) { if (($time->Date - $presence->[$#{$presence}][1]) < 900) { if ($user->GetField('debug_presence')) { # FIXME: remove my $start = new Orangutan::Date($presence->[$#{$presence}][1]); my $duration = $time->Date - $start->Date; $main::users->TellCreator( sprintf("User %s went away - removing short online period (%02d:%02d - %02d:%02d = %d:%02d).", $user->GetJabberUserID, $start->GetTime, $time->GetTime, int($duration / 3600), int(($duration % 3600) / 60)) ); } pop(@{$presence}); if ((scalar @{$presence} > 0) && (scalar @{$presence->[$#{$presence}]} == 3) && ($presence->[$#{$presence}][0] eq 'away')) { if ($user->GetField('debug_presence')) { # FIXME: remove my $away = new Orangutan::Date($presence->[$#{$presence}][1]); my $lasting = $time->Date - $away->Date; $main::users->TellCreator( sprintf("Prolonging last away period (starting at %02d:%02d and lasting %d:%02d).", $away->GetTime, int($lasting / 3600), int(($lasting % 3600) / 60)) ); } pop(@{$presence->[$#{$presence}]}); } } else { if ((scalar @{$presence} > 2) && (scalar @{$presence->[$#{$presence}-1]} == 3) && (scalar @{$presence->[$#{$presence}-2]} == 3) && ($presence->[$#{$presence}-1][0] eq 'away') && ($presence->[$#{$presence}-2][0] eq 'online') && (($presence->[$#{$presence}-1][2] - $presence->[$#{$presence}-1][1]) < 900)) { if ($user->GetField('debug_presence')) { # FIXME: remove my $start = new Orangutan::Date($presence->[$#{$presence}-1][1]); my $end = new Orangutan::Date($presence->[$#{$presence}-1][2]); my $duration = $end->Date - $start->Date; my $online = new Orangutan::Date($presence->[$#{$presence}-2][1]); my $lasting = $time->Date - $online->Date; $main::users->TellCreator( sprintf("User %s went away - removing short away period (%02d:%02d - %02d:%02d = %d:%02d), ". "this way increasing online period (%02d:%02d - %02d:%02d = %d:%02d).", $user->GetJabberUserID, $start->GetTime, $end->GetTime, int($duration / 3600), int(($duration % 3600) / 60), $online->GetTime, $time->GetTime, int($lasting / 3600), int(($lasting % 3600) / 60)) ); } splice(@{$presence}, -2); } $presence->[$#{$presence}][2] = $time->Date; push(@{$presence}, [ 'away', $time->Date ]); } } } } if ($created && (scalar @{$presence} > 0)) { $user->SetField('presence', $presence); } }, schedule => sub { my ($context, $scheduler, $arg) = @_; if ($arg eq 'clean') { my $time = new Orangutan::Date; foreach my $username ($main::users->GetUsers) { my $user = $main::users->GetUser($username); my $presence = $user->GetField('presence'); if (defined($presence)) { my $i = 0; my $date = $user->PreviousWorkDay($time); while ($i < scalar @{$presence}) { if (!defined($presence->[$i][2])) { last; } elsif ($presence->[$i][2] < $date->Date) { splice(@{$presence}, $i, 1); } elsif (($presence->[$i][2] - $presence->[$i][1]) < 900) { if (($i > 0) && ($i < $#{$presence}) && ($presence->[$i-1][0] eq $presence->[$i+1][0])) { $presence->[$i-1][2] = $presence->[$i+1][2]; splice(@{$presence}, $i, 2); } else { splice(@{$presence}, $i, 1); } } else { $i++; } } if ($user->GetField('debug_presence')) { # FIXME: remove my $message = 'History for user '.$username.":\n"; for ($i = 0; $i < scalar @{$presence}; $i++) { my $start = new Orangutan::Date($presence->[$i][1]); my $end = new Orangutan::Date($presence->[$i][2]); my $duration = $end->Date - $start->Date; $message .= sprintf("%s %02d:%02d - %02d:%02d = %d:%02d: %s\n", $start->DateTime('date'), $start->GetTime, $end->GetTime, int($duration / 3600), int(($duration % 3600) / 60), $presence->[$i][0]); } $main::users->TellCreator($message); } } } } my ($hour, $day, $month, $year) = (localtime(time))[2..5]; if ($hour >= 6) { ($day, $month, $year) = (localtime(time + 86400))[3..5]; } my $time = POSIX::mktime(0, 0, 6, $day, $month, $year); $scheduler->Schedule($time, $context, 'clean'); }, init => sub { # FIXME: remove my ($context) = @_; if ($main::logger->{'stdout'}) { foreach my $username ($main::users->GetUsers) { my $user = $main::users->GetUser($username); $user->SetField('debug_presence', 1); } } } ); # kate: syntax perl