def render_mailbox(self, user_ext): output = "<h1>Correo de voz</h1>\n" model = Model() model.session.commit() # refresh session all_messages = model.query(VoiceMailMessage).filter_by(mailboxuser=user_ext) folders = set() for message in all_messages: folders.add(message.dir) folders = list(folders) folders.sort() for folder in folders: result = [] messages = model.query(VoiceMailMessage).filter_by(mailboxuser=user_ext, dir=folder) output += "<h2>"+os.path.basename(folder)+"</h2>\n" for message in messages: actions2 = "" if message.msg_id: audio = html.format_audio('/voicemail/message/' + message.msg_id) actions = '<form method="POST" action="/voicemail/delete/%s/%s"><input type="hidden" name="msg_id" value="%s" /><input type="hidden" name="user_ext" value="%s" /><input type="submit" name="submit" value="Borrar" /></form>' % (user_ext, message.msg_id, message.msg_id, user_ext) if folder.endswith('INBOX'): actions2 += '<form method="POST" action="/voicemail/archive/%s/%s"><input type="hidden" name="msg_id" value="%s" /><input type="hidden" name="user_ext" value="%s" /><input type="submit" name="submit" value="Archivar" /></form>' % (user_ext, message.msg_id, message.msg_id, user_ext) else: audio = "" actions = "" result.append([message.callerid, time.ctime(message.origtime), str(message.duration), audio, actions, actions2]) output += html.format_table([['origen', 'fecha', 'duracion', 'audio', 'actions', '']] + result) return output
def render_all(self, user_ext=None): """ Render calls for the given extensions. user_ext -- extension to render calls for. """ model = Model() result = {} result['dateTimeFormat'] = 'iso8601' result['wikiURL'] = 'http://simile.mit.edu/shelf/' result['wikiSection'] = 'Simile Cubism Timeline' result['events'] = [] events = result['events'] if user_ext: user = model.query(User).filter_by(voip_id=user).first() calls = model.query(Call).filter_by(user=user) else: calls = model.query(Call) for call in calls: if not call.user: print "call without user!", call continue event = {} event['start'] = self.format_date(call.timestamp) event['end'] = self.format_date(call.timestamp+datetime.timedelta(seconds=float(call.duration))) event['title'] = "from %s to %s" % (call.user.voip_id, call.destination) provider_name = self.get_provider_name(call.provider) event['description'] = "from %s to %s.<br/>duration: %.2fmin<br/>provider: %s" % (call.user.voip_id, call.destination, float(call.duration)/60.0, provider_name) event['color'] = self.get_color(call.provider) # event['description'] = "" # event['image'] = "" # event['link'] = "" events.append(event) return json.dumps(result)
def __init__(self, id, cost, app_from, app_to): self._id = id self._callID = 0 self._provider = 'unknown' if cost: self._realcost = Decimal(cost) else: self._realcost = Decimal() try: self._cost = Decimal(cost) if self._cost: self._cost += Decimal(0.001) # benefit margin except: self._cost = Decimal(0.0) self._from = app_from self._to = app_to self._real_to = app_to model = Model() peer = model.query(SipPeer).filter_by(regexten=self._from).first() if peer: self._from = peer.name self._user = model.query(User).filter_by(voip_id=peer.regexten).first() self._from_exten = peer.regexten else: self._user = None self._from_exten = ''
def change_options(user_ext, options): model = Model() peer = model.query(SipPeer).filter_by(regexten=user_ext).first() if not peer: return False username = peer.name # password if 'passwd' in options: pass_string = "%s:asterisk:%s" % (username, options['password']) hashed = md5.new(pass_string).hexdigest() peer.md5secret = hashed peer.secret = '' # newcodecs newcodecs = options.get('codecs', False) if newcodecs: peer.disallow = 'all' peer.allow = ','.join(newcodecs) else: peer.disallow = '' peer.allow = '' # tls if options.get('tls', False): peer.transport = 'tls' else: peer.transport = 'udp' # srtp if options.get('srtp', False): peer.encryption = 'yes' else: peer.encryption = 'no' # voicemail exten = model.query(Extension).filter_by(exten=peer.regexten).first() if options.get('voicemail', False): exten.app = 'Gosub' exten.appdata = 'stdexten,%s,1(SIP/%s,default)' % (peer.regexten, peer.name) else: exten.app = 'Dial' exten.appdata = 'SIP/%s,60' % (peer.name, ) exten_sip = model.query(Extension).filter_by(exten=peer.name).first() exten_sip.app = exten.app exten_sip.appdata = exten.appdata model.session.commit() # reload asterisk reload_peer(peer.name) return True
def change_options(user_ext, options): model = Model() peer = model.query(SipPeer).filter_by(regexten=user_ext).first() if not peer: return False username = peer.name # password if "passwd" in options: pass_string = "%s:asterisk:%s" % (username, options["password"]) hashed = md5.new(pass_string).hexdigest() peer.md5secret = hashed peer.secret = "" # newcodecs newcodecs = options.get("codecs", False) if newcodecs: peer.disallow = "all" peer.allow = ",".join(newcodecs) else: peer.disallow = "" peer.allow = "" # tls if options.get("tls", False): peer.transport = "tls" else: peer.transport = "udp" # srtp if options.get("srtp", False): peer.encryption = "yes" else: peer.encryption = "no" # voicemail exten = model.query(Extension).filter_by(exten=peer.regexten).first() if options.get("voicemail", False): exten.app = "Gosub" exten.appdata = "stdexten,%s,1(SIP/%s,default)" % (peer.regexten, peer.name) else: exten.app = "Dial" exten.appdata = "SIP/%s,60" % (peer.name,) exten_sip = model.query(Extension).filter_by(exten=peer.name).first() exten_sip.app = exten.app exten_sip.appdata = exten.appdata model.session.commit() # reload asterisk reload_peer(peer.name) return True
def apply_transaction(self, address, balance, balance_confirmed, timestamp): model = Model() wallet = model.query(Wallet).filter_by(address=address).first() if wallet and wallet.user: user = wallet.user balance_unconfirmed = Decimal(balance) / Decimal("100000000") balance_confirmed = Decimal(balance_confirmed) / Decimal( "100000000") received = wallet.received if not wallet.received: received = Decimal("0") new_coins = balance_confirmed - received wallet.received = balance_confirmed wallet.unconfirmed = balance_unconfirmed # XXX need to add a mechanism to account credit (convert to euros) #user.credit += new_coins print "applied transaction", balance_confirmed, balance_unconfirmed, user, user.voip_id model.session.commit() sse.resource.notify( { 'confirmed': float(balance_confirmed), 'unconfirmed': float(balance_unconfirmed), 'currency': 'BTC' }, 'balance', user) else: print "unknown tx destination"
def general_stats(self): res = "" total = 0 total_free = 0 free_calls = 0 cost_calls = 0 total_cost = Decimal() total_benefit = Decimal() model = Model() calls = model.query(Call) for call in calls: cost = Decimal(call.cost) duration = call.charged minutes = duration/60 if cost: total += duration cost_calls += 1 total_cost += cost total_benefit += Decimal(minutes)*Decimal(0.001) + Decimal(0.001) else: total_free += duration free_calls += 1 res += "<p>Minutos con coste: %s</p>\n" % (total/60,) res += "<p>Minutos gratis: %s</p>\n" % (total_free/60,) res += "<p>Llamadas: %s Gratis: %s Con coste: %s</p>\n" % (calls.count(), free_calls, cost_calls) res += "<p>Coste total %.3f Beneficio %.3f</p>\n" % (total_cost, total_benefit) return res
def render_user(self, user_ext, request): model = Model() peer = model.query(SipPeer).filter_by(regexten=user_ext).first() creditlink = '' if peer: username = peer.name else: username = user_ext user = model.get_user_fromext(user_ext) logged = session.get_user(request) if user: credit = "%.3f" % (user.credit,) user_charges = charges.get_charges(user_ext) n_calls = len(user.calls) pager = self.render_pager(user_ext, n_calls) user_calls = calls.get_calls(user_ext, logged, 10) + "<p>%s</p>" % (pager,) creditlink = "" if user.credit > 0: if user.voip_id == logged.voip_id: creditlink += '<a href="/credit/transfer">Transferir</a>' else: creditlink += '<a href="/credit/transfer/%s">Transferir</a>' % (user.voip_id) if logged.admin: creditlink += ' <a href="/credit/add/%s">Crear</a>' % (user.voip_id) else: credit = 0.0 user_charges = "" user_calls = "" all_calls = self.render_user_calls(user_ext, request) args = {'ext': user_ext, 'username': username, 'credit': credit, 'credit_link':creditlink ,'calls': user_calls, 'charges': user_charges, 'all_calls': all_calls} return print_template('user-pbx-lorea', args)
def render_GET(self, request): res = None logged = session.get_user(request) if not logged: return redirectTo('/', request) parts = request.path.split("/") if len(parts) > 2 and logged.admin: user_ext = parts[2] else: user_ext = logged.voip_id args = { 'ext': user_ext, 'lowquality': '', 'tls': '', 'srtp': '', 'voicemail': '' } options = get_options(user_ext) if 'codecs' in options and 'gsm' in options['codecs']: args['lowquality'] = ' checked ' if options['tls']: args['tls'] = ' checked ' if options['srtp']: args['srtp'] = ' checked ' if options['voicemail']: args['voicemail'] = ' checked ' model = Model() user = model.query(User).filter_by(voip_id=user_ext).first() if user and (logged.admin or user.id == logged.id): args['bitcoin'] = self.render_btc(logged, user, wallet) else: return redirectTo('/', request) content = print_template('options', args) return print_template('content-pbx-lorea', {'content': content})
def render_GET(self, request): res = None logged = session.get_user(request) if not logged: return redirectTo('/', request) parts = request.path.split("/") if len(parts) > 2 and logged.admin: user_ext = parts[2] else: user_ext = logged.voip_id args = {'ext': user_ext, 'lowquality': '', 'tls': '', 'srtp': '', 'voicemail': ''} options = get_options(user_ext) if 'codecs' in options and 'gsm' in options['codecs']: args['lowquality'] = ' checked ' if options['tls']: args['tls'] = ' checked ' if options['srtp']: args['srtp'] = ' checked ' if options['voicemail']: args['voicemail'] = ' checked ' model = Model() user = model.query(User).filter_by(voip_id=user_ext).first() if user and (logged.admin or user.id == logged.id): args['bitcoin'] = self.render_btc(logged, user, wallet) else: return redirectTo('/', request) content = print_template('options', args) return print_template('content-pbx-lorea', {'content': content})
def check_password(self, username, password, user_ext=None): model = Model() peer = None if user_ext: peer = model.query(SipPeer).filter_by(regexten=user_ext).first() else: peer = model.query(SipPeer).filter_by(name=username).first() if peer: username = peer.name user_input = md5.new(username + ":asterisk:" + password).hexdigest() hashed = peer.md5secret if peer.secret and not hashed: hashed = md5.new(username + ":asterisk:" + peer.secret).hexdigest() if hashed == user_input: return peer return False
def get_user(request): model = Model() session_id = str(request.getSession().uid) web_session = model.query(WebSession).filter_by(session_id=session_id).first() if web_session: web_session.user.update_wallet(model) return web_session.user
def delete_voicemail(self, request, logged, user_ext, msg_id): model = Model() msg = model.query(VoiceMailMessage).filter_by(msg_id=msg_id, mailboxuser=user_ext).first() if msg and msg.recording and (msg.mailboxuser == logged.voip_id or logged.admin): mb_user = msg.mailboxuser number = msg.msgnum msgdir = msg.dir model.session.delete(msg) model.session.commit() # reorder other messages in the folder msgs = model.query(VoiceMailMessage).filter_by(mailboxuser=mb_user) for amsg in msgs: if amsg.msgnum > number and amsg.dir == msgdir: amsg.msgnum -= 1 model.session.commit() return mb_user return logged.voip_id
def parse_users(filename=None): extensions = {} model = Model() peers = model.query(SipPeer).order_by("regexten") for peer in peers: extensions[peer.regexten] = peer.name return extensions
def render_GET(self, request): session_id = str(request.getSession().uid) request.getSession().expire() model = Model() web_session = model.query(WebSession).filter_by(session_id=session_id).first() if web_session: model.session.delete(web_session) model.session.commit() return redirectTo("/", request)
def parse_users(filename=None): extensions = {} model = Model() peers = model.query(SipPeer).order_by('regexten') for peer in peers: extensions[peer.regexten] = peer.name return extensions
def render_user_calls(self, user_ext, request): FILE = "/var/log/asterisk/cdr-csv/Master.csv" if not os.path.exists(FILE): return f = open(FILE) csv_file = csv.reader(f) data = list(csv_file) logged = session.get_user(request) model = Model() peer = model.query(SipPeer).filter_by(regexten=user_ext).first() user_extensions = [user_ext] if peer: user_extensions.append(peer.name) res = "" calls = "" for a in data: if 'queue-multicall' in a: continue time_1 = a[9] time_2 = a[10] time_3 = a[11] duration = a[12] billsecs = int(a[13]) from_ext = a[1] from_name = a[4] appdata = a[8] status = a[-4] id = a[-2] delta = 0.0 #totalsecs += int(billsecs) t1 = datetime.strptime(time_1, "%Y-%m-%d %H:%M:%S") to_ext = a[2] if to_ext.startswith("stdexten-"): status = to_ext.split("-")[1] to_ext = a[8].split("@")[0] if "@" in appdata and "/" in appdata: dest = appdata.split("/")[1].split(",")[0] to_ext = dest if time_3: t2 = datetime.strptime(time_3, "%Y-%m-%d %H:%M:%S") delta = t2 - t1 if from_ext in user_extensions or to_ext in user_extensions: #calls = "<p>[%s] %s to %s for %s secs on %s/%s/%s %s</p>" % (id, from_ext, to_ext, delta, t1.day, t1.month, t1.year, status) + calls date = "%s/%s/%s" % (t1.day, t1.month, t1.year) if not from_ext in user_extensions and logged.admin: from_ext = "<a href='/user/%s'>%s</a>" % (from_ext, from_ext) if not to_ext in user_extensions and logged.admin: to_ext = "<a href='/user/%s'>%s</a>" % (to_ext, to_ext) calls = ( "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>" % (date, from_ext, to_ext, delta, status)) + calls #if status == "ANSWERED" and (billsecs > umbra or not umbra): # print from_ext,"->"," "*(14-len(a[2]))+a[2]+" ["+str(billsecs)+"]\t"+str(t1.day)+"\t"+str(t1.hour) res += calls return res
def get_options(user_ext): model = Model() peer = model.query(SipPeer).filter_by(regexten=user_ext).first() username = peer.name options = {'srtp': False, 'tls': False, 'codecs': []} if peer.encryption == 'yes': options['srtp'] = True if peer.transport == 'tls': options['tls'] = True if peer.disallow == 'all': options['codecs'] = [] if peer.allow: options['codecs'] = peer.allow.split(',') exten = model.query(Extension).filter_by(exten=peer.regexten).first() if exten.app == 'Gosub': options['voicemail'] = True else: options['voicemail'] = False return options
def get_options(user_ext): model = Model() peer = model.query(SipPeer).filter_by(regexten=user_ext).first() username = peer.name options = {"srtp": False, "tls": False, "codecs": []} if peer.encryption == "yes": options["srtp"] = True if peer.transport == "tls": options["tls"] = True if peer.disallow == "all": options["codecs"] = [] if peer.allow: options["codecs"] = peer.allow.split(",") exten = model.query(Extension).filter_by(exten=peer.regexten).first() if exten.app == "Gosub": options["voicemail"] = True else: options["voicemail"] = False return options
def change_password(user_ext, password): model = Model() peer = model.query(SipPeer).filter_by(regexten=user_ext).first() pass_string = "%s:asterisk:%s" % (peer.name, password) hashed = md5.new(pass_string).hexdigest() peer.md5secret = hashed peer.secret = "" model.session.commit() # reload asterisk reload_peer(peer.name)
def change_password(user_ext, password): model = Model() peer = model.query(SipPeer).filter_by(regexten=user_ext).first() pass_string = "%s:asterisk:%s" % (peer.name, password) hashed = md5.new(pass_string).hexdigest() peer.md5secret = hashed peer.secret = '' model.session.commit() # reload asterisk reload_peer(peer.name)
def render_user_calls(self, user_ext, request): FILE = "/var/log/asterisk/cdr-csv/Master.csv" if not os.path.exists(FILE): return f = open(FILE) csv_file = csv.reader(f) data = list(csv_file) logged = session.get_user(request) model = Model() peer = model.query(SipPeer).filter_by(regexten=user_ext).first() user_extensions = [user_ext] if peer: user_extensions.append(peer.name) res = "" calls = "" for a in data: if 'queue-multicall' in a: continue time_1 = a[9] time_2 = a[10] time_3 = a[11] duration = a[12] billsecs = int(a[13]) from_ext = a[1] from_name = a[4] appdata = a[8] status = a[-4] id = a[-2] delta = 0.0 #totalsecs += int(billsecs) t1 = datetime.strptime(time_1, "%Y-%m-%d %H:%M:%S") to_ext = a[2] if to_ext.startswith("stdexten-"): status = to_ext.split("-")[1] to_ext = a[8].split("@")[0] if "@" in appdata and "/" in appdata: dest = appdata.split("/")[1].split(",")[0] to_ext = dest if time_3: t2 = datetime.strptime(time_3, "%Y-%m-%d %H:%M:%S") delta = t2-t1 if from_ext in user_extensions or to_ext in user_extensions: #calls = "<p>[%s] %s to %s for %s secs on %s/%s/%s %s</p>" % (id, from_ext, to_ext, delta, t1.day, t1.month, t1.year, status) + calls date = "%s/%s/%s" % (t1.day, t1.month, t1.year) if not from_ext in user_extensions and logged.admin: from_ext = "<a href='/user/%s'>%s</a>" % (from_ext, from_ext) if not to_ext in user_extensions and logged.admin: to_ext = "<a href='/user/%s'>%s</a>" % (to_ext, to_ext) calls = ("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>" % (date, from_ext, to_ext, delta, status)) + calls #if status == "ANSWERED" and (billsecs > umbra or not umbra): # print from_ext,"->"," "*(14-len(a[2]))+a[2]+" ["+str(billsecs)+"]\t"+str(t1.day)+"\t"+str(t1.hour) res += calls return res
def create_user(username, password): username_avail = 1 model = Model() # check if username is taken if model.query(SipPeer).filter_by(name=username).first(): print "username already taken", username return False # find next available extension peers = model.query(SipPeer).order_by("regexten") maxexten = 0 for peer in peers: exten = int(peer.regexten) if exten < 9999 and exten > maxexten: maxexten = exten nextexten = maxexten + 1 if nextexten < 1000: nextexten = 1000 # create user in database password = md5.new("%s:asterisk:%s" % (username, password)).hexdigest() peer = create_user_internal( model, regexten=str(nextexten), name=username, md5secret=password, callerid="%s <%s>" % (username, nextexten), type="friend", host="dynamic", nat="comedia,force_rport", # natted qualify="yes", # follow status mailbox=str(nextexten), # register with voicemail mwi context="from-freeuser", ) # reload asterisk reload_peer(peer.name) print "user created", username, nextexten return peer
def render_voice_message(self, request, logged, msg_id): model = Model() msg = model.query(VoiceMailMessage).filter_by(msg_id=msg_id).first() if msg and msg.recording and (msg.mailboxuser == logged.voip_id): # no admin here: request.setHeader('Content-Description', 'File Transfer') request.setHeader('Content-Type', 'application/octet-stream') request.setHeader('Content-Disposition', 'attachment; filename=recording-'+msg_id+'-.ogg') request.setHeader('Content-Transfer-Encoding', 'binary') #request.setHeader('Expires', '0') request.setHeader('Content-Length', len(msg.recording)) return msg.recording return "no access"
def render_accounts(self, request): res = "<h2>accounts</h2>" logged = session.get_user(request) if not logged or not logged.admin: return redirectTo("/", request) model = Model() all_users = model.query(User) total_credit = Decimal() for user in all_users: ext = user.voip_id credit = user.credit peer = model.query(SipPeer).filter_by(regexten=ext).first() if peer and peer.name: username = peer.name else: username = "******" res += "<p>%s <a href='/user/%s'>%s</a> %.3f %s</p>" % (str(ext), str(ext), str(username), credit, str(user.email)) total_credit += Decimal(credit) res += "<p>total credit: %s</p>" % (total_credit,) return res
def general_stats(self): res = "" total = 0 total_free = 0 free_calls = 0 cost_calls = 0 total_cost = Decimal() total_benefit = Decimal() model = Model() calls = model.query(Call) for call in calls: cost = Decimal(call.cost) duration = call.charged minutes = duration / 60 if cost: total += duration cost_calls += 1 total_cost += cost total_benefit += Decimal(minutes) * Decimal(0.001) + Decimal( 0.001) else: total_free += duration free_calls += 1 model = Model() btc_received = model.query(func.sum(Wallet.received)).scalar() btc_unconfirmed = model.query(func.sum(Wallet.unconfirmed)).scalar() btc_accounted = model.query(func.sum(Wallet.accounted)).scalar() if btc_unconfirmed: unconfirmed = '(+%.3f)' % (float(btc_unconfirmed), ) else: unconfirmed = '' res += "<p>Minutos con coste: %s</p>\n" % (total / 60, ) res += "<p>Minutos gratis: %s</p>\n" % (total_free / 60, ) res += "<p>Llamadas: %s Gratis: %s Con coste: %s</p>\n" % ( calls.count(), free_calls, cost_calls) res += "<p>Coste total %.3f Beneficio %.3f</p>" % (total_cost, total_benefit) res += "<p>btc in: %.3f %s out: %.3f</p>\n" % ( float(btc_received), unconfirmed, float(btc_accounted)) return res
def create_user(username, password): username_avail = 1 model = Model() # check if username is taken if model.query(SipPeer).filter_by(name=username).first(): print "username already taken", username return False # find next available extension peers = model.query(SipPeer).order_by('regexten') maxexten = 0 for peer in peers: exten = int(peer.regexten) if exten < 9999 and exten > maxexten: maxexten = exten nextexten = maxexten + 1 if nextexten < 1000: nextexten = 1000 # create user in database password = md5.new("%s:asterisk:%s" % (username, password)).hexdigest() peer = create_user_internal( model, regexten=str(nextexten), name=username, md5secret=password, callerid='%s <%s>' % (username, nextexten), type='friend', host='dynamic', nat='comedia,force_rport', # natted qualify='yes', # follow status mailbox=str(nextexten), # register with voicemail mwi context="from-freeuser") # reload asterisk reload_peer(peer.name) print "user created", username, nextexten return peer
def render_accounts(self, request): res = "<h2>accounts</h2>" logged = session.get_user(request) if not logged or not logged.admin: return redirectTo("/", request) model = Model() all_users = model.query(User) total_credit = Decimal() for user in all_users: ext = user.voip_id credit = user.credit peer = model.query(SipPeer).filter_by(regexten=ext).first() if peer and peer.name: username = peer.name else: username = "******" res += "<p>%s <a href='/user/%s'>%s</a> %.3f</p>" % ( str(ext), str(ext), str(username), credit) total_credit += Decimal(credit) res += "<p>total credit: %s</p>" % (total_credit, ) return res
def minutes_stats(self, request, period, columns, val_checker, obj_class): model = Model() ts_start = time.time() - period ts_end = time.time() data = [] current = 0 for a in range(columns): selected = model.query(obj_class).filter(and_(obj_class.timestamp>datetime.fromtimestamp(ts_start), obj_class.timestamp<datetime.fromtimestamp(ts_end))) pars = list(val_checker(selected)) data.insert(0, [pars, {'label': str(current)}]) ts_start -= period ts_end -= period current -= 1 return json.dumps(data)
def general_stats(self): res = "" total = 0 total_free = 0 free_calls = 0 cost_calls = 0 total_cost = Decimal() total_benefit = Decimal() model = Model() calls = model.query(Call) for call in calls: cost = Decimal(call.cost) duration = call.charged minutes = duration/60 if cost: total += duration cost_calls += 1 total_cost += cost total_benefit += Decimal(minutes)*Decimal(0.001) + Decimal(0.001) else: total_free += duration free_calls += 1 model = Model() btc_received = model.query(func.sum(Wallet.received)).scalar() btc_unconfirmed = model.query(func.sum(Wallet.unconfirmed)).scalar() btc_accounted = model.query(func.sum(Wallet.accounted)).scalar() if btc_unconfirmed: unconfirmed = '(+%.3f)' % (float(btc_unconfirmed), ) else: unconfirmed = '' res += "<p>Minutos con coste: %s</p>\n" % (total/60,) res += "<p>Minutos gratis: %s</p>\n" % (total_free/60,) res += "<p>Llamadas: %s Gratis: %s Con coste: %s</p>\n" % (calls.count(), free_calls, cost_calls) res += "<p>Coste total %.3f Beneficio %.3f</p>" % (total_cost, total_benefit) res += "<p>btc in: %.3f %s out: %.3f</p>\n" % (float(btc_received), unconfirmed, float(btc_accounted)) return res
def archive_voicemail(self, request, logged, user_ext, msg_id): model = Model() msg = model.query(VoiceMailMessage).filter_by(msg_id=msg_id, mailboxuser=user_ext).first() if msg and msg.recording and (msg.mailboxuser == logged.voip_id or logged.admin): mb_user = msg.mailboxuser number = msg.msgnum msgdir = msg.dir destdir = '/var/spool/asterisk/voicemail/default/%s/Old' % (logged.voip_id,) msg.dir = destdir msg.msgnum = 500 model.session.commit() # reorder other messages in the folder msgs = model.query(VoiceMailMessage).filter_by(mailboxuser=mb_user) lastmsg = -1 for amsg in msgs: if amsg.msgnum > number and amsg.dir == msgdir: amsg.msgnum -= 1 if amsg.dir == destdir and amsg.msgnum > lastmsg and not amsg.msg_id == msg_id: lastmsg = amsg.msgnum msg.msgnum = lastmsg + 1 model.session.commit() return mb_user return logged.voip_id
def minutes_stats(self, request, period, columns, val_checker, obj_class): model = Model() ts_start = time.time() - period ts_end = time.time() data = [] current = 0 for a in range(columns): selected = model.query(obj_class).filter( and_(obj_class.timestamp > datetime.fromtimestamp(ts_start), obj_class.timestamp < datetime.fromtimestamp(ts_end))) pars = list(val_checker(selected)) data.insert(0, [pars, {'label': str(current)}]) ts_start -= period ts_end -= period current -= 1 return json.dumps(data)
def render_user(self, user_ext, request): model = Model() peer = model.query(SipPeer).filter_by(regexten=user_ext).first() creditlink = '' if peer: username = peer.name else: username = user_ext user = model.get_user_fromext(user_ext) logged = session.get_user(request) if user: credit = "%.3f" % (user.credit, ) user_charges = charges.get_charges(user_ext) n_calls = len(user.calls) pager = self.render_pager(user_ext, n_calls) user_calls = calls.get_calls(user_ext, logged, 10) + "<p>%s</p>" % (pager, ) creditlink = "" if user.credit > 0: if user.voip_id == logged.voip_id: creditlink += '<a href="/credit/transfer">Transferir</a>' else: creditlink += '<a href="/credit/transfer/%s">Transferir</a>' % ( user.voip_id) if logged.admin: creditlink += ' <a href="/credit/add/%s">Crear</a>' % ( user.voip_id) else: credit = 0.0 user_charges = "" user_calls = "" all_calls = self.render_user_calls(user_ext, request) args = { 'ext': user_ext, 'username': username, 'credit': credit, 'credit_link': creditlink, 'calls': user_calls, 'charges': user_charges, 'all_calls': all_calls } return print_template('user-pbx-lorea', args)
def add_call(user_ext, destination, date, real_duration, duration, cost, rate, provider_name): model = Model() user = model.get_user_fromext(user_ext) provider = model.query(Provider).filter_by(name=provider_name).first() if not provider: provider = Provider(provider_name) model.session.add(provider) model.session.commit() call = Call(user=user, destination=destination, timestamp=datetime.fromtimestamp(float(date)), duration=real_duration, charged=duration, cost=cost, rate=rate, provider=provider) model.session.add(call) model.session.commit()
def on_peer_event(self, event): peer_name = event['peer'].split('/')[1] model = Model() peer = model.query(SipPeer).filter_by(name=peer_name).first() if peer: event['username'] = peer_name event['exten'] = peer.regexten event['useragent'] = peer.useragent event['channel'] = False if peer.fullcontact and 'transport=tls' in peer.fullcontact.lower(): event['tls'] = True else: event['tls'] = False if peer.encryption == 'yes': event['srtp'] = True else: event['srtp'] = False sse.resource.notify(event, 'peer' ,'admin') else: event['channel'] = True sse.resource.notify(event, 'peer' ,'admin')
def login(self, login, password, request, email=''): peer = self.check_password(login, password) if peer: user_ext = peer.regexten model = Model() user = model.get_user_fromext(user_ext) if not user: user = User(user_ext) if email: user.email = email model.session.add(user) model.session.commit() session_id = str(request.getSession().uid) web_session = model.query(WebSession).filter_by(session_id=session_id).first() if not web_session: web_session = WebSession(session_id=session_id, timestamp=datetime.now(), user=user) model.session.add(web_session) model.session.commit() return redirectTo("/user/"+user_ext, request) return redirectTo("/", request)
def notifyChildren(self, value, section='message', sessions=[]): """ Notify all children of given sessions of some event with data. value -- message payload (string or json serializable object). section -- event name. sessions -- sessions to send to. """ model = Model() for req in self._connections.keys(): if req._disconnected: print "sse client disconnected", req self._connections.pop(req) else: conn = self._connections[req] web_session = model.query(WebSession).filter_by(session_id=conn.session).first() if sessions == 'all' or (conn.session in sessions) or (web_session and web_session.user and web_session.user.admin): #if not sessions or (conn.session in sessions) or (web_session and web_session.user and web_session.user.admin): if value.__class__ == str: conn.write(time.time(), value, section) else: conn.write(time.time(), json.dumps(value), section)
def on_peer_event(self, event): peer_name = event['peer'].split('/')[1] model = Model() peer = model.query(SipPeer).filter_by(name=peer_name).first() if peer: event['username'] = peer_name event['exten'] = peer.regexten event['useragent'] = peer.useragent event['channel'] = False if peer.fullcontact and 'transport=tls' in peer.fullcontact.lower( ): event['tls'] = True else: event['tls'] = False if peer.encryption == 'yes': event['srtp'] = True else: event['srtp'] = False sse.resource.notify(event, 'peer', 'all') else: event['channel'] = True sse.resource.notify(event, 'peer', 'all')
def apply_transaction(self, address, balance, balance_confirmed, timestamp): model = Model() wallet = model.query(Wallet).filter_by(address=address).first() if wallet and wallet.user: user = wallet.user balance_unconfirmed = Decimal(balance) / Decimal("100000000") balance_confirmed = Decimal(balance_confirmed) / Decimal("100000000") received = wallet.received if not wallet.received: received = Decimal("0") new_coins = balance_confirmed - received wallet.received = balance_confirmed wallet.unconfirmed = balance_unconfirmed # XXX need to add a mechanism to account credit (convert to euros) #user.credit += new_coins log.msg("btc %s/%s: %s (+%s)" %(address, user.voip_id, balance_confirmed, balance_unconfirmed), system='BTC,tx') model.session.commit() sse.resource.notify( {'confirmed': float(balance_confirmed), 'unconfirmed': float(balance_unconfirmed), 'currency': 'BTC'}, 'balance', user) else: print "unknown tx destination"
def render_all_text(self): model = Model() calls = model.query(Call).order_by(desc(Call.timestamp)).limit(1000) origins = set() count_country = defaultdict(int) result = "" call_data = [['Origin', 'Destination', 'Country', 'Duration', 'Date']] for call in calls: country_data = ext2country(str(call.destination)) count_country[country_data[0]+"-"+country_data[1]] += 1 if call.user: origin = str(call.user.voip_id) origins.add(str(call.user.voip_id)) else: origin = "unknown" origins.add('unknown') destination = str(call.destination) country_data = ": ".join(country_data) duration = "%.2f min" % (call.duration/60.0,) date = str(self.format_date(call.timestamp)) call_data.append([origin, destination, country_data, duration, date]) result += html.format_table(call_data) # country stats country_data = [['Country', 'Count']] for key, value in count_country.iteritems(): country_data.append([key, str(value)]) result += html.format_table(country_data) # number of origins origins = list(origins) origins.sort() result += "<p>Origins (%s): %s</p>" % (len(origins), str(origins)) return print_template('content-pbx-lorea', {'content': result})
def login(self, login, password, request, email=''): peer = self.check_password(login, password) if peer: user_ext = peer.regexten model = Model() user = model.get_user_fromext(user_ext) if not user: user = User(user_ext) if email: user.email = email model.session.add(user) model.session.commit() session_id = str(request.getSession().uid) web_session = model.query(WebSession).filter_by( session_id=session_id).first() if not web_session: web_session = WebSession(session_id=session_id, timestamp=datetime.now(), user=user) model.session.add(web_session) model.session.commit() return redirectTo("/user/" + user_ext, request) return redirectTo("/", request)
def reload_peers(): model = Model() peers = model.query(SipPeer) for peer in peers: reload_peer(peer.name)
class Accounting(object): def __init__(self): self.model = Model() def get_data(self): data = {} users = self.model.query(User) for user in users: if user.credit: data[user.voip_id] = user.credit return data def get_credit(self, user_ext): user = self.model.get_user_fromext(user_ext) if user: return user.credit else: return Decimal() def reset_credit(self, user_ext): user = self.model.get_user_fromext(user_ext) user.credit = Decimal() self.model.session.commit() self.update_user_context(user) def update_user_context(self, user): peer = self.model.query(SipPeer).filter_by( regexten=user.voip_id).first() if not peer: # old user print "user unavailable to update context", user.voip_id return if user.credit > Decimal(0.0) and peer.context == "from-freeuser": peer.context = "from-payuser" self.model.session.commit() reload_peer(peer.name) elif user.credit <= Decimal(0.0) and peer.context == "from-payuser": peer.context = "from-freeuser" self.model.session.commit() reload_peer(peer.name) def get_user_for_credit(self, user_ext): user = self.model.get_user_fromext(user_ext) if not user: # check at least user exists as asterisk user peer = self.model.query(SipPeer).filter_by( regexten=user_ext).first() if not peer: # check by name peer = self.model.query(SipPeer).filter_by( name=user_ext).first() if not peer: return else: user = self.model.get_user_fromext(peer.regexten) if not user: user = User(peer.regexten) self.model.session.add(user) return user def transfer_credit(self, logged, user_ext, credit): from obelisk.resources import sse if not (credit > 0.0 and logged.credit >= credit): return user = self.get_user_for_credit(user_ext) if not user: return logged.credit -= Decimal(credit) user.credit += Decimal(credit) self.model.session.commit() self.update_user_context(user) self.update_user_context(logged) charges.add_charge(user.voip_id, credit, 'transferencia de ' + logged.voip_id) charges.add_charge(logged.voip_id, -credit, 'transferencia a ' + user.voip_id) sse.resource.notify( { 'credit': float(user.credit), 'user': user.voip_id }, "credit", user) sse.resource.notify( { 'credit': float(logged.credit), 'user': logged.voip_id }, "credit", logged) def add_credit(self, user_ext, credit, reason=""): from obelisk.resources import sse user = self.get_user_for_credit(user_ext) if not user: return user.credit += Decimal(credit) self.model.session.commit() self.update_user_context(user) charges.add_charge(user.voip_id, credit, reason) sse.resource.notify( { 'credit': float(user.credit), 'user': user.voip_id }, "credit", user) return user.voip_id def remove_credit(self, user_ext, credit): user = self.model.get_user_fromext(user_ext) if not user: return user.credit -= Decimal(credit) self.model.session.commit() self.update_user_context(user)
def get_user(request): model = Model() session_id = str(request.getSession().uid) web_session = model.query(WebSession).filter_by(session_id=session_id).first() if web_session: return web_session.user
def get_peers(self): model = Model() output = cli.run_command('sip show peers') lines = output.split("\n") res = "" pln_nodes = [] formatted = {"local": [], "channels": [], "pln": [], "end": []} for line in lines[1:]: line = line.replace(" D ", "") line = line.replace(" N ", "") line = line.replace(" a ", "") line = line.replace(" A ", "") line = line.replace("Cached RT", "") parts = line.split() parts = map(lambda s: s.strip("()"), parts) if len(parts) > 8 or len(parts) <= 3: continue peer_name = parts[0].split("/")[0] ext = None ip = parts[1].strip() port = parts[2].strip() peer = model.query(SipPeer).filter_by(name=peer_name).first() output = {'name': peer_name, 'status': parts[3]} if peer: ext = peer.regexten if ext: # and "192.168." in line: # line = self.add_ip_href(line) dest = 'local' output['useragent'] = peer.useragent if peer.encryption == 'yes': output['srtp'] = True else: output['srtp'] = False if peer.fullcontact and 'transport=tls' in peer.fullcontact.lower( ): output['tls'] = True else: output['tls'] = False elif ip.startswith('1.'): dest = 'pln' if peer_name in pln_nodes: continue pln_nodes.append(peer_name) else: dest = 'channels' if len(parts) > 4 and not port == '0': # connected if dest == 'channels': output['ping'] = parts[4] else: output['exten'] = ext output['ping'] = parts[4] elif len(parts) > 3: if ext: output['exten'] = ext formatted[dest].append(output) dundi_output = cli.run_command('dundi show peers') lines = dundi_output.split("\n") res = "" for line in lines[1:-2]: line = line.replace("(S)", "") parts = line.split() if not len(parts) > 5: continue pln_id = parts[0] if pln_id == '00:50:bf:5a:71:6b': # ourselves continue pln_ip = parts[1] pln_port = parts[2] pln_model = parts[3] avg_time = parts[4] status = parts[5] dundi_peer = self.get_dundi_peer_name(pln_id) if dundi_peer in pln_nodes: continue if len(parts) > 6: latency = parts[6].strip("(") else: latency = '' output = {'name': dundi_peer, 'status': status, 'ping': latency} formatted['pln'].append(output) return formatted
def get_user_sessions(user): model = Model() web_sessions = model.query(WebSession).filter_by(user=user) return web_sessions
class Accounting(object): def __init__(self): self.model = Model() def get_data(self): data = {} users = self.model.query(User) for user in users: if user.credit: data[user.voip_id] = user.credit return data def get_credit(self, user_ext): user = self.model.get_user_fromext(user_ext) if user: return user.credit else: return Decimal() def reset_credit(self, user_ext): user = self.model.get_user_fromext(user_ext) user.credit = Decimal() self.model.session.commit() self.update_user_context(user) def update_user_context(self, user): peer = self.model.query(SipPeer).filter_by(regexten=user.voip_id).first() if not peer: # old user print "user unavailable to update context", user.voip_id return if user.credit > Decimal(0.0) and peer.context == "from-freeuser": peer.context = "from-payuser" self.model.session.commit() reload_peer(peer.name) elif user.credit <= Decimal(0.0) and peer.context == "from-payuser": peer.context = "from-freeuser" self.model.session.commit() reload_peer(peer.name) def get_user_for_credit(self, user_ext): user = self.model.get_user_fromext(user_ext) if not user: # check at least user exists as asterisk user peer = self.model.query(SipPeer).filter_by(regexten=user_ext).first() if not peer: # check by name peer = self.model.query(SipPeer).filter_by(name=user_ext).first() if not peer: return else: user = self.model.get_user_fromext(peer.regexten) if not user: user = User(peer.regexten) self.model.session.add(user) return user def transfer_credit(self, logged, user_ext, credit): from obelisk.resources import sse if not (credit > 0.0 and logged.credit >= credit): return user = self.get_user_for_credit(user_ext) if not user: return logged.credit -= Decimal(credit) user.credit += Decimal(credit) self.model.session.commit() self.update_user_context(user) self.update_user_context(logged) charges.add_charge(user.voip_id, credit, 'transferencia de ' + logged.voip_id) charges.add_charge(logged.voip_id, -credit, 'transferencia a ' + user.voip_id) sse.resource.notify({'credit': float(user.credit), 'user': user.voip_id}, "credit", user) sse.resource.notify({'credit': float(logged.credit), 'user': logged.voip_id}, "credit", logged) def add_credit(self, user_ext, credit, reason=""): from obelisk.resources import sse user = self.get_user_for_credit(user_ext) if not user: return user.credit += Decimal(credit) self.model.session.commit() self.update_user_context(user) charges.add_charge(user.voip_id, credit, reason) sse.resource.notify({'credit':float(user.credit), 'user':user.voip_id}, "credit", user) return user.voip_id def remove_credit(self, user_ext, credit): user = self.model.get_user_fromext(user_ext) if not user: return user.credit -= Decimal(credit) self.model.session.commit() self.update_user_context(user)
def render_GET(self, request): user = session.get_user(request) if not user: return redirectTo("/", request) model = Model() output = cli.run_command('sip show peers') lines = output.split("\n") res = "" formatted = { "local": "<tr><th>Nombre</th><th>Ext</th><th>Estado</th><th>Latencia</th><tr>\n", "channels": "<tr><th>Nombre</th><th>Estado</th><th>Latencia</th><tr>\n", "end": "<tr><th>Nombre</th><th>Ext</th><th>Estado</th><th>Latencia</th><tr>\n" } for line in lines[1:]: line = line.replace(" D ", "") line = line.replace(" N ", "") line = line.replace(" a ", "") line = line.replace(" A ", "") line = line.replace("Cached RT", "") parts = line.split() parts = map(lambda s: s.strip("()"), parts) if len(parts) > 8 or len(parts) <= 3: continue peer_name = parts[0].split("/")[0] ext = None peer = model.query(SipPeer).filter_by(name=peer_name).first() if peer: ext = peer.regexten if ("OK" in line or "LAGGED" in line) and ext: # and "192.168." in line: # line = self.add_ip_href(line) dest = 'local' elif ext: dest = 'end' else: dest = 'channels' if len(parts) > 4: # connected if dest == 'channels': output = "<tr><td>%s</td><td>%s</td><td>%sms</td><tr>" % ( peer_name, parts[3], parts[4]) else: output = "<tr><td>%s</td><td>%s</td><td>%s</td><td>%sms</td><tr>" % ( peer_name, ext, parts[3], parts[4]) elif len(parts) > 3: if dest == 'channels': output = "<tr><td>%s</td><td>%s</td><td></td>" % ( peer_name, parts[3]) else: output = "<tr><td>%s</td><td>%s</td><td>%s</td><td></td>" % ( peer_name, ext, parts[3]) else: print "not enough parts", parts continue formatted[dest] += output + "\n" res += "<h2>Local</h2>" res += "<table>" res += formatted['local'] res += "</table>" if user.admin: res += "<h2>Channels</h2><table>" res += formatted['channels'] res += "</table>" res += "<h2>Other</h2><table>" res += formatted['end'] res += "</table><pre>" res += "<h2>Calls</h2>" res += cli.run_command('core show calls') res += "</pre><pre>" res += cli.run_command('core show uptime') res += "</pre>" return print_template('content-pbx-lorea', {'content': res})