1# Orca
2#
3# Copyright 2010-2011 Consorcio Fernando de los Rios.
4# Author: Juanje Ojeda Croissier <jojeda@emergya.es>
5# Author: Javier Hernandez Antunez <jhernandez@emergya.es>
6#
7# This library is free software; you can redistribute it and/or
8# modify it under the terms of the GNU Lesser General Public
9# License as published by the Free Software Foundation; either
10# version 2.1 of the License, or (at your option) any later version.
11#
12# This library is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15# Lesser General Public License for more details.
16#
17# You should have received a copy of the GNU Lesser General Public
18# License along with this library; if not, write to the
19# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
20# Boston MA  02110-1301 USA.
21
22"""JSON backend for Orca settings"""
23
24__id__        = "$Id$"
25__version__   = "$Revision$"
26__date__      = "$Date$"
27__copyright__ = "Copyright (c) 2010-2011 Consorcio Fernando de los Rios."
28__license__   = "LGPL"
29
30from json import load, dump
31import os
32from orca import settings, acss
33
34class Backend:
35
36    def __init__(self, prefsDir):
37        """ Initialize the JSON Backend.
38        """
39        self.general = {}
40        self.pronunciations = {}
41        self.keybindings = {}
42        self.profiles = {}
43        self.settingsFile = os.path.join(prefsDir, "user-settings.conf")
44        self.appPrefsDir = os.path.join(prefsDir, "app-settings")
45
46        self._defaultProfiles = {'default': { 'profile':  settings.profile,
47                                                          'pronunciations': {},
48                                                          'keybindings': {}
49                                            }
50                                }
51
52    def saveDefaultSettings(self, general, pronunciations, keybindings):
53        """ Save default settings for all the properties from
54            orca.settings. """
55        prefs = {'general': general,
56                 'profiles': self._defaultProfiles,
57                 'pronunciations': pronunciations,
58                 'keybindings': keybindings}
59
60        self.general = general
61        self.profiles = self._defaultProfiles
62        self.pronunciations = pronunciations
63        self.keybindings = keybindings
64
65        settingsFile = open(self.settingsFile, 'w')
66        dump(prefs, settingsFile, indent=4)
67        settingsFile.close()
68
69    def getAppSettings(self, appName):
70        fileName = os.path.join(self.appPrefsDir, "%s.conf" % appName)
71        if os.path.exists(fileName):
72            settingsFile = open(fileName, 'r')
73            prefs = load(settingsFile)
74            settingsFile.close()
75        else:
76            prefs = {}
77
78        return prefs
79
80    def saveAppSettings(self, appName, profile, general, pronunciations, keybindings):
81        prefs = self.getAppSettings(appName)
82        profiles = prefs.get('profiles', {})
83        profiles[profile] = {'general': general,
84                             'pronunciations': pronunciations,
85                             'keybindings': keybindings}
86        prefs['profiles'] = profiles
87
88        fileName = os.path.join(self.appPrefsDir, "%s.conf" % appName)
89        settingsFile = open(fileName, 'w')
90        dump(prefs, settingsFile, indent=4)
91        settingsFile.close()
92
93    def saveProfileSettings(self, profile, general,
94                                  pronunciations, keybindings):
95        """ Save minimal subset defined in the profile against current
96            defaults. """
97        if profile is None:
98            profile = 'default'
99
100        general['pronunciations'] = pronunciations
101        general['keybindings'] = keybindings
102
103        with open(self.settingsFile, 'r+') as settingsFile:
104            prefs = load(settingsFile)
105            prefs['profiles'][profile] = general
106            settingsFile.seek(0)
107            settingsFile.truncate()
108            dump(prefs, settingsFile, indent=4)
109
110    def _getSettings(self):
111        """ Load from config file all settings """
112        settingsFile = open(self.settingsFile)
113        try:
114            prefs = load(settingsFile)
115        except ValueError:
116            return
117        self.general = prefs['general'].copy()
118        self.pronunciations = prefs['pronunciations']
119        self.keybindings = prefs['keybindings']
120        self.profiles = prefs['profiles'].copy()
121
122    def getGeneral(self, profile=None):
123        """ Get general settings from default settings and
124            override with profile values. """
125        self._getSettings()
126        generalSettings = self.general.copy()
127        defaultProfile = generalSettings.get('startingProfile',
128                                             ['Default', 'default'])
129        if profile is None:
130            profile = defaultProfile[1]
131        profileSettings = self.profiles[profile].copy()
132        for key, value in profileSettings.items():
133            if key == 'voices':
134                for voiceType, voiceDef in value.items():
135                    value[voiceType] = acss.ACSS(voiceDef)
136            if key not in ['startingProfile', 'activeProfile']:
137                generalSettings[key] = value
138        try:
139            generalSettings['activeProfile'] = profileSettings['profile']
140        except KeyError:
141            generalSettings['activeProfile'] = defaultProfile
142        return generalSettings
143
144    def getPronunciations(self, profile='default'):
145        """ Get pronunciation settings from default settings and
146            override with profile values. """
147        self._getSettings()
148        pronunciations = self.pronunciations.copy()
149        profileSettings = self.profiles[profile].copy()
150        if 'pronunciations' in profileSettings:
151            pronunciations = profileSettings['pronunciations']
152        return pronunciations
153
154    def getKeybindings(self, profile='default'):
155        """ Get keybindings settings from default settings and
156            override with profile values. """
157        self._getSettings()
158        keybindings = self.keybindings.copy()
159        profileSettings = self.profiles[profile].copy()
160        if 'keybindings' in profileSettings:
161            keybindings = profileSettings['keybindings']
162        return keybindings
163
164    def isFirstStart(self):
165        """ Check if we're in first start. """
166
167        return not os.path.exists(self.settingsFile)
168
169    def _setProfileKey(self, key, value):
170        self.general[key] = value
171
172        with open(self.settingsFile, 'r+') as settingsFile:
173            prefs = load(settingsFile)
174            prefs['general'][key] = value
175            settingsFile.seek(0)
176            settingsFile.truncate()
177            dump(prefs, settingsFile, indent=4)
178
179    def setFirstStart(self, value=False):
180        """Set firstStart. This user-configurable setting is primarily
181        intended to serve as an indication as to whether or not initial
182        configuration is needed."""
183        self.general['firstStart'] = value
184        self._setProfileKey('firstStart', value)
185
186    def availableProfiles(self):
187        """ List available profiles. """
188        self._getSettings()
189        profiles = []
190
191        for profileName in self.profiles.keys():
192            profileDict = self.profiles[profileName].copy()
193            profiles.append(profileDict.get('profile'))
194
195        return profiles
196
197    def removeProfile(self, profile):
198        """Remove an existing profile"""
199        def removeProfileFrom(dict):
200            del dict[profile]
201            # if we removed the last profile, restore the default ones
202            if len(dict) == 0:
203                for profileName in self._defaultProfiles:
204                    dict[profileName] = self._defaultProfiles[profileName].copy()
205
206        if profile in self.profiles:
207            removeProfileFrom(self.profiles)
208
209        with open(self.settingsFile, 'r+') as settingsFile:
210            prefs = load(settingsFile)
211            if profile in prefs['profiles']:
212                removeProfileFrom(prefs['profiles'])
213                settingsFile.seek(0)
214                settingsFile.truncate()
215                dump(prefs, settingsFile, indent=4)
216