1 new commit in StationPlaylist:
https://bitbucket.org/nvdaaddonteam/stationplaylist/commits/706305b7ba49/
Changeset: 706305b7ba49
Branch: staging
User: josephsl
Date: 2016-01-14 00:03:25+00:00
Summary: Merge branch '7.0/orangeTrackInfoBoard' into staging
Affected #: 4 files
diff --git a/addon/appModules/splstudio/__init__.py
b/addon/appModules/splstudio/__init__.py
index 2c5cee5..cb35a78 100755
--- a/addon/appModules/splstudio/__init__.py
+++ b/addon/appModules/splstudio/__init__.py
@@ -276,7 +276,7 @@ A: Automation.
C: Announce name of the currently playing track.
D: Remaining time for the playlist.
E: Overall metadata streaming status.
-1 through 4, 0: Metadata streaming status for DSP encoder and four additional
URL's.
+Shift+1 through shift+4, shift+0: Metadata streaming status for DSP encoder
and four additional URL's.
H: Duration of trakcs in this hour slot.
Shift+H: Duration of remaining trakcs in this hour slot.
I: Listener count.
@@ -305,7 +305,7 @@ A: Automation.
C: Toggle cart explorer.
Shift+C: Announce name of the currently playing track.
E: Overall metadata streaming status.
-1 through 4, 0: Metadata streaming status for DSP encoder and four additional
URL's.
+Shift+1 through shift+4, shift+0: Metadata streaming status for DSP encoder
and four additional URL's.
Shift+E: Record to file.
F: Track finder.
H: Duration of trakcs in this hour slot.
@@ -340,7 +340,7 @@ E: Elapsed time.
F: Track finder.
R: Remaining time for the currently playing track.
G: Overall metadata streaming status.
-1 through 4, 0: Metadata streaming status for DSP encoder and four additional
URL's.
+Shift+1 through shift+4, shift+0: Metadata streaming status for DSP encoder
and four additional URL's.
H: Duration of trakcs in this hour slot.
Shift+H: Duration of remaining trakcs in this hour slot.
K: Move to place marker track.
@@ -1682,11 +1682,11 @@ class AppModule(appModuleHandler.AppModule):
"kb:Control+k":"setPlaceMarker",
"kb:k":"findPlaceMarker",
"kb:e":"metadataStreamingAnnouncer",
- "kb:1":"metadataEnabled",
- "kb:2":"metadataEnabled",
- "kb:3":"metadataEnabled",
- "kb:4":"metadataEnabled",
- "kb:0":"metadataEnabled",
+ "kb:shift+1":"metadataEnabled",
+ "kb:shift+2":"metadataEnabled",
+ "kb:shift+3":"metadataEnabled",
+ "kb:shift+4":"metadataEnabled",
+ "kb:shift+0":"metadataEnabled",
"kb:f1":"layerHelp",
"kb:shift+f1":"openOnlineDoc",
"kb:control+shift+u":"updateCheck",
@@ -1720,11 +1720,11 @@ class AppModule(appModuleHandler.AppModule):
"kb:Control+k":"setPlaceMarker",
"kb:k":"findPlaceMarker",
"kb:e":"metadataStreamingAnnouncer",
- "kb:1":"metadataEnabled",
- "kb:2":"metadataEnabled",
- "kb:3":"metadataEnabled",
- "kb:4":"metadataEnabled",
- "kb:0":"metadataEnabled",
+ "kb:shift+1":"metadataEnabled",
+ "kb:shift+2":"metadataEnabled",
+ "kb:shift+3":"metadataEnabled",
+ "kb:shift+4":"metadataEnabled",
+ "kb:shift+0":"metadataEnabled",
"kb:f1":"layerHelp",
"kb:shift+f1":"openOnlineDoc",
}
@@ -1759,11 +1759,11 @@ class AppModule(appModuleHandler.AppModule):
"kb:Control+k":"setPlaceMarker",
"kb:k":"findPlaceMarker",
"kb:g":"metadataStreamingAnnouncer",
- "kb:1":"metadataEnabled",
- "kb:2":"metadataEnabled",
- "kb:3":"metadataEnabled",
- "kb:4":"metadataEnabled",
- "kb:0":"metadataEnabled",
+ "kb:shift+1":"metadataEnabled",
+ "kb:shift+2":"metadataEnabled",
+ "kb:shift+3":"metadataEnabled",
+ "kb:shift+4":"metadataEnabled",
+ "kb:shift+0":"metadataEnabled",
"kb:f1":"layerHelp",
"kb:shift+f1":"openOnlineDoc",
"kb:control+shift+u":"updateCheck",
diff --git a/addon/appModules/splstudio/splconfig.py
b/addon/appModules/splstudio/splconfig.py
index f388544..4246b83 100755
--- a/addon/appModules/splstudio/splconfig.py
+++ b/addon/appModules/splstudio/splconfig.py
@@ -53,7 +53,6 @@ SayPlayingCartName = boolean(default=true)
SayPlayingTrackName = string(default="True")
SPLConPassthrough = boolean(default=false)
CompatibilityLayer = option("off", "jfw", "wineyes", default="off")
-PlaylistRemainder = option("hour", "playlist", default="hour")
AutoUpdateCheck = boolean(default=true)
"""), encoding="UTF-8", list_values=False)
confspec.newlines = "\r\n"
@@ -91,7 +90,6 @@ SayPlayingTrackName = string(default="True")
[Advanced]
SPLConPassthrough = boolean(default=false)
CompatibilityLayer = option("off", "jfw", "wineyes", default="off")
-PlaylistRemainder = option("hour", "playlist", default="hour")
[Update]
AutoUpdateCheck = boolean(default=true)
"""), encoding="UTF-8", list_values=False)
@@ -110,6 +108,9 @@ _SPLDefaults7.validate(_val, copy=True)
# The following settings can be changed in profiles:
_mutatableSettings=("SayEndOfTrack","EndOfTrackTime","SaySongRamp","SongRampTime","MicAlarm","MicAlarmInterval","MetadataEnabled","UseScreenColumnOrder","ColumnOrder","IncludedColumns")
_mutatableSettings7=("IntroOutroAlarms", "MicrophoneAlarm",
"MetadataStreaming", "ColumnAnnouncement")
+# 7.0: Profile-specific confspec (might be removed once a more optimal way to
validate sections is found).
+# Dictionary comprehension is better here.
+confspecprofiles = {sect:key for sect, key in confspec7.iteritems() if sect in
_mutatableSettings7}
# Display an error dialog when configuration validation fails.
def runConfigErrorDialog(errorText, errorType):
@@ -161,6 +162,7 @@ _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 = ""
@@ -215,11 +217,15 @@ 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):
+ t = time.time()
global _configLoadStatus # To be mutated only during unlock routine.
- SPLConfigCheckpoint = ConfigObj(path, configspec = confspec7,
encoding="UTF-8")
+ # 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")
# 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)
@@ -240,20 +246,14 @@ def unlockConfig(path, profileName=None, prefill=False):
if isinstance(configTest[setting], dict):
for failedKey in
configTest[setting].keys():
if not
isinstance(SPLConfigCheckpoint[setting][failedKey], int):
- if prefill: # Base
profile only.
-
SPLConfigCheckpoint[setting][failedKey] = _SPLDefaults7[setting][failedKey]
- else: # Broadcast
profiles.
- if setting not
in _mutatableSettings7:
-
SPLConfigCheckpoint[setting][failedKey] = SPLConfigPool[0][setting][failedKey]
- else:
SPLConfigCheckpoint[setting][failedKey] = _SPLDefaults7[setting][failedKey]
+ # 7.0 optimization:
just reload from defaults dictionary, as broadcast profiles contain
profile-specific settings only.
+
SPLConfigCheckpoint[setting][failedKey] = _SPLDefaults7[setting][failedKey]
# 7.0: Disqualified from being cached this time.
SPLConfigCheckpoint.write()
_configLoadStatus[profileName] = "partialReset"
_extraInitSteps(SPLConfigCheckpoint, profileName=profileName)
- # Only run when loading profiles other than normal profile.
- if not prefill: _discardGlobalSettings(SPLConfigCheckpoint)
- # Conversely:
- else:
+ # Take care of global flags such as updates and so on.
+ if prefill:
if "PSZ" in SPLConfigCheckpoint:
splupdate.SPLAddonSize =
hex(int(SPLConfigCheckpoint["PSZ"], 16))
try: del SPLConfigCheckpoint["PSZ"]
@@ -266,6 +266,7 @@ def unlockConfig(path, profileName=None, prefill=False):
# 7.0 optimization: Store an online backup.
# This online backup is used to prolong SSD life (no need to save a
config if it is same as this copy).
_cacheConfig(SPLConfigCheckpoint)
+ print time.time()-t
return SPLConfigCheckpoint
# Extra initialization steps such as converting value types.
@@ -296,17 +297,6 @@ def _extraInitSteps(conf, profileName=None):
_configLoadStatus[profileName] = "metadataReset"
conf["MetadataStreaming"]["MetadataEnabled"] = [False, False,
False, False, False]
-# Discard global settings when loading broadcast profiles.
-# This helps in conserving memory.
-def _discardGlobalSettings(conf):
- for setting in SPLConfigPool[0].keys():
- # Ignore profile-specific settings/sections.
- if setting not in _mutatableSettings7:
- try:
- del conf[setting]
- except KeyError:
- pass
-
# Cache a copy of the loaded config.
# This comes in handy when saving configuration to disk. For the most part, no
change occurs to config.
# This helps prolong life of a solid-state drive (preventing unnecessary
writes).
@@ -328,6 +318,7 @@ def _cacheConfig(conf):
# Each record (profile name) consists of seven fields organized as a list:
# A bit vector specifying which days should this profile be active, the first
five fields needed for constructing a datetime.datetime object used to look up
when to trigger this profile, and an integer specifying the duration in minutes.
profileTriggers = {} # Using a pickle is quite elegant.
+profileTriggers2 = {} # For caching purposes.
# Profile triggers pickle.
SPLTriggersFile = os.path.join(globalVars.appArgs.configPath,
"spltriggers.pickle")
# Trigger timer.
@@ -335,11 +326,13 @@ triggerTimer = None
# Prepare the triggers dictionary and other runtime support.
def initProfileTriggers():
- global profileTriggers, SPLTriggerProfile, triggerTimer
+ global profileTriggers, profileTriggers2, SPLTriggerProfile,
triggerTimer
try:
profileTriggers = cPickle.load(file(SPLTriggersFile, "r"))
except IOError:
pass
+ # Cache profile triggers, used to compare the runtime dictionary
against the cache.
+ profileTriggers2 = profileTriggers
triggerStart()
# Locate time-based profiles if any.
@@ -448,12 +441,16 @@ def triggerStart(restart=False):
# Dump profile triggers pickle away.
def saveProfileTriggers():
- global triggerTimer, profileTriggers
+ global triggerTimer, profileTriggers, profileTriggers2
if triggerTimer is not None and triggerTimer.IsRunning():
triggerTimer.Stop()
triggerTimer = None
- cPickle.dump(profileTriggers, file(SPLTriggersFile, "wb"))
+ # Unless it is a daily show, profile triggers would not have been
modified.
+ # This trick is employed in order to reduce unnecessary disk writes.
+ if profileTriggers != profileTriggers2:
+ cPickle.dump(profileTriggers, file(SPLTriggersFile, "wb"))
profileTriggers = None
+ profileTriggers2 = None
# Instant profile switch helpers.
# A number of helper functions assisting instant switch profile routine and
others, including sorting and locating the needed profile upon request.
@@ -533,6 +530,8 @@ def _preSave(conf):
del conf["InstantProfile"]
except KeyError:
pass
+ # Todo for 7.2: Remove obsolete keys from normal profile (not
runtime config yet).
+ # Del PlaylistRemainder.
# For other profiles, remove global settings before writing to disk.
else:
# 6.1: Make sure column order and inclusion aren't same as
default values.
@@ -1065,7 +1064,6 @@ class SPLConfigDialog(gui.SettingsDialog):
item.Bind(wx.EVT_BUTTON, self.onAdvancedOptions)
self.splConPassthrough =
SPLConfig["Advanced"]["SPLConPassthrough"]
self.compLayer = SPLConfig["Advanced"]["CompatibilityLayer"]
- self.playlistRemainder =
SPLConfig["Advanced"]["PlaylistRemainder"]
self.autoUpdateCheck = SPLConfig["Update"]["AutoUpdateCheck"]
settingsSizer.Add(item)
diff --git a/addon/appModules/splstudio/splupdate.py
b/addon/appModules/splstudio/splupdate.py
index eee980d..211751e 100755
--- a/addon/appModules/splstudio/splupdate.py
+++ b/addon/appModules/splstudio/splupdate.py
@@ -45,13 +45,17 @@ def initialize():
SPLAddonCheck = SPLAddonState["PDT"]
SPLAddonSize = SPLAddonState["PSZ"]
except IOError:
- pass
+ SPLAddonState["PDT"] = 0
+ SPLAddonState["PSZ"] = 0x0
def terminate():
global SPLAddonState
- SPLAddonState["PSZ"] = SPLAddonSize
- SPLAddonState["PDT"] = SPLAddonCheck
- cPickle.dump(SPLAddonState, file(_updatePickle, "wb"))
+ # Store new values if it is absolutely required.
+ stateChanged = SPLAddonState["PSZ"] != SPLAddonSize or
SPLAddonState["PDT"] != SPLAddonCheck
+ if stateChanged:
+ SPLAddonState["PSZ"] = SPLAddonSize
+ SPLAddonState["PDT"] = SPLAddonCheck
+ cPickle.dump(SPLAddonState, file(_updatePickle, "wb"))
SPLAddonState = None
diff --git a/addon/installTasks.py b/addon/installTasks.py
index 59a6eaf..a6775ca 100755
--- a/addon/installTasks.py
+++ b/addon/installTasks.py
@@ -1,5 +1,5 @@
# StationPlaylist Studio add-on installation tasks
-# Copyright 2015 Joseph Lee and others, released under GPL.
+# Copyright 2015-2016 Joseph Lee and others, released under GPL.
# Provides needed routines during add-on installation and removal.
# Routines are partly based on other add-ons, particularly Place Markers by
Noelia Martinez (thanks add-on authors).
@@ -40,7 +40,6 @@ SayPlayingCartName = boolean(default=true)
SayPlayingTrackName = string(default="True")
SPLConPassthrough = boolean(default=false)
CompatibilityLayer = option("off", "jfw", "wineyes", default="off")
-PlaylistRemainder = option("hour", "playlist", default="hour")
AutoUpdateCheck = boolean(default=true)
"""), encoding="UTF-8", list_values=False)
confspec.newlines = "\r\n"
@@ -71,7 +70,6 @@ _conversionConfig = {
"SayPlayingTrackName":"SayStatus",
"SPLConPassthrough":"Advanced",
"CompatibilityLayer":"Advanced",
- "PlaylistRemainder":"Advanced",
"AutoUpdateCheck":"Update",
}
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.