summaryrefslogtreecommitdiffstats
path: root/glances/outputs/glances_bottle.py
diff options
context:
space:
mode:
Diffstat (limited to 'glances/outputs/glances_bottle.py')
-rw-r--r--glances/outputs/glances_bottle.py160
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'