Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly tracking inventory changes to the cached inventory #3860

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pokemongo_bot/cell_workers/recycle_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ def work(self):

if self.item_should_be_recycled(item_in_inventory, amount_to_recycle):
action_delay(self.bot.config.action_wait_min, self.bot.config.action_wait_max)
if ItemRecycler(self.bot, item_in_inventory, amount_to_recycle).work() == WorkerResult.ERROR:
# If at any recycling process call we got an error consider that the result of this task is error too.
if item_in_inventory.recycle(amount_to_recycle) == WorkerResult.ERROR:
worker_result = WorkerResult.ERROR

return worker_result
Expand Down
115 changes: 115 additions & 0 deletions pokemongo_bot/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from collections import OrderedDict

from pokemongo_bot.base_dir import _base_dir
from pokemongo_bot.services.item_recycle_worker import ItemRecycler

'''
Helper class for updating/retrieving Inventory data
Expand Down Expand Up @@ -108,16 +109,59 @@ def captured(self, pokemon_id):

class Item(object):
def __init__(self, item_id, item_count):
"""
Representation of an item
:param item_id: ID of the item
:type item_id: int
:param item_count: Quantity of the item
:type item_count: int
:return: An item
:rtype: Item
"""
self.id = item_id
self.name = Items.name_for(self.id)
self.count = item_count

def remove(self, amount):
"""
Remove a specified amount of an item from the cached inventory.
Note that it does **NOT** removes it in the server, it only removes it in cached inventory.
:param amount: Amount to remove
:type amount: int
:return: Nothing
:rtype: None
"""
if self.count < amount:
raise Exception('Tried to remove more {} than you have'.format(self.name))
self.count -= amount

def recycle(self, amount_to_recycle):
"""
Recycle (discard) the specified amount of item from the item inventory.
It is making a call to the server to request a recycling as well as updating the cached inventory.
:param amount_to_recycle: The amount to recycle.
:type amount_to_recycle: int
:return: Returns wether or not the task went well
:rtype: worker_result.WorkerResult
"""
if self.count < amount_to_recycle:
raise Exception('Tried to remove more {} than you have'.format(self.name))

item_recycler = ItemRecycler(_inventory.bot, self, amount_to_recycle)
item_recycler_work_result = item_recycler.work()

if item_recycler.is_recycling_success():
self.remove(amount_to_recycle)
return item_recycler_work_result

def add(self, amount):
"""
Add a specified amount of the item to the cached inventory
:param amount: Amount to add
:type amount: int
:return: Nothing.
:rtype: None
"""
if amount < 0:
raise Exception('Must add positive amount of {}'.format(self.name))
self.count += amount
Expand All @@ -132,15 +176,41 @@ class Items(_BaseInventoryComponent):
STATIC_DATA_FILE = os.path.join(_base_dir, 'data', 'items.json')

def parse(self, item_data):
"""
Make an instance of an Item from raw item data.
:param item_data: Item data to make an item from
:return: Instance of the Item.
:rtype: Item
"""
item_id = item_data.get(Items.ID_FIELD, None)
item_count = item_data['count'] if 'count' in item_data else 0
return Item(item_id, item_count)

def all(self):
"""
Get EVERY Item from the cached inventory.
:return: List of evey item in the cached inventory
:rtype: list of Item
"""
return list(self._data.values())

def get(self, item_id):
"""
Get ONE Item from the cached inventory.
:param item_id: Item's ID to search for.
:return: Instance of the item from the cached inventory
:rtype: Item
"""
return self._data.setdefault(item_id, Item(item_id, 0))

@classmethod
def name_for(cls, item_id):
"""
Search the name for an item from its ID.
:param item_id: Item's ID to search for.
:return: Item's name.
:rtype: str
"""
return cls.STATIC_DATA[str(item_id)]

@classmethod
Expand Down Expand Up @@ -1094,6 +1164,9 @@ def _calc_cp(base_attack, base_defense, base_stamina,
#
# Usage helpers

# TODO : Complete the doc
# Only type return have been filled for now. It helps the IDE to suggest methods of the class.

def init_inventory(bot):
global _inventory
_inventory = Inventory(bot)
Expand All @@ -1103,20 +1176,42 @@ def refresh_inventory():
_inventory.refresh()

def get_item_inventory_size():
"""

:return: Item inventory size
:rtype: int
"""
_inventory.retrieve_item_inventory_size()
return _inventory.item_inventory_size

def pokedex():
"""

:return:
:rtype: Pokedex
"""
return _inventory.pokedex


def candies(refresh=False):
"""

:param refresh:
:return:
:rtype: Candies
"""
if refresh:
refresh_inventory()
return _inventory.candy


def pokemons(refresh=False):
"""

:param refresh:
:return:
:rtype: Pokemons
"""
if refresh:
refresh_inventory()
return _inventory.pokemons
Expand All @@ -1132,16 +1227,36 @@ def items():


def types_data():
"""

:return:
:rtype: Types
"""
return Types


def levels_to_cpm():
"""

:return:
:rtype: LevelToCPm
"""
return LevelToCPm


def fast_attacks():
"""

:return:
:rtype: FastAttacks
"""
return FastAttacks


def charged_attacks():
"""

:return:
:rtype: ChargedAttack
"""
return ChargedAttacks
24 changes: 12 additions & 12 deletions pokemongo_bot/services/item_recycle_worker.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from pokemongo_bot.worker_result import WorkerResult
from pokemongo_bot.base_task import BaseTask
from pokemongo_bot import inventory
from pokemongo_bot.tree_config_builder import ConfigException

RECYCLE_REQUEST_RESPONSE_SUCCESS = 1
Expand All @@ -13,8 +12,9 @@ def __init__(self, bot, item_to_recycle, amount_to_recycle):
"""
Initialise an instance of ItemRecycler
:param bot: The instance of the Bot
:type bot: pokemongo_bot.PokemonGoBot
:param item_to_recycle: The item to recycle
:type item_to_recycle: Item
:type item_to_recycle: inventory.Item
:param amount_to_recycle: The amount to recycle
:type amount_to_recycle: int
:return: Nothing.
Expand All @@ -32,9 +32,9 @@ def work(self):
:rtype: WorkerResult
"""
if self.should_run():
self.request_recycle()
self._request_recycle()
if self.is_recycling_success():
self._update_inventory()
#self._update_inventory()
self._emit_recycle_succeed()
return WorkerResult.SUCCESS
else:
Expand All @@ -51,7 +51,7 @@ def should_run(self):
return True
return False

def request_recycle(self):
def _request_recycle(self):
"""
Request recycling of the item and store api call response's result.
:return: Nothing.
Expand All @@ -63,13 +63,13 @@ def request_recycle(self):
# {'responses': {'RECYCLE_INVENTORY_ITEM': {'result': 1, 'new_count': 46}}, 'status_code': 1, 'auth_ticket': {'expire_timestamp_ms': 1469306228058L, 'start': '/HycFyfrT4t2yB2Ij+yoi+on778aymMgxY6RQgvrGAfQlNzRuIjpcnDd5dAxmfoTqDQrbz1m2dGqAIhJ+eFapg==', 'end': 'f5NOZ95a843tgzprJo4W7Q=='}, 'request_id': 8145806132888207460L}
self.recycle_item_request_result = response.get('responses', {}).get('RECYCLE_INVENTORY_ITEM', {}).get('result', 0)

def _update_inventory(self):
"""
Updates the inventory. Prevent an unnecessary call to the api
:return: Nothing.
:rtype: None
"""
inventory.items().get(self.item_to_recycle.id).remove(self.amount_to_recycle)
# def _update_inventory(self):
# """
# Updates the inventory. Prevent an unnecessary call to the api
# :return: Nothing.
# :rtype: None
# """
# inventory.items().get(self.item_to_recycle.id).remove(self.amount_to_recycle)

def is_recycling_success(self):
"""
Expand Down