Fix overwriting config file with every update

This commit is contained in:
Gobinath 2017-04-25 13:18:37 -04:00
parent 00886cf4a5
commit 252d5fa9e8
3 changed files with 122 additions and 85 deletions

View File

@ -20,13 +20,17 @@ import gi
gi.require_version('Gdk', '3.0')
from gi.repository import Gdk, GLib
from html.parser import HTMLParser
from distutils.version import LooseVersion
import babel.dates, os, errno, re, subprocess, threading, logging, locale, json, shutil, pyaudio, wave
bin_directory = os.path.dirname(os.path.realpath(__file__))
home_directory = os.path.expanduser('~')
system_language_directory = os.path.join(bin_directory, 'config/lang')
config_directory = os.path.join(home_directory, '.config/safeeyes')
config_file_path = os.path.join(config_directory, 'safeeyes.json')
style_sheet_path = os.path.join(config_directory, 'style/safeeyes_style.css')
system_config_file_path = os.path.join(bin_directory, "config/safeeyes.json")
system_style_sheet_path = os.path.join(bin_directory, "config/style/safeeyes_style.css")
def play_notification():
"""
@ -312,6 +316,102 @@ def command_exist(command):
return False
def merge_configs(new_config, old_config):
"""
Merge the values of old_config into the new_config.
"""
new_config = new_config.copy()
new_config.update(old_config)
return new_config
def __initialize_safeeyes():
"""
Create the config file and style sheet in ~/.config/safeeyes directory.
"""
logging.info('Copy the config files to ~/.config/safeeyes')
style_dir_path = os.path.join(home_directory, '.config/safeeyes/style')
startup_dir_path = os.path.join(home_directory, '.config/autostart')
# Remove the ~/.config/safeeyes directory
shutil.rmtree(config_directory, ignore_errors=True)
# Remove the startup file
try:
os.remove(os.path.join(home_directory, os.path.join(startup_dir_path, 'safeeyes.desktop')))
except:
pass
# Create the ~/.config/safeeyes/style directory
mkdir(style_dir_path)
mkdir(startup_dir_path)
# Copy the safeeyes.json
shutil.copy2(system_config_file_path, config_file_path)
# Copy the new startup file
try:
os.symlink("/usr/share/applications/safeeyes.desktop", os.path.join(startup_dir_path, 'safeeyes.desktop'))
except OSError as exc:
pass
# Copy the new style sheet
if not os.path.isfile(style_sheet_path):
shutil.copy2(system_style_sheet_path, style_sheet_path)
def read_config():
"""
Read the configuration from the config directory.
If does not exist or outdated by major version, copy the system config and
startup script to user directory.
If the user config is outdated by minor version, update the config by the new values.
"""
logging.info('Reading the configuration file')
if not os.path.isfile(config_file_path):
logging.info('Safe Eyes configuration file not found')
__initialize_safeeyes()
# Read the configurations
with open(config_file_path) as config_file:
user_config = json.load(config_file)
with open(system_config_file_path) as config_file:
system_config = json.load(config_file)
user_config_version = str(user_config['meta']['config_version'])
system_config_version = str(system_config['meta']['config_version'])
if LooseVersion(user_config_version) < LooseVersion(system_config_version):
# Outdated user config
logging.info('Update the old config version {} with new config version {}'.format(user_config_version, system_config_version))
user_config_major_version = user_config_version.split('.')[0]
system_config_major_version = system_config_version.split('.')[0]
if LooseVersion(user_config_major_version) < LooseVersion(system_config_major_version):
# Major version change
__initialize_safeeyes()
# Update the user_config
user_config = system_config
else:
# Minor version change
new_config = system_config.copy()
new_config.update(user_config)
# Update the version
new_config['meta']['config_version'] = system_config_version
# Write the configuration to file
with open(config_file_path, 'w') as config_file:
json.dump(new_config, config_file, indent=4, sort_keys=True)
# Update the user_config
user_config = new_config
return user_config
class __HTMLTextExtractor(HTMLParser):
"""
Helper class to convert HTML to text

View File

@ -18,7 +18,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os, gi, json, shutil, dbus, logging, operator, psutil, sys
import os, gi, json, dbus, logging, operator, psutil
from threading import Timer
from dbus.mainloop.glib import DBusGMainLoop
gi.require_version('Gtk', '3.0')
@ -33,17 +33,13 @@ from safeeyes.TrayIcon import TrayIcon
from safeeyes import Utility
# Define necessary paths
config_file_path = os.path.join(Utility.config_directory, 'safeeyes.json')
style_sheet_path = os.path.join(Utility.config_directory, 'style/safeeyes_style.css')
log_file_path = os.path.join(Utility.config_directory, 'safeeyes.log')
break_screen_glade = os.path.join(Utility.bin_directory, "glade/break_screen.glade")
settings_dialog_glade = os.path.join(Utility.bin_directory, "glade/settings_dialog.glade")
about_dialog_glade = os.path.join(Utility.bin_directory, "glade/about_dialog.glade")
system_config_file_path = os.path.join(Utility.bin_directory, "config/safeeyes.json")
system_style_sheet_path = os.path.join(Utility.bin_directory, "config/style/safeeyes_style.css")
is_active = True
CONFIGURATION_VERSION = 5
SAFE_EYES_VERSION = "1.2.0a9"
"""
@ -167,7 +163,7 @@ def save_settings(config):
core.stop()
# Write the configuration to file
with open(config_file_path, 'w') as config_file:
with open(Utility.config_file_path, 'w') as config_file:
json.dump(config, config_file, indent=4, sort_keys=True)
# Reload the language translation
@ -200,80 +196,11 @@ def disable_safeeyes():
is_active = False
core.stop()
"""
Initialize the configuration directory and copy the files to ~/.config directory.
"""
def initialize_config():
global config
config_dir_path = os.path.join(Utility.home_directory, '.config/safeeyes/style')
startup_dir_path = os.path.join(Utility.home_directory, '.config/autostart')
Utility.mkdir(config_dir_path)
if not os.path.isfile(config_file_path):
# Copy the safeeyes.json
shutil.copy2(system_config_file_path, config_file_path)
# Overwrite the startup file only if config file is replaced
Utility.mkdir(startup_dir_path)
try:
os.symlink("/usr/share/applications/safeeyes.desktop", os.path.join(startup_dir_path, "safeeyes.desktop"))
except OSError as exc:
pass
# Copy the safeeyes_style.css
if not os.path.isfile(style_sheet_path):
shutil.copy2(system_style_sheet_path, style_sheet_path)
# Read the configuration
with open(config_file_path) as config_file:
config = json.load(config_file)
"""
Configuration file has a version config_version.
It is used to overwrite the exsiting config file if there is an update.
Earlier versions did not have this attribute so the following method
checks the version and if it mismatches, it will overwrite the exsiting
config files. If the version property is not available, the file is
considered as an older one and replaced by the new configuration file.
"""
def validate_config():
version_mismatch = False
try:
# Check the config version
config_version = config['meta']['config_version']
version_mismatch = config_version is not CONFIGURATION_VERSION
except:
version_mismatch = True
if version_mismatch:
# Remove ~/.config/safeeyes/safeeyes.json file
try:
os.remove(config_file_path)
except:
pass
# Remove ~/.config/safeeyes/style/safeeyes_style.css file
try:
os.remove(style_sheet_path)
except:
pass
# Remove startup script
try:
os.remove(os.path.join(Utility.home_directory, '.config/autostart/safeeyes.desktop'))
except:
pass
# Create config files again
initialize_config()
def running():
'''
"""
Check if SafeEyes is already running.
'''
"""
process_count = 0
for proc in psutil.process_iter():
try:
@ -291,17 +218,26 @@ def running():
def main():
initialize_config()
"""
Start the Safe Eyes.
"""
# Configure logging. Reset with every restart
# Create the directory to store log file if not exist
if not os.path.exists(Utility.config_directory):
try:
os.makedirs(Utility.config_directory)
except:
pass
# Configure logging.
logging.basicConfig(format='%(asctime)s [%(levelname)s]:[%(threadName)s] %(message)s', filename=log_file_path, filemode='w', level=logging.INFO)
logging.info("Starting Safe Eyes")
if not running():
validate_config()
global break_screen
global core
global config
global notification
global tray_icon
global language
@ -309,6 +245,8 @@ def main():
global plugins
global system_lock_command
config = Utility.read_config()
context = {}
language = Utility.load_language(config['language'])
# Get the lock command only one time
@ -322,7 +260,7 @@ def main():
context['version'] = SAFE_EYES_VERSION
tray_icon = TrayIcon(config, language, show_settings, show_about, enable_safeeyes, disable_safeeyes, on_quit)
break_screen = BreakScreen(on_skipped, on_postponed, break_screen_glade, style_sheet_path)
break_screen = BreakScreen(on_skipped, on_postponed, break_screen_glade, Utility.style_sheet_path)
break_screen.initialize(config, language)
notification = Notification(language)
plugins = Plugins(config)

View File

@ -1,11 +1,10 @@
{
"meta": {
"config_version": 5
"config_version": "5.0"
},
"allow_postpone": false,
"break_interval": 15,
"enable_screen_lock": false,
"enable_statistic": false,
"long_break_duration": 60,
"no_of_short_breaks_per_long_break": 5,
"pre_break_warning_time": 10,