Fixed the bug where if you change the theme or the font size it wasn't updating the number of rows/cols in the view.
Fixed the issue reported in #51 (https://github.com/liftoff/GateOne/issues/51) where session recording playback/export wasn't working at all.
Made it so that session recordings will now use the user's selected theme/colors.
Lots of CSS tweaks (hopefully will fix the "greyed out terminal" problem reported in https://github.com/liftoff/GateOne/issues/39).
Added the ability to disable terminal transitions (if you think the sliding effect is too slow/choppy or causes lag/drymouth/cancer/statistics/whatever).  Also to address https://github.com/liftoff/GateOne/issues/39
Doh, forgot to add the new playback.py
Fixed the bug where ctrl-l wasn't properly clearing the screen.  Was the result of my rstrip() inside of __spanify_scren() in terminal.py.  I've re-worked the logic in gateone.js so we can keep this bandwiwdth-saving feature while also being able to clear the screen =).
Made some major changes to the way screen updates are handled:  A considerable amount more processing is not being performed by the termUpdatedWorker (Web Worker).  This should make Gate One more responsive when there's a lot going on (in all your open terminals).  Also, the larger your terminal the more likely you are to benefit from these changes.  In my testing, these changes seem to make the most difference in Firefox.  There's definitely a speedup in Chrome but it isn't as noticable.  The biggest speedup has to go to be when the scrollback buffer gets re-enabled (a lot less of a pause now when that happens).
The process of linkifying and transforming text is now only performed on terminal lines that have changed since the last screen updated.  This seriously increased performance under certain loads.
Fixed the bug where terminal dimensions weren't set correctly after resuming sesions after restarting the Gate One server (I'm probably the only person that ran into this problem regularly but it was starting to get on my nerves =).
Fixed the JavaScript exception that could occur when a terminal closed before a slideToTerminal() timeout completed (just a minor annoyance but who needs such silly things cluttering up the JS console? =).
Fixed the problem with the Home and End keys in Application Cursor Keys mode (https://github.com/liftoff/GateOne/issues/8).
png support testing.
Well, printing PNGs to the terminal works but it breaks all unicode support.  It also seems to mess up the rows/cols
Added the ability to display PNG and JPEG images in terminals!  Try it:  "cat someimage.png" or "cat someimage.jpeg".  Screenshot here:  http://www.flickr.com/photos/danielmcdougall/6303905481/in/photostream/lightbox/ Note that only JPEGs with a JFIF or Exif header will work.
Fixed the issue where terminals would be missing a row whenever gateone.py was restarted (only applicable if dtach=True).
Fixed the alt-backspace key combination.
Added a new callback to the terminal.py:  CALLBACK_RESET.  It gets called whenever a terminal reset escape sequence is encountered (i.e. ^[[!p).
gateone.py and gateone.js are now configured to use the new CALLBACK_RESET.  Right now it just erases the screen and the scrollback buffer for the respective terminal.
Changed the way screen updates are handled in gateone.js (slightly) to get a slight performance boost...  Instead of setting the innerHTML of the terminal div it now uses createElement and replaceChild().  Please report in if this made a noticable difference for you.
Added some extra exception handling all over the place because I noticed that sometimes the new image handling code doesn't match JPEGs and they wind up throwing every possible escape handler (it's kind of ridiculous).  Anyway, Gate One terminals should be more robust as a result.  Also added some anti-spam logic to displayMessage in GateOne.Visual so that when such a situation occurs the browser won't eat up your CPU telling you the bell just rang in terminal X 100,000 times in a row.
Lots of major changes to the Terminal class inside terminal.py (aka the terminal emulator).  All the exception checks, conditionals, and new features has increased CPU consumption slightly so I figured it was time to optimize and make it work with the multiprocessing module.  These changes are outlined below...
* The callbacks inside Terminal.terminal.CALLBACKS are now dicts instead of functions.  This is so we can support multiple browsers viewing/using the same terminals (e.g. to fix this issue:  https://github.com/liftoff/GateOne/issues/26).
* Terminal.__init__() has been renamed to "initialize()" and a new __init__() function was defined that just calls initialize().  This is so we can "initalize" the terminal if __init__() isn't available (e.g. in subclassing/multiprocessing/mixin situations).
* Added a pair of new functions, Terminal.add_callback() and Terminal.remove_callback() to make it easier for a controlling process to add callbacks and to work around the fact that class properties aren't directly accessible when a Terminal() is being controlled by a multiprocessing Manager (or over the network, or via a proxy of some sort, etc etc).
* Added a new callback for when the LED state changes (Terminal.CALLBACK_LEDS).
Added nearly identical add_callback() and remove_callback() functions to termio.Multiplex for the same reasons mentioned above.
Gate One now supports multiple browsers viewing the same terminal session from different locations.
Gate One now supports listening on multiple IP addresses simultaneously.  This includes IPv6 addresses.  Also, the default listen address was changed from "0.0.0.0" to just "" which should have it listening on all IPv6 addresses in addition to all IPv4 addresses.
The terminal creation/reattach logic inside gateone.py now uses the add_callback() and remove_callback() functions from Terminal and Multiplex.
There's a new thread inside gateone.py:  CallbackThread().  It was created as a way to support callbacks coming over the multiprocessing.Queue() (since instancemethods aren't pickleable).  It looks a bit strange/complex but all it does is match up a string coming over the Queue() with a specific callback function (really, that's all it does).
Fixed a bug where the ^[< and ^[> escape sequences were not being recognized (this is what caused that two-character gap in midnight commander).
Moved handle_special from termio to terminal now that that's where the unicode encoding is happening.
The rate limiter was removed from a previous commit because, well, it didn't really work.  To get obtain a similar effect, a new function, _blocked_io_handler() has been added that gets registerd with io_loop.set_blocking_signal_threshold().  It will send a Ctrl-c to the running process if it blocks the IOLoop for longer than 4 seconds.  The end result isn't stellar but it does allow Gate One to keep running (which is better than nothing).
MAJOR CHANGES TO termio.py:  Multiprocessing!  It now executes the terminal emulator (terminal.Terminal) via a multiprocessing.Manager instance.  This should mean much better performance for servers running a lot of simultaneous terminals with many users.  The next step is to convert the create() method into something that can run over a multiprocessing.Manager as well.
Also, lots of minor changes to termio.py...  Certain functions have been broken in two in order to simplify the logic a bit.  It also paves the way for taking (more) advantage of the multiprocessing module.
Made some minor changes to the way that gateone.js detects the number of rows/columns that will fit inside the browser window.  This was to accomodate a larger array of font types (which have differing line heights) and explicit line heights (configured in CSS).
This is a BIG commit so if you read all this please do some serious testing to double-check that I didn't break anything that was previously working.  Thanks!
Fixed a bug with terminal.Terminal.insert_line() and delete_line() where they would fail if given an empty string as the number of lines.  This should fix this issue:  https://github.com/liftoff/GateOne/issues/30
Added a docstring to call_callback() in gateone.py and removed the unnecessary logging.debug line.
Fixed the wrap-around bug in vim when highlighting of parens is turned on.  Should fix https://github.com/liftoff/GateOne/issues/30 (for real this time =).
Regenerated the documentation to reflect recent changes/additions.
Added authpam.py to the docs and regenerated them.
Commented out the logging.debug line in Terminal.write (to speed it up ever so slightly).
Reverted a recent change in GateOne.Utils.getEmDimensions() since it appears that the new logic doesn't work right on Windows.
Changed all situations using .decode('utf-8', errors=whatever) to be .decode('utf-8', 'whatever') since Python 2.6 doesn't support keyword arguments with .decode.  This should fix https://github.com/liftoff/GateOne/issues/59
Added several helpful error messages in the event that a dependency cannot be found.
Made it so that multiprocessing gets disabled if you're running Gate One using Python 2.6.  Apparently the version of functools.partial in 2.6 isn't pickleable but in 2.7 it is.  Without that capability I don't know if it would be possible to support multiprocessing in Gate One (any ideas?).  For reference, the new rate limiter/autokill logic doesn't work as well without multiprocessing.
Fixed the bug where newlines weren't working properly (removed the tilda in front of termios.ONLCR in termio.py).
The rate limiter/autokill logic has been improved considerably.  No longer will a runaway process force you to restart Gate One (well, it shouldn't anyway if you're running Python 2.7+).  It takes a little while to kick in but it seems to work pretty good for killing things like "yes" and "while true; do echo foo; done".  I'll make it more sophisticated with fallbacks to killing a PID in the future.
Reverted my changes to --address.  Apparently they weren't necessary.
Changed how the logging gets configured in GateOne.init() inside of gateone.js (thanks to MostAwesomeDude on Freenode for the patch).
Generated a new gateone.pot (for multi-language support) since I've changed a few strings around recently.
Changed how user directories were getting created in auth.BaseAuthHandler (now using os.path.join instead of just string manipulation).  Hopefully this will fix https://github.com/liftoff/GateOne/issues/55
Added some more exception handling to TerminalWebSocket to keep trivial exceptions (i.e. non-problems) out of the logs.
Fixed the issue where calling CallbackThread.quit() would always result in an exception (it would still quit though =).
Cleaned up ssh_connect.py a bit (removed unused stuff).
Fixed a bug where having "address = ''" in server.conf would result in Gate One not listening on any addresses.
Added back the "separated by semicolons" option for specifying multiple addresses since having multiple --address options doesn't seem to work properly.
Changed ssh_connect.py so that it quits immediately after executing the ssh command (i.e. it doesn't stay running).  This could save a lot of memory for servers with a lot of open connections.
Made the path to ssh configurable in ssh_connect.py.  Also, by default it will use whatever is returned by `which ssh` and if that fails it will fall back to using /usr/bin/ssh.  This should resolve https://github.com/liftoff/GateOne/issues/62
Temporarily disabled multiprocessing support altogether.  It has turned out to be too fragile and it needs a complete rework to be more stable.  NOTE: Most of the code has just been commented out so there's a bit of a mess left over.  It won't stay like this :)
Uncommented the env['PATH'] line from termio.py inside of create() since it is apparently necessary for certain platforms.
Changed the bell sound (made it myself using Audacity--not bad for my first time making a new sound from scratch if I do say so myself =).  This was necessary as the current beep.ogg comes from KDE which is licensed GPLv2 which is incompatible with the AGPLv3 and Gate One's commercial licensing.  For reference, I tried to make the new sound as pleasant and non-annoying as possible.  As a bonus it also happens to be a lot smaller (5349 bytes) than the old sound (23474 bytes).
Added the pre-encoded data URI for bell.ogg to the utils module as fallback_bell.  This gets used by gateone.MainHandler in the event that the mimetype can't be detected (can occur on platforms without complete/working mimetype support).  It also gets used if bell.ogg can't be found.
Cleaned up the multiprocessing leftovers.
Regenerated the documentation.
Changed the logic inside utils.create_plugin_static_links() so that it now uses a pure-Python implementation instead of calling the 'find' command to find and remove old symbolic links.  This should solve https://github.com/liftoff/GateOne/issues/63
ssh_connect.py now uses just 'ssh' as the default path to the SSH executable.  This means it will rely on $PATH which is a simpler, more reliable mechanism (well, it should be anyway =).
Fixed a (minor) bug in gateone.TerminalWebSocket.authenticate() where it would miss TypeError exceptions (in the event that get_current_user() returns None).
Apparently base64.b64encode doesn't accept bytearrays in Python 2.6 so I added a little intermediary step that converts the bytearray to just bytes in terminal.Terminal.__spanify_screen() (the part that converts images for display in the terminal).