рдЗрдВрдЯрд░рдиреЗрдЯ рдкрд░ рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рд╡реЗ рд╕рднреА рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИрдВред рдореИрдВ рддрд╛рд░рд╛рдВрдХрди рдХреЗ рд▓рд┐рдП рд╡реЙрдпрд╕ рдЧрд╛рдЗрдб рдХреЗ рдЕрдкрдиреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рдиреЛрдЯ: рдореИрдВ рдПрдХ рдкреЗрд╢реЗрд╡рд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдирд╣реАрдВ рд╣реВрдВ, рдФрд░ рд╢рд╛рдпрдж рдХреБрдЫ рд╕рдорд╛рдзрд╛рди рдЖрдкрдХреЛ рдЬрдВрдЧрд▓реА рд▓рдЧ рд╕рдХрддреЗ рд╣реИрдВред рдХреБрдЫ рддрд░рдХреАрдмреЗрдВ рдкреБрд░рд╛рдиреА рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рдореИрдВ рдЖрд▓реЛрдЪрдирд╛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдФрд░ рдмреЗрд╣рддрд░ рдХреЗ рд▓рд┐рдП рд╡реНрдпрд╡рд╕реНрдерд╛ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реВрдВред
рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдг:
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЖрдИрд╡реАрдЖрд░ рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рддрд╛ рд╣реИ, рдЕрдкрдирд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИ рдФрд░, рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдЬрд╣рд╛рдВ рд╡рд╣ рдЪрд╛рд╣рддрд╛ рд╣реИ, рд╡рд╣рд╛рдВ рдкрд╣реБрдВрдЪ рдЬрд╛рддрд╛ рд╣реИред Mysql рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд╕рд╛рде рдЖрдВрдХрдбрд╝реЗ рднреА рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП рдЦрд░рд╛рдм рд╣реИрдВред
рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдХрдВрдкрдиреА рдФрд░ рдЙрд╕ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рдкреНрд░рдгрд╛рд▓реА рддреИрдирд╛рдд рд╣реИ:
~ 1000 рдлреЛрди, рд▓рдЧрднрдЧ 50 рд╡рд┐рднрд╛рдЧ
рд╕рд┐рд╕реНрдЯрдо рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕реЙрдлрд╝реНрдЯрд╡реЗрдпрд░ рдЙрддреНрдкрд╛рдж:
- рддрд╛рд░рд╛рдВрдХрди 13.10
- YandexSpeechKit
- рдЕрдЬрдЧрд░ 2.6.6
- рдореИрд╕реВрд░, MSSQL
- sox 14.2.0
- рдХрд░реНрд▓ 7.19.7
- рд▓рдВрдЧрдбрд╝рд╛ 3.99.5
рддрд╛рд░рд╛рдВрдХрди рдореЗрдВ рдбрд╛рдпрд▓рдкреНрд▓рд╛рди рдХрд╛ рд╡рд░реНрдгрдиред
[officevoicerec] exten => s,1,Answer() same => n,Macro(hangercheck,${CALLERID(num)}) same => n,Set(ITERATIONS=1) same => n,Set(HANGFLAG=TRUE) same => n,Background(/var/lib/asterisk/sounds/ru/speechrec/zdravstvuite)
рдЗрд╕ рдЯреБрдХрдбрд╝реЗ рдореЗрдВ, рдПрдХ рдореИрдХреНрд░реЛ рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рддрд╛рдХрд┐ рдпрд╣ рдЬрд╛рдВрдЪрд╛ рдЬрд╛ рд╕рдХреЗ рдХрд┐ рдлреЛрди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдиреЗ рд╢реБрднрдХрд╛рдордирд╛ рд╕рдВрджреЗрд╢ рд╕реБрдирдиреЗ рдХреЗ рдмрд╛рдж рд╣реА рд▓рдЯрдХрд╛ рджрд┐рдпрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдЕрдЧрд▓рд╛ рдЪрд░ рдХрд╛ рдорд╛рди рд╕реЗрдЯ рдХрд░ рд░рд╣рд╛ рд╣реИ:
рдорд╛рдиреНрдпрддрд╛ - рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рд╕рдордп рдХреЗ рд▓рд┐рдП рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рджреЛрд╣рд░рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред HANGFLAG - рдЗрд╕ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реИрдВрдЧрд░рдЪреЗрдХ рдореИрдХреНрд░реЛ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
same => n(rec),Set(RECFILE=/tmp/${UNIQUEID}.wav) same => n,Playback(/var/lib/asterisk/sounds/en/beep) same => n,Record(${RECFILE},3,8) same => n,AGI(pyreq8.py,${RECFILE}) same => n,GotoIf($["${NUMTOCALL}" = "repeat"]?repeat) same => n,Set(HANGFLAG=FALSE)
рд░рд┐рдХреЙрд░реНрдб рдлрд╝рд╛рдЗрд▓ рдЪрд░ рд╕реЗрдЯ рдХрд░реЗрдВ, рдлрд╝рд╛рдЗрд▓ рд▓рд┐рдЦреЗрдВред рд╣рдо рдорд╛рдиреНрдпрддрд╛ рдФрд░ рд╕рдВрдЦреНрдпрд╛ рдЦреЛрдЬ (рдмрд╛рдж рдореЗрдВ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рд╡рд░реНрдгрди рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛) рдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдЗрд▓ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдПрдХ рдПрдЧреА рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛рддреЗ рд╣реИрдВ, NUMTOCALL рдЪрд░ (рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджреНрд╡рд╛рд░рд╛ рдорд╛рди рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдХреА рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╣реБрдП, HANGFLAG рдХреЛ рд╕реЗрдЯ рдХрд░реЗрдВ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рд╡реНрдпрдХреНрддрд┐ рд╕рдордп рд╕реЗ рдкрд╣рд▓реЗ рд▓рдЯрдХрд╛ рдирд╣реАрдВ рд╣реИред
same => n,Macro(VRstat,${CALLERID(num)},${NUMTOCALL},${RSTATUS},${CHANNEL},${RECREZ}) same => n,GotoIf($[[${EXISTS(${FNAME})}]]?foundName:havenodescr) same => n(foundName),Set(FILE_FNAME=${STRREPLACE(FNAME, ,)}) same => n,GotoIf($["${STAT(f,/var/lib/asterisk/sounds/ru/cache/${FILE_FNAME}.mp3)}"="1"]?havecache:nocache)
рдЗрд╕ рдЦрдВрдб рдореЗрдВ, рдпрд╣ рдЬрд╛рдБрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдореИрдХреНрд░реЛ рдЪрд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рдЕрднрд┐рд╡рд╛рджрди рд╕рдВрджреЗрд╢ рдХреЛ рд╕реБрдирдиреЗ рдХреЗ рдмрд╛рдж рдХреЙрд▓рд░ рдХреЛ рд▓рдЯрдХрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдпрд╛ рдирд╣реАрдВ, рдлрд┐рд░ рдЪрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдХрдИ рдмрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рджреЛрд╣рд░рд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред HANGFLAG - рдЗрд╕ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реИрдВрдЧрд░рдЪреЗрдХ рдореИрдХреНрд░реЛ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
same => n(rec),Set(RECFILE=/tmp/${UNIQUEID}.wav) same => n,Playback(/var/lib/asterisk/sounds/en/beep) same => n,Record(${RECFILE},3,8) same => n,AGI(pyreq8.py,${RECFILE}) same => n,GotoIf($["${NUMTOCALL}" = "repeat"]?repeat) same => n,Set(HANGFLAG=FALSE)
рд░рд┐рдХреЙрд░реНрдб рдлрд╝рд╛рдЗрд▓ рдЪрд░ рд╕реЗрдЯ рдХрд░реЗрдВ, рдлрд╝рд╛рдЗрд▓ рд▓рд┐рдЦреЗрдВред рд╣рдо рдлрд╝рд╛рдЗрд▓ рдХреЛ рдорд╛рдиреНрдпрддрд╛ рдХреЗ рд▓рд┐рдП рднреЗрдЬрдиреЗ рдХреА рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░реА рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдирдВрдмрд░ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдХрд░рддреЗ рд╣реИрдВ (рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдХрд╛ рд╡рд┐рд╡рд░рдг рдиреАрдЪреЗ рд╣реЛрдЧрд╛), NUMTOCALL рдЪрд░ (рд╕реНрдХреНрд░рд┐рдкреНрдЯ рджреНрд╡рд╛рд░рд╛ рдорд╛рди рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдХреА рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╣реБрдП, HANGFLAG рдХреЛ рд╕реЗрдЯ рдХрд░реЗрдВ рдХрд┐ рд╡реНрдпрдХреНрддрд┐ рд╕рдордп рд╕реЗ рдкрд╣рд▓реЗ рд▓рдЯрдХрд╛ рдирд╣реАрдВ рдерд╛ред
same => n,Macro(VRstat,${CALLERID(num)},${NUMTOCALL},${RSTATUS},${CHANNEL},${RECREZ}) same => n,GotoIf($[[${EXISTS(${FNAME})}]]?foundName:havenodescr) same => n(foundName),Set(FILE_FNAME=${STRREPLACE(FNAME, ,)}) same => n,GotoIf($["${STAT(f,/var/lib/asterisk/sounds/ru/cache/${FILE_FNAME}.mp3)}"="1"]?havecache:nocache) same => n(nocache),System(curl "https://tts.voicetech.yandex.net/generate?format=mp3&lang=ru-RU&speaker=zahar&emotion=neutral&speed=0.8&key=" -G --data-urlencode "text= ${FNAME}." > /tmp/speech-${UNIQUEID}.mp3) same => n,System(/usr/local/bin/lame -S --scale 30 /tmp/speech-${UNIQUEID}.mp3 /var/lib/asterisk/sounds/ru/cache/${FILE_FNAME}.mp3) same => n(havecache),Playback(/var/lib/asterisk/sounds/ru/cache/${FILE_FNAME}) same => n,Dial(Local/${NUMTOCALL}@common-context)
рд╡реГрд╕реНрдЯ рдореИрдХреНрд░реЛ рдХреЛ рдЪрд▓рд╛рдирд╛ (рдЖрдВрдХрдбрд╝реЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░, рдЗрд╕рдХреА рддреБрдЪреНрдЫрддрд╛ рдХреЗ рдХрд╛рд░рдг рд╡рд░реНрдгрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛)ред рдЬрд╛рдВрдЪреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдЕрдиреБрд░реЛрдз рдХреЗ FNAME рд╡рд┐рд╡рд░рдг (рдЪрд░ pyreq8.py рджреНрд╡рд╛рд░рд╛ рд╕реЗрдЯ рд╣реИ)ред рдпрджрд┐ рдХреЛрдИ рд╡рд┐рд╡рд░рдг рд╣реИ, рддреЛ рдЪрд░ рдореЗрдВ рдХреИрд╢ рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рд╕реЗрдЯ рдХрд░реЗрдВ рдФрд░ рдЗрд╕рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░реЗрдВред рдпрджрд┐ рдлрд╝рд╛рдЗрд▓ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рд╕рдВрд╢реНрд▓реЗрд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдПрдордкреА 3 рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рд╡реЙрд▓реНрдпреВрдо рдмрдврд╝рд╛рддреЗ рд╣реИрдВ рдФрд░ рдлрд┐рд░ (рдпрд╛ рдпрджрд┐ рдХреИрд╢ рдореМрдЬреВрдж рд╣реИ), рддреЛ рдЗрд╕реЗ рдЪрд▓рд╛рдПрдВ рдФрд░ рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред
same => n(repeat),GotoIf($["${ITERATIONS}"="1"]?secretary) same => n,Background(/var/lib/asterisk/sounds/ru/speechrec/1-wav) same => n,Set(ITERATIONS=$[${ITERATIONS}+1]) same => n,Goto(rec)
рдмрд╛рд░-рдмрд╛рд░ рдкрд╣рдЪрд╛рдиред рдпрджрд┐ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ, рддреЛ рд╣рдо рд╕рдЪрд┐рд╡реЛрдВ рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рддреЗ рд╣реИрдВред
same => n(secretary),Macro(VRstat,${CALLERID(num)},${NUMTOCALL},${RSTATUS},${CHANNEL},${RECREZ}) same => n,Set(HANGFLAG=FALSE) same => n,Dial(Local/1000@common-context)
рд╕рдЪрд┐рд╡реЛрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рдгред рд╣рдо рдЖрдВрдХрдбрд╝реЛрдВ рдореЗрдВ рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ, рдЭрдВрдбрд╛ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рд▓рдЯрдХрд╛ рдирд╣реАрдВред рд╣рдо рд╕рдЪрд┐рд╡ рдХреЛ рдмреБрд▓рд╛рддреЗ рд╣реИрдВред
same => n(havenodescr),Playback(/var/lib/asterisk/sounds/ru/speechrec/wait2);thanks-wait) same => n,Noop('no description') same => n,Dial(Local/${NUMTOCALL}@common-context) same => n,Hangup()
рдПрдХ рдЧреНрд░рд╛рд╣рдХ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ, рдЬрд┐рд╕рдХреЗ рдкрд╛рд╕ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдореЗрдВ рд╡рд┐рд╡рд░рдг рдирд╣реАрдВ рд╣реИред рд╣рдо рд╕рдВрджреЗрд╢ рдЦреЛ рджреЗрддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдЖрдВрдХрдбрд╝реЛрдВ рдореЗрдВ рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВред
exten => h,1,Gotoif($["${HANGFLAG}"="TRUE"]?exec:noop) same => n(exec),Macro(VRstat,${CALLERID(num)},x,HANGER,${CHANNEL}) same => n(noop),Noop('exiting')
рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрдВрдЧрд░рдЪреЗрдХ рдореИрдХреНрд░реЛ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рд╕рдорд╛рдкреНрддрд┐ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ред
рдбрд╛рдпрд▓рди рд╡рд┐рд╡рд░рдгред рдореИрдХреНрд░реЛред
[macro-hangercheck] ;${ARG1} -clid exten => s,1,GotoIf($["${ARG1}"="anonymous"]?end) exten => s,n,MYSQL(Connect connid SRV user password db utf8) exten => s,n,MYSQL(SET NAMES utf8) exten => s,n,MYSQL(Query resultid ${connid} SELECT IFNULL((SELECT clid from ivr_stat where rstatus="HANGER" and calldate >=ADDDATE(NOW(),INTERVAL -48 HOUR) and clid="${ARG1}" order by calldate desc limit 1),"NF")) exten => s,n,MYSQL(Fetch fetchid ${resultid} VAR) exten => s,n,MYSQL(Clear ${resultid}) exten => s,n,MYSQL(Disconnect ${connid}) exten => s,n,GotoIf($["${VAR}"="NF"]?end) exten => s,n,Macro(VRstat,${ARG1},x,H_RECALL,${CHANNEL}) exten => s,n,Dial(Local/1000@common-context) exten => s,n,Hangup() exten => s,n(end),Noop(Hanger check failed)
рд╣рдо рдЖрдБрдХрдбрд╝реЛрдВ рдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЬрд╛рдБрдЪ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рджрд┐рдП рдЧрдП рдирдВрдмрд░ рдХреЛ рдкрд┐рдЫрд▓реЗ 48 рдШрдВрдЯреЗ рдХрд╣рд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЕрдЧрд░ рд╡рд╣ рдорд╛рдиреНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд┐рдП рдмрд┐рдирд╛ рдлреЛрди рд▓рдЯрдХрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рдЖрдБрдХрдбрд╝реЛрдВ рдореЗрдВ рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рд╕рдЪрд┐рд╡ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВред
рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП sql рдФрд░ mysql рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдгред
Sql рддрд╛рд▓рд┐рдХрд╛ dbo.phrasesред
id(PK, int), phrase (text), number(varchar(50))
рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд▓рд┐рдП рдкреВрд░реНрдг-рдкрд╛рда рдЦреЛрдЬ рдХреЛ рдЙрдард╛рдпрд╛ рдЧрдпрд╛ рд╣реИ; рдпрд╣ рдПрдХ рд▓рдВрдмреА рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╕рдордп рдХреАрд╡рд░реНрдб рджреНрд╡рд╛рд░рд╛ рд╕реНрд╡рд┐рдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд╛рдХреНрдпрд╛рдВрд╢: "рдХреГрдкрдпрд╛ рдореБрдЭреЗ рд╡рд┐рдЬреНрдЮрд╛рдкрди рд╡рд┐рднрд╛рдЧ рдХреЗ рдПрдХ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреЗ рд╕рд╛рде рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ," рдпрджрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдХреЛрдИ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рд╣реИ рдЬрд╣рд╛рдВ рд╡рд╛рдХреНрдпрд╛рдВрд╢ = "рд╡рд┐рдЬреНрдЮрд╛рдкрди рд╡рд┐рднрд╛рдЧ", рддреЛ рдХреЙрд▓рд░ рд╕рдВрдмрдВрдзрд┐рдд рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реЛрдЧрд╛ред
рдореАрдХрд▓ рдЯреЗрдмрд▓ рд░рд┐рдХреЛрдЧрд╕реНрдЯреИрдЯреНрд╕ред
id(PK, int), date (datetime), ctime(float), rtime(float),stime(float), phrase(varchar(60))
рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдорд╛рдиреНрдпрддрд╛ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдФрд░ рдорд╛рдиреНрдпрддрд╛ рд╕рдордп рдкрд░ рдЖрдВрдХрдбрд╝реЗ рдПрдХрддреНрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред CIME - рдСрдбрд┐рдпреЛ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдХрдирд╡рд░реНрдЯ рдХрд░рдиреЗ рдореЗрдВ рдмрд┐рддрд╛рдпрд╛ рдЧрдпрд╛ рд╕рдордп, рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рдиреЗ рдФрд░ рдкрд╣рдЪрд╛рдирдиреЗ рдореЗрдВ рдЦрд░реНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛, stime - рдЦреЛрдЬ рдореЗрдВ рдмрд┐рддрд╛рдпрд╛ рдЧрдпрд╛ рд╕рдордп
рдорд╛рдпрд┐рдХрд▓ рдЯреЗрдмрд▓ ivr_stat
id(PK, int), calldate (datetime),clid(varchar(15)),duration(int(20)),callednum(varchar(10)),rstatus(varchar(20)),channame(varchar30)),RECREZ(varchar(200))
рдЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдкрд╣рдЪрд╛рди рдкрд░рд┐рдгрд╛рдореЛрдВ (RECREZ, rstatus) рдкрд░ рдирдЬрд╝рд░ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдХреЙрд▓рд░ рдиреЗ рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рд╡рд╛рдХреНрдпрд╛рдВрд╢ (рдбрд┐рдЧреНрдирдо) рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдорд╛рдиреНрдпрддрд╛ рдореЗрдиреВ (рдЕрд╡рдзрд┐) рдФрд░ рдбрд┐рдмрдЧрд┐рдВрдЧ (channame) рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рд╡реНрдпрдХреНрддрд┐ рджреНрд╡рд╛рд░рд╛ рдХрд┐рддрдирд╛ рд╕рдордп рдХрд╛ рдЯреНрд░реИрдХ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдерд╛
рдордпреНрдпрдХрд▓ рдХрд╕реНрдЯрдорд░реИрд▓реЗрд╕реНрдЯреНрд╕ рдЯреЗрдмрд▓ред
id(PK, int), nomer(int(10)), request(varchar(100))
рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдореВрд╣реЛрдВ рдФрд░ рд╡рд┐рднрд╛рдЧреЛрдВ рдХреА рдПрдХ рд╕рд╣рд╛рдпрдХ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ред
рдордпрд╕реНрдХрд▓ рдЕрдВрдХ рддрд╛рд▓рд┐рдХрд╛ред
Num(text), name(text)
рдЖрд╡рд╛рдЬ рдЕрднрд┐рдирдп рдХреЗ рд▓рд┐рдП рджрд░реНрдЬ рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХреЗ рд╕рд╛рде рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ред
рдореИрд╕рдХрд▓ рдЯреЗрдмрд▓ spravochnik_rus рдФрд░ spravochnik_rus_name_num_no_tops
nomer(varchar(11)), fio(varchar(100))
рд╕рдВрдЦреНрдпрд╛ рд╡рд╛рд▓реЗ рд╕рдВрджрд░реНрдн рд╡реНрдпрдХреНрддрд┐ред рдЖрдВрддрд░рд┐рдХ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓рд╛ рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред рджреВрд╕рд░реЗ рдореЗрдВ, рдмрд╛рд╣рд░реА рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП, рдирд┐рджреЗрд╢рдХреЛрдВ рдФрд░ рдкреНрд░рдмрдВрдзрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдПрдХ рд╕рдЪрд┐рд╡рд╛рд▓рдп рдореЗрдВ рд▓рдкреЗрдЯреА рдЬрд╛рддреА рд╣реИред
рдПрдЬреАрдЖрдИ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЬреЛ рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рд╡рд╛рдХреНрдпрд╛рдВрд╢реЛрдВ рдХреЗ рд▓рд┐рдП рдЕрднрд┐рд╕рд░рдг, рднреЗрдЬрддрд╛ рдФрд░ рдЦреЛрдЬрддрд╛ рд╣реИред
рдкреНрд░рдпреБрдХреНрдд рдкреБрд╕реНрддрдХрд╛рд▓рдп:
import difflib from sys import exit import uuid import time import os import subprocess import xml.etree.ElementTree import MySQLdb import pymssql import string import re from itertools import permutations from os import remove import timeit
рдФрд░ asterisk.agi рд▓рд╛рдЗрдмреНрд░реЗрд░реА рднреА, рдЬрд┐рд╕реЗ рд╣рдо рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЖрдпрд╛рдд рдХрд░рддреЗ рд╣реИрдВ (рдбрд┐рдмрдЧрд┐рдВрдЧ рдПрдХ рд╡рд┐рдВрдбреЛрдЬрд╝ рдорд╢реАрди рдкрд░ рдХреА рдЬрд╛рддреА рд╣реИ)ред
рдЪрд░реЛрдВ рдХрд╛ рд╡рд░реНрдгрдиред
WINDEBUG = False
рдбрд┐рдмрдЧ рдзреНрд╡рдЬ
_digits = re.compile('\d')
рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдЪрд░ред
uniqid = str(uuid.uuid1()).replace('-', '')
рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдЪрд░ред
dkey = '12345678-9101-1121-3141-51617181920'
Yandex рднрд╛рд╖рдг рдХрд┐рдЯ рдПрдкреАрдЖрдИ рдХреБрдВрдЬреАред
lang = 'ru-RU'
рдпрд╛рдВрдбреЗрдХреНрд╕ рд╕реНрдкреАрдЪрд┐рдЯрдХ рдХреЗ рд▓рд┐рдП рднрд╛рд╖рд╛ рд╡рд┐рдХрд▓реНрдкред
topic = 'queries'
рдпрд╛рдВрдбреЗрдХреНрд╕ рд╕реНрдкреАрдЪрд┐рдЯрдХ рдХреЗ рд▓рд┐рдП рдорд╛рдиреНрдпрддрд╛ рдереАрдо рд╡рд┐рдХрд▓реНрдкред
callnumber = '222'
рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХреЙрд▓ рдирдВрдмрд░ред
setVar('NUMTOCALL', callnumber)
рдХреБрдЫ рдЧрд▓рдд рд╣реЛрдиреЗ рдкрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХреЙрд▓ рдирдВрдмрд░ рд╕реЗрдЯ рдХрд░рдирд╛ред
persondic = dict()
рд╢рдмреНрджрдХреЛрд╢ рдирд╛рдо - рд╕рдВрдЦреНрдпрд╛ред
persondicFI=dict()
рдПрдлрдЖрдИ тАЛтАЛрд╢рдмреНрджрдХреЛрд╢ - рд╕рдВрдЦреНрдпрд╛ред
persondicF=dict()
рд╢рдмреНрджрдХреЛрд╢ рдЕрдВрддрд┐рдо рдирд╛рдо - рд╕рдВрдЦреНрдпрд╛ред
otherdic = dict()
рдкреНрд░рдкрддреНрд░ рдХреА рдЕрдиреНрдп рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╢рдмреНрджрдХреЛрд╢ рд░рд┐рдХреЙрд░реНрдб - рд╕рдВрдЦреНрдпрд╛ред
descriptions = dict()
рдЖрд╡рд╛рдЬ рдЕрднрд┐рдирдп рдХреА рдкреАрдврд╝реА рдХреЗ рд▓рд┐рдП рд╡рд┐рд╡рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╢рдмреНрджрдХреЛрд╢, рд░рд┐рдХреЙрд░реНрдб - рд╕рдВрдЦреНрдпрд╛ред
duplicates = list()
рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕реЗрд╡рд╛ рд╕реВрдЪреА рд▓реЗрддрд╛ рд╣реИред
nums = list()
рд╕рднреА рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЗ рд╕рд╛рде рд╕реВрдЪреАред
outfile = '/tmp/' + uniqid + '-pcm.wav'
рдЪрд░ рдЕрд╕реНрдерд╛рдпреА рдЖрдЙрдЯрдкреБрдЯ рдСрдбрд┐рдпреЛ рдлрд╝рд╛рдЗрд▓ред
mysqlhost='myhost' mysqlpass='mypass' mysqluser='myuser' mysqldb='mydb' mssqlhost='mshost' mssqlpass='mspass' mssqluser='msuser' mssqldb='msdb'
Mysql рдФрд░ mssql рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╡рд░рдгред
if not WINDEBUG: from asterisk.agi import * agi = AGI() infile = agi.env['agi_arg_1'] caller = agi.get_variable('CALLERID(num)') else: caller = '1064' infile = ''
рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЖрдпрд╛рдд рдХрд░реЗрдВ, рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЗрдирдкреБрдЯ рдСрдбрд┐рдпреЛ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдирд╛рдо рдФрд░ рдХреЙрд▓рд░ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪрд░ рд╕реЗрдЯ рдХрд░реЗрдВред
рдлрд╝реАрдЪрд░ рд╡рд┐рд╡рд░рдг
def verb(s): if not WINDEBUG: agi.verbose(s) else: print s
рдбрд┐рдмрдЧрд┐рдВрдЧ рд╡реИрд░рд┐рдПрдмрд▓ рдХреЗ рдорд╛рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдо рддрд╛рд░рд╛рдВрдХрди рдХрдВрд╕реЛрд▓ рдпрд╛ рд╕реНрдЯреИрдбрдЖрдЙрдЯ рдореЗрдВ рд╕рдВрджреЗрд╢ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
def setVar(varname, varval): if not WINDEBUG: agi.set_variable(varname, varval) else: print "setting var " + varname + " with value " + varval
рдбреАрдмрдЧрд┐рдВрдЧ рд╡реИрд░рд┐рдПрдмрд▓ рдХреЗ рдорд╛рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдо рдбрд╛рдпрд▓рдкреИрди рд╡реИрд░рд┐рдПрдмрд▓ рдХреЗ рдорд╛рди рдХреЛ рддрд╛рд░рд╛рдВрдХрди рдпрд╛ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рд╕реНрдЯрдбрдЖрдЙрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдХрд░рддреЗ рд╣реИрдВред
def contains_digits(s): verb('enter contains_digits') return bool(_digits.search(s))
рдЬрд╛рдВрдЪреЗрдВ рдХрд┐ рдХреНрдпрд╛ рдЕрдВрдХ рд╣реИрдВред
def return_digits(s): verb('return digits') pstr = s.encode("utf-8") all = string.maketrans('', '') nodigs = all.translate(all, string.digits) return unicode(pstr.translate(all, nodigs), "utf-8")
рд╣рдо рдПрд╕ рд╕реЗ рдХреЗрд╡рд▓ рдирдВрдмрд░ рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред
def check_dob(num): if int(num) in nums: verb('checkdob success') return True else: verb('checkdob fail' + num) return False
рдЕрдВрдХ рд╕реВрдЪреА рдореЗрдВ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреА рдЬрд╛рдБрдЪ рдХрд░реЗрдВред
def set_dob(strnum): buf = return_digits(strnum) if contains_digits(strnum): if check_dob(buf): verb('setting var ' + buf) setVar('RSTATUS', 'SAYDIAL') return buf else: return "repeat" else: return "repeat"
рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╕реЗрдЯрд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рдиред
def checkSize(infile): if int(os.stat(infile).st_size) <= 26364: setVar('NUMTOCALL', 'repeat') setVar('RSTATUS', 'SILENCE') verb('empty file received') remove(infile) exit(9)
рдорд╛рдиреНрдпрддрд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рдкреНрдд рдСрдбрд┐рдпреЛ рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдлрд╝рд╛рдЗрд▓ рдХреА рдЬрд╛рдБрдЪ рдХрд░рдирд╛, рдпрджрд┐ рдЖрдХрд╛рд░ рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣реИ, рддреЛ рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╡реЗ рд╣реИрдВрдбрд╕реЗрдЯ рдореЗрдВ рдЪреБрдк рдереЗред
def addSessionStat(ctime, rtime, stime, phrase): cdate = time.strftime("%Y-%m-%d %H:%M:%S") db = MySQLdb.connect(host=mysqlhost, user=mysqluser, passwd=mysqluser, db=mysqldb, charset='utf8') cur = db.cursor() cur.execute( "INSERT INTO recogStats(date,ctime,rtime,stime,phrase) VALUES ('" + cdate + "','" + str(ctime) + "','" + str( rtime) + "','" + str(stime) + "','" + phrase + "')") db.commit() db.close()
рд░рд┐рдХреЙрд░реНрдбрд┐рдВрдЧ рдЖрдБрдХрдбрд╝реЗ рдорд╛рдиреНрдпрддрд╛ рд╕рдорд╛рд░реЛрд╣ред
def fillDics(): db = MySQLdb.connect(host=mysqlhost, user=mysqluser, passwd=mysqlpass, db="central_cdr", charset='utf8') cur = db.cursor() if len(caller) != 4: tbname = 'spravochnik_rus_name_num_no_tops' else: tbname = 'svravochnik_rus_persons' cur.execute("""SELECT nomer,fio from """ + tbname) for row in cur.fetchall(): fullfio=row[1].lower() f=" ".join(fullfio.split(' ')[0:1]) if not f in persondicF.keys():
рдпрд╣ рдлрдВрдХреНрд╢рди рд▓рд╛рд╕реНрдЯ рдиреЗрдо (PersondicF), рд▓рд╛рд╕реНрдЯ рдиреЗрдо (persondicFI), рдиреЗрдо (Persondic), рдбрд┐рдкрд╛рд░реНрдЯрдореЗрдВрдЯ рдиреЗрдо (рдЕрдиреНрдп), рд╕реНрдкреАрдЪ рд╕рд┐рдВрдереЗрд╕рд┐рд╕ рдХреЗ рд▓рд┐рдП рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрд╢рди (рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрд╢рди) рдФрд░ рд╕рднреА рдХрдВрдкрдиреА рдирдВрдмрд░ (рдЕрдВрдХ) рднрд░рддрд╛ рд╣реИред
рдХреЙрд▓рд░ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рд▓рдВрдмрд╛рдИ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд▓реА рдЬрд╛рддреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдирд┐рджреЗрд╢рдХреЛрдВ (рдЖрдВрддрд░рд┐рдХ рдХреЙрд▓рд░) рдХреА рд╕рдВрдЦреНрдпрд╛ рд╢рд╛рдорд┐рд▓ рд╣реЛрддреА рд╣реИ рдпрд╛ рдЗрд╕рдореЗрдВ (рдмрд╛рд╣реНрдп рдХреЙрд▓рд░) рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред
рдЙрдкрдирд╛рдореЛрдВ рдХреА рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреЛ рджреЛ рдЗрд╡рд╛рдиреЛрд╡реНрд╕ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдмрд╛рд╣рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
def convert(infile, outfile):
рдпрджрд┐ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИ, рддреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕реЗрдЯ рдХреА рдЧрдИ рд╕рдВрдЦреНрдпрд╛ рдФрд░ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╕реЗ рдмрд╛рд╣рд░ рдирд┐рдХрд▓рдиреЗ рдкрд░, рддрд╛рд░рд╛рдВрдХрди рдЪрд┐рд╣реНрди рдореЗрдВ рджрд░реНрдЬ рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдпред
def sendRecog(file): verb("Sending file to yandex: " + outfile) proc = subprocess.Popen(['curl', '--max-time', '5', '--silent', 'asr.yandex.net/asr_xml?key=' + dkey + '&uuid=' + uniqid + '&topic=' + topic + '&lang=ru-RU', '-F', 'Content-Type=audio/x-pcm;bit=16;rate=16000', '-F', 'audio=@' + outfile], stdout=subprocess.PIPE) (out, err) = proc.communicate() verb("return code is: " + str(proc.returncode)) if proc.returncode != 0: return "" remove(file) e = xml.etree.ElementTree.fromstring(out) if e.attrib['success'] == '1': verb(e._children[0].text) return e._children[0].text else: return ""
рдорд╛рдиреНрдпрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рд╛рдЗрд▓ рднреЗрдЬрдиреЗ рдФрд░ рдпреИрдВрдбреЗрдХреНрд╕ рд╕реЗ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдпред рдпрджрд┐ рдорд╛рдиреНрдпрддрд╛ рд╕рдлрд▓ рд╣реИ, рддреЛ рд╣рдо рдкрд╣рд▓рд╛ рдЙрддреНрддрд░ рд▓реЗрддреЗ рд╣реИрдВред рдореИрдВ рдХрд░реНрд▓ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрд╛, рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ рдЗрд╕ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
def searchfiobyf(f): if len(f.split(" "))==2: limit=2 elif len(f.split(" "))>=3: return f else: limit=1 for fio,num in persondic.iteritems(): cutfio=" ".join(fio.split(' ')[0:limit]) if f == cutfio: return fio
рдПрдХ рдкреВрд░реНрдг рдирд╛рдо рдХреА рдЦреЛрдЬ рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп, рдХреЗрд╡рд▓ рдЗрд╕ рдмрд╛рдд рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЕрдВрддрд┐рдо рдирд╛рдо рдпрд╛ рдЕрдВрддрд┐рдо рдирд╛рдо рдФрд░ рдкрд╣рд▓рд╛ рдирд╛рдо рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП рдЖрдпрд╛ рдерд╛ рдпрд╛ рдирд╣реАрдВред
def combinationSearcher(phrase,pdic,quality): verb(u'searching in persons') result = difflib.get_close_matches(phrase, pdic.keys(), 1, quality)
рд╕рдВрдпреЛрдЬрди рдЦреЛрдЬ рдлрд╝рдВрдХреНрд╢рди, рдЙрджрд╛рд╣рд░рдг: рд╡рд╛рдХреНрдпрд╛рдВрд╢ = "рдПрд▓реЗрдХреНрд╕реА рдкреЗрдЯреНрд░", pdic рдореЗрдВ "рдПрд▓реЗрдХреНрд╕реЗрд╡ рдкреАрдЯрд░" рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рд╢рд╛рдорд┐рд▓ рд╣реИ, get_close_matches рдлрд╝рдВрдХреНрд╢рди "рдПрд▓реЗрдХреНрд╕реАрд╡ рдкреАрдЯрд░" рд▓реМрдЯрд╛рдПрдЧрд╛ред рдлрд╝рдВрдХреНрд╢рди рдЧрд▓рдд рдкрд░рд┐рдгрд╛рдо рджреЗ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди, рдЬреИрд╕рд╛ рдХрд┐ рдЕрднреНрдпрд╛рд╕ рдиреЗ рджрд┐рдЦрд╛рдпрд╛ рд╣реИ, рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕рд╣реА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдПрдВ рд╣реИрдВред рдЧреБрдгрд╡рддреНрддрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдЖрдкрдХреЛ рд╕рдорд╛рди рд╡рд╛рдХреНрдпрд╛рдВрд╢реЛрдВ рдХреЗ рд▓рд┐рдП рдЦреЛрдЬ рдХреА рд╕рдЯреАрдХрддрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
def getNumByName(recognizedString): if u'' in recognizedString: verb('enter dobavochn') return set_dob(recognizedString) elif len(recognizedString.replace(" ", "")) == 4: verb('enter num say') return set_dob(recognizedString) if len(recognizedString) <= 5 and recognizedString.lower() not in [u"",u"",u""]: setVar('RSTATUS', 'SHORT') return "repeat" verb(u'start searching')
рд╡рд╛рдХреНрдпрд╛рдВрд╢ рджреНрд╡рд╛рд░рд╛ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХрд╛ рдореБрдЦреНрдп рдХрд╛рд░реНрдпред
рдЖрдЗрдП рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВред
if u'' in recognizedString: verb('enter dobavochn') return set_dob(recognizedString)
рдЙрджрд╛рд╣рд░рдг: рд╡рд╛рдХреНрдпрд╛рдВрд╢ "рдХреГрдкрдпрд╛, рд╡рд┐рд╕реНрддрд╛рд░ 1234" рд╡рд┐рд╕реНрддрд╛рд░ рд╕рдВрдЦреНрдпрд╛ (рдпрджрд┐ рдХреЛрдИ рд╣реЛ) рд╡рд╛рдкрд╕ рдХрд░ рджреЗрдЧрд╛ред
elif len(recognizedString.replace(" ", "")) == 4: verb('enter num say') return set_dob(recognizedString)
рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рдЪрд╛рд░-рдЕрдВрдХреАрдп рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдЙрдЪреНрдЪрд╛рд░рдг рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рд╕рдВрдмрдВрдзрд┐рдд рдПрдХреНрд╕рдЯреЗрдВрд╢рди (рдпрджрд┐ рдХреЛрдИ рд╣реЛ) рд▓реМрдЯрд╛рдПрдВ
if len(recognizedString) <= 5 and recognizedString.lower() not in [u"",u"",u""]: setVar('RSTATUS', 'SHORT') return "repeat"
рдЫреЛрдЯреЗ рд╡рд╛рдХреНрдпрд╛рдВрд╢реЛрдВ рдореЗрдВ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд░рди рдирд╣реАрдВ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП (рдпрд╣ рддрдм рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рдпрд╛рдВрдбреЗрдХреНрд╕ рдиреЗ рдмрд╛рддрдЪреАрдд рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рд╕реБрдирд╛ рдФрд░ рдкрд╣рдЪрд╛рдирд╛ рдЧрдпрд╛, рдЬрдм рдХреЙрд▓рд░ рдиреЗ рдорд╛рдиреНрдпрддрд╛ рд╕рдВрджреЗрд╢ рдирд╣реАрдВ рд╕реБрдирд╛)ред
if parts >= 5: verb('Phrase is long. Using FTDB') buf = mssqlwrapper(fixedstring) if buf != '': buf = mssqlwrapper(fixedstring)[0] if str(buf) in descriptions.keys(): setVar('FNAME', descriptions[str(buf)]) setVar('RSTATUS', 'DEPTSUCCESS') return buf else: setVar('RSTATUS', 'REQUESTNOTFOUND') return "repeat" result=""
рд▓рдВрдмреЗ рд╡рд╛рдХреНрдпрд╛рдВрд╢реЛрдВ (рдкрд╛рдВрдЪ рд╕реЗ рдЕрдзрд┐рдХ рд╢рдмреНрджреЛрдВ) рдХреЗ рд▓рд┐рдП, рд╣рдо рддреБрд░рдВрдд mssql рдХреЗ FT рдмреЗрд╕ рдХреА рдУрд░ рдореБрдбрд╝ рдЬрд╛рддреЗ рд╣реИрдВред
if parts == 1: mssqlcheck=mssqlwrapper(fixedstring) if mssqlcheck!='': if mssqlcheck[2]>=80: buf=str(mssqlcheck[0]) if buf in descriptions.keys(): setVar('FNAME', descriptions[str(buf)]) setVar('RSTATUS', 'DEPTSUCCESS') result=buf else: result=combinationSearcher(fixedstring,persondicF,0.7)
рдпрджрд┐ рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдореЗрдВ рдПрдХ рд╢рдмреНрдж рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдкрд╣рд▓реЗ рд╣рдо FT рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ, 80% рдХреА рд╕рдЯреАрдХрддрд╛ рдХреЗ рд╕рд╛рде, рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреА рддрд▓рд╛рд╢ рдХрд░рддреЗ рд╣реИрдВ, рдкрд░рд┐рдгрд╛рдо рдЪрд░ рдФрд░ рд╕реНрдерд┐рддрд┐ рдпреЛрдЬрдирд╛ рдирдВрдмрд░ рдЪрд░ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдЕрдиреНрдпрдерд╛ рд╣рдо рдЙрдкрдирд╛рдореЛрдВ рдХреЗ рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рд╕рдорд╛рди рд╢рдмреНрджреЛрдВ рдХреА рдЦреЛрдЬ рдХрд░рддреЗ рд╣реИрдВред
elif parts ==2: combs = list(permutations(split, parts)) for item in combs: element = " ".join(item) result=combinationSearcher(element,persondicFI,0.7) if result!="": break
рдпрджрд┐ рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдореЗрдВ рджреЛ рд╢рдмреНрдж рд╣реИрдВ, рддреЛ рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдПрдХ рдЙрдкрдирд╛рдо рдФрд░ рдПрдХ рдирд╛рдо рд╣реИред
рд╣рдо рд╕рдВрдпреЛрдЬрдиреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдмрдирд╛рддреЗ рд╣реИрдВ (рдЗрд╡рд╛рди рдЗрд╡рд╛рди, рдЗрд╡рд╛рди рдЗрд╡рд╛рди) рдФрд░ рдЗрд╕реА рддрд░рд╣ рдХреЗ рдореИрдЪреЛрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░рддреЗ рд╣реИрдВред
elif parts ==3: combs = list(permutations(split, parts)) for item in combs: element = " ".join(item) result=combinationSearcher(element,persondic,0.8) if result!="": break if result!="": return result
рддреАрди-рд╢рдмреНрдж рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдПрдХ рдирд╛рдо рд╣реИ, рд╕рдВрдпреЛрдЬрди рдХреА рдПрдХ рд╕реВрдЪреА рдмрдирд╛рдПрдВ рдФрд░ рдПрдХ рдирд╛рдо рдХреЗ рд╕рд╛рде рд╢рдмреНрджрдХреЛрд╢ рдореЗрдВ рджреЗрдЦреЗрдВред рдпрджрд┐ рдЪрд░ рдЦрд╛рд▓реА рдирд╣реАрдВ рд╣реИ рддреЛ рд╣рдо рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрд╛рддреЗ рд╣реИрдВред
buf = mssqlwrapper(recognizedString) if buf != '': buf = mssqlwrapper(recognizedString)[0] if str(buf) in descriptions.keys(): verb('it is') setVar('FNAME', descriptions[str(buf)]) setVar('RSTATUS', 'DEPTSUCCESS') return buf else: verb(u'item not found ' + recognizedString)
рдпрджрд┐ рд╣рдореЗрдВ рдорд┐рд▓рд╛рди рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ, рддреЛ рд╣рдо рдПрдлрдЯреА рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдПрдХ рдЦреЛрдЬ рдХрд░рддреЗ рд╣реИрдВ, рдЕрдЧрд░ рд╣рдореЗрдВ рдПрдХ рдореИрдЪ рдорд┐рд▓рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдкрд░рд┐рдгрд╛рдо рдФрд░ рд╡рд┐рд╡рд░рдг рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ, рдЕрдиреНрдпрдерд╛ рд╣рдо рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕рдВрдЦреНрдпрд╛ рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ рдФрд░ рд╕реНрдерд┐рддрд┐ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдирд╣реАрдВ рдорд┐рд▓рд╛ред
рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдореБрдЦреНрдп рдЕрдВрдЧред
fillDics() if not WINDEBUG: checkSize(infile) start_time = timeit.default_timer() convert(infile, outfile) convert_elapsed = timeit.default_timer() - start_time start_time = timeit.default_timer() checkstring = sendRecog(outfile).lower() recog_elapsed = timeit.default_timer() - start_time verb('convert_elapsed = ' + str(recog_elapsed)) if checkstring == "": verb('not recognized. using default.') setVar('NUMTOCALL', 'repeat') setVar('RSTATUS', 'SILENCE') exit(9) else: setVar('RECREZ', checkstring) else: checkstring = u"" start_time = timeit.default_timer() callnumber = getNumByName(checkstring) search_elapsed = timeit.default_timer() - start_time if not WINDEBUG: setVar('NUMTOCALL', str(callnumber)) addSessionStat(convert_elapsed, recog_elapsed, search_elapsed, checkstring.lower())
рд╢рдмреНрджрдХреЛрд╢реЛрдВ рдХреЛ рднрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рдВрдХреНрд╢рди рд▓реЙрдиреНрдЪ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЕрдЧрд░ рд╣рдо рдбрд┐рдмрдЧрд┐рдВрдЧ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ рдирд╣реАрдВ рд╣реИрдВ - рд╣рдо рдЯрд╛рдЗрдорд░ рдЪрд░ рдореЗрдВ рднрд░рддреЗ рд╣реИрдВ, рдлрд╝рд╛рдЗрд▓ рдЖрдХрд╛рд░ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ, рдХрдиреНрд╡рд░реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдорд╛рдиреНрдпрддрд╛ рдХреЗ рд▓рд┐рдП рднреЗрдЬрддреЗ рд╣реИрдВ, рдЕрдиреНрдпрдерд╛ рд╣рдо рдЪреЗрдХ рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдХреЗ рд╕рд╛рде рдЪреЗрдХрд╕реНрдЯреНрд░рд┐рдВрдЧ рдЪрд░ рднрд░рддреЗ рд╣реИрдВред
рдЕрдЧрд▓рд╛, рд╣рдо рдорд╛рдиреНрдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдорд░ рдХреЗ рдЪрд░ рдореЗрдВ рднрд░рддреЗ рд╣реИрдВ, рд╣рдо рдЕрдкрдиреА рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рд╡рд╛рдХреНрдпрд╛рдВрд╢реЛрдВ рдХреА рдЦреЛрдЬ рдХрд░рддреЗ рд╣реИрдВред рдФрд░, рд▓рдбрд╝рд╛рдХреВ рдХрд╛рдордХрд╛рдЬ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдо рдирдВрдмрд░рд┐рдВрдЧ рдпреЛрдЬрдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдЪрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЖрдВрдХрдбрд╝реЗ рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВред
рдХреБрдЫ рдЖрдБрдХрдбрд╝реЗред
рдЬреВрди 2018:
рд╕рдлрд▓ рдорд╛рдиреНрдпрддрд╛ - 1010
рдПрдХ рдЯреНрдпреВрдм рдореЗрдВ рдЪреБрдк рдереЗ - 78
рдорд╛рдиреНрдпрддрд╛ рд╡рд┐рдлрд▓ (рдХреЛрдИ рдореИрдЪ рдирд╣реАрдВ рдорд┐рд▓рд╛) - 79
рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЕрдиреБрд░реЛрдз - 4
рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рд╡рд┐рднрд╛рдЧ - 7
рдФрд╕рдд рдорд╛рдиреНрдпрддрд╛ рд╕рдордп (рдФрд╕рдд Yandex рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп) - 2.6 рд╕реЗрдХрдВрдб
рдЬреВрди 2017:
рд╕рдлрд▓ рдорд╛рдиреНрдпрддрд╛ - 1271
рдорд╛рдиреНрдпрддрд╛ рдкреНрд░рд╛рдкреНрдд рд╡рд┐рднрд╛рдЧ - 18
рдорд╛рдиреНрдпрддрд╛ рд╡рд┐рдлрд▓ (рдХреЛрдИ рдореИрдЪ рдирд╣реАрдВ рдорд┐рд▓рд╛) - 127
рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЕрдиреБрд░реЛрдз - 9
рдПрдХ рдЯреНрдпреВрдм рдореЗрдВ рдЪреБрдк рдереЗ - 71
рдФрд╕рдд рдорд╛рдиреНрдпрддрд╛ рд╕рдордп (рдФрд╕рдд Yandex рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп) - 1.5 рд╕реЗрдХрдВрдб
рдпрд╣ рд╕реЗрд╡рд╛ рдЙрд╕ рдХрдВрдкрдиреА рдореЗрдВ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рддреА рд╣реИ рдЬрд╣рд╛рдВ рдореИрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реВрдВред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдореЗрд░реА рдЙрдкрд▓рдмреНрдзрд┐рдпрд╛рдВ рдЕрдиреНрдп рд▓реЛрдЧреЛрдВ рдХреЛ рдЙрдирдХреЗ рд╡рд┐рдЪрд╛рд░реЛрдВ рдпрд╛ рдЗрд╕реА рддрд░рд╣ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдореЗрдВ рдорджрдж рдХрд░реЗрдВрдЧреАред рд╕рднреА рд╕рд╡рд╛рд▓реЛрдВ рдХреЗ рдЬрд╡рд╛рдм рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ред