Message-ID: <1348890851.2450.1711718792507.JavaMail.confluence@confluence-ru-0> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_2449_1961927959.1711718792507" ------=_Part_2449_1961927959.1711718792507 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html =D0=A2=D0=B0=D1=80=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D1= =8F CDR =D0=B2 =D0=BE=D0=BD=D0=BB=D0=B0=D0=B9=D0=BD-=D1=80=D0=B5=D0=B6=D0= =B8=D0=BC=D0=B5

=D0=A2=D0=B0=D1=80=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=86=D0=B8=D1=8F = CDR =D0=B2 =D0=BE=D0=BD=D0=BB=D0=B0=D0=B9=D0=BD-=D1=80=D0=B5=D0=B6=D0=B8=D0= =BC=D0=B5

CDR =D0=BC=D0=BE=D0=B6=D0=BD=D0=BE =D0=BF=D0=B5=D1=80=D0=B5=D0= =B4=D0=B0=D0=B2=D0=B0=D1=82=D1=8C =D0=B2 =D1=8F=D0=B4=D1=80=D0=BE =D0=90=D0= =A1=D0=A0 =D1=81 =D0=BF=D0=BE=D0=BC=D0=BE=D1=89=D1=8C=D1=8E =D1=81=D0=BF=D0= =B5=D1=86=D0=B8=D0=B0=D0=BB=D1=8C=D0=BD=D0=BE=D0=B3=D0=BE =D0=B0=D0=B3=D0= =B5=D0=BD=D1=82=D0=B0 (=D0=B8=D1=81=D1=85=D0=BE=D0=B4=D0=BD=D1=8B=D0=B9 =D0= =BA=D0=BE=D0=B4 =D0=BD=D0=B0 =D1=8F=D0=B7=D1=8B=D0=BA=D0=B5 Python =D0=BF= =D1=80=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD =D0=BE= =D0=B4=D0=BD=D0=B8=D0=BC =D0=B8=D0=B7 =D0=BD=D0=B0=D1=88=D0=B8=D1=85 =D0=BA= =D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=BE=D0=B2), =D0=BA=D0=BE=D1=82=D0=BE=D1=80= =D1=8B=D0=B9 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82 =D0=B2 =D1=80= =D0=B5=D0=B6=D0=B8=D0=BC=D0=B5 =D0=B4=D0=B5=D0=BC=D0=BE=D0=BD=D0=B0, =D0=BF= =D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D0=B5=D1=82 =D1=81=D0=BE=D0=B5=D0=B4= =D0=B8=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F =D0=BD=D0=B0 TCP-=D0=BF=D0=BE=D1=80=D1= =82=D1=83 =D1=81 =D0=BF=D0=BE=D0=BC=D0=BE=D1=89=D1=8C=D1=8E =D0=BE=D0=B1=D1= =8B=D1=87=D0=BD=D0=BE=D0=B3=D0=BE =D1=81=D0=BE=D0=BA=D0=B5=D1=82=D0=B0 =D0= =B8 =D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6=D0=B8=D0=B2=D0=B0=D0=B5=D1= =82 =D0=BF=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=BD=D0=BE=D0=B5 =D1=81=D0= =BE=D0=B5=D0=B4=D0=B8=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5 =D1=81 Oracle. =D0=90= =D0=B3=D0=B5=D0=BD=D1=82 =D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D0=B5= =D1=82 CDR =D0=B2 =D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=82=D0=B5 Asterisk PBX. = =D0=97=D0=B0=D0=BC=D0=B5=D0=BD=D0=B0 =D0=BF=D1=80=D0=B5=D1=84=D0=B8=D0=BA= =D1=81=D0=BE=D0=B2 =D0=BD=D0=B5 =D0=B2=D1=8B=D0=BF=D0=BE=D0=BB=D0=BD=D1=8F= =D0=B5=D1=82=D1=81=D1=8F.

=20

=D0=9A =D1=81=D0=BE=D0=B6=D0=B0=D0=BB=D0=B5=D0=BD=D0=B8=D1=8E, =D0=BA=D0= =BB=D0=B8=D0=B5=D0=BD=D1=82=D1=81=D0=BA=D0=B0=D1=8F =D1=87=D0=B0=D1=81=D1= =82=D1=8C =D1=81=D0=BA=D1=80=D0=B8=D0=BF=D1=82=D0=B0 =D0=BE=D1=82=D1=81=D1= =83=D1=82=D1=81=D1=82=D0=B2=D1=83=D0=B5=D1=82, =D0=BD=D0=BE =D0=BA=D0=B0=D0= =BA=D0=B8=D1=85-=D0=BB=D0=B8=D0=B1=D0=BE =D1=81=D0=BB=D0=BE=D0=B6=D0=BD=D0= =BE=D1=81=D1=82=D0=B5=D0=B9 =D0=B1=D1=8B=D1=82=D1=8C =D0=BD=D0=B5 =D0=B4=D0= =BE=D0=BB=D0=B6=D0=BD=D0=BE. =D0=9E=D0=BD=D0=B0 =D0=B4=D0=BE=D0=BB=D0=B6=D0= =BD=D0=B0 =D0=BF=D1=80=D0=B8=D0=BD=D0=B8=D0=BC=D0=B0=D1=82=D1=8C CDR =D0=BE= =D1=82 =D0=90=D0=A2=D0=A1 =D0=B8 =D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B0=D0=B2= =D0=B0=D1=82=D1=8C =D0=B5=D1=91 =D1=87=D0=B5=D1=80=D0=B5=D0=B7 =D1=81=D0=BE= =D0=BA=D0=B5=D1=82 =D0=B0=D0=B3=D0=B5=D0=BD=D1=82=D1=83.

=20
=20
=20 cdrd.py (=D1=81=D0=B5=D1=80=D0=B2=D0=B5=D1=80)= =20  Expand source=20 =20
=20
=20
#!/usr/bin/env python

import daemon
import socket=20
import re
import os
import sys
import select
import signal
import threading
import cx_Oracle

from time import strftime, sleep
from datetime import datetime

os.environ["ORACLE_HOME"]=3D"/usr/lib64/oracle/10.2.0.3/client"
os.environ["TNS_ADMIN"]=3D"/etc/oracle"
os.environ["NLS_LANG"]=3D"RUSSIAN_CIS.AL32UTF8"

bind_ip=3D"127.0.0.1"
bind_port=3D50000

db_login=3D"AIS_TEL"
db_password=3D"my_secret_password"
db_inst=3D"sl"

pid_file=3D"/tmp/cdrd.pid"
log_file=3D"/tmp/cdrd.log"

class Server:=20
=09def __init__(self):=20
=09=09self.host =3D bind_ip
=09=09self.port =3D bind_port=20
=09=09self.backlog =3D 1024=20
=09=09self.size =3D 1024=20
=09=09self.server =3D None=20
=09=09self.threads =3D []=20
=09=09self.db_login =3D db_login
=09=09self.db_password =3D db_password
=09=09self.db_inst =3D db_inst
=09=09self.log =3D sys.stdout=20
#=09=09self.log =3D open(log_file,'a+')
=09=09self.pid_file =3D pid_file
=09=09self.connection =3D None
=09=09self.select_timeout =3D 180
=09=09self.input =3D [];

=09=09signal.signal(signal.SIGTERM, self.sig_handler)
=09=09signal.signal(signal.SIGINT, self.sig_handler)
=09=09signal.signal(signal.SIGHUP, self.sig_handler)

=09def sig_handler(self,signum, frame):
=09=09self.logger("Got signal "+str(signum))
=09=09if signum =3D=3D signal.SIGTERM or signum =3D=3D signal.SIGINT:=20
=09=09=09self.exit(0)=20
=09=09if signum =3D=3D signal.SIGHUP:=20
=09=09=09self.reload(0)=20

=09def reload(self,code):
=09=09if self.connection:=20
=09=09=09self.logger("Closing database connection...")
=09=09=09self.connection.close()
=09=09=09self.connection =3D None

=09=09self.open_oracle()

=09def exit(self,code):
=09=09self.logger("Closing database connection...")
=09=09if self.connection: self.connection.close()
=09=09self.logger("Closing socket...")
=09=09if self.server: self.server.close()=20
=09=09self.logger("Waiting for threads...")
=09=09for c in self.threads:=20
=09=09=09c.join()
=09=09self.logger("Exiting...")
=09=09sys.exit(code)=20

=09def logger(self, message):
=09=09print >>self.log, strftime("%Y-%m-%d %H:%M:%S")+" hcdrd:", mess=
age
=09=09self.log.flush()

=09def open_socket(self):=20
=09=09while not self.server:
=09=09=09try:=20
=09=09=09=09self.server =3D socket.socket(socket.AF_INET, socket.SOCK_STREA=
M)=20
=09=09=09=09self.server.bind((self.host,self.port))=20
=09=09=09=09self.server.listen(self.backlog)=20
=09=09=09except socket.error, (value,message):=20
=09=09=09=09if self.server:=20
=09=09=09=09=09self.server.close()=20
=09=09=09=09self.logger("Could not open socket: "+message)
=09=09=09=09self.logger("Retrying in 10 sec")
=09=09=09=09self.server =3D None
=09=09=09=09sleep(10)

=09=09self.logger("Listening on "+str(self.host)+" port "+str(self.port))
=09=09self.input.append(self.server)

=09def open_oracle(self):=20
=09=09self.logger("Trying to connect to database... ")=20
=09=09try:
=09=09=09self.connection=3Dcx_Oracle.connect( user =3D self.db_login,\
=09=09=09                                   password =3D self.db_password,\
=09=09=09=09=09=09=09   dsn =3D self.db_inst,\
=09=09=09=09=09=09=09   threaded =3D True)
=09=09except cx_Oracle.DatabaseError,info:
=09=09=09self.logger("Logon Error on "+str(self.db_inst)+": "+str(info).rst=
rip())=20
=09=09=09self.connection =3D None
=09=09=09return False

=09=09self.logger("Successfull login to database "+self.db_inst)
=09

=09def accept(self):
=09=09try:
=09=09=09inputready,outputready,exceptready =3D select.select(self.input,[]=
,[],self.select_timeout)=20
=09=09except select.error,msg:
=09=09=09if msg[0] =3D=3D 4:
=09=09=09=09return True
=09=09=09else:
=09=09=09=09self.logger("Select error: "+str(msg[1]))
=09=09=09=09return False

=09=09for s in inputready:=20
=09=09=09if s =3D=3D self.server:=20
=09=09=09=09if self.connection:
=09=09=09=09=09c =3D PostCDR(self.server.accept(),self.connection.cursor(),=
self.logger)=20
=09=09=09=09else:
=09=09=09=09=09c =3D PostCDR(self.server.accept(),None,self.logger)=20
=09=09=09=09c.start()=20
=09=09=09=09self.threads.append(c)=20

=09def run(self):=20
#=09=09daemon.daemonize(self.pid_file)

=09=09self.logger("||| Server started |||")

=09=09self.open_socket()=20

=09=09running =3D 1

=09=09while running:=20
=09=09=09if self.connection:
=09=09=09=09try:
=09=09=09=09=09self.connection.ping()
=09=09=09=09except cx_Oracle.Error,info:
=09=09=09=09=09self.logger("Connection to database is dead: "+str(info).rst=
rip())=20
=09=09=09=09=09self.connection =3D None
=09=09=09=09=09self.open_oracle()
=09=09=09else:
=09=09=09=09self.open_oracle()

=09=09=09self.accept()

class PostCDR(threading.Thread):=20
=09def __init__(self,(client,address),cursor,logger):=20
=09=09threading.Thread.__init__(self)=20
=09=09self.client =3D client=20
=09=09self.address =3D address=20
=09=09self.size =3D 1024=20
=09=09self.cursor =3D cursor
=09=09self.cdr =3D {}
=09=09self.logger =3D logger

=09def postcdr(self):
=09=09if self.cursor:
=09=09=09try:
=09=09=09=09self.cursor.callproc("""AIS_NET.EX_AAA_PKG.CDR_PUT""",\
=09=09=09=09=09("Asterisk", \
=09=09=09=09=09"CDR_Status_Finished", \
=09=09=09=09=09str(self.cdr['sid']), \
=09=09=09=09=09None, \
=09=09=09=09=091094, \
=09=09=09=09=09None, \
=09=09=09=09=09None, \
=09=09=09=09=09None, \
=09=09=09=09=09None, \
=09=09=09=09=09str(self.cdr['calling_id']), \
=09=09=09=09=09str(self.cdr['called_id']), \
=09=09=09=09=09str(self.cdr['route_a']), \
=09=09=09=09=09str(self.cdr['route_b']), \
=09=09=09=09=09datetime.strptime(str(self.cdr['start']), "%Y-%m-%d %H:%M:%S=
"), \
=09=09=09=09=09datetime.strptime(str(self.cdr['end']), "%Y-%m-%d %H:%M:%S")=
, \
=09=09=09=09=09int(self.cdr['duration']), \
=09=09=09=09=09None, \
=09=09=09=09=09None, \
=09=09=09=09=09None, \
=09=09=09=09=09str(self.cdr['cause']), \
=09=09=09=09=091, \
=09=09=09=09=09"Uploaded via cdrd.py"))=20

=09=09=09except cx_Oracle.Error,info:
=09=09=09=09self.logger("Database error: "+str(info).rstrip())=20
=09=09=09=09return False=20
=09=09=09except ValueError,msg:
=09=09=09=09self.logger("Value error: "+str(msg))=20
=09=09=09=09return False=20
=09=09=09except Exception,msg:
=09=09=09=09self.logger("Unknown error: "+str(msg))=20
=09=09=09=09return False=20

=09=09=09return True
=09=09else:
=09=09=09return=20

=09def readline(self):
=09=09buffer =3D self.client.recv(self.size)
=09=09done =3D False

=09=09while not done:
=09=09=09if "\n" in buffer:
=09=09=09=09(line, buffer) =3D buffer.split("\n", 1)
=09=09=09=09yield line.rstrip()
=09=09=09else:
=09=09=09=09more =3D self.client.recv(self.size)
=09=09=09=09if not more:
=09=09=09=09=09done =3D True
=09=09=09=09=09self.client.close()=20
=09=09=09=09else:
=09=09=09=09=09buffer =3D buffer+more

=09=09if buffer:
=09=09=09yield buffer.rstrip()

=09def run(self):=20
=09=09running =3D 1=20
=09=09strings =3D iter(self.readline())

=09=09for key in ("sid", "start", "end", "calling_id", "called_id", "route_=
a", "route_b", "duration", "cause"):
=09=09=09try:=20
=09=09=09=09data =3D strings.next()
=09=09=09except:
=09=09=09=09self.logger("Connection closed unexpectedly with "+str(self.add=
ress[0])+":"+str(self.address[1]))
=09=09=09=09return 1
=09=09=09=09
=09=09=09self.cdr[key] =3D data

=09=09result =3D self.postcdr()

=09=09if result:
=09=09=09self.client.send("200 OK\n")
=09=09else:
=09=09=09self.client.send("700 ERROR\n")

=09=09self.client.close()=20


if __name__ =3D=3D "__main__":=20
=09print "Pidfile is",pid_file
=09print "Logging to",log_file
=09print "Starting..."

=09s =3D Server()
=09s.run()
=20
=20
------=_Part_2449_1961927959.1711718792507--