@ -2,12 +2,14 @@ import datetime
import decimal
import hashlib
import random
import sys
import time
import traceback
from collections import deque
from json import JSONDecodeError , loads , JSONEncoder
from typing import Any , Dict , List , Union
from typing import Any , Dict , List , Union , Mapping , Iterable , Tuple
from requests import Response , Session
from requests import Response , Session , post
from erepublik import utils
@ -26,11 +28,13 @@ class ErepublikNetworkException(Exception):
class MyCompanies :
work_units : int = 0
next_ot_time : datetime . datetime
holdings : Dict [ int , Dict ] = dict ( )
companies : Dict [ int , Dict ] = dict ( )
holdings : Dict [ int , Dict ] = None
companies : Dict [ int , Dict ] = None
ff_lockdown : int = 0
def __init__ ( self ) :
self . holdings = dict ( )
self . companies = dict ( )
self . next_ot_time = utils . now ( )
def prepare_holdings ( self , holdings : dict ) :
@ -41,7 +45,7 @@ class MyCompanies:
template = dict ( id = 0 , num_factories = 0 , region_id = 0 , companies = [ ] )
for holding_id , holding in holdings . items ( ) :
tmp : Dict [ str , Union [ List [ Any ] , Any ] ] = { }
tmp : Dict [ str , Union [ Iterable [ Any ] , Any ] ] = { }
for key in template :
if key == ' companies ' :
tmp . update ( { key : [ ] } )
@ -59,7 +63,7 @@ class MyCompanies:
production = 0 , base_production = 0 , wam_enabled = False , can_work_as_manager = False ,
preset_own_work = 0 , already_worked = False , can_assign_employees = False , preset_works = 0 ,
todays_works = 0 , holding_company_id = None , is_assigned_to_holding = False ,
cannot_work_as_manager_reason = False )
cannot_work_as_manager_reason = False , industry_id = 0 )
for c_id , company in companies . items ( ) :
tmp = { }
@ -117,7 +121,10 @@ class MyCompanies:
raw = [ ]
factory = [ ]
if holding_id in self . holdings :
for company_id in self . holdings . get ( holding_id , { } ) . get ( ' companies ' , [ ] ) :
for company_id in sorted ( self . holdings . get ( holding_id , { } ) . get ( ' companies ' , [ ] ) ,
key = lambda cid : ( - self . companies [ cid ] . get ( ' is_raw ' ) , # True, False
self . companies [ cid ] . get ( ' industry_id ' ) , # F W H A
- self . companies [ cid ] . get ( ' quality ' ) , ) ) : # 7, 6, .. 2, 1
company = self . companies . get ( company_id , { } )
wam_enabled = bool ( company . get ( ' wam_enabled ' , { } ) )
already_worked = not company . get ( ' already_worked ' , { } )
@ -154,28 +161,33 @@ class MyCompanies:
raise ErepublikException ( " Wrong function call " )
@property
def __dict__ ( self ) :
ret = { }
for key in dir ( self ) :
if not key . startswith ( ' _ ' ) :
ret [ key ] = getattr ( self , key )
return ret
class SlowRequests ( Session ) :
last_time : datetime . datetime
timeout = datetime . timedelta ( milliseconds = 500 )
uas = [
# Chrome
' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
' Chrome/73 .0.3683.103 Safari/537.36 ' ,
' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) '
' Chrome/72 .0.3626.13 Safari/537.36 ' ,
' Mozilla/5.0 (Windows NT 10.0 ; W in64; x 64) AppleWebKit/537.36 (KHTML, like Gecko) '
' Chrome/71 .0.3578.98 Safari/537.36 ' ,
' Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36 ' ,
' Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.11 Safari/537.36 ' ,
' Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36 ' ,
' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36 ' ,
' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76 .0.3809.132 Safari/537.36' ,
' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.80 Safari/537.36 ' ,
' Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77 .0.3865.90 Safari/537.36' ,
' Mozilla/5.0 (X11 ; L inux x86_ 64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36 ' ,
' Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75 .0.3770.80 Safari/537.36' ,
# FireFox
' Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66 .0) Gecko/20100101 Firefox/66 .0 ' ,
' Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:65 .0) Gecko/20100101 Firefox/65 .0 ' ,
' Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64 .0) Gecko/20100101 Firefox/64 .0 ' ,
' Mozilla/5.0 (X11; Linux x86_64; rv:66 .0) Gecko/20100101 Firefox/66 .0 ' ,
' Mozilla/5.0 (X11; Linux x86_64; rv:65 .0) Gecko/20100101 Firefox/65 .0 ' ,
' Mozilla/5.0 (X11; Linux x86_64; rv:64 .0) Gecko/20100101 Firefox/64 .0 ' ,
' Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69 .0) Gecko/20100101 Firefox/69 .0 ' ,
' Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68 .0) Gecko/20100101 Firefox/68 .0 ' ,
' Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67 .0) Gecko/20100101 Firefox/67 .0 ' ,
' Mozilla/5.0 (X11; Linux x86_64; rv:69 .0) Gecko/20100101 Firefox/69 .0 ' ,
' Mozilla/5.0 (X11; Linux x86_64; rv:68 .0) Gecko/20100101 Firefox/68 .0 ' ,
' Mozilla/5.0 (X11; Linux x86_64; rv:67 .0) Gecko/20100101 Firefox/67 .0 ' ,
]
debug = False
@ -278,38 +290,21 @@ class Config:
force_wam = False
sort_battles_time = True
force_travel = False
telegram = True
telegram_chat_id = 0
telegram_token = " "
@property
def wt ( self ) :
return self . work and self . train
@property
def __dict__ ( self ) - > Dict [ str , Union [ bool , str , List [ str ] ] ] :
return dict (
email = self . email ,
password = self . password,
work = self . work ,
train = self . train ,
wam = self . wam ,
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 ,
next_energy = self . next_energy ,
boosters = self . boosters ,
travel_to_fight = self . travel_to_fight ,
epic_hunt = self . epic_hunt ,
epic_hunt_ebs = self . epic_hunt_ebs ,
rw_def_side = self . rw_def_side ,
interactive = self . interactive ,
continuous_fighting = self . continuous_fighting ,
auto_buy_raw = self . auto_buy_raw ,
force_wam = self . force_wam ,
sort_battles_time = self . sort_battles_time ,
force_travel = self . force_travel ,
)
ret = { }
for key in dir ( self ) :
if not key . startswith ( ' _ ' ) and key not in [ ' email ' , ' password' ] :
ret [ key ] = getattr ( self , key )
return ret
class Energy :
@ -330,7 +325,7 @@ class Energy:
@property
def food_fights ( self ) :
return ( self . recoverable + self . recovered ) / / 10
return self . available / / 10
@property
def reference_time ( self ) :
@ -342,7 +337,7 @@ class Energy:
@property
def is_recoverable_full ( self ) :
return self . recoverable > = self . limit - self . interval
return self . recoverable > = self . limit - 5 * self . interval
@property
def is_recovered_full ( self ) :
@ -358,13 +353,11 @@ class Energy:
@property
def __dict__ ( self ) :
return dict (
limit = self . limit ,
interval = self . interval ,
recoverable = self . recoverable ,
recovered = self . recovered ,
reference_time = self . reference_time
)
ret = { }
for key in dir ( self ) :
if not key . startswith ( ' _ ' ) :
ret [ key ] = getattr ( self , key )
return ret
class Details ( object ) :
@ -410,6 +403,14 @@ class Details(object):
next_level_up = ( 1 + ( self . xp / / 10 ) ) * 10
return next_level_up - self . xp
@property
def __dict__ ( self ) :
ret = { }
for key in dir ( self ) :
if not key . startswith ( ' _ ' ) :
ret [ key ] = getattr ( self , key )
return ret
class Politics :
is_party_member : bool = False
@ -420,6 +421,14 @@ class Politics:
is_congressman : bool = False
is_country_president : bool = False
@property
def __dict__ ( self ) :
ret = { }
for key in dir ( self ) :
if not key . startswith ( ' _ ' ) :
ret [ key ] = getattr ( self , key )
return ret
class House ( object ) :
quality = None
@ -441,6 +450,9 @@ class CitizenAPI:
token : str = " "
def __init__ ( self ) :
"""
Class for unifying eRepublik known endpoints and their required/optional parameters
"""
self . _req = SlowRequests ( )
def post ( self , url : str , * args , * * kwargs ) - > Response :
@ -449,130 +461,144 @@ class CitizenAPI:
def get ( self , url : str , * * kwargs ) - > Response :
return self . _req . get ( url , * * kwargs )
def get_article_json ( self , article_id : int ) - > Response :
def _ get_main_ article_json( self , article_id : int ) - > Response :
return self . get ( " {} /main/articleJson/ {} " . format ( self . url , article_id ) )
def get_battlefield_choose_side ( self , battle : int , side : int ) - > Response :
def _ get_military_ battlefield_choose_side( self , battle : int , side : int ) - > Response :
return self . get ( " {} /military/battlefield-choose-side/ {} / {} " . format ( self . url , battle , side ) )
def get_candidate_party ( self , party_slug : str ) - > Response :
def _ get_candidate_party( self , party_slug : str ) - > Response :
return self . post ( " {} /candidate/ {} " . format ( self . url , party_slug ) )
def get_citizen_hovercard ( self , citizen : int ) - > Response :
def _ get_main_ citizen_hovercard( self , citizen : int ) - > Response :
return self . get ( " {} /main/citizen-hovercard/ {} " . format ( self . url , citizen ) )
def get_citizen_profile ( self , player_id : int ) :
def _ get_main_ citizen_profile_json ( self , player_id : int ) - > Response :
return self . get ( " {} /main/citizen-profile-json/ {} " . format ( self . url , player_id ) )
def get_citizen_daily_assistant ( self ) :
def _ get_main_ citizen_daily_assistant( self ) - > Response :
return self . get ( " {} /main/citizenDailyAssistant " . format ( self . url ) )
def get_city_data_residents ( self , city : int , page : int = 1 , params : Dict [ str , Any ] = None ) :
def _ get_main_ city_data_residents( self , city : int , page : int = 1 , params : Mapping [ str , Any ] = None ) - > Response :
if params is None :
params = { }
return self . get ( " {} /main/city-data/ {} /residents " . format ( self . url , city ) , params = { " currentPage " : page , * * params } )
def get_country_military ( self , country : str ) - > Response :
def _ get_country_military( self , country : str ) - > Response :
return self . get ( " {} /country/military/ {} " . format ( self . url , country ) )
def get_economy_inventory_items ( self ) - > Response :
def _ get_economy_citizen_accounts ( self , organisation_id : int ) - > Response :
return self . get ( " {} /economy/citizen-accounts/ {} " . format ( self . url , organisation_id ) )
def _get_economy_inventory_items ( self ) - > Response :
return self . get ( " {} /economy/inventory-items/ " . format ( self . url ) )
def get_economy_job_market_json ( self , country : int ) - > Response :
def _ get_economy_job_market_json( self , country : int ) - > Response :
return self . get ( " {} /economy/job-market-json/ {} /1/desc " . format ( self . url , country ) )
def get_economy_my_companies ( self ) - > Response :
def _ get_economy_my_companies( self ) - > Response :
return self . get ( " {} /economy/myCompanies " . format ( self . url ) )
def get_economy_my_market_offers ( self ) - > Response :
def _ get_economy_my_market_offers( self ) - > Response :
return self . get ( " {} /economy/myMarketOffers " . format ( self . url ) )
def get_job_data ( self ) - > Response :
def _ get_main_ job_data( self ) - > Response :
return self . get ( " {} /main/job-data " . format ( self . url ) )
def get_leaderboards_damage_aircraft_rankings ( self , country : int , weeks : int = 0 , mu : int = 0 ) - > Response :
def _ get_main_ leaderboards_damage_aircraft_rankings( self , country : int , weeks : int = 0 , mu : int = 0 ) - > Response :
data = ( country , weeks , mu )
return self . get ( " {} /main/leaderboards-damage-aircraft-rankings/ {} / {} / {} /0 " . format ( self . url , * data ) )
def get_leaderboards_damage_rankings ( self , country : int , weeks : int = 0 , mu : int = 0 , div : int = 0 ) - > Response :
def _ get_main_ leaderboards_damage_rankings( self , country : int , weeks : int = 0 , mu : int = 0 ,
div : int = 0 ) - > Response :
data = ( country , weeks , mu , div )
return self . get ( " {} /main/leaderboards-damage-rankings/ {} / {} / {} / {} " . format ( self . url , * data ) )
def get_leaderboards_kills_aircraft_rankings ( self , country : int , weeks : int = 0 , mu : int = 0 ) - > Response :
def _ get_main_ leaderboards_kills_aircraft_rankings( self , country : int , weeks : int = 0 , mu : int = 0 ) - > Response :
data = ( country , weeks , mu )
return self . get ( " {} /main/leaderboards-kills-aircraft-rankings/ {} / {} / {} /0 " . format ( self . url , * data ) )
def get_leaderboards_kills_rankings ( self , country : int , weeks : int = 0 , mu : int = 0 , div : int = 0 ) - > Response :
def _ get_main_ leaderboards_kills_rankings( self , country : int , weeks : int = 0 , mu : int = 0 ,
div : int = 0 ) - > Response :
data = ( country , weeks , mu , div )
return self . get ( " {} /main/leaderboards-kills-rankings/ {} / {} / {} / {} " . format ( self . url , * data ) )
def get_main ( self ) :
def _ get_main( self ) - > Response :
return self . get ( self . url )
def get_message_alerts ( self , page : int = 1 ) - > Response :
return self . get_message_alerts ( page )
def _ get_main_ messages_paginated ( self , page : int = 1 ) - > Response :
return self . get ( " {} /main/messages-paginated/ {} " . format ( self . url , page ) )
def get_military_campaigns ( self ) - > Response :
def _ get_military_campaigns( self ) - > Response :
return self . get ( " {} /military/campaigns-new/ " . format ( self . url ) )
def get_military_unit_data ( self , unit _id: int , * * kwargs ) - > Response :
def _ get_military_show_weapons ( self , battle _id: int ) - > Response :
params = { " _token " : self . token , " battleId " : battle_id }
return self . get ( " {} /military/show-weapons " . format ( self . url ) , params = params )
def _get_military_unit_data ( self , unit_id : int , * * kwargs ) - > Response :
params = { " groupId " : unit_id , " panel " : " members " , * * kwargs }
return self . get ( " {} /military/military-unit-data/ " . format ( self . url ) , params = params )
def get_money_donation_accept ( self , donation_id : int ) - > Response :
def _ get_main_ money_donation_accept( self , donation_id : int ) - > Response :
return self . get ( " {} /main/money-donation/accept/ {} " . format ( self . url , donation_id ) , params = { " _token " : self . token } )
def get_money_donation_reject ( self , donation_id : int ) - > Response :
def _ get_main_ money_donation_reject( self , donation_id : int ) - > Response :
return self . get ( " {} /main/money-donation/reject/ {} " . format ( self . url , donation_id ) , params = { " _token " : self . token } )
def get_party_members ( self , party : int ) - > Response :
def _ get_main_notifications_ajax_community ( self , page : int = 1 ) - > Response :
return self . get ( " {} /main/notificationsAjax/community/ {} " . format ( self . url , page ) )
def _get_main_notifications_ajax_system ( self , page : int = 1 ) - > Response :
return self . get ( " {} /main/notificationsAjax/system/ {} " . format ( self . url , page ) )
def _get_main_notifications_ajax_report ( self , page : int = 1 ) - > Response :
return self . get ( " {} /main/notificationsAjax/report/ {} " . format ( self . url , page ) )
def _get_main_party_members ( self , party : int ) - > Response :
return self . get ( " {} /main/party-members/ {} " . format ( self . url , party ) )
def get_rankings_parties ( self , country : int ) - > Response :
def _ get_main_ rankings_parties( self , country : int ) - > Response :
return self . get ( " {} /main/rankings-parties/1/ {} " . format ( self . url , country ) )
def get_training_grounds_json ( self ) - > Response :
def _ get_main_ training_grounds_json( self ) - > Response :
return self . get ( " {} /main/training-grounds-json " . format ( self . url ) )
def get_weekly_challenge_data ( self ) - > Response :
def _ get_main_ weekly_challenge_data( self ) - > Response :
return self . get ( " {} /main/weekly-challenge-data " . format ( self . url ) )
def post_activate_battle_effect ( self , battle : int , kind : str , citizen _id: int ) - > Response :
def _get_wars_show ( self , war _id: int ) - > Response :
return self . get ( " {} /wars/show/ {} " . format ( self . url , war_id ) )
def _post_main_activate_battle_effect ( self , battle : int , kind : str , citizen_id : int ) - > Response :
data = dict ( battleId = battle , citizenId = citizen_id , type = kind , _token = self . token )
return self . post ( " {} /main/fight-activateBattleEffect " . format ( self . url ) , data = data )
def post_article_comments ( self , article : int , page : int = 1 ) - > Response :
def _ post_main_ article_comments( self , article : int , page : int = 1 ) - > Response :
data = dict ( _token = self . token , articleId = article , page = page )
if page :
data . update ( { ' page ' : page } )
return self . post ( " {} /main/articleComments " . format ( self . url ) , data = data )
def post_article_comments_create ( self , message : str , article : int , parent : int = 0 ) - > Response :
def _ post_main_ article_comments_create( self , message : str , article : int , parent : int = 0 ) - > Response :
data = dict ( _token = self . token , message = message , articleId = article )
if parent :
data . update ( { " parentId " : parent } )
return self . post ( " {} /main/articleComments/create " . format ( self . url ) , data = data )
def post_battle_console ( self , battle : int , zone : int , round _id: int , division : int , page : int ,
damage : bool ) - > Response :
data = dict ( battleId = battle , zoneId = zone , action = " battleStatistics " , round = round_id , division = division ,
leftPage = page , rightPage = page , _token = self . token )
if damage :
data . update ( { " type " : " damage " } )
else :
data . update ( { " type " : " kills " } )
def _ post_main_ battlefield_travel ( self , side_id : int , battle _id: int ) - > Response :
data = dict ( _token = self . token , sideCountryId = side_id , battleId = battle_id )
return self . post ( " {} /main/battlefieldTravel " . format ( self . url ) , data = data )
return self . post ( " {} /military/battle-console " . format ( self . url ) , data = data )
def post_buy_gold_items ( self , currency : str , item : str , amount : int ) - > Response :
def _post_main_buy_gold_items ( self , currency : str , item : str , amount : int ) - > Response :
data = dict ( itemId = item , currency = currency , amount = amount , _token = self . token )
return self . post ( " {} /main/buyGoldItems " . format ( self . url ) , data = data )
def post_candidate_for_congress ( self , presentation : str = " " ) - > Response :
def _ post_candidate_for_congress( self , presentation : str = " " ) - > Response :
data = dict ( _token = self . token , presentation = presentation )
return self . post ( " {} /candidate-for-congress " . format ( self . url ) , data = data )
def post_citizen_add_remove_friend ( self , citizen : int , add : bool ) - > Response :
def _ post_main_ citizen_add_remove_friend( self , citizen : int , add : bool ) - > Response :
data = dict ( _token = self . token , citizenId = citizen , url = " //www.erepublik.com/en/main/citizen-addRemoveFriend " )
if add :
data . update ( { " action " : " addFriend " } )
@ -580,69 +606,83 @@ class CitizenAPI:
data . update ( { " action " : " removeFriend " } )
return self . post ( " {} /main/citizen-addRemoveFriend " . format ( self . url ) , data = data )
def post_collect_anniversary_reward ( self ) - > Response :
def _ post_main_ collect_anniversary_reward( self ) - > Response :
return self . post ( " {} /main/collect-anniversary-reward " . format ( self . url ) , data = { " _token " : self . token } )
def post_country_donate ( self , country : int , action : str , value : Union [ int , float ] , quality : int = None ) :
def _ post_main_ country_donate( self , country : int , action : str , value : Union [ int , float ] ,
quality : int = None ) - > Response :
json = dict ( countryId = country , action = action , _token = self . token , value = value , quality = quality )
return self . post ( " {} /main/country-donate " . format ( self . url ) , data = json ,
headers = { " Referer " : " {} /country/economy/Latvia " . format ( self . url ) } )
def post_daily_task_reward ( self ) - > Response :
def _ post_main_ daily_task_reward( self ) - > Response :
return self . post ( " {} /main/daily-tasks-reward " . format ( self . url ) , data = dict ( _token = self . token ) )
def post_delete_messag e ( self , msg _id: lis t) - > Response :
def _ post_main_donate_articl e( self , article _id: int , amount : in t) - > Response :
data = dict ( _token = self . token , articleId = article_id , amount = amount )
return self . post ( " {} /main/donate-article " . format ( self . url ) , data = data )
def _post_delete_message ( self , msg_id : list ) - > Response :
data = { " _token " : self . token , " delete_message[] " : msg_id }
return self . post ( " {} /main/messages-delete " . format ( self . url ) , data )
def post_eat ( self , color : str ) - > Response :
def _ post_eat( self , color : str ) - > Response :
data = dict ( _token = self . token , buttonColor = color )
return self . post ( " {} /main/eat " . format ( self . url ) , params = data )
def post_economy_activate_house ( self , quality : int ) - > Response :
def _ post_economy_activate_booster ( self , quality : int , duration : int , kind : str ) - > Response :
data = dict ( type = kind , quality = quality , duration = duration , fromInventory = True )
return self . post ( " {} /economy/activateBooster " . format ( self . url ) , data = data )
def _post_economy_activate_house ( self , quality : int ) - > Response :
data = { " action " : " activate " , " quality " : quality , " type " : " house " , " _token " : self . token }
return self . post ( " {} /economy/activateHouse " . format ( self . url ) , data = data )
def post_economy_assign_to_holding ( self , factory : int , holding : int ) - > Response :
def _ post_economy_assign_to_holding( self , factory : int , holding : int ) - > Response :
data = dict ( _token = self . token , factoryId = factory , action = " assign " , holdingCompanyId = holding )
return self . post ( " {} /economy/assign-to-holding " . format ( self . url ) , data = data )
def post_economy_create_company ( self , industry : int , building_type : int = 1 ) - > Response :
def _ post_economy_create_company( self , industry : int , building_type : int = 1 ) - > Response :
data = { " _token " : self . token , " company[industry_id] " : industry , " company[building_type] " : building_type }
return self . post ( " {} /economy/create-company " . format ( self . url ) , data = data ,
headers = { " Referer " : " {} /economy/create-company " . format ( self . url ) } )
def post_economy_donate_items_action ( self , citizen : int , amount : int , industry : int ,
def _ post_economy_donate_items_action( self , citizen : int , amount : int , industry : int ,
quality : int ) - > Response :
data = dict ( citizen_id = citizen , amount = amount , industry_id = industry , quality = quality , _token = self . token )
return self . post ( " {} /economy/donate-items-action " . format ( self . url ) , data = data ,
headers = { " Referer " : " {} /economy/donate-items/ {} " . format ( self . url , citizen ) } )
def post_economy_donate_money_action ( self , citizen : int , amount : float = 0.0 ,
def _ post_economy_donate_money_action( self , citizen : int , amount : float = 0.0 ,
currency : int = 62 ) - > Response :
data = dict ( citizen_id = citizen , _token = self . token , currency_id = currency , amount = amount )
return self . post ( " {} /economy/donate-money-action " . format ( self . url ) , data = data ,
headers = { " Referer " : " {} /economy/donate-money/ {} " . format ( self . url , citizen ) } )
def post_economy_exchange_purchase ( self , amount : float , currency : int , offer : int ) - > Response :
def _ post_economy_exchange_purchase( self , amount : float , currency : int , offer : int ) - > Response :
data = dict ( _token = self . token , amount = amount , currencyId = currency , offerId = offer )
return self . post ( " {} /economy/exchange/purchase/ " . format ( self . url ) , data = data )
def post_economy_exchange_retrieve ( self , personal : bool , page : int , currency : int ) - > Response :
def _ post_economy_exchange_retrieve( self , personal : bool , page : int , currency : int ) - > Response :
data = dict ( _token = self . token , personalOffers = int ( personal ) , page = page , currencyId = currency )
return self . post ( " {} /economy/exchange/retrieve/ " . format ( self . url ) , data = data )
def post_economy_job _market_apply ( self , citize n: int , salary : int ) - > Response :
def _ post_economy_game_tokens _market( self , actio n: str ) - > Response :
assert action in [ ' retrieve ' , ]
data = dict ( _token = self . token , action = action )
return self . post ( " {} /economy/gameTokensMarketAjax " . format ( self . url ) , data = data )
def _post_economy_job_market_apply ( self , citizen : int , salary : int ) - > Response :
data = dict ( _token = self . token , citizenId = citizen , salary = salary )
return self . post ( " {} /economy/job-market-apply " . format ( self . url ) , data = data )
def post_economy_marketplace ( self , country : int , industry : int , quality : int ,
def _ post_economy_marketplace( self , country : int , industry : int , quality : int ,
order_asc : bool = True ) - > Response :
data = dict ( countryId = country , industryId = industry , quality = quality , ajaxMarket = 1 ,
orderBy = " price_asc " if order_asc else " price_desc " , _token = self . token )
return self . post ( " {} /economy/marketplaceAjax " . format ( self . url ) , data = data )
def post_economy_marketplace_actions ( self , amount : int , buy : bool = False , * * kwargs ) - > Response :
def _ post_economy_marketplace_actions( self , amount : int , buy : bool = False , * * kwargs ) - > Response :
if buy :
data = dict ( _token = self . token , offerId = kwargs [ ' offer ' ] , amount = amount , orderBy = " price_asc " , currentPage = 1 ,
buyAction = 1 )
@ -651,24 +691,24 @@ class CitizenAPI:
industryId = kwargs [ " industry " ] , quality = kwargs [ " quality " ] , amount = amount , sellAction = ' postOffer ' )
return self . post ( " {} /economy/marketplaceActions " . format ( self . url ) , data = data )
def post_economy_resign ( self ) - > Response :
def _ post_economy_resign( self ) - > Response :
return self . post ( " {} /economy/resign " . format ( self . url ) ,
headers = { " Content-Type " : " application/x-www-form-urlencoded " } ,
data = { " _token " : self . token , " action_type " : " resign " } )
def post_economy_sell_company ( self , factory : int , pin : int = None , sell : bool = True ) - > Response :
url = " {} /economy/sell-company/ {} " . format ( self . url , factory )
def _ post_economy_sell_company( self , factory : int , pin : int = None , sell : bool = True ) - > Response :
data = dict ( _token = self . token , pin = " " if pin is None else pin )
if sell :
data . update ( { " sell " : " sell " } )
else :
data . update ( { " dissolve " : factory } )
return self . post ( url , data = d ata , headers = { " Referer " : url } )
return self . post ( " {} /economy/sell-company/ {} " . form at( self . url , factory ) ,
data = data , headers = { " Referer " : self . url } )
def post_economy_train ( self , tg_ids : List [ int ] ) - > Response :
def _ post_economy_train( self , tg_ids : List [ int ] ) - > Response :
data : Dict [ str , Union [ int , str ] ] = { }
if not tg_ids :
return self . get_training_grounds_json ( )
return self . _ get_main_ training_grounds_json( )
else :
for idx , tg_id in enumerate ( tg_ids ) :
data [ " grounds[ %i ][id] " % idx ] = tg_id
@ -677,11 +717,11 @@ class CitizenAPI:
data [ ' _token ' ] = self . token
return self . post ( " {} /economy/train " . format ( self . url ) , data = data )
def post_economy_upgrade_company ( self , factory : int , level : int , pin : str = None ) - > Response :
def _ post_economy_upgrade_company( self , factory : int , level : int , pin : str = None ) - > Response :
data = dict ( _token = self . token , type = " upgrade " , companyId = factory , level = level , pin = " " if pin is None else pin )
return self . post ( " {} /economy/upgrade-company " . format ( self . url ) , data = data )
def post_economy_work ( self , action_type : str , wam : List [ int ] = None , employ : Dict [ int , int ] = None ) :
def _ post_economy_work( self , action_type : str , wam : List [ int ] = None , employ : Dict [ int , int ] = None ) - > Response :
"""
:return: requests.Response or None
"""
@ -690,87 +730,100 @@ class CitizenAPI:
if wam is None :
wam = [ ]
data : Dict [ str , Union [ int , str ] ] = dict ( action_type = action_type , _token = self . token )
if action_type == " work " :
return self . post ( " {} /economy/work " . format ( self . url ) , data = data )
elif action_type == " production " :
if action_type == " production " :
max_idx = 0
for idx , company_id in enumerate ( sorted( wam or [ ] ) ) :
for company_id in sorted ( wam or [ ] ) :
data . update ( {
" companies[ %i ][id] " % idx : company_id ,
" companies[ %i ][employee_works] " % idx : employ . pop ( company_id , 0 ) ,
" companies[ %i ][own_work] " % idx : 1
" companies[ %i ][id] " % max_ idx: company_id ,
" companies[ %i ][employee_works] " % max_ idx: employ . pop ( company_id , 0 ) ,
" companies[ %i ][own_work] " % max_ idx: 1
} )
max_idx = idx + 1
for idx , company_id in enumerate ( sorted( employ or [ ] ) ) :
idx_ = idx + max_idx
max_idx + = 1
for company_id in sorted ( employ or [ ] ) :
data . update ( {
" companies[ %i ][id] " % idx_ : company_id ,
" companies[ %i ][employee_works] " % idx_ : employ . pop ( company_id ) ,
" companies[ %i ][own_work] " % idx_ : 0
" companies[ %i ][id] " % max_ idx: company_id ,
" companies[ %i ][employee_works] " % max_ idx: employ . pop ( company_id ) ,
" companies[ %i ][own_work] " % max_ idx: 0
} )
max_idx + = 1
return self . post ( " {} /economy/work " . format ( self . url ) , data = data )
else :
return
def post_economy_work_overtime ( self ) - > Response :
def _ post_economy_work_overtime( self ) - > Response :
data = dict ( action_type = " workOvertime " , _token = self . token )
return self . post ( " {} /economy/workOvertime " . format ( self . url ) , data = data )
def post_forgot_password ( self , email : str ) - > Response :
def _ post_forgot_password( self , email : str ) - > Response :
data = dict ( _token = self . token , email = email , commit = " Reset password " )
return self . post ( " {} /forgot-password " . format ( self . url ) , data = data )
def post_fight_activate_booster ( self , battle : int , quality : int , duration : int , kind : str ) - > Response :
def _ post_military_ fight_activate_booster( self , battle : int , quality : int , duration : int , kind : str ) - > Response :
data = dict ( type = kind , quality = quality , duration = duration , battleId = battle , _token = self . token )
return self . post ( " {} /military/fight-activateBooster " . format ( self . url ) , data = data )
def post_login ( self , email : str , password : str ) - > Response :
def _ post_login( self , email : str , password : str ) - > Response :
data = dict ( csrf_token = self . token , citizen_email = email , citizen_password = password , remember = ' on ' )
return self . post ( " {} /login " . format ( self . url ) , data = data )
def post_messages_alert ( self , notification_ids : list ) - > Response :
def _ post_main_ messages_alert( self , notification_ids : List [ int ] ) - > Response :
data = { " _token " : self . token , " delete_alerts[] " : notification_ids , " deleteAllAlerts " : " 1 " , " delete " : " Delete " }
return self . post ( " {} /main/messages-alerts/1 " . format ( self . url ) , data = data )
def post_messages_compose ( self , subject : str , body : str , citizens : List [ int ] ) - > Response :
def _ post_main_ messages_compose( self , subject : str , body : str , citizens : List [ int ] ) - > Response :
url_pk = 0 if len ( citizens ) > 1 else str ( citizens [ 0 ] )
data = dict ( citizen_name = " , " . join ( [ str ( x ) for x in citizens ] ) ,
citizen_subject = subject , _token = self . token , citizen_message = body )
return self . post ( " {} /main/messages-compose/ {} } ". format ( self . url , url_pk ) , data = data )
return self . post ( " {} /main/messages-compose/ {} " . format ( self . url , url_pk ) , data = data )
def post_military_battle_console ( self , battle_id : int , round_id : int , division : int ) - > Response :
data = dict ( battleId = battle_id , zoneId = round_id , action = " battleStatistics " , round = round_id , division = divisio n,
type = " damage " , leftPage = 1 , rightPage = 1 , _token = self . token )
return self . post ( " {} /military/battle-console " . format ( self . url , battle_id ) , data = data )
def _ post_military_battle_console( self , battle_id : int , action : str , page : int = 1 , * * kwargs ) - > Response :
data = dict ( battleId = battle_id , action = action , _token = self . toke n)
if action = = " battleStatistics " :
data . update ( round = kwargs [ " round_id " ] , zoneId = kwargs [ " round_id " ] , leftPage = page , rightPage = page ,
division = kwargs [ " division " ] , type = kwargs . get ( " type " , ' damage ' ) , )
elif action == " warList " :
data . update ( page = page )
return self . post ( " {} /military/battle-console " . format ( self . url ) , data = data )
def post_military_fight_air ( self , battle_id : int , side_id : int ) - > Response :
def _ post_military_change_weapon ( self , battle_id : int , battle_zone_id : int , customization_level : int ) - > Response :
data = dict ( _token = self . token , battleZoneId = battle_zone_id , battleId = battle_id ,
customizationLevel = customization_level )
return self . post ( " {} /military/change-weapon " . format ( self . url ) , data = data )
def _post_military_deploy_bomb ( self , battle_id : int , bomb_id : int ) - > Response :
data = dict ( battleId = battle_id , bombId = bomb_id , _token = self . token )
return self . post ( " {} /military/deploy-bomb " . format ( self . url ) , data = data )
def _post_military_fight_air ( self , battle_id : int , side_id : int ) - > Response :
data = dict ( sideId = side_id , battleId = battle_id , _token = self . token )
return self . post ( " {} /military/fight-shoooot/ {} " . format ( self . url , battle_id ) , data = data )
def post_military_fight_ground ( self , battle_id : int , side_id : int ) - > Response :
def _ post_military_fight_ground( self , battle_id : int , side_id : int ) - > Response :
data = dict ( sideId = side_id , battleId = battle_id , _token = self . token )
return self . post ( " {} /military/fight-shooot/ {} " . format ( self . url , battle_id ) , data = data )
def post_military_group_missions ( self ) - > Response :
def _ post_military_group_missions( self ) - > Response :
data = dict ( action = " check " , _token = self . token )
return self . post ( " {} /military/group-missions " . format ( self . url ) , data = data )
def post_travel ( self , check : str , * * kwargs ) - > Response :
def _ post_main_ travel( self , check : str , * * kwargs ) - > Response :
data = dict ( _token = self . token , check = check , * * kwargs )
return self . post ( " {} /main/travel " . format ( self . url ) , data = data )
def post_travel_data ( self , * * kwargs ) - > Response :
def _ post_main_vote_article ( self , article_id : int ) - > Response :
data = dict ( _token = self . token , articleId = article_id )
return self . post ( " {} /main/vote-article " . format ( self . url ) , data = data )
def _post_main_travel_data ( self , * * kwargs ) - > Response :
return self . post ( " {} /main/travelData " . format ( self . url ) , data = dict ( _token = self . token , * * kwargs ) )
def post_wars_attack_region ( self , war : int , region : int ) - > Response :
data = dict ( _token = self . token )
return self . post ( " {} /wars/attack-region/{} /{} " . format ( self . url , war , region ) , data = data )
def _ post_wars_attack_region( self , war_id : int , region_id : int , region_name : str ) - > Response :
data = { ' _token ' : self . token , ' warId ' : war_id , ' regionName ' : region_name , ' regionNameConfirm ' : region_name }
return self . post ( ' {} /wars/attack-region/{} /{} ' . format ( self . url , war_id , region_id ) , data = data )
def post_weekly_challenge_reward ( self , reward_id : int ) - > Response :
def _ post_main_ weekly_challenge_reward( self , reward_id : int ) - > Response :
data = dict ( _token = self . token , rewardId = reward_id )
return self . post ( " {} /main/weekly-challenge-collect-reward " . format ( self . url ) , data = data )
def post_write_article ( self , title : str , content : str , location : int , kind : int ) - > Response :
def _ post_main_ write_article( self , title : str , content : str , location : int , kind : int ) - > Response :
data = dict ( _token = self . token , article_name = title , article_body = content , article_location = location ,
article_category = kind )
return self . post ( " {} /main/write-article " . format ( self . url ) , data = data )
@ -778,73 +831,73 @@ class CitizenAPI:
# Wall Posts
# ## Country
def post_country_comment_retrieve ( self , post_id : int ) :
def _ post_main_ country_comment_retrieve( self , post_id : int ) - > Response :
data = { " _token " : self . token , " postId " : post_id }
return self . post ( " {} /main/country-comment/retrieve/json " . format ( self . url ) , data = data )
def post_country_comment_create ( self , post_id : int , comment_message : str ) :
def _ post_main_ country_comment_create( self , post_id : int , comment_message : str ) - > Response :
data = { " _token " : self . token , " postId " : post_id , ' comment_message ' : comment_message }
return self . post ( " {} /main/country-comment/create/json " . format ( self . url ) , data = data )
def post_country_post_create ( self , body : str , post_as : int ) :
def _ post_main_ country_post_create( self , body : str , post_as : int ) - > Response :
data = { " _token " : self . token , " post_message " : body , " post_as " : post_as }
return self . post ( " {} /main/country-post/create/json " . format ( self . url ) , data = data )
def post_country_post_retrieve ( self ) :
def _ post_main_ country_post_retrieve( self ) - > Response :
data = { " _token " : self . token , " page " : 1 , " switchedFrom " : False }
return self . post ( " {} /main/country-post/retrieve/json " . format ( self . url ) , data = data )
# ## Military Unit
def post_military_unit_comment_retrieve ( self , post_id : int ) :
def _ post_main_ military_unit_comment_retrieve( self , post_id : int ) - > Response :
data = { " _token " : self . token , " postId " : post_id }
return self . post ( " {} /main/military-unit-comment/retrieve/json " . format ( self . url ) , data = data )
def post_military_unit_comment_create ( self , post_id : int , comment_message : str ) :
def _ post_main_ military_unit_comment_create( self , post_id : int , comment_message : str ) - > Response :
data = { " _token " : self . token , " postId " : post_id , ' comment_message ' : comment_message }
return self . post ( " {} /main/military-unit-comment/create/json " . format ( self . url ) , data = data )
def post_military_unit_post_create ( self , body : str , post_as : int ) :
def _ post_main_ military_unit_post_create( self , body : str , post_as : int ) - > Response :
data = { " _token " : self . token , " post_message " : body , " post_as " : post_as }
return self . post ( " {} /main/military-unit-post/create/json " . format ( self . url ) , data = data )
def post_military_unit_post_retrieve ( self ) :
def _ post_main_ military_unit_post_retrieve( self ) - > Response :
data = { " _token " : self . token , " page " : 1 , " switchedFrom " : False }
return self . post ( " {} /main/military-unit-post/retrieve/json " . format ( self . url ) , data = data )
# ## Party
def post_party_comment_retrieve ( self , post_id : int ) :
def _ post_main_ party_comment_retrieve( self , post_id : int ) - > Response :
data = { " _token " : self . token , " postId " : post_id }
return self . post ( " {} /main/party-comment/retrieve/json " . format ( self . url ) , data = data )
def post_party_comment_create ( self , post_id : int , comment_message : str ) :
def _ post_main_ party_comment_create( self , post_id : int , comment_message : str ) - > Response :
data = { " _token " : self . token , " postId " : post_id , ' comment_message ' : comment_message }
return self . post ( " {} /main/party-comment/create/json " . format ( self . url ) , data = data )
def post_party_post_create ( self , body : str ) :
def _ post_main_ party_post_create( self , body : str ) - > Response :
data = { " _token " : self . token , " post_message " : body }
return self . post ( " {} /main/party-post/create/json " . format ( self . url ) , data = data )
def post_party_post_retrieve ( self ) :
def _ post_main_ party_post_retrieve( self ) - > Response :
data = { " _token " : self . token , " page " : 1 , " switchedFrom " : False }
return self . post ( " {} /main/party-post/retrieve/json " . format ( self . url ) , data = data )
# ## Friend's Wall
def post_wall_comment_retrieve ( self , post_id : int ) :
def _ post_main_ wall_comment_retrieve( self , post_id : int ) - > Response :
data = { " _token " : self . token , " postId " : post_id }
return self . post ( " {} /main/wall-comment/retrieve/json " . format ( self . url ) , data = data )
def post_wall_comment_create ( self , post_id : int , comment_message : str ) :
def _ post_main_ wall_comment_create( self , post_id : int , comment_message : str ) - > Response :
data = { " _token " : self . token , " postId " : post_id , ' comment_message ' : comment_message }
return self . post ( " {} /main/wall-comment/create/json " . format ( self . url ) , data = data )
def post_wall_post_create ( self , body : str ) :
def _ post_main_ wall_post_create( self , body : str ) - > Response :
data = { " _token " : self . token , " post_message " : body }
return self . post ( " {} /main/wall-post/create/json " . format ( self . url ) , data = data )
def post_wall_post_retrieve ( self ) :
def _ post_main_ wall_post_retrieve( self ) - > Response :
data = { " _token " : self . token , " page " : 1 , " switchedFrom " : False }
return self . post ( " {} /main/wall-post/retrieve/json " . format ( self . url ) , data = data )
@ -928,11 +981,12 @@ class Reporter:
class MyJSONEncoder ( JSONEncoder ) :
def default ( self , o ) :
from erepublik . citizen import Citizen
if isinstance ( o , decimal . Decimal ) :
return float ( " {:.02f} " . format ( o ) )
elif isinstance ( o , datetime . datetime ) :
return dict ( __type__ = ' datetime ' , year = o . year , month = o . month , day = o . day , hour = o . hour , minute = o . minute ,
second = o . second , microsecond = o . microsecond )
second = o . second , microsecond = o . microsecond , tzinfo = o . tzinfo . zone if o . tzinfo else None )
elif isinstance ( o , datetime . date ) :
return dict ( __type__ = ' date ' , year = o . year , month = o . month , day = o . day )
elif isinstance ( o , datetime . timedelta ) :
@ -944,14 +998,16 @@ class MyJSONEncoder(JSONEncoder):
return o . __dict__
elif isinstance ( o , deque ) :
return list ( o )
elif isinstance ( o , Citizen ) :
return o . to_json ( )
return super ( ) . default ( o )
class BattleSide :
id : int
points : int
deployed : List [ int ] = list ( )
allies : List [ int ] = list ( )
deployed : List [ int ] = None
allies : List [ int ] = None
def __init__ ( self , country_id : int , points : int , allies : List [ int ] , deployed : List [ int ] ) :
self . id = country_id
@ -959,12 +1015,20 @@ class BattleSide:
self . allies = [ int ( ally ) for ally in allies ]
self . deployed = [ int ( ally ) for ally in deployed ]
@property
def __dict__ ( self ) :
ret = { }
for key in dir ( self ) :
if not key . startswith ( ' _ ' ) :
ret [ key ] = getattr ( self , key )
return ret
class BattleDivision :
end : datetime . datetime
epic : bool
dom_pts : Dict [ str , int ] = dict ( )
wall : Dict [ str , Union [ int , float ] ] = dict ( )
dom_pts : Dict [ str , int ] = None
wall : Dict [ str , Union [ int , float ] ] = None
@property
def div_end ( self ) - > bool :
@ -973,8 +1037,16 @@ class BattleDivision:
def __init__ ( self , end : datetime . datetime , epic : bool , inv_pts : int , def_pts : int , wall_for : int , wall_dom : float ) :
self . end = end
self . epic = epic
self . dom_pts . update ( { " inv " : inv_pts , " def " : def_pts } )
self . wall . update ( { " for " : wall_for , " dom " : wall_dom } )
self . dom_pts = dict ( { " inv " : inv_pts , " def " : def_pts } )
self . wall = dict ( { " for " : wall_for , " dom " : wall_dom } )
@property
def __dict__ ( self ) :
ret = { }
for key in dir ( self ) :
if not key . startswith ( ' _ ' ) :
ret [ key ] = getattr ( self , key )
return ret
class Battle ( object ) :
@ -986,13 +1058,13 @@ class Battle(object):
start : datetime . datetime = None
invader : BattleSide = None
defender : BattleSide = None
div : Dict [ int , BattleDivision ] = dict ( )
div : Dict [ int , BattleDivision ] = None
@property
def is_air ( self ) - > bool :
return not bool ( self . zone_id % 4 )
def __init__ ( self , battle : d ict) :
def __init__ ( self , battle : D ict[ str , Any ] ):
self . id = int ( battle . get ( ' id ' , 0 ) )
self . war_id = int ( battle . get ( ' war_id ' , 0 ) )
self . zone_id = int ( battle . get ( ' zone_id ' , 0 ) )
@ -1009,12 +1081,13 @@ class Battle(object):
[ row . get ( ' id ' ) for row in battle . get ( ' def ' , { } ) . get ( ' ally_list ' ) ] ,
[ row . get ( ' id ' ) for row in battle . get ( ' def ' , { } ) . get ( ' ally_list ' ) if row [ ' deployed ' ] ] )
self . div = { }
for div , data in battle . get ( ' div ' , { } ) . items ( ) :
div = int ( div )
div = int ( data . get ( ' div ' ) )
if data . get ( ' end ' ) :
end = datetime . datetime . fromtimestamp ( data . get ( ' end ' ) , tz = utils . erep_tz )
else :
end = datetime . datetime . max
end = utils . localize_dt ( datetime. datetime . max - datetime . timedelta ( days = 1 ) )
battle_div = BattleDivision (
end = end , epic = data . get ( ' epic_type ' ) in [ 1 , 5 ] ,
@ -1035,6 +1108,14 @@ class Battle(object):
self . id , utils . COUNTRIES [ self . invader . id ] , utils . COUNTRIES [ self . defender . id ] , self . zone_id , time_part
)
@property
def __dict__ ( self ) :
ret = { }
for key in dir ( self ) :
if not key . startswith ( ' _ ' ) :
ret [ key ] = getattr ( self , key )
return ret
class EnergyToFight :
energy : int = 0
@ -1065,3 +1146,57 @@ class EnergyToFight:
if 0 < new_energy < self . energy :
self . energy = new_energy
return self . energy
class TelegramBot :
__initialized = False
__queue : List [ str ] = [ ]
chat_id = 0
api_url = " "
player_name = " "
__last_time : datetime . datetime = None
def do_init ( self , chat_id : int , token : str , player_name : str = " " ) :
self . chat_id = chat_id
self . api_url = " https://api.telegram.org/bot {} /sendMessage " . format ( token )
self . player_name = player_name
self . __initialized = True
self . __last_time = utils . good_timedelta ( utils . now ( ) , datetime . timedelta ( minutes = - 5 ) )
if self . __queue :
self . send_message ( " \n \n – – – – – – – – – – – – – – – – – – – – – – \n \n " . join ( self . __queue ) )
def send_message ( self , message : str ) - > bool :
if not self . __initialized :
self . __queue . append ( message )
return True
if self . player_name :
message = f " Player * { self . player_name } * \n " + message
if utils . good_timedelta ( utils . now ( ) , datetime . timedelta ( seconds = - 1 ) ) < = self . __last_time :
tb = traceback . extract_stack ( )
message + = " \n \n ``` \n {} \n ``` " . format ( " \n " . join ( [ ' File " {} " , line {} , in {} \n ' . format ( l . filename , l . lineno , l . name ) for l in tb ] ) )
response = post ( self . api_url , json = dict ( chat_id = self . chat_id , text = message , parse_mode = " Markdown " ) )
self . __last_time = utils . now ( )
return response . json ( ) . get ( ' ok ' )
def report_free_bhs ( self , battles : List [ Tuple [ int , int , int , int , datetime . timedelta ] ] ) :
battle_links = [ ]
for battle_id , side_id , against_id , damage , time_left in battles :
total_seconds = int ( time_left . total_seconds ( ) )
time_start = " "
hours , remainder = divmod ( total_seconds , 3600 )
if hours :
time_start = f " { hours } h "
minutes , seconds = divmod ( remainder , 60 )
time_start + = f " { minutes : 02 } m { seconds : 02 } s "
damage = " {:,} " . format ( damage ) . replace ( ' , ' , ' ' )
battle_links . append ( f " * { damage } *dmg bh for [ { utils . COUNTRIES [ side_id ] } vs { utils . COUNTRIES [ against_id ] } ] "
f " (https://www.erepublik.com/en/military/battlefield/ { battle_id } ) "
f " _time since start { time_start } _ " )
self . send_message ( " Free BHs: \n " + " \n " . join ( battle_links ) )
def report_full_energy ( self , available : int , limit : int , interval : int ) :
message = f " Full energy ( { available } hp/ { limit } hp + { interval } hp/6min) "
self . send_message ( message )
def report_medal ( self , msg ) :
self . send_message ( f " New award: * { msg } * " )