示例#1
0
def exploration_loop(log):
    import addon
    start_time = time.time()
    entry_point_reached = False

    # Init Route to root
    root = Route(label='Root menu', path=[1])
    Route.add_route_to_explore(root)

    while (Route.continue_epxloration()):
        log.debug('Loop entry')

        current_route = Route.get_route_to_explore()

        # Check if the entry point was reached
        if len(current_route.path) == len(
                Config.get('entry_point')) and not entry_point_reached:
            log.debug('Entry point ({}) reached'.format(
                Config.get('entry_point')))
            entry_point_reached = True

        # Hock sys.argv
        with mock.patch('sys.argv', current_route.get_fake_sys_argv()):

            if Config.get('autoreload_addon'):
                # We need to reload the addon module in order to be able
                # to modify the source code of the addon on the fly without restarting
                # the simulator
                # (usefull during dev)
                for k, v in sys.modules.items():
                    # print(str(k) + ' :: ' + str(v))
                    if 'plugin.video.catchuptvandmore' in str(v) and \
                            'plugin.video.catchuptvandmore/addon.py' not in str(v):
                        # print('\tRELOAD')
                        reload(v)
                reload(addon)

            # We need to clean this var
            RuntimeErrorCQ.last_error_message = ""

            # Simulate the addon execution
            addon.main()

            # We have to know the next item to epxlore
            # If next_item = -2 we just reload the addon we the same route
            next_item = -2

            # If an error was trigger
            if RuntimeErrorCQ.last_menu_triggered_error:

                log.warn('')
                log.warn(
                    WARNING +
                    ' The last selection triggered an error (see log above) ' +
                    WARNING)
                log.warn('')

                error = RuntimeErrorCQ(path=Route.pretty_exploring_routes())
                print(error)
                RuntimeErrorCQ.reset_error_trigger()

                if len(RuntimeErrorCQ.all_errors) >= Config.get(
                        'exit_after_x_errors'):
                    log.info(
                        'Max number of error reached ({}) --> Exit'.format(
                            Config.get('exit_after_x_errors')))
                    next_item = -1
                else:
                    log.info(
                        '[DEBUG] Max number of error not reached --> Go back')
                    next_item = 0

            # Else if the current directory is a playable item
            elif Directory.is_current_directory_playable():
                item = Directory.current_directory.items[1]
                log.info('Playable URL: {}'.format(item.url))
                next_item = 0
                if not Config.get('disable_video_player'):
                    player = Player(item.url)
                    player.play()

            # Else if succeeded is False (Happen when "No video found" notif is trigger)
            elif Directory.current_directory.succeeded is False:
                log.info(
                    'endOfDirectory was called with succeeded=False --> Go back'
                )
                next_item = 0

            # Else print the current directory
            else:
                print(Directory.current_directory)
                print(Route.pretty_exploring_routes() + '\n')

                # If the entry_point was not reached we follow the entry point path
                if not entry_point_reached:
                    next_item = Config.get('entry_point')[len(
                        current_route.path)]
                    if next_item == 'R':
                        next_item = randint(
                            1, len(Directory.current_directory.items))
                        log.info(
                            'Entry point not yet reached --> random next item: {}'
                            .format(next_item))
                    else:
                        next_item = int(next_item)
                        log.info(
                            'Entry point not yet reached --> next item: {}'.
                            format(next_item))

                # Else if we are in auto exploration
                elif Config.get('auto_exploration'):
                    log.debug('Auto exploration mode')
                    # If needed, add items of the current menu to explore later
                    AutoExploration.add_items_current_menu(
                        current_route.path, Directory.current_directory)

                    # We wait a fake time
                    sys.stdout.flush()
                    time.sleep(Config.get('wait_time'))

                    # We ask for the next item to epxlore
                    next_item = AutoExploration.next_item_to_explore(
                        current_route.path, Directory.current_directory)
                    log.info(
                        'next_item selected by auto exploration: {}'.format(
                            next_item))

                # Else we ask the user to choose the next item number
                else:
                    # We wait the user input
                    try:
                        sys.stdout.flush()
                        next_item = int(
                            input(
                                'Next item to select? (-1 to exit, <enter> to reload same directory)\n'
                            ))
                        log.info('Choosen next_item: {}'.format(next_item))

                    except Exception:
                        pass
                    print('')

            # Check for timeout
            delta_time = time.time() - start_time
            if Config.get('timeout') != -1 and delta_time >= Config.get(
                    'timeout'):
                log.warn('AUTO EXPLORATION TIMEOUT --> Exit exploration')
                next_item = -1

            # Else if the user wants to exit the simulator, let's break the loop
            if next_item == -1:
                break

            if Directory.current_directory is None:
                next_item = -2

            else:
                # If there is no item for this value, reload the same menu to prevent error
                if next_item > len(Directory.current_directory.items) or (
                        next_item == 0 and len(current_route.path) <= 1):
                    next_item = -2

            # If next_item has the default value just reload the same menu
            if next_item == -2:
                pass

            # Else if the user want to go back in the previous menu
            elif next_item == 0:
                Route.previous_route()

            # Else if the user want an item
            else:
                selected_item = Directory.current_directory.items[next_item]
                Route.add_item_to_explore(selected_item)