diff --git a/erepublik/citizen.py b/erepublik/citizen.py index d4e8aa7..2625480 100644 --- a/erepublik/citizen.py +++ b/erepublik/citizen.py @@ -17,6 +17,10 @@ class BaseCitizen(CitizenAPI): __last_full_update: datetime = utils.now().min promos: Dict[str, datetime] = None + inventory: Dict[str, int] = {'used': 0, 'total': 0} + boosters: Dict[int, Dict[int, int]] = {50: {}, 100: {}} + ot_points: int = 0 + food: Dict[str, int] = {"q1": 0, "q2": 0, "q3": 0, "q4": 0, "q5": 0, "q6": 0, "q7": 0, "total": 0} eb_normal = 0 eb_double = 0 @@ -239,6 +243,146 @@ class BaseCitizen(CitizenAPI): self.politics.is_party_president = bool(party.get('is_party_president')) self.politics.party_slug = f"{party.get('stripped_title')}-{party.get('party_id')}" + def update_inventory(self) -> Dict[str, Any]: + """ + Updates class properties and returns structured inventory. + Return structure: {status: {used: int, total: int}, items: {active/final/raw: {item_token:{quality: data}}} + If item kind is damageBoosters or aircraftDamageBoosters then kind is renamed to kind+quality and duration is + used as quality. + :return: dict + """ + self.food.update({"q1": 0, "q2": 0, "q3": 0, "q4": 0, "q5": 0, "q6": 0, "q7": 0}) + self.eb_small = self.eb_double = self.eb_normal = 0 + + j = self._get_economy_inventory_items().json() + active_items = {} + if j.get("inventoryItems", {}).get("activeEnhancements", {}).get("items", {}): + for item in j.get("inventoryItems", {}).get("activeEnhancements", {}).get("items", {}).values(): + if item.get('token'): + kind = re.sub(r'_q\d\d*', "", item.get('token')) + else: + kind = item.get('type') + if kind not in active_items: + active_items[kind] = {} + icon = item['icon'] if item['icon'] else "//www.erepublik.net/images/modules/manager/tab_storage.png" + item_data = dict(name=item.get("name"), time_left=item['active']['time_left'], icon=icon, kind=kind, + quality=item.get("quality", 0)) + + if item.get('isPackBooster'): + active_items[kind].update({0: item_data}) + else: + active_items[kind].update({item.get("quality"): item_data}) + + final_items = {} + for item in j.get("inventoryItems", {}).get("finalProducts", {}).get("items", {}).values(): + name = item['name'] + + if item.get('type'): + if item.get('type') in ['damageBoosters', "aircraftDamageBoosters"]: + kind = f"{item['type']}{item['quality']}" + if item['quality'] == 5: + self.boosters[50].update({item['duration']: item['amount']}) + elif item['quality'] == 10: + self.boosters[100].update({item['duration']: item['amount']}) + + delta = item['duration'] + if delta // 3600: + name += f" {delta // 3600}h" + if delta // 60 % 60: + name += f" {delta // 60 % 60}m" + if delta % 60: + name += f" {delta % 60}s" + else: + kind = item.get('type') + else: + if item['industryId'] == 1: + amount = item['amount'] + q = item['quality'] + if 1 <= q <= 7: + self.food.update({f"q{q}": amount}) + else: + if q == 10: + self.eb_normal = amount + elif q == 11: + self.eb_double = amount + elif q == 13: + self.eb_small += amount + elif q == 14: + self.eb_small += amount + elif q == 15: + self.eb_small += amount + kind = re.sub(r'_q\d\d*', "", item.get('token')) + + if item.get('token', "") == "house_q100": + self.ot_points = item['amount'] + + if kind not in final_items: + final_items[kind] = {} + + if item['icon']: + icon = item['icon'] + else: + if item['type'] == 'damageBoosters': + icon = "/images/modules/pvp/damage_boosters/damage_booster.png" + elif item['type'] == 'aircraftDamageBoosters': + icon = "/images/modules/pvp/damage_boosters/air_damage_booster.png" + elif item['type'] == 'prestigePointsBoosters': + icon = "/images/modules/pvp/prestige_points_boosters/prestige_booster.png" + elif item['type'] == 'speedBoosters': + icon = "/images/modules/pvp/speed_boosters/speed_booster.png" + elif item['type'] == 'catchupBoosters': + icon = "/images/modules/pvp/ghost_boosters/icon_booster_30_60.png" + else: + icon = "//www.erepublik.net/images/modules/manager/tab_storage.png" + data = dict(kind=kind, quality=item.get('quality', 0), amount=item.get('amount', 0), + durability=item.get('duration', 0), icon=icon, name=name) + if item.get('type') in ('damageBoosters', "aircraftDamageBoosters"): + data = {data['durability']: data} + else: + data = {data['quality']: data} + final_items[kind].update(data) + + raw_materials = {} + if j.get("inventoryItems", {}).get("rawMaterials", {}).get("items", {}): + for item in j.get("inventoryItems", {}).get("rawMaterials", {}).get("items", {}).values(): + if item['isPartial']: + continue + kind = re.sub(r'_q\d\d*', "", item.get('token')) + if kind == "magnesium": + kind = "raw_aircraft" + elif kind == "sand": + kind = "raw_house" + if kind not in raw_materials: + raw_materials[kind] = [] + if item['icon'].startswith('//www.erepublik.net/'): + icon = item['icon'] + else: + icon = "//www.erepublik.net/" + item['icon'] + + raw_materials[kind].append( + dict(name=item.get("name"), amount=item['amount'] + (item.get('underCostruction', 0) / 100), + icon=icon) + ) + + offers = {} + for offer in self._get_economy_my_market_offers().json(): + kind = self.get_industry_name(offer['industryId']) + data = dict(quality=offer.get('quality', 0), amount=offer.get('amount', 0), icon=offer.get('icon'), + kind=kind, name=kind) + data = {data['quality']: data} + + if kind not in offers: + offers[kind] = {} + + offers[kind].update(data) + + self.inventory.update({"used": j.get("inventoryStatus").get("usedStorage"), + "total": j.get("inventoryStatus").get("totalStorage")}) + inventory = dict(items=dict(active=active_items, final=final_items, + raw=raw_materials, offers=offers), status=self.inventory) + self.food["total"] = sum([self.food[q] * utils.FOOD_ENERGY[q] for q in utils.FOOD_ENERGY]) + return inventory + def _check_response_for_medals(self, html: str): new_medals = re.findall(r'(
.*?
\s*
)', html, re.M | re.S | re.I) @@ -447,6 +591,26 @@ class BaseCitizen(CitizenAPI): self.energy.recoverable = r_json.get("food_remaining") return response + def get_industry_id(self, industry_name: str) -> int: + """Returns industry id + + :type industry_name: str + :return: int + """ + return self.available_industries.get(industry_name, 0) + + def get_industry_name(self, industry_id: int) -> str: + """Returns industry name from industry ID + + :type industry_id: int + :return: industry name + :rtype: str + """ + for iname, iid in self.available_industries.items(): + if iid == industry_id: + return iname + return "" + class CitizenTravel(BaseCitizen): def _update_citizen_location(self, country_id: int, region_id: int): @@ -691,143 +855,6 @@ class CitizenEconomy(CitizenTravel): super().__init__() self.my_companies = MyCompanies() - def update_inventory(self) -> Dict[str, Any]: - """ - Updates class properties and returns structured inventory. - Return structure: {status: {used: int, total: int}, items: {active/final/raw: {item_token:{quality: data}}} - If item kind is damageBoosters or aircraftDamageBoosters then kind is renamed to kind+quality and duration is - used as quality. - :return: dict - """ - self.food.update({"q1": 0, "q2": 0, "q3": 0, "q4": 0, "q5": 0, "q6": 0, "q7": 0}) - self.eb_small = self.eb_double = self.eb_normal = 0 - - j = self._get_economy_inventory_items().json() - active_items = {} - if j.get("inventoryItems", {}).get("activeEnhancements", {}).get("items", {}): - for item in j.get("inventoryItems", {}).get("activeEnhancements", {}).get("items", {}).values(): - if item.get('token'): - kind = re.sub(r'_q\d\d*', "", item.get('token')) - else: - kind = item.get('type') - if kind not in active_items: - active_items[kind] = {} - icon = item['icon'] if item['icon'] else "//www.erepublik.net/images/modules/manager/tab_storage.png" - item_data = dict(name=item.get("name"), time_left=item['active']['time_left'], icon=icon, kind=kind, - quality=item.get("quality", 0)) - - if item.get('isPackBooster'): - active_items[kind].update({0: item_data}) - else: - active_items[kind].update({item.get("quality"): item_data}) - - final_items = {} - for item in j.get("inventoryItems", {}).get("finalProducts", {}).get("items", {}).values(): - name = item['name'] - - if item.get('type'): - if item.get('type') in ['damageBoosters', "aircraftDamageBoosters"]: - kind = f"{item['type']}{item['quality']}" - if item['quality'] == 5: - self.boosters[50].update({item['duration']: item['amount']}) - elif item['quality'] == 10: - self.boosters[100].update({item['duration']: item['amount']}) - - delta = item['duration'] - if delta // 3600: - name += f" {delta // 3600}h" - if delta // 60 % 60: - name += f" {delta // 60 % 60}m" - if delta % 60: - name += f" {delta % 60}s" - else: - kind = item.get('type') - else: - if item['industryId'] == 1: - amount = item['amount'] - q = item['quality'] - if 1 <= q <= 7: - self.food.update({f"q{q}": amount}) - else: - if q == 10: - self.eb_normal = amount - elif q == 11: - self.eb_double = amount - elif q == 13: - self.eb_small += amount - elif q == 14: - self.eb_small += amount - elif q == 15: - self.eb_small += amount - kind = re.sub(r'_q\d\d*', "", item.get('token')) - - if item.get('token', "") == "house_q100": - self.ot_points = item['amount'] - - if kind not in final_items: - final_items[kind] = {} - - if item['icon']: - icon = item['icon'] - else: - if item['type'] == 'damageBoosters': - icon = "/images/modules/pvp/damage_boosters/damage_booster.png" - elif item['type'] == 'aircraftDamageBoosters': - icon = "/images/modules/pvp/damage_boosters/air_damage_booster.png" - elif item['type'] == 'prestigePointsBoosters': - icon = "/images/modules/pvp/prestige_points_boosters/prestige_booster.png" - elif item['type'] == 'speedBoosters': - icon = "/images/modules/pvp/speed_boosters/speed_booster.png" - elif item['type'] == 'catchupBoosters': - icon = "/images/modules/pvp/ghost_boosters/icon_booster_30_60.png" - else: - icon = "//www.erepublik.net/images/modules/manager/tab_storage.png" - data = dict(kind=kind, quality=item.get('quality', 0), amount=item.get('amount', 0), - durability=item.get('duration', 0), icon=icon, name=name) - if item.get('type') in ('damageBoosters', "aircraftDamageBoosters"): - data = {data['durability']: data} - else: - data = {data['quality']: data} - final_items[kind].update(data) - - raw_materials = {} - if j.get("inventoryItems", {}).get("rawMaterials", {}).get("items", {}): - for item in j.get("inventoryItems", {}).get("rawMaterials", {}).get("items", {}).values(): - if item['isPartial']: - continue - kind = re.sub(r'_q\d\d*', "", item.get('token')) - if kind == "magnesium": - kind = "raw_aircraft" - elif kind == "sand": - kind = "raw_house" - if kind not in raw_materials: - raw_materials[kind] = [] - icon = (item['icon'] if item['icon'].startswith('//www.erepublik.net/') else "//www.erepublik." - "net/" + item['icon']) - raw_materials[kind].append( - dict(name=item.get("name"), amount=item['amount'] + (item.get('underCostruction', 0) / 100), - icon=icon) - ) - - offers = {} - for offer in self._get_economy_my_market_offers().json(): - kind = self.get_industry_name(offer['industryId']) - data = dict(quality=offer.get('quality', 0), amount=offer.get('amount', 0), icon=offer.get('icon'), - kind=kind, name=kind) - data = {data['quality']: data} - - if kind not in offers: - offers[kind] = {} - - offers[kind].update(data) - - self.inventory.update({"used": j.get("inventoryStatus").get("usedStorage"), - "total": j.get("inventoryStatus").get("totalStorage")}) - inventory = dict(items=dict(active=active_items, final=final_items, - raw=raw_materials, offers=offers), status=self.inventory) - self.food["total"] = sum([self.food[q] * utils.FOOD_ENERGY[q] for q in utils.FOOD_ENERGY]) - return inventory - def work_employees(self) -> bool: self.update_companies() ret = True @@ -1147,26 +1174,6 @@ class CitizenEconomy(CitizenTravel): self.write_log(f"{company_name} dissolved!") return self._post_economy_sell_company(factory_id, self.details.pin, sell=False) - def get_industry_id(self, industry_name: str) -> int: - """Returns industry id - - :type industry_name: str - :return: int - """ - return self.available_industries.get(industry_name, 0) - - def get_industry_name(self, industry_id: int) -> str: - """Returns industry name from industry ID - - :type industry_id: int - :return: industry name - :rtype: str - """ - for iname, iid in self.available_industries.items(): - if iid == industry_id: - return iname - return "" - def get_market_offers(self, country_id: int = None, product_name: str = None, quality: int = None) -> dict: raw_short_names = dict(frm="foodRaw", wrm="weaponRaw", hrm="houseRaw", arm="airplaneRaw") q1_industries = ["aircraft"] + list(raw_short_names.values()) @@ -1612,14 +1619,6 @@ class CitizenMilitary(CitizenTravel, CitizenTasks): except KeyError: self.report_error(f"Division {div} not available for battle {battle.id}!") def_points = inv_points = 3600 - kwargs = { - "bid": battle.id, - "air": "air" if battle.is_air else "ground", - "rw": "True" if battle.is_rw else "False", - "def": def_points, - "inv": inv_points, - "travel": "(TRAVEL)" if travel_needed else "", - } self.write_log(battle) points = def_points <= 1700 and inv_points <= 1700 diff --git a/erepublik/utils.py b/erepublik/utils.py index 6658f37..d2fad6d 100644 --- a/erepublik/utils.py +++ b/erepublik/utils.py @@ -30,7 +30,7 @@ if not sys.version_info >= (3, 7): 'But Your version is v{}.{}.{}'.format(*sys.version_info)) FOOD_ENERGY = dict(q1=2, q2=4, q3=6, q4=8, q5=10, q6=12, q7=20) -COMMIT_ID = "7b92e19" +COMMIT_ID = "62e265e" erep_tz = pytz.timezone('US/Pacific') AIR_RANKS = {1: "Airman", 2: "Airman 1st Class", 3: "Airman 1st Class*", 4: "Airman 1st Class**",