commit/StationPlaylist: josephsl: Merge branch 'master' into staging

  • From: commits-noreply@xxxxxxxxxxxxx
  • To: nvda-addons-commits@xxxxxxxxxxxxx
  • Date: Mon, 25 Jan 2016 17:30:06 -0000

1 new commit in StationPlaylist:

https://bitbucket.org/nvdaaddonteam/stationplaylist/commits/b336cc3950ba/
Changeset:   b336cc3950ba
Branch:      staging
User:        josephsl
Date:        2016-01-25 17:29:12+00:00
Summary:     Merge branch 'master' into staging

Affected #:  5 files

diff --git a/addon/appModules/splstudio/__init__.py 
b/addon/appModules/splstudio/__init__.py
index 0877619..38137a7 100755
--- a/addon/appModules/splstudio/__init__.py
+++ b/addon/appModules/splstudio/__init__.py
@@ -1605,7 +1605,7 @@ class AppModule(appModuleHandler.AppModule):
        script_trackTimeAnalysis.__doc__=_("Announces total length of tracks 
between analysis start marker and the current track")
 
        def script_switchProfiles(self, gesture):
-               splconfig.triggerProfileSwitch() if 
splconfig._SPLTriggerEndTimer.IsRunning() else splconfig.instantProfileSwitch()
+               splconfig.triggerProfileSwitch() if 
splconfig._triggerProfileActive else splconfig.instantProfileSwitch()
 
        def script_setPlaceMarker(self, gesture):
                obj = api.getFocusObject()

diff --git a/addon/appModules/splstudio/splconfig.py 
b/addon/appModules/splstudio/splconfig.py
index 7947260..ed21542 100755
--- a/addon/appModules/splstudio/splconfig.py
+++ b/addon/appModules/splstudio/splconfig.py
@@ -149,6 +149,7 @@ def resetAllConfig():
 
 # In case one or more profiles had config issues, look up the error message 
from the following map.
 _configErrors ={
+       "fileReset":"Settings reset to defaults due to configuration file 
coruption",
        "completeReset":"All settings reset to defaults",
        "partialReset":"Some settings reset to defaults",
        "columnOrderReset":"Column announcement order reset to defaults",
@@ -163,7 +164,6 @@ _configErrors ={
 _configLoadStatus = {} # Key = filename, value is pass or no pass.
 
 def initConfig():
-       t = time.time()
        # 7.0: When add-on 7.0 starts for the first time, check if a conversion 
file exists.
        # To be removed in add-on 7.2.
        curInstantProfile = ""
@@ -218,14 +218,20 @@ def initConfig():
        initProfileTriggers()
        # Let the update check begin.
        splupdate.initialize()
-       print time.time()-t
 
 # Unlock (load) profiles from files.
 def unlockConfig(path, profileName=None, prefill=False):
        global _configLoadStatus # To be mutated only during unlock routine.
        # Optimization: Profiles other than normal profile contains 
profile-specific sections only.
        # This speeds up profile loading routine significantly as there is no 
need to call a function to strip global settings.
-       SPLConfigCheckpoint = ConfigObj(path, configspec = confspec7 if prefill 
else confspecprofiles, encoding="UTF-8")
+       # 7.0: What if profiles have parsing errors?
+       # If so, reset everything back to factory defaults.
+       try:
+               SPLConfigCheckpoint = ConfigObj(path, configspec = confspec7 if 
prefill else confspecprofiles, encoding="UTF-8")
+       except:
+               open(path, "w").close()
+               SPLConfigCheckpoint = ConfigObj(path, configspec = confspec7 if 
prefill else confspecprofiles, encoding="UTF-8")
+               _configLoadStatus[profileName] = "fileReset"
        # 5.2 and later: check to make sure all values are correct.
        # 7.0: Make sure errors are displayed as config keys are now sections 
and may need to go through subkeys.
        configTest = SPLConfigCheckpoint.validate(_val, copy=prefill, 
preserve_errors=True)
@@ -684,9 +690,11 @@ def instantProfileSwitch():
 # The triggers version of the above function.
 # 7.0: Try consolidating this into one or some more functions.
 _SPLTriggerEndTimer = None
+# Record if time-based profile is active or not.
+_triggerProfileActive = False
 
 def triggerProfileSwitch():
-       global SPLPrevProfile, SPLConfig, SPLActiveProfile, triggerTimer, 
_SPLTriggerEndTimer
+       global SPLPrevProfile, SPLConfig, SPLActiveProfile, triggerTimer, 
_SPLTriggerEndTimer, _triggerProfileActive
        if _configDialogOpened:
                # Translators: Presented when trying to switch profiles when 
add-on settings dialog is active.
                ui.message(_("Add-on settings dialog is open, cannot switch 
profiles"))
@@ -706,6 +714,8 @@ def triggerProfileSwitch():
                        SPLPrevProfile = getProfileIndexByName(SPLActiveProfile)
                        # Pass in the prev profile, which will be None for 
instant profile switch.
                        switchProfile(SPLPrevProfile, triggerProfileIndex)
+                       # Set the global trigger flag to inform various 
subsystems such as add-on settings dialog.
+                       _triggerProfileActive = True
                        # Translators: Presented when switch to instant switch 
profile was successful.
                        ui.message(_("Switching profiles"))
                        # Pause automatic update checking.
@@ -721,6 +731,7 @@ def triggerProfileSwitch():
                                _SPLTriggerEndTimer.Start(triggerSettings[6] * 
60 * 1000, True)
                else:
                        switchProfile(None, SPLPrevProfile)
+                       _triggerProfileActive = False
                        SPLPrevProfile = None
                        # Translators: Presented when switching from instant 
switch profile to a previous profile.
                        ui.message(_("Returning to previous profile"))
@@ -1108,7 +1119,7 @@ class SPLConfigDialog(gui.SettingsDialog):
                self.profiles.SetFocus()
 
        def onOk(self, evt):
-               global SPLConfig, SPLActiveProfile, _configDialogOpened, 
SPLSwitchProfile, SPLPrevProfile, profileTriggers
+               global SPLConfig, SPLActiveProfile, _configDialogOpened, 
SPLSwitchProfile, SPLPrevProfile, profileTriggers, _triggerProfileActive
                selectedProfile = self.profiles.GetStringSelection().split(" 
<")[0]
                profileIndex = getProfileIndexByName(selectedProfile)
                SPLConfig["General"]["BeepAnnounce"] = 
self.beepAnnounceCheckbox.Value
@@ -1143,9 +1154,9 @@ class SPLConfigDialog(gui.SettingsDialog):
                applySections(profileIndex)
                SPLActiveProfile = selectedProfile
                SPLSwitchProfile = self.switchProfile
-               # Without nullifying prev profile while switch profile is 
undefined, NVDA will assume it can switch back to that profile when it can't.
-               # It also causes NVDA to display wrong label for switch button.
-               if self.switchProfile is None:
+               # Make sure to nullify prev profile if instant switch profile 
is gone.
+               # 7.0: Don't do the following in the midst of a broadcast.
+               if self.switchProfile is None and not _triggerProfileActive:
                        SPLPrevProfile = None
                _configDialogOpened = False
                # 7.0: Perform extra action such as restarting auto update 
timer.
@@ -1158,11 +1169,12 @@ class SPLConfigDialog(gui.SettingsDialog):
                super(SPLConfigDialog,  self).onOk(evt)
 
        def onCancel(self, evt):
-               global _configDialogOpened, SPLActiveProfile, SPLSwitchProfile, 
SPLConfig
+               global _configDialogOpened, SPLActiveProfile, SPLSwitchProfile, 
SPLConfig, profileTriggers
                # 6.1: Discard changes to included columns set.
                self.includedColumns.clear()
                self.includedColumns = None
-               # Remove profile triggers as well.
+               # Apply profile trigger changes if any.
+               profileTriggers = dict(self._profileTriggersConfig)
                self._profileTriggersConfig.clear()
                self._profileTriggersConfig = None
                triggerStart(restart=True)
@@ -1299,6 +1311,10 @@ class SPLConfigDialog(gui.SettingsDialog):
                if self.switchProfile == oldName:
                        self.switchProfile = newName
                        self.switchProfileRenamed = True
+               # Be sure to update profile triggers.
+               if oldName in self._profileTriggersConfig:
+                       self._profileTriggersConfig[newName] = 
self._profileTriggersConfig[oldName]
+                       del self._profileTriggersConfig[oldName]
                if self.activeProfile == oldName:
                        self.activeProfile = newName
                self.profileNames[profilePos] = newName
@@ -1312,6 +1328,13 @@ class SPLConfigDialog(gui.SettingsDialog):
                self.profiles.SetFocus()
 
        def onDelete(self, evt):
+               # Prevent profile deletion in the midst of a broadcast, 
otherwise time-based profile switching flag will become inconsistent.
+               # 7.1: Find a way to safely proceed via two-step verification 
if trying to delete currently active time-based profile.
+               global _SPLTriggerEndTimer, _triggerProfileActive
+               if (_SPLTriggerEndTimer is not None and 
_SPLTriggerEndTimer.IsRunning()) or _triggerProfileActive:
+                       gui.messageBox(_("Are you currently broadcasting a 
show? If so, please press SPL Assistant, F12 to switch back to a previously 
active profile before opening add-on settings to delete a profile."),
+                               _("Midst of a broadcast"), wx.OK | 
wx.ICON_ERROR, self)
+                       return
                index = self.profiles.Selection
                name = self.profiles.GetStringSelection().split(" <")[0]
                configPos = getProfileIndexByName(name)
@@ -1338,6 +1361,8 @@ class SPLConfigDialog(gui.SettingsDialog):
                self.profiles.Delete(index)
                del self.profileNames[profilePos]
                del _SPLCache[name]
+               if name in self._profileTriggersConfig:
+                       del self._profileTriggersConfig[name]
                # 6.3: Select normal profile if the active profile is gone.
                # 7.0: Consult profile names instead.
                try:
@@ -1355,7 +1380,7 @@ class SPLConfigDialog(gui.SettingsDialog):
        def onInstantSwitch(self, evt):
                selection = self.profiles.GetSelection()
                # More efficient to pull the name straight from the names pool.
-               selectedName = self.profileNames.index(selection)
+               selectedName = self.profileNames[selection]
                flag = _("instant switch")
                if self.instantSwitchCheckbox.Value:
                        if self.switchProfile is not None and (selectedName != 
self.switchProfile):

diff --git a/addon/appModules/splstudio/splmisc.py 
b/addon/appModules/splstudio/splmisc.py
index 8462ea7..8ef3962 100755
--- a/addon/appModules/splstudio/splmisc.py
+++ b/addon/appModules/splstudio/splmisc.py
@@ -332,7 +332,7 @@ class SPLCountdownTimer(object):
                        ui.message("Timer complete")
                        if self.func is not None:
                                self.func()
-                       self.stop()
+                       self.Stop()
                elif 0 < self.duration <= self.threshold:
                        ui.message(str(self.duration))
 

diff --git a/addon/installTasks.py b/addon/installTasks.py
index 34dd87e..14d7053 100755
--- a/addon/installTasks.py
+++ b/addon/installTasks.py
@@ -75,7 +75,12 @@ _conversionConfig = {
 
 # Invoked when upgrading to 7.0 (to be removed in 7.2).
 def config6to7(path):
-       profile = ConfigObj(path, configspec = confspec, encoding="UTF-8")
+       # Sometimes, an exception could be thrown if ConfigObj says it cannot 
parse the config file, so skip offending files.
+       # This means the unlock function in splconfig will handle this case.
+       try:
+               profile = ConfigObj(path, configspec = confspec, 
encoding="UTF-8")
+       except:
+               return
        # Optimization: no need to convert if sectionized.
        for section in ["General", "IntroOutroAlarms", "MicrophoneAlarm", 
"ColumnAnnouncement", "MetadataStreaming", "SayStatus", "Advanced", "Startup"]:
                if section in profile:

diff --git a/readme.md b/readme.md
index 50befe7..5df12f9 100755
--- a/readme.md
+++ b/readme.md
@@ -171,6 +171,7 @@ If you are using Studio on a touchscreen computer running 
Windows 8 or later and
 * It is now possible to use a different screen reader command layout for SPL 
Assistant commands. Go to advanced options dialog from add-on settings to 
configure this option between NVDA, JAWS and Window-Eyes layouts. See the SPL 
Assistant commands above for details.
 * NVDA can be configured to switch to a specific broadcast profile at a 
specific day and time. Use the new triggers dialog in add-on settings to 
configure this.
 * Entries in profiles combo box in add-on settings dialog now shows profile 
flags such as active, whether it is an instant switch profile and so on.
+* If a serious problem with reading broadcast profile files are found, NVDA 
will present an error dialog and reset settings to defaults instead of doing 
nothing or sounding an error tone.
 * In add-on settings dialog, the controls used to toggle announcement of 
scheduled time, listener count, cart name and track name has been moved to a 
dedicated status announcements dialog (select status announcement button to 
open this dialog).
 * Added a new setting in add-on settings dialog to let NVDA play beep for 
different track categories when moving between tracks in playlist viewer.
 * It is no longer required to stay in the playlist viewer window in order to 
obtain time announcements such as remaining time for the track and broadcaster 
time.

Repository URL: https://bitbucket.org/nvdaaddonteam/stationplaylist/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.

Other related posts: