/usr/lib/python3/dist-packages/glances/outdated.py is in glances 2.7.1.1-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | # -*- coding: utf-8 -*-
#
# This file is part of Glances.
#
# Copyright (C) 2016 Nicolargo <nicolas@nicolargo.com>
#
# Glances is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Glances is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Manage Glances update."""
from datetime import datetime, timedelta
from distutils.version import LooseVersion
import threading
import json
import pickle
import os
try:
import requests
except ImportError:
outdated_tag = False
else:
outdated_tag = True
from glances import __version__, __appname__
from glances.globals import BSD, LINUX, OSX, WINDOWS
from glances.logger import logger
class Outdated(object):
"""
This class aims at providing methods to warn the user when a new Glances
version is available on the Pypi repository (https://pypi.python.org/pypi/Glances/).
"""
PYPI_API_URL = 'https://pypi.python.org/pypi/Glances/json'
max_refresh_date = timedelta(days=7)
def __init__(self, args, config):
"""Init the Outdated class"""
self.args = args
self.config = config
# Set default value...
self.data = {
u'installed_version': __version__,
u'latest_version': '0.0',
u'refresh_date': datetime.now()
}
# Read the configuration file
self.load_config(config)
logger.debug("Check Glances version up-to-date: {}".format(not self.args.disable_check_update))
# And update !
self.get_pypi_version()
def load_config(self, config):
"""Load outdated parameter in the global section of the configuration file."""
global_section = 'global'
if (hasattr(config, 'has_section') and
config.has_section(global_section)):
self.args.disable_check_update = config.get_value(global_section, 'check_update').lower() == 'false'
else:
logger.debug("Cannot find section {} in the configuration file".format(global_section))
return False
return True
def installed_version(self):
return self.data['installed_version']
def latest_version(self):
return self.data['latest_version']
def refresh_date(self):
return self.data['refresh_date']
def get_pypi_version(self):
"""Wrapper to get the latest Pypi version (async)
The data are stored in a cached file
Only update online once a week
"""
if not outdated_tag or self.args.disable_check_update:
return
# If the cached file exist, read-it
cached_data = self._load_cache()
if cached_data == {}:
# Update needed
# Update and save the cache
thread = threading.Thread(target=self._update_pypi_version)
thread.start()
else:
# Update not needed
self.data['latest_version'] = cached_data['latest_version']
logger.debug("Get the Glances version from the cache file")
def is_outdated(self):
"""Return True if a new version is available"""
if self.args.disable_check_update:
# Check is disabled by configuration
return False
if not outdated_tag:
logger.debug("Python Request lib is not installed. Can not get last Glances version on Pypi.")
return False
logger.debug("Check Glances version (installed: {} / latest: {})".format(self.installed_version(), self.latest_version()))
return LooseVersion(self.latest_version()) > LooseVersion(self.installed_version())
def _load_cache(self):
"""Load cache file and return cached data"""
# If the cached file exist, read-it
cached_data = {}
try:
with open(os.path.join(self._cache_path(), 'glances-version.db'), 'rb') as f:
cached_data = pickle.load(f)
except Exception as e:
logger.debug("Cannot read the version cache file ({})".format(e))
else:
logger.debug("Read the version cache file")
if cached_data['installed_version'] != self.installed_version() or \
datetime.now() - cached_data['refresh_date'] > self.max_refresh_date:
# Reset the cache if:
# - the installed version is different
# - the refresh_date is > max_refresh_date
cached_data = {}
return cached_data
def _save_cache(self):
"""Save data to a file"""
# If the cached file exist, read-it
try:
with open(os.path.join(self._cache_path(), 'glances-version.db'), 'wb') as f:
pickle.dump(self.data, f)
except IOError:
return False
return True
def _cache_path(self):
"""Return the cached file path"""
if LINUX or BSD:
return os.path.join(os.environ.get('XDG_CONFIG_HOME') or
os.path.expanduser('~/.config'),
__appname__)
elif OSX:
return os.path.join(os.path.expanduser('~/Library/Application Support/'),
__appname__)
elif WINDOWS:
return os.path.join(os.environ.get('APPDATA'), __appname__)
def _update_pypi_version(self):
"""Get the latest Pypi version (as a string) via the Restful JSON API"""
# Get the Nginx status
logger.debug("Get latest Glances version from the PyPI RESTful API ({})".format(self.PYPI_API_URL))
# Update the current time
self.data[u'refresh_date'] = datetime.now()
try:
res = requests.get(self.PYPI_API_URL)
except Exception as e:
logger.debug("Cannot get the Glances version from the PyPI RESTful API ({})".format(e))
else:
if res.ok:
# Update data
self.data[u'latest_version'] = json.loads(res.text)['info']['version']
logger.debug("Save Glances version to the cache file")
else:
logger.debug("Cannot get the Glances version from the PyPI RESTful API ({})".format(res.reason))
# Save result to the cache file
# Note: also saved if the Glances Pypi version can not be grabed
self._save_cache()
return self.data
|