def offline(self, request, msisdn='', local='no'): api_log.info('%s - [PUT] %s/offline Data: msisdn: "%s"', request.getClientIP(), self.path, msisdn) try: sub = Subscriber() sub.expire_lu(msisdn) data = {'status': 'success', 'error': ''} except SubscriberException as e: data = {'status': 'failed', 'error': str(e)} api_log.debug(data) return data # Take advantage to point this subscriber to the new location in our hlr # so we (at least) don't have to wait for the next hlr sync run try: if local == 'yes': current_bts = config['local_ip'] else: current_bts = request.getClientIP() cur = db_conn.cursor() now = datetime.datetime.fromtimestamp(int(time.time())) cur.execute( 'UPDATE hlr SET current_bts=%(current_bts)s, updated=%(updated)s WHERE msisdn=%(msisdn)s', { 'msisdn': msisdn, 'current_bts': current_bts, 'updated': now }) db_conn.commit() except psycopg2.DatabaseError as e: data = {'status': 'failed', 'error': str(e)} api_log.debug(data) return data api_log.debug(data) return data
def validate_data(self, pin): res_log.debug('Check PIN length') if len(pin) > 4 or len(pin) < 4: raise ResellerException('PIN invalid length') res_log.debug('Check if Reseller exists') # check if reseller exists in the database and the PIN is valid try: cur = db_conn.cursor() cur.execute( 'SELECT msisdn,pin FROM resellers WHERE msisdn=%(msisdn)s', {'msisdn': str(self.reseller_msisdn)}) if cur.rowcount > 0: res_log.debug('Valid Reseller found') res_log.debug('Auth PIN') data = cur.fetchone() if data[1] != pin: raise ResellerException('Invalid PIN!') res_log.debug('Check if subscriber is valid') # check if subscriber exists try: sub = Subscriber() sub.get(self.subscriber_msisdn) except SubscriberException as e: raise ResellerException('Invalid subscriber') else: raise ResellerException('Invalid Reseller') except psycopg2.DatabaseError as e: raise ResellerException( 'Database error getting reseller msisdn: %s' % e)
def deactivate_subscriptions(self, msg): try: sms = SMS() sub = Subscriber() cur = db_conn.cursor() cur.execute( 'SELECT msisdn FROM subscribers WHERE subscription_status = 0 AND authorized = 1' ) count = cur.rowcount if count > 0: self.logger.info('Found %d subscribers to be deactivated' % count) subscribers_list = cur.fetchall() db_conn.commit() for mysub in subscribers_list: self.logger.debug( 'Send SMS that account is deactivated to %s' % mysub[0]) sms.send(config['smsc'], mysub[0], msg) # disable subscriber try: sub.authorized(mysub[0], 0) except SubscriberException as e: raise SubscriptionException( 'PG_HLR error in deactivating subscription: %s' % e) else: db_conn.commit() self.logger.info('No subscribers need to be deactivate') except psycopg2.DatabaseError as e: raise SubscriptionException( 'PG_HLR error in checking subscriptions to deactivate: %s' % e)
def search(self, request, search): api_log.info('%s - [GET] %s', request.getHost().host, self.path) try: sub = Subscriber() data = json.dumps(sub.get_msisdn_autocomplete(search)) except SubscriberException as e: data = {'status': 'failed', 'error': str(e)} api_log.debug(data) return data
def getAll(self, request): api_log.info('%s - [GET] %s', request.getHost().host, self.path) try: reseller = Subscriber() data = json.dumps(reseller.get_all(), cls=PGEncoder) except ResellerException as e: data = {'status': 'failed', 'error': str(e)} api_log.info(data) return data
def imei(self, request, partial_imei): api_log.info('%s - [GET] %s/%s', request.getHost().host, self.path, partial_imei) try: sub = Subscriber() data = json.dumps(sub.get_imei_autocomplete(partial_imei)) except SubscriberException as e: data = {'status': 'failed', 'error': str(e)} api_log.debug(data) return data
def delete(self, request, msisdn): api_log.info('%s - [DELETE] %s/%s', request.getHost().host, self.path, msisdn) try: sub = Subscriber() sub.delete(msisdn) data = {'status': 'success', 'error': ''} except SubscriberException as e: data = {'status': 'failed', 'error': str(e)} api_log.info(data) return data
def getAll(self, request): api_log.info('%s - [GET] %s', request.getHost().host, self.path) if (request.getHeader('Origin') and request.getHeader('Origin').find("8080") > -1): request.setHeader('Access-Control-Allow-Origin', '*') try: sub = Subscriber() data = json.dumps(sub.get_all(), cls=PGEncoder) except SubscriberException as e: data = {'status': 'failed', 'error': str(e)} api_log.info(data) return data
def extension(self, request, imsi): api_log.info('%s - [GET] %s/%s', request.getHost().host, self.path, imsi) if request.getHeader('Origin').find("8080") > -1: request.setHeader('Access-Control-Allow-Origin', '*') try: sub = Subscriber() data = json.dumps(sub.get_local_extension(imsi), cls=PGEncoder) except SubscriberException as e: data = {'status': 'failed', 'error': str(e)} api_log.debug(data) return data
def subscription_info(self): sub = Subscriber() unpaid = self.get_unpaid_subscriptions() print('---\n\n') for number in unpaid: print('PostGres: ' + number[0] + ':') info = sub.print_vty_hlr_info(number) if "No subscriber found for extension" in info: print('OsmoHLR: ' + info) print("Checking for 5 digit extension") info = sub.print_vty_hlr_info(number[0][-5:]) print('OsmoHLR: ' + info) print('---\n\n')
def send_subscription_fee_notice(self, msg): # get all subscribers try: sub = Subscriber() subscribers_list = sub.get_all() except SubscriberException as e: raise SubscriptionException('%s' % e) sms = SMS() for mysub in subscribers_list: self.logger.debug("Send sms to %s %s" % (mysub[1], msg)) sms.send(config['smsc'], mysub[1], msg)
def put(self, request, msisdn='', name='', balance='', authorized='', subscription_status='', location='', equipment='', roaming='', package=''): api_log.info( '%s - [PUT] %s/%s Data: name:"%s" balance:"%s" authorized:"%s" ' 'subscription_status:"%s" location:"%s" equipment:"%s" roaming:"%s" package:"%s"', request.getHost().host, self.path, msisdn, name, balance, authorized, subscription_status, location, equipment, roaming, package) try: sub = Subscriber() if subscription_status != '': sub.subscription(msisdn, subscription_status) if authorized != '': sub.authorized(msisdn, authorized) if msisdn != '' and name != '' or balance != '': sub.edit(msisdn, name, balance, location, equipment, roaming, package) data = {'status': 'success', 'error': ''} except SubscriberException as e: data = {'status': 'failed', 'error': str(e)} api_log.info(data) return data
def name(self, request, msisdn): if msisdn in self.remote_names: if (self.remote_names[msisdn][:2] == '__' and (time.time() - float(self.remote_names[msisdn][2:])) < 600): return '' sub = Subscriber() rname = sub.get_name(msisdn) if not rname: self.remote_names[msisdn] = '' return '' if rname == '_timeout_': self.remote_names[msisdn] = '__' + str(time.time()) return '' self.remote_names[msisdn] = rname return json.dumps(rname, cls=PGEncoder)
def post(self, request, msisdn, name, balance, location, equipment, package): api_log.info( '%s - [POST] %s Data: msisdn:"%s" name:"%s" balance:"%s" location:"%s equipment:"%s" package: "%s"', request.getHost().host, self.path, msisdn, name, balance, location, equipment, package) try: sub = Subscriber() num = sub.add(msisdn, name, balance, location, equipment, package) if num != msisdn: data = {'status': 'success', 'error': num} else: data = {'status': 'success', 'error': ''} except SubscriberException as e: data = {'status': 'failed', 'error': str(e)} api_log.info(data) return data
def send_subscription_fee_reminder(self, msg): try: subscribers_list = self.get_unpaid_subscriptions() except SubscriptionException as e: raise SubscribtionException( 'ERROR in getting unpaid subscriptions') sms = SMS() sub = Subscriber() for mysub in subscribers_list: package = sub.get_package(mysub[0]) self.logger.debug("Send sms to %s %s" % (mysub[0], msg)) sms.send(config['smsc'], mysub[0], msg) if package > 0: self.logger.info("Deactivate Package for %s", mysub[0]) sub.reset_package(mysub[0]) sms.send(config['smsc'], mysub[0], "Su paquete ha sido desactivado.")
def add(self, msisdn, credit): sub = Subscriber() sms = SMS() try: mysub = sub.get(msisdn) current_balance = sub.get_balance(msisdn) except SubscriberException as e: raise CreditException(e) new_balance = Decimal(str(credit)) + Decimal(str(current_balance)) # update subscriber balance try: cur = db_conn.cursor() cur.execute( 'UPDATE subscribers SET balance=%(new_balance)s WHERE msisdn=%(msisdn)s', { 'new_balance': Decimal(str(new_balance)), 'msisdn': msisdn }) db_conn.commit() sms.send(config['smsc'], msisdn, sms_credit_added % (credit, new_balance)) except psycopg2.DatabaseError as e: db_conn.rollback() raise CreditException( 'PG_HLR error updating subscriber balance: %s' % e) # insert transaction into the credit history try: cur = db_conn.cursor() cur.execute( 'INSERT INTO credit_history(msisdn,previous_balance,current_balance,amount) VALUES(%s,%s,%s,%s)', (msisdn, current_balance, new_balance, credit)) except psycopg2.DatabaseError as e: db_conn.rollback() raise CreditException( 'PG_HLR error inserting invoice in the history: %s' % e) finally: db_conn.commit()
def add(self, msisdn, pin, balance): # check if subscriber exists try: sub = Subscriber() sub.get(msisdn) except SubscriberException as e: raise ResellerException('Invalid subscriber: %s' % e) # provision the reseller try: cur = db_conn.cursor() cur.execute( 'INSERT INTO resellers(msisdn,pin,balance) VALUES(%(msisdn)s,%(pin)s,%(balance)s)', { 'msisdn': msisdn, 'pin': pin, 'balance': Decimal(str(balance)) }) db_conn.commit() except psycopg2.DatabaseError as e: raise ResellerException('PG_HLR error provisioning reseller: %s' % e)
def add_subscriber_credit(self, amount): res_log.info('Add %s to subscriber %s' % (amount, self.subscriber_msisdn)) try: sub = Subscriber() from modules.credit import Credit, CreditException credit = Credit() res_log.debug('Get current subscriber balance') current_subscriber_balance = sub.get_balance( self.subscriber_msisdn) res_log.debug('Current subscriber balance: %s' % current_subscriber_balance) new_balance = Decimal(str(current_subscriber_balance)) + Decimal( str(amount)) res_log.debug('New balance: %s' % new_balance) # Credit.add will send SMS credit.add(self.subscriber_msisdn, amount) self.subscriber_balance = new_balance except SubscriberException as e: raise ResellerException('Error getting subscriber balance: %s' % e) except CreditException as e: raise ResellerException('Error adding credit to subscriber: %s' % e)
def bill(self, session, subscriber, destination_number, context, duration): if context == 'LOCAL': bill_log.info( '===========================================================================' ) bill_log.info('LOCAL Context') bleg_connected = session.getVariable('bleg_uuid') hangup_cause = session.getVariable('hangup_cause') #subscriber = session.getVariable('bleg_destination_number') #print session.getVariable('bleg_billsec') configuration = Configuration() try: _charge_local = configuration.check_charge_local_calls() if _charge_local == 1: _charge = configuration.get_charge_local_calls() if duration > int(_charge[1]): call_cost = _charge[0] else: call_cost = 0 else: return except: bill_log.error('Error reading local calls charge config.') return # set destination_name and cost for the CDR session.setVariable('destination_name', 'Local') session.setVariable('cost', str(call_cost)) bill_log.info('Call duration: %d sec Call cost: %.2f' % (duration, call_cost)) if call_cost > Decimal('0.00'): sub = Subscriber() try: previous_balance = sub.get_balance(subscriber) current_balance = previous_balance - call_cost real_balance = 0 if current_balance < 0 else current_balance bill_log.info( 'Previous balance: %.2f Current Balance: %.2f' % (previous_balance, real_balance)) sub.set_balance(subscriber, real_balance) bill_log.info('Billing %s completed successfully' % subscriber) except SubscriberException as e: bill_log.error('Error during billing the subscriber: %s' % e) else: bill_log.info('Call too short to Bill') if context == 'OUTBOUND': bill_log.info( '===========================================================================' ) bill_log.info( 'OUTBOUND Context Bill subscriber %s destination %s' % (subscriber, destination_number)) sub = Subscriber() # get rate rate = self.get_rate(destination_number) log_dest = rate[1] package = sub.get_package(subscriber) if package == 1 and rate[1] == "Mexico Cellular-Telcel": bill_log.info( 'Subscriber has package, removing 5 mins from call duration of %s seconds', duration) log_dest = rate[1] + ' (P)' duration = duration - 300 if duration < 0: duration = 0 if 'charge_outbound_rate_type' in globals( ) and charge_outbound_rate_type == 'sec': call_cost = Decimal( math.ceil((rate[3] / 60) * duration * 100) / 100).quantize( Decimal('0.01')) else: call_cost = self.get_call_cost(duration, rate[3]) try: previous_balance = sub.get_balance(subscriber) current_balance = previous_balance - call_cost if current_balance < 0: # There was not enough balance to cover the rounded up minutes real_balance = 0 # Log what we ACTUALLY deducted in the CDR call_cost = previous_balance else: real_balance = current_balance bill_log.info('Previous balance: %.2f Current Balance: %.2f' % (previous_balance, real_balance)) sub.set_balance(subscriber, real_balance) bill_log.info('Billing %s completed successfully' % subscriber) except SubscriberException as e: bill_log.error('Error during billing the subscriber: %s' % e) # set destination_name and cost for the CDR session.setVariable('destination_name', log_dest) session.setVariable('cost', str(call_cost)) bill_log.info('Call duration: %d sec Call cost: %.2f' % (duration, call_cost)) if context == 'INBOUND': bill_log.info( '===========================================================================' ) bill_log.info('INBOUND Context') bleg_connected = session.getVariable('bleg_uuid') hangup_cause = session.getVariable('hangup_cause') subscriber = session.getVariable('bleg_destination_number') #print session.getVariable('bleg_billsec') configuration = Configuration() if (bleg_connected != '' and bleg_connected != None ) and hangup_cause == 'NORMAL_CLEARING': bill_log.info('Call B-leg was connected. Bill subscriber %s' % subscriber) try: charge_info = configuration.get_charge_inbound_calls() if charge_info[1] == 'call': bill_log.info('Charge type: per call, Cost: %s' % charge_info[0]) call_cost = charge_info[0] try: sub = Subscriber() previous_balance = sub.get_balance(subscriber) current_balance = previous_balance - call_cost bill_log.info( 'Previous balance: %.2f Current Balance: %.2f' % (previous_balance, current_balance)) sub.set_balance(subscriber, current_balance) bill_log.info('Billing %s completed successfully' % subscriber) except SubscriberException as e: bill_log.error( 'Error during billing the subscriber: %s' % e) elif charge_info[1] == 'min': bill_log.info( 'Charge type rate per min, cost per min: %s' % charge_info[0]) # BUG: Cannot get b-leg billsec from FS. Use the billsec of a-leg instead call_cost = self.get_call_cost(duration, charge_info[0]) bill_log.info('Call duration %s sec Call cost: %s' % (duration, call_cost)) try: sub = Subscriber() previous_balance = sub.get_balance(subscriber) current_balance = previous_balance - call_cost bill_log.info( 'Previous balance: %.2f Current Balance: %.2f' % (previous_balance, current_balance)) sub.set_balance(subscriber, current_balance) bill_log.info('Billing %s completed successfully' % subscriber) except SubscriberException as e: bill_log.error( 'Error during billing the subscriber: %s' % e) except ConfigurationException as e: bill_log.error(e) else: bill_log.info( 'Call B-leg was not connected. Not billing subscriber %s' % subscriber)
def get(self, request, msisdn): api_log.info('%s - [GET] %s/%s', request.getHost().host, self.path, msisdn) try: sub = Subscriber() if msisdn == 'all_connected': data = json.dumps(sub.get_all_connected(), cls=PGEncoder) elif msisdn == 'all_sip': data = json.dumps(sub.get_sip_connected()) elif msisdn == 'unpaid_subscription': data = json.dumps(sub.get_unpaid_subscription(), cls=PGEncoder) elif msisdn == 'paid_subscription': data = json.dumps(sub.get_paid_subscription(), cls=PGEncoder) elif msisdn == 'unauthorized': data = json.dumps(sub.get_unauthorized(), cls=PGEncoder) elif msisdn == 'online': data = json.dumps(sub.get_online(), cls=PGEncoder) elif msisdn == 'offline': data = json.dumps(sub.get_offline(), cls=PGEncoder) elif msisdn == 'all_roaming': data = json.dumps(sub.get_roaming(), cls=PGEncoder) elif msisdn == 'all_foreign': if request.getClientIP().find("10.23") > -1: request.setHeader('Access-Control-Allow-Origin', '*') data = json.dumps(sub.get_all_foreign(), cls=PGEncoder) else: data = json.dumps(sub.get(msisdn), cls=PGEncoder) except SubscriberException as e: data = {'status': 'failed', 'error': str(e)} if msisdn != 'all_connected': api_log.info(data) else: api_log.debug(data) return data