2017-08-29 14:06:02 +03:00
# coding=utf-8
import os , sys , pymysql , re , time
2017-10-20 15:52:03 +03:00
from ldap3 import Server , Connection , NTLM
2017-08-21 15:11:10 +03:00
2017-08-25 16:37:26 +03:00
def application ( environ , start_response ) :
2017-11-08 11:39:25 +03:00
#sys.stdout._encoding = 'utf-8'замена сцепления патриот стоимость работ смоленск
2017-08-25 16:37:26 +03:00
status = ' 200 OK '
# проверяем наличие параметров в запросе и всяко-разно реагируем
if environ [ ' QUERY_STRING ' ] == ' ' :
output = bytes ( ( header ( ) + body ( ) + footer ( ) ) . encode ( ' utf8 ' ) )
elif environ [ ' QUERY_STRING ' ] . split ( ' & ' ) :
paramDict = { item . split ( ' = ' ) [ 0 ] : item . split ( ' = ' ) [ 1 ] for item in environ [ ' QUERY_STRING ' ] . split ( ' & ' ) }
if paramDict . get ( ' query_type ' ) == ' internal ' :
output = bytes ( ( header ( ) + body ( ) + getInternalNumbers ( ) + footer ( ) ) . encode ( ' utf8 ' ) )
elif paramDict . get ( ' query_type ' ) == ' external ' :
output = bytes ( ( header ( ) + body ( ) + getCOline ( ) + footer ( ) ) . encode ( ' utf8 ' ) )
2017-08-28 15:39:17 +03:00
elif paramDict . get ( ' query_type ' ) == ' report ' :
output = bytes ( ( header ( ) + body ( ) + ReportForm ( ) + ReportData ( environ ) + footer ( ) ) . encode ( ' utf8 ' ) )
2017-10-20 15:52:03 +03:00
elif paramDict . get ( ' query_type ' ) == ' ldap ' :
2017-11-08 11:39:25 +03:00
domain = paramDict . get ( ' domain ' )
group = paramDict . get ( ' group ' )
output = bytes ( ( header ( ) + body ( ) + getLDAPusers ( domain , group ) + footer ( ) ) . encode ( ' utf8 ' ) )
2017-08-25 16:37:26 +03:00
else :
output = bytes ( ( header ( ) + body ( ) + footer ( ) ) . encode ( ' utf8 ' ) )
2017-08-21 15:11:10 +03:00
2017-08-25 16:37:26 +03:00
response_headers = [ ( ' Content-type ' , ' text/html;charset=utf-8 ' ) ,
( ' Content-Length ' , str ( len ( output ) ) ) ]
start_response ( status , response_headers )
2017-08-21 15:11:10 +03:00
2017-08-25 16:37:26 +03:00
return [ output ]
def header ( ) :
txtHeader = ' <html><head><meta charset= " utf-8 " ><link rel= " shortcut icon " href= " favicon.png " > \n ' \
' <link rel= " icon " type= " image/png " href= " favicon.png " > \n ' \
' <link href= " css/layout.css " rel= " stylesheet " type= " text/css " /> \n ' \
' <title>Телефоны</title> \n ' \
' <link href= " css/menu.css " rel= " stylesheet " type= " text/css " /></head><body> \n '
return txtHeader
def footer ( ) :
2017-08-28 15:39:17 +03:00
txtFooter = ' </body></html> \n '
2017-08-25 16:37:26 +03:00
return txtFooter
def body ( ) :
txtBody = ' <table><tr><td><h2 align=left>ТЕЛЕФОНЫ</h2></td></tr> \n ' \
2017-08-28 15:39:17 +03:00
' <tr><td> {} </td></tr></table> \n ' . format ( menu ( ) )
2017-08-25 16:37:26 +03:00
return txtBody
def menu ( ) :
#<div class="container">
txtMenu = ' <div class= " container " ><ul id= " nav " ></li> \n ' \
' <li><a class= " hsubs " href= " # " >Справочник</a><ul class= " subs " > \n ' \
' <li><a href= " ?query_type=external " >Городские телефоны</a></li> \n ' \
2017-11-08 11:39:25 +03:00
' <li><a href= " ?query_type=ldap&domain=domain1 " >Список абонентов 1</a></li> \n ' \
' <li><a href= " ?query_type=ldap&domain=domain2 " >Список абонентов 2</a></li> \n ' \
' <li><a href= " ?query_type=ldap&domain=domain3 " >Список абонентов 3</a></li></ul></li> \n ' \
2017-08-29 14:06:02 +03:00
' <li><a class= " hsubs " href= " " >Отчёты</a><ul class= " subs " > ' \
' <li><a href= " ?query_type=report&report_type=int " >Список звонков по номеру</a></li> \n ' \
' <li><a href= " ?query_type=report&report_type=dep " >Звонки по отделам</a></li> \n ' \
2017-08-25 16:37:26 +03:00
' </ul></div> \n '
return txtMenu
2017-11-08 11:39:25 +03:00
2017-08-25 16:37:26 +03:00
def getInternalNumbers ( ) :
conn = connectDB ( )
c = conn . cursor ( )
order = ' int_number '
2017-09-04 12:03:07 +03:00
result = ' <h4 align=left>Список внутренних телефонов</h4> '
2017-08-21 15:11:10 +03:00
qwr = " SELECT * FROM int_number ORDER by " + order
c . execute ( qwr )
2017-08-25 16:37:26 +03:00
listHeader = ' <table class= " table_dark " ><tr><th>№ п/п</th> \n ' \
' <th><a href=index.py?query_type=internal&order=int_number>Телефон</a></th> \n ' \
' <th><a href=index.py?query_type=internal&order=fio>ФИО</a></th> \n ' \
2017-11-08 11:39:25 +03:00
' <th>Описание<th>Электро-почта</th></tr> \n '
2017-08-25 16:37:26 +03:00
result = result + listHeader
2017-08-21 15:11:10 +03:00
for row in c . fetchall ( ) :
2017-11-08 11:39:25 +03:00
rowData = " <tr><td> %s </td><td> %s </td><td> %s </td><td> %s </td><td> %s </td></tr> \n " % ( row [ 0 ] , row [ 1 ] , row [ 2 ] , row [ 4 ] , row [ 3 ] )
2017-08-25 16:37:26 +03:00
result = result + rowData
return ( result + " </table> \n " )
2017-10-20 15:52:03 +03:00
2017-11-08 11:39:25 +03:00
# Список пользователей (ФИО, телефон, почта, отдел) из LDAP (AD)
def getLDAPusers ( domain , group ) :
2017-10-20 15:52:03 +03:00
order = ' int_number '
2017-11-08 11:39:25 +03:00
if domain == ' domain1 ' :
head = ' <p>Для внешних абонентов звонить на xxxxxx + добавочный номер</p> '
org = ' 1 '
s = Server ( ' 192.168.1.1 ' )
c = Connection ( s , user = ' domain1 \\ phone ' , password = " pass " , authentication = NTLM )
# perform the Bind operation
if not c . bind ( ) :
print ( ' error in bind ' , c . result )
c . search ( ' OU=users,dc=domain1,dc=local ' , ' (objectclass=person) ' ,
attributes = [ ' cn ' , ' mail ' , ' telephoneNumber ' , ' department ' , ' title ' , ' mobile ' ] )
elif domain == ' domain2 ' :
head = ' <p>Для внешних абонентов звонить на xxxxxxx + добавочный номер</p> '
org = ' 2 '
s = Server ( ' 192.168.2.2 ' )
c = Connection ( s , user = ' domain2 \\ phone ' , password = " pass " , authentication = NTLM )
# perform the Bind operation
if not c . bind ( ) :
print ( ' error in bind ' , c . result )
c . search ( ' OU=users,dc=domain2,dc=local ' , ' (objectclass=person) ' ,
attributes = [ ' cn ' , ' mail ' , ' telephoneNumber ' , ' department ' , ' title ' , ' mobile ' ] )
elif domain == ' domain3 ' :
head = ' <p>Для внешних абонентов звонить на xxxxxxx + добавочный номер</p> '
org = ' 3 '
s = Server ( ' 192.168.3.3 ' )
c = Connection ( s , user = ' domain3 \\ phone ' , password = " pass " , authentication = NTLM )
# perform the Bind operation
if not c . bind ( ) :
print ( ' error in bind ' , c . result )
c . search ( ' OU=users,dc=domain3,dc=local ' , ' (objectclass=person) ' ,
attributes = [ ' cn ' , ' mail ' , ' telephoneNumber ' , ' department ' , ' title ' , ' mobile ' ] )
result = ' <h4 align=left>Список абонентов %s </h4> \n %s ' % ( org , head )
#return (result + "</table>\n")
# listHeader = '<table class="table_dark"><tr>\n' \
# '<th><a href=index.py?query_type=internal&order=fio>ФИО</a></th>\n' \
# '<th>Отдел</th><th>Должность</th>\n' \
# '<th><a href=index.py?query_type=internal&order=int_number>Телефон</a></th>\n' \
# '<th>Эл.почта</th><th>Мобильный телефон</th></tr>\n'
listHeader = ' <table class= " table_dark " ><tr> \n ' \
' <th>ФИО</th> \n ' \
' <th>Отдел</th><th>Должность</th> \n ' \
' <th>Телефон</th> \n ' \
' <th>Эл.почта</th><th>Мобильный телефон</th></tr> \n '
2017-10-20 15:52:03 +03:00
result = result + listHeader
for item in c . entries :
# print(item)
# item = re.sub('\n', '', str(item))
item = str ( item )
name = re . search ( ' (cn:)(.+?)( \n ) ' , item )
if name :
name = name . groups ( ) [ 1 ]
else :
name = name
#print(name.groups()[1])
department = re . search ( " (department:)(.+?)( \n ) " , item )
if department :
dep = department . groups ( ) [ 1 ]
else :
dep = " "
2017-11-08 11:39:25 +03:00
title = re . search ( " (title:)(.+?)( \n ) " , item )
if title :
title = title . groups ( ) [ 1 ]
else :
title = " "
2017-10-20 15:52:03 +03:00
mail = re . search ( " (mail:)(.+?)( \n ) " , item )
if mail :
mail = mail . groups ( ) [ 1 ]
else :
mail = " "
telephone = re . search ( " (telephoneNumber:)(.+?)( \n ) " , item )
if telephone :
phone = telephone . groups ( ) [ 1 ]
else :
phone = " "
2017-11-08 11:39:25 +03:00
mobile = re . search ( " (mobile:)(.+?)( \n ) " , item )
if mobile :
mobile = mobile . groups ( ) [ 1 ]
else :
mobile = " "
rowData = " <tr><td> %s </td><td> %s </td><td> %s </td><td> %s </td><td><a href= \" mailto: %s \" > %s </a></td><td> %s </td></tr> \n " % ( name , dep , title , phone , mail , mail , mobile )
2017-10-20 15:52:03 +03:00
result = result + rowData
return ( result + " </table> \n " )
2017-08-25 16:37:26 +03:00
def getCOline ( ) :
conn = connectDB ( )
c = conn . cursor ( )
order = ' ext_co_line '
2017-09-04 12:03:07 +03:00
result = ' <h4 align=left>Список внешних линий</h4> '
2017-08-25 16:37:26 +03:00
qwr = " SELECT * FROM ext_co_line ORDER by " + order
c . execute ( qwr )
listHeader = ' <table class= " table_dark " ><tr><th>№ п/п</th> \n ' \
' <th>Линия</a></th> \n ' \
' <th>Номер телефона</th> \n ' \
' <th>Описание</th></tr> \n '
result = result + listHeader
for row in c . fetchall ( ) :
rowData = " <tr><td> %s </td><td> %s </td><td> %s </td><td> %s </td></tr> " % ( row [ 0 ] , row [ 1 ] , row [ 2 ] , row [ 3 ] )
result = result + rowData
return ( result + " </table> \n " )
2017-08-21 15:11:10 +03:00
2017-08-28 15:39:17 +03:00
def ReportForm ( ) :
txtReportForm = ' <h3 align=center>Отчёт по звонкам</h3><table><tr valign=top><td> ' \
' <form><input type=hidden name= " query_type " value= " report " > ' \
' <fieldset class= " report " > ' \
' <label>Номер<input type= " text " name= " int_number " ></label> ' \
' <label>Период с <input type= " date " name= " date_begin " ></label> ' \
' <label>По<input type= " date " name= " date_end " ></label> ' \
' </fieldset> ' \
' <fieldset class= " report-action " > ' \
' <input class= " btn " type= " submit " name= " submit " value= " Выбрать " > ' \
' </fieldset></form></td> '
return txtReportForm
def ReportData ( environ ) :
paramDict = { item . split ( ' = ' ) [ 0 ] : item . split ( ' = ' ) [ 1 ] for item in environ [ ' QUERY_STRING ' ] . split ( ' & ' ) }
2017-08-29 14:06:02 +03:00
# проверка корректности параметров
# внутренний номер (3 цифры 100-999)
templateNumber = ' (^[1-9][0-9][0-9]$) '
if re . match ( templateNumber , str ( paramDict . get ( ' int_number ' ) ) ) is not None :
numbers = paramDict . get ( ' int_number ' )
else :
return ErrorMessage ( ' Введите внутренний номер ' )
# проверка и преобразование дат в удобоваримый для субд формат
templateDate = ' ^(0[1-9]|[12][0-9]|3[01])[.](0[1-9]|1[012])[.](19|20)[0-9][0-9]$ '
if re . match ( templateDate , str ( paramDict . get ( ' date_begin ' ) ) ) is not None :
date_begin = time . strftime ( " % Y- % m- %d " , time . strptime ( str ( paramDict . get ( ' date_begin ' ) ) , " %d . % m. % Y " ) )
else :
return ErrorMessage ( ' Неверный формат даты начала периода ' )
if re . match ( templateDate , paramDict . get ( ' date_end ' ) ) is not None :
date_end = time . strftime ( " % Y- % m- %d " , time . strptime ( str ( paramDict . get ( ' date_end ' ) ) , " %d . % m. % Y " ) )
else :
return ErrorMessage ( ' Неверный формат даты окончания периода ' )
2017-08-28 15:39:17 +03:00
conn = connectDB ( )
c = conn . cursor ( )
order = ' call_date '
result = ' <td><h4 align=left>Список звонков с номера {} </h4> ' . format ( numbers )
2017-08-29 14:06:02 +03:00
qwr = " SELECT * FROM cdr where int_number= \' {} \' AND call_date BETWEEN CAST( \' {} \' AS DATE) AND CAST( \' {} \' AS DATE) LIMIT 1000 " . format ( numbers , date_begin , date_end )
2017-08-28 15:39:17 +03:00
c . execute ( qwr )
listHeader = ' <table class= " table_dark " ><tr> ' \
' <th>№ п/п</th><th>Дата</th><th>Время</th><th>Внут.номер</th><th>Внеш.линия</th><th>Вызываемый номер</th> ' \
' <th>Ring</th><th>Длительность</th><th>А С С </th><th>Код звонка</th><th>Направление</th><tr> \n '
result = result + listHeader
for row in c . fetchall ( ) :
2017-08-29 14:06:02 +03:00
rowData = ' <td> {} </td><td> {} </td><td> {} </td><td> {} </td><td> {} </td><td> {} </td><td> {} </td><td> {} </td><td> {} </td><td> {} </td><td> {} </td></tr> ' \
. format ( row [ 0 ] , row [ 1 ] , row [ 2 ] , row [ 3 ] , row [ 4 ] , row [ 5 ] , row [ 5 ] , row [ 7 ] , row [ 9 ] , row [ 9 ] , row [ 10 ] )
2017-08-28 15:39:17 +03:00
result = result + rowData
return ( result + " </table></td></tr></table> \n " + qwr )
2017-08-29 14:06:02 +03:00
def ErrorMessage ( txt ) :
2017-09-04 12:03:07 +03:00
return ( ' <td width=100 % a lign=center><font color=red> {} </font></td></tr></table> ' . format ( txt ) )
2017-08-28 15:39:17 +03:00
2017-08-25 16:37:26 +03:00
def connectDB ( ) :
c = pymysql . connect (
2017-11-08 11:39:25 +03:00
db = ' ats ' ,
2017-08-25 16:37:26 +03:00
user = ' ats ' ,
2017-11-08 11:39:25 +03:00
passwd = ' pass ' ,
host = ' x.x.x.x ' ,
2017-08-25 16:37:26 +03:00
charset = ' utf8 ' )
2017-08-28 15:39:17 +03:00
return c