diff --git a/erepublik/__init__.py b/erepublik/__init__.py index d1becf9..e8aa110 100644 --- a/erepublik/__init__.py +++ b/erepublik/__init__.py @@ -6,7 +6,6 @@ __author__ = """Eriks Karls""" __email__ = 'eriks@72.lv' __version__ = '0.24.1' -from erepublik import classes, constants, utils from erepublik.citizen import Citizen -__all__ = ["classes", "utils", "Citizen", 'constants'] +__all__ = ['Citizen', '__version__'] diff --git a/erepublik/_logging.py b/erepublik/_logging.py index f0e8c5c..a19408f 100644 --- a/erepublik/_logging.py +++ b/erepublik/_logging.py @@ -49,7 +49,7 @@ class ErepublikFormatter(logging.Formatter): default_fmt = "[%(asctime)s] %(levelname)s: %(msg)s" def converter(self, timestamp: Union[int, float]) -> datetime.datetime: - return datetime.datetime.utcfromtimestamp(timestamp).astimezone(erep_tz) + return datetime.datetime.fromtimestamp(timestamp).astimezone(erep_tz) def format(self, record: logging.LogRecord) -> str: """ diff --git a/erepublik/access_points.py b/erepublik/access_points.py index 0d30946..9c51fd5 100644 --- a/erepublik/access_points.py +++ b/erepublik/access_points.py @@ -3,11 +3,11 @@ import hashlib import random import time from typing import Any, Dict, List, Mapping, Union -from requests_toolbelt.utils import dump from requests import Response, Session +from requests_toolbelt.utils import dump -from . import constants, utils +from erepublik import constants, utils __all__ = ['SlowRequests', 'CitizenAPI'] diff --git a/erepublik/citizen.py b/erepublik/citizen.py index a41dc81..1bb9d2d 100644 --- a/erepublik/citizen.py +++ b/erepublik/citizen.py @@ -9,11 +9,12 @@ from threading import Event from time import sleep from typing import Any, Dict, List, NoReturn, Optional, Set, Tuple, Union -from requests import RequestException, Response, HTTPError +from requests import HTTPError, RequestException, Response -from . import access_points, classes, constants, _types as types, utils -from .classes import OfferItem -from ._logging import ErepublikErrorHTTTPHandler, ErepublikFileHandler, ErepublikFormatter, ErepublikLogConsoleHandler +from erepublik import _types as types +from erepublik import access_points, classes, constants, utils +from erepublik._logging import ErepublikErrorHTTTPHandler, ErepublikFileHandler, ErepublikFormatter, \ + ErepublikLogConsoleHandler class BaseCitizen(access_points.CitizenAPI): @@ -279,7 +280,7 @@ class BaseCitizen(access_points.CitizenAPI): return self._post_main_session_get_challenge(captcha_id, image_id).json() def solve_captcha(self, src: str) -> List[Dict[str, int]]: - raise NotImplemented + return [] @property def inventory(self) -> classes.Inventory: @@ -1327,7 +1328,7 @@ class CitizenEconomy(CitizenTravel): self._report_action('BOUGHT_PRODUCTS', json_ret.get('message'), kwargs=json_ret) return json_ret - def buy_market_offer(self, offer: OfferItem, amount: int = None) -> Optional[Dict[str, Any]]: + def buy_market_offer(self, offer: classes.OfferItem, amount: int = None) -> Optional[Dict[str, Any]]: if amount is None or amount > offer.amount: amount = offer.amount traveled = False @@ -2734,7 +2735,7 @@ class _Citizen(CitizenAnniversary, CitizenCompanies, CitizenLeaderBoard, self.buy_tg_contract() else: self.write_warning('Training ground contract active but ' - f"don't have enough gold ({self.details.gold}g {self.details.cc}cc)") + f"don't have enough gold ({self.details.gold}g {self.details.cc}cc)") if self.energy.is_energy_full and self.config.telegram: self.telegram.report_full_energy(self.energy.available, self.energy.limit, self.energy.interval) @@ -3170,7 +3171,7 @@ class Citizen(_Citizen): finally: self._concurrency_lock.set() - def buy_market_offer(self, offer: OfferItem, amount: int = None) -> Optional[Dict[str, Any]]: + def buy_market_offer(self, offer: classes.OfferItem, amount: int = None) -> Optional[Dict[str, Any]]: if not self._concurrency_lock.wait(self._concurrency_timeout): e = f'Concurrency not freed in {self._concurrency_timeout}sec!' self.report_error(e) diff --git a/erepublik/classes.py b/erepublik/classes.py index 08464ee..990d8e0 100644 --- a/erepublik/classes.py +++ b/erepublik/classes.py @@ -3,11 +3,13 @@ import hashlib import threading import weakref from decimal import Decimal -from typing import Any, Dict, Generator, Iterable, List, NamedTuple, NoReturn, Union, Optional +from io import BytesIO +from typing import Any, Dict, Generator, Iterable, List, NamedTuple, NoReturn, Optional, Tuple, Union -from requests import Response, Session, post, HTTPError +from requests import HTTPError, Response, Session, post -from . import constants, _types as types, utils +from erepublik import _types as types +from erepublik import constants, utils __all__ = ['Battle', 'BattleDivision', 'BattleSide', 'Company', 'Config', 'Details', 'Energy', 'ErepublikException', 'ErepublikNetworkException', 'EnergyToFight', 'Holding', 'Inventory', 'MyCompanies', 'OfferItem', 'Politics', @@ -627,14 +629,14 @@ class Reporter: def register_account(self): if not self.__registered: - r = self._bot_update(dict(key=self.key, check=True, player_id=self.citizen_id)) + r = self.__bot_update(dict(key=self.key, check=True, player_id=self.citizen_id)) if r: if not r.json().get('status'): self._req.post(f"{self.url}/bot/register", json=dict(name=self.name, email=self.email, player_id=self.citizen_id)) - self.report_action('STARTED', value=utils.now().strftime("%F %T")) self.__registered = True self.allowed = True + self.report_action('STARTED', value=utils.now().strftime("%F %T")) def send_state_update(self, xp: int, cc: float, gold: float, inv_total: int, inv: int, hp_limit: int, hp_interval: int, hp_available: int, food: int, pp: int): @@ -967,7 +969,7 @@ class TelegramReporter: if token is None: token = "864251270:AAFzZZdjspI-kIgJVk4gF3TViGFoHnf8H4o" self.chat_id = chat_id - self.api_url = f"https://api.telegram.org/bot{token}/sendMessage" + self.api_url = f"https://api.telegram.org/bot{token}" self.player_name = player_name or "" self.__initialized = True self._last_time = utils.good_timedelta(utils.now(), datetime.timedelta(minutes=-5)) @@ -1024,13 +1026,21 @@ class TelegramReporter: message = "\n\n".join(self.__queue) if self.player_name: message = f"Player *{self.player_name}*\n\n" + message - response = post(self.api_url, json=dict(chat_id=self.chat_id, text=message, parse_mode='Markdown')) + response = post(f"{self.api_url}/sendMessage", json=dict(chat_id=self.chat_id, text=message, parse_mode='Markdown')) self._last_time = utils.now() if response.json().get('ok'): self.__queue.clear() return True return False + def send_photos(self, photos: List[Tuple[str, BytesIO]]): + for photo_title, photo in photos: + photo.seek(0) + post(f"https://{self.api_url}/sendPhoto", + data=dict(chat_id=self.chat_id, caption=photo_title), + files=[('photo', ("f{utils.slugify(photo_title)}.png", photo))]) + return + class OfferItem(NamedTuple): price: float = 999_999_999. diff --git a/erepublik/utils.py b/erepublik/utils.py index e8e9f73..ff0c39c 100644 --- a/erepublik/utils.py +++ b/erepublik/utils.py @@ -15,7 +15,7 @@ import pytz import requests from requests import Response -from . import __version__, constants +from erepublik import __version__, constants try: import simplejson as json @@ -255,7 +255,7 @@ def json_dumps(obj, *args, **kwargs): def b64json(obj: Union[Dict[str, Union[int, List[str]]], List[str]]): if isinstance(obj, list): - return b64encode(json.dumps(obj).replace(' ', '').encode('utf-8')).decode('utf-8') + return b64encode(json.dumps(obj, separators=(',', ':')).encode('utf-8')).decode('utf-8') elif isinstance(obj, (int, str)): return obj elif isinstance(obj, dict): @@ -264,7 +264,7 @@ def b64json(obj: Union[Dict[str, Union[int, List[str]]], List[str]]): else: from .classes import ErepublikException raise ErepublikException(f'Unhandled object type! obj is {type(obj)}') - return b64encode(json.dumps(obj).replace(' ', '').encode('utf-8')).decode('utf-8') + return b64encode(json.dumps(obj, separators=(',', ':')).encode('utf-8')).decode('utf-8') class ErepublikJSONEncoder(json.JSONEncoder): diff --git a/requirements_dev.txt b/requirements_dev.txt index 273f0cd..44819d3 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,20 +1,21 @@ bump2version==1.0.1 -coverage==5.4 -edx-sphinx-theme==1.6.1 +coverage==5.5 +edx-sphinx-theme==2.0.0 flake8==3.8.4 -ipython>=7.19.0 +ipython>=7.21.0 jedi!=0.18.0 isort==5.7.0 -pip==21.0 -pre-commit==2.9.3 +pip==21.0.1 +pre-commit==2.10.1 pur==5.3.0 PyInstaller==4.2 PySocks==1.7.1 pytest==6.2.2 -pytz>=2020.5 -requests>=2.25.1 +pytz==2021.1 +requests==2.25.1 +requests-toolbelt==0.9.1 responses==0.12.1 -setuptools==52.0.0 -Sphinx==3.4.3 +setuptools==54.0.0 +Sphinx==3.5.1 twine==3.3.0 wheel==0.36.2 diff --git a/setup.py b/setup.py index 32fa6ea..54788a2 100644 --- a/setup.py +++ b/setup.py @@ -12,9 +12,10 @@ with open('HISTORY.rst') as history_file: history = history_file.read() requirements = [ - 'pytz>=2020.0', - 'requests>=2.24.0,<2.26.0', - 'PySocks==1.7.1' + 'PySocks==1.7.1', + 'pytz==2021.1', + 'requests==2.25.1', + 'requests-toolbelt==0.9.1', ] setup_requirements = []