class PluginLoaderTest(unittest.TestCase):
    def setUp(self):
        self.plugin_loader = PluginLoader()

    def test_load_namespace_class(self):
        package_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'resources', 'plugin_fixture')
        self.plugin_loader.load_plugin(package_path)
        loaded_class = self.plugin_loader.get_class('plugin_fixture.FakeTask')
        self.assertEqual(loaded_class({}, {}).work(), 'FakeTask')
        self.plugin_loader.remove_path(package_path)

    def test_load_zip(self):
        package_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'resources', 'plugin_fixture_test.zip')
        self.plugin_loader.load_plugin(package_path)
        loaded_class = self.plugin_loader.get_class('plugin_fixture_test.FakeTask')
        self.assertEqual(loaded_class({}, {}).work(), 'FakeTask')
        self.plugin_loader.remove_path(package_path)
class TreeConfigBuilder(object):
    def __init__(self, bot, tasks_raw):
        self.bot = bot
        self.tasks_raw = tasks_raw
        self.plugin_loader = PluginLoader()

    def _get_worker_by_name(self, name):
        try:
            worker = getattr(cell_workers, name)
        except AttributeError:
            raise ConfigException('No worker named {} defined'.format(name))

        return worker

    def _is_plugin_task(self, name):
        return '.' in name

    def build(self):
        workers = []

        for task in self.tasks_raw:
            task_type = task.get('type', None)
            if task_type is None:
                raise ConfigException('No type found for given task {}'.format(task))
            elif task_type == 'EvolveAll':
                raise ConfigException('The EvolveAll task has been renamed to EvolvePokemon')

            task_config = task.get('config', {})

            if self._is_plugin_task(task_type):
                worker = self.plugin_loader.get_class(task_type)
            else:
                worker = self._get_worker_by_name(task_type)

            error_string = ''
            if BaseTask.TASK_API_VERSION < worker.SUPPORTED_TASK_API_VERSION:
                error_string = 'Do you need to update the bot?'

            elif BaseTask.TASK_API_VERSION > worker.SUPPORTED_TASK_API_VERSION:
                error_string = 'Is there a new version of this task?'

            if error_string != '':
                raise MismatchTaskApiVersion(
                    'Task {} only works with task api version {}, you are currently running version {}. {}'
                    .format(
                        task_type,
                        worker.SUPPORTED_TASK_API_VERSION,
                        BaseTask.TASK_API_VERSION,
                        error_string
                    )
                )

            instance = worker(self.bot, task_config)
            if instance.enabled:
                workers.append(instance)

        return workers
class TreeConfigBuilder(object):
    def __init__(self, bot, tasks_raw):
        self.bot = bot
        self.tasks_raw = tasks_raw
        self.plugin_loader = PluginLoader()

    def _get_worker_by_name(self, name):
        try:
            worker = getattr(cell_workers, name)
        except AttributeError:
            raise ConfigException('No worker named {} defined'.format(name))

        return worker

    def _is_plugin_task(self, name):
        return '.' in name

    def build(self):
        workers = []

        for task in self.tasks_raw:
            task_type = task.get('type', None)
            if task_type is None:
                raise ConfigException(
                    'No type found for given task {}'.format(task))
            elif task_type == 'EvolveAll':
                raise ConfigException(
                    'The EvolveAll task has been renamed to EvolvePokemon')

            task_config = task.get('config', {})

            if self._is_plugin_task(task_type):
                worker = self.plugin_loader.get_class(task_type)
            else:
                worker = self._get_worker_by_name(task_type)

            error_string = ''
            if BaseTask.TASK_API_VERSION < worker.SUPPORTED_TASK_API_VERSION:
                error_string = 'Do you need to update the bot?'

            elif BaseTask.TASK_API_VERSION > worker.SUPPORTED_TASK_API_VERSION:
                error_string = 'Is there a new version of this task?'

            if error_string != '':
                raise MismatchTaskApiVersion(
                    'Task {} only works with task api version {}, you are currently running version {}. {}'
                    .format(task_type, worker.SUPPORTED_TASK_API_VERSION,
                            BaseTask.TASK_API_VERSION, error_string))

            instance = worker(self.bot, task_config)
            workers.append(instance)

        return workers
Example #4
0
def init_config():
    parser = argparse.ArgumentParser()
    config_file = os.path.join(_base_dir, 'configs', 'config.json')
    web_dir = "web"

    # If config file exists, load variables from json
    load = {}

    def _json_loader(filename):
        try:
            with open(filename, 'rb') as data:
                load.update(json.load(data))
        except ValueError:
            if jsonlint:
                with open(filename, 'rb') as data:
                    lint = jsonlint()
                    rc = lint.main(['-v', filename])

            logger.critical('Error with configuration file')
            sys.exit(-1)

    # Select a config file code
    parser.add_argument("-cf", "--config", help="Config File to use")
    parser.add_argument("-af", "--auth", help="Auth File to use")

    for _config in ['auth', 'config']:
        config_file = os.path.join(_base_dir, 'configs', _config + '.json')
        config_arg = parser.parse_known_args() and parser.parse_known_args(
        )[0].__dict__[_config] or None

        if config_arg and os.path.isfile(config_arg):
            _json_loader(config_arg)
            config_file = config_arg
        elif os.path.isfile(config_file):
            logger.info('No ' + _config +
                        ' argument specified, checking for ' + config_file)
            _json_loader(config_file)
        else:
            logger.info('Error: No /configs/' + _config + '.json')

    # Read passed in Arguments
    required = lambda x: x not in load
    add_config(parser,
               load,
               short_flag="-a",
               long_flag="--auth_service",
               help="Auth Service ('ptc' or 'google')",
               required=required("auth_service"),
               default=None)
    add_config(parser,
               load,
               short_flag="-u",
               long_flag="--username",
               help="Username",
               default=None)
    add_config(parser,
               load,
               short_flag="-capi",
               long_flag="--check_niantic_api",
               help="Enable killswitch on API Change",
               type=bool,
               default=True)
    add_config(parser,
               load,
               short_flag="-ws",
               long_flag="--websocket.server_url",
               help="Connect to websocket server at given url",
               default=False)
    add_config(parser,
               load,
               short_flag="-wss",
               long_flag="--websocket.start_embedded_server",
               help="Start embedded websocket server",
               default=False)
    add_config(
        parser,
        load,
        short_flag="-wsr",
        long_flag="--websocket.remote_control",
        help=
        "Enable remote control through websocket (requires websocket server url)",
        default=False)
    add_config(parser,
               load,
               short_flag="-p",
               long_flag="--password",
               help="Password",
               default=None)
    add_config(parser,
               load,
               short_flag="-l",
               long_flag="--location",
               help="Location",
               type=parse_unicode_str,
               default='')
    add_config(parser,
               load,
               short_flag="-lc",
               long_flag="--location_cache",
               help="Bot will start at last known location",
               type=bool,
               default=False)
    add_config(
        parser,
        load,
        long_flag="--forts.spin",
        help="Enable Spinning Pokestops",
        type=bool,
        default=True,
    )
    add_config(parser,
               load,
               short_flag="-wmax",
               long_flag="--walk_max",
               help="Walk instead of teleport with given speed",
               type=float,
               default=2.5)
    add_config(parser,
               load,
               short_flag="-wmin",
               long_flag="--walk_min",
               help="Walk instead of teleport with given speed",
               type=float,
               default=2.5)
    add_config(parser,
               load,
               short_flag="-k",
               long_flag="--gmapkey",
               help="Set Google Maps API KEY",
               type=str,
               default=None)
    add_config(parser,
               load,
               short_flag="-hk",
               long_flag="--hashkey",
               help="Set Bossland hashing key",
               type=str,
               default=None)
    add_config(parser,
               load,
               short_flag="-e",
               long_flag="--show_events",
               help="Show events",
               type=bool,
               default=False)
    add_config(parser,
               load,
               short_flag="-d",
               long_flag="--debug",
               help="Debug Mode",
               type=bool,
               default=False)
    add_config(parser,
               load,
               short_flag="-t",
               long_flag="--test",
               help="Only parse the specified location",
               type=bool,
               default=False)
    add_config(
        parser,
        load,
        short_flag="-du",
        long_flag="--distance_unit",
        help=
        "Set the unit to display distance in (e.g, km for kilometers, mi for miles, ft for feet)",
        type=str,
        default='km')
    add_config(
        parser,
        load,
        short_flag="-rt",
        long_flag="--reconnecting_timeout",
        help=
        "Timeout between reconnecting if error occured (in minutes, e.g. 15)",
        type=float,
        default=15.0)
    add_config(
        parser,
        load,
        short_flag="-hr",
        long_flag="--health_record",
        help=
        "Send anonymous bot event to GA for bot health record. Set \"health_record\":false if you need disable it.",
        type=bool,
        default=True)
    add_config(
        parser,
        load,
        short_flag="-ac",
        long_flag="--forts.avoid_circles",
        help=
        "Avoids circles (pokestops) of the max size set in max_circle_size flag",
        type=bool,
        default=False,
    )
    add_config(
        parser,
        load,
        short_flag="-mcs",
        long_flag="--forts.max_circle_size",
        help=
        "If avoid_circles flag is set, this flag specifies the maximum size of circles (pokestops) avoided",
        type=int,
        default=10,
    )
    add_config(
        parser,
        load,
        short_flag="-crf",
        long_flag="--forts.cache_recent_forts",
        help="Caches recent forts used by max_circle_size",
        type=bool,
        default=True,
    )
    add_config(
        parser,
        load,
        long_flag="--map_object_cache_time",
        help=
        "Amount of seconds to keep the map object in cache (bypass Niantic throttling)",
        type=float,
        default=5.0)
    add_config(
        parser,
        load,
        long_flag="--logging.color",
        help=
        "If logging_color is set to true, colorized logging handler will be used",
        type=bool,
        default=True)
    add_config(
        parser,
        load,
        long_flag="--logging.clean",
        help=
        "If clean_logging is set to true, meta data will be stripped from the log messages",
        type=bool,
        default=False)
    add_config(parser,
               load,
               long_flag="--heartbeat_threshold",
               help="A threshold between each heartbeat sending to server",
               type=int,
               default=10)
    add_config(parser,
               load,
               long_flag="--pokemon_bag.show_at_start",
               help="Logs all pokemon in the bag at bot start",
               type=bool,
               default=False)
    add_config(parser,
               load,
               long_flag="--pokemon_bag.show_count",
               help="Shows the amount of which pokemon (minimum 1)",
               type=bool,
               default=False)
    add_config(parser,
               load,
               long_flag="--pokemon_bag.show_candies",
               help="Shows the amount of candies for each pokemon",
               type=bool,
               default=False)
    add_config(parser,
               load,
               long_flag="--pokemon_bag.pokemon_info",
               help="List with the info to show for each pokemon",
               type=bool,
               default=[])
    add_config(parser,
               load,
               long_flag="--alt_min",
               help="Minimum random altitude",
               type=float,
               default=500)
    add_config(parser,
               load,
               long_flag="--alt_max",
               help="Maximum random altitude",
               type=float,
               default=1000)
    add_config(parser,
               load,
               long_flag="--replicate_gps_xy_noise",
               help="Add noise to current position",
               type=bool,
               default=False)
    add_config(parser,
               load,
               long_flag="--replicate_gps_z_noise",
               help="Add noise to current position",
               type=bool,
               default=False)
    add_config(
        parser,
        load,
        long_flag="--gps_xy_noise_range",
        help=
        "Intensity of gps noise (unit is lat and lng,) high values may cause issues (default=0.000125)",
        type=float,
        default=0.000125)
    add_config(parser,
               load,
               long_flag="--gps_z_noise_range",
               help="Intensity of gps noise (unit is in meter, default=12.5)",
               type=float,
               default=12.5)
    add_config(parser,
               load,
               long_flag="--gps_default_altitude",
               help="Initial altitude (default=8.0)",
               type=float,
               default=8.0)
    add_config(parser,
               load,
               long_flag="--enable_social",
               help="Enable social event exchange between bot",
               type=bool,
               default=True)

    add_config(
        parser,
        load,
        long_flag="--walker_limit_output",
        help=
        "Limit output from walker functions (move_to_fort, position_update, etc)",
        type=bool,
        default=False)

    # Start to parse other attrs
    config = parser.parse_args()
    if not config.username and 'username' not in load:
        config.username = raw_input("Username: "******"Password: "******"--map_object_cache_time is out of range! (should be >= 0.0)")
        return None

    if len(config.raw_tasks) == 0:
        logging.error(
            "No tasks are configured. Did you mean to configure some behaviors? Read https://github.com/PokemonGoF/PokemonGo-Bot/wiki/Configuration-files#configuring-tasks for more information"
        )
        return None

    if config.auth_service not in ['ptc', 'google']:
        logging.error("Invalid Auth service specified! ('ptc' or 'google')")
        return None

    def task_configuration_error(flag_name):
        parser.error("""
            \"{}\" was removed from the configuration options.
            You can now change the behavior of the bot by modifying the \"tasks\" key.
            Read https://github.com/PokemonGoF/PokemonGo-Bot/wiki/Configuration-files#configuring-tasks for more information.
            """.format(flag_name))

    old_flags = [
        'mode', 'catch_pokemon', 'spin_forts', 'forts_spin', 'hatch_eggs',
        'release_pokemon', 'softban_fix', 'longer_eggs_first', 'evolve_speed',
        'use_lucky_egg', 'item_filter', 'evolve_all', 'evolve_cp_min',
        'max_steps', 'catch_throw_parameters.excellent_rate',
        'catch_throw_parameters.great_rate',
        'catch_throw_parameters.nice_rate',
        'catch_throw_parameters.normal_rate',
        'catch_throw_parameters.spin_success_rate'
    ]
    for flag in old_flags:
        if flag in load:
            task_configuration_error(flag)
            return None

    nested_old_flags = [('forts', 'spin'), ('forts', 'move_to_spin'),
                        ('navigator', 'path_mode'), ('navigator', 'path_file'),
                        ('navigator', 'type')]
    for outer, inner in nested_old_flags:
        if load.get(outer, {}).get(inner, None):
            task_configuration_error('{}.{}'.format(outer, inner))
            return None

    if "evolve_captured" in load:
        logger.warning(
            'The evolve_captured argument is no longer supported. Please use the EvolvePokemon task instead'
        )

    if "walk" in load:
        logger.warning(
            'The walk argument is no longer supported. Please use the walk_max and walk_min variables instead'
        )

    if "daily_catch_limit" in load:
        logger.warning(
            'The daily_catch_limit argument has been moved into the CatchPokemon Task'
        )

    if "logging_color" in load:
        logger.warning(
            'The logging_color argument has been moved into the logging config section'
        )

    if config.walk_min < 1:
        parser.error("--walk_min is out of range! (should be >= 1.0)")
        return None

    if config.alt_min < -413.0:
        parser.error("--alt_min is out of range! (should be >= -413.0)")
        return None

    if not (config.location or config.location_cache):
        parser.error("Needs either --use-location-cache or --location.")
        return None

    plugin_loader = PluginLoader()
    for plugin in config.plugins:
        plugin_loader.load_plugin(plugin)

    # create web dir if not exists
    try:
        os.makedirs(web_dir)
    except OSError:
        if not os.path.isdir(web_dir):
            raise

    fix_nested_config(config)
    return config, config_file
Example #5
0
def init_config():
    parser = argparse.ArgumentParser()
    config_file = os.path.join(_base_dir, 'configs', 'config.json')
    web_dir = "web"

    # If config file exists, load variables from json
    load = {}

    def _json_loader(filename):
        try:
            with open(filename, 'rb') as data:
                load.update(json.load(data))
        except ValueError:
            if jsonlint:
                with open(filename, 'rb') as data:
                    lint = jsonlint()
                    rc = lint.main(['-v', filename])

            logger.critical('Error with configuration file')
            sys.exit(-1)

    # Select a config file code
    parser.add_argument("-cf", "--config", help="Config File to use")
    parser.add_argument("-af", "--auth", help="Auth File to use")

    for _config in ['auth', 'config']:
        config_file = os.path.join(_base_dir, 'configs', _config + '.json')
        config_arg = parser.parse_known_args() and parser.parse_known_args()[0].__dict__[_config] or None

        if config_arg and os.path.isfile(config_arg):
            _json_loader(config_arg)
            config_file = config_arg
        elif os.path.isfile(config_file):
            logger.info('No ' + _config + ' argument specified, checking for ' + config_file)
            _json_loader(config_file)
        else:
            logger.info('Error: No /configs/' + _config + '.json')

    # Read passed in Arguments
    required = lambda x: not x in load
    add_config(
        parser,
        load,
        short_flag="-a",
        long_flag="--auth_service",
        help="Auth Service ('ptc' or 'google')",
        required=required("auth_service"),
        default=None
    )
    add_config(
        parser,
        load,
        short_flag="-u",
        long_flag="--username",
        help="Username",
        default=None
    )
    add_config(
        parser,
        load,
        short_flag="-ws",
        long_flag="--websocket.server_url",
        help="Connect to websocket server at given url",
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-wss",
        long_flag="--websocket.start_embedded_server",
        help="Start embedded websocket server",
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-wsr",
        long_flag="--websocket.remote_control",
        help="Enable remote control through websocket (requires websocket server url)",
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-p",
        long_flag="--password",
        help="Password",
        default=None
    )
    add_config(
        parser,
        load,
        short_flag="-l",
        long_flag="--location",
        help="Location",
        type=parse_unicode_str,
        default=''
    )
    add_config(
        parser,
        load,
        short_flag="-lc",
        long_flag="--location_cache",
        help="Bot will start at last known location",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        long_flag="--forts.spin",
        help="Enable Spinning Pokestops",
        type=bool,
        default=True,
    )
    add_config(
        parser,
        load,
        short_flag="-wmax",
        long_flag="--walk_max",
        help="Walk instead of teleport with given speed",
        type=float,
        default=2.5
    )
    add_config(
        parser,
        load,
        short_flag="-wmin",
        long_flag="--walk_min",
        help="Walk instead of teleport with given speed",
        type=float,
        default=2.5
    )
    add_config(
        parser,
        load,
        short_flag="-k",
        long_flag="--gmapkey",
        help="Set Google Maps API KEY",
        type=str,
        default=None
    )
    add_config(
        parser,
        load,
        short_flag="-e",
        long_flag="--show_events",
        help="Show events",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-d",
        long_flag="--debug",
        help="Debug Mode",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-t",
        long_flag="--test",
        help="Only parse the specified location",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-du",
        long_flag="--distance_unit",
        help="Set the unit to display distance in (e.g, km for kilometers, mi for miles, ft for feet)",
        type=str,
        default='km'
    )
    add_config(
        parser,
        load,
        short_flag="-rt",
        long_flag="--reconnecting_timeout",
        help="Timeout between reconnecting if error occured (in minutes, e.g. 15)",
        type=float,
        default=15.0
    )
    add_config(
        parser,
        load,
        short_flag="-hr",
        long_flag="--health_record",
        help="Send anonymous bot event to GA for bot health record. Set \"health_record\":false if you need disable it.",
        type=bool,
        default=True
    )
    add_config(
        parser,
        load,
        short_flag="-ac",
        long_flag="--forts.avoid_circles",
        help="Avoids circles (pokestops) of the max size set in max_circle_size flag",
        type=bool,
        default=False,
    )
    add_config(
        parser,
        load,
        short_flag="-mcs",
        long_flag="--forts.max_circle_size",
        help="If avoid_circles flag is set, this flag specifies the maximum size of circles (pokestops) avoided",
        type=int,
        default=10,
    )
    add_config(
        parser,
        load,
        short_flag="-crf",
        long_flag="--forts.cache_recent_forts",
        help="Caches recent forts used by max_circle_size",
        type=bool,
        default=True,
    )
    add_config(
        parser,
        load,
        long_flag="--map_object_cache_time",
        help="Amount of seconds to keep the map object in cache (bypass Niantic throttling)",
        type=float,
        default=5.0
    )
    add_config(
        parser,
        load,
        long_flag="--logging.color",
        help="If logging_color is set to true, colorized logging handler will be used",
        type=bool,
        default=True
    )
    add_config(
        parser,
        load,
        long_flag="--logging.clean",
        help="If clean_logging is set to true, meta data will be stripped from the log messages",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        long_flag="--heartbeat_threshold",
        help="A threshold between each heartbeat sending to server",
        type=int,
        default=10
    )
    add_config(
        parser,
        load,
        long_flag="--pokemon_bag.show_at_start",
        help="Logs all pokemon in the bag at bot start",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        long_flag="--pokemon_bag.show_count",
        help="Shows the amount of which pokemon (minimum 1)",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        long_flag="--pokemon_bag.show_candies",
        help="Shows the amount of candies for each pokemon",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        long_flag="--pokemon_bag.pokemon_info",
        help="List with the info to show for each pokemon",
        type=bool,
        default=[]
    )
    add_config(
        parser,
        load,
        long_flag="--alt_min",
        help="Minimum random altitude",
        type=float,
        default=500
    )
    add_config(
        parser,
        load,
        long_flag="--alt_max",
        help="Maximum random altitude",
        type=float,
        default=1000
    )
    add_config(
        parser,
        load,
        long_flag="--replicate_gps_xy_noise",
        help="Add noise to current position",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        long_flag="--replicate_gps_z_noise",
        help="Add noise to current position",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        long_flag="--gps_xy_noise_range",
        help="Intensity of gps noise (unit is lat and lng,) high values may cause issues (default=0.000125)",
        type=float,
        default=0.000125
    )
    add_config(
        parser,
        load,
        long_flag="--gps_z_noise_range",
        help="Intensity of gps noise (unit is in meter, default=12.5)",
        type=float,
        default=12.5
    )
    add_config(
        parser,
        load,
        long_flag="--gps_default_altitude",
        help="Initial altitude (default=8.0)",
        type=float,
        default=8.0
    )
    add_config(
         parser,
         load,
         long_flag="--enable_social",
         help="Enable social event exchange between bot",
         type=bool,
         default=True
    )

    add_config(
         parser,
         load,
         long_flag="--walker_limit_output",
         help="Limit output from walker functions (move_to_fort, position_update, etc)",
         type=bool,
         default=False
    )

    # Start to parse other attrs
    config = parser.parse_args()
    if not config.username and 'username' not in load:
        config.username = raw_input("Username: "******"Password: "******"--map_object_cache_time is out of range! (should be >= 0.0)")
        return None

    if len(config.raw_tasks) == 0:
        logging.error("No tasks are configured. Did you mean to configure some behaviors? Read https://github.com/PokemonGoF/PokemonGo-Bot/wiki/Configuration-files#configuring-tasks for more information")
        return None

    if config.auth_service not in ['ptc', 'google']:
        logging.error("Invalid Auth service specified! ('ptc' or 'google')")
        return None

    def task_configuration_error(flag_name):
        parser.error("""
            \"{}\" was removed from the configuration options.
            You can now change the behavior of the bot by modifying the \"tasks\" key.
            Read https://github.com/PokemonGoF/PokemonGo-Bot/wiki/Configuration-files#configuring-tasks for more information.
            """.format(flag_name))

    old_flags = ['mode', 'catch_pokemon', 'spin_forts', 'forts_spin', 'hatch_eggs', 'release_pokemon', 'softban_fix',
                 'longer_eggs_first', 'evolve_speed', 'use_lucky_egg', 'item_filter', 'evolve_all', 'evolve_cp_min',
                 'max_steps', 'catch_throw_parameters.excellent_rate', 'catch_throw_parameters.great_rate',
                 'catch_throw_parameters.nice_rate', 'catch_throw_parameters.normal_rate',
                 'catch_throw_parameters.spin_success_rate']
    for flag in old_flags:
        if flag in load:
            task_configuration_error(flag)
            return None

    nested_old_flags = [('forts', 'spin'), ('forts', 'move_to_spin'), ('navigator', 'path_mode'), ('navigator', 'path_file'), ('navigator', 'type')]
    for outer, inner in nested_old_flags:
        if load.get(outer, {}).get(inner, None):
            task_configuration_error('{}.{}'.format(outer, inner))
            return None

    if "evolve_captured" in load:
        logger.warning('The evolve_captured argument is no longer supported. Please use the EvolvePokemon task instead')

    if "walk" in load:
        logger.warning('The walk argument is no longer supported. Please use the walk_max and walk_min variables instead')

    if "daily_catch_limit" in load:
        logger.warning('The daily_catch_limit argument has been moved into the CatchPokemon Task')

    if "logging_color" in load:
        logger.warning('The logging_color argument has been moved into the logging config section')

    if config.walk_min < 1:
        parser.error("--walk_min is out of range! (should be >= 1.0)")
        return None

    if config.alt_min < -413.0:
        parser.error("--alt_min is out of range! (should be >= -413.0)")
        return None

    if not (config.location or config.location_cache):
        parser.error("Needs either --use-location-cache or --location.")
        return None

    plugin_loader = PluginLoader()
    for plugin in config.plugins:
        plugin_loader.load_plugin(plugin)

    # create web dir if not exists
    try:
        os.makedirs(web_dir)
    except OSError:
        if not os.path.isdir(web_dir):
            raise

    fix_nested_config(config)
    return config, config_file
 def setUp(self):
     self.plugin_loader = PluginLoader()
Example #7
0
def init_config():
    parser = argparse.ArgumentParser()
    config_file = "configs/config.json"
    web_dir = "web"

    # If config file exists, load variables from json
    load = {}

    # Select a config file code
    parser.add_argument("-cf", "--config", help="Config File to use")
    config_arg = parser.parse_known_args() and parser.parse_known_args()[0].config or None
    if config_arg and os.path.isfile(config_arg):
        with open(config_arg) as data:
            load.update(json.load(data))
    elif os.path.isfile(config_file):
        logger.info('No config argument specified, checking for /configs/config.json')
        with open(config_file) as data:
            load.update(json.load(data))
    else:
        logger.info('Error: No /configs/config.json or specified config')

    # Read passed in Arguments
    required = lambda x: not x in load
    add_config(
        parser,
        load,
        short_flag="-a",
        long_flag="--auth_service",
        help="Auth Service ('ptc' or 'google')",
        required=required("auth_service"),
        default=None
    )
    add_config(
        parser,
        load,
        short_flag="-u",
        long_flag="--username",
        help="Username",
        default=None
    )
    add_config(
        parser,
        load,
        short_flag="-ws",
        long_flag="--websocket.server_url",
        help="Connect to websocket server at given url",
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-wss",
        long_flag="--websocket.start_embedded_server",
        help="Start embedded websocket server",
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-wsr",
        long_flag="--websocket.remote_control",
        help="Enable remote control through websocket (requires websocekt server url)",
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-p",
        long_flag="--password",
        help="Password",
        default=None
    )
    add_config(
        parser,
        load,
        short_flag="-l",
        long_flag="--location",
        help="Location",
        type=parse_unicode_str,
        default=''
    )
    add_config(
        parser,
        load,
        short_flag="-lc",
        long_flag="--location_cache",
        help="Bot will start at last known location",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        long_flag="--forts.spin",
        help="Enable Spinning Pokestops",
        type=bool,
        default=True,
    )
    add_config(
        parser,
        load,
        short_flag="-w",
        long_flag="--walk",
        help=
        "Walk instead of teleport with given speed (meters per second, e.g. 2.5)",
        type=float,
        default=2.5
    )
    add_config(
        parser,
        load,
        short_flag="-k",
        long_flag="--gmapkey",
        help="Set Google Maps API KEY",
        type=str,
        default=None
    )
    add_config(
        parser,
        load,
        short_flag="-e",
        long_flag="--show_events",
        help="Show events",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-d",
        long_flag="--debug",
        help="Debug Mode",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-t",
        long_flag="--test",
        help="Only parse the specified location",
        type=bool,
        default=False
    )
    add_config(
        parser,
        load,
        short_flag="-du",
        long_flag="--distance_unit",
        help="Set the unit to display distance in (e.g, km for kilometers, mi for miles, ft for feet)",
        type=str,
        default='km'
    )
    add_config(
        parser,
        load,
        short_flag="-ec",
        long_flag="--evolve_captured",
        help="(Ad-hoc mode) Pass \"all\" or a list of pokemon to evolve (e.g., \"Pidgey,Weedle,Caterpie\"). Bot will attempt to evolve all the pokemon captured!",
        type=str,
        default=[]
    )
    add_config(
        parser,
        load,
        short_flag="-rt",
        long_flag="--reconnecting_timeout",
        help="Timeout between reconnecting if error occured (in minutes, e.g. 15)",
        type=float,
        default=15.0
    )
    add_config(
        parser,
        load,
        short_flag="-hr",
        long_flag="--health_record",
        help="Send anonymous bot event to GA for bot health record. Set \"health_record\":false if you need disable it.",
        type=bool,
        default=True
    )
    add_config(
        parser,
        load,
        short_flag="-ac",
        long_flag="--forts.avoid_circles",
        help="Avoids circles (pokestops) of the max size set in max_circle_size flag",
        type=bool,
        default=False,
    )
    add_config(
        parser,
        load,
        short_flag="-mcs",
        long_flag="--forts.max_circle_size",
        help="If avoid_circles flag is set, this flag specifies the maximum size of circles (pokestops) avoided",
        type=int,
        default=10,
    )
    add_config(
        parser,
        load,
        long_flag="--catch_randomize_reticle_factor",
        help="Randomize factor for pokeball throwing accuracy (DEFAULT 1.0 means no randomize: always 'Excellent' throw. 0.0 randomizes between normal and 'Excellent' throw)",
        type=float,
        default=1.0
    )
    add_config(
        parser,
        load,
        long_flag="--catch_randomize_spin_factor",
        help="Randomize factor for pokeball curve throwing (DEFAULT 1.0 means no randomize: always perfect 'Super Spin' curve ball. 0.0 randomizes between normal and 'Super Spin' curve ball)",
        type=float,
        default=1.0
    )
    add_config(
        parser,
        load,
        long_flag="--map_object_cache_time",
        help="Amount of seconds to keep the map object in cache (bypass Niantic throttling)",
        type=float,
        default=5.0
    )

    # Start to parse other attrs
    config = parser.parse_args()
    if not config.username and 'username' not in load:
        config.username = raw_input("Username: "******"Password: "******"--map_object_cache_time is out of range! (should be >= 0.0)")
        return None

    if len(config.raw_tasks) == 0:
        logging.error("No tasks are configured. Did you mean to configure some behaviors? Read https://github.com/PokemonGoF/PokemonGo-Bot/wiki/Configuration-files#configuring-tasks for more information")
        return None

    if config.auth_service not in ['ptc', 'google']:
        logging.error("Invalid Auth service specified! ('ptc' or 'google')")
        return None

    def task_configuration_error(flag_name):
        parser.error("""
            \"{}\" was removed from the configuration options.
            You can now change the behavior of the bot by modifying the \"tasks\" key.
            Read https://github.com/PokemonGoF/PokemonGo-Bot/wiki/Configuration-files#configuring-tasks for more information.
            """.format(flag_name))

    old_flags = ['mode', 'catch_pokemon', 'spin_forts', 'forts_spin', 'hatch_eggs', 'release_pokemon', 'softban_fix',
                'longer_eggs_first', 'evolve_speed', 'use_lucky_egg', 'item_filter', 'evolve_all', 'evolve_cp_min', 'max_steps']
    for flag in old_flags:
        if flag in load:
            task_configuration_error(flag)
            return None

    nested_old_flags = [('forts', 'spin'), ('forts', 'move_to_spin'), ('navigator', 'path_mode'), ('navigator', 'path_file'), ('navigator', 'type')]
    for outer, inner in nested_old_flags:
        if load.get(outer, {}).get(inner, None):
            task_configuration_error('{}.{}'.format(outer, inner))
            return None

    if (config.evolve_captured
        and (not isinstance(config.evolve_captured, str)
             or str(config.evolve_captured).lower() in ["true", "false"])):
        parser.error('"evolve_captured" should be list of pokemons: use "all" or "none" to match all ' +
                     'or none of the pokemons, or use a comma separated list such as "Pidgey,Weedle,Caterpie"')
        return None

    if not (config.location or config.location_cache):
        parser.error("Needs either --use-location-cache or --location.")
        return None

    if config.catch_randomize_reticle_factor < 0 or 1 < config.catch_randomize_reticle_factor:
        parser.error("--catch_randomize_reticle_factor is out of range! (should be 0 <= catch_randomize_reticle_factor <= 1)")
        return None

    if config.catch_randomize_spin_factor < 0 or 1 < config.catch_randomize_spin_factor:
        parser.error("--catch_randomize_spin_factor is out of range! (should be 0 <= catch_randomize_spin_factor <= 1)")
        return None

    plugin_loader = PluginLoader()
    for plugin in config.plugins:
        plugin_loader.load_path(plugin)

    # create web dir if not exists
    try:
        os.makedirs(web_dir)
    except OSError:
        if not os.path.isdir(web_dir):
            raise

    if config.evolve_captured and isinstance(config.evolve_captured, str):
        config.evolve_captured = [str(pokemon_name).strip() for pokemon_name in config.evolve_captured.split(',')]

    fix_nested_config(config)
    return config
 def __init__(self, bot, tasks_raw):
     self.bot = bot
     self.tasks_raw = tasks_raw
     self.plugin_loader = PluginLoader()
class TreeConfigBuilder(object):
    def __init__(self, bot, tasks_raw):
        self.bot = bot
        self.tasks_raw = tasks_raw
        self.plugin_loader = PluginLoader()

    def _get_worker_by_name(self, name):
        try:
            worker = getattr(cell_workers, name)
        except AttributeError:
            raise ConfigException('No worker named {} defined'.format(name))

        return worker

    def _is_plugin_task(self, name):
        return '.' in name

    def build(self):
        workers = []
        deprecated_pokemon_task = False

        for task in self.tasks_raw:
            task_type = task.get('type', None)
            if task_type is None:
                raise ConfigException('No type found for given task {}'.format(task))
            elif task_type == 'EvolveAll':
                raise ConfigException('The EvolveAll task has been renamed to EvolvePokemon')

            task_config = task.get('config', {})

            if task_type in ['CatchVisiblePokemon', 'CatchLuredPokemon']:
                if deprecated_pokemon_task:
                    continue
                else:
                    deprecated_pokemon_task = True
                    task_type = 'CatchPokemon'
                    task_config = {}
                    self.bot.logger.warning('The CatchVisiblePokemon & CatchLuredPokemon tasks have been replaced with '
                                            'CatchPokemon.  CatchPokemon has been enabled with default settings.')

            if task_type == 'SleepSchedule':
                self.bot.logger.warning('The SleepSchedule task was moved out of the task section. '
                                        'See config.json.*example for more information.')
                continue

            if self._is_plugin_task(task_type):
                worker = self.plugin_loader.get_class(task_type)
            else:
                worker = self._get_worker_by_name(task_type)

            error_string = ''
            if BaseTask.TASK_API_VERSION < worker.SUPPORTED_TASK_API_VERSION:
                error_string = 'Do you need to update the bot?'

            elif BaseTask.TASK_API_VERSION > worker.SUPPORTED_TASK_API_VERSION:
                error_string = 'Is there a new version of this task?'

            if error_string != '':
                raise MismatchTaskApiVersion(
                    'Task {} only works with task api version {}, you are currently running version {}. {}'
                    .format(
                        task_type,
                        worker.SUPPORTED_TASK_API_VERSION,
                        BaseTask.TASK_API_VERSION,
                        error_string
                    )
                )

            instance = worker(self.bot, task_config)
            if instance.enabled:
                workers.append(instance)

        return workers
Example #10
0
def init_config():
    parser = argparse.ArgumentParser()
    config_file = os.path.join(_base_dir, "configs", "config.json")
    web_dir = "web"

    # If config file exists, load variables from json
    load = {}

    def _json_loader(filename):
        try:
            with open(filename, "rb") as data:
                load.update(json.load(data))
        except ValueError:
            if jsonlint:
                with open(filename, "rb") as data:
                    lint = jsonlint()
                    rc = lint.main(["-v", filename])

            logger.critical("Error with configuration file")
            sys.exit(-1)

    # Select a config file code
    parser.add_argument("-cf", "--config", help="Config File to use")
    config_arg = parser.parse_known_args() and parser.parse_known_args()[0].config or None

    if config_arg and os.path.isfile(config_arg):
        _json_loader(config_arg)
    elif os.path.isfile(config_file):
        logger.info("No config argument specified, checking for /configs/config.json")
        _json_loader(config_file)
    else:
        logger.info("Error: No /configs/config.json or specified config")

    # Read passed in Arguments
    required = lambda x: not x in load
    add_config(
        parser,
        load,
        short_flag="-a",
        long_flag="--auth_service",
        help="Auth Service ('ptc' or 'google')",
        required=required("auth_service"),
        default=None,
    )
    add_config(parser, load, short_flag="-u", long_flag="--username", help="Username", default=None)
    add_config(
        parser,
        load,
        short_flag="-ws",
        long_flag="--websocket.server_url",
        help="Connect to websocket server at given url",
        default=False,
    )
    add_config(
        parser,
        load,
        short_flag="-wss",
        long_flag="--websocket.start_embedded_server",
        help="Start embedded websocket server",
        default=False,
    )
    add_config(
        parser,
        load,
        short_flag="-wsr",
        long_flag="--websocket.remote_control",
        help="Enable remote control through websocket (requires websocekt server url)",
        default=False,
    )
    add_config(parser, load, short_flag="-p", long_flag="--password", help="Password", default=None)
    add_config(
        parser, load, short_flag="-l", long_flag="--location", help="Location", type=parse_unicode_str, default=""
    )
    add_config(
        parser,
        load,
        short_flag="-lc",
        long_flag="--location_cache",
        help="Bot will start at last known location",
        type=bool,
        default=False,
    )
    add_config(parser, load, long_flag="--forts.spin", help="Enable Spinning Pokestops", type=bool, default=True)
    add_config(
        parser,
        load,
        short_flag="-wmax",
        long_flag="--walk_max",
        help="Walk instead of teleport with given speed",
        type=float,
        default=2.5,
    )
    add_config(
        parser,
        load,
        short_flag="-wmin",
        long_flag="--walk_min",
        help="Walk instead of teleport with given speed",
        type=float,
        default=2.5,
    )
    add_config(
        parser, load, short_flag="-k", long_flag="--gmapkey", help="Set Google Maps API KEY", type=str, default=None
    )
    add_config(parser, load, short_flag="-e", long_flag="--show_events", help="Show events", type=bool, default=False)
    add_config(parser, load, short_flag="-d", long_flag="--debug", help="Debug Mode", type=bool, default=False)
    add_config(
        parser,
        load,
        short_flag="-t",
        long_flag="--test",
        help="Only parse the specified location",
        type=bool,
        default=False,
    )
    add_config(
        parser,
        load,
        short_flag="-du",
        long_flag="--distance_unit",
        help="Set the unit to display distance in (e.g, km for kilometers, mi for miles, ft for feet)",
        type=str,
        default="km",
    )
    add_config(
        parser,
        load,
        short_flag="-rt",
        long_flag="--reconnecting_timeout",
        help="Timeout between reconnecting if error occured (in minutes, e.g. 15)",
        type=float,
        default=15.0,
    )
    add_config(
        parser,
        load,
        short_flag="-hr",
        long_flag="--health_record",
        help='Send anonymous bot event to GA for bot health record. Set "health_record":false if you need disable it.',
        type=bool,
        default=True,
    )
    add_config(
        parser,
        load,
        short_flag="-ac",
        long_flag="--forts.avoid_circles",
        help="Avoids circles (pokestops) of the max size set in max_circle_size flag",
        type=bool,
        default=False,
    )
    add_config(
        parser,
        load,
        short_flag="-mcs",
        long_flag="--forts.max_circle_size",
        help="If avoid_circles flag is set, this flag specifies the maximum size of circles (pokestops) avoided",
        type=int,
        default=10,
    )
    add_config(
        parser,
        load,
        short_flag="-crf",
        long_flag="--forts.cache_recent_forts",
        help="Caches recent forts used by max_circle_size",
        type=bool,
        default=True,
    )
    add_config(
        parser,
        load,
        long_flag="--map_object_cache_time",
        help="Amount of seconds to keep the map object in cache (bypass Niantic throttling)",
        type=float,
        default=5.0,
    )
    add_config(
        parser,
        load,
        long_flag="--logging_color",
        help="If logging_color is set to true, colorized logging handler will be used",
        type=bool,
        default=True,
    )
    add_config(
        parser,
        load,
        long_flag="--heartbeat_threshold",
        help="A threshold between each heartbeat sending to server",
        type=int,
        default=10,
    )
    # Start to parse other attrs
    config = parser.parse_args()
    if not config.username and "username" not in load:
        config.username = raw_input("Username: "******"password" not in load:
        config.password = getpass("Password: "******"encrypt_location", "")
    config.catch = load.get("catch", {})
    config.release = load.get("release", {})
    config.plugins = load.get("plugins", [])
    config.raw_tasks = load.get("tasks", [])

    config.vips = load.get("vips", {})

    if config.map_object_cache_time < 0.0:
        parser.error("--map_object_cache_time is out of range! (should be >= 0.0)")
        return None

    if len(config.raw_tasks) == 0:
        logging.error(
            "No tasks are configured. Did you mean to configure some behaviors? Read https://github.com/PokemonGoF/PokemonGo-Bot/wiki/Configuration-files#configuring-tasks for more information"
        )
        return None

    if config.auth_service not in ["ptc", "google"]:
        logging.error("Invalid Auth service specified! ('ptc' or 'google')")
        return None

    def task_configuration_error(flag_name):
        parser.error(
            """
            \"{}\" was removed from the configuration options.
            You can now change the behavior of the bot by modifying the \"tasks\" key.
            Read https://github.com/PokemonGoF/PokemonGo-Bot/wiki/Configuration-files#configuring-tasks for more information.
            """.format(
                flag_name
            )
        )

    old_flags = [
        "mode",
        "catch_pokemon",
        "spin_forts",
        "forts_spin",
        "hatch_eggs",
        "release_pokemon",
        "softban_fix",
        "longer_eggs_first",
        "evolve_speed",
        "use_lucky_egg",
        "item_filter",
        "evolve_all",
        "evolve_cp_min",
        "max_steps",
        "catch_throw_parameters.excellent_rate",
        "catch_throw_parameters.great_rate",
        "catch_throw_parameters.nice_rate",
        "catch_throw_parameters.normal_rate",
        "catch_throw_parameters.spin_success_rate",
    ]
    for flag in old_flags:
        if flag in load:
            task_configuration_error(flag)
            return None

    nested_old_flags = [
        ("forts", "spin"),
        ("forts", "move_to_spin"),
        ("navigator", "path_mode"),
        ("navigator", "path_file"),
        ("navigator", "type"),
    ]
    for outer, inner in nested_old_flags:
        if load.get(outer, {}).get(inner, None):
            task_configuration_error("{}.{}".format(outer, inner))
            return None

    if "evolve_captured" in load:
        logger.warning("The evolve_captured argument is no longer supported. Please use the EvolvePokemon task instead")

    if "walk" in load:
        logger.warning(
            "The walk argument is no longer supported. Please use the walk_max and walk_min variables instead"
        )

    if not (config.location or config.location_cache):
        parser.error("Needs either --use-location-cache or --location.")
        return None

    plugin_loader = PluginLoader()
    for plugin in config.plugins:
        plugin_loader.load_plugin(plugin)

    # create web dir if not exists
    try:
        os.makedirs(web_dir)
    except OSError:
        if not os.path.isdir(web_dir):
            raise

    fix_nested_config(config)
    return config
Example #11
0
 def setUp(self):
     self.plugin_loader = PluginLoader()
Example #12
0
class PluginLoaderTest(unittest.TestCase):
    def setUp(self):
        self.plugin_loader = PluginLoader()

    def test_load_namespace_class(self):
        package_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'resources', 'plugin_fixture')
        self.plugin_loader.load_plugin(package_path)
        loaded_class = self.plugin_loader.get_class('plugin_fixture.FakeTask')
        self.assertEqual(loaded_class({}, {}).work(), 'FakeTask')
        self.plugin_loader.remove_path(package_path)

    def test_load_zip(self):
        package_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'resources', 'plugin_fixture_test.zip')
        self.plugin_loader.load_plugin(package_path)
        loaded_class = self.plugin_loader.get_class('plugin_fixture_test.FakeTask')
        self.assertEqual(loaded_class({}, {}).work(), 'FakeTaskZip')
        self.plugin_loader.remove_path(package_path)

    def copy_plugin(self):
        package_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'resources', 'plugin_fixture')
        dest_path = os.path.join(PLUGIN_PATH, 'org_repo', 'plugin_fixture_tests')
        shutil.copytree(package_path, os.path.join(dest_path))
        with open(os.path.join(os.path.dirname(dest_path), '.sha'), 'w') as file:
            file.write('testsha')
        return dest_path

    def test_load_github_already_downloaded(self):
        dest_path = self.copy_plugin()
        self.plugin_loader.load_plugin('org/repo#testsha')
        loaded_class = self.plugin_loader.get_class('plugin_fixture_tests.FakeTask')
        self.assertEqual(loaded_class({}, {}).work(), 'FakeTask')
        self.plugin_loader.remove_path(dest_path)
        shutil.rmtree(os.path.dirname(dest_path))

    def copy_zip(self):
        zip_name = 'test-pgo-plugin-2d54eddde33061be9b329efae0cfb9bd58842655.zip'
        fixture_zip = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'resources', zip_name)
        zip_dest = os.path.join(PLUGIN_PATH, 'org_test-pgo-plugin_2d54eddde33061be9b329efae0cfb9bd58842655.zip')
        shutil.copyfile(fixture_zip, zip_dest)

    @mock.patch.object(GithubPlugin, 'download', copy_zip)
    def test_load_github_not_downloaded(self):
        self.plugin_loader.load_plugin('org/test-pgo-plugin#2d54eddde33061be9b329efae0cfb9bd58842655')
        loaded_class = self.plugin_loader.get_class('test-pgo-plugin.PrintText')
        self.assertEqual(loaded_class({}, {}).work(), 'PrintText')
        dest_path = os.path.join(PLUGIN_PATH, 'org_test-pgo-plugin')
        self.plugin_loader.remove_path(os.path.join(dest_path, 'test-pgo-plugin'))
        shutil.rmtree(dest_path)