class tvmManual: def __init__( self ): """Runs some manual functions for following and tagging shows on TV Maze.""" self._init_vars() _startup( self.LW, self.SETTINGS, self.DIALOG ) options = [ self.SETTINGS['ADDONLANGUAGE']( 32202 ), self.SETTINGS['ADDONLANGUAGE']( 32203 ), self.SETTINGS['ADDONLANGUAGE']( 32205 ), self.SETTINGS['ADDONLANGUAGE']( 32206 ), self.SETTINGS['ADDONLANGUAGE']( 32302 ) ] ret = self.DIALOG.select( self.SETTINGS['ADDONLANGUAGE']( 32201 ), options ) self.LW.log( ['got back %s from the dialog box' % str( ret )] ) if ret == -1: return if ret == 0: self._option_follow_shows() elif ret == 1: self._option_unfollow_shows() elif ret == 2: self._option_tag_shows() elif ret == 3: self._option_untag_shows() elif ret == 4: self.SETTINGS['ADDON'].openSettings() self.LW.log( ['script version %s stopped' % self.SETTINGS['ADDONVERSION']], xbmc.LOGINFO ) def _init_vars( self ): self.SETTINGS = loadSettings() self.LW = Logger( preamble='[TVMI Manual]', logdebug=self.SETTINGS['debug'] ) self.LW.log( ['loaded settings', _logsafe_settings( self.SETTINGS )] ) self.TVMAZE = tvmaze.API( user=self.SETTINGS['tvmaze_user'], apikey=self.SETTINGS['tvmaze_apikey'] ) self.TVMCACHEFILE = os.path.join( self.SETTINGS['ADDONDATAPATH'], 'tvm_followed_cache.json' ) self.DIALOG = xbmcgui.Dialog() self.KODIMONITOR = xbmc.Monitor() def _option_follow_shows( self ): showlist = self._build_show_list() ret = self._select_shows_dialog( self.SETTINGS['ADDONLANGUAGE']( 32202 ), showlist ) if not ret: return else: with busyDialog(): self._add_shows( ret, showlist ) def _option_unfollow_shows( self ): with busyDialog(): followedlist, followedmap = self._build_tvmaze_list() ret = self._select_shows_dialog( self.SETTINGS['ADDONLANGUAGE']( 32203 ), followedlist ) if not ret: return else: with busyDialog(): self._unfollow_shows( ret, followedlist, followedmap ) def _option_tag_shows( self ): with busyDialog(): taglist, tagmap = _build_tag_list( self.TVMAZE, self.LW ) ret = self.DIALOG.select( self.SETTINGS['ADDONLANGUAGE']( 32204 ), taglist ) if ret == -1: return tagid = tagmap[taglist[ret]] showlist = self._build_show_list() ret = self._select_shows_dialog( self.SETTINGS['ADDONLANGUAGE']( 32205 ), showlist ) if not ret: return else: with busyDialog(): self._add_shows( ret, showlist, tagid=tagid ) def _option_untag_shows( self ): with busyDialog(): taglist, tagmap = _build_tag_list( self.TVMAZE, self.LW ) ret = self.DIALOG.select( self.SETTINGS['ADDONLANGUAGE']( 32204 ), taglist ) if ret == -1: return tagid = tagmap[taglist[ret]] with busyDialog(): taggedlist, taggedmap = self._build_tvmaze_list( tagid=tagid ) ret = self._select_shows_dialog( self.SETTINGS['ADDONLANGUAGE']( 32206 ), taggedlist ) if not ret: return else: with busyDialog(): self._unfollow_shows( ret, taggedlist, taggedmap, tagid=tagid ) return def _select_shows_dialog( self, header, options ): firstitem = self.SETTINGS['ADDONLANGUAGE']( 32303 ) response = False while not response: if firstitem == self.SETTINGS['ADDONLANGUAGE']( 32303 ): preselect = [] else: preselect = [] for i in range( 1,len( options ) ): preselect.append( i ) options[0] = firstitem ret = self.DIALOG.multiselect( header, options, preselect=preselect ) self.LW.log( ['got back a response of:', ret] ) if not ret: response = True elif ret[0] == 0: if firstitem == self.SETTINGS['ADDONLANGUAGE']( 32303 ): firstitem = self.SETTINGS['ADDONLANGUAGE']( 32304 ) else: firstitem = self.SETTINGS['ADDONLANGUAGE']( 32303 ) else: response = True return ret def _build_show_list( self ): self.LW.log( ['building show list'] ) showlist = [''] method = 'VideoLibrary.GetTVShows' params = '{"properties":["title"]}' items = sorted( _get_json( method, params, self.LW ).get( 'tvshows', [] ), key=lambda x:x['label'] ) for item in items: showlist.append( item['label'] ) return showlist def _build_tvmaze_list( self, tagid = '' ): if tagid: self.LW.log( ['building tagged list'] ) else: self.LW.log( ['building followed list'] ) tvmazelist = [''] tvmazemap = {} if tagid: success, loglines, results = self.TVMAZE.getTaggedShows( tagid, params={'embed':'show'} ) else: results = _update_followed_cache( self.TVMCACHEFILE, self.TVMAZE, self.LW ) if not results: return [], {} items = sorted( results, key=lambda x:x['_embedded']['show']['name'] ) for item in items: tvmazelist.append( item['_embedded']['show']['name'] ) tvmazemap[item['_embedded']['show']['name']] = item['show_id'] return tvmazelist, tvmazemap def _add_shows( self, showchoices, showlist, tagid = '' ): if tagid: self.LW.log( ['tagging shows'] ) else: self.LW.log( ['following shows'] ) for showchoice in showchoices: if showchoice == 0: continue showid = _manage_followed( re.sub( r' \([0-9]{4}\)', '', showlist[showchoice] ), 'follow', self.TVMAZE, self.LW ) if showid and tagid: self.KODIMONITOR.waitForAbort( 0.12 ) success, loglines, result = self.TVMAZE.tagShow( showid, tagid ) self.LW.log( loglines ) self.KODIMONITOR.waitForAbort( 0.12 ) def _unfollow_shows( self, showchoices, showlist, showmap, tagid='' ): if tagid: self.LW.log( 'untagging shows' ) else: self.LW.log( 'unfollowing shows' ) for showchoice in showchoices: if showchoice == 0: continue if tagid: success, loglines, result = self.TVMAZE.unTagShow( showmap.get( showlist[showchoice], 0 ), tagid ) else: success, loglines, result = self.TVMAZE.unFollowShow( showmap.get( showlist[showchoice], 0 ) ) self.LW.log( loglines ) self.KODIMONITOR.waitForAbort( 0.12 )
class tvmMonitor( xbmc.Monitor ): def __init__( self ): """Starts the background process for automatic marking of played TV shows.""" xbmc.Monitor.__init__( self ) _upgrade() self.WINDOW = xbmcgui.Window(10000) self._init_vars() self.LW.log( ['background monitor version %s started' % self.SETTINGS['ADDONVERSION']], xbmc.LOGINFO ) self.LW.log( ['debug logging set to %s' % self.SETTINGS['debug']], xbmc.LOGINFO ) while not self.abortRequested(): if self.waitForAbort( 10 ): break if self.PLAYINGEPISODE: try: self.PLAYINGEPISODETIME = self.KODIPLAYER.getTime() except RuntimeError: self.PLAYINGEPISODETIME = self.PLAYINGEPISODETIME self._set_property('script.tvmi.hidemenu', '' ) self.LW.log( ['background monitor version %s stopped' % self.SETTINGS['ADDONVERSION']], xbmc.LOGINFO ) def onNotification( self, sender, method, data ): if 'Player.OnPlay' in method: self.waitForAbort( 1 ) if self.KODIPLAYER.isPlayingVideo(): data = json.loads( data ) is_an_episode = data.get( 'item', {} ).get( 'type', '' ) == 'episode' if is_an_episode: self.LW.log( ['MONITOR METHOD: %s DATA: %s' % (str( method ), str( data ))] ) self.PLAYINGEPISODE = True self.PLAYINGEPISODETOTALTIME = self.KODIPLAYER.getTotalTime() self._get_show_ep_info( 'playing', data ) elif 'Player.OnStop' in method and self.PLAYINGEPISODE: if self.PLAYINGEPISODE: self.PLAYINGEPISODE = False data = json.loads( data ) self.LW.log( ['MONITOR METHOD: %s DATA: %s' % (str( method ), str( data ))] ) played_percentage = (self.PLAYINGEPISODETIME / self.PLAYINGEPISODETOTALTIME) * 100 self.LW.log( ['got played percentage of %s' % str( played_percentage )], xbmc.LOGINFO ) if played_percentage >= float( self.SETTINGS['percent_watched'] ): self.LW.log( ['item was played for the minimum percentage in settings, trying to mark'], xbmc.LOGINFO ) self._mark_episodes( 'playing' ) else: self.LW.log( ['item was not played long enough to be marked, skipping'], xbmc.LOGINFO ) self._reset_playing() elif 'VideoLibrary.OnScanStarted' in method: data = json.loads( data ) self.LW.log( ['MONITOR METHOD: %s DATA: %s' % (str( method ), str( data ))] ) self.SCANSTARTED = True elif 'VideoLibrary.OnUpdate' in method and self.SCANSTARTED: data = json.loads( data ) self.LW.log( ['MONITOR METHOD: %s DATA: %s' % (str( method ), str( data ))] ) self.SCANNEDDATA.append( data ) elif 'VideoLibrary.OnScanFinished' in method and self.SCANSTARTED: data = json.loads( data ) self.LW.log( ['MONITOR METHOD: %s DATA: %s' % (str( method ), str( data ))] ) for item in self.SCANNEDDATA: self._get_show_ep_info( 'scanned', item ) if self.abortRequested(): break if self.SETTINGS['mark_on_remove']: self._update_episode_cache( items=self.SCANNEDITEMS ) self._mark_episodes( 'scanned' ) self._reset_scanned() elif 'VideoLibrary.OnRemove' in method and self.SETTINGS['mark_on_remove']: data = json.loads( data ) self.LW.log( ['MONITOR METHOD: %s DATA: %s' % (str( method ), str( data ))] ) self._get_show_ep_info( 'removed', data ) self._mark_episodes( 'removed' ) self.REMOVEDITEMS = [] def onSettingsChanged( self ): self._init_vars() def _init_vars( self ): self.SETTINGS = loadSettings() self.LW = Logger( preamble='[TVMI Monitor]', logdebug=self.SETTINGS['debug'] ) self.LW.log( ['the settings are:', _logsafe_settings( self.SETTINGS )] ) self._set_property('script.tvmi.hidemenu', str( self.SETTINGS['hidemenu']).lower() ) self.TVMCACHEFILE = os.path.join( self.SETTINGS['ADDONDATAPATH'], 'tvm_followed_cache.json' ) self.EPISODECACHE = os.path.join( self.SETTINGS['ADDONDATAPATH'], 'episode_cache.json' ) self.KODIPLAYER = xbmc.Player() self.TVMAZE = tvmaze.API( user=self.SETTINGS['tvmaze_user'], apikey=self.SETTINGS['tvmaze_apikey'] ) self.TVMCACHE = _update_followed_cache( self.TVMCACHEFILE, self.TVMAZE, self.LW ) self.REMOVEDITEMS = [] self._reset_playing() self._reset_scanned() self.LW.log( ['initialized variables'] ) def _reset_playing( self ): self.PLAYINGEPISODE = False self.PLAYINGITEMS = [] self.PLAYINGEPISODETIME = 0 self.PLAYINGEPISODETOTALTIME = 0 def _reset_scanned( self ): self.SCANSTARTED = False self.SCANNEDITEMS = [] self.SCANNEDDATA = [] def _get_show_ep_info( self, thetype, data ): showid = 0 epid = 0 showname = '' if data.get( 'item', {} ).get( 'type', '' ) == 'episode': epid = data['item'].get( 'id', 0 ) if epid: method = 'VideoLibrary.GetEpisodeDetails' params = '{"episodeid":%s, "properties":["season", "episode", "tvshowid"]}' % str( epid ) r_dict = _get_json( method, params, self.LW ) season = r_dict.get( 'episodedetails', {} ).get( 'season', 0 ) episode = r_dict.get( 'episodedetails', {} ).get( 'episode', 0 ) showid = r_dict.get( 'episodedetails', {} ).get( 'tvshowid', 0 ) self.LW.log( ['moving on with season of %s, episode of %s, and showid of %s' % (str(season), str(episode), str(showid))] ) if showid: method = 'VideoLibrary.GetTVShowDetails' params = '{"tvshowid":%s}' % str( showid ) r_dict = _get_json( method, params, self.LW ) showname = r_dict.get( 'tvshowdetails', {} ).get( 'label', '' ) self.LW.log( ['moving on with TV show name of %s' % showname] ) elif thetype == 'removed': epid = data.get( 'id', 0 ) loglines, episode_cache = readFile( self.EPISODECACHE ) self.LW.log( loglines ) if episode_cache: self.LW.log( ['checking in cache for epid of %s' % str( epid )] ) ep_info = json.loads( episode_cache ).get( str( epid ), {} ) else: ep_info = {} showname = ep_info.get( 'name', '' ) season = ep_info.get( 'season', 0 ) episode = ep_info.get( 'episode', 0 ) if showname and season and episode: item = {'epid': epid, 'name':showname, 'season':season, 'episode':episode} else: item = {} if item: self.LW.log( ['storing item data of:', item] ) if thetype == 'scanned': self.SCANNEDITEMS.append( item ) elif thetype == 'playing': self.PLAYINGITEMS.append( item ) elif thetype == 'removed': self.REMOVEDITEMS.append( item ) self._update_episode_cache( epid=epid ) def _set_property( self, property_name, value='' ): try: self.WINDOW.setProperty( property_name, value ) self.LW.log( ['%s set to %s' % (property_name, value)] ) except Exception as e: self.LW.log( ['Exception: Could not set property %s to value %s' % (property_name, value), e]) def _update_episode_cache( self, epid=None, item=None, items=None ): loglines, episode_cache = readFile( self.EPISODECACHE ) self.LW.log( loglines ) cache_changed = True if episode_cache: epcache_json = json.loads( episode_cache ) else: epcache_json = {} if epid: try: del epcache_json[str( epid )] except KeyError: cache_changed = False elif item: epcache_json[str( item['epid'] )] = item elif items: for item in items: epcache_json[str( item['epid'] )] = item if cache_changed: success, loglines = writeFile( json.dumps( epcache_json ), self.EPISODECACHE, 'w' ) self.LW.log( loglines ) def _mark_episodes( self, thetype ): items = [] if thetype == 'playing': mark_type = 0 items = self.PLAYINGITEMS elif thetype == 'scanned': mark_type = 1 items = self.SCANNEDITEMS elif thetype == 'removed': mark_type = 0 items = self.REMOVEDITEMS for item in items: if self.SETTINGS['mark_on_remove'] and not thetype == 'scanned': self._update_episode_cache( epid=item.get( 'epid', 0 ) ) self.TVMCACHE = _mark_one( item, mark_type, self.SETTINGS['add_followed'], self.TVMCACHE, self.TVMCACHEFILE, self.TVMAZE, self.LW ) if self.abortRequested(): break
from itertools import zip_longest as _zip_longest from resources.lib.xlogger import Logger from resources.lib.kodisettings import getSettingBool, getSettingInt, getSettingString addon = xbmcaddon.Addon() addonname = addon.getAddonInfo('id') addonversion = addon.getAddonInfo('version') addonpath = addon.getAddonInfo('path') addonicon = xbmc.translatePath('%s/icon.png' % addonpath) language = addon.getLocalizedString preamble = '[SpeedFan Info]' logdebug = getSettingBool(addon, 'logging', default=False) lw = Logger(preamble=preamble, logdebug=logdebug) lw.log(['script version %s started' % addonversion], xbmc.LOGINFO) lw.log(['debug logging set to %s' % logdebug], xbmc.LOGINFO) class SpeedFanWindow(xbmcgui.WindowXMLDialog): def __init__(self, *args, **kwargs): self.KEEPRUNNING = True self.ACTION_PREVIOUS_MENU = 10 self.ACTION_BACK = 92 def onAction(self, action): if action == self.ACTION_PREVIOUS_MENU or action == self.ACTION_BACK: lw.log([ 'user initiated previous menu or back, telling addon to quit' ]) self.KEEPRUNNING = False
class tvmContext: def __init__( self, action ): """Allows access to TV Maze from context menu.""" self._init_vars() _startup( self.LW, self.SETTINGS, self.DIALOG ) self.LW.log( ['list item label: %s' % sys.listitem.getLabel()] ) self.LW.log( ['list item path: %s' % sys.listitem.getPath()] ) if 'follow' in action: self._manage_show_follow( action ) elif 'tag' in action: self._manage_show_tag( action ) elif 'mark' in action: self._manage_show_mark( action ) def _init_vars( self ): self.SETTINGS = loadSettings() self.LW = Logger( preamble='[TVMI Context]', logdebug=self.SETTINGS['debug'] ) self.LW.log( ['loaded settings', _logsafe_settings( self.SETTINGS )] ) self.TVMAZE = tvmaze.API( user=self.SETTINGS['tvmaze_user'], apikey=self.SETTINGS['tvmaze_apikey'] ) self.DIALOG = xbmcgui.Dialog() self.KODIMONITOR = xbmc.Monitor() self.TVMCACHEFILE = os.path.join( self.SETTINGS['ADDONDATAPATH'], 'tvm_followed_cache.json' ) def _get_details_from_path( self, thepath ): showid = re.findall( 'tvshowid=(.*)', thepath )[0] self.LW.log( ['showid is: %s' % showid] ) method = 'VideoLibrary.GetTVShowDetails' params = '{"tvshowid":%s}' % str( showid ) results = _get_json( method, params, self.LW ) self.LW.log( ['the show details are:', results] ) showname = results.get( 'tvshowdetails', {} ).get( 'label', '' ) method = 'VideoLibrary.GetEpisodeDetails' epid = re.findall( '\/titles\/[0-9].*[0-9]\/.*\/([0-9].*[0-9])\?season', thepath )[0] self.LW.log( ['epid is: %s' % epid] ) params = '{"episodeid":%s, "properties":["season", "episode"]}' % epid results = _get_json( method, params, self.LW ) self.LW.log( ['the episode details are:', results] ) season = results.get( 'episodedetails', {} ).get( 'season', 0 ) episode = results.get( 'episodedetails', {} ).get( 'episode', 0 ) self.LW.log( ['returning showname of %s, season of %s, and episode of %s' % (showname, str( season ), str( episode ))] ) return {'name':showname, 'season':season, 'episode':episode} def _manage_show_follow( self, action ): with busyDialog(): _manage_followed( sys.listitem.getLabel(), action, self.TVMAZE, self.LW ) def _manage_show_tag( self, action ): with busyDialog(): taglist, tagmap = _build_tag_list( self.TVMAZE, self.LW ) ret = self.DIALOG.select( self.SETTINGS['ADDONLANGUAGE']( 32204 ), taglist ) if ret == -1: return tagid = tagmap[taglist[ret]] with busyDialog(): showid = _manage_followed( re.sub( r' \([0-9]{4}\)', '', sys.listitem.getLabel() ), 'follow', self.TVMAZE, self.LW ) if action == 'tag': success, loglines, result = self.TVMAZE.tagShow( showid, tagid ) else: success, loglines, result = self.TVMAZE.unTagShow( showid, tagid ) self.LW.log( loglines ) def _manage_show_mark( self, action ): show_info = self._get_details_from_path( sys.listitem.getPath() ) if action == 'mark_watched': mark_type = 0 elif action == 'mark_acquired': mark_type = 1 elif action == 'mark_skipped': mark_type = 2 else: mark_type = -1 with busyDialog(): _mark_one( show_info, mark_type, self.SETTINGS['add_followed'], [], self.TVMCACHEFILE, self.TVMAZE, self.LW )
def __init__(self): """Runs the audio profiler switcher manually.""" settings = loadSettings() lw = Logger(preamble='[Audio Profiles]', logdebug=settings['debug']) lw.log(['script version %s started' % settings['ADDONVERSION']], xbmc.LOGINFO) lw.log(['debug logging set to %s' % settings['debug']], xbmc.LOGINFO) lw.log(['SYS.ARGV: %s' % str(sys.argv)]) lw.log(['loaded settings', settings]) profiles = Profiles(settings, lw) try: mode = sys.argv[1] except IndexError: mode = False lw.log(['MODE: %s' % str(mode)]) profiles.changeProfile(mode) lw.log(['script version %s stopped' % settings['ADDONVERSION']], xbmc.LOGINFO)
class apMonitor(xbmc.Monitor): def __init__(self): """Starts the background process for automatic audio profile switching.""" xbmc.Monitor.__init__(self) _upgrade() self._init_vars() self.LW.log([ 'background monitor version %s started' % self.SETTINGS['ADDONVERSION'] ], xbmc.LOGINFO) self.LW.log(['debug logging set to %s' % self.SETTINGS['debug']], xbmc.LOGINFO) self._change_profile(self.SETTINGS['auto_default'], forceload=self.SETTINGS['force_auto_default']) while not self.abortRequested(): if self.waitForAbort(10): break self.LW.log([ 'background monitor version %s stopped' % self.SETTINGS['ADDONVERSION'] ], xbmc.LOGINFO) def onNotification(self, sender, method, data): data = json.loads(data) if 'System.OnWake' in method: self.LW.log( ['MONITOR METHOD: %s DATA: %s' % (str(method), str(data))]) self._change_profile(self.SETTINGS['auto_default']) if 'Player.OnStop' in method: self.LW.log( ['MONITOR METHOD: %s DATA: %s' % (str(method), str(data))]) self.waitForAbort(1) if not self.KODIPLAYER.isPlaying(): self._change_profile(self.SETTINGS['auto_gui']) if 'Player.OnPlay' in method: self.LW.log( ['MONITOR METHOD: %s DATA: %s' % (str(method), str(data))]) self._auto_switch(data) def onSettingsChanged(self): self._init_vars() def _init_vars(self): self.SETTINGS = loadSettings() self.PROFILESLIST = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'] # this only includes mappings we are 100% sure are accurate every time self.MAPTYPE = { 'video': 'auto_videos', 'episode': 'auto_tvshows', 'musicvideo': 'auto_musicvideo', 'song': 'auto_music' } self.LW = Logger(preamble='[Audio Profiles Service]', logdebug=self.SETTINGS['debug']) self.PROFILES = Profiles(self.SETTINGS, self.LW, auto=True) self.KODIPLAYER = xbmc.Player() self.LW.log(['the settings are:', self.SETTINGS]) self.LW.log(['initialized variables']) def _auto_switch(self, data): if self.SETTINGS['player_show']: self.LW.log(['showing select menu']) if self.PROFILES.changeProfile('popup') is not None: self.LW.log(['option selected, returning']) return self.LW.log([ 'select menu timed out or was closed with no selection - continuing to auto select' ]) content_autoswitch = self._auto_switch_content(data) self.LW.log(['got a content autoswitch of %s' % content_autoswitch]) if content_autoswitch not in ['auto_music', 'auto_pvr_radio']: codec_setting, channels_setting = self._auto_switch_stream() if codec_setting != '0': the_setting = codec_setting self.LW.log(['using the codec setting of %s' % the_setting]) elif channels_setting != '0': the_setting = channels_setting self.LW.log(['using the channels setting of %s' % the_setting]) elif self.SETTINGS[ 'aggressive_music_match'] and codec_setting == '0' and channels_setting == '0' and content_autoswitch == 'auto_unknown': the_setting = self.SETTINGS['auto_music'] self.LW.log([ 'stream does not seem to be video, using the auto_music setting of %s' % the_setting ]) else: the_setting = self.SETTINGS[content_autoswitch] self.LW.log(['using the content setting of %s' % the_setting]) else: the_setting = self.SETTINGS[content_autoswitch] self.LW.log(['using the content setting of %s' % the_setting]) self._change_profile(the_setting) def _auto_switch_stream(self): if self.SETTINGS['codec_delay'] > 0: self.LW.log([ 'waiting %s seconds before trying to get stream details' % str(self.SETTINGS['codec_delay']) ]) self.waitForAbort(self.SETTINGS['codec_delay']) response = xbmc.executeJSONRPC( '{"jsonrpc":"2.0", "method":"Player.GetProperties", "params":{"playerid":1, "properties":["currentaudiostream"]}, "id":1}' ) r_dict = json.loads(response) self.LW.log(['got back audio stream data of:', r_dict]) try: codec = r_dict['result']['currentaudiostream']['codec'] except (IndexError, KeyError, ValueError, TypeError): codec = None try: channels = r_dict['result']['currentaudiostream']['channels'] except (IndexError, KeyError, ValueError, TypeError): channels = None self.LW.log([ 'got %s for the codec and %s for the channels' % (str(codec), str(channels)) ]) if codec: codec_set = 'auto_othercodec' for check_codec in ['ac3', 'eac3', 'dts', 'dtshd', 'truehd']: if codec in check_codec: codec_set = 'auto_%s' % check_codec break else: codec_set = 'none' try: codec_setting = self.SETTINGS[codec_set] except KeyError: codec_setting = '0' if channels: if channels > 2: channels_set = 'auto_multichannel' else: channels_set = 'auto_stereo' else: channels_set = 'none' try: channels_setting = self.SETTINGS[channels_set] except KeyError: channels_setting = '0' self.LW.log([ 'got codec set of %s and channels set of %s' % (codec_set, channels_set) ]) self.LW.log([ 'sending back codec setting of %s and channel setting of %s' % (codec_setting, channels_setting) ]) return codec_setting, channels_setting def _auto_switch_content(self, data): try: thetype = data['item']['type'] except KeyError: self.LW.log([ 'data did not include valid item and/or type for playing media - aborting' ]) return self.LW.log(['the type is: %s' % thetype]) theset = self.MAPTYPE.get(thetype) if not theset: if thetype == 'movie': # if video is a PVR recording assign to auto_pvr_tv if self._check_playing_file('pvr://'): theset = 'auto_pvr_tv' # if video is not from library assign to auto_videos elif 'id' not in data['item']: theset = 'auto_videos' # it must actually be a movie else: theset = 'auto_movies' # distinguish pvr TV and pvr RADIO elif 'channel' in thetype and 'channeltype' in data['item']: if 'tv' in data['item']['channeltype']: theset = 'auto_pvr_tv' elif 'radio' in data['item']['channeltype']: theset = 'auto_pvr_radio' else: theset = 'auto_unknown' # detect cdda that kodi return as unknown elif thetype == 'unknown': if self._check_playing_file('cdda://'): theset = 'auto_music' else: theset = 'auto_unknown' else: theset = 'auto_unknown' self.LW.log(['got %s from the content auto switch' % theset]) return theset def _change_profile(self, profile, forceload=False): if profile in self.PROFILESLIST: last_profile = self._get_last_profile() self.LW.log([ 'Last loaded profile: %s To switch profile: %s' % (last_profile, profile) ]) if last_profile != profile or forceload: self.PROFILES.changeProfile(profile) else: self.LW.log(['Same profile - profiles not switched']) elif profile == str(len(self.PROFILESLIST) + 1): self.LW.log([ 'this auto switch setting is set to show the select menu - showing menu' ]) self.PROFILES.changeProfile('popup') def _check_playing_file(self, thestr): try: thefile = self.KODIPLAYER.getPlayingFile() except RuntimeError: self.LW.log(['error trying to get playing file from Kodi']) return False self.LW.log(['the playing file is: %s' % thefile]) return thefile.startswith(thestr) def _get_last_profile(self): loglines, profile = readFile( os.path.join(self.SETTINGS['ADDONDATAPATH'], 'profile')) self.LW.log(loglines) if profile in self.PROFILESLIST: return profile else: return ''
class Main: def __init__(self, thepath): """Start the IR blaster.""" self.ROOTFILE = thepath self.ROOTPATH = os.path.dirname(thepath) self.LW = Logger(logfile=os.path.join(self.ROOTPATH, 'data', 'logs', 'client.log'), numbackups=config.Get('logbackups'), logdebug=config.Get('debug')) self.LW.log(['script started'], 'info') self._setPID() self._parse_argv() self._wait_for_prev_cmd() self._init_vars() if not self.BLASTER: self.LW.log( ['invalid blaster type configured in settings, quitting'], 'info') return if not self.DVR: self.LW.log(['invalid DVR type configured in settings, quitting'], 'info') return if self.ARGS.analogcheck: success, loglines = self.DVR.CheckAnalog(self.CHANNEL) self.LW.log(loglines) if success: self.LW.log([ 'analog check verified, everything looks OK', 'script finished' ], 'info') return self.LW.log([ 'analog check failed, sending commands to turn the TV box back on' ], 'info') self._send_commands(self.ANALOG_FAIL_CMDS) self._send_commands( self._check_cmd_ignore(self.PRE_CMD, self.IGNORE_PRECMD_FOR, self.PRE_LASTUSED_FILE)) if self.CHANNEL: self._send_commands(self._splitchannel()) elif self.ARGS.cmds: self._send_commands(self.ARGS.cmds) self._send_commands( self._check_cmd_ignore(self.POST_CMD, self.IGNORE_POSTCMD_FOR, self.POST_LASTUSED_FILE)) if (not self.ARGS.analogcheck) and config.Get('analog_check'): if os.name == 'nt': py_folder, py_file = os.path.split(sys.executable) cmd = [ os.path.join(py_folder, 'pythonw.exe'), self.ROOTFILE, '--analogcheck' ] + sys.argv[1:] self.LW.log(cmd) else: cmd = '%s %s --analogcheck %s %s' % ( sys.executable, self.ROOTFILE, sys.argv[1], sys.argv[2]) self.LW.log([cmd]) subprocess.Popen(cmd, shell=True) self.LW.log(['script finished'], 'info') def _check_cmd_ignore(self, cmd, ignore_for, lastused_file): if not cmd: if lastused_file == self.PRE_LASTUSED_FILE: cmd_type = 'pre' else: cmd_type = 'post' self.LW.log(['no %s command to check' % cmd_type]) return '' if ignore_for == 0: self.LW.log(['ignoring the cache time and running command']) return cmd if os.path.isfile(lastused_file): exists = True loglines, lastused = readFile(lastused_file) self.LW.log(loglines) else: exists = False if (not exists) or (time.time() - float(lastused) > ignore_for * 60): self.LW.log(['setting lastused and running command']) success, loglines = writeFile(str(time.time()), lastused_file, wtype='w') self.LW.log(loglines) return cmd self.LW.log(['ignoring command for now']) return '' def _init_vars(self): self.PRE_LASTUSED_FILE = os.path.join(self.ROOTPATH, 'data', 'precmd_lastused.txt') self.POST_LASTUSED_FILE = os.path.join(self.ROOTPATH, 'data', 'postcmd_lastused.txt') self.KEYPATH = os.path.join(self.ROOTPATH, 'data', 'keys') if self.ARGS.precmd: self.LW.log( ['overriding default pre command with ' + self.ARGS.precmd]) self.PRE_CMD = self.ARGS.precmd else: self.PRE_CMD = config.Get('pre_cmd') if self.ARGS.postcmd: self.LW.log( ['overriding default post command with ' + self.ARGS.postcmd]) self.POST_CMD = self.ARGS.postcmd else: self.POST_CMD = config.Get('post_cmd') if self.ARGS.wait: self.LW.log([ 'overriding default wait between with ' + str(self.ARGS.wait) ]) self.WAIT_BETWEEN = self.ARGS.wait else: self.WAIT_BETWEEN = config.Get('wait_between') if self.ARGS.forcepre: self.LW.log(['overriding default pre command cache time']) self.IGNORE_PRECMD_FOR = 0 else: self.IGNORE_PRECMD_FOR = config.Get('ignore_precmd_for') if self.ARGS.forcepost: self.LW.log(['overriding default post command cache time']) self.IGNORE_POSTCMD_FOR = 0 else: self.IGNORE_POSTCMD_FOR = config.Get('ignore_postcmd_for') if self.ARGS.irc: self.LW.log( ['overriding default IR channel(s) with ' + self.ARGS.irc]) self.IRC = self.ARGS.irc else: self.IRC = config.Get('irc') self.CHANNEL = self.ARGS.channel.strip() self.ANALOG_FAIL_CMDS = config.Get('analog_fail_cmds') self.LIVETV_DIR = config.Get('livetv_dir') self.BLASTER = self._pick_blaster() self.DVR = self._pick_dvr() def _parse_argv(self): parser = argparse.ArgumentParser() group = parser.add_mutually_exclusive_group(required=True) group.add_argument("-c", "--channel", help="the channel number") group.add_argument("-m", "--cmds", help="arbitrary string of commands") parser.add_argument( "-i", "--irc", help="the IR channel(s) on which to send the command") parser.add_argument( "-n", "--postchannel", help="the command to send after the channel number") parser.add_argument( "-b", "--precmd", help= "the string of commands (separated by pipe) to send before any other commands" ) parser.add_argument( "-e", "--postcmd", help= "the string of commands (separated by pipe) to send after any other commands" ) parser.add_argument( "-w", "--wait", type=int, help="the amount of time (in seconds) to wait between commands") parser.add_argument("-a", "--forcepre", help="force pre commands to run no matter what", action="store_true") parser.add_argument("-o", "--forcepost", help="force post commands to run no matter what", action="store_true") parser.add_argument( "-g", "--analogcheck", help= "check the analog encoder file and try channel again if not present", action="store_true") self.ARGS = parser.parse_args() self.LW.log(['the channel is ' + self.ARGS.channel]) self.LW.log(['analog check is ' + str(self.ARGS.analogcheck)]) def _pick_blaster(self): blaster_type = config.Get('blaster_type').lower() if blaster_type == 'iguanair': return iguanair.Blaster(keypath=self.KEYPATH, key_ext=config.Get('key_ext'), path_to_igc=config.Get('path_to_IGC'), irc=self.IRC, wait_between=self.WAIT_BETWEEN) elif blaster_type == 'iguanair-server': return iguanair_server.Blaster(ws_ip=config.Get('ws_ip'), ws_port=config.Get('ws_port'), irc=self.IRC) else: return None def _pick_dvr(self): dvr_type = config.Get('dvr_type').lower() if dvr_type == 'nextpvr': return nextpvr.DVR(config=config) else: return None def _send_commands(self, cmds): self.LW.log(['sending: %s' % cmds], 'info') loglines = self.BLASTER.SendCommands(cmds) self.LW.log(loglines) def _setPID(self): self.LW.log(['setting PID file']) try: last_pidfile = glob.glob( os.path.join(self.ROOTPATH, 'data', '*.pid'))[-1] loglines, prev_pid = readFile(last_pidfile) self.LW.log(loglines) pid = str(int(prev_pid) + 1) self.PREVPIDFILE = os.path.join(self.ROOTPATH, 'data', 'iguana-blaster-%s.pid' % prev_pid) except IndexError: pid = '0' self.PREVPIDFILE = os.path.join(self.ROOTPATH, 'data', 'dummy.pid') global pidfile pidfile = os.path.join(self.ROOTPATH, 'data', 'iguana-blaster-%s.pid' % pid) success, loglines = writeFile(pid, pidfile, wtype='w') self.LW.log(loglines) def _splitchannel(self): cmd_list = [] for digit in list(self.CHANNEL): try: blast_digit = config.Get('digit_map')[digit] except IndexError: blast_digit = '' if blast_digit: cmd_list.append(blast_digit) if config.Get('post_channel'): cmd_list.append(config.Get('post_channel')) return "|".join(list(cmd_list)) def _wait_for_prev_cmd(self): basetime = time.time() while os.path.isfile(self.PREVPIDFILE): time.sleep(1) if time.time() - basetime > config.Get('aborttime'): err_str = 'taking too long for previous process to close - aborting attempt to send IR commands' self.LW.log([err_str]) sys.exit(err_str)
class Main: def __init__(self): self._init_vars() self.LW = Logger(preamble='[Where Are You]', logdebug=self.SETTINGS['debug']) self.LW.log(['script version %s started' % self.SETTINGS['ADDONVERSION']], xbmc.LOGINFO) self._parse_argv() if self.TITLE and self.MESSAGE: self._display_dialog() elif self.SETTINGS['harmonycontrol']: self._mappings_options() if self.FROMSETTINGS: self.SETTINGS['ADDON'].openSettings() self.LW.log(['script stopped'], xbmc.LOGINFO) def _display_dialog(self): use_extended_dialog = False try: json_mappings = json.loads(self.SETTINGS['mappings']) except ValueError: json_mappings = {} if json_mappings and self.SETTINGS['harmonycontrol']: for item in json_mappings: thematch = json_mappings.get(item, {}).get('match', '') self.LW.log(['checking for %s in %s' % (thematch, self.TITLE)]) self.LW.log(['checking for %s in %s' % (thematch, self.MESSAGE)]) if thematch.lower() in self.TITLE.lower() or thematch.lower() in self.MESSAGE.lower(): self.LW.log(['found match']) activity, cmds = self._get_mapping_details( json_mappings, item) self.MESSAGE = '%s\n%s' % ( self.MESSAGE, self.SETTINGS['ADDONLANGUAGE'](32303)) use_extended_dialog = True break if use_extended_dialog: if self.DIALOG.yesno(self.TITLE, self.MESSAGE): self._run_activity(activity, cmds) else: self.DIALOG.ok(self.TITLE, self.MESSAGE) pluginhandle = int(sys.argv[1]) xbmcplugin.setContent(pluginhandle, 'files') play_item = xbmcgui.ListItem(path=os.path.join( self.SETTINGS['ADDONPATH'], 'resources', 'blank.mp4')) xbmcplugin.setResolvedUrl(pluginhandle, True, listitem=play_item) def _init_vars(self): self.SETTINGS = loadSettings() self.DIALOG = xbmcgui.Dialog() if self.SETTINGS['harmonycontrol']: if self.SETTINGS['controltype'] == 1: if self.SETTINGS['ha_secure']: conntype = 'https' else: conntype = 'http' headers = {} headers['Content-Type'] = 'application/json' headers['Accept'] = 'application/json' headers['Authorization'] = 'Bearer %s' % self.SETTINGS['ha_token'] self.JSONURL = URL('json', headers=headers) self.RESTURL = '%s://%s:%s/api/services' % ( conntype, self.SETTINGS['hub_ip'], self.SETTINGS['hub_port']) elif self.SETTINGS['controltype'] == 2: self.MYHUB = HubControl( self.SETTINGS['hub_ip'], thetimeout=self.SETTINGS['timeout'], delay=self.SETTINGS['delay']) def _get_hascripts(self): script_list = [] status, loglines, results = self.JSONURL.Get(self.RESTURL) self.LW.log(loglines) for domain in results: self.LW.log(['checking domain %s' % domain["domain"]]) if domain["domain"] == 'script': for script_name in domain["services"]: self.LW.log(['checking script %s' % script_name]) if not script_name in {'reload', 'turn_on', 'turn_off', 'toggle'}: self.LW.log(['saving script']) script_list.append(script_name) break script_list.sort() return script_list def _get_mappings(self): self.LW.log(['the settings mappings are:', self.SETTINGS['mappings']]) try: json_mappings = json.loads(self.SETTINGS['mappings']) except ValueError: json_mappings = {} saved_mappings = [] for item in json_mappings: mapping_name = json_mappings.get(item, {}).get('match') if mapping_name: saved_mappings.append(mapping_name) saved_mappings.sort() self.LW.log(['returning saved mappings of:', saved_mappings, 'returning json mappings of:', json_mappings]) return saved_mappings, json_mappings def _get_mapping_details(self, json_mappings, item): activity = json_mappings.get(item, {}).get('activity', '') if self.SETTINGS['harmonyadvanced'] and self.SETTINGS['controltype'] == 2: cmds = json_mappings.get(item, {}).get('cmds', '') else: cmds = '' return activity, cmds def _mappings_options(self): options = [self.SETTINGS['ADDONLANGUAGE'](32300)] options.append(self.SETTINGS['ADDONLANGUAGE'](32301)) options.append(self.SETTINGS['ADDONLANGUAGE'](32302)) ret = self.DIALOG.select( self.SETTINGS['ADDONLANGUAGE'](32200), options) self.LW.log(['got back %s from the dialog box' % str(ret)]) if ret == -1: return if ret == 0: self._option_add() elif ret == 1: self._option_edit() elif ret == 2: self._option_edit(dodelete=True) def _option_add(self, default_match='', default_activity='', default_cmds=''): thematch = self.DIALOG.input( self.SETTINGS['ADDONLANGUAGE'](32201), defaultt=default_match) if not thematch: return cmds = '' activity_list = [] if self.SETTINGS['controltype'] == 1: activity_list = self._get_hascripts() elif self.SETTINGS['controltype'] == 2: activities, loglines = self.MYHUB.getActivities() self.LW.log(loglines) for activity_key in activities: activity_list.append(activity_key) activity_list.sort() if activity_list: try: default_index = activity_list.index(default_activity) except ValueError: default_index = -1 ret = self.DIALOG.select( self.SETTINGS['ADDONLANGUAGE'](32203), activity_list, 0, default_index) if ret == -1: return else: activity = activity_list[ret] else: activity = self.DIALOG.input( self.SETTINGS['ADDONLANGUAGE'](32203), defaultt=default_activity) if self.SETTINGS['controltype'] == 2 and self.SETTINGS['harmonyadvanced']: cmds = self.DIALOG.input( self.SETTINGS['ADDONLANGUAGE'](32202), defaultt=default_cmds) saved_mappings, json_mappings = self._get_mappings() json_mappings[thematch] = {'match': thematch, 'activity': activity, 'cmds': cmds} self.SETTINGS['ADDON'].setSetting( 'mappings', json.dumps(json_mappings)) def _option_edit(self, dodelete=False): saved_mappings, json_mappings = self._get_mappings() if not json_mappings: self._option_add() return ret = self.DIALOG.select( self.SETTINGS['ADDONLANGUAGE'](32204), saved_mappings) if ret == -1: return if dodelete: del json_mappings[saved_mappings[ret]] self.SETTINGS['ADDON'].setSetting( 'mappings', json.dumps(json_mappings)) else: thematch = json_mappings.get( saved_mappings[ret], {}).get('match', '') activity = json_mappings.get( saved_mappings[ret], {}).get('activity', '') cmds = json_mappings.get(saved_mappings[ret], {}).get('cmds', '') self._option_add(default_match=thematch, default_activity=activity, default_cmds=cmds) def _parse_argv(self): try: check_from = sys.argv[1] except IndexError: check_from = '' if check_from == 'fromsettings': self.FROMSETTINGS = True self.TITLE = '' self.MESSAGE = '' return self.FROMSETTINGS = False try: params = dict(arg.split("=") for arg in sys.argv[2].split("&")) except IndexError: params = {} except Exception as e: self.LW.log(['no arguments found: %s' % e]) params = {} self.TITLE = _unquote_plus(params.get('title', '')) self.MESSAGE = _unquote_plus(params.get('message', '')) def _run_activity(self, activity, cmds): if self.SETTINGS['controltype'] == 1: self.LW.log(['the HA script to run is: %s' % activity]) if activity: payload = {"entity_id": "script.%s" % activity} theurl = self.RESTURL + '/script/' + activity status, loglines, results = self.JSONURL.Post( theurl, data=json.dumps(payload)) self.LW.log(loglines) elif self.SETTINGS['controltype'] == 2: self.LW.log(['the activity to run is: %s' % activity]) if activity: result, loglines = self.MYHUB.startActivity(activity) self.LW.log(loglines) self.LW.log(['the result from the hub was:', result]) else: self.LW.log(['no activity to run']) self.LW.log(['the extra commands to run are: %s' % cmds]) if cmds: result, loglines = self.MYHUB.runCommands(cmds) self.LW.log(loglines) self.LW.log(['the result from the hub was:', result]) else: self.LW.log(['no extra commands to run']) else: self.LW.log(['no hub IP address in settings'], xbmc.LOGWARNING)
class Main: def __init__(self): self._init_vars() self.LW = Logger(preamble='[Where Are You]', logdebug=self.SETTINGS['debug']) self.LW.log( ['script version %s started' % self.SETTINGS['ADDONVERSION']], xbmc.LOGINFO) self._parse_argv() if self.TITLE and self.MESSAGE: self._display_dialog() elif self.SETTINGS['harmonycontrol']: self._mappings_options() if self.FROMSETTINGS: self.SETTINGS['ADDON'].openSettings() self.LW.log(['script stopped'], xbmc.LOGINFO) def _display_dialog(self): use_extended_dialog = False try: json_mappings = json.loads(self.SETTINGS['mappings']) except ValueError: json_mappings = {} if json_mappings and self.SETTINGS['harmonycontrol']: for item in json_mappings: thematch = json_mappings.get(item, {}).get('match', '') self.LW.log(['checking for %s in %s' % (thematch, self.TITLE)]) self.LW.log( ['checking for %s in %s' % (thematch, self.MESSAGE)]) if thematch.lower() in self.TITLE.lower() or thematch.lower( ) in self.MESSAGE.lower(): self.LW.log(['found match']) activity, cmds = self._get_mapping_details( json_mappings, item) self.MESSAGE = '%s\n%s' % ( self.MESSAGE, self.SETTINGS['ADDONLANGUAGE'](32303)) use_extended_dialog = True break if use_extended_dialog: if self.DIALOG.yesno(self.TITLE, self.MESSAGE): self._run_activity(activity, cmds) else: self.DIALOG.ok(self.TITLE, self.MESSAGE) pluginhandle = int(sys.argv[1]) xbmcplugin.setContent(pluginhandle, 'files') play_item = xbmcgui.ListItem(path=os.path.join( self.SETTINGS['ADDONPATH'], 'resources', 'blank.mp4')) xbmcplugin.setResolvedUrl(pluginhandle, True, listitem=play_item) def _init_vars(self): self.SETTINGS = loadSettings() self.DIALOG = xbmcgui.Dialog() if self.SETTINGS['harmonycontrol']: self.MYHUB = HubControl(self.SETTINGS['hub_ip'], thetimeout=self.SETTINGS['timeout'], delay=self.SETTINGS['delay']) def _get_mappings(self): self.LW.log(['the settings mappings are:', self.SETTINGS['mappings']]) try: json_mappings = json.loads(self.SETTINGS['mappings']) except ValueError: json_mappings = {} saved_mappings = [] for item in json_mappings: mapping_name = json_mappings.get(item, {}).get('match') if mapping_name: saved_mappings.append(mapping_name) saved_mappings.sort() self.LW.log([ 'returning saved mappings of:', saved_mappings, 'returning json mappings of:', json_mappings ]) return saved_mappings, json_mappings def _get_mapping_details(self, json_mappings, item): activity = json_mappings.get(item, {}).get('activity', '') if self.SETTINGS['harmonyadvanced']: cmds = json_mappings.get(item, {}).get('cmds', '') else: cmds = '' return activity, cmds def _mappings_options(self): options = [self.SETTINGS['ADDONLANGUAGE'](32300)] options.append(self.SETTINGS['ADDONLANGUAGE'](32301)) options.append(self.SETTINGS['ADDONLANGUAGE'](32302)) ret = self.DIALOG.select(self.SETTINGS['ADDONLANGUAGE'](32200), options) self.LW.log(['got back %s from the dialog box' % str(ret)]) if ret == -1: return if ret == 0: self._option_add() elif ret == 1: self._option_edit() elif ret == 2: self._option_edit(dodelete=True) def _option_add(self, default_match='', default_activity='', default_cmds=''): thematch = self.DIALOG.input(self.SETTINGS['ADDONLANGUAGE'](32201), defaultt=default_match) if not thematch: return activity = self.DIALOG.input(self.SETTINGS['ADDONLANGUAGE'](32203), defaultt=default_activity) if self.SETTINGS['harmonyadvanced']: cmds = self.DIALOG.input(self.SETTINGS['ADDONLANGUAGE'](32202), defaultt=default_cmds) else: cmds = '' saved_mappings, json_mappings = self._get_mappings() json_mappings[thematch] = { 'match': thematch, 'activity': activity, 'cmds': cmds } self.SETTINGS['ADDON'].setSetting('mappings', json.dumps(json_mappings)) def _option_edit(self, dodelete=False): saved_mappings, json_mappings = self._get_mappings() if not json_mappings: self._option_add() return ret = self.DIALOG.select(self.SETTINGS['ADDONLANGUAGE'](32204), saved_mappings) if ret == -1: return if dodelete: del json_mappings[saved_mappings[ret]] self.SETTINGS['ADDON'].setSetting('mappings', json.dumps(json_mappings)) else: thematch = json_mappings.get(saved_mappings[ret], {}).get('match', '') activity = json_mappings.get(saved_mappings[ret], {}).get('activity', '') cmds = json_mappings.get(saved_mappings[ret], {}).get('cmds', '') self._option_add(default_match=thematch, default_activity=activity, default_cmds=cmds) def _parse_argv(self): try: check_from = sys.argv[1] except IndexError: check_from = '' if check_from == 'fromsettings': self.FROMSETTINGS = True self.TITLE = '' self.MESSAGE = '' return self.FROMSETTINGS = False try: params = dict(arg.split("=") for arg in sys.argv[2].split("&")) except IndexError: params = {} except Exception as e: self.LW.log(['no arguments found: %s' % e]) params = {} self.TITLE = py2_decode(_unquote_plus(params.get('title', ''))) self.MESSAGE = py2_decode(_unquote_plus(params.get('message', ''))) def _run_activity(self, activity, cmds): if self.SETTINGS['hub_ip']: self.LW.log(['the activity to run is: %s' % activity]) if activity: result, loglines = self.MYHUB.startActivity(activity) self.LW.log(loglines) self.LW.log(['the result from the hub was:', result]) else: self.LW.log(['no activity to run']) self.LW.log(['the extra commands to run are: %s' % cmds]) if cmds: result, loglines = self.MYHUB.runCommands(cmds) self.LW.log(loglines) self.LW.log(['the result from the hub was:', result]) else: self.LW.log(['no extra commands to run']) else: self.LW.log(['no hub IP address in settings'], xbmc.LOGWARNING)
class Main: def __init__( self, thepath ): """Start process to record IR keys.""" self.ROOTPATH = os.path.dirname( thepath ) self.LW = Logger( logfile=os.path.join(self.ROOTPATH, 'data', 'logs', 'record.log' ), numbackups=config.Get( 'logbackups' ), logdebug=config.Get( 'debug' ) ) self.LW.log( ['script started'], 'info' ) self._init_vars() thekey = input( self.DIALOGTEXT ) while thekey: self._capture_ir() self._create_key( thekey ) thekey = input( self.DIALOGTEXT ) self._cleanup() self.LW.log( ['script finished'], 'info' ) def _capture_ir( self ): print( 'waiting for remote command...' ) cmd = '"%s" --receiver-on --sleep %s > "%s"' % (self.PATHTOIGC, str( self.IGSLEEP ), self.TEMPKEY) self.LW.log( ['sending ' + cmd] ) try: subprocess.check_output( cmd, shell=True) except subprocess.CalledProcessError as e: self.LW.log( [e] ) time.sleep( self.IGSLEEP ) def _create_key( self, thekey ): loglines, raw_ir = readFile( self.TEMPKEY ) self.LW.log( loglines ) if raw_ir: first_pulse = False ir_cmd = [] for one_line in raw_ir.splitlines(): one_line = one_line.strip().replace( ':', '' ) if not first_pulse: if one_line.startswith( 'pulse' ): first_pulse = True ir_cmd.append( one_line ) else: if self._long_space( one_line ): break elif one_line.startswith( 'space' ) or one_line.startswith( 'pulse' ): ir_cmd.append( one_line ) if ir_cmd: success, loglines = writeFile( "\n".join( ir_cmd ), os.path.join( self.KEYPATH, 'KEY_%s%s' % (thekey, self.KEYEXT) ), wtype='w' ) self.LW.log( loglines ) self.WROTEKEY = success success, loglines = deleteFile( self.TEMPKEY ) self.LW.log( loglines ) def _create_key_dir( self, thepath ): f_exists, loglines = checkPath( os.path.join( thepath, '' ) ) self.LW.log (loglines ) return thepath def _cleanup( self ): self.LW.log( ['cleaning up before quitting'] ) if os.path.exists( self.TEMPKEY ): success, loglines = deleteFile( self.TEMPKEY ) self.LW.log( loglines ) success, loglines = deleteFolder( self.TEMPKEYPATH ) self.LW.log( loglines ) if not self.WROTEKEY: sucess, loglines = deleteFolder( self.KEYPATH ) self.LW.log( loglines ) def _get_igc( self, igc ): if igc: return osPathFromString( igc ) elif os.name == 'nt': return os.path.join( 'C:', 'Program Files (x86)', 'IguanaIR', 'igclient.exe' ) else : return 'igclient' def _init_vars( self ): self.TEMPKEYPATH = self._create_key_dir( os.path.join( self.ROOTPATH, 'data', 'tmp' ) ) self.TEMPKEY = os.path.join( self.TEMPKEYPATH, 'tmp.txt' ) self.KEYPATH = self._create_key_dir( os.path.join( self.ROOTPATH, 'data', 'keys' ) ) self.IGSLEEP = config.Get( 'ig_sleep' ) self.KEYEXT = config.Get( 'key_ext' ) self.DIALOGTEXT = 'Input key to record (hit enter with no key to exit):' self.PATHTOIGC = self._get_igc( config.Get( 'path_to_IGC' ) ) self.WROTEKEY = False def _long_space( self, one_line ): line_list = one_line.split( ' ' ) try: thetype = line_list[0] thevalue = line_list[1] except IndexError: thetype = '' thevalue = '' if thetype.lower() == 'space': try: value_int = int( thevalue.strip() ) except ValueError: return False if value_int > 20000: return True else: return False else: return False
class Main: def __init__(self): self._init_vars() self.LW = Logger(preamble='[Harmony Hub Control]', logdebug=self.SETTINGS['debug']) self.LW.log( ['script version %s started' % self.SETTINGS['ADDONVERSION']], xbmc.LOGINFO) self._parse_argv() if self.ACTION == 'fromsettings': self._mappings_options() self.SETTINGS['ADDON'].openSettings() elif self.ACTION: saved_mappings, json_mappings = self._get_mappings() activity, cmds = self._get_mapping_details(json_mappings, self.ACTION) self._run_activity(activity, cmds) else: self._pick_activity() self.LW.log(['script stopped'], xbmc.LOGINFO) def _init_vars(self): self.SETTINGS = loadSettings() self.DIALOG = xbmcgui.Dialog() self.MYHUB = HubControl(self.SETTINGS['hub_ip'], thetimeout=self.SETTINGS['timeout'], delay=self.SETTINGS['delay']) def _get_mappings(self): self.LW.log(['the settings mappings are:', self.SETTINGS['mappings']]) try: json_mappings = json.loads(self.SETTINGS['mappings']) except ValueError: json_mappings = {} saved_mappings = [] for item in json_mappings: mapping_name = json_mappings.get(item, {}).get('match') if mapping_name: saved_mappings.append(mapping_name) saved_mappings.sort() self.LW.log([ 'returning saved mappings of:', saved_mappings, 'returning json mappings of:', json_mappings ]) return saved_mappings, json_mappings def _get_mapping_details(self, json_mappings, item): activity = json_mappings.get(item, {}).get('activity', '') if self.SETTINGS['harmonyadvanced']: cmds = json_mappings.get(item, {}).get('cmds', '') else: cmds = '' return activity, cmds def _mappings_options(self): options = [self.SETTINGS['ADDONLANGUAGE'](32300)] options.append(self.SETTINGS['ADDONLANGUAGE'](32301)) options.append(self.SETTINGS['ADDONLANGUAGE'](32302)) ret = self.DIALOG.select(self.SETTINGS['ADDONLANGUAGE'](32200), options) self.LW.log(['got back %s from the dialog box' % str(ret)]) if ret == -1: return if ret == 0: self._option_add() elif ret == 1: self._option_edit() elif ret == 2: self._option_edit(dodelete=True) def _option_add(self, default_match='', default_activity='', default_cmds=''): thematch = self.DIALOG.input(self.SETTINGS['ADDONLANGUAGE'](32201), defaultt=default_match) if not thematch: return activity = self.DIALOG.input(self.SETTINGS['ADDONLANGUAGE'](32203), defaultt=default_activity) if self.SETTINGS['harmonyadvanced']: cmds = self.DIALOG.input(self.SETTINGS['ADDONLANGUAGE'](32202), defaultt=default_cmds) else: cmds = '' saved_mappings, json_mappings = self._get_mappings() json_mappings[thematch] = { 'match': thematch, 'activity': activity, 'cmds': cmds } self.SETTINGS['ADDON'].setSetting('mappings', json.dumps(json_mappings)) def _option_edit(self, dodelete=False): saved_mappings, json_mappings = self._get_mappings() if not json_mappings: self._option_add() return ret = self.DIALOG.select(self.SETTINGS['ADDONLANGUAGE'](32204), saved_mappings) if ret == -1: return if dodelete: del json_mappings[saved_mappings[ret]] self.SETTINGS['ADDON'].setSetting('mappings', json.dumps(json_mappings)) else: thematch = json_mappings.get(saved_mappings[ret], {}).get('match', '') activity = json_mappings.get(saved_mappings[ret], {}).get('activity', '') cmds = json_mappings.get(saved_mappings[ret], {}).get('cmds', '') self._option_add(default_match=thematch, default_activity=activity, default_cmds=cmds) def _parse_argv(self): try: self.ACTION = sys.argv[1] except IndexError: self.ACTION = '' def _pick_activity(self): saved_mappings, json_mappings = self._get_mappings() dialog_return, loglines = hcdialog.Dialog().start( self.SETTINGS, title=self.SETTINGS['ADDONLANGUAGE'](32205), buttons=saved_mappings) self.LW.log(loglines) if dialog_return is None: return activity, cmds = self._get_mapping_details( json_mappings, saved_mappings[dialog_return]) self._run_activity(activity, cmds) def _run_activity(self, activity, cmds): if self.SETTINGS['hub_ip']: self.LW.log(['the activity to run is: %s' % activity]) if activity: result, loglines = self.MYHUB.startActivity(activity) self.LW.log(loglines) self.LW.log(['the result from the hub was:', result]) else: self.LW.log(['no activity to run']) self.LW.log(['the extra commands to run are: %s' % cmds]) if cmds: result, loglines = self.MYHUB.runCommands(cmds) self.LW.log(loglines) self.LW.log(['the result from the hub was:', result]) else: self.LW.log(['no extra commands to run']) else: self.LW.log(['no hub IP address in settings'], xbmc.LOGWARNING)