diff options
Diffstat (limited to 'glances/outputs/glances_bottle.py')
-rw-r--r-- | glances/outputs/glances_bottle.py | 160 |
1 files changed, 97 insertions, 63 deletions
diff --git a/glances/outputs/glances_bottle.py b/glances/outputs/glances_bottle.py index b5ff8bbf..a7b60831 100644 --- a/glances/outputs/glances_bottle.py +++ b/glances/outputs/glances_bottle.py @@ -23,12 +23,11 @@ import json import os import sys -# Import Glances libs +from glances.core.glances_globals import is_windows from glances.core.glances_logging import logger -# Import mandatory Bottle lib try: - from bottle import Bottle, template, static_file, TEMPLATE_PATH, abort, response, request + from bottle import Bottle, static_file, abort, response, request except ImportError: logger.critical('Bottle module not found. Glances cannot start in web server mode.') sys.exit(2) @@ -53,9 +52,6 @@ class GlancesBottle(object): # Define routes self._route() - # Update the template path (glances/outputs/bottle) - TEMPLATE_PATH.append(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'bottle')) - # Path where the statics files are stored self.STATIC_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'static') @@ -63,10 +59,17 @@ class GlancesBottle(object): """Define route.""" self._app.route('/', method="GET", callback=self._index) self._app.route('/<refresh_time:int>', method=["GET", "POST"], callback=self._index) + self._app.route('/<filename:re:.*\.css>', method="GET", callback=self._css) self._app.route('/<filename:re:.*\.js>', method="GET", callback=self._js) + self._app.route('/<filename:re:.*\.js.map>', method="GET", callback=self._js_map) + self._app.route('/<filename:re:.*\.html>', method="GET", callback=self._html) + + self._app.route('/<filename:re:.*\.png>', method="GET", callback=self._images) self._app.route('/favicon.ico', method="GET", callback=self._favicon) + # REST API + self._app.route('/api/2/help', method="GET", callback=self._api_help) self._app.route('/api/2/pluginslist', method="GET", callback=self._api_plugins) self._app.route('/api/2/all', method="GET", callback=self._api_all) self._app.route('/api/2/all/limits', method="GET", callback=self._api_all_limits) @@ -86,7 +89,7 @@ class GlancesBottle(object): self.plugins_list = self.stats.getAllPlugins() # Bind the Bottle TCP address/port - bindmsg = _("Glances web server started on http://{0}:{1}/").format(self.args.bind_address, self.args.port) + bindmsg = 'Glances web server started on http://{0}:{1}/'.format(self.args.bind_address, self.args.port) logger.info(bindmsg) print(bindmsg) self._app.run(host=self.args.bind_address, port=self.args.port, quiet=not self.args.debug) @@ -105,7 +108,12 @@ class GlancesBottle(object): self.stats.update() # Display - return self.display(self.stats, refresh_time=refresh_time) + return static_file("index.html", root=os.path.join(self.STATIC_PATH, 'html')) + + def _html(self, filename): + """Bottle callback for *.html files.""" + # Return the static file + return static_file(filename, root=os.path.join(self.STATIC_PATH, 'html')) def _css(self, filename): """Bottle callback for *.css files.""" @@ -117,16 +125,60 @@ class GlancesBottle(object): # Return the static file return static_file(filename, root=os.path.join(self.STATIC_PATH, 'js')) + def _js_map(self, filename): + """Bottle callback for *.js.map files.""" + # Return the static file + return static_file(filename, root=os.path.join(self.STATIC_PATH, 'js')) + + def _images(self, filename): + """Bottle callback for *.png files.""" + # Return the static file + return static_file(filename, root=os.path.join(self.STATIC_PATH, 'images')) + def _favicon(self): """Bottle callback for favicon.""" # Return the static file return static_file('favicon.ico', root=self.STATIC_PATH) + def _api_help(self): + """Glances API RESTFul implementation. + + Return the help data or 404 error. + """ + response.content_type = 'application/json' + + # Update the stat + view_data = self.stats.get_plugin("help").get_view_data() + try: + plist = json.dumps(view_data, sort_keys=True) + except Exception as e: + abort(404, "Cannot get help view data (%s)" % str(e)) + return plist + def _api_plugins(self): """ - Glances API RESTFul implementation - Return the plugin list - or 404 error + @api {get} /api/2/pluginslist Get plugins list + @apiVersion 2.0 + @apiName pluginslist + @apiGroup plugin + + @apiSuccess {String[]} Plugins list. + + @apiSuccessExample Success-Response: + HTTP/1.1 200 OK + [ + "load", + "help", + "ip", + "memswap", + "processlist", + ... + ] + + @apiError Cannot get plugin list. + + @apiErrorExample Error-Response: + HTTP/1.1 404 Not Found """ response.content_type = 'application/json' @@ -140,8 +192,8 @@ class GlancesBottle(object): return plist def _api_all(self): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON representation of all the plugins HTTP/200 if OK HTTP/400 if plugin is not found @@ -149,19 +201,28 @@ class GlancesBottle(object): """ response.content_type = 'application/json' - # Update the stat - self.stats.update() + if not self.args.debug: + # Update the stat + self.stats.update() - try: - # Get the JSON value of the stat value - statval = json.dumps(self.stats.getAllAsDict()) - except Exception as e: - abort(404, "Cannot get stats (%s)" % str(e)) - return statval + try: + # Get the JSON value of the stat ID + statval = json.dumps(self.stats.getAllAsDict()) + except Exception as e: + abort(404, "Cannot get stats (%s)" % str(e)) + return statval + else: + path = "~/glances/" + if is_windows: + path = "D:\\glances\\" + filepath = path + "debug.json" + + f = open(filepath) + return f.read() def _api_all_limits(self): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON representation of all the plugins limits HTTP/200 if OK HTTP/400 if plugin is not found @@ -177,8 +238,8 @@ class GlancesBottle(object): return limits def _api_all_views(self): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON representation of all the plugins views HTTP/200 if OK HTTP/400 if plugin is not found @@ -194,8 +255,8 @@ class GlancesBottle(object): return limits def _api(self, plugin): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON representation of a given plugin HTTP/200 if OK HTTP/400 if plugin is not found @@ -217,8 +278,8 @@ class GlancesBottle(object): return statval def _api_limits(self, plugin): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON limits of a given plugin HTTP/200 if OK HTTP/400 if plugin is not found @@ -234,14 +295,14 @@ class GlancesBottle(object): try: # Get the JSON value of the stat limits - ret = self.stats.get_plugin(plugin).get_limits() + ret = self.stats.get_plugin(plugin).limits except Exception as e: abort(404, "Cannot get limits for plugin %s (%s)" % (plugin, str(e))) return ret def _api_views(self, plugin): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON views of a given plugin HTTP/200 if OK HTTP/400 if plugin is not found @@ -263,8 +324,8 @@ class GlancesBottle(object): return ret def _api_item(self, plugin, item): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the JSON represenation of the couple plugin/item HTTP/200 if OK HTTP/400 if plugin is not found @@ -287,8 +348,8 @@ class GlancesBottle(object): return plist def _api_value(self, plugin, item, value): - """ - Glances API RESTFul implementation + """Glances API RESTFul implementation. + Return the process stats (dict) for the given item=value HTTP/200 if OK HTTP/400 if plugin is not found @@ -309,33 +370,6 @@ class GlancesBottle(object): else: return pdict - def display(self, stats, refresh_time=None): - """Display stats on the web page. - - stats: Stats database to display - """ - - stats = { - 'system': self.stats.get_plugin('system').get_stats_display(args=self.args), - 'uptime': self.stats.get_plugin('uptime').get_stats_display(args=self.args), - 'cpu': self.stats.get_plugin('cpu').get_stats_display(args=self.args), - 'load': self.stats.get_plugin('load').get_stats_display(args=self.args), - 'mem': self.stats.get_plugin('mem').get_stats_display(args=self.args), - 'memswap': self.stats.get_plugin('memswap').get_stats_display(args=self.args), - 'network': self.stats.get_plugin('network').get_stats_display(args=self.args), - 'diskio': self.stats.get_plugin('diskio').get_stats_display(args=self.args), - 'fs': self.stats.get_plugin('fs').get_stats_display(args=self.args), - 'raid': self.stats.get_plugin('raid').get_stats_display(args=self.args), - 'sensors': self.stats.get_plugin('sensors').get_stats_display(args=self.args), - 'alert': self.stats.get_plugin('alert').get_stats_display(args=self.args), - 'processcount': self.stats.get_plugin('processcount').get_stats_display(args=self.args), - 'monitor': self.stats.get_plugin('monitor').get_stats_display(args=self.args), - 'processlist': self.stats.get_plugin('processlist').get_stats_display(args=self.args), - 'docker': self.stats.get_plugin('docker').get_stats_display(args=self.args) - } - - return template('base', refresh_time=refresh_time, stats=stats) - class EnableCors(object): name = 'enable_cors' |