Compare commits

...

14 Commits

8 changed files with 71 additions and 33 deletions

View File

@ -4,7 +4,7 @@
__author__ = """Eriks Karls""" __author__ = """Eriks Karls"""
__email__ = 'eriks@72.lv' __email__ = 'eriks@72.lv'
__version__ = '0.21.4.4' __version__ = '0.21.5.1'
from erepublik import classes, utils, constants from erepublik import classes, utils, constants
from erepublik.citizen import Citizen from erepublik.citizen import Citizen

View File

@ -38,8 +38,10 @@ class SlowRequests(Session):
] ]
debug: bool = False debug: bool = False
def __init__(self): def __init__(self, proxies: Dict[str, str] = None):
super().__init__() super().__init__()
if proxies:
self.proxies = proxies
self.request_log_name = utils.get_file(utils.now().strftime("debug/requests_%Y-%m-%d.log")) self.request_log_name = utils.get_file(utils.now().strftime("debug/requests_%Y-%m-%d.log"))
self.last_time = utils.now() self.last_time = utils.now()
self.headers.update({ self.headers.update({
@ -132,6 +134,14 @@ class CitizenBaseAPI:
def _get_main(self) -> Response: def _get_main(self) -> Response:
return self.get(self.url) return self.get(self.url)
def set_socks_proxy(self, host: str, port: int, username: str = None, password: str = None):
url = f'socks5://{username}:{password}@{host}:{port}' if username and password else f'socks5://{host}:{port}'
self._req.proxies = dict(http=url, https=url)
def set_http_proxy(self, host: str, port: int, username: str = None, password: str = None):
url = f'http://{username}:{password}@{host}:{port}' if username and password else f'socks5://{host}:{port}'
self._req.proxies = dict(http=url)
class ErepublikAnniversaryAPI(CitizenBaseAPI): class ErepublikAnniversaryAPI(CitizenBaseAPI):
def _post_main_collect_anniversary_reward(self) -> Response: def _post_main_collect_anniversary_reward(self) -> Response:

View File

@ -624,8 +624,16 @@ class BaseCitizen(access_points.CitizenAPI):
self.sleep(5 * 60) self.sleep(5 * 60)
else: else:
raise classes.ErepublikException(f"HTTP {response.status_code} error!") raise classes.ErepublikException(f"HTTP {response.status_code} error!")
if re.search(r'Occasionally there are a couple of things which we need to check or to implement in order make '
r'your experience in eRepublik more pleasant. <strong>Don\'t worry about ongoing battles, timer '
r'will be stopped during maintenance.</strong>', response.text):
self.write_log("eRepublik ss having maintenance. Sleeping for 5 minutes")
self.sleep(5 * 60)
return True
return bool(re.search(r'body id="error"|Internal Server Error|' return bool(re.search(r'body id="error"|Internal Server Error|'
r'CSRF attack detected|meta http-equiv="refresh"|not_authenticated', response.text)) r'CSRF attack detected|meta http-equiv="refresh"|'
r'not_authenticated', response.text))
def _report_action(self, action: str, msg: str, **kwargs: Optional[Dict[str, Any]]): def _report_action(self, action: str, msg: str, **kwargs: Optional[Dict[str, Any]]):
""" Report action to all available reporting channels """ Report action to all available reporting channels
@ -874,6 +882,8 @@ class CitizenCompanies(BaseCitizen):
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.prepare_companies(utils.json.loads(have_companies.group(1))) self.my_companies.prepare_companies(utils.json.loads(have_companies.group(1)))
self.reporter.report_action('COMPANIES', json_val=self.my_companies.as_dict)
def assign_company_to_holding(self, company: classes.Company, holding: classes.Holding) -> Response: def assign_company_to_holding(self, company: classes.Company, holding: classes.Holding) -> Response:
""" """
Assigns factory to new holding Assigns factory to new holding
@ -1138,7 +1148,6 @@ class CitizenEconomy(CitizenTravel):
self.details.gold = float(response.json().get("gold").get("value")) self.details.gold = float(response.json().get("gold").get("value"))
if response.json().get('error'): if response.json().get('error'):
self._report_action("BUY_GOLD", "Unable to buy gold!", kwargs=response.json()) self._report_action("BUY_GOLD", "Unable to buy gold!", kwargs=response.json())
self.stop_threads.wait()
return False return False
else: else:
self._report_action('BUY_GOLD', f'New amount {self.details.cc}cc, {self.details.gold}g', self._report_action('BUY_GOLD', f'New amount {self.details.cc}cc, {self.details.gold}g',
@ -1654,11 +1663,11 @@ class CitizenMilitary(CitizenTravel):
self.write_log("Hits: {:>4} | Damage: {}".format(total_hits, total_damage)) self.write_log("Hits: {:>4} | Damage: {}".format(total_hits, total_damage))
ok_to_fight = False ok_to_fight = False
if total_damage: if total_damage:
self.reporter.report_action('FIGHT', dict(battle_id=battle.id, side=side, dmg=total_damage, self.reporter.report_fighting(battle, not side.is_defender, division, total_damage, total_hits)
air=battle.has_air, hits=total_hits, # self.reporter.report_action('FIGHT', dict(battle_id=battle.id, side=side, dmg=total_damage,
round=battle.zone_id)) # air=battle.has_air, hits=total_hits,
self.reporter.report_action("FIGHT", dict(battle=str(battle), side=str(side), dmg=total_damage, # round=battle.zone_id,
air=battle.has_air, hits=total_hits)) # extra=dict(battle=battle, side=side)))
return error_count return error_count
def _shoot(self, battle: classes.Battle, division: classes.BattleDivision, side: classes.BattleSide): def _shoot(self, battle: classes.Battle, division: classes.BattleDivision, side: classes.BattleSide):

View File

@ -3,7 +3,7 @@ import hashlib
import threading import threading
import weakref import weakref
from decimal import Decimal from decimal import Decimal
from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union, NoReturn
from requests import Response, Session, post from requests import Response, Session, post
@ -28,13 +28,23 @@ class Holding:
id: int id: int
region: int region: int
companies: List["Company"] companies: List["Company"]
name: str
_citizen = weakref.ReferenceType _citizen = weakref.ReferenceType
def __init__(self, _id: int, region: int, citizen): def __init__(self, _id: int, region: int, citizen, name: str = None):
self._citizen = weakref.ref(citizen) self._citizen = weakref.ref(citizen)
self.id: int = _id self.id: int = _id
self.region: int = region self.region: int = region
self.companies: List["Company"] = list() self.companies: List["Company"] = list()
if name:
self.name = name
else:
name = f"Holding (#{self.id}) with {len(self.companies)} "
if len(self.companies) == 1:
name += "company"
else:
name += "companies"
self.name = name
@property @property
def wam_count(self) -> int: def wam_count(self) -> int:
@ -48,7 +58,7 @@ class Holding:
def employable_companies(self) -> List["Company"]: def employable_companies(self) -> List["Company"]:
return [company for company in self.companies if company.preset_works] return [company for company in self.companies if company.preset_works]
def add_company(self, company: "Company"): def add_company(self, company: "Company") -> NoReturn:
self.companies.append(company) self.companies.append(company)
self.companies.sort() self.companies.sort()
@ -62,7 +72,7 @@ class Holding:
wrm += company.raw_usage wrm += company.raw_usage
return dict(frm=frm, wrm=wrm) return dict(frm=frm, wrm=wrm)
def get_wam_companies(self, raw_factory: bool = None): def get_wam_companies(self, raw_factory: bool = None) -> Optional[List["Company"]]:
raw = [] raw = []
factory = [] factory = []
for company in self.wam_companies: for company in self.wam_companies:
@ -80,7 +90,7 @@ class Holding:
else: else:
raise ErepublikException("raw_factory should be True/False/None") raise ErepublikException("raw_factory should be True/False/None")
def __str__(self): def __str__(self) -> str:
name = f"Holding (#{self.id}) with {len(self.companies)} " name = f"Holding (#{self.id}) with {len(self.companies)} "
if len(self.companies) % 10 == 1: if len(self.companies) % 10 == 1:
name += "company" name += "company"
@ -92,8 +102,9 @@ class Holding:
return str(self) return str(self)
@property @property
def as_dict(self): def as_dict(self) -> Dict[str, Union[str, int, List[Dict[str, Union[str, int, bool, float, Decimal]]]]]:
return dict(name=str(self), id=self.id, region=self.region, companies=self.companies, wam_count=self.wam_count) return dict(name=self.name, id=self.id, region=self.region,
companies=[c.as_dict for c in self.companies], wam_count=self.wam_count)
@property @property
def citizen(self): def citizen(self):
@ -203,7 +214,7 @@ class Company:
return str(self) return str(self)
@property @property
def as_dict(self): def as_dict(self) -> Dict[str, Union[str, int, bool, float, Decimal]]:
return dict(name=str(self), holding=self.holding.id, id=self.id, quality=self.quality, is_raw=self.is_raw, 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, 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, can_wam=self.can_wam, cannot_wam_reason=self.cannot_wam_reason, industry=self.industry,
@ -219,7 +230,7 @@ class Company:
return self.holding.citizen._post_economy_upgrade_company(self.id, level, self.holding.citizen.details.pin) return self.holding.citizen._post_economy_upgrade_company(self.id, level, self.holding.citizen.details.pin)
@property @property
def holding(self): def holding(self) -> Holding:
return self._holding() return self._holding()
@ -245,10 +256,10 @@ class MyCompanies:
for holding in holdings.values(): for holding in holdings.values():
if holding.get('id') not in self.holdings: if holding.get('id') not in self.holdings:
self.holdings.update({ self.holdings.update({
int(holding.get('id')): Holding(holding['id'], holding['region_id'], self.citizen) int(holding.get('id')): Holding(holding['id'], holding['region_id'], self.citizen, holding['name'])
}) })
if not self.holdings.get(0): if not self.holdings.get(0):
self.holdings.update({0: Holding(0, 0, self.citizen)}) # unassigned self.holdings.update({0: Holding(0, 0, self.citizen, 'Unassigned')}) # unassigned
def prepare_companies(self, companies: Dict[str, Dict[str, Any]]): def prepare_companies(self, companies: Dict[str, Dict[str, Any]]):
""" """
@ -300,9 +311,11 @@ class MyCompanies:
self.companies.clear() self.companies.clear()
@property @property
def as_dict(self): def as_dict(self) -> Dict[str, Union[str, int, datetime.datetime, Dict[str, Dict[str, Union[str, int, List[Dict[str, Union[str, int, bool, float, Decimal]]]]]]]]:
return dict(name=str(self), work_units=self.work_units, next_ot_time=self.next_ot_time, 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)) ff_lockdown=self.ff_lockdown,
holdings={str(hi): h.as_dict for hi, h in self.holdings.items()},
company_count=len(self.companies))
@property @property
def citizen(self): def citizen(self):
@ -618,6 +631,12 @@ class Reporter:
else: else:
self.__to_update.append(json_data) self.__to_update.append(json_data)
def report_fighting(self, battle: "Battle", invader: bool, division: "BattleDivision", damage: float, hits: int):
side = battle.invader if invader else battle.defender
self.report_action('FIGHT', dict(battle_id=battle.id, side=side, dmg=damage,
air=battle.has_air, hits=hits,
round=battle.zone_id, extra=dict(battle=battle, side=side, division=division)))
def report_promo(self, kind: str, time_until: datetime.datetime): 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)) self._req.post(f"{self.url}/promos/add/", data=dict(kind=kind, time_untill=time_until))

View File

@ -278,14 +278,13 @@ def process_error(log_info: str, name: str, exc_info: tuple, citizen=None, commi
elif interactive is not None: elif interactive is not None:
write_silent_log(log_info) write_silent_log(log_info)
trace = inspect.trace() trace = inspect.trace()
local_vars = None
if trace: if trace:
trace_local_vars = trace[-1][0].f_locals local_vars = trace[-1][0].f_locals
if trace_local_vars.get('__name__') == '__main__': if local_vars.get('__name__') == '__main__':
local_vars = {'commit_id': trace_local_vars.get('COMMIT_ID'), local_vars.update({'commit_id': local_vars.get('COMMIT_ID'),
'interactive': trace_local_vars.get('INTERACTIVE'), 'interactive': local_vars.get('INTERACTIVE'),
'version': trace_local_vars.get('__version__'), 'version': local_vars.get('__version__'),
'config': trace_local_vars.get('CONFIG')} 'config': local_vars.get('CONFIG')})
else: else:
local_vars = dict() local_vars = dict()
send_email(name, content, citizen, local_vars=local_vars) send_email(name, content, citizen, local_vars=local_vars)

View File

@ -7,11 +7,12 @@ isort==5.5.3
pip==20.2.3 pip==20.2.3
PyInstaller==4.0 PyInstaller==4.0
pytz==2020.1 pytz==2020.1
pytest==6.0.2 pytest==6.1.0
responses==0.12.0 responses==0.12.0
setuptools==50.3.0 setuptools==50.3.0
Sphinx==3.2.1 Sphinx==3.2.1
requests==2.24.0 requests==2.24.0
PySocks==1.7.1
tox==3.20.0 tox==3.20.0
twine==3.2.0 twine==3.2.0
watchdog==0.10.3 watchdog==0.10.3

View File

@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 0.21.4.4 current_version = 0.21.5.1
commit = True commit = True
tag = True tag = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\.?(?P<dev>\d+)? parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\.?(?P<dev>\d+)?

View File

@ -11,7 +11,7 @@ with open('README.rst') as readme_file:
with open('HISTORY.rst') as history_file: with open('HISTORY.rst') as history_file:
history = history_file.read() history = history_file.read()
requirements = ['pytz==2020.1', 'requests==2.24.0'] requirements = ['pytz==2020.1', 'requests==2.24.0', 'PySocks==1.7.1']
setup_requirements = [] setup_requirements = []
@ -43,6 +43,6 @@ setup(
test_suite='tests', test_suite='tests',
tests_require=test_requirements, tests_require=test_requirements,
url='https://github.com/eeriks/erepublik/', url='https://github.com/eeriks/erepublik/',
version='0.21.4.4', version='0.21.5.1',
zip_safe=False, zip_safe=False,
) )