def checkLimits(self, user_obj): result = CanStayOnlineResult() if CHARGE_DEBUG: toLog("checkLimits called for %s" % user_obj.getUserID(), LOG_DEBUG) credit = user_obj.calcCurrentCredit() if credit <= 0: #now set reasons for all instances to credit finished result.setKillForAllInstances( errorText("USER_LOGIN", "CREDIT_FINISHED", False), user_obj.instances) return result credit_usage_per_second = 0 earliest_rule_end = defs.MAXLONG next_more_applicable = defs.MAXLONG seconds_from_morning = secondsFromMorning() for _index in range(user_obj.instances): if not user_obj.charge_info.accounting_started[_index]: continue cur_rule = user_obj.charge_info.effective_rules[_index] # find new rule try: effective_rule = self.getEffectiveRule(user_obj, _index + 1) except LoginException, e: result.addInstanceToKill(_index + 1, e.getErrorText()) continue if cur_rule != effective_rule: cur_rule.end(user_obj, _index + 1) effective_rule.start(user_obj, _index + 1) #change current effective rule user_obj.charge_info.setEffectiveRule(_index + 1, effective_rule) # if effective_rule ras or port are wildcards if effective_rule.priority < 3: #check if a more applicable rule (ras or ports are specified) #can be used before this rule ends next_more_applicable_rule = self.getNextMoreApplicableRule( user_obj, _index + 1) if next_more_applicable_rule != None: next_more_applicable = min( next_more_applicable_rule.interval.getStartSeconds() - seconds_from_morning, next_more_applicable) earliest_rule_end = min( earliest_rule_end, effective_rule.interval.getEndSeconds() - seconds_from_morning + 1) #+1 to ensure we don't run at 23:59:59 or such times credit_usage_per_second += effective_rule.cpm / 60.0 + \ effective_rule.cpk * effective_rule.assumed_kps
def checkLimits(self,user_obj): result=CanStayOnlineResult() credit=user_obj.calcCurrentCredit() if credit<=0: #now set reasons for all instances to credit finished result.setKillForAllInstances(errorText("USER_LOGIN","CREDIT_FINISHED",False),user_obj.instances) return result credit_usage_per_second=0 earliest_rule_end=defs.MAXLONG next_more_applicable=defs.MAXLONG seconds_from_morning=secondsFromMorning() for _index in range(user_obj.instances): cur_rule = user_obj.charge_info.effective_rules[_index] # find new rule try: effective_rule = self.getEffectiveRule(user_obj,_index+1) except LoginException,e: result.addInstanceToKill(_index+1,str(e)) continue if cur_rule != effective_rule: cur_rule.end(user_obj, _index+1) effective_rule.start(user_obj,_index+1) # if effective_rule ras or port are wildcards if effective_rule.priority < 3: #check if a more applicable rule (ras or ports are specified) #can be used before this rule ends next_more_applicable_rule=self.getNextMoreApplicableRule(user_obj,_index+1) if next_more_applicable_rule!=None: next_more_applicable=min(next_more_applicable_rule.interval.getStartSeconds()-seconds_from_morning,next_more_applicable) #change current effective rule user_obj.charge_info.effective_rules[_index] = effective_rule earliest_rule_end=min(earliest_rule_end,effective_rule.interval.getEndSeconds()-seconds_from_morning+1)#+1 to ensure we don't run at 23:59:59 or such times credit_usage_per_second += effective_rule.cpm / 60.0 + \ effective_rule.cpk * effective_rule.assumed_kps
def checkLimits(self,user_obj,before_start_accounting=False): """ Check Limits and return a CanStayOnlineResult The remaining time returned is the time until one of instances should be killed This works for no-multilogin and multilogin rases before_start_accounting(boolean): for no-multilogin session, we want to know how much user can talk before the start accounting. So we should set this to True """ result=CanStayOnlineResult() credit=user_obj.calcCurrentCredit() if credit<=0: #now set reasons for all instances to credit finished result.setKillForAllInstances(errorText("USER_LOGIN","CREDIT_FINISHED",False),user_obj.instances) return result start=time.time() playing={} for instance in range(1,user_obj.instances+1): if before_start_accounting or user_obj.charge_info.accounting_started[instance-1]: playing[instance]={"call_start_time":user_obj.getTypeObj().getCallStartTime(instance)} playing[instance]["call_start_rule"]=self._getEffectiveRuleForTime(user_obj,instance,playing[instance]["call_start_time"]) playing[instance]["call_start_prefix"]=playing[instance]["call_start_rule"].getPrefixObj(user_obj,instance,not before_start_accounting) if CHARGE_DEBUG: toLog("Playing Dic: %s"%playing, LOG_DEBUG) #playing instances, those who have accounting started remaining_time = 0 first_iter = True #is this the first iteration? first iteration is important because it examines current state of user break_loop = False while not break_loop: #continue until one of instances should be killed #this works well on single login sessions, that we want to know when user should #be killed at start of session #for multi login users, we do the loop just once credit_usage_per_second=0 credit_finish_time=defs.MAXLONG earliest_rule_end=defs.MAXLONG next_more_applicable=defs.MAXLONG free_seconds_end=defs.MAXLONG #if user has free seconds remaining from first rule seconds_from_morning=secondsFromMorning(start) no_effective_rule=0 #number of instances without effective rule for this iteration if CHARGE_DEBUG: toLog("Loop Start: %s first_iter: %s remaining_time: %s before_start_accounting=%s"%(start,first_iter,remaining_time, before_start_accounting),LOG_DEBUG) for instance in playing.keys(): try: effective_rule = self._getEffectiveRuleForTime(user_obj,instance,start) except LoginException,e: no_effective_rule += 1 if first_iter: result.addInstanceToKill(instance,str(e)) del(playing[instance]) else: break_loop=True continue if first_iter and not before_start_accounting: #change effective rule cur_rule=user_obj.charge_info.effective_rules[instance-1] if cur_rule!= effective_rule: cur_rule.end(user_obj, instance) effective_rule.start(user_obj,instance) user_obj.charge_info.setEffectiveRule(instance, effective_rule) # if effective_rule ras or port are wildcards if effective_rule.priority < 3: #check if a more applicable rule (ras or ports are specified) #can be used before this rule ends next_more_applicable_rule=self._getNextMoreApplicableRuleForTime(user_obj, instance, effective_rule, start) if next_more_applicable_rule!=None: next_more_applicable=min(next_more_applicable_rule.interval.getStartSeconds()-seconds_from_morning,next_more_applicable) earliest_rule_end=min(earliest_rule_end,effective_rule.interval.getEndSeconds()-seconds_from_morning+1) #check free seconds if start - playing[instance]["call_start_time"] < playing[instance]["call_start_prefix"].getFreeSeconds(): free_seconds_end=min(free_seconds_end,playing[instance]["call_start_prefix"].getFreeSeconds() - (start - playing[instance]["call_start_time"]) ) else: credit_usage_per_second += effective_rule.getPrefixObj(user_obj,instance,False).getCPM() / 60.0 #end for #if all instances knocked out because of no effective rule if not len(playing) or no_effective_rule==len(playing): break if credit_usage_per_second: credit_finish_time = credit / credit_usage_per_second next_event = min(earliest_rule_end,next_more_applicable,credit_finish_time,free_seconds_end) # we should have at least one increment if next_event < 1: next_event = 1 toLog("VoIPCharge:Next Event is zero credit: %s credit_usage_per: %s remaining_time: %s next_event: %s credit_finish_time: %s free_seconds_end: %s earliest_rule_end: %s next_more_applicable: %s seconds_from_morning: %s"% \ (credit,credit_usage_per_second,remaining_time,next_event,credit_finish_time,free_seconds_end,earliest_rule_end,next_more_applicable,seconds_from_morning) \ ,LOG_ERROR) #reduce the temp credit if credit_usage_per_second: credit -= next_event * credit_usage_per_second if credit <= 0: break_loop=True remaining_time += next_event # don't go for more than 1 week, who can talk for one week? ;) # this may happen if cpm is 0 if remaining_time > 7 * 24 * 3600 : break_loop = True first_iter = False start += next_event if CHARGE_DEBUG: toLog("Loop End: credit: %s credit_usage_per: %s remaining_time: %s next_event: %s credit_finish_time: %s free_seconds_end: %s earliest_rule_end: %s next_more_applicable: %s seconds_from_morning: %s"% \ (credit,credit_usage_per_second,remaining_time,next_event,credit_finish_time,free_seconds_end,earliest_rule_end,next_more_applicable,seconds_from_morning) \ ,LOG_DEBUG) if not before_start_accounting: break_loop=True
def checkLimits(self,user_obj,before_start_accounting=False): """ Check Limits and return a CanStayOnlineResult The remaining time returned is the time until one of instances should be killed This works for no-multilogin and multilogin rases before_start_accounting(boolean): for no-multilogin session, we want to know how much user can talk before the start accounting. So we should set this to True """ result=CanStayOnlineResult() credit=user_obj.calcCurrentCredit() if credit<=0: #now set reasons for all instances to credit finished result.setKillForAllInstances(errorText("USER_LOGIN","CREDIT_FINISHED"),user_obj.instances) return result start=time.time() playing={} for instance in range(1,user_obj.instances+1): if before_start_accounting or user_obj.charge_info.accounting_started[instance-1]: playing[instance]={"call_start_time":user_obj.getTypeObj().getCallStartTime(instance)} playing[instance]["call_start_rule"]=self._getEffectiveRuleForTime(user_obj,instance,playing[instance]["call_start_time"]) playing[instance]["call_start_prefix"]=playing[instance]["call_start_rule"].getPrefixObj(user_obj,instance,not before_start_accounting) if CHARGE_DEBUG: toLog("Playing Dic: %s"%playing, LOG_DEBUG) #playing instances, those who have accounting started remaining_time = 0 first_iter = True #is this the first iteration? first iteration is important because it examines current state of user break_loop = False while not break_loop: #continue until one of instances should be killed #this works well on single login sessions, that we want to know when user should #be killed at start of session #for multi login users, we do the loop just once credit_usage_per_second=0 credit_finish_time=defs.MAXLONG earliest_rule_end=defs.MAXLONG next_more_applicable=defs.MAXLONG free_seconds_end=defs.MAXLONG #if user has free seconds remaining from first rule seconds_from_morning=secondsFromMorning(start) no_effective_rule=0 #number of instances without effective rule for this iteration if CHARGE_DEBUG: toLog("Loop Start: %s first_iter: %s remaining_time: %s"%(start,first_iter,remaining_time),LOG_DEBUG) for instance in playing.keys(): try: effective_rule = self._getEffectiveRuleForTime(user_obj,instance,start) except LoginException,e: no_effective_rule += 1 if first_iter: result.addInstanceToKill(instance,str(e)) del(playing[instance]) else: break_loop=True continue if first_iter: #change effective rule cur_rule=user_obj.charge_info.effective_rules[instance-1] if cur_rule!= effective_rule: cur_rule.end(user_obj, instance) effective_rule.start(user_obj,instance) user_obj.charge_info.effective_rules[instance-1] = effective_rule # if effective_rule ras or port are wildcards if effective_rule.priority < 3: #check if a more applicable rule (ras or ports are specified) #can be used before this rule ends next_more_applicable_rule=self._getNextMoreApplicableRuleForTime(user_obj, instance, effective_rule, start) if next_more_applicable_rule!=None: next_more_applicable=min(next_more_applicable_rule.interval.getStartSeconds()-seconds_from_morning,next_more_applicable) earliest_rule_end=min(earliest_rule_end,effective_rule.interval.getEndSeconds()-seconds_from_morning+1)#+1 to ensure we don't run at 23:59:59 or such times #check free seconds if start - playing[instance]["call_start_time"] < playing[instance]["call_start_prefix"].getFreeSeconds(): free_seconds_end=min(free_seconds_end,playing[instance]["call_start_prefix"].getFreeSeconds() - (start - playing[instance]["call_start_time"]) ) else: credit_usage_per_second += effective_rule.getPrefixObj(user_obj,instance,False).getCPM() / 60.0 #end for #if all instances knocked out because of no effective rule if not len(playing) or no_effective_rule==len(playing): break if credit_usage_per_second: credit_finish_time = credit / credit_usage_per_second next_event = min(earliest_rule_end,next_more_applicable,credit_finish_time,free_seconds_end) #reduce the temp credit if credit_usage_per_second: credit -= next_event * credit_usage_per_second if credit <= 0: break_loop=True remaining_time += next_event # don't go for more than 1 week, who can talk for one week? ;) # this may happen if cpm is 0 if remaining_time > 7 * 24 * 3600 : break_loop = True first_iter = False start += next_event if CHARGE_DEBUG: toLog("Loop End: credit: %s credit_usage_per: %s remaining_time: %s next_event: %s credit_finish_time: %s free_seconds_end: %s earliest_rule_end: %s next_more_applicable: %s seconds_from_morning: %s"% \ (credit,credit_usage_per_second,remaining_time,next_event,credit_finish_time,free_seconds_end,earliest_rule_end,next_more_applicable,seconds_from_morning) \ ,LOG_DEBUG) if not before_start_accounting: break_loop=True