Add some basic logging to the application. Also for severe errors, track them in info.log file in local folder
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,4 @@
|
|||||||
__pycache__
|
__PYCache__
|
||||||
Data
|
Data
|
||||||
src/themes/__current_theme
|
src/themes/__current_theme
|
||||||
designer.bat
|
designer.bat
|
||||||
@@ -8,3 +8,4 @@ launch.bat
|
|||||||
spec_files/**/output
|
spec_files/**/output
|
||||||
*.txt
|
*.txt
|
||||||
*.json
|
*.json
|
||||||
|
info.log
|
||||||
|
|||||||
@@ -28,14 +28,13 @@ class ACFValue:
|
|||||||
self._description = ""
|
self._description = ""
|
||||||
self._value = value
|
self._value = value
|
||||||
self._string = self._value
|
self._string = self._value
|
||||||
try:
|
if self._value.isdigit():
|
||||||
self.numeric_value = float(self._value)
|
self.numeric_value = float(self._value)
|
||||||
except Exception:
|
|
||||||
self.is_numeric = False
|
|
||||||
self.numeric_value = 0.0
|
|
||||||
else:
|
|
||||||
self.is_numeric = True
|
self.is_numeric = True
|
||||||
self._string += " ms"
|
self._string += " ms"
|
||||||
|
else:
|
||||||
|
self.is_numeric = False
|
||||||
|
self.numeric_value = 0.0
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def list_from_series(cls, series):
|
def list_from_series(cls, series):
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import webbrowser
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from time import sleep, time
|
from time import sleep, time
|
||||||
|
import logging
|
||||||
|
|
||||||
from pandas import read_csv
|
from pandas import read_csv
|
||||||
|
|
||||||
@@ -58,6 +59,7 @@ from downloadtargetfactory import get_download_target
|
|||||||
from settings import Settings
|
from settings import Settings
|
||||||
from updatescontroller import UpdatesController
|
from updatescontroller import UpdatesController
|
||||||
from urlbutton import UrlButton
|
from urlbutton import UrlButton
|
||||||
|
import loggingconf # noqa 401
|
||||||
|
|
||||||
# import default_imgs_rc
|
# import default_imgs_rc
|
||||||
|
|
||||||
@@ -256,6 +258,7 @@ class Artemis(QMainWindow, Ui_MainWindow):
|
|||||||
font.setUnderline(self.settings.font['underline'])
|
font.setUnderline(self.settings.font['underline'])
|
||||||
self.apply_font(font)
|
self.apply_font(font)
|
||||||
except Exception: # Invalid font
|
except Exception: # Invalid font
|
||||||
|
logging.warning("Invalid Font in settings.json")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
@@ -357,6 +360,7 @@ class Artemis(QMainWindow, Ui_MainWindow):
|
|||||||
try:
|
try:
|
||||||
webbrowser.open(Constants.GFD_SITE + query.lower())
|
webbrowser.open(Constants.GFD_SITE + query.lower())
|
||||||
except Exception:
|
except Exception:
|
||||||
|
logging.error("Cannot open browser")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def set_initial_size(self):
|
def set_initial_size(self):
|
||||||
@@ -445,7 +449,8 @@ class Artemis(QMainWindow, Ui_MainWindow):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
is_checksum_ok = checksum_ok(db, get_db_hash_code())
|
is_checksum_ok = checksum_ok(db, get_db_hash_code())
|
||||||
except Exception:
|
except ValueError as e:
|
||||||
|
logging.info(e)
|
||||||
pop_up(self, title=Messages.NO_CONNECTION,
|
pop_up(self, title=Messages.NO_CONNECTION,
|
||||||
text=Messages.NO_CONNECTION_MSG).show()
|
text=Messages.NO_CONNECTION_MSG).show()
|
||||||
else:
|
else:
|
||||||
@@ -485,7 +490,8 @@ class Artemis(QMainWindow, Ui_MainWindow):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
is_checksum_ok = checksum_ok(db, get_db_hash_code())
|
is_checksum_ok = checksum_ok(db, get_db_hash_code())
|
||||||
except Exception:
|
except ValueError as e:
|
||||||
|
logging.info(e)
|
||||||
pop_up(self, title=Messages.NO_CONNECTION,
|
pop_up(self, title=Messages.NO_CONNECTION,
|
||||||
text=Messages.NO_CONNECTION_MSG).show()
|
text=Messages.NO_CONNECTION_MSG).show()
|
||||||
else:
|
else:
|
||||||
|
|||||||
45
src/loggingconf.py
Normal file
45
src/loggingconf.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import logging
|
||||||
|
import logging.config
|
||||||
|
from constants import __BASE_FOLDER__
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
"""Import the module to initialize the logging configuration"""
|
||||||
|
|
||||||
|
_LOGGING_CONFIG = {
|
||||||
|
'version': 1,
|
||||||
|
'formatters': {
|
||||||
|
'general': {
|
||||||
|
'format': '%(asctime)s::%(levelname)s::%(module)s::%(funcName)s::%(message)s',
|
||||||
|
'datefmt': '%d/%m/%Y %I:%M:%S %p'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'handlers': {
|
||||||
|
'console': {
|
||||||
|
'level': 'INFO',
|
||||||
|
'formatter': 'general',
|
||||||
|
'class': 'logging.StreamHandler',
|
||||||
|
'stream': 'ext://sys.stdout',
|
||||||
|
},
|
||||||
|
'file': {
|
||||||
|
'class': 'logging.FileHandler',
|
||||||
|
'level': 'ERROR',
|
||||||
|
'filename': os.path.join(__BASE_FOLDER__, 'info.log'),
|
||||||
|
'mode': 'w',
|
||||||
|
'encoding': 'utf8',
|
||||||
|
'formatter': 'general'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'root': {
|
||||||
|
'level': 'DEBUG',
|
||||||
|
'handlers': ['console', 'file']
|
||||||
|
},
|
||||||
|
'loggers': {
|
||||||
|
'root.sublogger': {
|
||||||
|
'propagate': False,
|
||||||
|
'level': 'DEBUG',
|
||||||
|
'handlers': ['console', 'file']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logging.config.dictConfig(_LOGGING_CONFIG)
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import os.path
|
import os.path
|
||||||
from constants import Constants
|
from constants import Constants
|
||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
class Settings:
|
class Settings:
|
||||||
@@ -16,7 +17,8 @@ class Settings:
|
|||||||
try:
|
try:
|
||||||
with open(Constants.SETTINGS_FILE, 'r') as settings_file:
|
with open(Constants.SETTINGS_FILE, 'r') as settings_file:
|
||||||
self._dct = json.load(settings_file)
|
self._dct = json.load(settings_file)
|
||||||
except Exception:
|
except FileNotFoundError:
|
||||||
|
logging.info("No settings.json file")
|
||||||
pass # Invalid file.
|
pass # Invalid file.
|
||||||
|
|
||||||
def save(self, **kwargs):
|
def save(self, **kwargs):
|
||||||
|
|||||||
@@ -272,17 +272,15 @@ class ThemeManager:
|
|||||||
|
|
||||||
def apply_default_theme(self):
|
def apply_default_theme(self):
|
||||||
"""Apply the default theme if no theme is set or the theme name is invalid."""
|
"""Apply the default theme if no theme is set or the theme name is invalid."""
|
||||||
try:
|
pretty_name = self._theme_names.get(self._pretty_name(ThemeConstants.DEFAULT), None)
|
||||||
self._theme_names[
|
if pretty_name is None:
|
||||||
self._pretty_name(ThemeConstants.DEFAULT)
|
|
||||||
].setChecked(True)
|
|
||||||
except Exception:
|
|
||||||
pop_up(
|
pop_up(
|
||||||
self._owner,
|
self._owner,
|
||||||
title=ThemeConstants.THEME_NOT_FOUND,
|
title=ThemeConstants.THEME_NOT_FOUND,
|
||||||
text=ThemeConstants.MISSING_THEME
|
text=ThemeConstants.MISSING_THEME
|
||||||
).show()
|
).show()
|
||||||
else:
|
else:
|
||||||
|
pretty_name.setChecked(True)
|
||||||
self._apply(ThemeConstants.DEFAULT_THEME_PATH)
|
self._apply(ThemeConstants.DEFAULT_THEME_PATH)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
@@ -291,11 +289,11 @@ class ThemeManager:
|
|||||||
if self._owner.settings.theme is not None:
|
if self._owner.settings.theme is not None:
|
||||||
theme_path = os.path.join(ThemeConstants.FOLDER, self._owner.settings.theme)
|
theme_path = os.path.join(ThemeConstants.FOLDER, self._owner.settings.theme)
|
||||||
theme_name = self._pretty_name(os.path.basename(theme_path))
|
theme_name = self._pretty_name(os.path.basename(theme_path))
|
||||||
try:
|
theme = self._theme_names.get(theme_name, None)
|
||||||
self._theme_names[theme_name].setChecked(True)
|
if theme is None:
|
||||||
except Exception:
|
|
||||||
self.apply_default_theme()
|
self.apply_default_theme()
|
||||||
else:
|
else:
|
||||||
|
theme.setChecked(True)
|
||||||
self._apply(theme_path, save=False)
|
self._apply(theme_path, save=False)
|
||||||
else:
|
else:
|
||||||
self.apply_default_theme()
|
self.apply_default_theme()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import subprocess as sp
|
import subprocess as sp
|
||||||
import webbrowser
|
import webbrowser
|
||||||
from PyQt5.QtCore import QObject, pyqtSlot, QProcess
|
from PyQt5.QtCore import QObject, pyqtSlot, QProcess
|
||||||
@@ -99,6 +100,7 @@ class UpdatesController(QObject):
|
|||||||
try:
|
try:
|
||||||
updater.startDetached(command)
|
updater.startDetached(command)
|
||||||
except BaseException:
|
except BaseException:
|
||||||
|
logging.error("Unable to start updater")
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
qApp.quit()
|
qApp.quit()
|
||||||
@@ -122,6 +124,7 @@ class UpdatesController(QObject):
|
|||||||
) as proc:
|
) as proc:
|
||||||
updater_version = proc.stdout.read().rstrip("\r\n") # Strip any possible newline, to be sure.
|
updater_version = proc.stdout.read().rstrip("\r\n") # Strip any possible newline, to be sure.
|
||||||
except Exception:
|
except Exception:
|
||||||
|
logging.error("Unable to query the updater")
|
||||||
updater_version = latest_updater_version
|
updater_version = latest_updater_version
|
||||||
if latest_updater_version is None:
|
if latest_updater_version is None:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import hashlib
|
import hashlib
|
||||||
from PyQt5.QtWidgets import QMessageBox
|
from PyQt5.QtWidgets import QMessageBox
|
||||||
@@ -107,7 +108,7 @@ def checksum_ok(data, reference_hash_code):
|
|||||||
|
|
||||||
Expects a sha256 code as argument."""
|
Expects a sha256 code as argument."""
|
||||||
if reference_hash_code is None:
|
if reference_hash_code is None:
|
||||||
raise Exception("ERROR: Invalid hash code.")
|
raise ValueError("ERROR: Invalid hash code.")
|
||||||
code = hashlib.sha256()
|
code = hashlib.sha256()
|
||||||
code.update(data)
|
code.update(data)
|
||||||
return code.hexdigest() == reference_hash_code
|
return code.hexdigest() == reference_hash_code
|
||||||
@@ -192,6 +193,7 @@ def safe_cast(value, cast_type, default=-1):
|
|||||||
try:
|
try:
|
||||||
r = cast_type(value)
|
r = cast_type(value)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
logging.error("Cast type failure")
|
||||||
r = default
|
r = default
|
||||||
finally:
|
finally:
|
||||||
return r
|
return r
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import re
|
import re
|
||||||
from PyQt5.QtGui import QPixmap
|
from PyQt5.QtGui import QPixmap
|
||||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
|
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
|
||||||
@@ -347,6 +348,7 @@ class ForecastData(_BaseWeatherData):
|
|||||||
self._set_dates(forecast, rows["solar_row"])
|
self._set_dates(forecast, rows["solar_row"])
|
||||||
self._set_labels_values(labels_table)
|
self._set_labels_values(labels_table)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
logging.error("Update ForecastData failure")
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def remove_data(self):
|
def remove_data(self):
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import urllib3
|
import urllib3
|
||||||
@@ -39,12 +40,19 @@ def _download_multiline_file_as_list(url=Database.LINK_REF):
|
|||||||
try:
|
try:
|
||||||
return download_file(url, encoding="UTF-8").splitlines()[-1].split(Database.DELIMITER)
|
return download_file(url, encoding="UTF-8").splitlines()[-1].split(Database.DELIMITER)
|
||||||
except Exception:
|
except Exception:
|
||||||
|
logging.error("Database metadata download failure")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_folder_hash_code():
|
def get_folder_hash_code():
|
||||||
return _download_multiline_file_as_list()[0]
|
f = _download_multiline_file_as_list()
|
||||||
|
if f is not None:
|
||||||
|
return f[0]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def get_db_hash_code():
|
def get_db_hash_code():
|
||||||
return _download_multiline_file_as_list()[1]
|
f = _download_multiline_file_as_list()
|
||||||
|
if f is not None:
|
||||||
|
return f[1]
|
||||||
|
return None
|
||||||
|
|||||||
Reference in New Issue
Block a user