ВидеоКонф(ВКС)  ::   FAQ  ::   Поиск  ::   Регистрация  ::   Вход

Asterisk CDR Viewer Mod, в mysql не попадает filename

Новичком считается только что прочитавший «Астериск - будущее телефонии»
http://asterisk.ru/knowledgebase/books
и пытающийся сделать большее

Модераторы: april22, Zavr2008

Asterisk CDR Viewer Mod, в mysql не попадает filename

Сообщение Elektronik » 20 окт 2017, 15:38

Добрый день!
Прикручиваю Asterisk CDR Viewer Mod, возникли 2 проблемы, которые никак не могу решить\найти решение, прошу Вашей помощи.

Как выглядит у меня:
cdr.JPG

Как должно выглядеть:
cdrfine.JPG


Проблема видна на картинках выше.
1. Статус выводится кодом, который получается из таблицы, такое ощущение, что не хватает куска кода, который преобразует из значения (0,8,4) в слово отвечено\занято\отклонено и и т.д.
2. Не отображаются файлы для прослушивания разговора, потому что не попадает имя файла в таблицу, почему не попадает не понимаю, собственно поэтому пишу сей пост.
3. Файлы согласно www/html/cdr/inc/config/config.php должны попадать в определенную папку (например год/месяц/число/*.mp3), но как связан этот конфиг и mixmonitor и как вообще могут быть связаны не пойму.
4. Опять же судя по конфигу, vaw в mp3 должны перекодироваться ночью, а они кодируются сразу после записи
ниже логи того, что может пригодиться.
Если еще что то надо -- скажите.

[Показать] Спойлер: readme Asterisk CDR Viewer Mod
===============================================
Системные требования
===============================================

- PHP 5.2 и выше
- База данных MySQL или другая, которая поддерживается PDO (PostgreSQL...)
- Веб-сервер (Nginx, Apache, Lighttpd...)


===============================================
Форматы записей разговоров
===============================================

Используется HTML5 плеер для воспроизведения записей разговоров.
Доступные форматы аудио: MP3, WAV, OGG, AAC...

Проверенные форматы аудио. Проверялось в Internet Explorer 11, Chrome 56, Firefox 52:
- MP3. Поддерживаются все браузеры
- WAV. Не работает в Internet Explorer
- OGG. Не работает в Internet Explorer

Формат GSM не поддерживается для воспроизведения ни одним браузером.


===============================================
Проверка обновлений
===============================================

Начиная с версии 2.3 доступна проверка обновлений. Чтобы проверить доступность новой версии, нужно щелкнуть на стрелочку в самом низу веб-интерфейса (подвал), рядом с надписью "Asterisk CDR Viewer Mod v[версия]".
Проверяется только доступность новой версии, но автоматического обновления не происходит. Обновлять необходимо вручную.
Если доступна новая версия, то будут отображены: текущая версия, новая версия, изменения в последнем релизе.


===============================================
Редактирование базы данных
===============================================

С базой данных MySQL удобнее всего работать через PHPMYADMIN. Официальный сайт: https://www.phpmyadmin.net/
Если у вас используется не база данных MySQL (а например PostgreSQL), или PHPMYADMIN не установлен, то следует использовать ADMINER. Официальный сайт: https://www.adminer.org/


===============================================
Создание таблицы в базе
===============================================

Имя файла записи разговора будет храниться в базе MySQL (можно также выбрать, например, PostgreSQL).

Для MySQL можно использовать файл импорта "mysql_cdr.sql", можно найти в папке docs. Если импортировать этот файл в базу, то в базе будет создана таблица "cdr" со всем необходимыми для Asterisk полями.
Имя колонки для файла записи звонка будет "filename". Также будут созданы необходимые индексы и триггер, о котором можно прочитать ниже.
В дополнение ко всему, файл импорта создаст новые колонки в базе для Asterisk 12+.
Если имя таблицы "cdr" (или имя колонки для файла записи звонка) не устраивает, после импорта сами сможете переименовать. Например, с помощью PHPMYADMIN или ADMINER.

Если НЕ использовали файл импорта в базу
==
Допустим мы настроили Asterisk для работы с базой и уже создали таблицу, например "cdr". Теперь нам необходимо добавить с нашу таблицу новую колонку, например "filename", в которой будет
имя файла с записью, удобнее это сделать через PHPMYADMIN или ADMINER (смотреть здесь: https://www.adminer.org). Название колонки можно задать в конфиге. / `filename` varchar(255) DEFAULT 'none' /

Более подробно о том, как настроить Asterisk для работы с MySQL можно найти в интернете.


===============================================
Настройка Asterisk
===============================================

Для того, чтобы Asterisk смог взаимодействовать с новыми столбцами в таблице, необходимо в файле cdr_mysql.conf создать их алиасы.
Добавим в конец этого файла ( секция [columns] ) строчки:
alias realdst => realdst
alias remoteip => remoteip
alias start => calldate
alias название_столбца => название_столбца

Вместо "название_столбца" вставьте название столбца, в котором хранится название записи звонка, например "filename".
Алиас "remoteip" нужен для записи IP адреса клиента Asterisk. Это НЕОБЯЗАТЕЛЬНО.


Все изменения производим в extensions.ael, либо в extensions.conf. В зависимости от того, в какой файле у нас написан диалплан.

Если название столбца, в котором хранится название записи звонка у вас отличается от "filename", то необходимо внести соответствующие изменения в диалплан.
Необходимо изменить строку "Set(CDR(filename)=${fname}.mp3);", на "Set(CDR(название_столбца)=${fname}.mp3);"

==
Для extensions.ael, extensions.conf
==

В "globals" добавим пару переменных:
===
// Если 0, запись разговоров отключена
// Если 1, запись разговоров включена с одновременной конвертацией в MP3
// Если 2, запись разговоров включена и выполняется запись в формат WAV. Преобразование в MP3 формат должно быть выполнено скриптом "proc_records.sh"
RECORDING=1;
// Путь к папке с записями разговоров
DIR_RECORDS=/var/calls/;
===

Добавим макрос.
Сразу уточним, что в этом макросе, если RECORDING=1 запись прямо во время разговора конвертируется в MP3. т.е. существует некоторая нагрузка на сервер.
Если же RECORDING=2, то нагрузка на сервер минимальная, т.к. запись выполняется в родной формат Asterisk - WAV. Конвертирование в MP3 должно быть выполнено
с помощью скрипта "proc_records.sh", который можно найти в папке docs. В скрипте написаны подробные комментарии по его настройке

==
Для extensions.ael
==

// MixMonitor
macro recording(calling,called) {
if ("${RECORDING}" = "1") {
Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${calling}-${called});
Set(monopt=nice -n 19 /usr/bin/lame -b 32 --silent "${DIR_RECORDS}${fname}.wav" "${DIR_RECORDS}${fname}.mp3" && rm -f "${DIR_RECORDS}${fname}.wav" && chmod o+r "${DIR_RECORDS}${fname}.mp3");
Set(CDR(filename)=${fname}.mp3);
Set(CDR(realdst)=${called});
Set(CDR(remoteip)=${CHANNEL(recvip)});
MixMonitor(${DIR_RECORDS}${fname}.wav,b,${monopt});
} else if ("${RECORDING}" = "2") {
Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${calling}-${called});
Set(CDR(filename)=${fname}.wav);
Set(CDR(realdst)=${called});
Set(CDR(remoteip)=${CHANNEL(recvip)});
MixMonitor(${DIR_RECORDS}${fname}.wav,b);
}
return;
};

Пример вызова макроса:
context internal {
_X. => {
&recording(${CALLERID(num)},${EXTEN});
Dial(SIP/${EXTEN},60);
Hangup();
};
};

==
Для extensions.conf
==

; MixMonitor
[macro-recording]
exten => s,1,GoToIf($["${RECORDING}" = "1"]?mp3:no)
exten => s,n,GoToIf($["${RECORDING}" = "2"]?wav:no)
exten => s,n(mp3),Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${ARG1}-${ARG2});
exten => s,n,Set(monopt=nice -n 19 /usr/bin/lame -b 32 --silent "${DIR_RECORDS}${fname}.wav" "${DIR_RECORDS}${fname}.mp3" && rm -f "${DIR_RECORDS}${fname}.wav" && chmod o+r "${DIR_RECORDS}${fname}.mp3");
exten => s,n,Set(CDR(filename)=${fname}.mp3);
exten => s,n,Set(CDR(realdst)=${ARG2});
exten => s,n,Set(CDR(remoteip)=${CHANNEL(recvip)});
exten => s,n,MixMonitor(${DIR_RECORDS}${fname}.wav,b,${monopt});
exten => s,n,Goto(no);
exten => s,n(wav),Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${ARG1}-${ARG2});
exten => s,n,Set(CDR(filename)=${fname}.wav);
exten => s,n,Set(CDR(realdst)=${ARG2});
exten => s,n,Set(CDR(remoteip)=${CHANNEL(recvip)});
exten => s,n,MixMonitor(${DIR_RECORDS}${fname}.wav,b);
exten => s,n,Goto(no);
exten => s,n(no),Verbose(Exit record);

Пример вызова макроса:
[internal]
exten => _X.,1,Macro(recording,${CALLERID(num)},${EXTEN})
exten => _X.,n,Dial(SIP/${EXTEN},60)
exten => _X.,n,Hangup()

====
Дополнительно (необязательно). Если НЕ использовали файл импорта в базу "cdr_mysql.sql"
====

В Asterisk если используется макрос, то звонок совершается с экстеншеном s. Чтобы Номер назначения был действительным, а не s или ~~s~~, то сделаем следующее:
Через PHPMYADMIN или ADMINER (смотреть здесь: https://www.adminer.org). В таблицу нужно добавить новое поле "realdst" с типом "varchar" и размером "80". Теперь нужно добавить триггер на таблицу.
Для этого зайдем в Триггеры - Добавить триггер. Назначаем имя триггеру, остальное оставляем без изменений. В поле "Определение" вставляем текст ниже (то, что начинается на // - не вставлять):
//-- Начало --//
BEGIN
IF ((NEW.dst = 's' OR NEW.dst = '~~s~~') AND NEW.realdst != '') THEN
SET NEW.dst = NEW.realdst;
END IF;
END
//-- / Конец --//

Для того, чтобы в поле "realdst" записывался правильный Номер назначения, нужно отредактировать диалплан. Макрос выше в редактировании не нуждается.
В используемом у вас макросе необходимо добавить строчку, это только пример. Задайте правильные имена параметров (${number}, ${ARG1}).
==
Для extensions.ael
==
Set(CDR(realdst)=${number});

==
Для extensions.conf
==
exten => s,n,Set(CDR(realdst)=${ARG1});


===============================================
Настройка папки со звонками
===============================================

Записи разговоров будут складываться в папку "/var/calls/" из примера выше.

Есть два варианта хранения файлов записей.
1. Все записи разговоров хранятся в одной папке.
2. Записи разговоров должны распределяться по папкам в соответствии с датой.

Также есть возможность настройки "отложенной конвертации записей разговоров".
Когда днем выполняется запись в формат WAV, а ночью необходимо по CRON запустить скрипт для преобразования файлов из WAV в MP3.
"Отложенную конвертацию записей разговоров" и распределение по папкам в соответствии с датой можно использовать вместе, а можно что-то одно.

За распределение файлов записей по папкам, преобразование файлов из WAV в MP3 отвечает скрипт "proc_records.sh" из папки docs.

==
Для 2 варианта
==

Каждый день в 00.01 часов записи из папки "/var/calls/" по CRON должны распределяться по дате
в соответствующие папки.

Для распределения файлов по папкам в соответствии с датой нужно использовать скрипт "proc_records.sh" из папки docs.

Формат хранения записей (пример):
1. /var/calls/2014/2014-09/2014-09-29
2. /var/calls/2014/09/29

Настройки скрипта "proc_records.sh" для соответствующего формата:
1.
===
DIR_DST="/var/calls/$Y/$YM/$YMD/"
MOVE_BY_DATE=true
===

2.
===
DIR_DST="/var/calls/$Y/$M/$D/"
MOVE_BY_DATE=true
===

Настройки скрипта "proc_records.sh" для преобразования файлов из WAV в MP3:
--
За включение преобразования файлов из WAV в MP3 в скрипте отвечает переменная "CONV_TO_MP3". Необходимо установить ее значение в true или false.
Также можно настроить уровень вложенности поиска WAV файлов для их преобразования в переменной "DEPTH". Примеры значений для переменной
1 - это все файлы в папке /var/calls/
2 - это все файлы в /var/calls/, /var/calls/2017/ ...
3 - это все файлы в /var/calls/, /var/calls/2017/, /var/calls/2017/04 ...
...

==
Для вариантов, когда Asterisk сам распределяет записи по папкам в соответствии с датой.
==

Если у вас Asterisk сам распределяет записи звонков по папкам в соответствии с датой, тогда необходимости запуска скрипта по CRON нет.
Если только у вас не настроена "отложенная конвертация записей разговоров"

Возможные форматы хранения записей:
1. /var/calls/2014/2014-09/2014-09-29
2. /var/calls/2014/09/29


===============================================
Удаление старых записей звонков
===============================================

Для удаления старых записей звонков нужно использовать скрипт "proc_records.sh" из папки docs. В нем есть подробные комментарии по настройке.
Можно удалять только старые записи звонков, но будут оставаться пустые папки. Можно включить удаление пустых папок, тогда все пустые папки в директории,
которая задана в "DIR_SOURCE" будут удалены.

Чтобы все работало, для начала нужно определиться с форматом хранения записей звонков и правильно зададь значение переменной "DEPTH".
Если все файлы хранятся в одной папке, то значение переменной можно установить в "DEPTH=1". Если записи звонков распределяются по папкам в соответствии с датой, то
значение переменной можно установить в "DEPTH=3". Более подробно смотреть комментарии в скрипте.

Чтобы включить удаление старых записей звонков, в скрипте следует задать:
===
CLEAN_OLD=true
===

В переменной "CLEAN_OLD_AFTER" задается количество дней хранения файлов записей звонков. Например: Если задано "CLEAN_OLD_AFTER=365", то все файлы, старше 365 дней будут удалены.
Берется время изменения файла, расширение файла при удалении НЕ учитывается. Т.е. если в папке, например, есть "*.txt" файл старше этого срока, он также будет удален.

В переменной "CLEAN_OLD_EMPTYDIR" можно включить удаление пустых папок. Чтобы это включить, в скрипте следует задать:
===
CLEAN_OLD_EMPTYDIR=true
===

===============================================
Настройка
===============================================

Пример конфиг файла находится в "inc/config/config.php.sample". Перед началом использования этот файл нужно переименовать в "config.php".

Все настройки находятся в файле "inc/config/config.php" с подробными комментариями, тут не должно возникнуть сложностей.

Можно использовать "пользовательский" конфиг. Это значит, что будет использоваться альтернативный конфиг файл с настройками.
Для этого нужно создать еще один файл с конфигом, например: "inc/config/config-anotherconfig.php". Формат имени файла конфига: config-[уникальное_имя_конфига].php
Чтобы использовать созданный "пользовательский" конфиг - config-anotherconfig.php, нужно к адресу сайта с установленным скриптом (Например: http://example.com/cdr/index.php) добавить параметр ?config=anotherconfig.
Получается адрес: http://example.com/cdr/index.php?config=anotherconfig

===

Кратко:
1. Скачать ZIP архив с GitHub или выполнить git clone https://github.com/prog-it/Asterisk-CDR-Viewer-Mod.git
2. Распаковать или Перенести файлы в нужную папку на сервере
3. Переименовать файл "inc/config/config.php.sample" в "config.php". Т.е. будет файл "inc/config/config.php"
4. Настроить параметры в "inc/config/config.php"
5. Почти готово. Если необходим доступ только для определенных пользователей, то необходимо создать файл .htpasswd.

Создание .htpasswd файла
===
htpasswd -c /path/to/.htpasswd admin
===

Пример конфига для Nginx:
===
location /path/to/script {
auth_basic "CDR Viewer Mod";
auth_basic_user_file /path/to/.htpasswd;
}
===

Пример конфига для Apache:
===
<Location "/path/to/script">
AuthName "CDR Viewer Mod"
AuthType Basic
AuthUserFile /path/to/.htpasswd
require valid-user
</Location>
===

5. Прописать в конфиге скрипта имена пользователей в виде массива, которым разрешен доступ
===
'admins' => array(
'admin1',
'admin2',
'admin3',
),
===

Если массив пустой, то разрешен доступ всем пользователям
===
'admins' => array(

),
===


===============================================
Настройка тарифов на звонки
===============================================

Тарифы на звонки задаются в файле "my_callrates.csv" (inc/plugins/my_callrates.csv). Путь к этому файлу можно изменить в конфиге.

Формат задания тарифы в CSV файле:
Код_региона,стоимость_минуты[,Направление,Тип_тарификации,Доп_тариф]

-- То, что в фигурных скобках - необязательно

Пример для Мегафона, с поминутной тарификацией, стоимость первой минуты 90 коп., после первой минуты 10 коп (доп. тариф).
===
8922,0.90,Мегафон,m,0.10
===

Типы тарификации:
s - посекундно (нет доп. тарифа)
m - поминутно (есть доп. тариф)
c - за весь звонок (нет доп. тарифа)
1m+s - посекундно со 2 минуты (есть доп. тариф)
30s+s - посекундно после 30 секунды
30s+6s - округление интервалами до 6 сек. по истечении первых 30 сек. разговора (Skype Connect)

===============================================

Остальное можно прочитать с файле "Старый Readme.txt"


[Показать] Спойлер: extensions.conf
[general]
static=yes
writeprotect=yes

[globals]

RECORDING=1
DIR_RECORDS=/records/callrecords/

[default]

[outcoling]
exten => _X.,1,Macro(recording,${CALLERID(num)},${EXTEN})
exten => _x.,2, answer()
exten => _xxxx,3,Dial(SIP/${EXTEN},,t&m)
exten => _8xxxxxxxxxx,3,Dial(SIP/ntel/${EXTEN})
exten => _7xxxxxxxxxx,3,Dial(SIP/zadarma/${EXTEN})
exten => 700,3,Goto(menu,s,1) ;если мы изнутри позвоним на этот номер, то мы сможем проверить работу нашего голосового меню.
exten => _x.,n,hangup()

[incoming]
exten => _X.,1,Macro(recording,${CALLERID(num)},${EXTEN})
;exten => _x.,1,Set(fname=${STRFTIME(${EPOCH},,%Y%m%d%H%M)}-${CALLERID(number)}-${EXTEN})
;exten => _x.,2,MixMonitor(/records/callrecords/${fname}.wav)
exten => _x.,n,Answer()
exten => _x.,n,Goto(menu,s,1) ;если мы изнутри позвоним на этот номер, то мы сможем проверить работу нашего голосового меню. Благодаря этой строчки нет необходимости для проверки звонить постоянно с внешки
;exten => _x.4,1,dial(SIP/1207,5,t&m)
;exten => _x,5,Goto(autoanswer,s,1) ;перевод на автоответчик
exten => _x.,n,hangup()

[menu]
exten => s,1,Background(/var/lib/asterisk/moh/voicemail/sagamenu2) ;здесь ловится звонок из контекста incoming и проигрывается записанное нами приветствие.
exten => 1,1,Dial(SIP/1103&SIP/1108&SIP/1113&SIP/1209&SIP/1210&SIP/1110&SIP/1218&SIP/1115&SIP/1206&SIP/1227&SIP/1122&SIP/1126,,Tt&m) ; 1 нажал, в отдел продаж попал
exten => 2,1,Dial(SIP/1203&SIP/1208&SIP/1202&SIP/1205&SIP/1200&SIP/1229&SIP/1204,,Tt&m) ; 2 нажал, в бухгалтерию попал
exten => 3,1,Dial(SIP/1105&SIP/1215&SIP/1109,,Tt&m) ; 3 нажал, в логистику и закупки попал
exten => 4,1,Dial(SIP/1114,,t&m) ; 4 нажал, к юристу попал
exten => 5,1,Dial(SIP/1101&SIP/1118&SIP/1223,,Tt&m) ; 5 нажал, в фин.отдел попал
exten => 6,1,Dial(SIP/1207,,Tt&m) 6 нажал, в IT-отдел попал
;exten => 9,1,Dial(SIP/,,Tt&m) ; 9 нажал, на факс попал
exten => 0,1,Dial(SIP/1102&SIP/1101,,Tt&m) ; 0 нажал, на секретаря попал
exten => _XXXX,1,Dial(SIP/${EXTEN},,Tt&m) ; набор трехзначного внутреннего номера
exten => s,2,WaitExten(7) ;если человек не нажал ничего, ждем 5 секунд и
exten => s,3,Dial(SIP/1102&SIP/1207,20,Tt&m) ; переводим на секретаря, ожидание 20 сек
exten => s,n,Hangup()
;exten => s,n,Goto(autoanswer,s,1) ;перевод на автоответчик

[autoanswer]
exten => s,1,Background(/var/lib/asterisk/moh/voicebox/avtootvet) ;проигрывается наше записанное приветствие.
exten => s,2,Set(fname=${STRFTIME(${EPOCH},,%Y%m%d%H%M)}-${CALLERID(number)}-${EXTEN}) ;определяется имя файла (fname)
exten => s,3,Record(/records/voicemail/${fname}.wav,0,,X) ;теперь записывается сам файл после бип...
exten => s,n,WaitExten(15)
exten => #,n,Hangup
exten => s,n,Hangup ;кладем трубку

[messages]
exten => _XXX,1,MessageSend(sip:${EXTEN},"${CALLERID(name)}"${MESSAGE(from)})

[macro-recording]
exten => s,1,GoToIf($["${RECORDING}" = "1"]?mp3:no)
exten => s,n,GoToIf($["${RECORDING}" = "2"]?wav:no)
exten => s,n(mp3),Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${ARG1}-${ARG2});
exten => s,n,Set(monopt=nice -n 19 /usr/bin/lame -b 32 --silent "${DIR_RECORDS}${fname}.wav" "${DIR_RECORDS}${fname}.mp3" && rm -f "${DIR_RECORDS}${fname}.wav" && chmod o+r "${DIR_RECORDS}${fname}.mp3");
exten => s,n,Set(CDR(filename)=${fname}.mp3);
exten => s,n,Set(CDR(realdst)=${ARG2});
exten => s,n,Set(CDR(remoteip)=${CHANNEL(recvip)});
exten => s,n,MixMonitor(${DIR_RECORDS}${fname}.wav,b,${monopt});
exten => s,n,Goto(no);
exten => s,n(wav),Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${ARG1}-${ARG2});
exten => s,n,Set(CDR(filename)=${fname}.wav);
exten => s,n,Set(CDR(realdst)=${ARG2});
exten => s,n,Set(CDR(remoteip)=${CHANNEL(recvip)});
exten => s,n,MixMonitor(${DIR_RECORDS}${fname}.wav,b);
exten => s,n,Goto(no);
exten => s,n(no),Verbose(Exit record);


[Показать] Спойлер: cdr_mysql.conf
[global]
hostname=localhost
dbname=asterisk
table=cdr
password=***
user=asterisk
;port=3306
;sock=/tmp/mysql.sock

[columns]
static "<value>" => <column>
alias <cdrvar> => <column>

alias start => calldate
alias realdst => realdst
;alias remoteip => remoteip
alias filename => filename

alias clid => <a_field_not_named_clid>
alias src => <a_field_not_named_src>
alias dst => <a_field_not_named_dst>
alias dcontext => <a_field_not_named_dcontext>
alias channel => <a_field_not_named_channel>
alias dstchannel => <a_field_not_named_dstchannel>
alias lastapp => <a_field_not_named_lastapp>
alias lastdata => <a_field_not_named_lastdata>
alias duration => <a_field_not_named_duration>
alias billsec => <a_field_not_named_billsec>
alias disposition => <a_field_not_named_disposition>
alias amaflags => <a_field_not_named_amaflags>
alias accountcode => <a_field_not_named_accountcode>
alias userfield => <a_field_not_named_userfield>
alias uniqueid => <a_field_not_named_uniqueid>


[Показать] Спойлер: mysql>
cdrtable.JPG

mysql> mysql> select filename from cdr;
+----------+
| filename |
+----------+
| none |
| none |
| none |
| none |
| none |
+----------+

mysql> describe cdr;
+-------------+--------------+------+-----+---------------------+---------------
| Field | Type | Null | Key | Default | Extra
+-------------+--------------+------+-----+---------------------+---------------
| id | int(10) | NO | PRI | NULL | auto_increment
| calldate | datetime | NO | MUL | 0000-00-00 00:00:00 |
| clid | varchar(80) | NO | MUL | |
| src | varchar(80) | NO | MUL | |
| dst | varchar(80) | NO | MUL | |
| realdst | varchar(80) | NO | | |
| dcontext | varchar(80) | NO | MUL | |
| channel | varchar(80) | NO | | |
| dstchannel | varchar(80) | NO | | |
| lastapp | varchar(80) | NO | | |
| lastdata | varchar(80) | NO | | |
| duration | int(11) | NO | | 0 |
| billsec | int(11) | NO | | 0 |
| disposition | varchar(45) | NO | | |
| amaflags | int(11) | NO | | 0 |
| remoteip | varchar(60) | NO | | |
| accountcode | varchar(20) | NO | MUL | |
| peeraccount | varchar(20) | NO | | |
| uniqueid | varchar(32) | NO | MUL | |
| userfield | varchar(255) | NO | | |
| did | varchar(50) | NO | MUL | |
| linkedid | varchar(32) | NO | | |
| sequence | int(11) | NO | | 0 |
| filename | varchar(255) | YES | | none |
+-------------+--------------+------+-----+---------------------+----


www
[Показать] Спойлер: www/html/cdr/inc/config.php
//Mysql
$db_type = 'mysql';
$db_host = 'localhost';
$db_port = '3306';
$db_user = '****';
$db_pass = '****';
$db_name = 'asterisk';
$db_table_name = 'cdr';
$db_options = array();
// $db_options = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8");
// Если др. значение, то все записи хранятся в одной папке (/var/calls)
$system_storage_format = '1';
// Папка, где находятся записи Asterisk
$system_monitor_dir = '/records/callrecords'; // без слеша на конце
// Формат аудио, в котором записываются записи звонков
// Плеер не воспроизводит WAV формат!
$system_audio_format = 'mp3';



[Показать] Спойлер: www/html/cdr/inc/config/config.php
<?php

return array(
### Подключение к базе данных
'db' => array(
# Тип базы, который поддерживается PDO. Например: mysql, pgsql
'type' => 'mysql',
# Хост
'host' => 'localhost',
# Порт
'port' => '3306',
# Пользователь
'user' => '***',
# Имя базы
'name' => 'asterisk',
# Пароль
'pass' => '****',
# Название таблицы
'table' => 'cdr',
# Доп. опции подключения
'options' => array(
//PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
),
),

### Системное
'system' => array(
## Название столбца в БД, в котором хранится название записи звонка
'column_name' => 'filename',

## Путь к папке для временных файлов
'tmp_dir' => '/tmp',

## Путь к папке, где находятся записи Asterisk. БЕЗ слеша на конце
'monitor_dir' => '/records/callrecords',

### Формат хранения файлов записей Asterisk
## Если 1, то файлы записей должны распределяться скриптом по папкам в соответствии с датой "/var/calls/2015/2015-01/2015-01-01".
# Записи за сегодня находятся в "/var/calls", записи за прошедшие даты в папках в соответствии с датой "/var/calls/2015/2015-01/2015-01-01"

## Если 2, то файлы записей должны распределяться скриптом по папкам в соответствии с датой "/var/calls/2015/12/01".
# Записи за сегодня находятся в "/var/calls", записи за прошедшие даты в папках в соответствии с датой "/var/calls/2015/12/01"

## Если 3, то файлы записей должны распределяться по папкам Asterisk-ом в соответствии с датой "/var/calls/2015/2015-01/2015-01-01".
# Записи за все даты находятся в папках в соответствии с датой "/var/calls/2015/2015-01/2015-01-01"

## Если 4, то файлы записей должны распределяться по папкам Asterisk-ом в соответствии с датой "/var/calls/2015/12/01".
# Записи за все даты находятся в папках в соответствии с датой "/var/calls/2015/12/01"

## Если др. значение, то все записи хранятся в одной папке "/var/calls"
'storage_format' => 8,

## Размер файла в Килобайтах, больше которого считается, что файл существует
'fsize_exists' => 10,

## Формат аудио, в котором записываются записи звонков
# Плеер не воспроизводит WAV в Enternet Explorer. В последних версиях Firefox и Chrome все работает
# Например: mp3, wav
'audio_format' => 'mp3',

## Отложенная конвертация записей звонков. Полезно для снижения нагрузки на сервер
# В этом режиме Asterisk должен записывать записи звонков в WAV, затем каждый день в 00.01 часов файлы из WAV должны быть конвертированы в MP3 с помощью скрипта (см. в папке docs + Readme.txt)
# Файлы за сегодняшний день хранятся в WAV, за прошедшие дни в MP3. В "audio_format" должно быть задано: mp3. В базу в поле 'filename' будет записано имя файла с расширением wav (имя_файла.wav)
# Если 0 - выключить, 1 - включить
'audio_defconv' => 1,

## Если записи звонков / факсов через некоторое время архивируются, раскомментировать строку ниже и указать формат архива (zip gz rar bz2 и т.д.)
# Имя архива должно быть "имя_файла.mp3.zip". Т.е. к имени файла из базы должно быть добавлено расширение архива, например: zip
//'archive_format' => 'zip',

## Разделитель в CSV файле отчета
# Обычно используется запятая ",". Но по умолчанию в Microsoft Office для русского языка установлен разделитель точка с запятой ";"
'csv_delim' => ';',

## Имена пользователей, которым разрешен доступ к сайту. Работает, только если настроена Basic-Auth аутентификация (htpasswd файл) на веб-сервере
# Добавлять имена пользователей в виде массива. Например: 'admins' => array( 'admin1', 'admin2', 'admin3' );
# Если массив пустой, то разрешено всем. Т.е. если задано: 'admins' => array( );
'admins' => array(

),

## Используемые плагины
# Если плагин не нужен, закомментировать соответствующую строку
# Название плагина => имя файла
'plugins' => array(
'Расход средств' => 'my_callrates',
),
),

### Тарифы на звонки
'callrate' => array(
## Включение / Отключение функционала подсчета тарифов. Если отключено, то будет работать немного быстрее при большом количестве записей в выводе
# Если 0 - выключить, 1 - включить
'enabled' => 1,

## Нетарифицируемый интервал в секундах
'free_interval' => 3,

## Путь к CSV файлу с тарифами
# Задается для расчета тарифов при поиске в базе и плагина
'csv_file' => 'inc/plugins/my_callrates.csv',

## Название валюты, которая используется при тарификации
# Например: Будет показано не "1.29", а "1.29 название_валюты"
'currency' => '',
),

### Отображение
'display' => array(
'lookup' => array(
## URL сервиса информации о номере
# Где "%n" будет заменено на номер телефона
'url' => 'https://zvonok.octo.net/number.aspx/' . '%n',

## Минимальная длина номера, для которого будет подставлен URL с инфо о номере
'num_length' => 7,
),

'main' => array(
## Количество записей для показа на странице по умолчанию
'result_limit' => 100,
## Количество показанных записей, после которых снова будет показана шапка (Дата, Статус...)
'header_step' => 30,

### Если 0 - выключить, 1 - включить
## Показ без дублирующихся записей в Asterisk 13 и выше
'duphide' => 1,

## Показ кнопки - Воспроизведение записи звонка
'rec_play' => 1,

## Показ кнопки - Удаление записи звонка
'rec_delete' => 1,

## Возможность редактировать поле "Комментарий" (userfield)
'userfield_edit' => 1,

## Показ контекстного пункта меню - Удаление строки из базы
'entry_delete' => 1,

## Показать Вх. / Исх. канал полностью
# В колонках Вх. / Исх. канал, Например, вместо "SIP" будет показано "SIP/123"
'full_channel' => 1,

## Показать при наведении на "Вх. / Исх. канал", канал полностью с его ID
# При наведении на колонки Вх. / Исх. канал, во всплывающей подсказке, Например, вместо "SIP" или "SIP/100" будет показано "SIP/123-00000025"
'full_channel_tooltip' => 0,
),

### Включение / Отключение показа фильтров поиска
# Если 0 - всегда скрывать, 1 - всегда показывать, 2 - показать при нажатии на кнопку "Дополнительные фильтры"
'search' => array(
## Кто звонил
'src' => 1,
## Куда звонили
'dst' => 1,
## Статус звонка
'disposition' => 1,
## Длительность
'duration' => 2,
## Входящий канал
'channel' => 2,
## Имя звонящего
'clid' => 1,
## DID (Внешний номер)
'did' => 2,
## Исходящий канал
'dstchannel' => 2,
## Код аккаунта
'accountcode' => 0,
## Комментарий (userfield)
'userfield' => 2,
## Приложение
'lastapp' => 2,
## Параллельные звонки
'chart_cc' => 2,
## ASR и ACD (Коэффициент отвеченных вызовов / Средняя продолжительность вызова)
'asr_report' => 0,
## CSV файл
'csv' => 2,
## График звонков
'chart' => 2,
## Расход минут
'minutes_report' => 1,
),

### Включение / Отключение показа некоторых колонок
# Если 0 - скрыть, 1 - показать
'column' => array(
## DID
'did' => 0,
## CallerID
'clid' => 1,
## Аккаунт
'accountcode' => 0,
## Тариф
'callrates' => 1,
## Направление звонка
'callrates_dst' => 0,
## Входящий канал
'channel' => 1,
## Исходящий канал
'dstchannel' => 1,
## Приложение
'lastapp' => 1,
## Файл
'file' => 1,
## Комментарий (userfield)
'userfield' => 1,
),
),

### Параметры сайта
'site' => array(
'main' => array(
## Meta - Title
'title' => 'Детализация звонков',

## Meta - Description
'desc' => 'Детализация звонков',

## Meta - Robots
'robots' => 'noindex, nofollow',

## Текст в шапке
'head' => 'Детализация звонков',

## Путь к изображению с вашим логотипом, которое будет показано в шапке вместо текста
# Если нужно оставить текст, то закомментировать строку ниже или задать значение ''
//'logo_path' => 'img/example_logo.png',

## Путь к основному разделу сайта
# Чтобы стрелка (рядом с текстом или логотипом в шапке) не показывалась, закомментировать строку ниже или задать значение ''
'main_section' => '../',
),

'js' => array(
## Автовоспроизведение записи звонка. Если 0 - выключить, 1 - включить
'player_autoplay' => 1,

## Показ даты записи звонка над плеером. Если 0 - скрыть, 1 - показать
'player_title' => 1,

## Символ, который будет добавлен в Meta - Title страницы во время воспроизведения записи звонка
'player_symbol' => '&#9835;&#9835;&#9835;',

## Показ стрелок для быстрой навигации справа. Если 0 - скрыть, 1 - показать
'scroll_show' => 1,
),
),

### CDN
# Пути к некоторым CSS и JS файлам. Можно указать URL и загружать, например, jQuery с Google CDN
'cdn' => array(
'css' => array(
## Tooltips
'tooltips' => 'img/simptip.min.css',
## jQuery contextMenu
'jquery_contextmenu' => 'img/jquery-contextmenu/jquery.contextMenu.min.css',
),

'js' => array(
## Плеер
'player' => 'img/player.js',
## Скин для плеера
'player_skin' => 'img/player_skin.js',
## jQuery
'jquery' => 'img/jquery.min.js',
## jQuery query object
'jquery_object' => 'img/jquery.query-object.min.js',
## Clipboard JS
'clipboard_js' => 'img/clipboard.min.js',
## jQuery contextMenu
'jquery_contextmenu' => 'img/jquery-contextmenu/jquery.contextMenu.min.js',
## jQuery UI position
'jquery_ui_position' => 'img/jquery-contextmenu/jquery.ui.position.min.js',
),
),


);


Может быть ответ на поверхности, но голова уже вскипела за несколько дней разбора полетов и взгляд замылен.
Надеюсь на вашу лояльность и хороший пинок в правильном направлении (лучше в виде ссылки :) )
Аватар пользователя
Elektronik
 
Сообщений: 56
Зарегистрирован: 16 окт 2017, 13:42
Откуда: Москва

Re: Asterisk CDR Viewer Mod, в mysql не попадает filename

Сообщение awsswa » 20 окт 2017, 16:28

не соответствие директории для поиска файлов и самого расположения файлов
покажите запись из базы mysql с именем файла
и из настроек программы - каталог где должен осуществляться поиск
платный суппорт по мере возможностей
awsswa
 
Сообщений: 2390
Зарегистрирован: 09 июн 2012, 10:52
Откуда: Россия, Пермь skype: yarick_perm

Re: Asterisk CDR Viewer Mod, в mysql не попадает filename

Сообщение Elektronik » 20 окт 2017, 16:50

То что не соответствует я понимаю, вот только где...
Скорее не соответствие
Немного не понял вас, что именно показать, вроде в 1 посте эта инфа есть. Сейчас продублирую.
в конфигах указанно, что имя файла сохраняется в переменную filename. по умолчанию сохранение было в /var/calls/, но у меня сохраннение идет по другому пути, /records/callrecords/
в базу имя файла не попадает, собственно в этом и был вопрос:
mysql> select filename from cdr;
+----------+
| filename |
+----------+
| none |
| none |
| none |
| none |
| none |
| none |
| none |
+----------+
в шапке темы я указал скрин с phpmyadmin, что бы было читабельней смотреть таблицу, потому что если я переношу копипаст с консоли (mysql>, он получается мягко-говоря кривоватый.

и третье предложение совсем не понял. из настроек какой программы?
если это конфиг Asterisk CDR Viewer Mod, тогда в файле
[Показать] Спойлер: www/html/cdr/inc/config.php
// $db_options = array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8");
// Если др. значение, то все записи хранятся в одной папке (/var/calls)
$system_storage_format = '1';
// Папка, где находятся записи Asterisk
$system_monitor_dir = '/records/callrecords'; // без слеша на конце

и в
[Показать] Спойлер: www/html/cdr/inc/config/config.php
### Системное
'system' => array(
## Название столбца в БД, в котором хранится название записи звонка
'column_name' => 'filename',

## Путь к папке для временных файлов
'tmp_dir' => '/tmp',

## Путь к папке, где находятся записи Asterisk. БЕЗ слеша на конце
'monitor_dir' => '/records/callrecords',

### Формат хранения файлов записей Asterisk
## Если 1, то файлы записей должны распределяться скриптом по папкам в соответствии с датой "/var/calls/2015/2015-01/2015-01-01".
# Записи за сегодня находятся в "/var/calls", записи за прошедшие даты в папках в соответствии с датой "/var/calls/2015/2015-01/2015-01-01"

## Если 2, то файлы записей должны распределяться скриптом по папкам в соответствии с датой "/var/calls/2015/12/01".
# Записи за сегодня находятся в "/var/calls", записи за прошедшие даты в папках в соответствии с датой "/var/calls/2015/12/01"

## Если 3, то файлы записей должны распределяться по папкам Asterisk-ом в соответствии с датой "/var/calls/2015/2015-01/2015-01-01".
# Записи за все даты находятся в папках в соответствии с датой "/var/calls/2015/2015-01/2015-01-01"

## Если 4, то файлы записей должны распределяться по папкам Asterisk-ом в соответствии с датой "/var/calls/2015/12/01".
# Записи за все даты находятся в папках в соответствии с датой "/var/calls/2015/12/01"

## Если др. значение, то все записи хранятся в одной папке "/var/calls"
'storage_format' => 8,

## Размер файла в Килобайтах, больше которого считается, что файл существует
'fsize_exists' => 10,

## Формат аудио, в котором записываются записи звонков
# Плеер не воспроизводит WAV в Enternet Explorer. В последних версиях Firefox и Chrome все работает
# Например: mp3, wav
'audio_format' => 'mp3',

## Отложенная конвертация записей звонков. Полезно для снижения нагрузки на сервер
# В этом режиме Asterisk должен записывать записи звонков в WAV, затем каждый день в 00.01 часов файлы из WAV должны быть конвертированы в MP3 с помощью скрипта (см. в папке docs + Readme.txt)
# Файлы за сегодняшний день хранятся в WAV, за прошедшие дни в MP3. В "audio_format" должно быть задано: mp3. В базу в поле 'filename' будет записано имя файла с расширением wav (имя_файла.wav)
# Если 0 - выключить, 1 - включить
'audio_defconv' => 1,

## Если записи звонков / факсов через некоторое время архивируются, раскомментировать строку ниже и указать формат архива (zip gz rar bz2 и т.д.)
# Имя архива должно быть "имя_файла.mp3.zip". Т.е. к имени файла из базы должно быть добавлено расширение архива, например: zip
//'archive_format' => 'zip',

## Разделитель в CSV файле отчета
# Обычно используется запятая ",". Но по умолчанию в Microsoft Office для русского языка установлен разделитель точка с запятой ";"
'csv_delim' => ';',

## Имена пользователей, которым разрешен доступ к сайту. Работает, только если настроена Basic-Auth аутентификация (htpasswd файл) на веб-сервере
# Добавлять имена пользователей в виде массива. Например: 'admins' => array( 'admin1', 'admin2', 'admin3' );
# Если массив пустой, то разрешено всем. Т.е. если задано: 'admins' => array( );
'admins' => array(

),


а переменная filename берется и делается в диалплане в макросе
[Показать] Спойлер:
[macro-recording]
exten => s,1,GoToIf($["${RECORDING}" = "1"]?mp3:no)
exten => s,n,GoToIf($["${RECORDING}" = "2"]?wav:no)
exten => s,n(mp3),Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${ARG1}-${ARG2});
exten => s,n,Set(monopt=nice -n 19 /usr/bin/lame -b 32 --silent "${DIR_RECORDS}${fname}.wav" "${DIR_RECORDS$
exten => s,n,Set(CDR(filename)=${fname}.mp3);
exten => s,n,Set(CDR(realdst)=${ARG2});
exten => s,n,Set(CDR(remoteip)=${CHANNEL(recvip)});
exten => s,n,MixMonitor(${DIR_RECORDS}${fname}.wav,b,${monopt});
exten => s,n,Goto(no);
exten => s,n(wav),Set(fname=${UNIQUEID}-${STRFTIME(${EPOCH},,%Y-%m-%d-%H_%M)}-${ARG1}-${ARG2});
exten => s,n,Set(CDR(filename)=${fname}.wav);
exten => s,n,Set(CDR(realdst)=${ARG2});
exten => s,n,Set(CDR(remoteip)=${CHANNEL(recvip)});
exten => s,n,MixMonitor(${DIR_RECORDS}${fname}.wav,b);
exten => s,n,Goto(no);
exten => s,n(no),Verbose(Exit record);


На самом деле, думаю, что я не понял ваших 2х вопросов. надеюсь ответил правильно, но сомневаюсь :(
Аватар пользователя
Elektronik
 
Сообщений: 56
Зарегистрирован: 16 окт 2017, 13:42
Откуда: Москва

Re: Asterisk CDR Viewer Mod, в mysql не попадает filename

Сообщение fecyt » 20 окт 2017, 17:00

Я ставил для тестов Asterisk CDR Viewer Mod v2.6.0. Менял только маршрут до .wav файла. Все отображается ок.
В базе у вас в поле disposition пишется 8, вот она у вас и отображается в состоянии. А файлы чувствительны к регистру, что в конце стоит .WAV или .wav? первый вариант не прочтется.
fecyt
 
Сообщений: 148
Зарегистрирован: 17 янв 2017, 18:51

Re: Asterisk CDR Viewer Mod, в mysql не попадает filename

Сообщение fecyt » 20 окт 2017, 17:10

И кстати, filename=uniqueid. Так, что в mysql он попадает. С этим все ок. Скорее всего или файл называете некорректно, или маршрут до него неправильный.
fecyt
 
Сообщений: 148
Зарегистрирован: 17 янв 2017, 18:51

Re: Asterisk CDR Viewer Mod, в mysql не попадает filename

Сообщение Elektronik » 20 окт 2017, 17:38

fecyt писал(а):И кстати, filename=uniqueid. Так, что в mysql он попадает. С этим все ок. Скорее всего или файл называете некорректно, или маршрут до него неправильный.

в базу все попадает, но имя файла попадает пустое. Значит оно берется из какого то не того значения и записывается пустое в filename.
из лога видно, что файл "/records/callrecords/1508497625.7 -2017-10-20-14_07-1207-89151276136.mp3" создается и кладется в нужную папку, он действительно туда кладется, только в не до конца нужную (должна создаваться папка (/records/callrecords/2017/10/20/filename.mp3)), как указано в конфиге www/html/cdr/inc/config/config.php, но опять же, как говорил выше, я не понимаю, как из этого файла астериск должен читать переменные, если они даже где то указанны, хотя я не нашел где...:(

мои ответы могут быть немного сумбурными, отрывками, прошу простить если что, вторую неделю ищу решение, копаюсь в конфигах, пытаюсь понять...или бошка взорвется или придется поставить чистый Asterisk CDR Viewer и допиливать самому. это если я совсем сдамся...

сам файл пишется, вручную если зайти в папку слушается.
[Показать] Спойлер: запись файла
== Using SIP RTP CoS mark 5
-- Executing [89151276136@outcoling:1] Macro("SIP/1207-00000004", "recording,1207,89151276136") in new stack
-- Executing [s@macro-recording:1] GotoIf("SIP/1207-00000004", "1?mp3:no") in new stack
-- Goto (macro-recording,s,3)
-- Executing [s@macro-recording:3] Set("SIP/1207-00000004", "fname=1508497625.7-2017-10-20-14_07-1207-8915127613 6") in new stack
-- Executing [s@macro-recording:4] Set("SIP/1207-00000004", "monopt=nice -n 19 /usr/bin/lame -b 32 --silent "/re cords/callrecords/1508497625.7-2017-10-20-14_07-1207-89151276136.wav" "/records/callrecords/1508497625.7-2017-10-20- 14_07-1207-89151276136.mp3" && rm -f "/records/callrecords/1508497625.7-2017-10-20-14_07-1207-89151276136.wav" && ch mod o+r "/records/callrecords/1508497625.7-2017-10-20-14_07-1207-89151276136.mp3"") in new stack
-- Executing [s@macro-recording:5] Set("SIP/1207-00000004", "CDR(filename)=1508497625.7-2017-10-20-14_07-1207-89 151276136.mp3") in new stack
-- Executing [s@macro-recording:6] Set("SIP/1207-00000004", "CDR(realdst)=89151276136") in new stack
-- Executing [s@macro-recording:7] Set("SIP/1207-00000004", "CDR(remoteip)=10.0.0.119") in new stack
-- Executing [s@macro-recording:8] MixMonitor("SIP/1207-00000004", "/records/callrecords/1508497625.7-2017-10-20 -14_07-1207-89151276136.wav,b,nice -n 19 /usr/bin/lame -b 32 --silent "/records/callrecords/1508497625.7-2017-10-20- 14_07-1207-89151276136.wav" "/records/callrecords/1508497625.7-2017-10-20-14_07-1207-89151276136.mp3" && rm -f "/rec ords/callrecords/1508497625.7-2017-10-20-14_07-1207-89151276136.wav" && chmod o+r "/records/callrecords/1508497625.7 -2017-10-20-14_07-1207-89151276136.mp3"") in new stack
-- Executing [s@macro-recording:9] Goto("SIP/1207-00000004", "no") in new stack
-- Goto (macro-recording,s,16)
-- Executing [s@macro-recording:16] Verbose("SIP/1207-00000004", "Exit record") in new stack
Exit record
-- Executing [89151276136@outcoling:2] Answer("SIP/1207-00000004", "") in new stack
== Begin MixMonitor Recording SIP/1207-00000004
> 0x7fe2101fb350 -- Probation passed - setting RTP source address to 10.0.0.119:5062
-- Executing [89151276136@outcoling:3] Dial("SIP/1207-00000004", "SIP/ntel/89151276136") in new stack
== Using SIP RTP CoS mark 5
-- Called SIP/ntel/89151276136
-- SIP/ntel-00000005 is making progress passing it to SIP/1207-00000004
> 0x1c20950 -- Probation passed - setting RTP source address to 109.71.241.71:14026
-- SIP/ntel-00000005 is ringing
-- SIP/ntel-00000005 answered SIP/1207-00000004
-- Channel SIP/ntel-00000005 joined 'simple_bridge' basic-bridge <e4e96259-ca9a-4502-86ad-5d967d9443b3>
-- Channel SIP/1207-00000004 joined 'simple_bridge' basic-bridge <e4e96259-ca9a-4502-86ad-5d967d9443b3>
-- Channel SIP/1207-00000004 left 'simple_bridge' basic-bridge <e4e96259-ca9a-4502-86ad-5d967d9443b3>
== Spawn extension (outcoling, 89151276136, 3) exited non-zero on 'SIP/1207-00000004'
== MixMonitor close filestream (mixed)
== Executing [nice -n 19 /usr/bin/lame -b 32 --silent "/records/callrecords/1508497625.7-2017-10-20-14_07-1207-891 51276136.wav" "/records/callrecords/1508497625.7-2017-10-20-14_07-1207-89151276136.mp3" && rm -f "/records/callrecor ds/1508497625.7-2017-10-20-14_07-1207-89151276136.wav" && chmod o+r "/records/callrecords/1508497625.7-2017-10-20-14 _07-1207-89151276136.mp3"]
-- Channel SIP/ntel-00000005 left 'simple_bridge' basic-bridge <e4e96259-ca9a-4502-86ad-5d967d9443b3>
== End MixMonitor Recording SIP/1207-00000004


fecyt писал(а):Я ставил для тестов Asterisk CDR Viewer Mod v2.6.0. Менял только маршрут до .wav файла. Все отображается ок.
В базе у вас в поле disposition пишется 8, вот она у вас и отображается в состоянии. А файлы чувствительны к регистру, что в конце стоит .WAV или .wav? первый вариант не прочтется.


макрос из ридми я копировал без изменений, там и не надо ничего меня, режим указывается в глобалс. по поводу диспозишен не понял. в базе не указанно, оно попадает в базу (не только 8, были и другие значения, я просто удалял таблицу и создал новую из файла docs/mysql_sdr.sql, когда в очередной раз устал искать что я не так натворил ).
wav я тоже нигде не менял, вроде только пути и значения в конфиге.

[Показать] Спойлер: создание таблицы ниже
CREATE TABLE IF NOT EXISTS `cdr` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`calldate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`clid` varchar(80) NOT NULL DEFAULT '',
`src` varchar(80) NOT NULL DEFAULT '',
`dst` varchar(80) NOT NULL DEFAULT '',
`realdst` varchar(80) NOT NULL DEFAULT '',
`dcontext` varchar(80) NOT NULL DEFAULT '',
`channel` varchar(80) NOT NULL DEFAULT '',
`dstchannel` varchar(80) NOT NULL DEFAULT '',
`lastapp` varchar(80) NOT NULL DEFAULT '',
`lastdata` varchar(80) NOT NULL DEFAULT '',
`duration` int(11) NOT NULL DEFAULT '0',
`billsec` int(11) NOT NULL DEFAULT '0',
`disposition` varchar(45) NOT NULL DEFAULT '',
`amaflags` int(11) NOT NULL DEFAULT '0',
`remoteip` varchar(60) NOT NULL DEFAULT '',
`accountcode` varchar(20) NOT NULL DEFAULT '',
`peeraccount` varchar(20) NOT NULL DEFAULT '',
`uniqueid` varchar(32) NOT NULL DEFAULT '',
`userfield` varchar(255) NOT NULL DEFAULT '',
`did` varchar(50) NOT NULL DEFAULT '',
`linkedid` varchar(32) NOT NULL DEFAULT '',
`sequence` int(11) NOT NULL DEFAULT '0',
`filename` varchar(255) DEFAULT 'none',
PRIMARY KEY (`id`),
KEY `calldate` (`calldate`),
KEY `src` (`src`),
KEY `dst` (`dst`),
KEY `accountcode` (`accountcode`),
KEY `uniqueid` (`uniqueid`),
KEY `dcontext` (`dcontext`),
KEY `clid` (`clid`),
KEY `did` (`did`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Аватар пользователя
Elektronik
 
Сообщений: 56
Зарегистрирован: 16 окт 2017, 13:42
Откуда: Москва

Re: Asterisk CDR Viewer Mod, в mysql не попадает filename

Сообщение Elektronik » 20 окт 2017, 18:16

Нашел в /www/html/inc/functions.php следующий текст
[Показать] Спойлер:
// Стиль текста для вызовов
$style = '';
switch ($disposition) {
case 'ANSWERED':
$dispTxt = 'Отвечено';
$style = 'answer';
break;
case 'NO ANSWER':
$dispTxt = 'Не отвечено';
$style = 'noanswer';
break;
case 'BUSY':
$dispTxt = 'Занято';
$style = 'busy';
break;
case 'FAILED':
$dispTxt = 'Ошибка';
$style = 'failed';
break;
case 'CONGESTION':
$dispTxt = 'Перегрузка';
$style = 'congestion';
break;
default:
$dispTxt = $disposition;


что наталкивает на мысль, что в поле disposition отправляется не правильное значение из астериск, ибо должны быть там значения ANSWERED, NO ANSWER, BUS и так делее. в какую сторону копать? почему идут какие то цифры, вместо того, что должно идти?
Аватар пользователя
Elektronik
 
Сообщений: 56
Зарегистрирован: 16 окт 2017, 13:42
Откуда: Москва

Re: Asterisk CDR Viewer Mod, в mysql не попадает filename

Сообщение fecyt » 20 окт 2017, 22:47

Файл должен иметь имя равное uniqueid, а у вас добавляется еще и дата. В функциях значит надо менять шаблон поиска файла.

https://wiki.asterisk.org/wiki/display/AST/Function_CDR

Код: выделить все
u - Retrieves the raw, unprocessed value.
For example, 'start', 'answer', and 'end' will be retrieved as epoch values, when the u option is passed, but formatted as YYYY-MM-DD HH:MM:SS otherwise. Similarly, disposition and amaflags will return their raw integral values.
fecyt
 
Сообщений: 148
Зарегистрирован: 17 янв 2017, 18:51

Re: Asterisk CDR Viewer Mod, в mysql не попадает filename

Сообщение Elektronik » 23 окт 2017, 17:44

fecyt писал(а):https://wiki.asterisk.org/wiki/display/AST/Function_CDR

Код: выделить все
u - Retrieves the raw, unprocessed value.
For example, 'start', 'answer', and 'end' will be retrieved as epoch values, when the u option is passed, but formatted as YYYY-MM-DD HH:MM:SS otherwise. Similarly, disposition and amaflags will return their raw integral values.


Искал день, где же может прятаться dispositions,u
не нашел. пошел проверять все файлы, в которых теоретически может задаваться значение.
УРА! НАШЕЛ! каких то 6 часов и проблема решена :) Понедельник, мозг отдохнул, да еще Ваша наводка...:)

в /etc/asterisk/cdr_odbc.conf
закоментирована строка dispositionstring=yes
вот поэтому и возвращал значение цифрой! а ведь черным по белому написано, disposition строчная = да\нет :)

mysql> select disposition from cdr;
+-------------+
| disposition |
+-------------+
| 8 |
| 8 |
| 8 |
| 8 |
| 8 |
| 8 |
| 8 |
| 8 |
| 0 |
| ANSWERED |
+-------------+

хорошо, эту проблему решили, спасибо Вам за это!
решено.JPG


Теперь надо побороть вторую, с именем файла. пойдем искать дальше...

fecyt писал(а):Файл должен иметь имя равное uniqueid, а у вас добавляется еще и дата. В функциях значит надо менять шаблон поиска файла.


так же пытался некоторое время добавить к uniqueid в functions.php звездочку. PHP я вплотную занимался более 10 лет назад, потом полностью ушел от программирования, только батнички да по мелочи по надобности, почти все забыл. Короче не вышло у меня добавить звездочку после $uniqueid, что бы он искал $uniqueid*. или ничего не происходит, или сайт крашится совсем :(

в www/html/cdr/inc/functions.php есть строки:

/* CDR Table Display Functions */
function formatCallDate($calldate, $uniqueid) {
//$calldate = date('d.m.Y H:i:s', strtotime($calldate));
echo '<td class="record_col"><abbr class="simptip-position-top simptip-smooth simptip-fade" data-clipboard data-clipboard-text="'.$uniqueid.'" data-tooltip="UID: '.$uniqueid.'">'.$calldate.'</abbr></td>' . PHP_EOL;

если честно, я не понял, что делает это код.
на всякий случай скидываю
[Показать] Спойлер: functions.php
<?php

/* Recorded file */
function formatFiles($row, $file_params) {
# Кнопка прослушать запись
$tpl['btn_record'] = '
<div class="img_play" data-title="'.$row['calldate'].'"></div>
';

# Кнопка скачать запись
$tpl['btn_download'] = '
<div class="img_dl"></div>
';

# Кнопка удалить запись
$tpl['btn_delete'] = '
<div class="img_delete"></div>
';

# Файл не найден
$tpl['error'] = '
<td class="record_col">
<div class="img_notfound"></div>
</td>
';

# Прослушивание, скачивание, удаление
$tpl['record'] = '
<td class="record_col">
<div class="recordBox">
[_btn_record]
[_btn_download]
[_btn_delete]
</div>
</td>
';

# Скачивание, удаление
$tpl['download'] = '
<td class="record_col">
<div class="recordBox">
[_btn_download]
</div>
</td>
';

$tpl['record'] = str_replace(
array(
'[_btn_record]',
'[_btn_download]',
'[_btn_delete]',
),
array(
Config::get('display.main.rec_play') == 1 ? $tpl['btn_record'] : '',
$tpl['btn_download'],
Config::get('display.main.rec_delete') == 1 ? $tpl['btn_delete'] : '',
),
$tpl['record']
);
$tpl['download'] = str_replace('[_btn_download]', $tpl['btn_download'], $tpl['download']);

# Файл не существует
$tmp['result'] = $tpl['error'];
# Аудио
if ( $file_params['type'] == 'audio' ) {
$tmp['result'] = $tpl['record'];
}
# Архив
else if ( $file_params['type'] == 'archive' ) {
$tmp['result'] = $tpl['download'];
}
# Факс
else if ( $file_params['type'] == 'fax' ) {
$tmp['result'] = $tpl['download'];
}

echo $tmp['result'];
}

# Получить параметры файла записи звонка
function getFileParams($row) {
# uniq_name.mp3
$recorded_file = '';
$tmp['result'] = array(
# Тип файла. false, если файл не существует
'type' => false,
# Путь к файлу в base64. То, что после dl.php?f=
'path' => '',
);
$tmp['system_audio_format'] = Config::get('system.audio_format');
# В базе есть колонка с именем записи разговора
if ( isset($row[Config::get('system.column_name')]) ) {
$recorded_file = $row[Config::get('system.column_name')];
}

$mycalldate_ymd = substr($row['calldate'], 0, 10); // ymd
$mycalldate_ym = substr($row['calldate'], 0, 7); // ym
$mycalldate_y = substr($row['calldate'], 0, 4); // y
$mycalldate_m = substr($row['calldate'], 5, 2); // m
$mycalldate_d = substr($row['calldate'], 8, 2); // d
$mydate = date('Y-m-d');

# Имя файла при отложенной конвертации
if ( Config::get('system.audio_defconv') == 1 && $recorded_file ) {
if ( $mycalldate_ymd < $mydate ) {
$recorded_file = preg_replace('#(.+)\.(wav|mp3|wma|ogg|aac)$#i', '${1}.'.$tmp['system_audio_format'], $recorded_file);
} else {
$tmp['system_audio_format'] = 'wav';
}
}

# Получение имени файла и пути
if ( $mycalldate_ymd < $mydate && Config::get('system.storage_format') === 1 ) {
$rec['filename'] = "$mycalldate_y/$mycalldate_ym/$mycalldate_ymd/$recorded_file";
} else if ( $mycalldate_ymd < $mydate && Config::get('system.storage_format') === 2 ) {
$rec['filename'] = "$mycalldate_y/$mycalldate_m/$mycalldate_d/$recorded_file";
} else if ( Config::get('system.storage_format') === 3 ) {
$rec['filename'] = "$mycalldate_y/$mycalldate_ym/$mycalldate_ymd/$recorded_file";
} else if ( Config::get('system.storage_format') === 4 ) {
$rec['filename'] = "$mycalldate_y/$mycalldate_m/$mycalldate_d/$recorded_file";
} else {
$rec['filename'] = $recorded_file;
}

$rec['path'] = Config::get('system.monitor_dir').'/'.$rec['filename'];

# Аудио
if ( file_exists($rec['path']) && $recorded_file && filesize($rec['path'])/1024 >= Config::get('system.fsize_exists') && preg_match('#(.+)\.'.$tmp['system_audio_format'].'$#i', $rec['filename']) ) {
$tmp['result'] = array(
'type' => 'audio',
'path' => base64_encode($rec['filename']),
);
}
# Архив
else if (
Config::exists('system.archive_format') &&
$recorded_file &&
file_exists($rec['path'].'.'.Config::get('system.archive_format')) &&
filesize($rec['path'].'.'.Config::get('system.archive_format'))/1024 >= Config::get('system.fsize_exists')
) {
$tmp['result'] = array(
'type' => 'archive',
'path' => base64_encode( $rec['filename'].'.'.Config::get('system.archive_format') ),
);
}
# Факс
//else if (file_exists($rec['path']) && preg_match('#(.*)\.tiff?$#i', $rec['filename']) && $rec['filesize'] >= Config::get('system.fsize_exists')) {
else if ( file_exists($rec['path']) && $recorded_file && filesize($rec['path'])/1024 >= Config::get('system.fsize_exists') ) {
$tmp['result'] = array(
'type' => 'fax',
'path' => base64_encode($rec['filename']),
);
}

return $tmp['result'];
}

/* CDR Table Display Functions */
function formatCallDate($calldate, $uniqueid) {
//$calldate = date('d.m.Y H:i:s', strtotime($calldate));
echo '<td class="record_col"><abbr class="simptip-position-top simptip-smooth simptip-fade" data-clipboard data-clipboard-text="'.$uniqueid.'" data-tooltip="UID: '.$uniqueid.'">'.$calldate.'</abbr></td>' . PHP_EOL;
}

function formatChannel($channel) {
$chan['short'] = preg_replace('#(.*)\/[^\/]+$#', '$1', $channel);
$chan['full'] = preg_replace('#(.*)-[^-]+$#', '$1', $channel);
$chan['tooltip'] = $chan['full'];
$chan['txt'] = $chan['short'];
if ( Config::exists('display.main.full_channel_tooltip') && Config::get('display.main.full_channel_tooltip') == 1 ) {
$chan['tooltip'] = $channel;
}
if ( Config::exists('display.main.full_channel') && Config::get('display.main.full_channel') == 1 ) {
$chan['txt'] = $chan['full'];
}
echo '<td class="record_col"><abbr class="simptip-position-top simptip-smooth simptip-fade" data-clipboard data-clipboard-text="'.$chan['tooltip'].'" data-tooltip="Канал: '.$chan['tooltip'].'">'.$chan['txt'].'</abbr></td>' . PHP_EOL;
}

function formatClid($clid) {
$clid_only = explode(' <', $clid, 2);
$clid_only = htmlspecialchars($clid_only[0]);
$clid = htmlspecialchars($clid);
echo '<td class="record_col"><abbr class="simptip-position-top simptip-smooth simptip-fade" data-clipboard data-clipboard-text="'.$clid.'" data-tooltip="CallerID: '.$clid.'">'.$clid_only.'</abbr></td>' . PHP_EOL;
}

function formatSrc($src, $clid) {
if ( empty($src) ) {
echo '<td class="record_col">Неизвестно</td>' . PHP_EOL;
} else {
$src = htmlspecialchars($src);
$clid = htmlspecialchars($clid);
$src_show = $src;
$clipboard = 'data-clipboard data-clipboard-text="'.$clid.'"';
if ( is_numeric($src) && strlen($src) >= Config::get('display.lookup.num_length') && strlen(Config::get('display.lookup.url')) > 0 ) {
$rev = str_replace( '%n', $src, Config::get('display.lookup.url') );
$src_show = '<a href="'.$rev.'" target="reverse">'.$src.'</a>';
$clipboard = '';
}
echo '<td class="record_col"><abbr class="simptip-position-top simptip-smooth simptip-fade" '.$clipboard.' data-tooltip="CallerID: '.$clid.'">'.$src_show.'</abbr></td>' . PHP_EOL;
}
}

function formatApp($app, $lastdata) {
$tooltip = $app . '(' . $lastdata . ')';
echo '<td class="record_col"><abbr class="simptip-position-top simptip-smooth simptip-fade" data-clipboard data-clipboard-text="'.$tooltip.'" data-tooltip="Приложение: '.$tooltip.'">'.$app.'</abbr></td>' . PHP_EOL;
}

function formatDst($dst, $dcontext) {
$dst_show = $dst;
$clipboard = 'data-clipboard data-clipboard-text="'.$dcontext.'"';
if ( is_numeric($dst) && strlen($dst) >= Config::get('display.lookup.num_length') && strlen(Config::get('display.lookup.url')) > 0 ) {
$rev = str_replace( '%n', $dst, Config::get('display.lookup.url') );
$dst_show = '<a href="'.$rev.'" target="reverse">'.$dst.'</a>';
$clipboard = '';
}
echo '<td class="record_col"><abbr class="simptip-position-top simptip-smooth simptip-fade" '.$clipboard.' data-tooltip="Контекст назначения: '.$dcontext.'">'.$dst_show.'</abbr></td>' . PHP_EOL;
}

function formatDisposition($disposition, $amaflags) {
switch ($amaflags) {
case 0:
$amaflags = 'DOCUMENTATION';
break;
case 1:
$amaflags = 'IGNORE';
break;
case 2:
$amaflags = 'BILLING';
break;
case 3:
default:
$amaflags = 'DEFAULT';
}
// Стиль текста для вызовов
$style = '';
switch ($disposition) {
case 'ANSWERED':
$dispTxt = 'Отвечено';
$style = 'answer';
break;
case 'NO ANSWER':
$dispTxt = 'Не отвечено';
$style = 'noanswer';
break;
case 'BUSY':
$dispTxt = 'Занято';
$style = 'busy';
break;
case 'FAILED':
$dispTxt = 'Ошибка';
$style = 'failed';
break;
case 'CONGESTION':
$dispTxt = 'Перегрузка';
$style = 'congestion';
break;
default:
$dispTxt = $disposition;
}
echo '<td class="record_col '.$style.'"><div class="status status-'.$style.'"></div><abbr class="simptip-position-top simptip-smooth simptip-fade" data-clipboard data-clipboard-text="'.$amaflags.'" data-tooltip="AMA флаг: '.$amaflags.'">'.$dispTxt.'</abbr></td>' . PHP_EOL;
}

function formatDuration($duration, $billsec) {
$duration = sprintf( '%02d', intval($duration/60) ).':'.sprintf( '%02d', intval($duration%60) );
$billduration = sprintf( '%02d', intval($billsec/60) ).':'.sprintf( '%02d', intval($billsec%60) );
echo '<td class="record_col"><abbr class="simptip-position-top simptip-smooth simptip-fade" data-clipboard data-clipboard-text="'.$billduration.'" data-tooltip="По биллингу: '.$billduration.'">'.$duration.'</abbr></td>' . PHP_EOL;
}

function formatUserField($userfield) {
echo '<td class="record_col userfield">'.$userfield.'</td>' . PHP_EOL;
}

function formatAccountCode($accountcode) {
echo '<td class="record_col"><abbr data-clipboard data-clipboard-text="'.$accountcode.'">'.$accountcode.'</abbr></td>' . PHP_EOL;
}

/* Asterisk RegExp parser */
function asteriskregexp2sqllike($source_data, $user_num) {
$number = $user_num;
if (strlen($number) < 1) {
$number = $_REQUEST[$source_data];
}
if ('__' == substr($number,0,2)) {
$number = substr($number,1);
} elseif ('_' == substr($number,0,1)) {
$number_chars = preg_split('//', substr($number,1), -1, PREG_SPLIT_NO_EMPTY);
$number = '';
foreach ($number_chars as $chr) {
if ($chr == 'X') {
$number .= '[0-9]';
} elseif ($chr == 'Z') {
$number .= '[1-9]';
} elseif ($chr == 'N') {
$number .= '[2-9]';
} elseif ($chr == '.') {
$number .= '.+';
} elseif ($chr == '!') {
$_REQUEST[ $source_data .'_neg' ] = 'true';
} else {
$number .= $chr;
}
}
$_REQUEST[$source_data .'_mod'] = 'asterisk-regexp';
}
return $number;
}

/* empty() wrapper */
function is_blank(&$value) {
if ( isset($value) ) {
return empty($value) && !is_numeric($value);
}
return true;
}

/*
Money format

*/
// cents: 0=never, 1=if needed, 2=always
// title: title to show
function formatMoney($number, $cents = 2, $title = '') {
if ( is_numeric($number) ) {
// whole number
if ( floor($number) == $number ) {
$money = number_format( $number, ($cents == 2 ? 2 : 0) ); // format
} else { // cents
$money = number_format( round($number, 2), ($cents == 0 ? 0 : 2) ); // format
} // integer or decimal

if ( $title ) {
$title = ' class="simptip-position-top simptip-smooth simptip-fade" data-clipboard data-clipboard-text="'.$title.'" data-tooltip="'.$title.'"';
}
echo '<td class="chart_data"><span'.$title.'>'.$money.'</span>'.Config::get('callrate.currency').'</td>' . PHP_EOL;
} else {
echo '<td class="chart_data"></td>' . PHP_EOL;
}
}

/*
CallRate
return callrate array [ areacode, rate, description, bill type, total_rate]
*/
function callrates($dst, $duration, $file) {
global $callrate_cache;
if (strlen($file) == 0) {
$file = Config::get('callrate.csv_file');
if (strlen($file) == 0) {
return array('', '', '', '', '');
}
}

if (!array_key_exists($file, $callrate_cache)) {
$callrate_cache[$file] = array();
$fr = fopen($file, 'r') or exit('Не удалось открыть файл с тарифами ('.$file.')');
while (($fr_data = fgetcsv($fr, 1000, ',')) !== false) {
if ($fr_data[0] !== null) {
// Не указан доп. тариф
if ( !isset($fr_data[4]) ) {
$fr_data[4] = null;
}
$callrate_cache[$file][$fr_data[0]] = array($fr_data[1], $fr_data[2], $fr_data[3], $fr_data[4]);
}
}
fclose($fr);
}

for ($i = strlen($dst); $i > 0; $i--) {
if (array_key_exists(substr($dst,0,$i), $callrate_cache[$file])) {
$call_rate = 0;
if ($callrate_cache[$file][substr($dst,0,$i)][2] == 's') {
// per second
if ( $duration >= Config::get('callrate.free_interval') ) {
$call_rate = $duration * ($callrate_cache[$file][substr($dst,0,$i)][0] / 60);
}
} elseif ($callrate_cache[$file][substr($dst,0,$i)][2] == 'c') {
// per call
if ( $duration >= Config::get('callrate.free_interval') ) {
$call_rate = $callrate_cache[$file][substr($dst,0,$i)][0];
}
} elseif ($callrate_cache[$file][substr($dst,0,$i)][2] == '1m+s') {
// 1 minute + per second
if ( $duration < Config::get('callrate.free_interval') ) {}
else if ( $duration < 60 ) {
$call_rate = $callrate_cache[$file][substr($dst,0,$i)][0];
} else {
// указан доп тариф
if (isset($callrate_cache[$file][substr($dst,0,$i)][3]) && $callrate_cache[$file][substr($dst,0,$i)][3] && $callrate_cache[$file][substr($dst,0,$i)][3] > 0) {
$ext_rate = $callrate_cache[$file][substr($dst,0,$i)][3];
} else {
$ext_rate = $callrate_cache[$file][substr($dst,0,$i)][0]/60;
}
$call_rate = $callrate_cache[$file][substr($dst,0,$i)][0] + ( ($duration-60) * ($ext_rate) );
}
} elseif ($callrate_cache[$file][substr($dst,0,$i)][2] == '30s+s') {
// 30 second + per second
if ($duration > 0 && $duration <= 30) {
$call_rate = ($callrate_cache[$file][substr($dst,0,$i)][0] / 2);
} elseif ( $duration > 30 && $duration < 60) {
$call_rate = ($callrate_cache[$file][substr($dst,0,$i)][0] / 2) + (($duration-30) * ($callrate_cache[$file][substr($dst,0,$i)][0] / 60));
} else {
$call_rate = $callrate_cache[$file][substr($dst,0,$i)][0] + (($duration-60) * ($callrate_cache[$file][substr($dst,0,$i)][0] / 60));
}
} elseif ($callrate_cache[$file][substr($dst,0,$i)][2] == '30s+6s') {
// 30 second + 6 second
if ($duration > 0 && $duration <= 30) {
$call_rate = ($callrate_cache[$file][substr($dst,0,$i)][0] / 2);
} else {
$call_rate = ceil($duration / 6) * ($callrate_cache[$file][substr($dst,0,$i)][0] / 10);
}
} else {
//( $callrate_cache[substr($dst,0,$i)][2] == 'm' ) {
// per minute
if ( $duration >= Config::get('callrate.free_interval') ) {
// всего минут разговор
$call_rate = ceil($duration/60);
// указан доп тариф
if (isset($callrate_cache[$file][substr($dst,0,$i)][3]) && $callrate_cache[$file][substr($dst,0,$i)][3] && $callrate_cache[$file][substr($dst,0,$i)][3] > 0) {
$call_rate = $callrate_cache[$file][substr($dst,0,$i)][0] + ( ($call_rate-1) * $callrate_cache[$file][substr($dst,0,$i)][3] );
} else {
$call_rate = $call_rate*$callrate_cache[$file][substr($dst,0,$i)][0];
}
}
}
return array(substr($dst,0,$i),$callrate_cache[$file][substr($dst,0,$i)][0],$callrate_cache[$file][substr($dst,0,$i)][1],$callrate_cache[$file][substr($dst,0,$i)][2],$call_rate);
}
}
return array (0, 0, 'Неизвестно', 'Неизвестно', 0);
}


/*
Connect to DB. Return PDO object
$errors - show connection errors
*/
function dbConnect( $errors = true ) {
$dbh = null;
try {
$dbh = new PDO(
Config::get('db.type') .
':host=' . Config::get('db.host') .
';port=' . Config::get('db.port') .
';dbname=' . Config::get('db.name'),
Config::get('db.user'),
Config::get('db.pass'),
Config::get('db.options')
);
}
catch (PDOException $e) {
if ( $errors === true ) {
echo "\nPDO::errorInfo():\n";
print $e->getMessage();
}
}
return $dbh;
}


но думаю не здесь собака зарыта...будем искать дальше...если у кого есть какие мысли, подсказывайте :)

Спасибо!
Аватар пользователя
Elektronik
 
Сообщений: 56
Зарегистрирован: 16 окт 2017, 13:42
Откуда: Москва

Re: Asterisk CDR Viewer Mod, в mysql не попадает filename

Сообщение Elektronik » 24 окт 2017, 15:50

/var/log/asterisk/cdr-csv/Master.csv

"","4955584468","s","menu","""4955584468"" <4955584468>","SIP/ntel00000002","","BackGround","/var/lib/asterisk/moh/voicemail/sagamenu2","2017-10-24 11:43:28","2017-10-24 11:43:28","2017-10-24 11:43:37",8,8,"ANSWERED","DOCUMENTATION","1508845408.4",""

filename даже не отправляется в базу данных, получается и нечего искать, не в макросе поиска дело, а в том, что имя файла не попадает в базу.
Аватар пользователя
Elektronik
 
Сообщений: 56
Зарегистрирован: 16 окт 2017, 13:42
Откуда: Москва

След.

Вернуться в Вопросы новичков

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19

© 2008 — 2024 Asterisk.ru
Digium, Asterisk and AsteriskNOW are registered trademarks of Digium, Inc.
Design and development by PostMet-Netzwerk GmbH