def debug_exception(logger_func=logger.error): # type: (Callable[[Text], None]) -> Generator[None, None, None] """ Diagnostic helper context manager It controls execution within its context and writes extended diagnostic info to the Kodi log if an unhandled exception happens within the context. The info includes the following items: - System info - Python version - Kodi version - Module path. - Code fragment where the exception has happened. - Global variables. - Local variables. After logging the diagnostic info the exception is re-raised. Example:: with debug_exception(): # Some risky code raise RuntimeError('Fatal error!') :param logger_func: logger function that accepts a single argument that is a log message. """ try: yield except Exception as exc: frame_info = inspect.trace(5)[-1] message = EXCEPTION_TEMPLATE.format( exc_type=type(exc), exc=exc, system_info=uname(), python_version=sys.version.replace('\n', ' '), os_info=xbmc.getInfoLabel('System.OSVersionInfo'), kodi_version=xbmc.getInfoLabel('System.BuildVersion'), file_path=frame_info[1], lineno=frame_info[2], sys_argv=pformat(sys.argv), sys_path=pformat(sys.path), code_context=_format_code_context(frame_info), global_vars=_format_vars(frame_info[0].f_globals), local_vars=_format_vars(frame_info[0].f_locals)) logger_func(message) raise exc
def defaultUserAgent(): """Return a string representing the default user agent.""" _implementation = platform.python_implementation() if _implementation == 'CPython': _implementation_version = platform.python_version() elif _implementation == 'PyPy': _implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major, sys.pypy_version_info.minor, sys.pypy_version_info.micro) if sys.pypy_version_info.releaselevel != 'final': _implementation_version = ''.join( [_implementation_version, sys.pypy_version_info.releaselevel]) elif _implementation == 'Jython': _implementation_version = platform.python_version() # Complete Guess elif _implementation == 'IronPython': _implementation_version = platform.python_version() # Complete Guess else: _implementation_version = 'Unknown' try: p_system = platform.system() p_release = platform.release() except IOError: p_system = 'Unknown' p_release = 'Unknown' return " ".join([ '%s/%s' % ('Plex-for-Kodi', util.ADDON.getAddonInfo('version')), '%s/%s' % ('Kodi', xbmc.getInfoLabel('System.BuildVersion').replace(' ', '-')), '%s/%s' % (_implementation, _implementation_version), '%s/%s' % (p_system, p_release) ])
def get_selected_item_label(): """Get label the selected item in the current Kodi menu Returns: str: Selected item label """ return xbmc.getInfoLabel('ListItem.Label')
def __init__(self, *args, **kwargs): kodigui.BaseDialog.__init__(self, *args, **kwargs) self.handler = kwargs.get('handler') self.initialVideoSettings = {} self.initialAudioStream = None self.initialSubtitleStream = None self.bifURL = None self.baseURL = None self.hasBif = bool(self.bifURL) self.baseOffset = 0 self._duration = 0 self.offset = 0 self.selectedOffset = 0 self.bigSeekOffset = 0 self.bigSeekChanged = False self.title = '' self.title2 = '' self.fromSeek = 0 self.initialized = False self.playlistDialog = None self.timeout = None self.autoSeekTimeout = None self.hasDialog = False self.lastFocusID = None self.previousFocusID = None self.playlistDialogVisible = False self._seeking = False self._applyingSeek = False self._seekingWithoutOSD = False self._delayedSeekThread = None self._delayedSeekTimeout = 0 self._osdHideAnimationTimeout = 0 self._osdHideFast = False self._hideDelay = self.HIDE_DELAY self._autoSeekDelay = self.AUTO_SEEK_DELAY self._atSkipStep = -1 self._lastSkipDirection = None self._forcedLastSkipAmount = None self._enableIntroSkip = plexapp.ACCOUNT.hasPlexPass() self.intro = self.handler.player.video.intro self._introSkipShownStarted = None self.skipSteps = self.SKIP_STEPS self.useAutoSeek = util.advancedSettings.autoSeek self.useDynamicStepsForTimeline = util.advancedSettings.dynamicTimelineSeek if util.kodiSkipSteps and util.advancedSettings.kodiSkipStepping: self.skipSteps = {"negative": [], "positive": []} for step in util.kodiSkipSteps: key = "negative" if step < 0 else "positive" self.skipSteps[key].append(step * 1000) self.skipSteps["negative"].reverse() try: seconds = int( xbmc.getInfoLabel("Skin.String(SkinHelper.AutoCloseVideoOSD)")) if seconds > 0: self._hideDelay = seconds except ValueError: pass
def merge(**kwargs): if xbmc.getInfoLabel('Skin.String({})'.format(ADDON_ID)) == FORCE_RUN_FLAG: raise PluginError(_.MERGE_IN_PROGRESS) xbmc.executebuiltin('Skin.SetString({},{})'.format(ADDON_ID, FORCE_RUN_FLAG)) gui.notification(_.MERGE_STARTED)
def getViewPosition(self): try: return int( xbmc.getInfoLabel('Container({0}).Position'.format( self.controlID))) except: return 0
def playvid(videourl, name, download=None): if download == 1: downloadVideo(videourl, name) else: iconimage = xbmc.getInfoImage("ListItem.Thumb") subject = xbmc.getInfoLabel("ListItem.Plot") listitem = xbmcgui.ListItem(name) listitem.setArt({'thumb': iconimage, 'icon': "DefaultVideo.png", 'poster': iconimage}) listitem.setInfo('video', {'Title': name, 'Genre': 'P**n', 'plot': subject, 'plotoutline': subject}) if videourl.startswith('is://') or '.mpd' in videourl: videourl = videourl[5:] if videourl.startswith('is://') else videourl if PY2: listitem.setProperty('inputstreamaddon', 'inputstream.adaptive') else: listitem.setProperty('inputstream', 'inputstream.adaptive') if '|' in videourl: videourl, strhdr = videourl.split('|') listitem.setProperty('inputstream.adaptive.stream_headers', strhdr) if '.m3u8' in videourl: listitem.setProperty('inputstream.adaptive.manifest_type', 'hls') listitem.setMimeType('application/vnd.apple.mpegstream_url') elif '.mpd' in videourl: listitem.setProperty('inputstream.adaptive.manifest_type', 'mpd') listitem.setMimeType('application/dash+xml') elif '.ism' in videourl: listitem.setProperty('inputstream.adaptive.manifest_type', 'ism') listitem.setMimeType('application/vnd.ms-sstr+xml') listitem.setContentLookup(False) if int(sys.argv[1]) == -1: xbmc.Player().play(videourl, listitem) else: listitem.setPath(str(videourl)) xbmcplugin.setResolvedUrl(addon_handle, True, listitem)
def getTimeFormat(): """ Get global time format. Kodi's time format handling is broken right now, as they return incompatible formats for strftime. %H%H is being returned for manually set zero-padded values, in case of a regional zero-padded hour component, only %H is returned. For now, sail around that by testing the current time for padded hour values. Tests of the values returned by xbmc.getRegion("time"): %I:%M:%S %p = h:mm:ss, non-zero-padded, 12h PM %I:%M:%S = 12h, h:mm:ss, non-zero-padded, regional %I%I:%M:%S = 12h, zero padded, hh:mm:ss %H%H:%M:%S = 24h, zero padded, hh:mm:ss %H:%M:%S = 24h, zero padded, regional, regional (central europe) :return: tuple of strftime-compatible format, boolean padHour """ origFmt = xbmc.getRegion('time') fmt = origFmt.replace("%H%H", "%H").replace("%I%I", "%I") # Checking for %H%H or %I%I only would be the obvious way here to determine whether the hour should be padded, # but the formats returned for regional settings with padding only have %H in them. This seems like a Kodi bug. # Use a fallback. currentTime = xbmc.getInfoLabel('System.Time') padHour = "%H%H" in origFmt or "%I%I" in origFmt or ( currentTime[0] == "0" and currentTime[1] != ":") return fmt, padHour
def system_information(): build = xbmc.getInfoLabel("System.BuildVersion") log.info("System information: %(os)s_%(arch)s %(version)s" % PLATFORM) log.info("Kodi build version: %s" % build) log.info("OS type: %s" % platform.system()) log.info("uname: %s" % repr(platform.uname())) return PLATFORM
def __init__(self): window('jellyfin_should_stop', clear=True) self.settings['addon_version'] = client.get_version() self.settings['profile'] = xbmc.translatePath('special://profile') self.settings['mode'] = settings('useDirectPaths') self.settings['log_level'] = settings('logLevel') or "1" self.settings['auth_check'] = True self.settings['enable_context'] = settings('enableContext.bool') self.settings['enable_context_transcode'] = settings( 'enableContextTranscode.bool') self.settings['kodi_companion'] = settings('kodiCompanion.bool') window('jellyfin_kodiProfile', value=self.settings['profile']) settings('platformDetected', client.get_platform()) if self.settings['enable_context']: window('jellyfin_context.bool', True) if self.settings['enable_context_transcode']: window('jellyfin_context_transcode.bool', True) LOG.info("--->>>[ %s ]", client.get_addon_name()) LOG.info("Version: %s", client.get_version()) LOG.info("KODI Version: %s", xbmc.getInfoLabel('System.BuildVersion')) LOG.info("Platform: %s", settings('platformDetected')) LOG.info("Python Version: %s", sys.version) LOG.info("Using dynamic paths: %s", settings('useDirectPaths') == "0") LOG.info("Log Level: %s", self.settings['log_level']) window('jellyfin.connected.bool', True) settings('groupedSets.bool', objects.utils.get_grouped_set()) xbmc.Monitor.__init__(self)
def getRoleItemDDPosition(self): y = 980 if xbmc.getCondVisibility('Control.IsVisible(500)'): y += 360 if xbmc.getCondVisibility('Control.IsVisible(501)'): y += 360 if xbmc.getCondVisibility('Control.IsVisible(502)'): y += 520 if xbmc.getCondVisibility( '!String.IsEmpty(Window.Property(on.extras))'): y -= 300 if xbmc.getCondVisibility( 'Integer.IsGreater(Window.Property(hub.focus),0) + Control.IsVisible(500)' ): y -= 500 if xbmc.getCondVisibility( 'Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(501)' ): y -= 360 if xbmc.getCondVisibility( 'Integer.IsGreater(Window.Property(hub.focus),1) + Control.IsVisible(502)' ): y -= 500 focus = int(xbmc.getInfoLabel('Container(403).Position')) x = ((focus + 1) * 304) - 100 return x, y
class KodiVersion(object): __metaclass__ = MetaClass version = xbmc.getInfoLabel('System.BuildVersion').decode('utf-8') match = re.search(r'([0-9]+)\.([0-9]+)', version) if match: major, minor = match.groups() match = re.search('-([a-zA-Z]+)([0-9]*)', version) if match: tag, tag_version = match.groups() match = re.search(r'\w+:(\w+-\w+)', version) if match: revision = match.group(1) try: major = int(major) except: major = 0 try: minor = int(minor) except: minor = 0 try: revision = revision.decode('utf-8') except: revision = u'' try: tag = tag.decode('utf-8') except: tag = u'' try: tag_version = int(tag_version) except: tag_version = 0
def kodiVersion(): xbmc_version = xbmc.getInfoLabel("System.BuildVersion") version = float(xbmc_version[:4]) if version >= 11.0 and version <= 11.9: codename = 'Eden' elif version >= 12.0 and version <= 12.9: codename = 'Frodo' elif version >= 13.0 and version <= 13.9: codename = 'Gotham' elif version >= 14.0 and version <= 14.9: codename = 'Helix' elif version >= 15.0 and version <= 15.9: codename = 'Isengard' elif version >= 16.0 and version <= 16.9: codename = 'Jarvis' elif version >= 17.0 and version <= 17.9: codename = 'Krypton' elif version >= 18.0 and version <= 18.9: codename = 'Leia' elif version >= 19.0 and version <= 19.9: codename = 'Matrix' else: codename = "Decline" return codename
def __init__(self, prop, val='1', end=None): from kodi_six import xbmcaddon self._addonID = xbmcaddon.Addon().getAddonInfo('id') self.prop = prop self.val = val self.end = end self.old = xbmc.getInfoLabel('Window(10000).Property({0}}.{1})'.format(self._addonID, prop))
def set_settings(min_bandwidth, max_bandwidth, is_ia=False): current_settings = None if is_ia: new_ia_settings = { 'MINBANDWIDTH': min_bandwidth, 'MAXBANDWIDTH': max_bandwidth, 'IGNOREDISPLAY': 'true', 'HDCPOVERRIDE': 'true', 'STREAMSELECTION': '0', 'MEDIATYPE': '0', 'MAXRESOLUTION': '0', 'MAXRESOLUTIONSECURE': '0', } inputstream.set_bandwidth_bin(1000000000) #1000m/bit current_settings = inputstream.get_settings(new_ia_settings.keys()) if new_ia_settings != current_settings: inputstream.set_settings(new_ia_settings) else: new_gui_settings = { 'network.bandwidth': int(max_bandwidth / 1000), } current_settings = get_gui_settings(new_gui_settings.keys()) if new_gui_settings != current_settings: set_gui_settings(new_gui_settings) if current_settings and xbmc.getInfoLabel( 'Skin.String(quality_reset_thread)') != '1' and not ADDON_DEV: xbmc.executebuiltin('Skin.SetString(quality_reset_thread,1)') thread = Thread(target=reset_thread, args=(is_ia, current_settings)) thread.start()
def adjust_AddonXml(): PLog('adjust_AddonXml:') repl_leia = 'addon="xbmc.python" version="2.25.0"' repl_matrix = 'addon="xbmc.python" version="3.0.0"' KODI_VERSION = xbmc.getInfoLabel('System.BuildVersion') path = xbmc.translatePath('special://home/addons/' + ADDON_ID + '/addon.xml') PLog(KODI_VERSION) PLog(path) page = RLoad(path, abs_path=True) change = False if KODI_VERSION.startswith('19.'): # Kodi Matrix if repl_leia in page: page = page.replace(repl_leia, repl_matrix) page = py2_encode(page) PLog('adjust_AddonXml: ersetze %s durch %s' % (repl_leia, repl_matrix)) RSave(path, page) change = True else: # Kodi <= Leia if repl_matrix in page: page = page.replace(repl_matrix, repl_leia) page = py2_encode(page) PLog('adjust_AddonXml: ersetze %s durch %s' % (repl_matrix, repl_leia)) RSave(path, page) change = True if change == False: PLog(u'adjust_AddonXml: addon.xml unverändert') return
def get_selected_item_stream(): """Get 'stream' dict of the selected item in the current Kodi menu Returns: dict: Selected item 'stream' dict """ stream = {} stream['video_codec'] = xbmc.getInfoLabel('ListItem.VideoCodec') stream['aspect'] = xbmc.getInfoLabel('ListItem.VideoAspect') stream['aspect'] = float(stream['aspect']) if stream['aspect'] != '' else stream['aspect'] # stream['width'] (TODO) # stream['channels'] (TODO) stream['audio_codec'] = xbmc.getInfoLabel('ListItem.VideoCodec') stream['audio_language'] = xbmc.getInfoLabel('ListItem.AudioLanguage') stream['subtitle_language'] = xbmc.getInfoLabel('ListItem.SubtitleLanguage') return stream
def user_playlist_toggle(): if not session.is_logged_in: return url = xbmc.getInfoLabel("ListItem.FilenameandPath") if not Const.addon_id in url: return item_type = 'unknown' if 'play_track/' in url: item_type = 'track' userpl_id = settings.default_trackplaylist_id userpl_name = settings.default_trackplaylist_title item_id = url.split('play_track/')[1] item_id = item_id.split('/')[0] item = session.get_track(item_id) elif 'play_video/' in url: item_type = 'video' userpl_id = settings.default_videoplaylist_id userpl_name = settings.default_videoplaylist_title item_id = url.split('play_video/')[1] item_id = item_id.split('/')[0] item = session.get_video(item_id) elif 'album/' in url: item_type = 'album' userpl_id = settings.default_albumplaylist_id userpl_name = settings.default_albumplaylist_title item_id = url.split('album/')[1] item_id = int('0%s' % item_id.split('/')[0]) item = session.get_album(item_id) if userpl_id: if item._userplaylists and userpl_id in item._userplaylists: user_playlist_remove_album(userpl_id, item.id, dialog=False) return tracks = session.get_album_items(item.id) for track in tracks: if track.available: item.id = track.id # Add First Track of Album break else: return try: if not userpl_id: # Dialog Mode if default Playlist not set user_playlist_add_item(item_type, '%s' % item_id) return if item._userplaylists and userpl_id in item._userplaylists: session.show_busydialog(_T(Msg.i30264), userpl_name) session.user.remove_playlist_entry(playlist=userpl_id, item_id=item.id) else: session.show_busydialog(_T(Msg.i30263), userpl_name) session.user.add_playlist_entries(playlist=userpl_id, item_ids=['%s' % item.id]) except Exception as e: log.logException(e, txt='Couldn' 't toggle playlist for %s' % item_type) traceback.print_exc() session.hide_busydialog() xbmc.executebuiltin('Container.Refresh()')
def run(self): duration, stones = self.getpystone() info = LANGUAGE(30007) % (platform_detect.platform_detect(), platform_detect.processor_detect(), platform_detect.getcpu(), cpu_count()) envo = LANGUAGE(30008) % (xbmc.getInfoLabel('System.BuildVersion'), platform.system()) textviewer('%s[CR]%s[CR]%s' % (envo, info, self.rank(stones)))
def get_kodi_version(): """Get Kodi major version Returns: int: Kodi major version (e.g. 18) """ xbmc_version = xbmc.getInfoLabel("System.BuildVersion") return int(xbmc_version.split('-')[0].split('.')[0])
def __new__(cls, *args, **kwargs): textures = {'textureback': os.path.join(skin.images, 'Slider', 'osd_slider_bg.png'), 'texture': os.path.join(skin.images, 'Slider', 'osd_slider_nibNF.png'), 'texturefocus': os.path.join(skin.images, 'Slider', 'osd_slider_nib.png')} _set_textures(textures, kwargs) if xbmc.getInfoLabel('System.BuildVersion')[:2] >= '17': kwargs['orientation'] = xbmcgui.HORIZONTAL return super(Slider, cls).__new__(cls, -10, -10, 1, 1, *args, **kwargs)
def get_selected_item_params(): """Get 'params' dict of the selected item in the current Kodi menu Returns: dict: Selected item 'params' dict """ path = xbmc.getInfoLabel('ListItem.FilenameAndPath') return get_params_in_query(path)
def _get_fake_uuid(with_hostname=True): """ Generate a uuid based on various system information """ import platform list_values = [xbmc.getInfoLabel('System.Memory(total)')] if with_hostname: list_values.append(platform.node()) return '_'.join(list_values)
def get_selected_item_info(): """Get 'info' dict of the selected item in the current Kodi menu Returns: dict: Selected item 'info' dict """ info = {} info['plot'] = xbmc.getInfoLabel('ListItem.Plot') return info
def setview(): skin = xbmc.getSkinDir().lower() win = xbmcgui.Window(xbmcgui.getCurrentWindowId()) viewtype = str(win.getFocusId()) addon.setSetting('setview', ';'.join([skin, viewtype])) addon.setSetting('customview', 'true') viewName = xbmc.getInfoLabel('Container.Viewmode') notify(i18n('dflt_view_set'), '{0} {1}'.format(i18n('dflt_set'), viewName)) xbmc.executebuiltin('Container.Refresh')
def PlayVideo(url, title, thumb, Plot, sub_path=None, Merk='false'): PLog('PlayVideo:') PLog(url) PLog(title) PLog(Plot) PLog(sub_path) # Header-Check: Flickr gibt bei Fehlern HTML-Seite zurück # Bsp.: <h1>This page is private.</h1> # OK: content-type': 'video/mp4' # Fehlervideo nicht benötigt (Zugriff nur auf öffentl. Inhalte) # 01.12.2019 Header-Check gelöscht, dto. in RequestUrl, #if 'text/html' in str(page): # ffmpeg-erzeugtes Fehlerbild-mp4-Video (10 sec) # PLog('Error: Textpage ' + url) # url = os.path.join("%s", 'PrivatePage720x640.mp4') % (RESOURCES_PATH) # return PlayVideo(url, title, thumb, Plot) li = xbmcgui.ListItem(path=url) li.setArt({'thumb': thumb, 'icon': thumb}) Plot = Plot.replace('||', '\n') # || Code für LF (\n scheitert in router) infoLabels = {} infoLabels['title'] = title infoLabels['sorttitle'] = title #infoLabels['genre'] = genre #infoLabels['plot'] = Plot #infoLabels['plotoutline'] = Plot infoLabels['tvshowtitle'] = Plot infoLabels['tagline'] = Plot infoLabels['mediatype'] = 'video' li.setInfo(type="Video", infoLabels=infoLabels) # Abfrage: ist gewählter Eintrag als Video deklariert? - Falls ja, # IsPlayable-Test # erfolgt der Aufruf indirekt (setResolvedUrl). Falls nein, # wird der Player direkt aufgerufen. Direkter Aufruf ohne IsPlayable-Eigenschaft # verhindert Resume-Funktion. # Mit xbmc.Player() ist die Unterscheidung Kodi V18/V17 nicht mehr erforderlich, # xbmc.Player().updateInfoTag bei Kodi V18 entfällt. # Die Player-Varianten PlayMedia + XBMC.PlayMedia scheitern bei Kommas in Url. # IsPlayable = xbmc.getInfoLabel( 'ListItem.Property(IsPlayable)') # 'true' / 'false' PLog("IsPlayable: %s, Merk: %s" % (IsPlayable, Merk)) PLog("kodi_version: " + KODI_VERSION) # Debug # kodi_version = re.search('(\d+)', KODI_VERSION).group(0) # Major-Version reicht hier - entfällt #if Merk == 'true': # entfällt bisher - erfordert # xbmc.Player().play(url, li, windowed=False) # eigene Resumeverwaltung # return if IsPlayable == 'true': # true xbmcplugin.setResolvedUrl(HANDLE, True, li) # indirekt else: # false, None od. Blank xbmc.Player().play(url, li, windowed=False) # direkter Start return
def main(): if xbmc.getInfoLabel('Window(10000).Property(script.plex.service.started)'): # Prevent add-on updates from starting a new version of the addon return xbmcgui.Window(10000).setProperty('script.plex.service.started', '1') if xbmcaddon.Addon().getSetting('kiosk.mode') == 'true': xbmc.log('script.plex: Starting from service (Kiosk Mode)', xbmc.LOGINFO) xbmc.executebuiltin('RunScript(script.plex)')
def getAllListItems(): focusId = xbmcgui.Window().getFocusId() numItems = int('0%s' % xbmc.getInfoLabel('Container(%s).NumItems' % focusId)) items = [] for pos in range(1, numItems): item = getGuiListItem(focusId, pos) if item.get('Artist') and item.get('Title'): items.append(item) return items
def getVersion(self): log('getVersion') count = 0 try: while not self.myMonitor.abortRequested() and count < 15: count += 1 if self.myMonitor.waitForAbort(1): return build = (xbmc.getInfoLabel('System.OSVersionInfo') or 'busy') if build.lower() != 'busy': return REAL_SETTINGS.setSetting("Version",str(build)) except Exception as e: log("getVersion Failed! " + str(e), xbmc.LOGERROR)
def addUser(user): user['save'] = 'false' # var.addon.getSetting('save_login') users = loadUsers() if var.multiuser else [] num = [n for n, i in enumerate(users) if user['name'] == i['name']] if num: users[num[0]] = user else: users.append(user) writeConfig('accounts.lst', json.dumps(users)) if xbmc.getInfoLabel('Container.FolderPath') == sys.argv[0]: xbmc.executebuiltin('Container.Refresh')
def kodi_version(): # Kodistubs returns empty string, causing Python 3 tests to choke on int() # TODO: Make Kodistubs version configurable for testing purposes if sys.version_info.major == 2: default_versionstring = "18" else: default_versionstring = "19.1 (19.1.0) Git:20210509-85e05228b4" version_string = xbmc.getInfoLabel( 'System.BuildVersion') or default_versionstring return int(version_string.split(' ', 1)[0].split('.', 1)[0])
def __new__(cls, *args, **kwargs): if xbmc.getInfoLabel('System.BuildVersion')[:2] >= '13': textures = {'focusTexture': os.path.join(skin.images, 'RadioButton', 'MenuItemFO.png'), 'noFocusTexture': os.path.join(skin.images, 'RadioButton', 'MenuItemNF.png'), 'focusOnTexture': os.path.join(skin.images, 'RadioButton', 'radiobutton-focus.png'), 'noFocusOnTexture': os.path.join(skin.images, 'RadioButton', 'radiobutton-focus.png'), 'focusOffTexture': os.path.join(skin.images, 'RadioButton', 'radiobutton-nofocus.png'), 'noFocusOffTexture': os.path.join(skin.images, 'RadioButton', 'radiobutton-nofocus.png')} else: # This is for compatibility with Frodo and earlier versions. textures = {'focusTexture': os.path.join(skin.images, 'RadioButton', 'MenuItemFO.png'), 'noFocusTexture': os.path.join(skin.images, 'RadioButton', 'MenuItemNF.png'), 'TextureRadioFocus': os.path.join(skin.images, 'RadioButton', 'radiobutton-focus.png'), 'TextureRadioNoFocus': os.path.join(skin.images, 'RadioButton', 'radiobutton-nofocus.png')} _set_textures(textures, kwargs) return super(RadioButton, cls).__new__(cls, -10, -10, 1, 1, *args, **kwargs)