goalMessenger.py (8359B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\dailygoals\client\goalMessenger.py 2 from six.moves import http_client as httplib 3 import logging 4 import uuid 5 import blue 6 from carbon.common.script.sys.serviceConst import ROLE_QA, ROLE_PROGRAMMER 7 from dailygoals.client.utils import format_goal_from_payload 8 from eveProto.generated.eve_public.dailygoal.api.requests_pb2 import GetRequest, GetResponse, GetAllCurrentRequest, GetAllCurrentResponse, GetAllWithRewardsRequest, GetAllWithRewardsResponse, RedeemRequest, RedeemResponse, PayForCompletionRequest, PayForCompletionResponse 9 from eveProto.generated.eve_public.dailygoal.api.admin.admin_pb2 import ProgressRequest, ProgressResponse 10 from eveProto.generated.eve_public.dailygoal.api.notices_pb2 import ProgressedNotice, CompletedNotice, CurrentGoalsNotice, RedeemedNotice 11 import dailygoals.client.goalMessengerSignals as messenger_signals 12 from stackless_response_router.exceptions import TimeoutException, UnpackException 13 from dailygoals.client.errors import GoalMessengerError, GoalNotRedeemableToCurrentLocation 14 logger = logging.getLogger(__name__) 15 16 class DailyGoalMessenger(object): 17 _instance = None 18 public_gateway = None 19 20 @classmethod 21 def get_instance(cls, public_gateway): 22 if not cls._instance: 23 cls._instance = DailyGoalMessenger(public_gateway) 24 return cls._instance 25 26 def __init__(self, public_gateway): 27 self.public_gateway = public_gateway 28 self._subscribe_to_notices() 29 30 def _subscribe_to_notices(self): 31 self.public_gateway.subscribe_to_notice(CurrentGoalsNotice, lambda payload, _: self.on_current_goals_received(payload)) 32 self.public_gateway.subscribe_to_notice(CompletedNotice, lambda payload, _: self.on_goal_completed(payload)) 33 self.public_gateway.subscribe_to_notice(ProgressedNotice, lambda payload, _: self.on_goal_progressed(payload)) 34 self.public_gateway.subscribe_to_notice(RedeemedNotice, lambda payload, _: self.on_goal_redeemed(payload)) 35 36 def _is_programmer(self): 37 return session and session.role & ROLE_PROGRAMMER 38 39 def iter_format_goals(self, goals): 40 for goal in goals: 41 yield format_goal_from_payload(goal_id=uuid.UUID(bytes=goal.id.uuid), goal_attributes=goal.goal, goal_progress=goal.current_progress, earnings=goal.earnings, paid_completion=goal.paid_completion) 42 43 def get_current_goals(self): 44 if self._is_programmer(): 45 import dailygoals.client.qa_settings as daily_goals_qa_settings 46 if daily_goals_qa_settings.daily_goals_get_goals_force_delay.get() > 0: 47 blue.synchro.Sleep(daily_goals_qa_settings.daily_goals_get_goals_force_delay.get() * 1000) 48 if daily_goals_qa_settings.daily_goals_get_goals_force_errors.get(): 49 if daily_goals_qa_settings.daily_goals_get_goals_randomize_errors.get(): 50 import random 51 if random.random() > 0.5: 52 raise Exception 53 else: 54 raise Exception 55 logger.info('Daily Goals: sending GetAllCurrentRequest') 56 request = GetAllCurrentRequest() 57 code, payload = self._send_request(request, GetAllCurrentResponse) 58 if payload.goals is None: 59 return [] 60 data = [ goal for goal in self.iter_format_goals(payload.goals) if goal is not None ] 61 return data 62 63 def get_goal(self, goal_id): 64 logger.info('Daily Goals: sending GetRequest for goal %s' % goal_id) 65 request = GetRequest() 66 request.goal.uuid = goal_id.bytes 67 code, payload = self._send_request(request, GetResponse) 68 goal_data = format_goal_from_payload(goal_id=goal_id, goal_attributes=payload.goal, goal_progress=payload.progress, earnings=payload.earnings) 69 return goal_data 70 71 def pay_for_completion(self, goal_id): 72 logger.info('Daily Goals: sending PayForCompletionRequest for goal %s' % goal_id) 73 request = PayForCompletionRequest() 74 request.goal.uuid = goal_id.bytes 75 try: 76 self._send_request(request, PayForCompletionResponse) 77 except GoalMessengerError as gme: 78 logger.error('Daily Goals: error while paying to complete goal %s', goal_id) 79 raise gme 80 81 def get_all_with_rewards_page(self, token = '', size = 100): 82 logger.info('Daily Goals: sending GetAllWithRewardsRequest') 83 request = GetAllWithRewardsRequest() 84 request.page.size = size 85 request.page.token = token 86 try: 87 logger.info('GetAllWithRewardsRequest sent with data %s', request) 88 code, payload = self._send_request(request, GetAllWithRewardsResponse) 89 logger.info('GetAllWithRewardsResponse received with data %s', payload) 90 except GoalMessengerError as gme: 91 logger.error('Daily Goals: Unable to get page with token %s', token) 92 raise gme 93 94 goal_id_list = [ uuid.UUID(bytes=identifier.uuid) for identifier in payload.ids ] 95 return (payload.next_page.token, goal_id_list) 96 97 def redeem_reward(self, goal_id, do_redeem_current_location): 98 logger.info('Daily Goals: sending RedeemRequest for goal %s, to current location: %s' % (goal_id, do_redeem_current_location)) 99 request = RedeemRequest() 100 request.goal.uuid = goal_id.bytes 101 request.redeem_current_location = do_redeem_current_location 102 try: 103 self._send_request(request, RedeemResponse) 104 except GoalMessengerError as gme: 105 logger.error('Daily Goals: error while redeeming reward for goal %s', goal_id) 106 if do_redeem_current_location and gme.status_code == httplib.FORBIDDEN: 107 raise GoalNotRedeemableToCurrentLocation(goal_id, session.locationid) 108 109 def set_goal_progress(self, goal_id, character_id, progress_to_add): 110 logger.info('Daily Goals: sending ProgressRequest for goal %s, progress +=%s' % (goal_id, progress_to_add)) 111 if session and session.role & ROLE_QA: 112 request = ProgressRequest() 113 request.goal.uuid = goal_id.bytes 114 request.character.sequential = character_id 115 request.progress = progress_to_add 116 self._send_request(request, ProgressResponse) 117 118 def on_current_goals_received(self, _payload): 119 messenger_signals.on_current_goals_received_internal() 120 121 def on_goal_completed(self, payload): 122 goal_id = uuid.UUID(bytes=payload.goal.uuid) 123 logger.info('Daily Goals: goal %s Completed Notice' % goal_id) 124 messenger_signals.on_goal_completed_internal(goal_id) 125 126 def on_goal_progressed(self, payload): 127 goal_id = uuid.UUID(bytes=payload.goal.uuid) 128 current_progress = payload.current_progress 129 messenger_signals.on_goal_progressed_internal(goal_id, current_progress) 130 131 def on_goal_redeemed(self, payload): 132 goal_id = uuid.UUID(bytes=payload.goal.uuid) 133 logger.info('Daily Goals: goal %s Redeemed Notice' % goal_id) 134 messenger_signals.on_goal_redeemed_internal(goal_id) 135 136 def _send_request(self, request, response_class, timeout_seconds = 10, max_attempts = 2): 137 try: 138 response_primitive, payload = self.public_gateway.send_blocking_character_request_and_receive_response(request_payload=request, expected_response_class=response_class, timeout_seconds=timeout_seconds, max_attempts=max_attempts, retry_delay_in_seconds=1) 139 if response_primitive.status_code != httplib.OK: 140 if hasattr(request, 'goal') and hasattr(request.goal, 'uuid'): 141 goal_uuid = uuid.UUID(bytes=request.goal.uuid) 142 else: 143 goal_uuid = None 144 logger.error('{proto}: statusCode={status_code}, statusMessage={status_message}, goal={goal_uuid}'.format(proto=request.DESCRIPTOR.full_name, status_code=response_primitive.status_code, status_message=response_primitive.status_message, goal_uuid=goal_uuid or 'undefined')) 145 raise GoalMessengerError(request.DESCRIPTOR.name, response_primitive.status_code) 146 except TimeoutException as exc: 147 raise GoalMessengerError('Exceeded max retries for' + request.DESCRIPTOR.name, httplib.REQUEST_TIMEOUT) 148 149 return (response_primitive.status_code, payload)