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
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
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()
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
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
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)