Compare commits

..

2 Commits

Author SHA1 Message Date
6b40f8f7aa Bump version: 0.29.0 → 0.29.0.1 2022-02-01 22:35:27 +02:00
db3282cde0 Bugfix 2022-02-01 22:35:12 +02:00
15 changed files with 68 additions and 95 deletions

View File

@ -21,7 +21,7 @@ insert_final_newline = false
indent_style = tab
[*.py]
max_line_length = 120
max_line_length = 240
line_length=120
multi_line_output=0
balanced_wrapping=True

View File

@ -10,13 +10,6 @@ eRepublik script
:target: https://erepublik.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://github.com/eeriks/erepublik/actions/workflows/codeql-analysis.yml/badge.svg?branch=master
:target: //github.com/eeriks/erepublik/actions/workflows/codeql-analysis.yml
:alt: CodeQL
.. image:: https://github.com/eeriks/erepublik/actions/workflows/pythonpackage.yml/badge.svg
:target: https://github.com/eeriks/erepublik/actions/workflows/pythonpackage.yml
:alt: Python package
Python package for automated eRepublik playing

View File

@ -4,7 +4,7 @@
__author__ = """Eriks Karls"""
__email__ = "eriks@72.lv"
__version__ = "0.30.0.4"
__version__ = "0.29.0.1"
from erepublik.citizen import Citizen

View File

@ -9,7 +9,7 @@ from logging import LogRecord, handlers
from pathlib import Path
from typing import Any, Dict, Union
from httpx import post
import requests
from erepublik.classes import Reporter
from erepublik.constants import erep_tz
@ -112,7 +112,7 @@ class ErepublikErrorHTTTPHandler(handlers.HTTPHandler):
def _get_last_response(self) -> Dict[str, str]:
response = self.reporter.citizen.r
url = str(response.url)
url = response.url
last_index = url.index("?") if "?" in url else len(response.url)
name = slugify(response.url[len(self.reporter.citizen.url) : last_index])
@ -209,6 +209,6 @@ class ErepublikErrorHTTTPHandler(handlers.HTTPHandler):
headers = {"Authorization": s}
data = self.mapLogRecord(record)
files = data.pop("files") if "files" in data else None
post(f"{proto}://{self.host}{self.url}", headers=headers, data=data, files=files)
requests.post(f"{proto}://{self.host}{self.url}", headers=headers, data=data, files=files)
except Exception:
self.handleError(record)

View File

@ -4,8 +4,9 @@ import random
import time
from typing import Any, Dict, List, Mapping, Union
from httpx import Response, Client as Session, RequestError
#from requests_toolbelt.utils import dump
from requests import Response, Session
from requests.exceptions import ConnectionError
from requests_toolbelt.utils import dump
from erepublik import constants, utils
@ -14,12 +15,11 @@ __all__ = ["SlowRequests", "CitizenAPI"]
class SlowRequests(Session):
last_time: datetime.datetime
__timeout: datetime.timedelta = datetime.timedelta(milliseconds=500)
timeout: datetime.timedelta = datetime.timedelta(milliseconds=500)
debug: bool = False
http2 = True
def __init__(self, proxies: Dict[str, str] = None, user_agent: str = None):
super().__init__(http2=True, follow_redirects=True)
super().__init__()
if proxies:
self.proxies = proxies
if user_agent is None:
@ -27,13 +27,13 @@ class SlowRequests(Session):
self.request_log_name = utils.get_file(utils.now().strftime("debug/requests_%Y-%m-%d.log"))
self.last_time = utils.now()
self.headers.update({"User-Agent": user_agent})
self.event_hooks["response"] = [self._log_response]
self.hooks["response"] = [self._log_response]
@property
def as_dict(self):
return dict(
last_time=self.last_time,
__timeout=self.__timeout,
timeout=self.timeout,
cookies=self.cookies.get_dict(),
debug=self.debug,
user_agent=self.headers["User-Agent"],
@ -46,14 +46,14 @@ class SlowRequests(Session):
self._log_request(url, method, **kwargs)
try:
resp = super().request(method, url, *args, **kwargs)
except RequestError:
except ConnectionError:
time.sleep(1)
return self.request(method, url, *args, **kwargs)
# self._log_response(resp)
return resp
def _slow_down_requests(self):
ltt = utils.good_timedelta(self.last_time, self.__timeout)
ltt = utils.good_timedelta(self.last_time, self.timeout)
if ltt > utils.now():
seconds = (ltt - utils.now()).total_seconds()
time.sleep(seconds if seconds > 0 else 0)
@ -81,7 +81,7 @@ class SlowRequests(Session):
def _log_response(self, response: Response, *args, **kwargs):
redirect = kwargs.get("redirect")
url = str(response.request.url)
url = response.request.url
if self.debug:
if response.history and not redirect:
for hist_resp in response.history:
@ -92,7 +92,7 @@ class SlowRequests(Session):
fd_time = self.last_time.strftime("%Y/%m/%d/%H-%M-%S")
fd_name = utils.slugify(url[len(CitizenBaseAPI.url) :])
fd_extra = "_REDIRECT" if redirect else ""
response.read()
try:
utils.json.loads(response.text)
fd_ext = "json"
@ -102,9 +102,9 @@ class SlowRequests(Session):
filename = f"{fd_path}/{fd_time}_{fd_name}{fd_extra}.{fd_ext}"
utils.write_file(filename, response.text)
#if not redirect:
# data = dump.dump_all(response)
# utils.write_file(f"debug/dumps/{fd_time}_{fd_name}{fd_extra}.{fd_ext}.dump", data.decode("utf8"))
if not redirect:
data = dump.dump_all(response)
utils.write_file(f"debug/dumps/{fd_time}_{fd_name}{fd_extra}.{fd_ext}.dump", data.decode("utf8"))
@staticmethod
def get_random_user_agent() -> str:
@ -145,7 +145,7 @@ class CitizenBaseAPI:
return dict(url=self.url, request=self._req.as_dict, token=self.token)
def post(self, url: str, data=None, json=None, **kwargs) -> Response:
return self._req.post(url, data=data, json=json, **kwargs)
return self._req.post(url, data, json, **kwargs)
def get(self, url: str, **kwargs) -> Response:
return self._req.get(url, **kwargs)

View File

@ -9,7 +9,7 @@ from threading import Event
from time import sleep
from typing import Any, Dict, List, NoReturn, Optional, Set, Tuple, TypedDict, Union
from httpx import RequestError, Response
from requests import RequestException, Response
from erepublik import _types as types
from erepublik import access_points, classes, constants, utils
@ -118,7 +118,7 @@ class BaseCitizen(access_points.CitizenAPI):
else:
try:
response = super().get(url, **kwargs)
except RequestError:
except RequestException:
self.report_error("Network error while issuing GET request")
self.sleep(60)
return self.get(url, **kwargs)
@ -151,7 +151,7 @@ class BaseCitizen(access_points.CitizenAPI):
try:
response = super().post(url, data=data, json=json, **kwargs)
except RequestError:
except RequestException:
self.report_error("Network error while issuing POST request")
self.sleep(60)
return self.post(url, data=data, json=json, **kwargs)
@ -327,7 +327,7 @@ class BaseCitizen(access_points.CitizenAPI):
r"((?P<amount>\d+) item\(s\) )?[eE]xpires? on Day (?P<eday>\d,\d{3}), (?P<time>\d\d:\d\d)",
_expire_value,
).groupdict()
eday = utils.date_from_eday(int(_data["eday"].replace(",", ""))).date()
eday = utils.date_from_eday(int(_data["eday"].replace(",", "")))
dt = constants.erep_tz.localize(datetime.combine(eday, time(*[int(_) for _ in _data["time"].split(":")])))
return {"amount": _data.get("amount"), "expiration": dt}
@ -613,10 +613,7 @@ class BaseCitizen(access_points.CitizenAPI):
"comment_url",
"rfc2109",
]
cookies = []
for cookie in self._req.cookies.jar:
cookies.append({attr: getattr(cookie, attr, None) for attr in cookie_attrs if hasattr(cookie, attr)})
#cookies = [{attr: getattr(cookie, attr) for attr in cookie_attrs} for cookie in self._req.cookies]
cookies = [{attr: getattr(cookie, attr) for attr in cookie_attrs} for cookie in self._req.cookies]
with open(filename, "w") as f:
utils.json_dump(
@ -1964,7 +1961,7 @@ class CitizenTasks(CitizenEconomy):
else:
self.reporter.report_action("WORK", json_val=js)
else:
seconds = 360 - self.now.timestamp() % 360
seconds = self.now.timestamp() % 360
self.write_warning(f"I don't have energy to work. Will sleep for {seconds}s")
self.sleep(seconds)
self.work()
@ -2010,7 +2007,7 @@ class CitizenTasks(CitizenEconomy):
self.buy_food(120)
self.reporter.report_action("WORK_OT", r.json())
elif self.energy.food_fights < 1 and self.ot_points >= 24:
seconds = 360 - self.now.timestamp() % 360
seconds = self.now.timestamp() % 360
self.write_warning(f"I don't have energy to work OT. Will sleep for {seconds}s")
self.sleep(seconds)
self.work_ot()
@ -2284,9 +2281,9 @@ class _Citizen(
if data and kind in self.config.auto_sell:
if kind in ["food", "weapon", "house", "airplane"]:
for quality, amount in data.items():
self.sell_produced_product(kind, quality, int(data))
self.sell_produced_product(kind, quality)
elif kind.endswith("Raw"):
self.sell_produced_product(kind, 1, int(data))
self.sell_produced_product(kind, 1)
else:
raise classes.ErepublikException(f"Unknown kind produced '{kind}'")
elif self.config.auto_buy_raw and re.search(r"not_enough_[^_]*_raw", response.get("message")):
@ -2343,7 +2340,7 @@ class _Citizen(
def work_as_manager(self) -> bool:
"""Does Work as Manager in all holdings with wam. If employees assigned - work them also
:return: if there is more wam work to do
:return: if has more wam work to do
:rtype: bool
"""
if self.restricted_ip:
@ -2351,23 +2348,17 @@ class _Citizen(
return False
self.update_citizen_info()
self.update_companies()
wam_holdings: List[classes.Holding] = [
holding for holding in self.my_companies.get_wam_holdings() if holding.wam_count
]
regions: Dict[int, classes.Holding] = {}
for holding in self.my_companies.holdings.values():
if holding.wam_count:
regions.update({holding.region: holding})
# Check for current region
for holding in wam_holdings:
if holding.region == self.details.current_region:
self._wam(holding)
self.update_companies()
wam_holdings: List[classes.Holding] = [
holding for holding in wam_holdings if not holding.region == self.details.current_region
]
if self.details.current_region in regions:
self._wam(regions.pop(self.details.current_region))
self.update_companies()
for holding in wam_holdings:
# Don't travel if not enough energy (either work in all holding factories or 2h energy worth)
if self.energy.energy < 2 * self.energy.interval * 10 < holding.wam_count * 10:
break
for holding in regions.values():
raw_usage = holding.get_wam_raw_usage()
free_storage = self.inventory.total - self.inventory.used
if (raw_usage["frm"] + raw_usage["wrm"]) * 100 > free_storage:
@ -2378,6 +2369,9 @@ class _Citizen(
self.update_companies()
wam_count = self.my_companies.get_total_wam_count()
# if wam_count:
# self.logger.debug(f"Wam ff lockdown is now {wam_count}, was {self.my_companies.ff_lockdown}")
# self.my_companies.ff_lockdown = wam_count
self.travel_to_residence()
return bool(wam_count)

View File

@ -7,7 +7,7 @@ from decimal import Decimal
from io import BytesIO
from typing import Any, Dict, Generator, Iterable, List, NamedTuple, NoReturn, Optional, Tuple, Union
from httpx import HTTPError, Response, Client as Session, post
from requests import HTTPError, Response, Session, post
from erepublik import _types as types
from erepublik import constants, utils
@ -382,19 +382,17 @@ class MyCompanies:
return raw_factories.pop(-1)
else:
if raw:
raw += Decimal(
inv_raw.get(constants.INDUSTRIES[ids[1]], {}).get(0, {}).get("amount", Decimal("0.0"))
)
raw += inv_raw.get(constants.INDUSTRIES[ids[1]], {}).get(0, {}).get("amount", 0.0)
if raw > 0:
to_remove = sorted(raw_factories, key=lambda c: (c.industry not in ids, c.raw_usage))
if to_remove:
return raw_factories.pop(raw_factories.index(to_remove[0]))
return raw_factories.remove(to_remove[0])
else:
to_remove = sorted(final_factories, key=lambda c: (c.industry != ids[0], c.raw_usage))
if to_remove:
return final_factories.pop(final_factories.index(to_remove[0]))
return final_factories.remove(to_remove[0])
def get_raw_usage_for_companies(self, *companies: Company) -> Tuple[Decimal, Decimal, Decimal, Decimal]:
def get_raw_usage_for_companies(self, *companies: Company) -> Tuple[float, float, float, float]:
frm = wrm = hrm = arm = Decimal("0.00")
for company in companies:
if company.industry in self._frm_fab_ids:
@ -411,12 +409,6 @@ class MyCompanies:
def companies(self) -> Generator[Company, None, None]:
return (c for c in self._companies)
def get_wam_holdings(self) -> Generator[Holding, None, None]:
for holding in sorted(
self.holdings.values(), key=lambda h: (-len(h.get_wam_companies(False)), -len(h.get_wam_companies()))
):
yield holding
def __str__(self):
return f"MyCompanies: {sum(1 for _ in self.companies)} companies in {len(self.holdings)} holdings"
@ -772,7 +764,7 @@ class Reporter:
def __init__(self, citizen):
self._citizen = weakref.ref(citizen)
self._req = Session(follow_redirects=True)
self._req = Session()
self.url = "https://erep.lv"
self._req.headers.update({"user-agent": "eRepublik Script Reporter v3", "erep-version": utils.__version__})
self.__to_update = []

View File

@ -121,6 +121,7 @@ class Industries:
14: "WRM q3",
15: "WRM q4",
16: "WRM q5",
17: "houseRaw",
18: "houseRaw",
19: "HRM q2",
20: "HRM q3",

View File

@ -12,8 +12,8 @@ from pathlib import Path
from typing import Any, Dict, List, Union
import pytz
import httpx
from httpx import Response
import requests
from requests import Response
from erepublik import __version__, constants
@ -93,7 +93,7 @@ def eday_from_date(date: Union[datetime.date, datetime.datetime] = None) -> int:
return (date - datetime.datetime(2007, 11, 20, 0, 0, 0)).days
def date_from_eday(eday: int) -> datetime.datetime:
def date_from_eday(eday: int) -> datetime.date:
return localize_dt(datetime.date(2007, 11, 20)) + datetime.timedelta(days=eday)
@ -204,7 +204,7 @@ def calculate_hit(
def get_ground_hit_dmg_value(
citizen_id: int, natural_enemy: bool = False, true_patriot: bool = False, booster: int = 0, weapon_power: int = 200
) -> Decimal:
r = httpx.get(f"https://www.erepublik.com/en/main/citizen-profile-json/{citizen_id}").json()
r = requests.get(f"https://www.erepublik.com/en/main/citizen-profile-json/{citizen_id}").json()
rang = r["military"]["militaryData"]["ground"]["rankNumber"]
strength = r["military"]["militaryData"]["ground"]["strength"]
elite = r["citizenAttributes"]["level"] > 100
@ -217,7 +217,7 @@ def get_ground_hit_dmg_value(
def get_air_hit_dmg_value(
citizen_id: int, natural_enemy: bool = False, true_patriot: bool = False, booster: int = 0, weapon_power: int = 0
) -> Decimal:
r = httpx.get(f"https://www.erepublik.com/en/main/citizen-profile-json/{citizen_id}").json()
r = requests.get(f"https://www.erepublik.com/en/main/citizen-profile-json/{citizen_id}").json()
rang = r["military"]["militaryData"]["aircraft"]["rankNumber"]
elite = r["citizenAttributes"]["level"] > 100
return calculate_hit(0, rang, true_patriot, elite, natural_enemy, booster, weapon_power)

View File

@ -1,16 +1,16 @@
-r requirements.txt
-r requirements-tests.txt
bump2version==1.0.1
coverage==6.3.2
coverage==6.3
edx-sphinx-theme==3.0.0
flake8==4.0.1
ipython>=8.1.1
ipython>=8.0.1
jedi!=0.18.0
isort==5.10.1
pre-commit==2.17.0
pur==6.0.1
responses==0.18.0
responses==0.17.0
Sphinx==4.4.0
twine==3.8.0
twine==3.7.1
wheel==0.37.1
black==22.1.0

View File

@ -1,2 +1,2 @@
-r requirements.txt
pytest==7.0.1
pytest==6.2.5

View File

@ -1,8 +1,4 @@
PySocks==1.7.1
pytz>2021.0
httpx==0.22.0
h2==4.1.0
socksio==1.0.0
brotli==1.0.9
#requests>2.25.0,!=2.27.0
#requests-toolbelt==0.9.1
requests>2.25.0,!=2.27.0
requests-toolbelt==0.9.1

View File

@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.30.0.4
current_version = 0.29.0.1
commit = True
tag = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\.?(?P<dev>\d+)?
@ -19,8 +19,8 @@ universal = 1
[flake8]
exclude = docs,.git,log,debug,venv
line_length = 120
max-line-length = 120
line_length = 140
max-line-length = 140
ignore = D100,D101,D102,D103,E203
[pycodestyle]
@ -38,4 +38,4 @@ warn_unused_configs = True
[isort]
multi_line_output = 2
line_length = 120
line_length = 140

View File

@ -49,6 +49,6 @@ setup(
test_suite="tests",
tests_require=test_requirements,
url="https://github.com/eeriks/erepublik/",
version="0.30.0.4",
version="0.29.0.1",
zip_safe=False,
)

View File

@ -102,8 +102,7 @@ class TestErepublik(unittest.TestCase):
# self.citizen.my_companies.ff_lockdown = 160
# self.assertEqual(
# self.citizen.should_fight(),
# (435, "Fight count modified (old count: 595 | FF: 595
# | WAM ff_lockdown: 160 | New count: 435)", False),
# (435, "Fight count modified (old count: 595 | FF: 595 | WAM ff_lockdown: 160 | New count: 435)", False),
# )
# self.citizen.my_companies.ff_lockdown = 0
#
@ -113,8 +112,7 @@ class TestErepublik(unittest.TestCase):
# self.citizen.my_companies.ff_lockdown = 160
# self.assertEqual(
# self.citizen.should_fight(),
# (240, "Fight count modified (old count: 400 | FF: 400
# | WAM ff_lockdown: 160 | New count: 240)", False),
# (240, "Fight count modified (old count: 400 | FF: 400 | WAM ff_lockdown: 160 | New count: 240)", False),
# )
# self.citizen.my_companies.ff_lockdown = 0
# self.citizen.config.all_in = False
@ -126,8 +124,7 @@ class TestErepublik(unittest.TestCase):
# self.citizen.my_companies.ff_lockdown = 160
# self.assertEqual(
# self.citizen.should_fight(),
# (160, "Fight count modified (old count: 320 | FF: 400
# | WAM ff_lockdown: 160 | New count: 160)", False),
# (160, "Fight count modified (old count: 320 | FF: 400 | WAM ff_lockdown: 160 | New count: 160)", False),
# )
# self.citizen.my_companies.ff_lockdown = 0
# self.citizen.energy.limit = 3000