Added wheel of fortune endpoints, restructured work as manager, limiting log row length to 120 characters

This commit is contained in:
Eriks Karls 2020-03-03 13:07:39 +02:00
parent 7ec15a9645
commit 93f2f2887f
5 changed files with 233 additions and 224 deletions

View File

@ -5,7 +5,7 @@
__author__ = """Eriks Karls""" __author__ = """Eriks Karls"""
__email__ = 'eriks@72.lv' __email__ = 'eriks@72.lv'
__version__ = '0.20.0' __version__ = '0.20.0'
__commit_id__ = "e0c0967" __commit_id__ = "7ec15a9"
from erepublik import classes, utils from erepublik import classes, utils
from erepublik.citizen import Citizen from erepublik.citizen import Citizen

View File

@ -7,7 +7,6 @@ from requests import Response, Session
from erepublik import utils from erepublik import utils
__all__ = ['SlowRequests', 'CitizenAPI'] __all__ = ['SlowRequests', 'CitizenAPI']
@ -147,6 +146,12 @@ class ErepublikAnniversaryAPI(CitizenBaseAPI):
data = {'nodeId': node_id, '_token': self.token} data = {'nodeId': node_id, '_token': self.token}
return self.post("{}/main/map-rewards-claim".format(self.url), data=data) return self.post("{}/main/map-rewards-claim".format(self.url), data=data)
def _post_main_wheel_of_fortune_spin(self, cost) -> Response:
return self.post(f"{self.url}/wheeloffortune-spin", data={'_token': self.token, "cost": cost})
def _post_main_wheel_of_fortune_build(self) -> Response:
return self.post(f"{self.url}/wheeloffortune-build", data={'_token': self.token})
class ErepublikArticleAPI(CitizenBaseAPI): class ErepublikArticleAPI(CitizenBaseAPI):
def _get_main_article_json(self, article_id: int) -> Response: def _get_main_article_json(self, article_id: int) -> Response:
@ -211,28 +216,25 @@ class ErepublikCompanyAPI(CitizenBaseAPI):
return self.post("{}/economy/upgrade-company".format(self.url), data=data) return self.post("{}/economy/upgrade-company".format(self.url), data=data)
def _post_economy_work(self, action_type: str, wam: List[int] = None, employ: Dict[int, int] = None) -> Response: def _post_economy_work(self, action_type: str, wam: List[int] = None, employ: Dict[int, int] = None) -> Response:
""" data: Dict[str, Union[int, str]] = dict(action_type=action_type, _token=self.token)
:return: requests.Response or None if action_type == "production":
"""
if employ is None: if employ is None:
employ = {} employ = {}
if wam is None: if wam is None:
wam = [] wam = []
data: Dict[str, Union[int, str]] = dict(action_type=action_type, _token=self.token)
if action_type == "production":
max_idx = 0 max_idx = 0
for company_id in sorted(wam or []): for company_id in sorted(wam or []):
data.update({ data.update({
"companies[%i][id]" % max_idx: company_id, f"companies[{max_idx}][id]": company_id,
"companies[%i][employee_works]" % max_idx: employ.pop(company_id, 0), f"companies[{max_idx}][employee_works]": employ.pop(company_id, 0),
"companies[%i][own_work]" % max_idx: 1 f"companies[{max_idx}][own_work]": 1
}) })
max_idx += 1 max_idx += 1
for company_id in sorted(employ or []): for company_id in sorted(employ or []):
data.update({ data.update({
"companies[%i][id]" % max_idx: company_id, f"companies[{max_idx}][id]": company_id,
"companies[%i][employee_works]" % max_idx: employ.pop(company_id), f"companies[{max_idx}][employee_works]": employ.pop(company_id, 0),
"companies[%i][own_work]" % max_idx: 0 f"companies[{max_idx}][own_work]": 0
}) })
max_idx += 1 max_idx += 1
return self.post("{}/economy/work".format(self.url), data=data) return self.post("{}/economy/work".format(self.url), data=data)

View File

@ -1,10 +1,11 @@
import re import re
import sys import sys
import warnings
from datetime import datetime, timedelta from datetime import datetime, timedelta
from itertools import product from itertools import product
from threading import Event from threading import Event
from time import sleep from time import sleep
from typing import Any, Dict, List, Optional, Set, Tuple, Union from typing import Any, Dict, List, Optional, Set, Tuple, Union, Callable
from requests import RequestException, Response from requests import RequestException, Response
@ -405,6 +406,14 @@ class BaseCitizen(CitizenAPI):
return iname return iname
return "" return ""
def get_countries_with_regions(self) -> Set[int]:
response_json = self._post_main_travel_data().json()
return_list = {*[]}
for country_data in response_json['countries'].values():
if country_data['currentRegions']:
return_list.add(country_data['id'])
return return_list
def __str__(self) -> str: def __str__(self) -> str:
return f"Citizen {self.name}" return f"Citizen {self.name}"
@ -653,6 +662,32 @@ class CitizenAnniversary(BaseCitizen):
node = self.get_anniversary_quest_data().get('cities', {}).get(str(node_id), {}) node = self.get_anniversary_quest_data().get('cities', {}).get(str(node_id), {})
return self._post_map_rewards_speedup(node_id, node.get("skipCost", 0)) return self._post_map_rewards_speedup(node_id, node.get("skipCost", 0))
def spin_wheel_of_fortune(self, max_cost=0, spin_count=0):
def _write_spin_data(cost, cc, prize):
self.write_log(f"Cost: {cost:4d} | Currency left: {cc:,} | Prize: {prize}")
base = self._post_main_wheel_of_fortune_build().json()
current_cost = 0 if base.get('progress').get('free_spin') else base.get('cost')
current_count = base.get('progress').get('spins')
if not max_cost and not spin_count:
r = self._post_main_wheel_of_fortune_spin(current_cost).json()
_write_spin_data(current_cost, r.get('account'),
base.get('prizes').get('prizes').get(str(r.get('result'))).get('tooltip'))
else:
is_cost: Callable[[], bool] = lambda: (max_cost != current_cost if max_cost else True)
is_count: Callable[[], bool] = lambda: (spin_count != current_count if spin_count else True)
while is_cost() or is_count():
r = self._spin_wheel_of_loosing(current_cost)
current_count += 1
current_cost = r.get('cost')
_write_spin_data(current_cost, r.get('account'),
base.get('prizes').get('prizes').get(str(r.get('result'))).get('tooltip'))
def _spin_wheel_of_loosing(self, current_cost: int) -> Dict[str, Any]:
r = self._post_main_wheel_of_fortune_spin(current_cost).json()
self.details.cc = r.get('account')
return r.get('result')
class CitizenTravel(BaseCitizen): class CitizenTravel(BaseCitizen):
def _update_citizen_location(self, country_id: int, region_id: int): def _update_citizen_location(self, country_id: int, region_id: int):
@ -726,75 +761,34 @@ class CitizenTravel(BaseCitizen):
return d.get('regions', []) return d.get('regions', [])
def get_travel_countries(self) -> Set[int]: def get_travel_countries(self) -> Set[int]:
response_json = self._post_main_travel_data().json() warnings.simplefilter('always')
return_list = {*[]} warnings.warn('CitizenTravel.get_travel_countries() are being deprecated, '
for country_data in response_json['countries'].values(): 'please use BaseCitizen.get_countries_with_regions()', DeprecationWarning)
if country_data['currentRegions']: return self.get_countries_with_regions()
return_list.add(country_data['id'])
return return_list
class CitizenEconomy(CitizenTravel): class CitizenCompanies(BaseCitizen):
food: Dict[str, int] = {"q1": 0, "q2": 0, "q3": 0, "q4": 0, "q5": 0, "q6": 0, "q7": 0, "total": 0} def employ_employees(self) -> bool:
inventory: Dict[str, int] = {"used": 0, "total": 0}
boosters: Dict[int, Dict[int, int]] = {100: {}, 50: {}}
work_units = 0
ot_points = 0
my_companies: MyCompanies = None
def __init__(self):
super().__init__()
self.my_companies = MyCompanies()
def work_employees(self) -> bool:
self.update_companies() self.update_companies()
ret = True ret = True
work_units_needed = 0
employee_companies = self.my_companies.get_employable_factories() employee_companies = self.my_companies.get_employable_factories()
for c_id, preset_count in employee_companies.items(): work_units_needed = sum(employee_companies.values())
work_units_needed += preset_count
if work_units_needed: if work_units_needed:
if work_units_needed <= self.my_companies.work_units: if work_units_needed <= self.my_companies.work_units:
self._do_wam_and_employee_work(employee_companies=employee_companies) response = self._post_economy_work("production", employ=employee_companies).json()
self.reporter.report_action("WORK_EMPLOYEES", response, response.get('status', False))
self.update_companies() self.update_companies()
if self.my_companies.get_employable_factories(): ret = bool(self.my_companies.get_employable_factories())
ret = False
else:
ret = True
return ret return ret
def work_wam(self) -> bool: def work_as_manager_in_holding(self, holding_id: int) -> Optional[Dict[str, Any]]:
return self._work_as_manager(holding_id)
def _work_as_manager(self, wam_holding_id: int = 0) -> Optional[Dict[str, Any]]:
self.update_citizen_info() self.update_citizen_info()
self.update_companies() self.update_inventory()
# Prevent messing up levelup with wam
if not (self.is_levelup_close and self.config.fight) or self.config.force_wam:
# Check for current region
regions = {}
for holding_id, holding in self.my_companies.holdings.items():
if self.my_companies.get_holding_wam_companies(holding_id):
regions.update({holding["region_id"]: holding_id})
if self.details.current_region in regions:
self._do_wam_and_employee_work(regions.pop(self.details.current_region, None))
for holding_id in regions.values():
self._do_wam_and_employee_work(holding_id)
self.travel_to_residence()
else:
self.write_log("Did not wam because I would mess up levelup!")
self.update_companies()
return not self.my_companies.get_total_wam_count()
def _do_wam_and_employee_work(self, wam_holding_id: int = 0, employee_companies: dict = None) -> bool:
self.update_citizen_info()
if employee_companies is None:
employee_companies = {}
data = {"action_type": "production"} data = {"action_type": "production"}
extra = {} extra = {}
wam_list = [] wam_list = []
@ -816,80 +810,18 @@ class CitizenEconomy(CitizenTravel):
extra_needed = self.my_companies.get_needed_inventory_usage(companies=wam_list) extra_needed = self.my_companies.get_needed_inventory_usage(companies=wam_list)
has_space = extra_needed < free_inventory has_space = extra_needed < free_inventory
if not has_space: if not has_space:
inv_w = len(str(self.inventory["total"]))
self.write_log(
"Inv: {:{inv_w}}/{:{inv_w}} ({:4.2f}), Energy: {}/{} + {} (+{}hp/6min) WAM count {:3}".format(
self.inventory["used"], self.inventory["total"], extra_needed,
self.energy.recovered, self.energy.limit, self.energy.recoverable, self.energy.interval,
len(wam_list), inv_w=inv_w
))
wam_list.pop(-1) wam_list.pop(-1)
if wam_list or employee_companies: if wam_list:
data.update(extra) data.update(extra)
if wam_list: if wam_list:
wam_holding = self.my_companies.holdings.get(wam_holding_id) wam_holding = self.my_companies.holdings.get(wam_holding_id)
if not self.details.current_region == wam_holding['region_id']: if not self.details.current_region == wam_holding['region_id']:
if not self.travel_to_region(wam_holding['region_id']): self.write_log("Unable to work as manager because of location - please travel!")
return False return
response = self._post_economy_work("production", wam=wam_list, employ=employee_companies).json() response = self._post_economy_work("production", wam=wam_list,
if response.get("status"): employ=self.my_companies.get_employable_factories()).json()
self.reporter.report_action("WORK_WAM_EMPLOYEES", response) return response
if self.config.auto_sell:
for kind, data in response.get("result", {}).get("production", {}).items():
if kind in self.config.auto_sell and data:
if kind in ["food", "weapon", "house", "airplane"]:
for quality, amount in data.items():
self.sell_produced_product(kind, quality)
elif kind.endswith("Raw"):
self.sell_produced_product(kind, 1)
else:
raise ErepublikException("Unknown kind produced '{kind}'".format(kind=kind))
elif self.config.auto_buy_raw and re.search(r"not_enough_[^_]*_raw", response.get("message")):
raw_kind = re.search(r"not_enough_(\w+)_raw", response.get("message"))
if raw_kind:
raw_kind = raw_kind.group(1)
result = response.get("result", {})
amount_remaining = round(result.get("consume") + 0.49) - round(result.get("stock") - 0.49)
industry = "{}Raw".format(raw_kind)
while amount_remaining > 0:
amount = amount_remaining
best_offer = self.get_market_offers(self.details.citizenship, industry, 1)
amount = best_offer['amount'] if amount >= best_offer['amount'] else amount
rj = self.buy_from_market(amount=best_offer['amount'], offer=best_offer['offer_id'])
if not rj.get('error'):
amount_remaining -= amount
else:
self.write_log(rj.get('message', ""))
break
else:
return self._do_wam_and_employee_work(wam_holding_id, employee_companies)
elif response.get("message") == "not_enough_health_food":
self.buy_food()
return self._do_wam_and_employee_work(wam_holding_id, employee_companies)
else:
msg = "I was not able to wam and or employ because:\n{}".format(response)
self.reporter.report_action("WORK_WAM_EMPLOYEES", response, msg)
self.write_log(msg)
wam_count = self.my_companies.get_total_wam_count()
if wam_count:
self.write_log("Wam ff lockdown is now {}, was {}".format(wam_count, self.my_companies.ff_lockdown))
self.my_companies.ff_lockdown = wam_count
return bool(wam_count)
def update_money(self, page: int = 0, currency: int = 62) -> Dict[str, Any]:
"""
Gets monetary market offers to get exact amount of CC and Gold available
"""
if currency not in [1, 62]:
currency = 62
resp = self._post_economy_exchange_retrieve(False, page, currency)
resp_data = resp.json()
self.details.cc = float(resp_data.get("ecash").get("value"))
self.details.gold = float(resp_data.get("gold").get("value"))
return resp_data
def update_companies(self): def update_companies(self):
html = self._get_economy_my_companies().text html = self._get_economy_my_companies().text
@ -903,6 +835,56 @@ class CitizenEconomy(CitizenTravel):
self.my_companies.prepare_holdings(utils.json.loads(have_holdings.group(1))) self.my_companies.prepare_holdings(utils.json.loads(have_holdings.group(1)))
self.my_companies.update_holding_companies() self.my_companies.update_holding_companies()
def assign_factory_to_holding(self, factory_id: int, holding_id: int) -> Response:
"""
Assigns factory to new holding
"""
company = self.my_companies.companies[factory_id]
company_name = self.factories[company['industry_id']]
if not company['is_raw']:
company_name += f" q{company['quality']}"
self.write_log(f"{company_name} moved to {holding_id}")
return self._post_economy_assign_to_holding(factory_id, holding_id)
def upgrade_factory(self, factory_id: int, level: int) -> Response:
return self._post_economy_upgrade_company(factory_id, level, self.details.pin)
def create_factory(self, industry_id: int, building_type: int = 1) -> Response:
"""
param industry_ids: FRM={q1:7, q2:8, q3:9, q4:10, q5:11} WRM={q1:12, q2:13, q3:14, q4:15, q5:16}
HRM={q1:18, q2:19, q3:20, q4:21, q5:22} ARM={q1:24, q2:25, q3:26, q4:27, q5:28}
Factories={Food:1, Weapons:2, House:4, Aircraft:23} <- Building_type 1
Storage={1000: 1, 2000: 2} <- Building_type 2
"""
company_name = self.factories[industry_id]
if building_type == 2:
company_name = f"Storage"
self.write_log(f"{company_name} created!")
return self._post_economy_create_company(industry_id, building_type)
def dissolve_factory(self, factory_id: int) -> Response:
company = self.my_companies.companies[factory_id]
company_name = self.factories[company['industry_id']]
if not company['is_raw']:
company_name += f" q{company['quality']}"
self.write_log(f"{company_name} dissolved!")
return self._post_economy_sell_company(factory_id, self.details.pin, sell=False)
class CitizenEconomy(CitizenTravel):
def update_money(self, page: int = 0, currency: int = 62) -> Dict[str, Any]:
"""
Gets monetary market offers to get exact amount of CC and Gold available
"""
if currency not in [1, 62]:
currency = 62
resp = self._post_economy_exchange_retrieve(False, page, currency)
resp_data = resp.json()
self.details.cc = float(resp_data.get("ecash").get("value"))
self.details.gold = float(resp_data.get("gold").get("value"))
return resp_data
def check_house_durability(self) -> Dict[int, datetime]: def check_house_durability(self) -> Dict[int, datetime]:
ret = {} ret = {}
inv = self.update_inventory() inv = self.update_inventory()
@ -1031,42 +1013,6 @@ class CitizenEconomy(CitizenTravel):
self.reporter.report_action("BUY_PRODUCT", ret.json()) self.reporter.report_action("BUY_PRODUCT", ret.json())
return json_ret return json_ret
def assign_factory_to_holding(self, factory_id: int, holding_id: int) -> Response:
"""
Assigns factory to new holding
"""
company = self.my_companies.companies[factory_id]
company_name = self.factories[company['industry_id']]
if not company['is_raw']:
company_name += f" q{company['quality']}"
self.write_log(f"{company_name} moved to {holding_id}")
return self._post_economy_assign_to_holding(factory_id, holding_id)
def upgrade_factory(self, factory_id: int, level: int) -> Response:
return self._post_economy_upgrade_company(factory_id, level, self.details.pin)
def create_factory(self, industry_id: int, building_type: int = 1) -> Response:
"""
param industry_ids: FRM={q1:7, q2:8, q3:9, q4:10, q5:11} WRM={q1:12, q2:13, q3:14, q4:15, q5:16}
HRM={q1:18, q2:19, q3:20, q4:21, q5:22} ARM={q1:24, q2:25, q3:26, q4:27, q5:28}
Factories={Food:1, Weapons:2, House:4, Aircraft:23} <- Building_type 1
Storage={1000: 1, 2000: 2} <- Building_type 2
"""
company_name = self.factories[industry_id]
if building_type == 2:
company_name = f"Storage"
self.write_log(f"{company_name} created!")
return self._post_economy_create_company(industry_id, building_type)
def dissolve_factory(self, factory_id: int) -> Response:
company = self.my_companies.companies[factory_id]
company_name = self.factories[company['industry_id']]
if not company['is_raw']:
company_name += f" q{company['quality']}"
self.write_log(f"{company_name} dissolved!")
return self._post_economy_sell_company(factory_id, self.details.pin, sell=False)
def get_market_offers(self, country_id: int = None, product_name: str = None, quality: int = None) -> dict: 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") raw_short_names = dict(frm="foodRaw", wrm="weaponRaw", hrm="houseRaw", arm="airplaneRaw")
q1_industries = ["aircraft"] + list(raw_short_names.values()) q1_industries = ["aircraft"] + list(raw_short_names.values())
@ -1095,7 +1041,7 @@ class CitizenEconomy(CitizenTravel):
if country_id: if country_id:
countries = [country_id] countries = [country_id]
else: else:
countries = self.get_travel_countries() countries = self.get_countries_with_regions()
start_dt = self.now start_dt = self.now
iterable = [countries, product_name or items, [quality] if quality else range(1, 8)] iterable = [countries, product_name or items, [quality] if quality else range(1, 8)]
@ -1130,9 +1076,9 @@ class CitizenEconomy(CitizenTravel):
ret = items ret = items
return ret return ret
def buy_food(self): def buy_food(self, energy_amount: int = 0):
hp_per_quality = {"q1": 2, "q2": 4, "q3": 6, "q4": 8, "q5": 10, "q6": 12, "q7": 20} hp_per_quality = {"q1": 2, "q2": 4, "q3": 6, "q4": 8, "q5": 10, "q6": 12, "q7": 20}
hp_needed = 48 * self.energy.interval * 10 - self.food["total"] hp_needed = energy_amount if energy_amount else 48 * self.energy.interval * 10 - self.food["total"]
local_offers = self.get_market_offers(country_id=self.details.current_country, product_name="food") local_offers = self.get_market_offers(country_id=self.details.current_country, product_name="food")
cheapest_q, cheapest = sorted(local_offers.items(), key=lambda v: v[1]["price"] / hp_per_quality[v[0]])[0] cheapest_q, cheapest = sorted(local_offers.items(), key=lambda v: v[1]["price"] / hp_per_quality[v[0]])[0]
@ -1196,25 +1142,6 @@ class CitizenEconomy(CitizenTravel):
rf"storage.", response.text).group(1) rf"storage.", response.text).group(1)
return self.donate_items(citizen_id, int(available), industry_id, quality) return self.donate_items(citizen_id, int(available), industry_id, quality)
def sell_produced_product(self, kind: str, quality: int = 1, amount: int = 0):
if not amount:
inv_resp = self._get_economy_inventory_items().json()
category = "rawMaterials" if kind.endswith("Raw") else "finalProducts"
item = "{}_{}".format(self.available_industries[kind], quality)
amount = inv_resp.get("inventoryItems").get(category).get("items").get(item).get("amount", 0)
if amount >= 1:
lowest_price = self.get_market_offers(country_id=self.details.citizenship,
product_name=kind, quality=int(quality))
if lowest_price["citizen_id"] == self.details.citizen_id:
price = lowest_price["price"]
else:
price = lowest_price["price"] - 0.01
self.post_market_offer(industry=self.available_industries[kind], amount=int(amount),
quality=int(quality), price=price)
def contribute_cc_to_country(self, amount=0., country_id: int = 71) -> bool: def contribute_cc_to_country(self, amount=0., country_id: int = 71) -> bool:
self.update_money() self.update_money()
amount = int(amount) amount = int(amount)
@ -1272,18 +1199,8 @@ class CitizenMedia(BaseCitizen):
resp = self._post_main_vote_article(article_id).json() resp = self._post_main_vote_article(article_id).json()
return not bool(resp.get('error')) return not bool(resp.get('error'))
def get_article_comments(self, article_id: int, page_id: int = 1) -> Response: def get_article_comments(self, article_id: int, page_id: int = 1) -> Dict[str, Any]:
return self._post_main_article_comments(article_id, page_id) return self._post_main_article_comments(article_id, page_id).json()
def comment_article(self, article_id: int = 2645676, msg: str = None) -> Response:
if msg is None:
msg = self.eday
r = self.get_article_comments(article_id, 2)
r = self.get_article_comments(article_id, r.json()["pages"])
comments = r.json()["comments"]
if not comments[max(comments.keys())]["isMyComment"]:
r = self.write_article_comment(msg, article_id)
return r
def write_article_comment(self, message: str, article_id: int, parent_id: int = None) -> Response: def write_article_comment(self, message: str, article_id: int, parent_id: int = None) -> Response:
return self._post_main_article_comments_create(message, article_id, parent_id) return self._post_main_article_comments_create(message, article_id, parent_id)
@ -2150,10 +2067,8 @@ class CitizenTasks(BaseCitizen):
self.ot_points = ot.get("points", 0) self.ot_points = ot.get("points", 0)
class Citizen( class Citizen(CitizenAnniversary, CitizenCompanies, CitizenEconomy, CitizenLeaderboard,
CitizenAnniversary, CitizenEconomy, CitizenLeaderboard, CitizenMedia, CitizenMilitary, CitizenMedia, CitizenMilitary, CitizenPolitics, CitizenSocial, CitizenTasks):
CitizenPolitics, CitizenSocial, CitizenTasks
):
debug: bool = False debug: bool = False
def __init__(self, email: str = "", password: str = "", auto_login: bool = True): def __init__(self, email: str = "", password: str = "", auto_login: bool = True):
@ -2365,3 +2280,95 @@ class Citizen(
self._eat("blue") self._eat("blue")
self._eat("orange") self._eat("orange")
self.write_log(self.health_info) self.write_log(self.health_info)
def sell_produced_product(self, kind: str, quality: int = 1, amount: int = 0):
if not amount:
inv_resp = self._get_economy_inventory_items().json()
category = "rawMaterials" if kind.endswith("Raw") else "finalProducts"
item = "{}_{}".format(self.available_industries[kind], quality)
amount = inv_resp.get("inventoryItems").get(category).get("items").get(item).get("amount", 0)
if amount >= 1:
lowest_price = self.get_market_offers(country_id=self.details.citizenship,
product_name=kind, quality=int(quality))
if lowest_price["citizen_id"] == self.details.citizen_id:
price = lowest_price["price"]
else:
price = lowest_price["price"] - 0.01
self.post_market_offer(industry=self.available_industries[kind], amount=int(amount),
quality=int(quality), price=price)
def _wam(self, holding_id: int):
response = self.work_as_manager_in_holding(holding_id)
if response.get("status"):
self.reporter.report_action("WORK_AS_MANAGER", response, response.get("status"))
if self.config.auto_sell:
for kind, data in response.get("result", {}).get("production", {}).items():
if data and kind in self.config.auto_sell:
if kind in ["food", "weapon", "house", "airplane"]:
for quality, amount in data.items():
self.sell_produced_product(kind, quality)
elif kind.endswith("Raw"):
self.sell_produced_product(kind, 1)
else:
raise ErepublikException("Unknown kind produced '{kind}'".format(kind=kind))
elif self.config.auto_buy_raw and re.search(r"not_enough_[^_]*_raw", response.get("message")):
raw_kind = re.search(r"not_enough_(\w+)_raw", response.get("message"))
if raw_kind:
raw_kind = raw_kind.group(1)
result = response.get("result", {})
amount_remaining = round(result.get("consume") + 0.49) - round(result.get("stock") - 0.49)
while amount_remaining > 0:
amount = amount_remaining
best_offer = self.get_market_offers(self.details.citizenship, f"{raw_kind}Raw", 1)
amount = best_offer['amount'] if amount >= best_offer['amount'] else amount
rj = self.buy_from_market(amount=best_offer['amount'], offer=best_offer['offer_id'])
if not rj.get('error'):
amount_remaining -= amount
else:
self.write_log(rj.get('message', ""))
break
else:
return self._wam(holding_id)
elif response.get("message") == "not_enough_health_food":
self.buy_food()
return self._wam(holding_id)
else:
msg = "I was not able to wam and or employ because:\n{}".format(response)
self.reporter.report_action("WORK_WAM_EMPLOYEES", response, msg)
self.write_log(msg)
self.update_companies()
def work_as_manager(self):
self.update_citizen_info()
self.update_companies()
# Prevent messing up levelup with wam
if not (self.is_levelup_close and self.config.fight) or self.config.force_wam:
regions = {}
for holding_id, holding in self.my_companies.holdings.items():
if self.my_companies.get_holding_wam_companies(holding_id):
regions.update({holding["region_id"]: holding_id})
# Check for current region
if self.details.current_region in regions:
response = self._wam(regions.pop(self.details.current_region))
for holding_id in regions.values():
self.travel_to_holding(holding_id)
response = self._wam(holding_id)
wam_count = self.my_companies.get_total_wam_count()
if wam_count:
self.write_log("Wam ff lockdown is now {}, was {}".format(wam_count, self.my_companies.ff_lockdown))
self.my_companies.ff_lockdown = wam_count
return bool(wam_count)
else:
self.write_log("Did not WAM because I would mess up levelup!")
self.my_companies.ff_lockdown = 0
self.travel_to_residence()
self.update_companies()
return not self.my_companies.get_total_wam_count()

View File

@ -88,8 +88,7 @@ class MyCompanies:
ret = {} ret = {}
for company_id, company in self.companies.items(): for company_id, company in self.companies.items():
if company.get('preset_works'): if company.get('preset_works'):
preset_works: int = int(company.get('preset_works', 0)) ret[company_id] = int(company.get('preset_works', 0))
ret.update({company_id: preset_works})
return ret return ret
def get_total_wam_count(self) -> int: def get_total_wam_count(self) -> int:
@ -455,9 +454,8 @@ class Reporter:
self.__bot_update(data) self.__bot_update(data)
def report_action(self, action: str, json_val: Dict[Any, Any] = None, value: str = None): def report_action(self, action: str, json_val: Dict[Any, Any] = None, value: str = None):
if not self.key: if all([self.key, self.email, self.name, self.citizen_id]):
if not all([self.email, self.name, self.citizen_id]): return
pass
json_data = {'player_id': self.citizen_id, 'key': self.key, 'log': dict(action=action)} json_data = {'player_id': self.citizen_id, 'key': self.key, 'log': dict(action=action)}
if json_val: if json_val:
json_data['log'].update(dict(json=json_val)) json_data['log'].update(dict(json=json_val))
@ -665,7 +663,8 @@ class TelegramBot:
self._threads = [] self._threads = []
self.__queue = [] self.__queue = []
self.__thread_stopper = threading.Event() if stop_event is None else stop_event self.__thread_stopper = threading.Event() if stop_event is None else stop_event
self._last_full_energy_report = self._next_time = self._last_time = utils.good_timedelta(utils.now(), datetime.timedelta(hours=1)) self._last_full_energy_report = self._last_time = utils.good_timedelta(utils.now(), datetime.timedelta(hours=1))
self._next_time = utils.now()
@property @property
def __dict__(self): def __dict__(self):
@ -690,7 +689,7 @@ class TelegramBot:
self.__queue.clear() self.__queue.clear()
return True return True
self._threads = [t for t in self._threads if t.is_alive()] self._threads = [t for t in self._threads if t.is_alive()]
self._next_time = utils.good_timedelta(utils.now(), datetime.timedelta(minutes=1)) self._next_time = utils.good_timedelta(utils.now(), datetime.timedelta(seconds=20))
if not self._threads: if not self._threads:
name = "telegram_{}send".format(f"{self.player_name}_" if self.player_name else "") name = "telegram_{}send".format(f"{self.player_name}_" if self.player_name else "")
send_thread = threading.Thread(target=self.__send_messages, name=name) send_thread = threading.Thread(target=self.__send_messages, name=name)
@ -736,7 +735,7 @@ class TelegramBot:
message = f"Player *{self.player_name}*\n" + message message = f"Player *{self.player_name}*\n" + message
response = post(self.api_url, json=dict(chat_id=self.chat_id, text=message, parse_mode="Markdown")) response = post(self.api_url, json=dict(chat_id=self.chat_id, text=message, parse_mode="Markdown"))
self._last_time = utils.now() self._last_time = utils.now()
if response.json().get('ok'): if response.json().get('ok') and not self.__queue:
self.__queue = [] self.__queue.clear()
return True return True
return False return False

View File

@ -3,6 +3,7 @@ import inspect
import os import os
import re import re
import sys import sys
import textwrap
import time import time
import traceback import traceback
import unicodedata import unicodedata
@ -187,7 +188,7 @@ silent_sleep = time.sleep
def _write_log(msg, timestamp: bool = True, should_print: bool = False): def _write_log(msg, timestamp: bool = True, should_print: bool = False):
erep_time_now = now() erep_time_now = now()
txt = "[{}] {}".format(erep_time_now.strftime('%F %T'), msg) if timestamp else msg txt = textwrap.fill("[{}] {}".format(erep_time_now.strftime('%F %T'), msg) if timestamp else msg, 120)
if not os.path.isdir('log'): if not os.path.isdir('log'):
os.mkdir('log') os.mkdir('log')
with open("log/%s.log" % erep_time_now.strftime('%F'), 'a', encoding="utf-8") as f: with open("log/%s.log" % erep_time_now.strftime('%F'), 'a', encoding="utf-8") as f: