Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl -w
- use strict;
- use feature "state";
- use Data::Dumper;
- use Storable;
- use DateTime;
- use Switch;
- use Time::Format;
- use WebService::GData::YouTube;
- use LWP::Simple;
- use Data::Validate::URI qw(is_web_uri);
- use POE;
- use POE::Component::IRC;
- use POE::Component::IRC::Plugin::Console;
- use POE::Component::IRC::Plugin::NickServID;
- use POE::Component::IRC::Plugin::BotAddressed;
- use POE::Component::IRC::Plugin::Logger;
- use WWW::Wikipedia;
- use WWW::YouTube::Info;
- use Google::Search;
- use DBI;
- my $dbh = DBI->connect("dbi:SQLite:dbname=raven.db","","") or die $DBI::errstr;
- my @tables = $dbh->tables();
- my @help = (
- ['.8ball','Predict the future with yes/no questions. - ex. .8ball Is Raven awesome?'],
- ['.tell','Leave a message for a user - ex. .tell user The server is down again.'],
- ['.google','Search Google and return the first result'],
- ['.youtube','Search YouTube and return the first result'],
- ['.wiki','Search for a wiki on the selected topic'],
- ['.down','Check if a website is down.'],
- ['.quote','Record or play back a quote. ".quote" random quote from any user, ".quote user" random quote for the user, ".quote user Message to be quoted" save a new quote'],
- ['.info','Record or play back stored info'],
- ['.define','Look up a definition of a word'],
- ['.urban','Search the Urban Dictionary'],
- ['.devbukkit','Search dev.bukkit.org for plugins'],
- ['.seen','Show last activity for a user'],
- );
- my @ophelp = (
- ['join','Join a channel'],
- ['part','Leave a channel'],
- ['op','Add an op'],
- ['deop','Remove an op'],
- ['speakas','Make the bot say something in a channel or to a user - ex. /msg RavenBot #MyChannel What are you doing, Dave?'],
- ['emoteas','Make the bot perform a CTCP ACTION [/me] in a channel or to a user chat'],
- ['shutdown','Terminate the bot'],
- );
- my $URLValidator = Data::Validate::URI->new();
- # Create tables (if they don't exist)
- $dbh->do("CREATE TABLE IF NOT EXISTS Channels(name)");
- $dbh->do("CREATE TABLE IF NOT EXISTS Ops(name)");
- $dbh->do("CREATE TABLE IF NOT EXISTS Tells(sender, rcpt, channel, message)");
- $dbh->do("CREATE TABLE IF NOT EXISTS Info(key PRIMARY KEY, data)");
- $dbh->do("CREATE TABLE IF NOT EXISTS Quotes(user, data)");
- $dbh->do("CREATE TABLE IF NOT EXISTS LastSeen(user PRIMARY KEY, timestamp)");
- # Prepare Database statements
- my $addQuote = $dbh->prepare("INSERT INTO Quotes(user, data) VALUES (?, ?);");
- my $getUserQuote = $dbh->prepare("SELECT data FROM Quotes WHERE user = ? ORDER BY RANDOM () LIMIT 1;");
- my $getAnyQuote = $dbh->prepare("SELECT user, data FROM Quotes ORDER BY RANDOM () LIMIT 1;");
- my $updateLastSeen = $dbh->prepare("REPLACE INTO LastSeen(user, timestamp) VALUES (?, ?);");
- my $getLastSeen = $dbh->prepare("SELECT timestamp FROM LastSeen WHERE user = ?;");
- my $updateInfo = $dbh->prepare("REPLACE INTO Info(key, data) VALUES (?, ?);");
- my $getInfo = $dbh->prepare("SELECT data FROM Info WHERE key = ?;");
- my $addTell = $dbh->prepare("INSERT INTO Tells(sender, rcpt, channel, message) VALUES (?, ?, ?, ?);");
- my $getTells = $dbh->prepare("SELECT rowid, sender, channel, message FROM Tells WHERE rcpt = ?;");
- my $removeTells = $dbh->prepare("DELETE FROM Tells WHERE rcpt = ?;");
- my $addChannel = $dbh->prepare("REPLACE INTO Channels (name) VALUES (?);");
- my $removeChannel = $dbh->prepare("DELETE FROM Channels WHERE name = ?;");
- my $addOp = $dbh->prepare("REPLACE INTO Ops (name) VALUES (?);");
- my $removeOp = $dbh->prepare("DELETE FROM Ops WHERE name = ?;");
- # Finished setup
- # Color contants
- my $WHITE = "\x0300";
- my $BLACK = "\x0301";
- my $BLUE = "\x0302";
- my $GREEN = "\x0303";
- my $RED = "\x0304";
- my $BROWN = "\x0305";
- my $PURPLE = "\x0306";
- my $ORANGE = "\x0307";
- my $YELLOW = "\x0308";
- my $LIGHT_GREEN = "\x0309";
- my $TEAL = "\x0310";
- my $LIGHT_CYAN = "\x0311";
- my $LIGHT_BLUE = "\x0312";
- my $PINK = "\x0313";
- my $GREY = "\x0314";
- my $LIGHT_GREY = "\x0315";
- my $NORMAL = "\x0f";
- my @magic8ball = (
- qq<$GREEN Signs point to yes.>,
- qq<$GREEN Yes.>,
- qq<$YELLOW Reply hazy, try again.>,
- qq<$GREEN Without a doubt.>,
- qq<$RED My sources say no.>,
- qq<$GREEN As I see it, yes.>,
- qq<$GREEN You may rely on it.>,
- qq<$YELLOW Concentrate and ask again.>,
- qq<$RED Outlook not so good.>,
- qq<$GREEN It is decidedly so.>,
- qq<$YELLOW Better not tell you now.>,
- qq<$RED Very doubtful.>,
- qq<$GREEN Yes - definitely.>,
- qq<$GREEN It is certain.>,
- qq<$YELLOW Cannot predict now.>,
- qq<$GREEN Most likely.>,
- qq<$YELLOW Ask again later.>,
- qq<$RED My reply is no.>,
- qq<$GREEN Outlook good.>,
- qq<$RED Do not count on it.>,
- );
- my ($irc) = POE::Component::IRC->spawn();
- my @channels = &LoadChannels;
- my @ops = &LoadOps;
- POE::Session->create(
- inline_states => {
- _start => \&bot_start,
- irc_001 => \&on_connect,
- irc_public => \&on_public,
- irc_msg => \&on_private,
- irc_join => \&on_join,
- irc_bot_mentioned => \&on_mention,
- irc_kick => \&on_kick,
- irc_disconnected => \&on_disconnect,
- },
- );
- sub bot_start {
- $irc->yield(register => "all");
- my $nick = "RavenBot";
- $irc->yield(connect => {
- Nick => $nick,
- Username => 'ravenbot',
- Ircname => q{MCPortCentral's RavenBot},
- Server => 'irc.esper.net',
- Port => '6667',
- Flood => 'true',
- }
- );
- #$irc->plugin_add( 'Console', POE::Component::IRC::Plugin::Console->new( bindport => 1234, password => 'test' ));
- $irc->plugin_add( 'NickServID', POE::Component::IRC::Plugin::NickServID->new( Password => 'Raven!@)(' ) );
- $irc->plugin_add( 'BotAddressed', POE::Component::IRC::Plugin::BotAddressed->new() );
- $irc->plugin_add( 'Logger', POE::Component::IRC::Plugin::Logger->new( Path => '/opt/RavenBot/ravenbot/logs', DCC => 0, Private => 1, Public => 1, ) );
- }
- sub on_connect {
- $irc->yield(join => $_) for @channels;
- return;
- }
- sub on_disconnect {
- &bot_start;
- return;
- }
- sub on_public {
- my ($kernel, $who, $where, $msg) = @_[KERNEL, ARG0, ARG1, ARG2];
- my $nick = (split /!/, $who)[0];
- my $channel = $where->[0];
- my $dt = DateTime->now( time_zone=> 'UTC' );
- my $ts = $dt->epoch;
- my $isOp = 0;
- if ($msg =~ /youtube\.com/) {
- my @matches = ($msg =~ m/v\=.*/g);
- my $videoid = substr($matches[0],2,11);
- my $yt = new WebService::GData::YouTube();
- $yt->query->q($videoid)->limit(1,0);
- my $videos = $yt->search_video();
- if (!(defined $videos)) { return }
- my $length = $$videos[0]->{_feed}{'media$group'}{'yt$duration'}{'seconds'};
- my $time = &ConvertFromSeconds($length);
- my $url = $$videos[0]->{_feed}{link}[0]{href};
- $url =~ s/\&feature=youtube_gdata//g;
- my $uploader = $$videos[0]->{_feed}{'media$group'}{'media$credit'}[0]{'yt$display'};
- my $uploadedon = substr($$videos[0]->{_feed}{'media$group'}{'yt$uploaded'}{text}, 0, 10);
- my $views = &AddCommas($$videos[0]->{_feed}{'yt$statistics'}{viewCount});
- eval{ $irc->yield(privmsg => $channel, $nick . qq<: \x02> . $$videos[0]->title . qq<\x02 - length: \x02> . $time . qq<\x02 - > . $url . qq< - \x02> . $views . qq<\x02 views - uploaded by: \x02> . $uploader . qq<\x02 on \x02> . $uploadedon . qq<\x02> ); };
- $irc->yield(privmsg => $channel, $nick . qq<: Error while finding information>) if $@;
- }
- foreach (@ops) {
- if ( $nick eq $_ ) { $isOp = 1; }
- }
- $getTells->execute($nick);
- while (my $row = $getTells->fetchrow_hashref){
- $irc->yield(notice => $nick, $$row{'sender'} . ' in ' . $$row{'channel'} . '> ' . $$row{'message'});
- $dbh->do("DELETE FROM Tells where rowid = " . $$row{'rowid'} . ";");
- }
- $updateLastSeen->execute($nick, $ts);
- if ($msg =~ /^\./) {
- my ($command, @cmdargs) = (split / /, $msg);
- switch ($command)
- {
- case '.8ball' {
- my $response = $magic8ball[rand @magic8ball];
- my $question = "";
- for (my $i = 0; $i <= $#cmdargs; $i++) {
- $question .= $cmdargs[$i] . " ";
- }
- chop($question);
- $irc->yield(privmsg => $channel, $nick . q< asked "> . $question . q<" - > . $response);
- }
- case /\.t($|ell$)/ {
- my $numArgs = @cmdargs;
- if ($numArgs == 0) {
- $irc->yield(privmsg => $channel, qq<$nick: Who did you want to tell and what?>);
- return;
- }
- if ($numArgs == 1) {
- $irc->yield(privmsg => $channel, qq<$nick: What did you want to tell that user?>);
- } else {
- my $rcpt = $cmdargs[0];
- my $msg = "";
- for (my $i =1; $i <= $#cmdargs; $i++) {
- $msg .= $cmdargs[$i] . " ";
- }
- chop($msg);
- $addTell->execute($nick, $rcpt, $channel, $msg);
- $irc->yield(privmsg => $channel, qq<$nick: \x02$rcpt\x02 will be notified on their next activity.>);
- }
- }
- case /\.g($|oogle$)/ {
- my $query = "";
- for (my $i = 0; $i <= $#cmdargs; $i++) {
- $query .= $cmdargs[$i] . " ";
- }
- chop($query);
- my $search = Google::Search->Web( query => $query );
- eval{
- my $result = $search->first;
- my $content;
- if (defined $result) {
- $content = $result->content;
- } else {
- $content = "No results found";
- }
- $content =~ s|<.+?>||g;
- $irc->yield(privmsg => $channel, $nick . q<: > . $result->unescapedUrl . qq< - \x02> . $result->titleNoFormatting . qq<\x02: "> . $content . q<">);
- };
- $irc->yield(privmsg => $channel, $nick . qq<: Error while finding information>) if $@;
- }
- case /\.(yt$|youtube$)/ {
- my $yt = new WebService::GData::YouTube();
- my $query = "";
- for (my $i = 0; $i <= $#cmdargs; $i++) {
- $query .= $cmdargs[$i] . " ";
- }
- chop($query);
- eval{
- $yt->query->q($query)->limit(1,0);
- my $videos = $yt->search_video();
- my $length = $$videos[0]->{_feed}{'media$group'}{'yt$duration'}{'seconds'};
- my $time = &ConvertFromSeconds($length);
- my $url = $$videos[0]->{_feed}{link}[0]{href};
- $url =~ s/\&feature=youtube_gdata//g;
- my $uploader = $$videos[0]->{_feed}{'media$group'}{'media$credit'}[0]{'yt$display'};
- my $uploadedon = substr($$videos[0]->{_feed}{'media$group'}{'yt$uploaded'}{text}, 0, 10);
- my $views = &AddCommas($$videos[0]->{_feed}{'yt$statistics'}{viewCount});
- $irc->yield(privmsg => $channel, $nick . qq<: \x02> . $$videos[0]->title . qq<\x02 - length: \x02> . $time . qq<\x02 - > . $url . qq< - \x02> . $views . qq<\x02 views - uploaded by: \x02> . $uploader . qq<\x02 on \x02> . $uploadedon . qq<\x02> );
- };
- $irc->yield(privmsg => $channel, $nick . qq<: Error while finding information>) if $@;
- }
- case ".wiki" {
- my $query = "wiki ";
- for (my $i = 0; $i <= $#cmdargs; $i++) {
- $query .= $cmdargs[$i] . " ";
- }
- chop($query);
- eval{
- my $search = Google::Search->Web( query => $query );
- my $result = $search->first;
- my $content = $result->content;
- $content =~ s|<.+?>||g;
- $irc->yield(privmsg => $channel, $nick . q<: > . $result->unescapedUrl . qq< - \x02> . $result->titleNoFormatting . qq<\x02: "> . $content . q<">);
- };
- $irc->yield(privmsg => $channel, $nick . qq<: Error while finding information>) if $@;
- }
- case ".down" {
- my $url = $cmdargs[0];
- if ($URLValidator->is_web_uri( $url )) {
- my $status = "";
- if (! head($url) ){
- $status = "$url appears to be " . $RED . "down" . $NORMAL . "!";
- } else {
- $status = "$url appears to be " . $GREEN . "up" . $NORMAL . "!";
- }
- $irc->yield(privmsg => $channel, $nick . qq<: $status>);
- } else {
- $irc->yield(privmsg => $channel, $nick . qq<: $url does not appear to be a valid URL.>);
- }
- }
- case /\.q($|uote$)/ {
- my $numArgs = @cmdargs;
- if ($numArgs == 0) {
- $getAnyQuote->execute;
- my $result = $getAnyQuote->fetchrow_hashref;
- $irc->yield(privmsg => $channel, '<' . $$result{'user'} . '> ' . $$result{'data'});
- return;
- }
- if ($numArgs == 1) {
- $getUserQuote->execute($cmdargs[0]);
- my $result = $getUserQuote->fetch;
- if (!(defined $result)) {
- $irc->yield(privmsg => $channel, 'No quotes found for ' . $cmdargs[0] . '.');
- return;
- }
- $irc->yield(privmsg => $channel, '<' . $cmdargs[0] . '> ' . $$result[0]);
- } else {
- my $user = $cmdargs[0];
- my $quote = "";
- for (my $i =1; $i <= $#cmdargs; $i++) {
- $quote .= $cmdargs[$i] . " ";
- }
- chop($quote);
- $addQuote->execute($user, $quote);
- $irc->yield(privmsg => $channel, qq<$nick: Quote added to database.>);
- }
- }
- case /\.i($|nfo$)/ {
- my $numArgs = @cmdargs;
- if ($numArgs == 0) {
- $irc->yield(privmsg => $channel, qq<$nick: No key specified.>);
- return;
- }
- if ($numArgs == 1) {
- $getInfo->execute($cmdargs[0]);
- my $result = $getInfo->fetch;
- $irc->yield(privmsg => $channel, qq<\x02> . $cmdargs[0] . qq<\x02 - > . $$result[0]);
- } else {
- my $key = $cmdargs[0];
- my $data = "";
- for (my $i = 1; $i <= $#cmdargs; $i++) {
- $data .= $cmdargs[$i] . " ";
- }
- chop($data);
- $updateInfo->execute($key, $data);
- $irc->yield(privmsg => $channel, qq<$nick: Value set.>);
- }
- }
- case ".define" {
- my $query = "define:";
- for (my $i = 0; $i <= $#cmdargs; $i++) {
- $query .= $cmdargs[$i] . " ";
- }
- chop($query);
- eval{
- my $search = Google::Search->Web( query => $query );
- my $result = $search->first;
- #print Dumper($result);
- my $content = $result->content;
- $content =~ s|<.+?>||g;
- $irc->yield(privmsg => $channel, $nick . q<: > . $result->unescapedUrl . qq< - \x02> . $result->titleNoFormatting . qq<\x02: "> . $content . q<">);
- };
- $irc->yield(privmsg => $channel, $nick . qq<: Error while finding information>) if $@;
- }
- case ".urban" {
- my $query = "site:urbandictionary.com ";
- for (my $i = 0; $i <= $#cmdargs; $i++) {
- $query .= $cmdargs[$i] . " ";
- }
- chop($query);
- eval{
- my $search = Google::Search->Web( query => $query );
- my $result = $search->first;
- my $content = $result->content;
- $content =~ s|<.+?>||g;
- $irc->yield(privmsg => $channel, $nick . q<: > . $result->unescapedUrl . qq< - \x02> . $result->titleNoFormatting . qq<\x02: "> . $content . q<">);
- };
- $irc->yield(privmsg => $channel, $nick . qq<: Error while finding information>) if $@;
- }
- case /.(db$|devbukkit$)/ {
- my $query = "site:dev.bukkit.org ";
- for (my $i = 0; $i <= $#cmdargs; $i++) {
- $query .= $cmdargs[$i] . " ";
- }
- chop($query);
- my $search = Google::Search->Web( query => $query );
- eval{
- my $result = $search->first;
- my $content;
- if (defined $result) {
- $content = $result->content;
- } else {
- $content = "No results found";
- }
- $content =~ s|<.+?>||g;
- $irc->yield(privmsg => $channel, $nick . q<: > . $result->unescapedUrl . qq< - \x02> . $result->titleNoFormatting . qq<\x02: "> . $content . q<">);
- };
- $irc->yield(privmsg => $channel, $nick . qq<: Error while finding information>) if $@;
- }
- case ".seen" {
- my $numArgs = @cmdargs;
- if ($numArgs >= 1) {
- my $user = $cmdargs[0];
- $getLastSeen->execute($user);
- my $result = $getLastSeen->fetch;
- if (!(defined $result)){
- $irc->yield(privmsg => $channel, qq<\x02$user\x02 does not have any known activity.>);
- return;
- }
- my $time = $$result[0];
- my $lastseen = DateTime->from_epoch ( epoch => $time );
- my $lsmsg = $lastseen->day . '-' . $lastseen->month_abbr . '-' . $lastseen->year . ' ' . $lastseen->hms . ' UTC';
- my $duration = &ConvertFromSeconds(($ts - $time));
- $irc->yield(privmsg => $channel, qq<\x02$user\x02 was last seen $lsmsg ($duration ago).>);
- }
- }
- case /.(brainfuck$|bf$)/ {
- $irc->yield(privmsg => $channel, qq<\x02$nick\x02 No esoteric programming languages allowed.>);
- }
- case /.help$/ {
- for (my $i = 0; $i <= $#help; $i++) {
- $irc->yield(notice => $nick, $help[$i][0] . ' - ' . $help[$i][1]);
- }
- }
- }
- }
- return;
- }
- sub on_private {
- my ($kernel, $from, $to, $msg, $identified) = @_[KERNEL, ARG0, ARG1, ARG2, ARG3];
- my $nick = (split /!/, $from)[0];
- my ($command, @cmdargs) = (split / /, $msg);
- my $isOp = 0;
- foreach (@ops) {
- if ( $nick eq $_ ) { $isOp = 1; }
- }
- switch ($command) {
- case 'tables' {
- if ($isOp == 1) {
- $irc->yield(privmsg => $nick, @tables);
- } else {
- $irc->yield(privmsg => $nick, "You cannot do that.");
- }
- }
- case 'emoteas' {
- if ($isOp == 1) {
- my $response;
- for (my $i = 1; $i <= $#cmdargs; $i++) {
- $response .= $cmdargs[$i] . " ";
- }
- $irc->yield(ctcp => $cmdargs[0], qq<ACTION $response>);
- $irc->yield(privmsg => $nick, "Sent!");
- } else {
- $irc->yield(privmsg => $nick, "You cannot do that.");
- }
- }
- case 'speakas' {
- if ($isOp == 1) {
- my $response;
- for (my $i = 1; $i <= $#cmdargs; $i++) {
- $response .= $cmdargs[$i] . " ";
- }
- $irc->yield(privmsg => $cmdargs[0], $response);
- $irc->yield(privmsg => $nick, "Sent!");
- } else {
- $irc->yield(privmsg => $nick, "You cannot do that.");
- }
- }
- case 'join' {
- if ($isOp == 1) {
- $irc->yield(join => $cmdargs[0]);
- $addChannel->execute($cmdargs[0]);
- } else {
- $irc->yield(privmsg => $nick, "You cannot do that.");
- }
- }
- case 'part' {
- if ($isOp == 1) {
- $irc->yield(part => $cmdargs[0]);
- $removeChannel->execute($cmdargs[0]);
- } else {
- $irc->yield(privmsg => $nick, "You cannot do that.");
- }
- }
- case 'op' {
- if ($isOp == 1) {
- push(@ops, $cmdargs[0]);
- $addOp->execute($cmdargs[0]);
- $irc->yield(privmsg => $nick, "You have granted op to $cmdargs[0].");
- } else {
- $irc->yield(privmsg => $nick, "You cannot do that.");
- }
- }
- case 'deop' {
- if ($isOp == 1) {
- my $index = &Find($cmdargs[0], @ops);
- delete $ops[$index];
- $removeOp->execute($cmdargs[0]);
- $irc->yield(privmsg => $nick, "You have removed op from $cmdargs[0].");
- } else {
- $irc->yield(privmsg => $nick, "You cannot do that.");
- }
- }
- case 'shutdown' {
- if ($isOp == 1) {
- $irc->yield(quit => "Nevermore!");
- $irc->yield(shutdown => "");
- } else {
- $irc->yield(privmsg => $nick, "You cannot do that.");
- }
- }
- case 'help' {
- for (my $i = 0; $i <= $#ophelp; $i++) {
- $irc->yield(privmsg => $nick, $ophelp[$i][0] . ' - ' . $ophelp[$i][1]);
- }
- }
- else {
- $irc->yield(privmsg => $nick, "I don't recognize that.");
- }
- }
- return;
- }
- sub on_join {
- return;
- }
- sub on_mention {
- state $lastCall = 0;
- my ($kernel, $who, $where, $msg) = @_[KERNEL, ARG0, ARG1, ARG2];
- my $nick = (split /!/, $who)[0];
- my $channel = $where->[0];
- my $ts = DateTime->now( time_zone => 'UTC' );
- if ($ts->epoch >= ($lastCall + 60) && !($msg =~ /^[\.<]/)) {
- $irc->yield(ctcp => $channel, "ACTION senses someone talking about it.");
- $lastCall = $ts->epoch;
- }
- return;
- }
- sub on_kick {
- my ($kernel, $kicker, $where, $kickee, $why) = @_[KERNEL, ARG0, ARG1, ARG2, ARG3];
- my $nick = (split /!/, $kickee)[0];
- my $channel = $where;
- $irc->yield(privmsg => $channel, "Meh... I didn't like them anyway. :P");
- return;
- }
- sub irc_console_connect {
- my ($peeradr, $peerport, $wheel_id) = @_[ARG0 .. ARG2];
- return;
- }
- sub irc_console_authed {
- my $wheel_id = $_[ARG0];
- return;
- }
- sub irc_console_close {
- my $wheel_id = $_[ARG0];
- return;
- }
- sub irc_console_rw_fail {
- my ($peeradr, $peerport) = @_[ARG0, ARG1];
- return;
- }
- $poe_kernel->run();
- exit 0;
- sub LoadOps {
- my $results = $dbh->selectall_arrayref("SELECT name FROM Ops;", { Slice => {} });
- my @ops;
- foreach my $entry ( @$results ) {
- push(@ops, $entry->{name});
- }
- if (!(@ops)) {
- print "No ops defined. Please enter name of first op: ";
- my $firstop = <>;
- chomp($firstop);
- push(@ops, $firstop);
- }
- return @ops;
- }
- sub LoadChannels {
- my $results = $dbh->selectall_arrayref("SELECT name FROM Channels;", { Slice => {} });
- my @channels;
- foreach my $entry ( @$results ) {
- push (@channels, $entry->{name});
- }
- return @channels;
- }
- sub Find($@) {
- my $s = shift;
- $_ eq $s && return @_ while $_=pop;
- -1;
- }
- sub AddCommas {
- local $_ = shift;
- 1 while s/^([-+]?\d+)(\d{3})/$1,$2/;
- return $_;
- }
- sub ConvertFromSeconds {
- my $seconds = $_[0];
- my $days = "";
- my $hours = "";
- my $minutes = "";
- if ($seconds > 86400) {
- $days = int($seconds / 86400) . "d ";
- $seconds = $seconds % 86400;
- } else {
- $days = "";
- }
- if ($seconds > 3600) {
- $hours = int($seconds / 3600) . "h ";
- $seconds = $seconds % 3600;
- } else {
- $hours = "";
- }
- if ($seconds > 60) {
- $minutes = int($seconds / 60) . "m ";
- $seconds = $seconds % 60;
- } else {
- $minutes = "";
- }
- if ($seconds > 0) {
- $seconds .= "s"
- } else {
- $seconds = "0s";
- }
- return ($days . $hours . $minutes . $seconds);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement