123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428 |
- <?php
- /**
- * AskoziaPBX calls recodrings viewer class
- */
- class AskoziaMonitor {
- /**
- * Contains system alter config as key=>value
- *
- * @var array
- */
- protected $altCfg = array();
- /**
- * Contains default recorded calls path
- *
- * @var string
- */
- protected $voicePath = '/mnt/askozia/';
- /**
- * Contains voice recors archive path
- *
- * @var string
- */
- protected $archivePath = '/mnt/calls_archive/';
- /**
- * Contains default recorded files file extension
- *
- * @var string
- */
- protected $callsFormat = '*.gsm';
- /**
- * Flag for telepathy detection of users
- *
- * @var bool
- */
- protected $onlyMobileFlag = true;
- /**
- * Contains user assigned tags as login=>usertags
- *
- * @var array
- */
- protected $userTags = array();
- /**
- * FFmpeg installed?
- *
- * @var bool
- */
- protected $ffmpegFlag = false;
- /**
- * installed ffmpeg path
- *
- * @var string
- */
- protected $ffmpegPath = '';
- /**
- * Basic ffmpeg path to search. May be configurable in future.
- *
- * @var string
- */
- protected $baseConverterPath = '/usr/local/bin/ffmpeg';
- /**
- * File path for converted voice files
- *
- * @var string
- */
- protected $convertedPath = 'exports/';
- /**
- * ffmpeg log path
- *
- * @var string
- */
- protected $converterLogPath = 'exports/voiceconvert.log';
- /**
- * Default icons path
- */
- const ICON_PATH = 'skins/calls/';
- /**
- * Default module path
- */
- const URL_ME = '?module=askoziamonitor';
- /**
- * URL of user profile route
- */
- const URL_PROFILE = '?module=userprofile&username=';
- /**
- * Creates new askozia monitor instance
- *
- * @return void
- */
- public function __construct() {
- $this->loadConfig();
- $this->detectFfmpeg();
- }
- /**
- * Loads all required configs and sets some options
- *
- * @return void
- */
- protected function loadConfig() {
- global $ubillingConfig;
- $this->altCfg = $ubillingConfig->getAlter();
- if ((!isset($this->altCfg['WDYC_ONLY_MOBILE'])) OR ( !@$this->altCfg['WDYC_ONLY_MOBILE'])) {
- $this->onlyMobileFlag = false;
- }
- }
- /**
- * Detects is ffmpeg available on local system and sets ffmpegFlag and path properties.
- *
- * @return void
- */
- protected function detectFfmpeg() {
- if (file_exists($this->baseConverterPath)) {
- $this->ffmpegFlag = true;
- $this->ffmpegPath = $this->baseConverterPath;
- }
- }
- /**
- * Loads existing tagtypes and usertags into protected props for further usage
- *
- * @return void
- */
- protected function loadUserTags() {
- $this->userTags = zb_UserGetAllTags();
- }
- /**
- * Catches file download or convert request
- *
- * @return void
- */
- public function catchFileDownload() {
- if (ubRouting::checkGet('dlaskcall')) {
- $origFileName = ubRouting::get('dlaskcall');
- $downloadableName = '';
- //voice records
- if (file_exists($this->voicePath . $origFileName)) {
- $downloadableName = $this->voicePath . $origFileName;
- } else {
- //archive download
- if (file_exists($this->archivePath . $origFileName)) {
- $downloadableName = $this->archivePath . $origFileName;
- }
- }
- //voice files converter installed?
- if ($this->ffmpegFlag) {
- if (ubRouting::checkGet('playable')) {
- //need to run converter
- if (!empty($downloadableName)) {
- //original file is already located
- $newFileExtension = (ubRouting::checkGet('mp3')) ? '.mp3' : '.ogg';
- $newFilePath = $this->convertedPath . $origFileName . $newFileExtension;
- $command = $this->ffmpegPath . ' -y -i ' . $downloadableName . ' ' . $newFilePath . ' 2>> ' . $this->converterLogPath;
- shell_exec($command);
- $downloadableName = $newFilePath;
- }
- }
- } else {
- show_error(__('ffmpeg is not installed. Web player and converter not available.'));
- }
- //file download processing
- if (!empty($downloadableName)) {
- zb_DownloadFile($downloadableName, 'default');
- } else {
- show_error(__('File not exist') . ': ' . $origFileName);
- }
- }
- }
- /**
- * Returns available calls files array
- *
- * @return array
- */
- protected function getCallsDir() {
- $result = array();
- if (file_exists($this->voicePath)) {
- $result = rcms_scandir($this->voicePath, $this->callsFormat, 'file');
- }
- return ($result);
- }
- /**
- * Returns available archived calls files array
- *
- * @return array
- */
- protected function getArchiveDir() {
- $result = array();
- if (file_exists($this->archivePath)) {
- $result = rcms_scandir($this->archivePath, $this->callsFormat, 'file');
- }
- return ($result);
- }
- /**
- * Returns calls list container
- *
- * @return string
- */
- public function renderCallsList() {
- $opts = '"order": [[ 0, "desc" ]]';
- $columns = array(__('Date'), __('Number'), __('User'), __('Tags'), __('File'));
- if (ubRouting::checkGet('username')) {
- $loginFilter = '&loginfilter=' . ubRouting::get('username');
- } else {
- $loginFilter = '';
- }
- if (ubRouting::checkGet('renderall')) {
- $filterNumber = '&renderall=true';
- } else {
- $filterNumber = '';
- }
- $result = wf_JqDtLoader($columns, self::URL_ME . '&ajax=true' . $loginFilter . $filterNumber, false, __('Calls records'), 100, $opts);
- return ($result);
- }
- /**
- * Renders user tags if available
- *
- * @param string $userLogin
- *
- * @return string
- */
- protected function renderUserTags($userLogin) {
- $result = '';
- if (!empty($userLogin)) {
- if (isset($this->userTags[$userLogin])) {
- if (!empty($this->userTags[$userLogin])) {
- $result .= implode(', ', $this->userTags[$userLogin]);
- }
- }
- }
- return ($result);
- }
- /**
- * Renders json recorded calls list
- *
- * @param string $filterLogin
- * @param bool $renderAll
- *
- * @return void
- */
- public function jsonCallsList($filterLogin = '', $renderAll = false) {
- $allAddress = zb_AddressGetFulladdresslistCached();
- $allRealnames = zb_UserGetAllRealnames();
- $this->loadUserTags();
- $json = new wf_JqDtHelper();
- $allVoiceFiles = $this->getCallsDir();
- $allArchiveFiles = $this->getArchiveDir();
- $telepathy = new Telepathy(false, true);
- $telepathy->usePhones();
- $askCalls = new nya_askcalls();
- $previousCalls = $askCalls->getAll('filename');
- $curYear = curyear() . '-';
- //current year filter for all calls
- if (empty($filterLogin) AND ! $renderAll) {
- $renderAll = false;
- } else {
- $renderAll = true;
- }
- $allCallsLabel = ($renderAll) ? wf_img('skins/allcalls.png', __('All time')) . ' ' : '';
- //normal voice records rendering
- if (!empty($allVoiceFiles)) {
- /**
- * Fuck a fucking placement, I don't need you motherfuckers
- * I'ma get it on my own before I get on your production
- * 'Cause you fucking pieces of shit don't show no motherfucking love to me
- * I see right through your guise, you try and hide but you can't run from me
- */
- foreach ($allVoiceFiles as $io => $each) {
- $fileName = $each;
- $explodedFile = explode('_', $fileName);
- $cleanDate = explode('.', $explodedFile[2]);
- $cleanDate = $cleanDate[0];
- $callingNumber = $explodedFile[1];
- $callDirection = ($explodedFile[0] == 'in') ? self::ICON_PATH . 'incoming.png' : self::ICON_PATH . 'outgoing.png';
- //unfinished calls
- if ((!ispos($cleanDate, 'in')) AND ( !ispos($cleanDate, 'out'))) {
- if (!isset($previousCalls[$fileName])) {
- //here onlyMobile flag used for mobile normalizing too
- $userLogin = $telepathy->getByPhoneFast($callingNumber, $this->onlyMobileFlag, $this->onlyMobileFlag);
- $askCalls->data('filename', ubRouting::filters($fileName, 'mres'));
- $askCalls->data('login', ubRouting::filters($userLogin, 'mres'));
- $askCalls->create();
- } else {
- $userLogin = $previousCalls[$fileName]['login'];
- }
- $userLink = (!empty($userLogin)) ? wf_Link('?module=userprofile&username=' . $userLogin, web_profile_icon() . ' ' . @$allAddress[$userLogin]) . ' ' . @$allRealnames[$userLogin] : '';
- $newDateString = date_format(date_create_from_format('Y-m-d-H-i-s', $cleanDate), 'Y-m-d H:i:s');
- $cleanDate = $newDateString;
- $fileUrl = self::URL_ME . '&dlaskcall=' . $fileName;
- if ((empty($filterLogin)) OR ( $filterLogin == $userLogin)) {
- if ($renderAll) {
- $data[] = wf_img($callDirection) . ' ' . $cleanDate;
- $data[] = $callingNumber;
- $data[] = $userLink;
- $data[] = $this->renderUserTags($userLogin);
- $data[] = $this->getSoundcontrols($fileUrl) . $allCallsLabel;
- $json->addRow($data);
- } else {
- if (ispos($cleanDate, $curYear)) {
- $data[] = wf_img($callDirection) . ' ' . $cleanDate;
- $data[] = $callingNumber;
- $data[] = $userLink;
- $data[] = $this->renderUserTags($userLogin);
- $data[] = $this->getSoundcontrols($fileUrl) . $allCallsLabel;
- $json->addRow($data);
- }
- }
- }
- unset($data);
- }
- }
- }
- //archived records rendering
- if (!empty($allArchiveFiles)) {
- $archiveLabel = wf_img('skins/calls/archived.png', __('Archive'));
- foreach ($allArchiveFiles as $io => $each) {
- $fileName = $each;
- $explodedFile = explode('_', $fileName);
- $cleanDate = explode('.', $explodedFile[2]);
- $cleanDate = $cleanDate[0];
- $callingNumber = $explodedFile[1];
- $callDirection = ($explodedFile[0] == 'in') ? self::ICON_PATH . 'incoming.png' : self::ICON_PATH . 'outgoing.png';
- //unfinished calls
- if ((!ispos($cleanDate, 'in')) AND ( !ispos($cleanDate, 'out'))) {
- if (!isset($previousCalls[$fileName])) {
- //here onlyMobile flag used for mobile normalizing too
- $userLogin = $telepathy->getByPhoneFast($callingNumber, $this->onlyMobileFlag, $this->onlyMobileFlag);
- $askCalls->data('filename', ubRouting::filters($fileName, 'mres'));
- $askCalls->data('login', ubRouting::filters($userLogin, 'mres'));
- $askCalls->create();
- } else {
- $userLogin = $previousCalls[$fileName]['login'];
- }
- $userLink = (!empty($userLogin)) ? wf_Link('?module=userprofile&username=' . $userLogin, web_profile_icon() . ' ' . @$allAddress[$userLogin]) . ' ' . @$allRealnames[$userLogin] : '';
- $newDateString = date_format(date_create_from_format('Y-m-d-H-i-s', $cleanDate), 'Y-m-d H:i:s');
- $cleanDate = $newDateString;
- $fileUrl = self::URL_ME . '&dlaskcall=' . $fileName;
- if ((empty($filterLogin)) OR ( $filterLogin == $userLogin)) {
- if ($renderAll) {
- $data[] = wf_img($callDirection) . ' ' . $cleanDate;
- $data[] = $callingNumber;
- $data[] = $userLink;
- $data[] = $this->renderUserTags($userLogin);
- $data[] = $this->getSoundcontrols($fileUrl) . ' ' . $archiveLabel . $allCallsLabel;
- $json->addRow($data);
- } else {
- if (ispos($cleanDate, $curYear)) {
- $data[] = wf_img($callDirection) . ' ' . $cleanDate;
- $data[] = $callingNumber;
- $data[] = $userLink;
- $data[] = $this->renderUserTags($userLogin);
- $data[] = $this->getSoundcontrols($fileUrl) . ' ' . $archiveLabel . $allCallsLabel;
- $json->addRow($data);
- }
- }
- }
- unset($data);
- }
- }
- }
- $telepathy->savePhoneTelepathyCache();
- $json->getJson();
- }
- /**
- * Returns controls for some recorded call file
- *
- * @param string $fileUrl
- *
- * @return string
- */
- protected function getSoundcontrols($fileUrl) {
- $result = '';
- if (!empty($fileUrl)) {
- if ($this->ffmpegFlag) {
- $playableUrl = $fileUrl . '&playable=true';
- $iconPlay = wf_img('skins/play.png', __('Play'));
- $iconPause = wf_img('skins/pause.png', __('Pause'));
- $playerId = 'player_' . wf_InputId();
- $playControlId = 'controller_' . wf_InputId();
- $result .= wf_tag('audio', false, '', 'id="' . $playerId . '" src="' . $playableUrl . '" preload=none') . wf_tag('audio', true);
- $playController = 'document.getElementById(\'' . $playerId . '\').play();';
- $result .= wf_Link('#', $iconPlay, false, '', 'id="' . $playControlId . '" onclick="' . $playController . '"') . ' ';
- $result .= wf_Link('#', $iconPause, false, '', 'onclick="document.getElementById(\'' . $playerId . '\').pause();"') . ' ';
- $result .= wf_Link($playableUrl, wf_img('skins/icon_ogg.png', __('Download') . ' ' . __('as OGG'))) . ' ';
- $result .= wf_Link($playableUrl . '&mp3=true', wf_img('skins/icon_mp3.png', __('Download') . ' ' . __('as MP3'))) . ' ';
- } else {
- $result .= wf_Link('#', wf_img('skins/factorcontrol.png', __('ffmpeg is not installed. Web player and converter not available.'))) . ' ';
- }
- //basic download control
- $result .= wf_Link($fileUrl, wf_img('skins/icon_download.png', __('Download') . ' ' . __('as is')));
- }
- return ($result);
- }
- }
|