timer.py (4736B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\control\timer.py 2 from carbon.common.script.util.timerstuff import AutoTimer 3 from datetime import datetime 4 from gametime import DAY, HOUR, MIN, SEC 5 from localization.formatters.timeIntervalFormatters import FormatTimeIntervalShortWritten 6 from logging import getLogger 7 from signals import Signal 8 logger = getLogger('CountdownTimer') 9 10 def get_time_left_text(seconds_left): 11 if seconds_left > DAY: 12 show_from = 'day' 13 show_to = 'hour' 14 elif seconds_left > HOUR: 15 show_from = 'hour' 16 show_to = 'minute' 17 elif seconds_left > 10 * MIN: 18 show_from = 'minute' 19 show_to = 'minute' 20 elif seconds_left > MIN: 21 show_from = 'minute' 22 show_to = 'second' 23 else: 24 show_from = 'second' 25 show_to = 'second' 26 return FormatTimeIntervalShortWritten(seconds_left, showFrom=show_from, showTo=show_to) 27 28 29 class CountdownTimer(object): 30 DEFAULT_MSECS_BETWEEN_UPDATES = 250 31 DEFAULT_MAX_FETCHING_ATTEMPTS = 1 32 33 def __init__(self, fetch_timestamp_to_countdown_to, msecs_between_updates = DEFAULT_MSECS_BETWEEN_UPDATES, max_fetching_attempts = DEFAULT_MAX_FETCHING_ATTEMPTS): 34 self._fetch_timestamp_to_countdown_to = fetch_timestamp_to_countdown_to 35 self._msecs_between_updates = msecs_between_updates 36 self._max_fetching_attempts = max_fetching_attempts 37 self._timestamp_to_countdown_to = None 38 self._text = None 39 self._update_timer = None 40 self._fetching_attempts = 0 41 self.on_updated = Signal('CountdownTimer::on_updated') 42 43 def start_timer(self): 44 self.stop_timer() 45 self._update() 46 self._update_timer = AutoTimer(interval=self._msecs_between_updates, method=self._update) 47 48 def stop_timer(self): 49 if self._update_timer: 50 self._update_timer.KillTimer() 51 self._update_timer = None 52 self._update_text(text='') 53 54 @property 55 def timestamp_to_countdown_to(self): 56 if self._timestamp_to_countdown_to is None and self._fetching_attempts < self._max_fetching_attempts: 57 self._fetching_attempts += 1 58 self._timestamp_to_countdown_to = self._fetch_timestamp_to_countdown_to() 59 logger.info('Fetched timestamp to countdown to: %s', self._timestamp_to_countdown_to) 60 return self._timestamp_to_countdown_to 61 62 def _reset_timestamp_to_countdown_to(self): 63 self._timestamp_to_countdown_to = None 64 65 def _calculate_seconds_left(self): 66 now = self._get_now() 67 seconds_left = int((self.timestamp_to_countdown_to - now).total_seconds()) 68 return seconds_left * SEC 69 70 def _get_now(self): 71 return datetime.utcnow() 72 73 def _handle_negative_countdowns(self, seconds_left): 74 seconds_left = abs(seconds_left) 75 if seconds_left <= 2 * MIN: 76 logger.info('Attempted to update CountdownTimer with a negative time under 2 minutes (%s: %s), keep trying', seconds_left, get_time_left_text(seconds_left)) 77 self._reset_timestamp_to_countdown_to() 78 self._increase_timer_interval() 79 else: 80 logger.info('Attempted to update CountdownTimer with a negative time above 2 minutes (%s: %s), stop timer', seconds_left, get_time_left_text(seconds_left)) 81 self.stop_timer() 82 if seconds_left > 365 * DAY: 83 logger.error('CountdownTimer received negative time above 1 year (%s: %s)', seconds_left, get_time_left_text(seconds_left)) 84 85 def _update(self): 86 try: 87 seconds_left = self._calculate_seconds_left() 88 except TypeError as exc: 89 logger.info('Failed to calculate seconds left in CountdownTimer: %s', exc) 90 self.stop_timer() 91 return 92 93 if seconds_left <= 0: 94 self._handle_negative_countdowns(seconds_left) 95 return 96 text = get_time_left_text(seconds_left) 97 self._update_text(text) 98 self._reset_timer_interval_if_needed() 99 100 def _increase_timer_interval(self): 101 if not self._update_timer: 102 return 103 msecs_between_updates = self._msecs_between_updates * max(1, self._fetching_attempts) * 5 104 self._update_timer.Reset(msecs_between_updates) 105 106 def _reset_timer_interval_if_needed(self): 107 self._fetching_attempts = 0 108 if not self._update_timer: 109 return 110 if self._update_timer.interval == self._msecs_between_updates: 111 return 112 self._update_timer.Reset(self._msecs_between_updates) 113 114 def _update_text(self, text): 115 if text != self._text: 116 self.on_updated(text) 117 self._text = text