diff --git a/pokemongo_bot/__init__.py b/pokemongo_bot/__init__.py index 8fa4e8247a..c31c1085b3 100644 --- a/pokemongo_bot/__init__.py +++ b/pokemongo_bot/__init__.py @@ -27,7 +27,7 @@ from pokemongo_bot.socketio_server.runner import SocketIoRunner from pokemongo_bot.websocket_remote_control import WebsocketRemoteControl from worker_result import WorkerResult -from tree_config_builder import ConfigException, TreeConfigBuilder +from tree_config_builder import ConfigException, MismatchTaskApiVersion, TreeConfigBuilder class PokemonGoBot(object): diff --git a/pokemongo_bot/base_task.py b/pokemongo_bot/base_task.py index ac48b9a676..22bbedf4e8 100644 --- a/pokemongo_bot/base_task.py +++ b/pokemongo_bot/base_task.py @@ -2,6 +2,7 @@ class BaseTask(object): + TASK_API_VERSION = 1 def __init__(self, bot, config): self.bot = bot diff --git a/pokemongo_bot/cell_workers/catch_lured_pokemon.py b/pokemongo_bot/cell_workers/catch_lured_pokemon.py index 8da2eae36a..c0e9283b82 100644 --- a/pokemongo_bot/cell_workers/catch_lured_pokemon.py +++ b/pokemongo_bot/cell_workers/catch_lured_pokemon.py @@ -7,6 +7,8 @@ class CatchLuredPokemon(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + def work(self): lured_pokemon = self.get_lured_pokemon() if lured_pokemon: diff --git a/pokemongo_bot/cell_workers/catch_visible_pokemon.py b/pokemongo_bot/cell_workers/catch_visible_pokemon.py index 6ddb5a06d0..102d6c01c8 100644 --- a/pokemongo_bot/cell_workers/catch_visible_pokemon.py +++ b/pokemongo_bot/cell_workers/catch_visible_pokemon.py @@ -6,6 +6,8 @@ class CatchVisiblePokemon(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + def work(self): if 'catchable_pokemons' in self.bot.cell and len(self.bot.cell['catchable_pokemons']) > 0: # Sort all by distance from current pos- eventually this should diff --git a/pokemongo_bot/cell_workers/collect_level_up_reward.py b/pokemongo_bot/cell_workers/collect_level_up_reward.py index fd74acf6eb..950f450660 100644 --- a/pokemongo_bot/cell_workers/collect_level_up_reward.py +++ b/pokemongo_bot/cell_workers/collect_level_up_reward.py @@ -2,6 +2,8 @@ class CollectLevelUpReward(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + current_level = 0 previous_level = 0 diff --git a/pokemongo_bot/cell_workers/evolve_pokemon.py b/pokemongo_bot/cell_workers/evolve_pokemon.py index 1f1a19e1e3..74eb0abf79 100644 --- a/pokemongo_bot/cell_workers/evolve_pokemon.py +++ b/pokemongo_bot/cell_workers/evolve_pokemon.py @@ -4,6 +4,7 @@ class EvolvePokemon(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 def initialize(self): self.api = self.bot.api diff --git a/pokemongo_bot/cell_workers/follow_cluster.py b/pokemongo_bot/cell_workers/follow_cluster.py index 26fbd6ace9..8448fcf742 100644 --- a/pokemongo_bot/cell_workers/follow_cluster.py +++ b/pokemongo_bot/cell_workers/follow_cluster.py @@ -4,6 +4,7 @@ from pokemongo_bot.base_task import BaseTask class FollowCluster(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 def initialize(self): self.is_at_destination = False diff --git a/pokemongo_bot/cell_workers/follow_path.py b/pokemongo_bot/cell_workers/follow_path.py index 7219bb98a6..6e183ed1d7 100644 --- a/pokemongo_bot/cell_workers/follow_path.py +++ b/pokemongo_bot/cell_workers/follow_path.py @@ -11,6 +11,8 @@ class FollowPath(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + def initialize(self): self.ptr = 0 self._process_config() diff --git a/pokemongo_bot/cell_workers/follow_spiral.py b/pokemongo_bot/cell_workers/follow_spiral.py index 9b7781aeca..f175369e45 100644 --- a/pokemongo_bot/cell_workers/follow_spiral.py +++ b/pokemongo_bot/cell_workers/follow_spiral.py @@ -8,6 +8,8 @@ from pokemongo_bot.base_task import BaseTask class FollowSpiral(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + def initialize(self): self.steplimit = self.config.get("diameter", 4) self.step_size = self.config.get("step_size", 70) diff --git a/pokemongo_bot/cell_workers/handle_soft_ban.py b/pokemongo_bot/cell_workers/handle_soft_ban.py index d00679d2ec..8018b7c33e 100644 --- a/pokemongo_bot/cell_workers/handle_soft_ban.py +++ b/pokemongo_bot/cell_workers/handle_soft_ban.py @@ -10,6 +10,8 @@ class HandleSoftBan(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + def work(self): if not self.should_run(): return diff --git a/pokemongo_bot/cell_workers/incubate_eggs.py b/pokemongo_bot/cell_workers/incubate_eggs.py index c49a7f07e2..5761090ea5 100644 --- a/pokemongo_bot/cell_workers/incubate_eggs.py +++ b/pokemongo_bot/cell_workers/incubate_eggs.py @@ -3,6 +3,8 @@ class IncubateEggs(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + last_km_walked = 0 def initialize(self): diff --git a/pokemongo_bot/cell_workers/move_to_fort.py b/pokemongo_bot/cell_workers/move_to_fort.py index 25d4e91490..e4b4187d20 100644 --- a/pokemongo_bot/cell_workers/move_to_fort.py +++ b/pokemongo_bot/cell_workers/move_to_fort.py @@ -9,6 +9,7 @@ class MoveToFort(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 def initialize(self): self.lure_distance = 0 diff --git a/pokemongo_bot/cell_workers/move_to_map_pokemon.py b/pokemongo_bot/cell_workers/move_to_map_pokemon.py index 7a7dfb9f38..08ff35f281 100644 --- a/pokemongo_bot/cell_workers/move_to_map_pokemon.py +++ b/pokemongo_bot/cell_workers/move_to_map_pokemon.py @@ -14,6 +14,8 @@ class MoveToMapPokemon(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + def initialize(self): self.last_map_update = 0 self.pokemon_data = self.bot.pokemon_list diff --git a/pokemongo_bot/cell_workers/nickname_pokemon.py b/pokemongo_bot/cell_workers/nickname_pokemon.py index f344ba1ac5..cda206ad20 100644 --- a/pokemongo_bot/cell_workers/nickname_pokemon.py +++ b/pokemongo_bot/cell_workers/nickname_pokemon.py @@ -2,6 +2,8 @@ from pokemongo_bot.base_task import BaseTask class NicknamePokemon(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + def initialize(self): self.template = self.config.get('nickname_template','').lower().strip() if self.template == "{name}": diff --git a/pokemongo_bot/cell_workers/recycle_items.py b/pokemongo_bot/cell_workers/recycle_items.py index 7c58111d69..2c969913b0 100644 --- a/pokemongo_bot/cell_workers/recycle_items.py +++ b/pokemongo_bot/cell_workers/recycle_items.py @@ -4,6 +4,8 @@ from pokemongo_bot.tree_config_builder import ConfigException class RecycleItems(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + def initialize(self): self.item_filter = self.config.get('item_filter', {}) self._validate_item_filter() diff --git a/pokemongo_bot/cell_workers/sleep_schedule.py b/pokemongo_bot/cell_workers/sleep_schedule.py index 81d1642d9b..5a7d617e23 100644 --- a/pokemongo_bot/cell_workers/sleep_schedule.py +++ b/pokemongo_bot/cell_workers/sleep_schedule.py @@ -27,6 +27,7 @@ class SleepSchedule(BaseTask): duration_random_offset: (HH:MM) random offset of duration of sleep for this example the possible duration is 5:00-6:00 """ + SUPPORTED_TASK_API_VERSION = 1 LOG_INTERVAL_SECONDS = 600 SCHEDULING_MARGIN = timedelta(minutes=10) # Skip if next sleep is RESCHEDULING_MARGIN from now diff --git a/pokemongo_bot/cell_workers/spin_fort.py b/pokemongo_bot/cell_workers/spin_fort.py index 2bd8b49c87..e04a86dbc6 100644 --- a/pokemongo_bot/cell_workers/spin_fort.py +++ b/pokemongo_bot/cell_workers/spin_fort.py @@ -13,6 +13,8 @@ class SpinFort(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + def should_run(self): if not self.bot.has_space_for_loot(): self.emit_event( diff --git a/pokemongo_bot/cell_workers/transfer_pokemon.py b/pokemongo_bot/cell_workers/transfer_pokemon.py index f815768558..c48e17b20d 100644 --- a/pokemongo_bot/cell_workers/transfer_pokemon.py +++ b/pokemongo_bot/cell_workers/transfer_pokemon.py @@ -5,6 +5,8 @@ class TransferPokemon(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + def work(self): pokemon_groups = self._release_pokemon_get_groups() for pokemon_id in pokemon_groups: diff --git a/pokemongo_bot/cell_workers/update_title_stats.py b/pokemongo_bot/cell_workers/update_title_stats.py index 13b80fc11a..1f9b2a0e9b 100644 --- a/pokemongo_bot/cell_workers/update_title_stats.py +++ b/pokemongo_bot/cell_workers/update_title_stats.py @@ -49,6 +49,7 @@ class UpdateTitleStats(BaseTask): stats : An array of stats to display and their display order (implicitly), see available stats above. """ + SUPPORTED_TASK_API_VERSION = 1 DEFAULT_MIN_INTERVAL = 10 DEFAULT_DISPLAYED_STATS = [] diff --git a/pokemongo_bot/test/resources/plugin_fixture/__init__.py b/pokemongo_bot/test/resources/plugin_fixture/__init__.py index 647158bf44..57caf83dce 100644 --- a/pokemongo_bot/test/resources/plugin_fixture/__init__.py +++ b/pokemongo_bot/test/resources/plugin_fixture/__init__.py @@ -1 +1,2 @@ from fake_task import FakeTask +from unsupported_api_task import UnsupportedApiTask diff --git a/pokemongo_bot/test/resources/plugin_fixture/fake_task.py b/pokemongo_bot/test/resources/plugin_fixture/fake_task.py index 0965b1ffe6..ff729adee4 100644 --- a/pokemongo_bot/test/resources/plugin_fixture/fake_task.py +++ b/pokemongo_bot/test/resources/plugin_fixture/fake_task.py @@ -1,5 +1,7 @@ from pokemongo_bot.base_task import BaseTask class FakeTask(BaseTask): + SUPPORTED_TASK_API_VERSION = 1 + def work(self): return 'FakeTask' diff --git a/pokemongo_bot/test/resources/plugin_fixture/unsupported_api_task.py b/pokemongo_bot/test/resources/plugin_fixture/unsupported_api_task.py new file mode 100644 index 0000000000..871e38f82d --- /dev/null +++ b/pokemongo_bot/test/resources/plugin_fixture/unsupported_api_task.py @@ -0,0 +1,7 @@ +from pokemongo_bot.base_task import BaseTask + +class UnsupportedApiTask(BaseTask): + SUPPORTED_TASK_API_VERSION = 2 + + def work(): + return 2 diff --git a/pokemongo_bot/tree_config_builder.py b/pokemongo_bot/tree_config_builder.py index ce62c7fc61..6242747b25 100644 --- a/pokemongo_bot/tree_config_builder.py +++ b/pokemongo_bot/tree_config_builder.py @@ -1,9 +1,13 @@ import cell_workers from pokemongo_bot.plugin_loader import PluginLoader +from pokemongo_bot.base_task import BaseTask class ConfigException(Exception): pass +class MismatchTaskApiVersion(Exception): + pass + class TreeConfigBuilder(object): def __init__(self, bot, tasks_raw): self.bot = bot @@ -38,6 +42,24 @@ def build(self): 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) diff --git a/tests/tree_config_builder_test.py b/tests/tree_config_builder_test.py index fd1ca0d00e..cd8bed22e0 100644 --- a/tests/tree_config_builder_test.py +++ b/tests/tree_config_builder_test.py @@ -1,9 +1,9 @@ import unittest import json import os -from pokemongo_bot import PokemonGoBot, ConfigException, TreeConfigBuilder, PluginLoader +from pokemongo_bot import PokemonGoBot, ConfigException, MismatchTaskApiVersion, TreeConfigBuilder, PluginLoader, BaseTask from pokemongo_bot.cell_workers import HandleSoftBan, CatchLuredPokemon -from pokemongo_bot.test.resources.plugin_fixture import FakeTask +from pokemongo_bot.test.resources.plugin_fixture import FakeTask, UnsupportedApiTask def convert_from_json(str): return json.loads(str) @@ -99,3 +99,40 @@ def test_load_plugin_task(self): tree = builder.build() result = tree[0].work() self.assertEqual(result, 'FakeTask') + + def setupUnsupportedBuilder(self): + package_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), '..', 'pokemongo_bot', 'test', 'resources', 'plugin_fixture') + plugin_loader = PluginLoader() + plugin_loader.load_path(package_path) + + obj = convert_from_json("""[{ + "type": "plugin_fixture.UnsupportedApiTask" + }]""") + + return TreeConfigBuilder(self.bot, obj) + + def test_task_version_too_high(self): + builder = self.setupUnsupportedBuilder() + + previous_version = BaseTask.TASK_API_VERSION + BaseTask.TASK_API_VERSION = 1 + + self.assertRaisesRegexp( + MismatchTaskApiVersion, + "Task plugin_fixture.UnsupportedApiTask only works with task api version 2, you are currently running version 1. Do you need to update the bot?", + builder.build) + + BaseTask.TASK_API_VERSION = previous_version + + def test_task_version_too_low(self): + builder = self.setupUnsupportedBuilder() + + previous_version = BaseTask.TASK_API_VERSION + BaseTask.TASK_API_VERSION = 3 + + self.assertRaisesRegexp( + MismatchTaskApiVersion, + "Task plugin_fixture.UnsupportedApiTask only works with task api version 2, you are currently running version 3. Is there a new version of this task?", + builder.build) + + BaseTask.TASK_API_VERSION = previous_version