예제 #1
0
 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')
예제 #2
0
 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()
예제 #3
0
 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' )
예제 #4
0
 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)
예제 #5
0
 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'] )
예제 #6
0
 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'])
예제 #7
0
 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)
예제 #8
0
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 )
예제 #9
0
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 )
예제 #10
0
    from itertools import izip_longest as _zip_longest
except ImportError:
    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'
예제 #11
0
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 ''
예제 #12
0
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)
예제 #13
0
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)
예제 #14
0
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)
예제 #15
0
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
예제 #16
0
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
예제 #17
0
 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)
예제 #18
0
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)