Example #1
0
 def test_setSetting_When_nested_setting_does_not_exist_but_part_of_its_xml_path_does_Then_create_it(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(platform=p, init_with='<advancedsettings><video></video></advancedsettings>')
     s.setSetting('video/displayremotecodes', 'true')
     xml = s.__str__()
     log.debug(xml)
     [self.assertTrue(s in xml) for s in ('<video>','<displayremotecodes>','true','</displayremotecodes>','</video>')]
Example #2
0
 def test_setSetting_When_setting_does_not_exist_Then_create_it(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(platform=p, init_with='<advancedsettings><loglevel>0</loglevel></advancedsettings>')
     s.setSetting('displayremotecodes', 'true')
     xml = s.__str__()
     log.debug(xml)
     [self.assertTrue(s in xml) for s in ('<displayremotecodes>','true','</displayremotecodes>')]
Example #3
0
 def test_getSetting_When_non_empty_setting_Then_return_as_str(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(
         platform=p,
         init_with=
         '<advancedsettings><loglevel>0</loglevel></advancedsettings>')
     self.assertEqual('0', s.getSetting('loglevel'))
Example #4
0
 def test_getSetting_When_setting_does_not_exist_Then_return_none(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(
         platform=p,
         init_with=
         '<advancedsettings><loglevel></loglevel></advancedsettings>')
     self.assertIsNone(s.getSetting('foo'))
Example #5
0
 def test_hasSetting_When_setting_exists_at_depth_eq_1_Then_returns_true(
         self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     advanced = AdvancedSettings(
         platform=p,
         init_with=
         """<advancedsettings><loglevel>0</loglevel></advancedsettings>""")
     self.assertTrue(advanced.hasSetting('loglevel'))
Example #6
0
 def test_setSetting_When_setting_exists_Then_update_it(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(platform=p, init_with='<advancedsettings><loglevel>3</loglevel></advancedsettings>')
     s.setSetting('loglevel', '2')
     xml = s.__str__()
     log.debug(xml)
     self.assertTrue('<loglevel>' in xml)
     self.assertTrue('2' in xml)
     self.assertTrue('</loglevel>' in xml)
     self.assertFalse('3' in xml)
Example #7
0
 def test_save_When_advancedsettings_file_does_not_exist_Then_backup_is_not_created(self):
     sandbox = tempfile.mkdtemp(suffix='mythbox')
     try:
         p = Mock()
         when(p).getUserDataDir().thenReturn(sandbox)
         advanced = AdvancedSettings(platform=p)
         advanced.save()
         self.assertTrue(os.path.exists(os.path.join(sandbox, 'advancedsettings.xml')))
         self.assertFalse(os.path.exists(os.path.join(sandbox, 'advancedsettings.xml.mythbox')))
     finally:
         shutil.rmtree(sandbox)
Example #8
0
 def test_setSetting_When_nested_setting_does_not_exist_Then_create_it(
         self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(platform=p)
     s.setSetting('video/displayremotecodes', 'true')
     xml = s.__str__()
     log.debug(xml)
     [
         self.assertTrue(s in xml)
         for s in ('<video>', '<displayremotecodes>', 'true',
                   '</displayremotecodes>', '</video>')
     ]
Example #9
0
 def test_setSetting_When_setting_exists_Then_update_it(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(
         platform=p,
         init_with=
         '<advancedsettings><loglevel>3</loglevel></advancedsettings>')
     s.setSetting('loglevel', '2')
     xml = s.__str__()
     log.debug(xml)
     self.assertTrue('<loglevel>' in xml)
     self.assertTrue('2' in xml)
     self.assertTrue('</loglevel>' in xml)
     self.assertFalse('3' in xml)
Example #10
0
 def test_setSetting_When_setting_does_not_exist_Then_create_it(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(
         platform=p,
         init_with=
         '<advancedsettings><loglevel>0</loglevel></advancedsettings>')
     s.setSetting('displayremotecodes', 'true')
     xml = s.__str__()
     log.debug(xml)
     [
         self.assertTrue(s in xml)
         for s in ('<displayremotecodes>', 'true', '</displayremotecodes>')
     ]
Example #11
0
 def test_save_When_advancedsettings_file_does_not_exist_Then_backup_is_not_created(
         self):
     sandbox = tempfile.mkdtemp(suffix='mythbox')
     try:
         p = Mock()
         when(p).getUserDataDir().thenReturn(sandbox)
         advanced = AdvancedSettings(platform=p)
         advanced.save()
         self.assertTrue(
             os.path.exists(os.path.join(sandbox, 'advancedsettings.xml')))
         self.assertFalse(
             os.path.exists(
                 os.path.join(sandbox, 'advancedsettings.xml.mythbox')))
     finally:
         shutil.rmtree(sandbox)
Example #12
0
 def test_getSetting_When_non_empty_nested_setting_Then_return_as_str(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     xml = """
     <advancedsettings>
         <loglevel>0</loglevel>
         <video>
             <usetimeseeking>true</usetimeseeking>
         </video>
     </advancedsettings>
     """
     s = AdvancedSettings(platform=p, init_with=xml)
     self.assertEqual('0', s.getSetting('loglevel'))
     self.assertEqual('true', s.getSetting('video/usetimeseeking'))
     self.assertIsNone(s.getSetting('loglevel/foo'))
Example #13
0
 def test_save_When_advancedsettings_file_does_exist_and_no_backup_exists_Then_backup_created(self):
     sandbox = tempfile.mkdtemp(suffix='mythbox')
     f = open(os.path.join(sandbox, 'advancedsettings.xml'), 'w')
     f.write('<advancedsettings><loglevel>0</loglevel></advancedsettings>')
     f.close()
     self.assertTrue(os.path.exists(os.path.join(sandbox, 'advancedsettings.xml')))
     
     try:
         p = Mock()
         when(p).getUserDataDir().thenReturn(sandbox)
         advanced = AdvancedSettings(platform=p)
         advanced.save()
         self.assertTrue(os.path.exists(os.path.join(sandbox, 'advancedsettings.xml.mythbox')))
     finally:
         shutil.rmtree(sandbox)
Example #14
0
 def __init__(self, *args, **kwargs):
     BaseWindow.__init__(self, *args, **kwargs)
     [
         setattr(self, k, v) for k, v in kwargs.iteritems() if k in (
             'settings',
             'translator',
             'platform',
             'fanArt',
             'cachesByName',
         )
     ]
     self.settingsMap = {}  # key = controlId,  value = Setting
     self.t = self.translator.get
     self.advanced = AdvancedSettings(platform=self.platform)
     log.debug('Advanced settings:\n %s' % self.advanced)
Example #15
0
 def test_getSetting_When_non_empty_nested_setting_Then_return_as_str(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     xml = """
     <advancedsettings>
         <loglevel>0</loglevel>
         <video>
             <usetimeseeking>true</usetimeseeking>
         </video>
     </advancedsettings>
     """
     s = AdvancedSettings(platform=p, init_with=xml)
     self.assertEqual('0', s.getSetting('loglevel'))
     self.assertEqual('true', s.getSetting('video/usetimeseeking'))
     self.assertIsNone(s.getSetting('loglevel/foo'))
Example #16
0
 def __init__(self, *args, **kwargs):
     BaseWindow.__init__(self, *args, **kwargs)
     [setattr(self,k,v) for k,v in kwargs.iteritems() if k in ('settings','translator','platform','fanArt','cachesByName',)]
     self.settingsMap = {}  # key = controlId,  value = Setting
     self.t = self.translator.get
     self.advanced = AdvancedSettings(platform=self.platform)
     log.debug('Advanced settings:\n %s' % self.advanced)
Example #17
0
 def test_str_When_advancedsettings_file_does_not_exists_Then_constructor_will_initialize_a_new_dom(
         self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     advanced = AdvancedSettings(platform=p)
     s = '%s' % advanced
     log.debug(s)
     self.assertTrue("<advancedsettings />" in s)
Example #18
0
    def test_save_When_advancedsettings_file_does_exist_and_no_backup_exists_Then_backup_created(
            self):
        sandbox = tempfile.mkdtemp(suffix='mythbox')
        f = open(os.path.join(sandbox, 'advancedsettings.xml'), 'w')
        f.write('<advancedsettings><loglevel>0</loglevel></advancedsettings>')
        f.close()
        self.assertTrue(
            os.path.exists(os.path.join(sandbox, 'advancedsettings.xml')))

        try:
            p = Mock()
            when(p).getUserDataDir().thenReturn(sandbox)
            advanced = AdvancedSettings(platform=p)
            advanced.save()
            self.assertTrue(
                os.path.exists(
                    os.path.join(sandbox, 'advancedsettings.xml.mythbox')))
        finally:
            shutil.rmtree(sandbox)
Example #19
0
 def __init__(self, *args, **kwargs):
     BaseWindow.__init__(self, *args, **kwargs)
     [
         setattr(self, k, v)
         for k, v in kwargs.iteritems()
         if k in ("settings", "translator", "platform", "fanArt", "cachesByName")
     ]
     self.settingsMap = {}  # key = controlId,  value = Setting
     self.t = self.translator.get
     self.advanced = AdvancedSettings(platform=self.platform)
     log.debug("Advanced settings:\n %s" % self.advanced)
Example #20
0
 def test_setSetting_Works_for_many_settings(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(platform=p)
     s.setSetting('loglevel', '2')
     s.setSetting('displayremotecodes', 'true')
     xml = s.__str__()
     log.debug(xml)
     self.assertTrue('<loglevel>' in xml)
     self.assertTrue('2' in xml)
     self.assertTrue('</loglevel>' in xml)
     self.assertTrue('<displayremotecodes>' in xml)
     self.assertTrue('true' in xml)
     self.assertTrue('</displayremotecodes>' in xml)
Example #21
0
 def test_setSetting_Works_for_many_settings(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(platform=p)
     s.setSetting('loglevel', '2')
     s.setSetting('displayremotecodes', 'true')
     xml = s.__str__()
     log.debug(xml)
     self.assertTrue('<loglevel>' in xml)
     self.assertTrue('2' in xml)
     self.assertTrue('</loglevel>' in xml)
     self.assertTrue('<displayremotecodes>' in xml)
     self.assertTrue('true' in xml)
     self.assertTrue('</displayremotecodes>' in xml)
Example #22
0
 def test_hasSetting_When_setting_exists_at_depth_gt_1_Then_returns_true(
         self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     xml = """
     <advancedsettings>
         <loglevel>0</loglevel>
         <video>
             <usetimeseeking>true</usetimeseeking>
         </video>
     </advancedsettings>
     """
     s = AdvancedSettings(platform=p, init_with=xml)
     self.assertTrue(s.hasSetting('video/usetimeseeking'))
     self.assertFalse(s.hasSetting('video/usetimeseeking/crapola'))
     self.assertTrue(s.hasSetting('loglevel'))
     self.assertFalse(s.hasSetting('loglevel/crapola'))
     self.assertTrue(s.hasSetting('video'))
Example #23
0
 def test_hasSetting_When_setting_exists_at_depth_gt_1_Then_returns_true(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     xml = """
     <advancedsettings>
         <loglevel>0</loglevel>
         <video>
             <usetimeseeking>true</usetimeseeking>
         </video>
     </advancedsettings>
     """
     s = AdvancedSettings(platform=p, init_with=xml)
     self.assertTrue(s.hasSetting('video/usetimeseeking'))
     self.assertFalse(s.hasSetting('video/usetimeseeking/crapola'))
     self.assertTrue(s.hasSetting('loglevel'))
     self.assertFalse(s.hasSetting('loglevel/crapola'))
     self.assertTrue(s.hasSetting('video'))
Example #24
0
class SettingsWindow(BaseWindow):
    
    def __init__(self, *args, **kwargs):
        BaseWindow.__init__(self, *args, **kwargs)
        [setattr(self,k,v) for k,v in kwargs.iteritems() if k in ('settings','translator','platform','fanArt','cachesByName',)]
        self.settingsMap = {}  # key = controlId,  value = Setting
        self.t = self.translator.get
        self.advanced = AdvancedSettings(platform=self.platform)
        log.debug('Advanced settings:\n %s' % self.advanced)
                 
    def register(self, setting):
        self.settingsMap[setting.widget.getId()] = setting
    
    @timed 
    def onInit(self):
        if not self.win:
            log.debug('onInit')
            self.win = xbmcgui.Window(xbmcgui.getCurrentWindowId())
            
            # Nav Buttons
            self.testSettingsButton = self.getControl(253)
            self.clearCacheButton = self.getControl(405)
            
            self.streamingEnabledRadioButton = self.getControl(208)
            self.recordingsButton = self.getControl(205) 
            
            # MythTV Settings
            if hasattr(self.settings, 'master') and self.settings.master:
                self.setWindowProperty('MasterBackendHostname', '%s / %s' % (self.settings.master.hostname, self.settings.master.ipAddress))
                self.setWindowProperty('MasterBackendPort', str(self.settings.master.port))
            
            self.register(Setting(self.settings, 'streaming_enabled', bool, None, self.getControl(208)))
            self.register(Setting(self.settings, 'paths_recordedprefix', str, ExternalizedSettingValidator(MythSettings.verifyRecordingDirs), self.getControl(205)))
            self.register(Setting(self.settings, 'confirm_on_delete', bool, None, self.getControl(206)))
            self.register(Setting(self.settings, 'aggressive_caching', bool, None, self.getControl(207)))
            
            # MySQL Settings
            self.register(Setting(self.settings, 'mysql_host', str, ExternalizedSettingValidator(MythSettings.verifyMySQLHost), self.getControl(301)))
            self.register(Setting(self.settings, 'mysql_port', int, ExternalizedSettingValidator(MythSettings.verifyMySQLPort), self.getControl(302)))
            self.register(Setting(self.settings, 'mysql_database', str, ExternalizedSettingValidator(MythSettings.verifyMySQLDatabase), self.getControl(303)))
            self.register(Setting(self.settings, 'mysql_user', str, ExternalizedSettingValidator(MythSettings.verifyMySQLUser), self.getControl(304)))              
            self.register(Setting(self.settings, 'mysql_password', str, None, self.getControl(305)))
    
            # Fanart Settings
            self.register(Setting(self.settings, 'fanart_tvdb',   bool, None, self.getControl(401)))
            self.register(Setting(self.settings, 'fanart_tvrage', bool, None, self.getControl(406)))
            self.register(Setting(self.settings, 'fanart_tmdb',   bool, None, self.getControl(402)))
            self.register(Setting(self.settings, 'fanart_imdb',   bool, None, self.getControl(403)))
            self.register(Setting(self.settings, 'fanart_google', bool, None, self.getControl(404)))
    
            # Advanced Settings
            self.register(Setting(self.settings, 'logging_enabled', bool, None, self.getControl(502)))
            self.register(Setting(self.settings, 'feeds_twitter', str, None, self.getControl(503)))
            self.setWindowProperty('debugLogLocation', self.translator.get(m.DEBUG_LOG_LOCATION) % self.platform.getXbmcLog())
                        
            # Playback settings
            self.advanced.get = self.advanced.getSetting
            self.advanced.put = self.advanced.setSetting
            self.register(Setting(self.advanced, 'video/timeseekforward', Seconds, None, self.getControl(602)))
            self.register(Setting(self.advanced, 'video/timeseekbackward', NegativeSeconds, None, self.getControl(603)))
            self.register(Setting(self.advanced, 'video/timeseekforwardbig', Seconds, None, self.getControl(604)))
            self.register(Setting(self.advanced, 'video/timeseekbackwardbig', NegativeSeconds, None, self.getControl(605)))

            self.render()
            
    @catchall    
    @window_busy
    def onClick(self, controlId):
        log.debug('onClick %s ' % controlId)
        source = self.getControl(controlId)

        mappedSetting = self.settingsMap.get(controlId)
        if mappedSetting:
            mappedSetting.readInput()
            if mappedSetting.store == self.advanced:
                self.advanced.put('video/usetimeseeking', 'true') # required for seek values to take effect
                self.advanced.save()
                log.debug(self.advanced)
            else:
                if self.streamingEnabledRadioButton == source: 
                    self.renderStreaming()
                self.settings.save()
        elif self.testSettingsButton == source: self.testSettings()
        elif self.clearCacheButton == source: self.clearCache()
        else: log.debug("nothing done onClick")
        log.debug('=================================\n%s' % self.settings)
            
    def onFocus(self, controlId):
        pass
            
    @catchall
    def onAction(self, action):
        if action.getId() in Action.GO_BACK:
            self.close()

    def renderStreaming(self):
        # special mutual exclusion for handling of streaming enabled
        self.recordingsButton.setEnabled(not self.streamingEnabledRadioButton.isSelected())

    @window_busy
    def render(self):
        for setting in self.settingsMap.values():
            log.debug('Rendering %s' % safe_str(setting.key))
            setting.render()

        self.renderStreaming()
                    
        import default
        about = "[B]%s[/B]\n\n%s\n\n%s\n\n%s\n\n\n\nMythBox would not be possible without the\nfollowing opensource software and services" % (default.__scriptname__, default.__author__, default.__url__, self.platform.addonVersion())
        opensource = """
        [B]Software[/B]
        
        BiDict
        BeautifulSoup
        Decorator
        Eclipse
        ElementTree
        FeedParser
        GNU/Linux
        HTMLTestRunner
        IMDBPy
        Mockito
        MythTV
        MySQL-Connector-Python
        ODict
        PyDev for Eclipse
        Python
        Python-Twitter 
        SimpleJSON
        TheMovieDb Python API
        TVDB Python API
        TVRage Python API
        Twisted
        XBMC
        
        [B]Services[/B]
        
        Google Image Search
        Google Code Project Hosting
        Internet Movie Database
        The Movie Database
        TVDB
        TVRage
        Twitter
        """
        self.setWindowProperty('AboutText', about)
        self.setWindowProperty('OpensourceText', opensource)
        self.setWindowProperty('ReadmeText', '%s\n%s' % (
            open(os.path.join(self.platform.getScriptDir(), 'README.md'), 'r').read(),
            open(os.path.join(self.platform.getScriptDir(), 'FAQ'), 'r').read()))

    @window_busy
    def testSettings(self):
        try:
            self.settings.verify()
            self.setWindowProperty('MasterBackendHostname', '%s / %s' % (self.settings.master.hostname, self.settings.master.ipAddress))
            self.setWindowProperty('MasterBackendPort', str(self.settings.master.port))
            xbmcgui.Dialog().ok(self.t(m.INFO), u'', self.t(m.SETTINGS_OK))
        except SettingsException, ex:
            self.settings.master = None
            self.setWindowProperty('MasterBackendHostname', '')
            self.setWindowProperty('MasterBackendPort', '')
            xbmcgui.Dialog().ok(self.t(m.ERROR), u'', str(ex))
Example #25
0
 def test_hasSetting_When_setting_exists_at_depth_eq_1_Then_returns_true(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     advanced = AdvancedSettings(platform=p, init_with="""<advancedsettings><loglevel>0</loglevel></advancedsettings>""")
     self.assertTrue(advanced.hasSetting('loglevel'))
Example #26
0
 def test_hasSetting_When_setting_does_not_exist_Then_returns_false(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     advanced = AdvancedSettings(platform=p)
     self.assertFalse(advanced.hasSetting('loglevel'))
Example #27
0
 def test_constructor_When_seeded_with_xml_as_string(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     xml = """<advancedsettings><loglevel>0</loglevel></advancedsettings>"""
     advanced = AdvancedSettings(platform=p, init_with=xml)
     self.assertTrue(advanced.hasSetting('loglevel'))
Example #28
0
 def test_constructor_When_seeded_with_xml_as_string(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     xml = """<advancedsettings><loglevel>0</loglevel></advancedsettings>"""
     advanced = AdvancedSettings(platform=p, init_with=xml)
     self.assertTrue(advanced.hasSetting('loglevel'))
Example #29
0
 def test_getSetting_When_setting_does_not_exist_Then_return_none(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(platform=p, init_with='<advancedsettings><loglevel></loglevel></advancedsettings>')
     self.assertIsNone(s.getSetting('foo'))
Example #30
0
 def test_getSetting_When_empty_setting_but_setting_exists_Then_return_as_empty_str(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     s = AdvancedSettings(platform=p, init_with='<advancedsettings><loglevel></loglevel></advancedsettings>')
     self.assertEqual('', s.getSetting('loglevel'))
Example #31
0
 def test_hasSetting_When_setting_does_not_exist_Then_returns_false(self):
     p = Mock()
     when(p).getUserDataDir().thenReturn('')
     advanced = AdvancedSettings(platform=p)
     self.assertFalse(advanced.hasSetting('loglevel'))
Example #32
0
class SettingsWindow(BaseWindow):
    def __init__(self, *args, **kwargs):
        BaseWindow.__init__(self, *args, **kwargs)
        [
            setattr(self, k, v) for k, v in kwargs.iteritems() if k in (
                'settings',
                'translator',
                'platform',
                'fanArt',
                'cachesByName',
            )
        ]
        self.settingsMap = {}  # key = controlId,  value = Setting
        self.t = self.translator.get
        self.advanced = AdvancedSettings(platform=self.platform)
        log.debug('Advanced settings:\n %s' % self.advanced)

    def register(self, setting):
        self.settingsMap[setting.widget.getId()] = setting

    @timed
    def onInit(self):
        if not self.win:
            log.debug('onInit')
            self.win = xbmcgui.Window(xbmcgui.getCurrentWindowId())

            # Nav Buttons
            self.testSettingsButton = self.getControl(253)
            self.clearCacheButton = self.getControl(405)

            self.streamingEnabledRadioButton = self.getControl(208)
            self.recordingsButton = self.getControl(205)

            # MythTV Settings
            if hasattr(self.settings, 'master') and self.settings.master:
                self.setWindowProperty(
                    'MasterBackendHostname',
                    '%s / %s' % (self.settings.master.hostname,
                                 self.settings.master.ipAddress))
                self.setWindowProperty('MasterBackendPort',
                                       str(self.settings.master.port))

            self.register(
                Setting(self.settings, 'streaming_enabled', bool, None,
                        self.getControl(208)))
            self.register(
                Setting(
                    self.settings, 'paths_recordedprefix', str,
                    ExternalizedSettingValidator(
                        MythSettings.verifyRecordingDirs),
                    self.getControl(205)))
            self.register(
                Setting(self.settings, 'confirm_on_delete', bool, None,
                        self.getControl(206)))
            self.register(
                Setting(self.settings, 'aggressive_caching', bool, None,
                        self.getControl(207)))

            # MySQL Settings
            self.register(
                Setting(
                    self.settings, 'mysql_host', str,
                    ExternalizedSettingValidator(MythSettings.verifyMySQLHost),
                    self.getControl(301)))
            self.register(
                Setting(
                    self.settings, 'mysql_port', int,
                    ExternalizedSettingValidator(MythSettings.verifyMySQLPort),
                    self.getControl(302)))
            self.register(
                Setting(
                    self.settings, 'mysql_database', str,
                    ExternalizedSettingValidator(
                        MythSettings.verifyMySQLDatabase),
                    self.getControl(303)))
            self.register(
                Setting(
                    self.settings, 'mysql_user', str,
                    ExternalizedSettingValidator(MythSettings.verifyMySQLUser),
                    self.getControl(304)))
            self.register(
                Setting(self.settings, 'mysql_password', str, None,
                        self.getControl(305)))

            # Fanart Settings
            self.register(
                Setting(self.settings, 'fanart_tvdb', bool, None,
                        self.getControl(401)))
            self.register(
                Setting(self.settings, 'fanart_tvrage', bool, None,
                        self.getControl(406)))
            self.register(
                Setting(self.settings, 'fanart_tmdb', bool, None,
                        self.getControl(402)))
            self.register(
                Setting(self.settings, 'fanart_imdb', bool, None,
                        self.getControl(403)))
            self.register(
                Setting(self.settings, 'fanart_google', bool, None,
                        self.getControl(404)))

            # Advanced Settings
            self.register(
                Setting(self.settings, 'logging_enabled', bool, None,
                        self.getControl(502)))
            self.register(
                Setting(self.settings, 'feeds_twitter', str, None,
                        self.getControl(503)))
            self.setWindowProperty(
                'debugLogLocation',
                self.translator.get(m.DEBUG_LOG_LOCATION) %
                self.platform.getXbmcLog())

            # Playback settings
            self.advanced.get = self.advanced.getSetting
            self.advanced.put = self.advanced.setSetting
            self.register(
                Setting(self.advanced, 'video/timeseekforward', Seconds, None,
                        self.getControl(602)))
            self.register(
                Setting(self.advanced, 'video/timeseekbackward',
                        NegativeSeconds, None, self.getControl(603)))
            self.register(
                Setting(self.advanced, 'video/timeseekforwardbig', Seconds,
                        None, self.getControl(604)))
            self.register(
                Setting(self.advanced, 'video/timeseekbackwardbig',
                        NegativeSeconds, None, self.getControl(605)))

            self.render()

    @catchall
    @window_busy
    def onClick(self, controlId):
        log.debug('onClick %s ' % controlId)
        source = self.getControl(controlId)

        mappedSetting = self.settingsMap.get(controlId)
        if mappedSetting:
            mappedSetting.readInput()
            if mappedSetting.store == self.advanced:
                self.advanced.put(
                    'video/usetimeseeking',
                    'true')  # required for seek values to take effect
                self.advanced.save()
                log.debug(self.advanced)
            else:
                if self.streamingEnabledRadioButton == source:
                    self.renderStreaming()
                self.settings.save()
        elif self.testSettingsButton == source:
            self.testSettings()
        elif self.clearCacheButton == source:
            self.clearCache()
        else:
            log.debug("nothing done onClick")
        log.debug('=================================\n%s' % self.settings)

    def onFocus(self, controlId):
        pass

    @catchall
    def onAction(self, action):
        if action.getId() in Action.GO_BACK:
            self.close()

    def renderStreaming(self):
        # special mutual exclusion for handling of streaming enabled
        self.recordingsButton.setEnabled(
            not self.streamingEnabledRadioButton.isSelected())

    @window_busy
    def render(self):
        for setting in self.settingsMap.values():
            log.debug('Rendering %s' % safe_str(setting.key))
            setting.render()

        self.renderStreaming()

        import default
        about = "[B]%s[/B]\n\n%s\n\n%s\n\n%s\n\n\n\nMythBox would not be possible without the\nfollowing opensource software and services" % (
            default.__scriptname__, default.__author__, default.__url__,
            self.platform.addonVersion())
        opensource = """
        [B]Software[/B]
        
        BiDict
        BeautifulSoup
        Decorator
        Eclipse
        ElementTree
        FeedParser
        GNU/Linux
        HTMLTestRunner
        IMDBPy
        Mockito
        MythTV
        MySQL-Connector-Python
        ODict
        PyDev for Eclipse
        Python
        Python-Twitter 
        SimpleJSON
        TheMovieDb Python API
        TVDB Python API
        TVRage Python API
        Twisted
        XBMC
        
        [B]Services[/B]
        
        Google Image Search
        Google Code Project Hosting
        Internet Movie Database
        The Movie Database
        TVDB
        TVRage
        Twitter
        """
        self.setWindowProperty('AboutText', about)
        self.setWindowProperty('OpensourceText', opensource)
        self.setWindowProperty(
            'ReadmeText', '%s\n%s' %
            (open(os.path.join(self.platform.getScriptDir(), 'README.md'),
                  'r').read(),
             open(os.path.join(self.platform.getScriptDir(), 'FAQ'),
                  'r').read()))

    @window_busy
    def testSettings(self):
        try:
            self.settings.verify()
            self.setWindowProperty(
                'MasterBackendHostname',
                '%s / %s' % (self.settings.master.hostname,
                             self.settings.master.ipAddress))
            self.setWindowProperty('MasterBackendPort',
                                   str(self.settings.master.port))
            xbmcgui.Dialog().ok(self.t(m.INFO), u'', self.t(m.SETTINGS_OK))
        except SettingsException, ex:
            self.settings.master = None
            self.setWindowProperty('MasterBackendHostname', '')
            self.setWindowProperty('MasterBackendPort', '')
            xbmcgui.Dialog().ok(self.t(m.ERROR), u'', str(ex))