Code cleanup
This commit is contained in:
parent
81bd09e13e
commit
ffbbd25e54
@ -5,9 +5,9 @@
|
||||
__author__ = """Eriks Karls"""
|
||||
__email__ = 'eriks@72.lv'
|
||||
__version__ = '0.20.3.5'
|
||||
__commit_id__ = "fc4295d"
|
||||
__commit_id__ = "81bd09e"
|
||||
|
||||
from erepublik import classes, utils
|
||||
from erepublik import classes, utils, constants
|
||||
from erepublik.citizen import Citizen
|
||||
|
||||
__all__ = ["classes", "utils", "Citizen"]
|
||||
__all__ = ["classes", "utils", "Citizen", ]
|
||||
|
@ -5,7 +5,7 @@ from typing import Any, Dict, List, Mapping, Union
|
||||
|
||||
from requests import Response, Session
|
||||
|
||||
from erepublik import utils
|
||||
from . import constants, utils
|
||||
|
||||
__all__ = ['SlowRequests', 'CitizenAPI']
|
||||
|
||||
@ -45,7 +45,7 @@ class SlowRequests(Session):
|
||||
})
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
def as_dict(self):
|
||||
return dict(last_time=self.last_time, timeout=self.timeout, user_agent=self.headers['User-Agent'],
|
||||
request_log_name=self.request_log_name, debug=self.debug)
|
||||
|
||||
@ -461,13 +461,13 @@ class ErepublikPresidentAPI(CitizenBaseAPI):
|
||||
|
||||
def _post_new_war(self, self_country_id: int, attack_country_id: int, debate: str = "") -> Response:
|
||||
data = dict(requirments=1, _token=self.token, debate=debate,
|
||||
countryNameConfirm=utils.COUNTRY_LINK[attack_country_id])
|
||||
return self.post("{}/{}/new-war".format(self.url, utils.COUNTRY_LINK[self_country_id]), data=data)
|
||||
countryNameConfirm=constants.COUNTRIES[attack_country_id].link)
|
||||
return self.post("{}/{}/new-war".format(self.url, constants.COUNTRIES[self_country_id].link), data=data)
|
||||
|
||||
def _post_new_donation(self, country_id: int, amount: int, org_name: str, debate: str = "") -> Response:
|
||||
data = dict(requirments=1, _token=self.token, debate=debate, currency=1, value=amount, commit='Propose',
|
||||
type_name=org_name)
|
||||
return self.post("{}/{}/new-donation".format(self.url, utils.COUNTRY_LINK[country_id]), data=data)
|
||||
return self.post("{}/{}/new-donation".format(self.url, constants.COUNTRIES[country_id].link), data=data)
|
||||
|
||||
|
||||
class ErepublikProfileAPI(CitizenBaseAPI):
|
||||
|
@ -10,16 +10,11 @@ from typing import Any, Callable, Dict, List, NoReturn, Optional, Set, Tuple, Un
|
||||
|
||||
from requests import HTTPError, RequestException, Response
|
||||
|
||||
from erepublik import utils
|
||||
from erepublik.access_points import CitizenAPI
|
||||
from erepublik.classes import COUNTRIES, Battle, BattleDivision, Config, Country, Details, Energy, \
|
||||
ErepublikException, MyCompanies, MyJSONEncoder, OfferItem, Politics, Reporter, TelegramBot, Holding, BattleSide, \
|
||||
Company
|
||||
from erepublik.utils import erep_tz
|
||||
from . import utils, classes, access_points, constants
|
||||
|
||||
|
||||
class BaseCitizen(CitizenAPI):
|
||||
__last_full_update: datetime = utils.now().min
|
||||
class BaseCitizen(access_points.CitizenAPI):
|
||||
_last_full_update: datetime = utils.now().min
|
||||
|
||||
promos: Dict[str, datetime] = None
|
||||
inventory: Dict[str, int] = {'used': 0, 'total': 0}
|
||||
@ -34,13 +29,13 @@ class BaseCitizen(CitizenAPI):
|
||||
|
||||
eday = 0
|
||||
|
||||
config: Config = None
|
||||
energy: Energy = None
|
||||
details: Details = None
|
||||
politics: Politics = None
|
||||
reporter: Reporter = None
|
||||
config: classes.Config = None
|
||||
energy: classes.Energy = None
|
||||
details: classes.Details = None
|
||||
politics: classes.Politics = None
|
||||
reporter: classes.Reporter = None
|
||||
stop_threads: Event = None
|
||||
telegram: TelegramBot = None
|
||||
telegram: classes.TelegramBot = None
|
||||
|
||||
r: Response = None
|
||||
name: str = "Not logged in!"
|
||||
@ -51,14 +46,14 @@ class BaseCitizen(CitizenAPI):
|
||||
def __init__(self, email: str = "", password: str = ""):
|
||||
super().__init__()
|
||||
self.commit_id = utils.COMMIT_ID
|
||||
self.config = Config()
|
||||
self.energy = Energy()
|
||||
self.details = Details()
|
||||
self.politics = Politics()
|
||||
self.my_companies = MyCompanies(self)
|
||||
self.reporter = Reporter(self)
|
||||
self.config = classes.Config()
|
||||
self.energy = classes.Energy()
|
||||
self.details = classes.Details()
|
||||
self.politics = classes.Politics()
|
||||
self.my_companies = classes.MyCompanies(self)
|
||||
self.reporter = classes.Reporter(self)
|
||||
self.stop_threads = Event()
|
||||
self.telegram = TelegramBot(stop_event=self.stop_threads)
|
||||
self.telegram = classes.TelegramBot(stop_event=self.stop_threads)
|
||||
|
||||
self.config.email = email
|
||||
self.config.password = password
|
||||
@ -85,7 +80,7 @@ class BaseCitizen(CitizenAPI):
|
||||
self.token = re_login_token.group(1)
|
||||
self._login()
|
||||
else:
|
||||
raise ErepublikException("Something went wrong! Can't find token in page! Exiting!")
|
||||
raise classes.ErepublikException("Something went wrong! Can't find token in page! Exiting!")
|
||||
try:
|
||||
self.update_citizen_info(resp.text)
|
||||
except (AttributeError, utils.json.JSONDecodeError, ValueError, KeyError):
|
||||
@ -206,11 +201,12 @@ class BaseCitizen(CitizenAPI):
|
||||
self.energy.recoverable = citizen.get("energyFromFoodRemaining", 0)
|
||||
|
||||
self.details.current_region = citizen.get("regionLocationId", 0)
|
||||
self.details.current_country = COUNTRIES.get(citizen.get("countryLocationId", 0)) # country where citizen is located
|
||||
self.details.current_country = constants.COUNTRIES.get(
|
||||
citizen.get("countryLocationId", 0)) # country where citizen is located
|
||||
self.details.residence_region = citizen.get("residence", {}).get("regionId", 0)
|
||||
self.details.residence_country = COUNTRIES.get(citizen.get("residence", {}).get("countryId", 0))
|
||||
self.details.residence_country = constants.COUNTRIES.get(citizen.get("residence", {}).get("countryId", 0))
|
||||
self.details.citizen_id = citizen.get("citizenId", 0)
|
||||
self.details.citizenship = COUNTRIES.get(int(citizen.get("country", 0)))
|
||||
self.details.citizenship = constants.COUNTRIES.get(int(citizen.get("country", 0)))
|
||||
self.details.xp = citizen.get("currentExperiencePoints", 0)
|
||||
self.details.daily_task_done = citizen.get("dailyTasksDone", False)
|
||||
self.details.daily_task_reward = citizen.get("hasReward", False)
|
||||
@ -359,7 +355,7 @@ class BaseCitizen(CitizenAPI):
|
||||
|
||||
offers = {}
|
||||
for offer in self._get_economy_my_market_offers().json():
|
||||
kind = self.get_industry_name(offer['industryId'])
|
||||
kind = constants.INDUSTRIES[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}
|
||||
@ -373,7 +369,7 @@ class BaseCitizen(CitizenAPI):
|
||||
"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])
|
||||
self.food["total"] = sum([self.food[q] * constants.FOOD_ENERGY[q] for q in constants.FOOD_ENERGY])
|
||||
return inventory
|
||||
|
||||
def write_log(self, *args, **kwargs):
|
||||
@ -397,34 +393,14 @@ class BaseCitizen(CitizenAPI):
|
||||
sleep(seconds)
|
||||
|
||||
def to_json(self, indent: bool = False) -> str:
|
||||
return utils.json.dumps(self.__dict__, cls=MyJSONEncoder, indent=4 if indent else None, sort_keys=True)
|
||||
return utils.json.dumps(self, cls=classes.MyJSONEncoder, indent=4 if indent else None, sort_keys=True)
|
||||
|
||||
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 industry_name, ind_id in self.available_industries.items():
|
||||
if ind_id == industry_id:
|
||||
return industry_name
|
||||
return ""
|
||||
|
||||
def get_countries_with_regions(self) -> Set[Country]:
|
||||
def get_countries_with_regions(self) -> Set[constants.Country]:
|
||||
r_json = self._post_main_travel_data().json()
|
||||
return_set = {*[]}
|
||||
for country_data in r_json['countries'].values():
|
||||
if country_data['currentRegions']:
|
||||
return_set.add(COUNTRIES[country_data['id']])
|
||||
return_set.add(constants.COUNTRIES[country_data['id']])
|
||||
return return_set
|
||||
|
||||
def __str__(self) -> str:
|
||||
@ -434,10 +410,16 @@ class BaseCitizen(CitizenAPI):
|
||||
return self.__str__()
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
ret = super().__dict__.copy()
|
||||
def as_dict(self):
|
||||
ret = self.__dict__.copy()
|
||||
ret.pop('stop_threads', None)
|
||||
ret.pop('_CitizenMilitary__last_war_update_data', None)
|
||||
ret.update(_properties=dict(
|
||||
now=self.now, should_do_levelup=self.should_do_levelup, is_levelup_reachable=self.is_levelup_reachable,
|
||||
max_time_till_full_ff=self.max_time_till_full_ff, is_levelup_close=self.is_levelup_close,
|
||||
time_till_full_ff=self.time_till_full_ff, time_till_week_change=self.time_till_week_change,
|
||||
next_wc_start=self.next_wc_start, next_reachable_energy=self.next_reachable_energy,
|
||||
health_info=self.health_info))
|
||||
|
||||
return ret
|
||||
|
||||
@ -510,27 +492,6 @@ class BaseCitizen(CitizenAPI):
|
||||
can_do_max_amount_of_dmg = self.energy.recoverable + 2 * self.energy.interval >= self.energy.limit
|
||||
return can_reach_next_level and can_do_max_amount_of_dmg
|
||||
|
||||
@property
|
||||
def available_industries(self) -> Dict[str, int]:
|
||||
"""
|
||||
Returns currently available industries as dict(name: id)
|
||||
:return: Dict[str, int]
|
||||
"""
|
||||
return {"food": 1, "weapon": 2, "house": 4, "aircraft": 23,
|
||||
"foodRaw": 7, "weaponRaw": 12, "houseRaw": 17, "airplaneRaw": 24}
|
||||
|
||||
@property
|
||||
def factories(self) -> Dict[int, str]:
|
||||
"""Returns factory industries as dict(id: name)
|
||||
:return: Factory id:name dict
|
||||
:rtype: Dict[int, str]
|
||||
"""
|
||||
return {1: "Food", 2: "Weapons", 4: "House", 23: "Aircraft",
|
||||
7: "FRM q1", 8: "FRM q2", 9: "FRM q3", 10: "FRM q4", 11: "FRM q5",
|
||||
12: "WRM q1", 13: "WRM q2", 14: "WRM q3", 15: "WRM q4", 16: "WRM q5",
|
||||
18: "HRM q1", 19: "HRM q2", 20: "HRM q3", 21: "HRM q4", 22: "HRM q5",
|
||||
24: "ARM q1", 25: "ARM q2", 26: "ARM q3", 27: "ARM q4", 28: "ARM q5", }
|
||||
|
||||
@property
|
||||
def now(self) -> datetime:
|
||||
"""
|
||||
@ -591,7 +552,7 @@ class BaseCitizen(CitizenAPI):
|
||||
self.telegram.report_medal(f"Level *{level}*")
|
||||
self.reporter.report_action("LEVEL_UP", value=level)
|
||||
|
||||
def _travel(self, country: Country, region_id: int = 0) -> Response:
|
||||
def _travel(self, country: constants.Country, region_id: int = 0) -> Response:
|
||||
data = {
|
||||
"toCountryId": country.id,
|
||||
"inRegionId": region_id,
|
||||
@ -662,7 +623,7 @@ class BaseCitizen(CitizenAPI):
|
||||
self.write_log("eRepublik servers are having internal troubles. Sleeping for 5 minutes")
|
||||
self.sleep(5 * 60)
|
||||
else:
|
||||
raise ErepublikException(f"HTTP {response.status_code} error!")
|
||||
raise classes.ErepublikException(f"HTTP {response.status_code} error!")
|
||||
return bool(re.search(r'body id="error"|Internal Server Error|'
|
||||
r'CSRF attack detected|meta http-equiv="refresh"|not_authenticated', response.text))
|
||||
|
||||
@ -676,7 +637,7 @@ class BaseCitizen(CitizenAPI):
|
||||
:param msg: Message about the action
|
||||
:param kwargs: Extra information regarding action
|
||||
"""
|
||||
kwargs = utils.json.loads(utils.json.dumps(kwargs or {}, cls=MyJSONEncoder))
|
||||
kwargs = utils.json.loads(utils.json.dumps(kwargs or {}, cls=classes.MyJSONEncoder))
|
||||
action = action[:32]
|
||||
self.write_log(msg)
|
||||
if self.reporter.allowed:
|
||||
@ -730,11 +691,11 @@ class CitizenAnniversary(BaseCitizen):
|
||||
|
||||
|
||||
class CitizenTravel(BaseCitizen):
|
||||
def _update_citizen_location(self, country: Country, region_id: int):
|
||||
def _update_citizen_location(self, country: constants.Country, region_id: int):
|
||||
self.details.current_region = region_id
|
||||
self.details.current_country = country
|
||||
|
||||
def get_country_travel_region(self, country: Country) -> int:
|
||||
def get_country_travel_region(self, country: constants.Country) -> int:
|
||||
regions = self.get_travel_regions(country=country)
|
||||
regs = []
|
||||
if regions:
|
||||
@ -763,7 +724,7 @@ class CitizenTravel(BaseCitizen):
|
||||
if data.get('alreadyInRegion'):
|
||||
return True
|
||||
else:
|
||||
country = COUNTRIES[data.get('preselectCountryId')]
|
||||
country = constants.COUNTRIES[data.get('preselectCountryId')]
|
||||
r_json = self._travel(country, region_id).json()
|
||||
if r_json.get('message', '') == 'success':
|
||||
self._update_citizen_location(country, region_id)
|
||||
@ -771,7 +732,7 @@ class CitizenTravel(BaseCitizen):
|
||||
return True
|
||||
return False
|
||||
|
||||
def travel_to_country(self, country: Country) -> bool:
|
||||
def travel_to_country(self, country: constants.Country) -> bool:
|
||||
data = self._post_main_travel_data(countryId=country.id, check="getCountryRegions").json()
|
||||
|
||||
regs = []
|
||||
@ -788,12 +749,12 @@ class CitizenTravel(BaseCitizen):
|
||||
return True
|
||||
return False
|
||||
|
||||
def travel_to_holding(self, holding: Holding) -> bool:
|
||||
def travel_to_holding(self, holding: classes.Holding) -> bool:
|
||||
data = self._post_main_travel_data(holdingId=holding.id).json()
|
||||
if data.get('alreadyInRegion'):
|
||||
return True
|
||||
else:
|
||||
country = COUNTRIES[data.get('preselectCountryId')]
|
||||
country = constants.COUNTRIES[data.get('preselectCountryId')]
|
||||
region_id = data.get('preselectRegionId')
|
||||
r_json = self._travel(country, region_id).json()
|
||||
if r_json.get('message', '') == 'success':
|
||||
@ -802,7 +763,7 @@ class CitizenTravel(BaseCitizen):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_travel_regions(self, holding: Holding = None, battle: Battle = None, country: Country = None
|
||||
def get_travel_regions(self, holding: classes.Holding = None, battle: classes.Battle = None, country: constants.Country = None
|
||||
) -> Union[List[Any], Dict[str, Dict[str, Any]]]:
|
||||
return self._post_main_travel_data(
|
||||
holdingId=holding.id if holding else 0,
|
||||
@ -810,7 +771,7 @@ class CitizenTravel(BaseCitizen):
|
||||
countryId=country.id if country else 0
|
||||
).json().get('regions', [])
|
||||
|
||||
def get_travel_countries(self) -> Set[Country]:
|
||||
def get_travel_countries(self) -> Set[constants.Country]:
|
||||
warnings.simplefilter('always')
|
||||
warnings.warn('CitizenTravel.get_travel_countries() are being deprecated, '
|
||||
'please use BaseCitizen.get_countries_with_regions()', DeprecationWarning)
|
||||
@ -833,10 +794,10 @@ class CitizenCompanies(BaseCitizen):
|
||||
|
||||
return ret
|
||||
|
||||
def work_as_manager_in_holding(self, holding: Holding) -> Optional[Dict[str, Any]]:
|
||||
def work_as_manager_in_holding(self, holding: classes.Holding) -> Optional[Dict[str, Any]]:
|
||||
return self._work_as_manager(holding)
|
||||
|
||||
def _work_as_manager(self, wam_holding: Holding = None) -> Optional[Dict[str, Any]]:
|
||||
def _work_as_manager(self, wam_holding: classes.Holding = None) -> Optional[Dict[str, Any]]:
|
||||
if self.restricted_ip:
|
||||
return None
|
||||
self.update_companies()
|
||||
@ -879,7 +840,7 @@ class CitizenCompanies(BaseCitizen):
|
||||
self.my_companies.prepare_holdings(utils.json.loads(have_holdings.group(1)))
|
||||
self.my_companies.prepare_companies(utils.json.loads(have_companies.group(1)))
|
||||
|
||||
def assign_company_to_holding(self, company: Company, holding: Holding) -> Response:
|
||||
def assign_company_to_holding(self, company: classes.Company, holding: classes.Holding) -> Response:
|
||||
"""
|
||||
Assigns factory to new holding
|
||||
"""
|
||||
@ -1019,7 +980,7 @@ class CitizenEconomy(CitizenTravel):
|
||||
return ret
|
||||
|
||||
def post_market_offer(self, industry: int, quality: int, amount: int, price: float) -> Response:
|
||||
if industry not in self.available_industries.values():
|
||||
if not constants.INDUSTRIES[industry]:
|
||||
self.write_log(f"Trying to sell unsupported industry {industry}")
|
||||
|
||||
data = {
|
||||
@ -1032,7 +993,7 @@ class CitizenEconomy(CitizenTravel):
|
||||
}
|
||||
ret = self._post_economy_marketplace_actions(**data)
|
||||
message = (f"Posted market offer for {amount}q{quality} "
|
||||
f"{self.get_industry_name(industry)} for price {price}cc")
|
||||
f"{constants.INDUSTRIES[industry]} for price {price}cc")
|
||||
self._report_action("ECONOMY_SELL_PRODUCTS", message, kwargs=ret.json())
|
||||
return ret
|
||||
|
||||
@ -1048,43 +1009,46 @@ class CitizenEconomy(CitizenTravel):
|
||||
self._report_action("BOUGHT_PRODUCTS", "", kwargs=json_ret)
|
||||
return json_ret
|
||||
|
||||
def get_market_offers(self, product_name: str, quality: int = None, country: Country = None) -> Dict[str, OfferItem]:
|
||||
def get_market_offers(
|
||||
self, product_name: str, quality: int = None, country: constants.Country = None
|
||||
) -> Dict[str, classes.OfferItem]:
|
||||
raw_short_names = dict(frm="foodRaw", wrm="weaponRaw", hrm="houseRaw", arm="airplaneRaw")
|
||||
q1_industries = ["aircraft"] + list(raw_short_names.values())
|
||||
if product_name not in self.available_industries and product_name not in raw_short_names:
|
||||
self.write_log(f"Industry '{product_name}' not implemented")
|
||||
raise ErepublikException(f"Industry '{product_name}' not implemented")
|
||||
elif product_name in raw_short_names:
|
||||
if product_name in raw_short_names:
|
||||
quality = 1
|
||||
product_name = raw_short_names[product_name]
|
||||
elif not constants.INDUSTRIES[product_name]:
|
||||
self.write_log(f"Industry '{product_name}' not implemented")
|
||||
raise classes.ErepublikException(f"Industry '{product_name}' not implemented")
|
||||
|
||||
offers: Dict[str, OfferItem] = {}
|
||||
offers: Dict[str, classes.OfferItem] = {}
|
||||
|
||||
max_quality = 0
|
||||
if quality:
|
||||
offers[f"q{quality}"] = OfferItem()
|
||||
offers[f"q{quality}"] = classes.OfferItem()
|
||||
else:
|
||||
max_quality = 1 if product_name in q1_industries else 5 if product_name == 'house' else 7
|
||||
for q in range(max_quality):
|
||||
offers[f"q{q + 1}"] = OfferItem()
|
||||
offers[f"q{q + 1}"] = classes.OfferItem()
|
||||
|
||||
if country:
|
||||
countries: Set[Country] = {country}
|
||||
countries: Set[constants.Country] = {country}
|
||||
else:
|
||||
countries: Set[Country] = self.get_countries_with_regions()
|
||||
countries: Set[constants.Country] = self.get_countries_with_regions()
|
||||
|
||||
start_dt = self.now
|
||||
iterable = [countries, [quality] if quality else range(1, max_quality + 1)]
|
||||
for country, q in product(*iterable):
|
||||
r = self._post_economy_marketplace(country, self.available_industries[product_name], q).json()
|
||||
r = self._post_economy_marketplace(country, constants.INDUSTRIES[product_name], q).json()
|
||||
obj = offers[f"q{q}"]
|
||||
if not r.get("error", False):
|
||||
for offer in r["offers"]:
|
||||
if (obj.price > float(offer["priceWithTaxes"]) or (
|
||||
obj.price == float(offer["priceWithTaxes"]) and obj.amount < int(offer["amount"])
|
||||
)):
|
||||
offers[f"q{q}"] = obj = OfferItem(
|
||||
float(offer["priceWithTaxes"]), COUNTRIES[int(offer["country_id"])], int(offer["amount"]),
|
||||
offers[f"q{q}"] = obj = classes.OfferItem(
|
||||
float(offer["priceWithTaxes"]),
|
||||
constants.COUNTRIES[int(offer["country_id"])], int(offer["amount"]),
|
||||
int(offer["id"]), int(offer["citizen_id"])
|
||||
)
|
||||
self.write_log(f"Scraped market in {self.now - start_dt}!")
|
||||
@ -1095,16 +1059,17 @@ class CitizenEconomy(CitizenTravel):
|
||||
hp_needed = energy_amount if energy_amount else 48 * self.energy.interval * 10 - self.food["total"]
|
||||
local_offers = self.get_market_offers("food", country=self.details.current_country)
|
||||
|
||||
cheapest_q, cheapest = sorted(local_offers.items(), key=lambda v: v[1].price / utils.FOOD_ENERGY[v[0]])[0]
|
||||
cheapest_q, cheapest = sorted(local_offers.items(), key=lambda v: v[1].price / constants.FOOD_ENERGY[v[0]])[0]
|
||||
|
||||
if cheapest.amount * utils.FOOD_ENERGY[cheapest_q] < hp_needed:
|
||||
if cheapest.amount * constants.FOOD_ENERGY[cheapest_q] < hp_needed:
|
||||
amount = cheapest.amount
|
||||
else:
|
||||
amount = hp_needed // utils.FOOD_ENERGY[cheapest_q]
|
||||
amount = hp_needed // constants.FOOD_ENERGY[cheapest_q]
|
||||
|
||||
if amount * cheapest.price < self.details.cc:
|
||||
data = dict(offer=cheapest.offer_id, amount=amount, price=cheapest.price,
|
||||
cost=amount * cheapest.price, quality=cheapest_q, energy=amount * utils.FOOD_ENERGY[cheapest_q])
|
||||
cost=amount * cheapest.price, quality=cheapest_q,
|
||||
energy=amount * constants.FOOD_ENERGY[cheapest_q])
|
||||
self._report_action("BUY_FOOD", "", kwargs=data)
|
||||
self.buy_from_market(cheapest.offer_id, amount)
|
||||
self.update_inventory()
|
||||
@ -1166,11 +1131,11 @@ class CitizenEconomy(CitizenTravel):
|
||||
def donate_items(self, citizen_id: int = 1620414, amount: int = 0, industry_id: int = 1, quality: int = 1) -> int:
|
||||
if amount < 1:
|
||||
return 0
|
||||
ind = {v: k for k, v in self.available_industries.items()}
|
||||
self.write_log(f"Donate: {amount:4d}q{quality} {ind[industry_id]} to {citizen_id}")
|
||||
industry = constants.INDUSTRIES[industry_id]
|
||||
self.write_log(f"Donate: {amount:4d}q{quality} {industry} to {citizen_id}")
|
||||
response = self._post_economy_donate_items_action(citizen_id, amount, industry_id, quality)
|
||||
if re.search(rf"Successfully transferred {amount} item\(s\) to", response.text):
|
||||
msg = (f"Successfully donated {amount}q{quality} {self.get_industry_name(industry_id)} "
|
||||
msg = (f"Successfully donated {amount}q{quality} {industry} "
|
||||
f"to citizen with id {citizen_id}!")
|
||||
self._report_action("DONATE_ITEMS", msg)
|
||||
return amount
|
||||
@ -1182,19 +1147,19 @@ class CitizenEconomy(CitizenTravel):
|
||||
if re.search(r'You do not have enough items in your inventory to make this donation', response.text):
|
||||
self._report_action("DONATE_ITEMS",
|
||||
f"Unable to donate {amount}q{quality} "
|
||||
f"{self.get_industry_name(industry_id)}, not enough left!")
|
||||
f"{industry}, not enough left!")
|
||||
return 0
|
||||
available = re.search(
|
||||
r'Cannot transfer the items because the user has only (\d+) free slots in (his|her) storage.',
|
||||
response.text
|
||||
).group(1)
|
||||
self._report_action('DONATE_ITEMS',
|
||||
f'Unable to donate {amount}q{quality}{self.get_industry_name(industry_id)}'
|
||||
f'Unable to donate {amount}q{quality}{industry}'
|
||||
f', receiver has only {available} storage left!')
|
||||
self.sleep(5)
|
||||
return self.donate_items(citizen_id, int(available), industry_id, quality)
|
||||
|
||||
def contribute_cc_to_country(self, amount, country: Country) -> bool:
|
||||
def contribute_cc_to_country(self, amount, country: constants.Country) -> bool:
|
||||
self.update_money()
|
||||
amount = int(amount)
|
||||
if self.details.cc < amount or amount < 20:
|
||||
@ -1209,7 +1174,7 @@ class CitizenEconomy(CitizenTravel):
|
||||
f" treasury", kwargs=r.json())
|
||||
return False
|
||||
|
||||
def contribute_food_to_country(self, amount, quality, country: Country) -> bool:
|
||||
def contribute_food_to_country(self, amount, quality, country: constants.Country) -> bool:
|
||||
self.update_inventory()
|
||||
amount = amount // 1
|
||||
if self.food["q" + str(quality)] < amount or amount < 10:
|
||||
@ -1226,7 +1191,7 @@ class CitizenEconomy(CitizenTravel):
|
||||
f"{country}'s treasury", kwargs=r.json())
|
||||
return False
|
||||
|
||||
def contribute_gold_to_country(self, amount: int, country: Country) -> bool:
|
||||
def contribute_gold_to_country(self, amount: int, country: constants.Country) -> bool:
|
||||
self.update_money()
|
||||
|
||||
if self.details.cc < amount:
|
||||
@ -1304,13 +1269,13 @@ class CitizenMedia(BaseCitizen):
|
||||
article_id = 0
|
||||
return article_id
|
||||
else:
|
||||
raise ErepublikException("Article kind must be one of:\n{}\n'{}' is not supported".format(
|
||||
raise classes.ErepublikException("Article kind must be one of:\n{}\n'{}' is not supported".format(
|
||||
"\n".join(["{}: {}".format(k, v) for k, v in kinds.items()]), kind
|
||||
))
|
||||
|
||||
|
||||
class CitizenMilitary(CitizenTravel):
|
||||
all_battles: Dict[int, Battle] = None
|
||||
all_battles: Dict[int, classes.Battle] = None
|
||||
countries: Dict[int, Dict[str, Union[str, List[int]]]] = None
|
||||
__last_war_update_data = None
|
||||
|
||||
@ -1344,10 +1309,10 @@ class CitizenMilitary(CitizenTravel):
|
||||
if r_json.get("battles"):
|
||||
all_battles = {}
|
||||
for battle_data in r_json.get("battles", {}).values():
|
||||
all_battles[battle_data.get('id')] = Battle(battle_data)
|
||||
all_battles[battle_data.get('id')] = classes.Battle(battle_data)
|
||||
self.all_battles = all_battles
|
||||
|
||||
def get_battle_for_war(self, war_id: int) -> Optional[Battle]:
|
||||
def get_battle_for_war(self, war_id: int) -> Optional[classes.Battle]:
|
||||
self.update_war_info()
|
||||
war_info = self.get_war_status(war_id)
|
||||
return self.all_battles.get(war_info.get("battle_id"), None)
|
||||
@ -1375,7 +1340,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
def get_available_weapons(self, battle_id: int):
|
||||
return self._get_military_show_weapons(battle_id).json()
|
||||
|
||||
def set_default_weapon(self, battle: Battle, division: BattleDivision) -> int:
|
||||
def set_default_weapon(self, battle: classes.Battle, division: classes.BattleDivision) -> int:
|
||||
available_weapons = self._get_military_show_weapons(battle.id).json()
|
||||
while not isinstance(available_weapons, list):
|
||||
available_weapons = self._get_military_show_weapons(battle.id).json()
|
||||
@ -1390,7 +1355,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
pass
|
||||
return self.change_weapon(battle, weapon_quality, division)
|
||||
|
||||
def change_weapon(self, battle: Battle, quality: int, battle_zone: BattleDivision) -> int:
|
||||
def change_weapon(self, battle: classes.Battle, quality: int, battle_zone: classes.BattleDivision) -> int:
|
||||
r = self._post_military_change_weapon(battle.id, battle_zone.id, quality)
|
||||
influence = r.json().get('weaponInfluence')
|
||||
self._report_action("MILITARY_WEAPON", f"Switched to q{quality} weapon,"
|
||||
@ -1442,19 +1407,19 @@ class CitizenMilitary(CitizenTravel):
|
||||
#
|
||||
# self.active_fs = active_fs
|
||||
|
||||
def sorted_battles(self, sort_by_time: bool = True, only_tp=False) -> List[Battle]:
|
||||
cs_battles_priority_air: List[Battle] = []
|
||||
cs_battles_priority_ground: List[Battle] = []
|
||||
cs_battles_air: List[Battle] = []
|
||||
cs_battles_ground: List[Battle] = []
|
||||
deployed_battles_air: List[Battle] = []
|
||||
deployed_battles_ground: List[Battle] = []
|
||||
ally_battles_air: List[Battle] = []
|
||||
ally_battles_ground: List[Battle] = []
|
||||
other_battles_air: List[Battle] = []
|
||||
other_battles_ground: List[Battle] = []
|
||||
def sorted_battles(self, sort_by_time: bool = True, only_tp=False) -> List[classes.Battle]:
|
||||
cs_battles_priority_air: List[classes.Battle] = []
|
||||
cs_battles_priority_ground: List[classes.Battle] = []
|
||||
cs_battles_air: List[classes.Battle] = []
|
||||
cs_battles_ground: List[classes.Battle] = []
|
||||
deployed_battles_air: List[classes.Battle] = []
|
||||
deployed_battles_ground: List[classes.Battle] = []
|
||||
ally_battles_air: List[classes.Battle] = []
|
||||
ally_battles_ground: List[classes.Battle] = []
|
||||
other_battles_air: List[classes.Battle] = []
|
||||
other_battles_ground: List[classes.Battle] = []
|
||||
|
||||
ret_battles: List[Battle] = []
|
||||
ret_battles: List[classes.Battle] = []
|
||||
if sort_by_time:
|
||||
battle_list = sorted(self.all_battles.values(), key=lambda b: b.start)
|
||||
battle_list.reverse()
|
||||
@ -1520,20 +1485,22 @@ class CitizenMilitary(CitizenTravel):
|
||||
ret_battles = ret_battles + cs_battles + deployed_battles + other_battles
|
||||
return ret_battles
|
||||
|
||||
def get_cheap_tp_divisions(self) -> Optional[BattleDivision]:
|
||||
air_divs: List[Tuple[BattleDivision, int]] = []
|
||||
ground_divs: List[Tuple[BattleDivision, int]] = []
|
||||
def get_cheap_tp_divisions(self) -> Optional[classes.BattleDivision]:
|
||||
air_divs: List[Tuple[classes.BattleDivision, int]] = []
|
||||
ground_divs: List[Tuple[classes.BattleDivision, int]] = []
|
||||
for battle in reversed(self.sorted_battles(True, True)):
|
||||
for division in battle.div.values():
|
||||
if not division.terrain:
|
||||
if division.is_air:
|
||||
medal = self.get_battle_round_data(division)[self.details.citizenship == division.battle.defender.id]
|
||||
medal = self.get_battle_round_data(division)[
|
||||
self.details.citizenship == division.battle.defender.id]
|
||||
if not medal and division.battle.start:
|
||||
return division
|
||||
else:
|
||||
air_divs.append((division, medal.get('1').get('raw_value')))
|
||||
else:
|
||||
medal = self.get_battle_round_data(division)[self.details.citizenship == division.battle.defender.id]
|
||||
medal = self.get_battle_round_data(division)[
|
||||
self.details.citizenship == division.battle.defender.id]
|
||||
if not medal and division.battle.start:
|
||||
return division
|
||||
else:
|
||||
@ -1554,9 +1521,9 @@ class CitizenMilitary(CitizenTravel):
|
||||
if self.should_fight()[0]:
|
||||
self.write_log("Checking for battles to fight in...")
|
||||
for battle in self.sorted_battles(self.config.sort_battles_time):
|
||||
if not isinstance(battle, Battle):
|
||||
if not isinstance(battle, classes.Battle):
|
||||
continue
|
||||
battle_zone: Optional[BattleDivision] = None
|
||||
battle_zone: Optional[classes.BattleDivision] = None
|
||||
for div in battle.div.values():
|
||||
if div.terrain == 0:
|
||||
if div.div_end:
|
||||
@ -1571,7 +1538,8 @@ class CitizenMilitary(CitizenTravel):
|
||||
continue
|
||||
if not battle_zone:
|
||||
continue
|
||||
allies = battle.invader.deployed + battle.defender.deployed + [battle.invader.country, battle.defender.country]
|
||||
allies = battle.invader.deployed + battle.defender.deployed + [battle.invader.country,
|
||||
battle.defender.country]
|
||||
|
||||
travel_needed = self.details.current_country not in allies
|
||||
|
||||
@ -1610,7 +1578,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
self.travel_to_residence()
|
||||
break
|
||||
|
||||
def fight(self, battle: Battle, division: BattleDivision, side: BattleSide = None, count: int = None) -> int:
|
||||
def fight(self, battle: classes.Battle, division: classes.BattleDivision, side: classes.BattleSide = None, count: int = None) -> int:
|
||||
"""Fight in a battle.
|
||||
|
||||
Will auto activate booster and travel if allowed to do it.
|
||||
@ -1632,7 +1600,8 @@ class CitizenMilitary(CitizenTravel):
|
||||
if not division.is_air and self.config.boosters:
|
||||
self.activate_dmg_booster()
|
||||
if side is None:
|
||||
side = battle.defender if self.details.citizenship in battle.defender.allies + [battle.defender.country] else battle.invader
|
||||
side = battle.defender if self.details.citizenship in battle.defender.allies + [
|
||||
battle.defender.country] else battle.invader
|
||||
error_count = 0
|
||||
ok_to_fight = True
|
||||
if count is None:
|
||||
@ -1657,7 +1626,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
air=battle.has_air, hits=total_hits))
|
||||
return error_count
|
||||
|
||||
def _shoot(self, battle: Battle, division: BattleDivision, side: BattleSide):
|
||||
def _shoot(self, battle: classes.Battle, division: classes.BattleDivision, side: classes.BattleSide):
|
||||
if division.is_air:
|
||||
response = self._post_military_fight_air(battle.id, side.id, division.id)
|
||||
else:
|
||||
@ -1679,7 +1648,8 @@ class CitizenMilitary(CitizenTravel):
|
||||
elif r_json.get("message") == "NOT_ENOUGH_WEAPONS":
|
||||
self.set_default_weapon(battle, division)
|
||||
elif r_json.get("message") == "FIGHT_DISABLED":
|
||||
self._post_main_profile_update('options', params='{"optionName":"enable_web_deploy","optionValue":"off"}')
|
||||
self._post_main_profile_update('options',
|
||||
params='{"optionName":"enable_web_deploy","optionValue":"off"}')
|
||||
self.set_default_weapon(battle, division)
|
||||
else:
|
||||
if r_json.get("message") == "UNKNOWN_SIDE":
|
||||
@ -1698,7 +1668,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
|
||||
return hits, err, damage
|
||||
|
||||
def deploy_bomb(self, battle: Battle, bomb_id: int, inv_side: bool = None, count: int = 1) -> int:
|
||||
def deploy_bomb(self, battle: classes.Battle, bomb_id: int, inv_side: bool = None, count: int = 1) -> int:
|
||||
"""Deploy bombs in a battle for given side.
|
||||
|
||||
:param battle: Battle
|
||||
@ -1724,7 +1694,8 @@ class CitizenMilitary(CitizenTravel):
|
||||
if self.details.current_country not in good_countries:
|
||||
has_traveled = self.travel_to_battle(battle, good_countries)
|
||||
else:
|
||||
involved = [battle.invader.country, battle.defender.country] + battle.invader.deployed + battle.defender.deployed
|
||||
involved = [battle.invader.country,
|
||||
battle.defender.country] + battle.invader.deployed + battle.defender.deployed
|
||||
if self.details.current_country not in involved:
|
||||
count = 0
|
||||
errors = deployed_count = 0
|
||||
@ -1743,7 +1714,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
self._report_action("MILITARY_BOMB", f"Deployed {deployed_count} bombs in battle {battle.id}")
|
||||
return deployed_count
|
||||
|
||||
def change_division(self, battle: Battle, division: BattleDivision):
|
||||
def change_division(self, battle: classes.Battle, division: classes.BattleDivision):
|
||||
"""Change division.
|
||||
|
||||
:param battle: Battle
|
||||
@ -1790,7 +1761,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
duration = length
|
||||
break
|
||||
if duration:
|
||||
self._report_action("MILITARY_BOOSTER", f"Activated 50% {duration/60}h damage booster")
|
||||
self._report_action("MILITARY_BOOSTER", f"Activated 50% {duration / 60}h damage booster")
|
||||
self._post_economy_activate_booster(5, duration, "damage")
|
||||
|
||||
def get_active_ground_damage_booster(self):
|
||||
@ -1810,7 +1781,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
self._report_action('MILITARY_BOOSTER', 'Activated PrestigePoint booster')
|
||||
return self._post_military_fight_activate_booster(battle_id, 1, 180, "prestige_points")
|
||||
|
||||
def _rw_choose_side(self, battle: Battle, side: BattleSide) -> Response:
|
||||
def _rw_choose_side(self, battle: classes.Battle, side: classes.BattleSide) -> Response:
|
||||
return self._post_main_battlefield_travel(side.id, battle.id)
|
||||
|
||||
def should_travel_to_fight(self) -> bool:
|
||||
@ -1884,7 +1855,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
|
||||
return (count if count > 0 else 0), msg, force_fight
|
||||
|
||||
def get_battle_round_data(self, division: BattleDivision) -> Tuple[Any, Any]:
|
||||
def get_battle_round_data(self, division: classes.BattleDivision) -> Tuple[Any, Any]:
|
||||
battle = division.battle
|
||||
|
||||
data = dict(zoneId=battle.zone_id, round_id=battle.zone_id, division=division.div,
|
||||
@ -1900,7 +1871,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
self.get_csrf_token()
|
||||
self.launch_attack(war_id, region_id, region_name)
|
||||
|
||||
def get_active_wars(self, country: Country = None) -> List[int]:
|
||||
def get_active_wars(self, country: constants.Country = None) -> List[int]:
|
||||
r = self._get_country_military(country.link if country else self.details.citizenship.link)
|
||||
all_war_ids = re.findall(r'//www\.erepublik\.com/en/wars/show/(\d+)"', r.text)
|
||||
return [int(wid) for wid in all_war_ids]
|
||||
@ -1917,11 +1888,11 @@ class CitizenMilitary(CitizenTravel):
|
||||
self._post_wars_attack_region(war_id, region_id, region_name)
|
||||
self._report_action("MILITARY_QUEUE_ATTACK", f"Battle for *{region_name}* queued")
|
||||
|
||||
def travel_to_battle(self, battle: Battle, allowed_countries: List[Country]) -> bool:
|
||||
def travel_to_battle(self, battle: classes.Battle, allowed_countries: List[constants.Country]) -> bool:
|
||||
data = self.get_travel_regions(battle=battle)
|
||||
|
||||
regs = []
|
||||
countries: Dict[int, Country] = {c.id: c for c in allowed_countries}
|
||||
countries: Dict[int, constants.Country] = {c.id: c for c in allowed_countries}
|
||||
if data:
|
||||
for region in data.values():
|
||||
if region['countryId'] in countries: # Is not occupied by other country
|
||||
@ -1936,7 +1907,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
return True
|
||||
return False
|
||||
|
||||
def get_country_mus(self, country: Country) -> Dict[int, str]:
|
||||
def get_country_mus(self, country: constants.Country) -> Dict[int, str]:
|
||||
ret = {}
|
||||
r = self._get_main_leaderboards_damage_rankings(country.id)
|
||||
for data in r.json()["mu_filter"]:
|
||||
@ -1974,7 +1945,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
|
||||
|
||||
class CitizenPolitics(BaseCitizen):
|
||||
def get_country_parties(self, country: Country = None) -> dict:
|
||||
def get_country_parties(self, country: constants.Country = None) -> dict:
|
||||
r = self._get_main_rankings_parties(country.id if country else self.details.citizenship.id)
|
||||
ret = {}
|
||||
for name, id_ in re.findall(r'<a class="dotted" title="([^"]+)" href="/en/party/[\w\d-]+-(\d+)/1">', r.text):
|
||||
@ -1989,13 +1960,15 @@ class CitizenPolitics(BaseCitizen):
|
||||
self._report_action('POLITIC_PARTY_PRESIDENT', 'Applied for party president elections')
|
||||
return self._get_candidate_party(self.politics.party_slug)
|
||||
|
||||
def get_country_president_election_result(self, country: Country, year: int, month: int) -> Dict[str, int]:
|
||||
timestamp = int(erep_tz.localize(datetime(year, month, 5)).timestamp())
|
||||
def get_country_president_election_result(self, country: constants.Country, year: int, month: int) -> Dict[str, int]:
|
||||
timestamp = int(constants.erep_tz.localize(datetime(year, month, 5)).timestamp())
|
||||
resp = self._get_presidential_elections(country.id, timestamp)
|
||||
candidates = re.findall(r'class="candidate_info">(.*?)</li>', resp.text, re.S | re.M)
|
||||
ret = {}
|
||||
for candidate in candidates:
|
||||
name = re.search(r'<a hovercard=1 class="candidate_name" href="//www.erepublik.com/en/citizen/profile/\d+" title="(.*)">', candidate)
|
||||
name = re.search(
|
||||
r'<a hovercard=1 class="candidate_name" href="//www.erepublik.com/en/citizen/profile/\d+" title="(.*)">',
|
||||
candidate)
|
||||
name = name.group(1)
|
||||
votes = re.search(r'<span class="votes">(\d+) votes</span>', candidate).group(1)
|
||||
ret.update({name: int(votes)})
|
||||
@ -2251,7 +2224,7 @@ class Citizen(CitizenAnniversary, CitizenCompanies, CitizenEconomy, CitizenLeade
|
||||
|
||||
def __init__(self, email: str = "", password: str = "", auto_login: bool = True):
|
||||
super().__init__(email, password)
|
||||
self.__last_full_update = utils.good_timedelta(self.now, - timedelta(minutes=5))
|
||||
self._last_full_update = utils.good_timedelta(self.now, - timedelta(minutes=5))
|
||||
self.set_debug(True)
|
||||
if auto_login:
|
||||
self.login()
|
||||
@ -2276,7 +2249,7 @@ class Citizen(CitizenAnniversary, CitizenCompanies, CitizenEconomy, CitizenLeade
|
||||
"" if self.config.telegram_chat_id or self.config.telegram_token else self.name)
|
||||
self.telegram.send_message(f"*Started* {utils.now():%F %T}")
|
||||
|
||||
self.__last_full_update = utils.good_timedelta(self.now, - timedelta(minutes=5))
|
||||
self._last_full_update = utils.good_timedelta(self.now, - timedelta(minutes=5))
|
||||
self.update_all(True)
|
||||
|
||||
def update_citizen_info(self, html: str = None):
|
||||
@ -2351,10 +2324,10 @@ class Citizen(CitizenAnniversary, CitizenCompanies, CitizenEconomy, CitizenLeade
|
||||
|
||||
def update_all(self, force_update=False):
|
||||
# Do full update max every 5 min
|
||||
if utils.good_timedelta(self.__last_full_update, timedelta(minutes=5)) > self.now and not force_update:
|
||||
if utils.good_timedelta(self._last_full_update, timedelta(minutes=5)) > self.now and not force_update:
|
||||
return
|
||||
else:
|
||||
self.__last_full_update = self.now
|
||||
self._last_full_update = self.now
|
||||
self.update_citizen_info()
|
||||
self.update_war_info()
|
||||
self.update_inventory()
|
||||
@ -2467,7 +2440,7 @@ class Citizen(CitizenAnniversary, CitizenCompanies, CitizenEconomy, CitizenLeade
|
||||
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)
|
||||
item = "{}_{}".format(constants.INDUSTRIES[kind], quality)
|
||||
amount = inv_resp.get("inventoryItems").get(category).get("items").get(item).get("amount", 0)
|
||||
|
||||
if amount >= 1:
|
||||
@ -2478,10 +2451,10 @@ class Citizen(CitizenAnniversary, CitizenCompanies, CitizenEconomy, CitizenLeade
|
||||
else:
|
||||
price = lowest_price.price - 0.01
|
||||
|
||||
self.post_market_offer(industry=self.available_industries[kind], amount=int(amount),
|
||||
self.post_market_offer(industry=constants.INDUSTRIES[kind], amount=int(amount),
|
||||
quality=int(quality), price=price)
|
||||
|
||||
def _wam(self, holding: Holding) -> NoReturn:
|
||||
def _wam(self, holding: classes.Holding) -> NoReturn:
|
||||
response = self.work_as_manager_in_holding(holding)
|
||||
if response is None:
|
||||
return
|
||||
@ -2496,7 +2469,7 @@ class Citizen(CitizenAnniversary, CitizenCompanies, CitizenEconomy, CitizenLeade
|
||||
elif kind.endswith("Raw"):
|
||||
self.sell_produced_product(kind, 1)
|
||||
else:
|
||||
raise ErepublikException("Unknown kind produced '{kind}'".format(kind=kind))
|
||||
raise classes.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:
|
||||
@ -2542,7 +2515,7 @@ class Citizen(CitizenAnniversary, CitizenCompanies, CitizenEconomy, CitizenLeade
|
||||
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: Dict[int, Holding] = {}
|
||||
regions: Dict[int, classes.Holding] = {}
|
||||
for holding in self.my_companies.holdings.values():
|
||||
if holding.wam_count:
|
||||
regions.update({holding.region: holding})
|
||||
@ -2570,8 +2543,8 @@ class Citizen(CitizenAnniversary, CitizenCompanies, CitizenEconomy, CitizenLeade
|
||||
self.update_companies()
|
||||
return bool(self.my_companies.get_total_wam_count())
|
||||
|
||||
def sorted_battles(self, sort_by_time: bool = True, only_tp=False) -> List[Battle]:
|
||||
battles: List[Battle] = self.reporter.fetch_battle_priorities(self.details.current_country)
|
||||
def sorted_battles(self, sort_by_time: bool = True, only_tp=False) -> List[classes.Battle]:
|
||||
battles: List[classes.Battle] = self.reporter.fetch_battle_priorities(self.details.current_country)
|
||||
return battles + super().sorted_battles(sort_by_time, only_tp)
|
||||
|
||||
def command_central(self):
|
||||
|
@ -6,52 +6,10 @@ from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union
|
||||
|
||||
from requests import Response, Session, post
|
||||
|
||||
from erepublik import utils
|
||||
from erepublik.utils import json
|
||||
from . import utils, constants
|
||||
|
||||
INDUSTRIES = {1: "Food", 2: "Weapons", 4: "House", 23: "Aircraft",
|
||||
7: "FRM q1", 8: "FRM q2", 9: "FRM q3", 10: "FRM q4", 11: "FRM q5",
|
||||
12: "WRM q1", 13: "WRM q2", 14: "WRM q3", 15: "WRM q4", 16: "WRM q5",
|
||||
18: "HRM q1", 19: "HRM q2", 20: "HRM q3", 21: "HRM q4", 22: "HRM q5",
|
||||
24: "ARM q1", 25: "ARM q2", 26: "ARM q3", 27: "ARM q4", 28: "ARM q5", }
|
||||
|
||||
|
||||
class Country:
|
||||
id: int
|
||||
name: str
|
||||
link: str
|
||||
iso: str
|
||||
|
||||
def __init__(self, country_id: int, name: str, link: str, iso: str):
|
||||
self.id = country_id
|
||||
self.name = name
|
||||
self.link = link
|
||||
self.iso = iso
|
||||
|
||||
def __repr__(self):
|
||||
return f"Country({self.id}, '{self.name}', '{self.link}', '{self.iso}')"
|
||||
|
||||
def __str__(self):
|
||||
return f"#{self.id} {self.name}"
|
||||
|
||||
def __format__(self, format_spec):
|
||||
return self.iso
|
||||
|
||||
def __int__(self):
|
||||
return self.id
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, (int, float)):
|
||||
return self.id == int(other)
|
||||
else:
|
||||
try:
|
||||
return self.id == int(other)
|
||||
except ValueError:
|
||||
return self == other
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
return dict(id=self.id, name=self.name, iso=self.iso)
|
||||
__all__ = ['Battle', 'BattleDivision', 'BattleSide', 'Company', 'Config', 'Details', 'Energy', 'ErepublikException',
|
||||
'Holding', 'MyCompanies', 'MyJSONEncoder', 'OfferItem', 'Politics', 'Reporter', 'TelegramBot']
|
||||
|
||||
|
||||
class ErepublikException(Exception):
|
||||
@ -132,7 +90,7 @@ class Holding:
|
||||
return str(self)
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
def as_dict(self):
|
||||
return dict(name=str(self), id=self.id, region=self.region, companies=self.companies, wam_count=self.wam_count)
|
||||
|
||||
|
||||
@ -229,7 +187,7 @@ class Company:
|
||||
return self._sort_keys != other._sort_keys
|
||||
|
||||
def __str__(self):
|
||||
name = f"(#{self.id:>9d}) {INDUSTRIES[self.industry]}"
|
||||
name = f"(#{self.id:>9d}) {constants.INDUSTRIES[self.industry]}"
|
||||
if not self.is_raw:
|
||||
name += f" q{self.quality}"
|
||||
return name
|
||||
@ -238,7 +196,7 @@ class Company:
|
||||
return str(self)
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
def as_dict(self):
|
||||
return dict(name=str(self), holding=self.holding.id, id=self.id, quality=self.quality, is_raw=self.is_raw,
|
||||
raw_usage=self.raw_usage, products_made=self.products_made, wam_enabled=self.wam_enabled,
|
||||
can_wam=self.can_wam, cannot_wam_reason=self.cannot_wam_reason, industry=self.industry,
|
||||
@ -328,7 +286,7 @@ class MyCompanies:
|
||||
self.companies.clear()
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
def as_dict(self):
|
||||
return dict(name=str(self), work_units=self.work_units, next_ot_time=self.next_ot_time,
|
||||
ff_lockdown=self.ff_lockdown, holdings=self.holdings, company_count=len(self.companies))
|
||||
|
||||
@ -397,7 +355,7 @@ class Config:
|
||||
self.telegram_token = ""
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
def as_dict(self):
|
||||
return dict(email=self.email, work=self.work, train=self.train, wam=self.wam, ot=self.ot,
|
||||
auto_sell=self.auto_sell, auto_sell_all=self.auto_sell_all, employees=self.employees,
|
||||
fight=self.fight, air=self.air, ground=self.ground, all_in=self.all_in,
|
||||
@ -453,6 +411,13 @@ class Energy:
|
||||
def available(self):
|
||||
return self.recovered + self.recoverable
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
return dict(limit=self.limit, interval=self.interval, recoverable=self.recoverable, recovered=self.recovered,
|
||||
reference_time=self.reference_time, food_fights=self.food_fights,
|
||||
is_recoverable_full=self.is_recoverable_full, is_recovered_full=self.is_recovered_full,
|
||||
is_energy_full=self.is_energy_full, available=self.available)
|
||||
|
||||
|
||||
class Details:
|
||||
xp = 0
|
||||
@ -462,11 +427,11 @@ class Details:
|
||||
gold = 0
|
||||
next_pp: List[int] = None
|
||||
citizen_id = 0
|
||||
citizenship: Country
|
||||
citizenship: constants.Country
|
||||
current_region = 0
|
||||
current_country: Country
|
||||
current_country: constants.Country
|
||||
residence_region = 0
|
||||
residence_country: Country
|
||||
residence_country: constants.Country
|
||||
daily_task_done = False
|
||||
daily_task_reward = False
|
||||
mayhem_skills = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0, 8: 0, 9: 0, 10: 0, 11: 0, 12: 0, 13: 0, 14: 0, }
|
||||
@ -500,6 +465,15 @@ class Details:
|
||||
next_level_up = (1 + (self.xp // 10)) * 10
|
||||
return next_level_up - self.xp
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
return dict(xp=self.xp, cc=self.cc, pp=self.pp, pin=self.pin, gold=self.gold, next_pp=self.next_pp,
|
||||
citizen_id=self.citizen_id, citizenship=self.citizenship, current_region=self.current_region,
|
||||
current_country=self.current_country, residence_region=self.residence_region,
|
||||
residence_country=self.residence_country, daily_task_done=self.daily_task_done,
|
||||
daily_task_reward=self.daily_task_reward, mayhem_skills=self.mayhem_skills,
|
||||
xp_till_level_up=self.xp_till_level_up)
|
||||
|
||||
|
||||
class Politics:
|
||||
is_party_member: bool = False
|
||||
@ -510,6 +484,12 @@ class Politics:
|
||||
is_congressman: bool = False
|
||||
is_country_president: bool = False
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
return dict(is_party_member=self.is_party_member, party_id=self.party_id, party_slug=self.party_slug,
|
||||
is_party_president=self.is_party_president, is_congressman=self.is_congressman,
|
||||
is_country_president=self.is_country_president)
|
||||
|
||||
|
||||
class House:
|
||||
quality = None
|
||||
@ -543,7 +523,7 @@ class Reporter:
|
||||
return self.citizen.details.citizen_id
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
def as_dict(self):
|
||||
return dict(name=self.name, email=self.email, citizen_id=self.citizen_id, key=self.key, allowed=self.allowed,
|
||||
queue=self.__to_update)
|
||||
|
||||
@ -614,7 +594,7 @@ class Reporter:
|
||||
def report_promo(self, kind: str, time_until: datetime.datetime):
|
||||
self._req.post(f"{self.url}/promos/add/", data=dict(kind=kind, time_untill=time_until))
|
||||
|
||||
def fetch_battle_priorities(self, country: Country) -> List["Battle"]:
|
||||
def fetch_battle_priorities(self, country: constants.Country) -> List["Battle"]:
|
||||
try:
|
||||
battle_response = self._req.get(f'{self.url}/api/v1/battles/{country.id}')
|
||||
return [self.citizen.all_battles[bid] for bid in battle_response.json().get('battle_ids', []) if
|
||||
@ -631,7 +611,7 @@ class Reporter:
|
||||
return
|
||||
|
||||
|
||||
class MyJSONEncoder(json.JSONEncoder):
|
||||
class MyJSONEncoder(utils.json.JSONEncoder):
|
||||
def default(self, o):
|
||||
from erepublik.citizen import Citizen
|
||||
if isinstance(o, Decimal):
|
||||
@ -646,8 +626,8 @@ class MyJSONEncoder(json.JSONEncoder):
|
||||
microseconds=o.microseconds, total_seconds=o.total_seconds())
|
||||
elif isinstance(o, Response):
|
||||
return dict(headers=o.headers.__dict__, url=o.url, text=o.text)
|
||||
elif hasattr(o, '__dict__'):
|
||||
return o.__dict__
|
||||
elif hasattr(o, 'as_dict'):
|
||||
return o.as_dict
|
||||
elif isinstance(o, set):
|
||||
return list(o)
|
||||
elif isinstance(o, Citizen):
|
||||
@ -660,14 +640,14 @@ class MyJSONEncoder(json.JSONEncoder):
|
||||
|
||||
class BattleSide:
|
||||
points: int
|
||||
deployed: List[Country]
|
||||
allies: List[Country]
|
||||
deployed: List[constants.Country]
|
||||
allies: List[constants.Country]
|
||||
battle: "Battle"
|
||||
country: Country
|
||||
country: constants.Country
|
||||
defender: bool
|
||||
|
||||
def __init__(self, battle: "Battle", country: Country, points: int, allies: List[Country], deployed: List[Country],
|
||||
defender: bool):
|
||||
def __init__(self, battle: "Battle", country: constants.Country, points: int, allies: List[constants.Country],
|
||||
deployed: List[constants.Country], defender: bool):
|
||||
self.battle = battle
|
||||
self.country = country
|
||||
self.points = points
|
||||
@ -691,7 +671,7 @@ class BattleSide:
|
||||
return self.country.iso
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
def as_dict(self):
|
||||
return dict(points=self.points, country=self.country, defender=self.defender, allies=self.allies,
|
||||
deployed=self.deployed, battle=repr(self.battle))
|
||||
|
||||
@ -709,9 +689,9 @@ class BattleDivision:
|
||||
battle: "Battle"
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
def as_dict(self):
|
||||
return dict(id=self.id, division=self.div, terrain=(self.terrain, self.terrain_display), wall=self.wall,
|
||||
dom_pts=self.dom_pts, epic=self.epic, battle=str(self.battle), end=self.div_end)
|
||||
epic=self.epic, battle=str(self.battle), end=self.div_end)
|
||||
|
||||
@property
|
||||
def is_air(self):
|
||||
@ -743,7 +723,7 @@ class BattleDivision:
|
||||
|
||||
@property
|
||||
def terrain_display(self):
|
||||
return _TERRAINS[self.terrain]
|
||||
return constants.TERRAINS[self.terrain]
|
||||
|
||||
def __str__(self):
|
||||
base_name = f"Div #{self.id} d{self.div}"
|
||||
@ -771,7 +751,7 @@ class Battle:
|
||||
region_name: str
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
def as_dict(self):
|
||||
return dict(id=self.id, war_id=self.war_id, divisions=self.div, zone=self.zone_id, rw=self.is_rw,
|
||||
dict_lib=self.is_dict_lib, start=self.start, sides={'inv': self.invader, 'def': self.defender},
|
||||
region=[self.region_id, self.region_name])
|
||||
@ -805,27 +785,28 @@ class Battle:
|
||||
self.zone_id = int(battle.get('zone_id'))
|
||||
self.is_rw = bool(battle.get('is_rw'))
|
||||
self.is_as = bool(battle.get('is_as'))
|
||||
self.is_dict_lib = bool(battle.get('is_dict')) or bool(battle.get('is_lib'))
|
||||
self.region_id = battle.get('region', {}).get('id')
|
||||
self.region_name = battle.get('region', {}).get('name')
|
||||
self.start = datetime.datetime.fromtimestamp(int(battle.get('start', 0)), tz=utils.erep_tz)
|
||||
self.start = datetime.datetime.fromtimestamp(int(battle.get('start', 0)), tz=constants.erep_tz)
|
||||
|
||||
self.invader = BattleSide(
|
||||
self, COUNTRIES[battle.get('inv', {}).get('id')], battle.get('inv', {}).get('points'),
|
||||
[COUNTRIES[row.get('id')] for row in battle.get('inv', {}).get('ally_list')],
|
||||
[COUNTRIES[row.get('id')] for row in battle.get('inv', {}).get('ally_list') if row['deployed']], False
|
||||
self, constants.COUNTRIES[battle.get('inv', {}).get('id')], battle.get('inv', {}).get('points'),
|
||||
[constants.COUNTRIES[row.get('id')] for row in battle.get('inv', {}).get('ally_list')],
|
||||
[constants.COUNTRIES[row.get('id')] for row in battle.get('inv', {}).get('ally_list') if row['deployed']], False
|
||||
)
|
||||
|
||||
self.defender = BattleSide(
|
||||
self, COUNTRIES[battle.get('def', {}).get('id')], battle.get('def', {}).get('points'),
|
||||
[COUNTRIES[row.get('id')] for row in battle.get('def', {}).get('ally_list')],
|
||||
[COUNTRIES[row.get('id')] for row in battle.get('def', {}).get('ally_list') if row['deployed']], True
|
||||
self, constants.COUNTRIES[battle.get('def', {}).get('id')], battle.get('def', {}).get('points'),
|
||||
[constants.COUNTRIES[row.get('id')] for row in battle.get('def', {}).get('ally_list')],
|
||||
[constants.COUNTRIES[row.get('id')] for row in battle.get('def', {}).get('ally_list') if row['deployed']], True
|
||||
)
|
||||
|
||||
self.div = {}
|
||||
for div, data in battle.get('div', {}).items():
|
||||
div = int(div)
|
||||
if data.get('end'):
|
||||
end = datetime.datetime.fromtimestamp(data.get('end'), tz=utils.erep_tz)
|
||||
end = datetime.datetime.fromtimestamp(data.get('end'), tz=constants.erep_tz)
|
||||
else:
|
||||
end = utils.localize_dt(datetime.datetime.max - datetime.timedelta(days=1))
|
||||
|
||||
@ -838,12 +819,12 @@ class Battle:
|
||||
self.div.update({div: battle_div})
|
||||
|
||||
def __str__(self):
|
||||
now = utils.now()
|
||||
time_now = utils.now()
|
||||
is_started = self.start < utils.now()
|
||||
if is_started:
|
||||
time_part = " {}".format(now - self.start)
|
||||
time_part = " {}".format(time_now - self.start)
|
||||
else:
|
||||
time_part = "-{}".format(self.start - now)
|
||||
time_part = "-{}".format(self.start - time_now)
|
||||
|
||||
return f"Battle {self.id} for {self.region_name[:16]} | {self.invader} : {self.defender} | Round time {time_part}"
|
||||
|
||||
@ -902,7 +883,7 @@ class TelegramBot:
|
||||
self._next_time = utils.now()
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
def as_dict(self):
|
||||
return {'chat_id': self.chat_id, 'api_url': self.api_url, 'player': self.player_name,
|
||||
'last_time': self._last_time, 'next_time': self._next_time, 'queue': self.__queue,
|
||||
'initialized': self.__initialized, 'has_threads': bool(len(self._threads))}
|
||||
@ -962,54 +943,7 @@ class TelegramBot:
|
||||
|
||||
class OfferItem(NamedTuple):
|
||||
price: float = 99_999.
|
||||
country: Country = Country(0, "", "", "")
|
||||
country: constants.Country = constants.Country(0, "", "", "")
|
||||
amount: int = 0
|
||||
offer_id: int = 0
|
||||
citizen_id: int = 0
|
||||
|
||||
|
||||
COUNTRIES: Dict[int, Country] = {
|
||||
1: Country(1, 'Romania', 'Romania', 'ROU'), 9: Country(9, 'Brazil', 'Brazil', 'BRA'),
|
||||
10: Country(10, 'Italy', 'Italy', 'ITA'), 11: Country(11, 'France', 'France', 'FRA'),
|
||||
12: Country(12, 'Germany', 'Germany', 'DEU'), 13: Country(13, 'Hungary', 'Hungary', 'HUN'),
|
||||
14: Country(14, 'China', 'China', 'CHN'), 15: Country(15, 'Spain', 'Spain', 'ESP'),
|
||||
23: Country(23, 'Canada', 'Canada', 'CAN'), 24: Country(24, 'USA', 'USA', 'USA'),
|
||||
26: Country(26, 'Mexico', 'Mexico', 'MEX'), 27: Country(27, 'Argentina', 'Argentina', 'ARG'),
|
||||
28: Country(28, 'Venezuela', 'Venezuela', 'VEN'), 29: Country(29, 'United Kingdom', 'United-Kingdom', 'GBR'),
|
||||
30: Country(30, 'Switzerland', 'Switzerland', 'CHE'), 31: Country(31, 'Netherlands', 'Netherlands', 'NLD'),
|
||||
32: Country(32, 'Belgium', 'Belgium', 'BEL'), 33: Country(33, 'Austria', 'Austria', 'AUT'),
|
||||
34: Country(34, 'Czech Republic', 'Czech-Republic', 'CZE'), 35: Country(35, 'Poland', 'Poland', 'POL'),
|
||||
36: Country(36, 'Slovakia', 'Slovakia', 'SVK'), 37: Country(37, 'Norway', 'Norway', 'NOR'),
|
||||
38: Country(38, 'Sweden', 'Sweden', 'SWE'), 39: Country(39, 'Finland', 'Finland', 'FIN'),
|
||||
40: Country(40, 'Ukraine', 'Ukraine', 'UKR'), 41: Country(41, 'Russia', 'Russia', 'RUS'),
|
||||
42: Country(42, 'Bulgaria', 'Bulgaria', 'BGR'), 43: Country(43, 'Turkey', 'Turkey', 'TUR'),
|
||||
44: Country(44, 'Greece', 'Greece', 'GRC'), 45: Country(45, 'Japan', 'Japan', 'JPN'),
|
||||
47: Country(47, 'South Korea', 'South-Korea', 'KOR'), 48: Country(48, 'India', 'India', 'IND'),
|
||||
49: Country(49, 'Indonesia', 'Indonesia', 'IDN'), 50: Country(50, 'Australia', 'Australia', 'AUS'),
|
||||
51: Country(51, 'South Africa', 'South Africa', 'ZAF'),
|
||||
52: Country(52, 'Republic of Moldova', 'Republic-of-Moldova', 'MDA'),
|
||||
53: Country(53, 'Portugal', 'Portugal', 'PRT'), 54: Country(54, 'Ireland', 'Ireland', 'IRL'),
|
||||
55: Country(55, 'Denmark', 'Denmark', 'DNK'), 56: Country(56, 'Iran', 'Iran', 'IRN'),
|
||||
57: Country(57, 'Pakistan', 'Pakistan', 'PAK'), 58: Country(58, 'Israel', 'Israel', 'ISR'),
|
||||
59: Country(59, 'Thailand', 'Thailand', 'THA'), 61: Country(61, 'Slovenia', 'Slovenia', 'SVN'),
|
||||
63: Country(63, 'Croatia', 'Croatia', 'HRV'), 64: Country(64, 'Chile', 'Chile', 'CHL'),
|
||||
65: Country(65, 'Serbia', 'Serbia', 'SRB'), 66: Country(66, 'Malaysia', 'Malaysia', 'MYS'),
|
||||
67: Country(67, 'Philippines', 'Philippines', 'PHL'), 68: Country(68, 'Singapore', 'Singapore', 'SGP'),
|
||||
69: Country(69, 'Bosnia and Herzegovina', 'Bosnia-Herzegovina', 'BiH'),
|
||||
70: Country(70, 'Estonia', 'Estonia', 'EST'), 80: Country(80, 'Montenegro', 'Montenegro', 'MNE'),
|
||||
71: Country(71, 'Latvia', 'Latvia', 'LVA'), 72: Country(72, 'Lithuania', 'Lithuania', 'LTU'),
|
||||
73: Country(73, 'North Korea', 'North-Korea', 'PRK'), 74: Country(74, 'Uruguay', 'Uruguay', 'URY'),
|
||||
75: Country(75, 'Paraguay', 'Paraguay', 'PRY'), 76: Country(76, 'Bolivia', 'Bolivia', 'BOL'),
|
||||
77: Country(77, 'Peru', 'Peru', 'PER'), 78: Country(78, 'Colombia', 'Colombia', 'COL'),
|
||||
79: Country(79, 'Republic of Macedonia (FYROM)', 'Republic-of-Macedonia-FYROM', 'MKD'),
|
||||
81: Country(81, 'Republic of China (Taiwan)', 'Republic-of-China-Taiwan', 'TWN'),
|
||||
82: Country(82, 'Cyprus', 'Cyprus', 'CYP'), 167: Country(167, 'Albania', 'Albania', 'ALB'),
|
||||
83: Country(83, 'Belarus', 'Belarus', 'BLR'), 84: Country(84, 'New Zealand', 'New-Zealand', 'NZL'),
|
||||
164: Country(164, 'Saudi Arabia', 'Saudi-Arabia', 'SAU'), 165: Country(165, 'Egypt', 'Egypt', 'EGY'),
|
||||
166: Country(166, 'United Arab Emirates', 'United-Arab-Emirates', 'UAE'),
|
||||
168: Country(168, 'Georgia', 'Georgia', 'GEO'), 169: Country(169, 'Armenia', 'Armenia', 'ARM'),
|
||||
170: Country(170, 'Nigeria', 'Nigeria', 'NGA'), 171: Country(171, 'Cuba', 'Cuba', 'CUB')
|
||||
}
|
||||
|
||||
_TERRAINS = {0: "Standard", 1: 'Industrial', 2: 'Urban', 3: 'Suburbs', 4: 'Airport', 5: 'Plains', 6: 'Wasteland',
|
||||
7: 'Mountains', 8: 'Beach', 9: 'Swamp', 10: 'Mud', 11: 'Hills', 12: 'Jungle', 13: 'Forest', 14: 'Desert'}
|
||||
|
182
erepublik/constants.py
Normal file
182
erepublik/constants.py
Normal file
@ -0,0 +1,182 @@
|
||||
from typing import Dict, Optional, Union
|
||||
|
||||
import pytz
|
||||
|
||||
__all__ = ["erep_tz", "Country", "AIR_RANKS", "COUNTRIES", "FOOD_ENERGY", "GROUND_RANKS", "GROUND_RANK_POINTS", "INDUSTRIES", "TERRAINS"]
|
||||
|
||||
erep_tz = pytz.timezone('US/Pacific')
|
||||
|
||||
|
||||
class Country:
|
||||
id: int
|
||||
name: str
|
||||
link: str
|
||||
iso: str
|
||||
|
||||
def __init__(self, country_id: int, name: str, link: str, iso: str):
|
||||
self.id = country_id
|
||||
self.name = name
|
||||
self.link = link
|
||||
self.iso = iso
|
||||
|
||||
def __repr__(self):
|
||||
return f"Country({self.id}, '{self.name}', '{self.link}', '{self.iso}')"
|
||||
|
||||
def __str__(self):
|
||||
return f"#{self.id} {self.name}"
|
||||
|
||||
def __format__(self, format_spec):
|
||||
return self.iso
|
||||
|
||||
def __int__(self):
|
||||
return self.id
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, (int, float)):
|
||||
return self.id == int(other)
|
||||
else:
|
||||
try:
|
||||
return self.id == int(other)
|
||||
except ValueError:
|
||||
return self == other
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
return dict(id=self.id, name=self.name, iso=self.iso)
|
||||
|
||||
|
||||
class Industries:
|
||||
__by_name = {'food': 1, 'weapons': 2, 'house': 4, 'aircraft': 23,
|
||||
'frm q1': 7, 'frm q2': 8, 'frm q3': 9, 'frm q4': 10, 'frm q5': 11,
|
||||
'wrm q1': 12, 'wrm q2': 13, 'wrm q3': 14, 'wrm q4': 15, 'wrm q5': 16,
|
||||
'hrm q1': 18, 'hrm q2': 19, 'hrm q3': 20, 'hrm q4': 21, 'hrm q5': 22,
|
||||
'arm q1': 24, 'arm q2': 25, 'arm q3': 26, 'arm q4': 27, 'arm q5': 28}
|
||||
__by_id = {1: "Food", 2: "Weapons", 4: "House", 23: "Aircraft",
|
||||
7: "FRM q1", 8: "FRM q2", 9: "FRM q3", 10: "FRM q4", 11: "FRM q5",
|
||||
12: "WRM q1", 13: "WRM q2", 14: "WRM q3", 15: "WRM q4", 16: "WRM q5",
|
||||
18: "HRM q1", 19: "HRM q2", 20: "HRM q3", 21: "HRM q4", 22: "HRM q5",
|
||||
24: "ARM q1", 25: "ARM q2", 26: "ARM q3", 27: "ARM q4", 28: "ARM q5"}
|
||||
|
||||
def __getitem__(self, item) -> Optional[Union[int, str]]:
|
||||
if isinstance(item, int):
|
||||
return self.__by_id.get(item, None)
|
||||
elif isinstance(item, str):
|
||||
return self.__by_name.get(item.lower(), None)
|
||||
return
|
||||
|
||||
def __getattr__(self, item) -> Optional[Union[int, str]]:
|
||||
return self[item]
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
return dict(by_id=self.__by_id, by_name=self.__by_name)
|
||||
|
||||
|
||||
AIR_RANKS: Dict[int, str] = {
|
||||
1: "Airman", 2: "Airman 1st Class", 3: "Airman 1st Class*", 4: "Airman 1st Class**", 5: "Airman 1st Class***",
|
||||
6: "Airman 1st Class****", 7: "Airman 1st Class*****", 8: "Senior Airman", 9: "Senior Airman*",
|
||||
10: "Senior Airman**", 11: "Senior Airman***", 12: "Senior Airman****", 13: "Senior Airman*****",
|
||||
14: "Staff Sergeant", 15: "Staff Sergeant*", 16: "Staff Sergeant**", 17: "Staff Sergeant***",
|
||||
18: "Staff Sergeant****", 19: "Staff Sergeant*****", 20: "Aviator", 21: "Aviator*", 22: "Aviator**",
|
||||
23: "Aviator***", 24: "Aviator****", 25: "Aviator*****", 26: "Flight Lieutenant", 27: "Flight Lieutenant*",
|
||||
28: "Flight Lieutenant**", 29: "Flight Lieutenant***", 30: "Flight Lieutenant****", 31: "Flight Lieutenant*****",
|
||||
32: "Squadron Leader", 33: "Squadron Leader*", 34: "Squadron Leader**", 35: "Squadron Leader***",
|
||||
36: "Squadron Leader****", 37: "Squadron Leader*****", 38: "Chief Master Sergeant", 39: "Chief Master Sergeant*",
|
||||
40: "Chief Master Sergeant**", 41: "Chief Master Sergeant***", 42: "Chief Master Sergeant****",
|
||||
43: "Chief Master Sergeant*****", 44: "Wing Commander", 45: "Wing Commander*", 46: "Wing Commander**",
|
||||
47: "Wing Commander***", 48: "Wing Commander****", 49: "Wing Commander*****", 50: "Group Captain",
|
||||
51: "Group Captain*", 52: "Group Captain**", 53: "Group Captain***", 54: "Group Captain****",
|
||||
55: "Group Captain*****", 56: "Air Commodore", 57: "Air Commodore*", 58: "Air Commodore**", 59: "Air Commodore***",
|
||||
60: "Air Commodore****", 61: "Air Commodore*****",
|
||||
}
|
||||
|
||||
COUNTRIES: Dict[int, Country] = {
|
||||
1: Country(1, 'Romania', 'Romania', 'ROU'), 9: Country(9, 'Brazil', 'Brazil', 'BRA'),
|
||||
10: Country(10, 'Italy', 'Italy', 'ITA'), 11: Country(11, 'France', 'France', 'FRA'),
|
||||
12: Country(12, 'Germany', 'Germany', 'DEU'), 13: Country(13, 'Hungary', 'Hungary', 'HUN'),
|
||||
14: Country(14, 'China', 'China', 'CHN'), 15: Country(15, 'Spain', 'Spain', 'ESP'),
|
||||
23: Country(23, 'Canada', 'Canada', 'CAN'), 24: Country(24, 'USA', 'USA', 'USA'),
|
||||
26: Country(26, 'Mexico', 'Mexico', 'MEX'), 27: Country(27, 'Argentina', 'Argentina', 'ARG'),
|
||||
28: Country(28, 'Venezuela', 'Venezuela', 'VEN'), 29: Country(29, 'United Kingdom', 'United-Kingdom', 'GBR'),
|
||||
30: Country(30, 'Switzerland', 'Switzerland', 'CHE'), 31: Country(31, 'Netherlands', 'Netherlands', 'NLD'),
|
||||
32: Country(32, 'Belgium', 'Belgium', 'BEL'), 33: Country(33, 'Austria', 'Austria', 'AUT'),
|
||||
34: Country(34, 'Czech Republic', 'Czech-Republic', 'CZE'), 35: Country(35, 'Poland', 'Poland', 'POL'),
|
||||
36: Country(36, 'Slovakia', 'Slovakia', 'SVK'), 37: Country(37, 'Norway', 'Norway', 'NOR'),
|
||||
38: Country(38, 'Sweden', 'Sweden', 'SWE'), 39: Country(39, 'Finland', 'Finland', 'FIN'),
|
||||
40: Country(40, 'Ukraine', 'Ukraine', 'UKR'), 41: Country(41, 'Russia', 'Russia', 'RUS'),
|
||||
42: Country(42, 'Bulgaria', 'Bulgaria', 'BGR'), 43: Country(43, 'Turkey', 'Turkey', 'TUR'),
|
||||
44: Country(44, 'Greece', 'Greece', 'GRC'), 45: Country(45, 'Japan', 'Japan', 'JPN'),
|
||||
47: Country(47, 'South Korea', 'South-Korea', 'KOR'), 48: Country(48, 'India', 'India', 'IND'),
|
||||
49: Country(49, 'Indonesia', 'Indonesia', 'IDN'), 50: Country(50, 'Australia', 'Australia', 'AUS'),
|
||||
51: Country(51, 'South Africa', 'South Africa', 'ZAF'),
|
||||
52: Country(52, 'Republic of Moldova', 'Republic-of-Moldova', 'MDA'),
|
||||
53: Country(53, 'Portugal', 'Portugal', 'PRT'), 54: Country(54, 'Ireland', 'Ireland', 'IRL'),
|
||||
55: Country(55, 'Denmark', 'Denmark', 'DNK'), 56: Country(56, 'Iran', 'Iran', 'IRN'),
|
||||
57: Country(57, 'Pakistan', 'Pakistan', 'PAK'), 58: Country(58, 'Israel', 'Israel', 'ISR'),
|
||||
59: Country(59, 'Thailand', 'Thailand', 'THA'), 61: Country(61, 'Slovenia', 'Slovenia', 'SVN'),
|
||||
63: Country(63, 'Croatia', 'Croatia', 'HRV'), 64: Country(64, 'Chile', 'Chile', 'CHL'),
|
||||
65: Country(65, 'Serbia', 'Serbia', 'SRB'), 66: Country(66, 'Malaysia', 'Malaysia', 'MYS'),
|
||||
67: Country(67, 'Philippines', 'Philippines', 'PHL'), 68: Country(68, 'Singapore', 'Singapore', 'SGP'),
|
||||
69: Country(69, 'Bosnia and Herzegovina', 'Bosnia-Herzegovina', 'BiH'),
|
||||
70: Country(70, 'Estonia', 'Estonia', 'EST'), 80: Country(80, 'Montenegro', 'Montenegro', 'MNE'),
|
||||
71: Country(71, 'Latvia', 'Latvia', 'LVA'), 72: Country(72, 'Lithuania', 'Lithuania', 'LTU'),
|
||||
73: Country(73, 'North Korea', 'North-Korea', 'PRK'), 74: Country(74, 'Uruguay', 'Uruguay', 'URY'),
|
||||
75: Country(75, 'Paraguay', 'Paraguay', 'PRY'), 76: Country(76, 'Bolivia', 'Bolivia', 'BOL'),
|
||||
77: Country(77, 'Peru', 'Peru', 'PER'), 78: Country(78, 'Colombia', 'Colombia', 'COL'),
|
||||
79: Country(79, 'Republic of Macedonia (FYROM)', 'Republic-of-Macedonia-FYROM', 'MKD'),
|
||||
81: Country(81, 'Republic of China (Taiwan)', 'Republic-of-China-Taiwan', 'TWN'),
|
||||
82: Country(82, 'Cyprus', 'Cyprus', 'CYP'), 167: Country(167, 'Albania', 'Albania', 'ALB'),
|
||||
83: Country(83, 'Belarus', 'Belarus', 'BLR'), 84: Country(84, 'New Zealand', 'New-Zealand', 'NZL'),
|
||||
164: Country(164, 'Saudi Arabia', 'Saudi-Arabia', 'SAU'), 165: Country(165, 'Egypt', 'Egypt', 'EGY'),
|
||||
166: Country(166, 'United Arab Emirates', 'United-Arab-Emirates', 'UAE'),
|
||||
168: Country(168, 'Georgia', 'Georgia', 'GEO'), 169: Country(169, 'Armenia', 'Armenia', 'ARM'),
|
||||
170: Country(170, 'Nigeria', 'Nigeria', 'NGA'), 171: Country(171, 'Cuba', 'Cuba', 'CUB')
|
||||
}
|
||||
|
||||
FOOD_ENERGY: Dict[str, int] = dict(q1=2, q2=4, q3=6, q4=8, q5=10, q6=12, q7=20)
|
||||
|
||||
GROUND_RANKS: Dict[int, str] = {
|
||||
1: "Recruit", 2: "Private", 3: "Private*", 4: "Private**", 5: "Private***",
|
||||
6: "Corporal", 7: "Corporal*", 8: "Corporal**", 9: "Corporal***",
|
||||
10: "Sergeant", 11: "Sergeant*", 12: "Sergeant**", 13: "Sergeant***",
|
||||
14: "Lieutenant", 15: "Lieutenant*", 16: "Lieutenant**", 17: "Lieutenant***",
|
||||
18: "Captain", 19: "Captain*", 20: "Captain**", 21: "Captain***",
|
||||
22: "Major", 23: "Major*", 24: "Major**", 25: "Major***",
|
||||
26: "Commander", 27: "Commander*", 28: "Commander**", 29: "Commander***",
|
||||
30: "Lt Colonel", 31: "Lt Colonel*", 32: "Lt Colonel**", 33: "Lt Colonel***",
|
||||
34: "Colonel", 35: "Colonel*", 36: "Colonel**", 37: "Colonel***",
|
||||
38: "General", 39: "General*", 40: "General**", 41: "General***",
|
||||
42: "Field Marshal", 43: "Field Marshal*", 44: "Field Marshal**", 45: "Field Marshal***",
|
||||
46: "Supreme Marshal", 47: "Supreme Marshal*", 48: "Supreme Marshal**", 49: "Supreme Marshal***",
|
||||
50: "National Force", 51: "National Force*", 52: "National Force**", 53: "National Force***",
|
||||
54: "World Class Force", 55: "World Class Force*", 56: "World Class Force**", 57: "World Class Force***",
|
||||
58: "Legendary Force", 59: "Legendary Force*", 60: "Legendary Force**", 61: "Legendary Force***",
|
||||
62: "God of War", 63: "God of War*", 64: "God of War**", 65: "God of War***",
|
||||
66: "Titan", 67: "Titan*", 68: "Titan**", 69: "Titan***",
|
||||
70: "Legends I", 71: "Legends II", 72: "Legends III", 73: "Legends IV", 74: "Legends V", 75: "Legends VI",
|
||||
76: "Legends VII", 77: "Legends VIII", 78: "Legends IX", 79: "Legends X", 80: "Legends XI", 81: "Legends XII",
|
||||
82: "Legends XIII", 83: "Legends XIV", 84: "Legends XV", 85: "Legends XVI", 86: "Legends XVII", 87: "Legends XVIII",
|
||||
88: "Legends XIX", 89: "Legends XX",
|
||||
}
|
||||
|
||||
GROUND_RANK_POINTS: Dict[int, int] = {
|
||||
1: 0, 2: 15, 3: 45, 4: 80, 5: 120, 6: 170, 7: 250, 8: 350, 9: 450, 10: 600, 11: 800, 12: 1000,
|
||||
13: 1400, 14: 1850, 15: 2350, 16: 3000, 17: 3750, 18: 5000, 19: 6500, 20: 9000, 21: 12000,
|
||||
22: 15500, 23: 20000, 24: 25000, 25: 31000, 26: 40000, 27: 52000, 28: 67000, 29: 85000,
|
||||
30: 110000, 31: 140000, 32: 180000, 33: 225000, 34: 285000, 35: 355000, 36: 435000, 37: 540000,
|
||||
38: 660000, 39: 800000, 40: 950000, 41: 1140000, 42: 1350000, 43: 1600000, 44: 1875000,
|
||||
45: 2185000, 46: 2550000, 47: 3000000, 48: 3500000, 49: 4150000, 50: 4900000, 51: 5800000,
|
||||
52: 7000000, 53: 9000000, 54: 11500000, 55: 14500000, 56: 18000000, 57: 22000000, 58: 26500000,
|
||||
59: 31500000, 60: 37000000, 61: 43000000, 62: 50000000, 63: 100000000, 64: 200000000,
|
||||
65: 500000000, 66: 1000000000, 67: 2000000000, 68: 4000000000, 69: 10000000000, 70: 20000000000,
|
||||
71: 30000000000, 72: 40000000000, 73: 50000000000, 74: 60000000000, 75: 70000000000,
|
||||
76: 80000000000, 77: 90000000000, 78: 100000000000, 79: 110000000000, 80: 120000000000,
|
||||
81: 130000000000, 82: 140000000000, 83: 150000000000, 84: 160000000000, 85: 170000000000,
|
||||
86: 180000000000, 87: 190000000000, 88: 200000000000, 89: 210000000000
|
||||
}
|
||||
|
||||
INDUSTRIES = Industries()
|
||||
|
||||
TERRAINS: Dict[int, str] = {0: "Standard", 1: 'Industrial', 2: 'Urban', 3: 'Suburbs', 4: 'Airport', 5: 'Plains',
|
||||
6: 'Wasteland', 7: 'Mountains', 8: 'Beach', 9: 'Swamp', 10: 'Mud', 11: 'Hills',
|
||||
12: 'Jungle', 13: 'Forest', 14: 'Desert'}
|
@ -9,109 +9,47 @@ import traceback
|
||||
import unicodedata
|
||||
from decimal import Decimal
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Mapping, Optional, Union
|
||||
from typing import Any, List, Mapping, Optional, Union
|
||||
|
||||
import pytz
|
||||
import requests
|
||||
|
||||
from . import __commit_id__, __version__
|
||||
from . import __commit_id__, __version__, constants
|
||||
|
||||
try:
|
||||
import simplejson as json
|
||||
except ImportError:
|
||||
import json
|
||||
|
||||
__all__ = ["FOOD_ENERGY", "COMMIT_ID", "erep_tz",
|
||||
"now", "localize_dt", "localize_timestamp", "good_timedelta", "eday_from_date", "date_from_eday",
|
||||
"get_sleep_seconds", "interactive_sleep", "silent_sleep",
|
||||
"write_silent_log", "write_interactive_log", "get_file", "write_file",
|
||||
"send_email", "normalize_html_json", "process_error", "process_warning",
|
||||
'calculate_hit', 'get_ground_hit_dmg_value', 'get_air_hit_dmg_value']
|
||||
__all__ = ['COMMIT_ID', 'VERSION', 'calculate_hit', 'caught_error', 'date_from_eday', 'eday_from_date',
|
||||
'get_air_hit_dmg_value', 'get_file', 'get_ground_hit_dmg_value', 'get_sleep_seconds', 'good_timedelta',
|
||||
'interactive_sleep', 'json', 'localize_dt', 'localize_timestamp', 'normalize_html_json', 'now',
|
||||
'process_error', 'process_warning', 'send_email', 'silent_sleep', 'slugify', 'write_file',
|
||||
'write_interactive_log', 'write_silent_log']
|
||||
|
||||
if not sys.version_info >= (3, 7):
|
||||
raise AssertionError('This script requires Python version 3.7 and higher\n'
|
||||
'But Your version is v{}.{}.{}'.format(*sys.version_info))
|
||||
|
||||
FOOD_ENERGY: Dict[str, int] = dict(q1=2, q2=4, q3=6, q4=8, q5=10, q6=12, q7=20)
|
||||
COMMIT_ID: str = __commit_id__
|
||||
VERSION: str = __version__
|
||||
|
||||
erep_tz = pytz.timezone('US/Pacific')
|
||||
AIR_RANKS: Dict[int, str] = {
|
||||
1: "Airman", 2: "Airman 1st Class", 3: "Airman 1st Class*", 4: "Airman 1st Class**", 5: "Airman 1st Class***",
|
||||
6: "Airman 1st Class****", 7: "Airman 1st Class*****", 8: "Senior Airman", 9: "Senior Airman*",
|
||||
10: "Senior Airman**", 11: "Senior Airman***", 12: "Senior Airman****", 13: "Senior Airman*****",
|
||||
14: "Staff Sergeant", 15: "Staff Sergeant*", 16: "Staff Sergeant**", 17: "Staff Sergeant***",
|
||||
18: "Staff Sergeant****", 19: "Staff Sergeant*****", 20: "Aviator", 21: "Aviator*", 22: "Aviator**",
|
||||
23: "Aviator***", 24: "Aviator****", 25: "Aviator*****", 26: "Flight Lieutenant", 27: "Flight Lieutenant*",
|
||||
28: "Flight Lieutenant**", 29: "Flight Lieutenant***", 30: "Flight Lieutenant****", 31: "Flight Lieutenant*****",
|
||||
32: "Squadron Leader", 33: "Squadron Leader*", 34: "Squadron Leader**", 35: "Squadron Leader***",
|
||||
36: "Squadron Leader****", 37: "Squadron Leader*****", 38: "Chief Master Sergeant", 39: "Chief Master Sergeant*",
|
||||
40: "Chief Master Sergeant**", 41: "Chief Master Sergeant***", 42: "Chief Master Sergeant****",
|
||||
43: "Chief Master Sergeant*****", 44: "Wing Commander", 45: "Wing Commander*", 46: "Wing Commander**",
|
||||
47: "Wing Commander***", 48: "Wing Commander****", 49: "Wing Commander*****", 50: "Group Captain",
|
||||
51: "Group Captain*", 52: "Group Captain**", 53: "Group Captain***", 54: "Group Captain****",
|
||||
55: "Group Captain*****", 56: "Air Commodore", 57: "Air Commodore*", 58: "Air Commodore**", 59: "Air Commodore***",
|
||||
60: "Air Commodore****", 61: "Air Commodore*****",
|
||||
}
|
||||
|
||||
GROUND_RANKS: Dict[int, str] = {
|
||||
1: "Recruit", 2: "Private", 3: "Private*", 4: "Private**", 5: "Private***",
|
||||
6: "Corporal", 7: "Corporal*", 8: "Corporal**", 9: "Corporal***",
|
||||
10: "Sergeant", 11: "Sergeant*", 12: "Sergeant**", 13: "Sergeant***",
|
||||
14: "Lieutenant", 15: "Lieutenant*", 16: "Lieutenant**", 17: "Lieutenant***",
|
||||
18: "Captain", 19: "Captain*", 20: "Captain**", 21: "Captain***",
|
||||
22: "Major", 23: "Major*", 24: "Major**", 25: "Major***",
|
||||
26: "Commander", 27: "Commander*", 28: "Commander**", 29: "Commander***",
|
||||
30: "Lt Colonel", 31: "Lt Colonel*", 32: "Lt Colonel**", 33: "Lt Colonel***",
|
||||
34: "Colonel", 35: "Colonel*", 36: "Colonel**", 37: "Colonel***",
|
||||
38: "General", 39: "General*", 40: "General**", 41: "General***",
|
||||
42: "Field Marshal", 43: "Field Marshal*", 44: "Field Marshal**", 45: "Field Marshal***",
|
||||
46: "Supreme Marshal", 47: "Supreme Marshal*", 48: "Supreme Marshal**", 49: "Supreme Marshal***",
|
||||
50: "National Force", 51: "National Force*", 52: "National Force**", 53: "National Force***",
|
||||
54: "World Class Force", 55: "World Class Force*", 56: "World Class Force**", 57: "World Class Force***",
|
||||
58: "Legendary Force", 59: "Legendary Force*", 60: "Legendary Force**", 61: "Legendary Force***",
|
||||
62: "God of War", 63: "God of War*", 64: "God of War**", 65: "God of War***",
|
||||
66: "Titan", 67: "Titan*", 68: "Titan**", 69: "Titan***",
|
||||
70: "Legends I", 71: "Legends II", 72: "Legends III", 73: "Legends IV", 74: "Legends V", 75: "Legends VI",
|
||||
76: "Legends VII", 77: "Legends VIII", 78: "Legends IX", 79: "Legends X", 80: "Legends XI", 81: "Legends XII",
|
||||
82: "Legends XIII", 83: "Legends XIV", 84: "Legends XV", 85: "Legends XVI", 86: "Legends XVII", 87: "Legends XVIII",
|
||||
88: "Legends XIX", 89: "Legends XX",
|
||||
}
|
||||
|
||||
GROUND_RANK_POINTS: Dict[int, int] = {
|
||||
1: 0, 2: 15, 3: 45, 4: 80, 5: 120, 6: 170, 7: 250, 8: 350, 9: 450, 10: 600, 11: 800, 12: 1000,
|
||||
13: 1400, 14: 1850, 15: 2350, 16: 3000, 17: 3750, 18: 5000, 19: 6500, 20: 9000, 21: 12000,
|
||||
22: 15500, 23: 20000, 24: 25000, 25: 31000, 26: 40000, 27: 52000, 28: 67000, 29: 85000,
|
||||
30: 110000, 31: 140000, 32: 180000, 33: 225000, 34: 285000, 35: 355000, 36: 435000, 37: 540000,
|
||||
38: 660000, 39: 800000, 40: 950000, 41: 1140000, 42: 1350000, 43: 1600000, 44: 1875000,
|
||||
45: 2185000, 46: 2550000, 47: 3000000, 48: 3500000, 49: 4150000, 50: 4900000, 51: 5800000,
|
||||
52: 7000000, 53: 9000000, 54: 11500000, 55: 14500000, 56: 18000000, 57: 22000000, 58: 26500000,
|
||||
59: 31500000, 60: 37000000, 61: 43000000, 62: 50000000, 63: 100000000, 64: 200000000,
|
||||
65: 500000000, 66: 1000000000, 67: 2000000000, 68: 4000000000, 69: 10000000000, 70: 20000000000,
|
||||
71: 30000000000, 72: 40000000000, 73: 50000000000, 74: 60000000000, 75: 70000000000,
|
||||
76: 80000000000, 77: 90000000000, 78: 100000000000, 79: 110000000000, 80: 120000000000,
|
||||
81: 130000000000, 82: 140000000000, 83: 150000000000, 84: 160000000000, 85: 170000000000,
|
||||
86: 180000000000, 87: 190000000000, 88: 200000000000, 89: 210000000000
|
||||
}
|
||||
|
||||
|
||||
def now() -> datetime.datetime:
|
||||
return datetime.datetime.now(erep_tz).replace(microsecond=0)
|
||||
return datetime.datetime.now(constants.erep_tz).replace(microsecond=0)
|
||||
|
||||
|
||||
def localize_timestamp(timestamp: int) -> datetime.datetime:
|
||||
return datetime.datetime.fromtimestamp(timestamp, erep_tz)
|
||||
return datetime.datetime.fromtimestamp(timestamp, constants.erep_tz)
|
||||
|
||||
|
||||
def localize_dt(dt: Union[datetime.date, datetime.datetime]) -> datetime.datetime:
|
||||
try:
|
||||
try:
|
||||
return erep_tz.localize(dt)
|
||||
return constants.erep_tz.localize(dt)
|
||||
except AttributeError:
|
||||
return erep_tz.localize(datetime.datetime.combine(dt, datetime.time(0, 0, 0)))
|
||||
return constants.erep_tz.localize(datetime.datetime.combine(dt, datetime.time(0, 0, 0)))
|
||||
except ValueError:
|
||||
return dt.astimezone(erep_tz)
|
||||
return dt.astimezone(constants.erep_tz)
|
||||
|
||||
|
||||
def good_timedelta(dt: datetime.datetime, td: datetime.timedelta) -> datetime.datetime:
|
||||
@ -124,7 +62,7 @@ def good_timedelta(dt: datetime.datetime, td: datetime.timedelta) -> datetime.da
|
||||
:return: datetime object with correct timezone when jumped over DST
|
||||
:rtype: datetime.datetime
|
||||
"""
|
||||
return erep_tz.normalize(dt + td)
|
||||
return constants.erep_tz.normalize(dt + td)
|
||||
|
||||
|
||||
def eday_from_date(date: Union[datetime.date, datetime.datetime] = now()) -> int:
|
||||
|
Loading…
x
Reference in New Issue
Block a user