Index: bot_seen/bot_seen.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/bot/bot_seen/Attic/bot_seen.install,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 bot_seen.install
--- bot_seen/bot_seen.install	5 Jan 2007 03:32:23 -0000	1.1.2.1
+++ bot_seen/bot_seen.install	7 Aug 2007 05:02:46 -0000
@@ -13,6 +13,7 @@ function bot_seen_install() {
         channel varchar(60) NOT NULL default '',
         message text NOT NULL default '',
         timestamp int NOT NULL default '0',
+        back_in int NOT NULL default -1,
         PRIMARY KEY (nick)
       ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
       break;
@@ -22,8 +23,23 @@ function bot_seen_install() {
         channel varchar(60) NOT NULL default '',
         message text NOT NULL default '',
         timestamp integer NOT NULL default '0',
+        back_in int NOT NULL default -1,
         PRIMARY KEY (nick)
       )");
       break;
   }
 }
+
+function bot_seen_update_1() {
+  switch ($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      break;
+    case 'pgsql':
+      $ret[] = update_sql("ALTER TABLE {bot_seen} ADD COLUMN back_in integer");
+      $ret[] = update_sql("UPDATE {bot_seen} SET back_in = -1");
+      $ret[] = update_sql("ALTER TABLE {bot_seen} ALTER COLUMN back_in set NOT NULL");
+      $ret[] = update_sql("ALTER TABLE {bot_seen} ALTER COLUMN back_in set default -1");
+      break;
+  }
+}
Index: bot_seen/bot_seen.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/bot/bot_seen/Attic/bot_seen.module,v
retrieving revision 1.1.2.7
diff -u -p -r1.1.2.7 bot_seen.module
--- bot_seen/bot_seen.module	29 Jun 2007 02:38:43 -0000	1.1.2.7
+++ bot_seen/bot_seen.module	7 Aug 2007 05:02:46 -0000
@@ -32,9 +32,9 @@ function bot_seen_irc_msg_channel($data,
   $to = $from_query ? $data->nick : $data->channel;
   $nicks = array(); // list of nicks to search for.
 
-  // log the message, whatever it is. no UPDATEs; just start anew, eh?
-  db_query("DELETE FROM {bot_seen} WHERE LOWER(nick) = '%s'", drupal_strtolower($data->nick));
-  db_query("INSERT INTO {bot_seen} (nick, channel, message, timestamp) VALUES ('%s', '%s', '%s', %d)", $data->nick, $data->channel, $data->message, time());
+  bot_seen_update_last_seen($data);
+
+  bot_seen_match_away($data);
 
   // Match 'seen foo' in any mode, regardless if the bot was addressed.
   if (preg_match("/^seen ([a-zA-Z0-9\[\]\{\}\\\|\^\`\-\_\*]*)( ?\?|$)/i", $data->message, $matches)) {
@@ -64,10 +64,165 @@ function bot_seen_irc_msg_channel($data,
 
   // display a maximum of up to three results to...
   $messages = array_splice($messages, 0, 3); // ...prevent flooding.
-  foreach ($messages as $message) { bot_message($to, $message); }
+  foreach ($messages as $message) {
+    bot_message($to, $message);
+  }
   // @todo include a message stating number of results not shown.
 }
 
+function bot_seen_update_last_seen($data) {
+  $message = "";
+  $back_in = bot_seen_parse_absence_time($data->message, $message);
+  if($message != "") {
+    $message = preg_replace("/,\s+$/", "", $message);
+    $data->message = $message;
+  }
+  
+  // log the message, whatever it is. no UPDATEs; just start anew, eh?
+  db_query("DELETE FROM {bot_seen} WHERE LOWER(nick) = '%s'", drupal_strtolower($data->nick));
+  db_query("INSERT INTO {bot_seen} (nick, channel, message, timestamp, back_in) VALUES ('%s', '%s', '%s', %d)", $data->nick, $data->channel, $data->message, time(), $back_in);
+}
+
+function bot_seen_match_away($data) {
+  $query_args = array();
+  $query = "SELECT * FROM bot_seen WHERE LOWER(nick) IN('%s'";
+  $query_args[] = $data->nick;
+  // Indicate if anyone was messaging someone else.  The default is no
+  $flag = FALSE;
+  if(preg_match("/^([\w()\[\]!^`{}-]+): /", $data->message, $matches)) {
+    // Ignore messages to the bot
+    if($matches[1] != variable_get('bot_nickname', 'bot_module')) {
+      $query_args[] = $matches[1];
+      $query .= ", '%s'";
+      $flag = TRUE;
+    }
+  }
+  $query .= ")";
+  $result = db_query($query, $query_args);
+  $seen = db_fetch_object($result);
+  if($seen->back_in != 0) {
+    bot_message($data->channel, "Welcome back, ". $data->nick);
+    // We don't need to set the back_in time because it's set in bot_update
+  }
+  if($flag) {
+    $other_nick = db_fetch_object($result);
+    if($other_nick->back_in > time()) {
+      $time = bot_seen_verbose_format_interval($other_nick->back_in - time());
+      bot_message($query_args[1] ." is expected back in ". $time);
+    }
+  }
+}
+
+/**
+ * Tries to get an absence time from a user msg.
+ *
+ * @param $string
+ *   A regular chat line the user emitted.
+ * @return
+ *   The interval in seconds or FALSE if none given.
+ */
+function bot_seen_parse_absence_time($string, &$message) {
+  $interval = '(\d+|(?:an|a|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|sixteen|seventeen|eighteen|ninteen|twenty|thirty|fourty|fifty|sixty|seventy|eighty|ninty|hundred|thousand)\s+)\s*(hours?|hrs?|h|hs|minutes?|mins?|mn|m|seconds?|sc|secs?|s)\s*(?:,|\s*and\s*)?\s*';
+  if (preg_match('~(.*,\s+)?(?:^\s*|\bI(?:\'|’|\s+wi)ll\s+)(?:bb|be\s+back|return\s+in|see\s+you)\s*(?:[a-z]+\s+){0,3}(?:'. $interval .')(?:'. $interval .')?(?:'. $interval .')?~i', $string, $matches)) {
+    array_shift($matches);
+    $message = array_shift($matches);
+    for ($i = 0, $time = 0; isset($matches[$i]) && isset($matches[$i + 1]); $i += 2) {
+      $time += bot_seen_parse_interval($matches[$i], $matches[$i + 1]);
+    }
+    return $time;
+  }
+
+  return 0;
+}
+
+/**
+ * Parse an interval
+ * Parses an interval like 2 hours, two hours, 2h, 2hrs... 
+ * those are all 7200. Two hundred hours is also legal.
+ *
+ * @param $num 
+ *   The number, in either string or number.
+ * @param $quantifier 
+ *   minutes, seconds, hours, secs, s, h, etc.
+ * @return
+ *   The amount of time in seconds
+ */
+function bot_seen_parse_interval($num, $quantifier) {
+  if (is_numeric($num)) {
+    $num = (int)$num;
+  }
+  elseif (!is_integer($num)) {
+    $_num = split("[ -]", $num);
+    $num = 1;
+    print_r($_num);
+    foreach($_num as $n) {
+      switch (trim(strtolower($n))) {
+        case 'an':
+        case 'a':
+        case 'one':       $num *= 1;    break;
+        case 'two':       $num *= 2;    break;
+        case 'three':     $num *= 3;    break;
+        case 'four':      $num *= 4;    break;
+        case 'five':      $num *= 5;    break;
+        case 'six':       $num *= 6;    break;
+        case 'seven':     $num *= 7;    break;
+        case 'eight':     $num *= 8;    break;
+        case 'nine':      $num *= 9;    break;
+        case 'ten':       $num *= 10;   break;
+        case 'eleven':    $num *= 11;   break;
+        case 'twelve':    $num *= 12;   break;
+        case 'thirteen':  $num *= 13;   break;
+        case 'fourteen':  $num *= 14;   break;
+        case 'fifteen':   $num *= 15;   break;
+        case 'sixteen':   $num *= 16;   break;
+        case 'seventeen': $num *= 17;   break;
+        case 'eighteen':  $num *= 18;   break;
+        case 'ninteen':   $num *= 19;   break;
+        case 'twenty':    $num *= 20;   break;
+        case 'thirty':    $num *= 30;   break;
+        case 'fourty':    $num *= 40;   break;
+        case 'fifty':     $num *= 50;   break;
+        case 'sixty':     $num *= 60;   break;
+        case 'seventy':   $num *= 70;   break;
+        case 'eighty':    $num *= 80;   break;
+        case 'ninty':     $num *= 90;   break;
+        case 'hundred':   $num *= 100;  break;
+        case 'thousand':  $num *= 1000; break;
+        default:          $num += 0;    break;
+      }
+    }
+  }
+
+  switch (trim(strtolower($quantifier))) {
+    case 'hour': case 'hours': case 'hs': case 'hr': case 'hrs': case 'h':       $quantifier = 3600; break;
+    case 'minute': case 'minutes': case 'min': case 'mins': case 'mn': case 'm': $quantifier = 60; break;
+    case 'second': case 'seconds': case 'sec': case 'secs': case 'sc': case 's': $quantifier = 1; break;
+    default: $quantifier = 0; break;
+  }
+
+  return $quantifier * $num;
+}
+
+function bot_seen_verbose_format_interval($timestamp) {
+  $units = array('1 year|@count years' => 31536000, '1 week|@count weeks' => 604800, '1 day|@count days' => 86400, '1 hour|@count hours' => 3600, '1 minute|@count minutes' => 60);
+  $output = '';
+  // Keep a counter
+  $counter = 0;
+  foreach ($units as $key => $value) {
+    ++$counter;
+    if($counter == 2) {
+      return;
+    }
+    $key = explode('|', $key);
+    if ($timestamp >= $value) {
+      $extra = $timestamp % $value == 0 ? ', ' : ' and ';
+      $output .=  ($output ? $extra : '') . format_plural(floor($timestamp / $value), $key[0], $key[1]);
+      $timestamp %= $value;
+    }
+  }
+  return $output ? $output : t('0 seconds');
+}
+
 /**
  * All responses are available via a query.
  */
