Permalink
Browse files

onoff.py: Added some use of the logging module for debugging purposes.

gateone.py:  Fixed a bug that could crop up (depending on your Python version/env) where the render_style() function would throw a UnicodeEncodeError.  This should solve the most recent problem reported in issue #161 .
gateone.py:  The --combine_css option has been modified to save theme CSS into independent files.  It will also display/log what was combined and where everything was saved.
Terminal application terminal.js:  Added a class to the 'terminfo' div (to get rid of the use of {{prefix}} in the .css)
Terminal themes:  Added .✈terminfo to the themes where it was missing.
terminal.py:  Fixed a bug reported in issue #210 (#210) where the horizontal_tab() function had a typo.
SSH Plugin:  When using the 'ssh=' query string parameter to open a new terminal to a specific SSH URL it will now remove the 'ssh=' query string variable after the connection is established (to avoid confusion as to whether or not opening a new terminal will automatically open the same SSH URL).
setup.py:  Separated termio.py and terminal.py into their own globally-installable module (termio).  This should make it easier for other applications to use these modules independently of Gate One.
setup.py:  Separated onoff.py into its own globally-installable module (onoff).  Also to make it easier for other applications to take advantage of this module (onoff.py uses the Apache 2.0 license).
setup.py:  Added some logic to remove the old termio.py and terminal.py locations.  Not bothering for onoff.py since it wasn't there in 1.1.  You can remove it yourself if you like.
termio.py:  Fixed a bug where getstatusoutput() would hang forever waiting for a defunct process to be reaped.  This required a minor change to MultiplexPOSIXIOLoop.read().
  • Loading branch information...
1 parent 9fe08f7 commit 6c5d163b27e0e03b640d5dfb9c9ab2334c6c1ee1 @liftoff committed Feb 27, 2013
@@ -565,7 +565,7 @@ def add_terminal_callbacks(self, term, multiplex, callback_id):
Sets up all the callbacks associated with the given *term*, *multiplex*
instance and *callback_id*.
"""
- import terminal
+ from termio import terminal
refresh = partial(self.refresh_screen, term)
multiplex.add_callback(multiplex.CALLBACK_UPDATE, refresh, callback_id)
ended = partial(self.term_ended, term)
@@ -46,7 +46,7 @@
import os
import re
import logging
-import terminal
+from termio import terminal
class HTMLOutput(terminal.FileType):
"""
@@ -78,7 +78,7 @@ def retrieve_log_frames(golog_path, rows, cols, limit=None):
If *limit* is given, only return that number of frames (e.g. for preview)
"""
out_frames = []
- from terminal import Terminal
+ from termio.terminal import Terminal
terminal_emulator = Terminal
term = terminal_emulator(
# 14/7 for the em_height should be OK for most browsers to ensure that
@@ -320,7 +320,7 @@ def _retrieve_log_flat(queue, settings):
out_dict['result'] = "Success"
from io import BytesIO
# Use the terminal emulator to create nice HTML-formatted output
- from terminal import Terminal
+ from termio.terminal import Terminal
term = Terminal(rows=100, cols=300, em_dimensions=0)
io_obj = BytesIO()
flatten_log(log_path, io_obj)
@@ -17,7 +17,7 @@
#{{container}} .sideinfo {
display: none; /* Not enough room for it on mobile */
}
- #{{container}} .✈playbackControls {
+ .✈playbackControls {
display: none; /* Small screens really don't have room for this */
}
}
@@ -86,6 +86,7 @@ go.Base.update(go.SSH, {
if (go.Terminal.terminals[term]['title'] == 'Gate One') {
go.Terminal.sendString(sshQueryString + '\n', term);
}
+ u.removeQueryVariable('ssh'); // Clean up the URL
}
go.Events.on("terminal:new_terminal", connect);
} else {
@@ -507,7 +507,7 @@ go.Base.update(GateOne.Terminal, {
return;
}
var displayText = termObj.id.split('term')[1] + ": " + go.Terminal.terminals[term]['title'],
- termInfoDiv = u.createElement('div', {'id': 'terminfo'}),
+ termInfoDiv = u.createElement('div', {'id': 'terminfo', 'class': 'terminfo'}),
marginFix = Math.round(go.Terminal.terminals[term]['title'].length/2),
infoContainer = u.createElement('div', {'id': 'infocontainer', 'style': {'margin-right': '-' + marginFix + 'em'}});
termInfoDiv.innerHTML = displayText;
@@ -41,7 +41,7 @@
/* The "reverse" default needs to be set in the theme since the background will vary */
#{{container}} span.reverse { color: #222; background-color: #ccc; } /* Black on White */
#{{container}} span.cursor { color: #000; background-color: #ccc; }
-#{{prefix}}terminfo {
+#{{container}} .✈terminfo {
color: #fff;
font-weight: bold;
font-size: 1.1em;
@@ -39,6 +39,11 @@
-o-transform-origin: left bottom;
transform-origin: left bottom;
}
+#{{container}} .✈terminfo {
+ color: #fff;
+ font-weight: bold;
+ font-size: 1.1em;
+}
/* The "reverse" default needs to be set in the theme since the background will vary */
#{{container}} span.reverse { color: #000; background-color: #ccc; } /* Black on White */
#{{container}} span.cursor { color: #000; background-color: #ccc; }
@@ -40,7 +40,11 @@
-o-transform-origin: left bottom;
transform-origin: left bottom;
}
-
+#{{container}} .✈terminfo {
+ color: #fff;
+ font-weight: bold;
+ font-size: 1.1em;
+}
/* The "reverse" default needs to be set in the theme since the background will vary */
#{{container}} span.reverse { color: #002b36; background-color: #839496; }
#{{container}} span.cursor { color: #002b36; background-color: #eee8d5; }
@@ -38,6 +38,11 @@
-o-transform-origin: left bottom;
transform-origin: left bottom;
}
+#{{container}} .✈terminfo {
+ color: #000;
+ font-weight: bold;
+ font-size: 1.1em;
+}
/* The "reverse" default needs to be set in the theme since the background will vary */
#{{container}} span.reverse { color: #000; background-color: #fff; }
#{{container}} span.cursor { color: #fff; background-color: #000; }
View
@@ -5,8 +5,6 @@
#
# For license information see LICENSE.txt
-# TODO:
-
# Meta
__version__ = '1.2.0'
__version_info__ = (1, 2, 0)
@@ -1526,8 +1524,10 @@ def render_style(self, style_path, **kwargs):
style_path,
**kwargs
)
- with io.open(rendered_path, 'w') as f:
- f.write(style_css.decode('utf-8'))
+ # NOTE: Tornado templates are always rendered as bytes. That is why
+ # we're using 'wb' below...
+ with io.open(rendered_path, 'wb') as f:
+ f.write(style_css)
# Remove older versions of the rendered template if present
for fname in os.listdir(cache_dir):
if fname == rendered_filename:
@@ -1633,8 +1633,7 @@ def get_theme(self, settings):
#rendered_path = self.render_style(print_css_path, **template_args)
# TODO: Do something about the print stylesheet (needs to go in terminal)
# Combine the theme files into one
- # Don't need a hashed name for the theme:
- filename = 'theme.css'
+ filename = 'theme.css' # Don't need a hashed name for the theme
cached_theme_path = os.path.join(cache_dir, filename)
with io.open(cached_theme_path, 'w') as f:
for path in theme_files:
@@ -3137,7 +3136,7 @@ def main():
filepath = os.path.join(static_dir, filename)
if filename.endswith('.js'):
with io.open(filepath) as js_file:
- f.write(js_file.read() + '\n')
+ f.write(js_file.read() + u'\n')
# Gate One applications
for application in appslist:
if enabled_applications:
@@ -3155,7 +3154,7 @@ def main():
filepath = os.path.join(static_dir, filename)
if filename.endswith('.js'):
with io.open(filepath) as js_file:
- f.write(js_file.read() + '\n')
+ f.write(js_file.read() + u'\n')
app_settings = all_settings['*'].get(application, None)
enabled_app_plugins = []
if app_settings:
@@ -3178,7 +3177,7 @@ def main():
filepath = os.path.join(static_dir, filename)
if filename.endswith('.js'):
with io.open(filepath) as js_file:
- f.write(js_file.read() + '\n')
+ f.write(js_file.read() + u'\n')
f.flush()
sys.exit(0)
if options.combine_css:
@@ -3189,9 +3188,16 @@ def main():
applications_dir = os.path.join(GATEONE_DIR, 'applications')
appslist = os.listdir(applications_dir)
appslist.sort()
+ themes = os.listdir(os.path.join(GATEONE_DIR, 'templates', 'themes'))
+ theme_writers = {}
+ for theme in themes:
+ combined_theme_path = "%s_theme_%s" % (
+ options.combine_css.split('.css')[0], theme)
+ theme_writers[theme] = io.open(combined_theme_path, 'w')
# NOTE: We skip gateone.css because that isn't used when embedding
with io.open(options.combine_css, 'w') as f:
# Gate One plugins
+ # TODO: Add plugin theme files to this
for plugin in pluginslist:
if enabled_plugins and plugin not in enabled_plugins:
continue
@@ -3203,11 +3209,11 @@ def main():
filepath = os.path.join(css_dir, filename)
if filename.endswith('.css'):
with io.open(filepath) as css_file:
- f.write(css_file.read() + '\n')
+ f.write(css_file.read() + u'\n')
# Gate One applications
for application in appslist:
if enabled_applications:
- # Only export JS of enabled apps
+ # Only export CSS of enabled apps
if application not in enabled_applications:
continue
css_dir = os.path.join(GATEONE_DIR,
@@ -3222,7 +3228,7 @@ def main():
filepath = os.path.join(css_dir, filename)
if filename.endswith('.css'):
with io.open(filepath) as css_file:
- f.write(css_file.read() + '\n')
+ f.write(css_file.read() + u'\n')
elif os.path.isdir(filepath):
subdirs.append(filepath)
while subdirs:
@@ -3233,7 +3239,11 @@ def main():
filepath = os.path.join(subdir, filename)
if filename.endswith('.css'):
with io.open(filepath) as css_file:
- f.write(css_file.read() + '\n')
+ combined = css_file.read() + u'\n'
+ if os.path.split(subdir)[1] == 'themes':
+ theme_writers[filename].write(combined)
+ else:
+ f.write(combined)
elif os.path.isdir(filepath):
subdirs.append(filepath)
app_settings = all_settings['*'].get(application, None)
@@ -3259,7 +3269,7 @@ def main():
filepath = os.path.join(css_dir, filename)
if filename.endswith('.css'):
with io.open(filepath) as css_file:
- f.write(css_file.read() + '\n')
+ f.write(css_file.read() + u'\n')
elif os.path.isdir(os.path.join(
css_dir, filename)):
subdirs.append(filepath)
@@ -3271,17 +3281,42 @@ def main():
filepath = os.path.join(subdir, filename)
if filename.endswith('.css'):
with io.open(filepath) as css_file:
- f.write(css_file.read() + '\n')
+ with io.open(filepath) as css_file:
+ combined = css_file.read() + u'\n'
+ _dir = os.path.split(subdir)[1]
+ if _dir == 'themes':
+ theme_writers[filename].write(
+ combined)
+ else:
+ f.write(combined)
elif os.path.isdir(filepath):
subdirs.append(filepath)
f.flush()
+ for writer in theme_writers.values():
+ writer.flush()
+ writer.close()
# Now perform a replacement of the {{container}} variable
with io.open(options.combine_css, 'r') as f:
css_data = f.read()
css_data = css_data.replace(
'#{{container}}', options.combine_css_container)
with io.open(options.combine_css, 'w') as f:
f.write(css_data)
+ logging.info(_(
+ "Non-theme CSS has been combined and saved to: %s"
+ % options.combine_css))
+ for theme in theme_writers.keys():
+ combined_theme_path = "%s_theme_%s" % (
+ options.combine_css.split('.css')[0], theme)
+ with io.open(combined_theme_path, 'r') as f:
+ css_data = f.read()
+ css_data = css_data.replace(
+ '#{{container}}', options.combine_css_container)
+ with io.open(combined_theme_path, 'w') as f:
+ f.write(css_data)
+ logging.info(_(
+ "The %s theme CSS has been combined and saved to: %s"
+ % (theme.split('.css')[0], combined_theme_path)))
sys.exit(0)
# Display the version in case someone sends in a log for for support
logging.info(_("Gate One %s" % __version__))
View
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+#
+# Copyright 2011 Liftoff Software Corporation
+#
+# For license information see LICENSE.txt
+
+# Meta
+__version__ = '1.0.0'
+__version_info__ = (1, 0, 0)
+__license__ = "Apache 2.0 (see LICENSE.txt)"
+__author__ = 'Dan McDougall <daniel.mcdougall@liftoffsoftware.com>'
+
+from .onoff import OnOffMixin, __version__, __version_info__
+__all__ = ['OnOffMixin']
Oops, something went wrong.

0 comments on commit 6c5d163

Please sign in to comment.