Index: terminal.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/terminal/terminal.module,v
retrieving revision 1.8
diff -u -r1.8 terminal.module
--- terminal.module	11 Jun 2009 22:19:50 -0000	1.8
+++ terminal.module	24 Nov 2009 16:35:41 -0000
@@ -3,28 +3,20 @@
 // $Id: terminal.module,v 1.8 2009/06/11 22:19:50 snufkin Exp $
 
 /**
- * @file 
+ * @file
+ * Provides a Terminal to Drupal. 
  */
 
 /**
  * Implementation of hook_menu()
  */
 function terminal_menu() {
-  $items = array();
   $items['terminal/input'] = array(
     'title' => 'Terminal AJAX Callback',
     'page callback' => 'terminal_ajax_callback',
     'access arguments' => array('access terminal'),
     'type' => MENU_CALLBACK,
   );
-
-  $items['terminal/state'] = array(
-    'title' => 'State callback',
-    'page callback' => 'terminal_state_callback',
-    'access arguments' => array('access terminal'),
-    'type' => MENU_CALLBACK,
-  );
-
   return $items;
 }
 
@@ -36,77 +28,73 @@
 }
 
 /**
- * Terminal textarea
- */
-function terminal_form() {
-  $form = array();
-  return $form;
-}
-
-/**
  * Implementation of hook_init()
  */
 function terminal_init() {
   if (user_access('access terminal')) {
-  drupal_add_js(drupal_get_path('module', 'terminal') .'/terminal.js');
-  drupal_add_js(drupal_get_path('module', 'terminal') .'/jquery.terminal.js');
-  drupal_add_css(drupal_get_path('module', 'terminal') .'/terminal.css');
-  global $user;
-  $host = $_SERVER['host'];
-  $settings = array(
-    'user' => $user->name,
-    'host' => $host,
-    'sitename' => variable_get('site_name', ''),
-  );
-  drupal_add_js($settings, 'setting');
+    // The jQuery Plugin module contains the jQuery Cookie plugin, which is
+    // helpful to keep the terminal up if desired.
+    if (module_exists('jquery_plugin')) {
+      jquery_plugin_add('cookie');
+    }
+
+    // Add all the Terminal JavaScript and CSS.
+    drupal_add_js(drupal_get_path('module', 'terminal') .'/terminal.js');
+    drupal_add_js(drupal_get_path('module', 'terminal') .'/jquery.terminal.js');
+    drupal_add_css(drupal_get_path('module', 'terminal') .'/terminal.css');
+    global $user;
+    $settings = array(
+      'user' => $user->name,
+      'server' => $_SERVER['SERVER_NAME'],
+      'sitename' => variable_get('site_name', ''),
+    );
+    drupal_add_js(array('terminal' => $settings), 'setting');
   }
 }
 
 /**
- * Set/get the terminal visibility state
+ * Menu callback; A user executed a terminal command.
  */
-function terminal_state_callback($state = NULL) {
-  // Yes I know, per-user. Also not sure if its safe.
-  if (isset($state)) {
-    variable_set('terminal_state', $state);
-  }
-  else {
-    print variable_get('terminal_state', 'visible');
-  }
-}
-
 function terminal_ajax_callback() {
   $input = $_POST['input'];
-  terminal_log_history($input);
+  if (!empty($input)) {
+    // Retrieve the desired command, and construct the arguments.
+    $args = explode(' ', $input);
+    $name = array_shift($args);
+    $command = terminal_commands($name);
+    if (isset($command['callback']) && function_exists($command['callback'])) {
+      call_user_func($command['callback'], $args);
+    }
+    else {
+      print t('Terminal: !command: command not found', array('!command' => $name));
+    }
 
-  $args = explode(" ", $input);
-  $command = array_shift($args);
-  if (function_exists('terminal_'. $command)) {
-    call_user_func('terminal_'. $command, $args);
-  }
-  else {
-    print t('Invalid command');
+    // Log the executed command.
+    watchdog('terminal', 'Executed "%input" in the terminal.', array('%input' => $input));
   }
-
   exit;
 }
 
-function terminal_nodedel($args) {
-  $nid = $args[0];
-  $node = node_load($nid);
-  node_delete($nid);
-  print t('Node @title deleted', array('@title' => $node->title));
-}
-
-function terminal_goto($args) {
-  $path = $args[0];
-  print $path;
-}
-
-function terminal_adduser($args) {
-}
-
-function terminal_log_history($input) {
-  global $user;
-  db_query('INSERT INTO {terminal_history} (uid, input) VALUES (%d, "%s")', $input, $user->uid);
+/**
+ * Retrieves the available commands exposed to the Terminal.
+ *
+ * @param $command
+ *   If given, will return just information about the provided command.
+ * @return
+ *   All the available commands. If the $command parameter is provided, will
+ *   return just information on the given command. NULL if the command doesn't
+ *   exist.
+ */
+function terminal_commands($command = NULL) {
+  static $commands = NULL;
+  if (!isset($commands)) {
+    // Load all modulename.terminal.inc files.
+    module_load_all_includes('terminal.inc');
+    // Retrieve all available Terminal commands.
+    $commands = module_invoke_all('terminal');
+  }
+  if (isset($command)) {
+    return isset($commands[$command]) ? $commands[$command] : NULL;
+  }
+  return $commands;
 }
Index: terminal.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/terminal/terminal.install,v
retrieving revision 1.3
diff -u -r1.3 terminal.install
--- terminal.install	9 Jun 2009 18:42:16 -0000	1.3
+++ terminal.install	24 Nov 2009 16:35:41 -0000
@@ -2,31 +2,10 @@
 // $Id: terminal.install,v 1.3 2009/06/09 18:42:16 snufkin Exp $
 
 /**
- * Implementation of hook_schema()
-  */
-function terminal_schema() {
-  $schema = array();
-  $schema['terminal_history'] = array(
-    'description' => t('History of commands issued by the users.'),
-    'fields' => array(
-      'uid' => array(
-        'description' => t('User id of the user issuing the command.'),
-        'type' => 'int',
-      ),
-      'input' => array(
-        'description' => t('Full input submitted.'),
-        'type' => 'varchar',
-        'length' => 256,
-      ),
-    ),
-  );
-  return $schema;
-}
-
-function terminal_install() {
-  drupal_install_schema('terminal');
-}
-
-function terminal_uninstall() {
-  drupal_uninstall_schema('terminal');
+ * We can use watchdog instead of keeping our own Terminal history.
+ */
+function terminal_update_6001() {
+  $ret = array();
+  $ret[] = update_sql('DROP TABLE IF EXISTS {terminal_history}');
+  return $ret;
 }
Index: terminal.css
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/terminal/terminal.css,v
retrieving revision 1.1
diff -u -r1.1 terminal.css
--- terminal.css	11 Jun 2009 22:19:50 -0000	1.1
+++ terminal.css	24 Nov 2009 16:35:41 -0000
@@ -1,3 +1,5 @@
+/* $Id$ */
+
 #terminal-corner {
   position: fixed;
   bottom: 0;
@@ -14,7 +16,6 @@
   height: 200px;
 }
 
-
 #terminal-container input {
   background: #ccc;
 }
Index: terminal.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/terminal/terminal.js,v
retrieving revision 1.6
diff -u -r1.6 terminal.js
--- terminal.js	11 Jun 2009 22:19:50 -0000	1.6
+++ terminal.js	24 Nov 2009 16:35:41 -0000
@@ -1,64 +1,90 @@
 // $Id: terminal.js,v 1.6 2009/06/11 22:19:50 snufkin Exp $
 
+/**
+ * The base DrupalTerminal namespace.
+ */
+DrupalTerminal = {
+  visible: 0
+};
+
 if (Drupal.jsEnabled) {
   $(document).ready(function() {
-      // Attach the terminal to the bottom, hidden by default
-      $('html').append('<div id="terminal-container" style="display: none"></div>').append('<img id="terminal-corner" src="images/bar.png" />');
+    // Attach the terminal to the bottom, hidden by default
+    $('html').append('<div id="terminal-container" style="display: none"></div>').append('<img id="terminal-corner" src="images/bar.png" />');
 
-      // Corner recover icon
-      $('#terminal-corner').text('^---');
+    // Corner recover icon
+    $('#terminal-corner').text('^---');
 
-      var user = Drupal.settings['user'];
-      var host = Drupal.settings['user'];
-      var sitename = Drupal.settings['sitename'];
-      var welcome_message = 'Welcome to ' + sitename + '!';
-      var prompt = user + '@' + host + ' >';
-
-      $('#terminal-container').terminal('index.php?q=terminal/input', {custom_prompt : prompt, hello_message : welcome_message});
-
-      $.get('index.php?q=terminal/state', function(state) {
-        if ('visible' == state) {
-          $('#terminal-container').show();
+    var user = Drupal.settings['terminal']['user'];
+    var host = Drupal.settings['terminal']['server'];
+    var sitename = Drupal.settings['terminal']['sitename'];
+    var welcome_message = 'Welcome to ' + sitename + '!';
+    var prompt = user + '@' + host + ' >';
+
+    $('#terminal-container').terminal(Drupal.settings.basePath + '?q=terminal/input', {custom_prompt : prompt, hello_message : welcome_message});
+
+    // See whether or not we should display the terminal on page load.
+    DrupalTerminal.visible = jQuery.cookie ? $.cookie('DrupalTerminal') : 0;
+    if (DrupalTerminal.visible == 1) {
+      $('#terminal-container').show();
+      $('#terminal-corner').hide();
+    }
+    else {
+      $('#terminal-container').hide();
+      $('#terminal-corner').show();
+    }
+
+    // Register the terminal events.
+    $('#terminal-container').dblclick( function() {
+      DrupalTerminal.close();
+    });
+    $('#terminal-corner').click( function() {
+      DrupalTerminal.open();
+    });
+    if (window.addEventListener) {
+      window.addEventListener("keydown", function(e) {
+        if (e.keyCode == 192) {
+          DrupalTerminal.toggle();
         }
-        else {
-          $('#terminal-corner').show();
-        }
-      });
-
-
-      // Attach click events
-      DrupalTerminal.toggle();
+      }, true);
+    }
   });
 }
 
-DrupalTerminal = new Object;
-
-DrupalTerminal.toggle = function () {
-  $('#terminal-container').dblclick( function() {
-      $(this).toggle("slow", function() {
-        $('#terminal-corner').show();
-        DrupalTerminal.set('hidden');
-        });
-      });
-  $('#terminal-corner').click( function() {
-      $('#terminal-container').toggle("slow", function() {
-        $('#terminal-corner').hide();
-        DrupalTerminal.set('visible');
-        });
-      });
+/**
+ * Closes or displays the terminal depending on its current visibility.
+ */
+DrupalTerminal.toggle = function() {
+  if (DrupalTerminal.visible) {
+    return DrupalTerminal.close();
+  }
+  else {
+    return DrupalTerminal.open();
+  }
 }
 
 /**
- * Set the terminal state via callback
+ * Opens the terminal.
  */
-DrupalTerminal.set = function(state) {
-  $.get('index.php?q=terminal/state/' + state);
-}
+DrupalTerminal.open = function() {
+  $('#terminal-container').slideDown("slow", function() {
+    $('#terminal-corner').hide();
+  });
+  if (jQuery.cookie) {
+    $.cookie('DrupalTerminal', 1);
+  }
+  return DrupalTerminal.visible = 1;
+};
 
 /**
- * Fetch the terminal state.
+ * Closes the terminal.
  */
-DrupalTerminal.get = function() {
-  $.get('index.php?q=terminal/state', function(state) {
+DrupalTerminal.close = function() {
+  $('#terminal-container').slideUp("slow", function() {
+    $('#terminal-corner').show();
   });
-}
+  if (jQuery.cookie) {
+    $.cookie('DrupalTerminal', 0);
+  }
+  return DrupalTerminal.visible = 0;
+};
Index: terminal.api.php
===================================================================
RCS file: terminal.api.php
diff -N terminal.api.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ terminal.api.php	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,22 @@
+<?php
+// $Id$
+
+/**
+ * Expose a method to be executed by the Drupal Terminal.
+ *
+ * @return
+ *   An array of terminal commands. Each command has one of the following items:
+ *   - "title": The name of the command.
+ *   - "description": A short help text for the command.
+ *   - "callback": The function callback which is executed when the command is
+ *     run by the user.
+ */
+function hook_terminal() {
+  $commands['help'] = array(
+    'title' => t('Help'),
+    'pattern' => t('help [pattern]'),
+    'description' => t('Displays helpful information about builtin commands. If PATTERN is specified, gives detailed help on the command matching PATTERN.'),
+    'callback' => 'terminal_command_help',
+  );
+  return $commands;
+}
Index: terminal.terminal.inc
===================================================================
RCS file: terminal.terminal.inc
diff -N terminal.terminal.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ terminal.terminal.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,36 @@
+<?php
+// $Id$
+
+/**
+ * Implementation of hook_terminal().
+ */
+function terminal_terminal() {
+  $commands['help'] = array(
+    'title' => t('Help'),
+    'pattern' => t('help [PATTERN]'),
+    'description' => t('Displays helpful information about builtin commands. If PATTERN is specified, gives detailed help on the command matching PATTERN.'),
+    'callback' => 'terminal_command_help',
+  );
+  return $commands;
+}
+
+/**
+ * Terminal callback for the "help" command".
+ */
+function terminal_command_help($args = array()) {
+  $commands = terminal_commands();
+  // Check if the user wants help on a certain command.
+  $name = isset($args[0]) ? $args[0] : -1;
+  if (isset($commands[$name])) {
+    $command = $commands[$name];
+    $title = isset($command['title']) ? $command['title'] : $name;
+    $description = isset($command['description']) ? $command['description'] : '';
+    $pattern = isset($command['pattern']) ? $command['pattern'] : $name;
+    echo "$title: $pattern\n $description";
+  }
+  else {
+    // Present information about all the available commands.
+    echo t("Drupal Terminal, version !version\nExecute 'help [command]' to retrieve more information about the given command:\n", array('!version' => '$Id$'));
+    echo implode(', ', array_keys($commands));
+  }
+}
