Initial implementation
authorJoey Schulze <joey@infodrom.org>
Sat, 12 Dec 2009 00:05:33 +0000 (01:05 +0100)
committerJoey Schulze <joey@infodrom.org>
Fri, 25 Feb 2011 17:40:22 +0000 (18:40 +0100)
index.php
phone.css
phone.js [new file with mode: 0644]
phone.php [new file with mode: 0644]

index 7c08877..579282b 100644 (file)
--- a/index.php
+++ b/index.php
@@ -1,3 +1,22 @@
+<?
+include_once('phone.php');
+
+if (!empty($_POST['func'])) {
+  $data = array();
+  if ($_POST['func'] == 'incoming') {
+    $data['incoming'] = get_incoming();
+  } elseif ($_POST['func'] == 'callinfo') {
+    $data = callinfo($_POST['dir'],$_POST['call']);
+  }
+  header('Content-type: application/json; charset=UTF-8');
+  echo json_encode($data);
+  exit;
+} elseif (!empty($_GET['dir']) && !empty($_GET['call'])) {
+  send_call($_GET['dir'], $_GET['call']);
+  exit;
+}
+
+?>
 <html>
 <head>
 <title>Infodrom Phone Answering Machine</title>
 <link href="phone.css" rel="stylesheet" type="text/css">
 </head>
 <script type="text/javascript" src="lib/json_parse.js"></script>
-<script type="text/javascript" src="basics.js"></script>
+<script type="text/javascript" src="lib/basics.js"></script>
 <script type="text/javascript" src="phone.js"></script>
 <script type="text/javascript" src="lib/debug_joey.js"></script>
 
-<body>
+<body onload="page_init()">
 <div style="margin-top: -5px">
-<span id="channels"><span style="margin-right: 450px;">Loading data...</span></span>
+</div>
+
+<div>
+<div class="phonelist" id="incoming">
+<p class="title">Incoming Calls</p>
+<ul class="phonelist" id="incoming_calls">
+<li>Loading data...</li>
+</ul>
+</div>
+
+<div class="phonelist" id="archive">
+<p class="title">Archived Calls</p>
+<ul class="phonelist" id="archive_calls">
+<li>Loading data...</li>
+</ul>
+</div>
+
+</div>
+
+<div class="phonecall">
+<p class="title">Play message</p>
+<p id="callspeaker">&nbsp;</p>
+<iframe class="phonecall" id="phonecall"></iframe>
+<p id="calldate">&nbsp;</p>
+<p id="callnote"></p>
 </div>
 
 </body>
index cf32ead..e69de29 100644 (file)
--- a/phone.css
+++ b/phone.css
@@ -1,6 +0,0 @@
-body {
-    font-family: Verdana, Helvetica, Arial, sans-serif;
-    font-size: 10px;
-    background-color: #f7f7f7;
-    color: #000000;
-}
diff --git a/phone.js b/phone.js
new file mode 100644 (file)
index 0000000..ad7f6ae
--- /dev/null
+++ b/phone.js
@@ -0,0 +1,68 @@
+function page_init()
+{
+    var frame = document.getElementById('phonecall');
+    frame.src = '';
+    fetch_incoming();
+}
+
+function fetch_incoming_callback(data)
+{
+    var calls = document.getElementById('incoming_calls');
+    var div = document.getElementById('incoming');
+
+    while (calls.childNodes.length > 0)
+       calls.removeChild(calls.childNodes[0]);
+
+    if (data.incoming.length > 0) {
+       div.style.display = '';
+
+       for (var i=0; i < data.incoming.length; i++) {
+           var elem = document.createElement('li');
+           var text = data.incoming[i].date + ', ';
+           if (data.incoming[i].name == '*** Unknown ***' && data.incoming[i].number != '0')
+               text += data.incoming[i].number;
+           else
+               text += data.incoming[i].name;
+           text += ', ' + data.incoming[i].length;
+
+           elem.innerHTML = text;
+           elem.payload = new Array();
+           elem.payload['dir'] = 'incoming';
+           elem.payload['fname'] = data.incoming[i].fname;
+           elem.onclick = play_message;
+           calls.appendChild(elem);
+       }
+    } else {
+       div.style.display = 'none';
+    }
+}
+
+function fetch_incoming()
+{
+    ajax_request('incoming', '', fetch_incoming_callback);
+}
+
+function play_message_callback(data)
+{
+    var speaker = document.getElementById('callspeaker');
+    var date = document.getElementById('calldate');
+    var note = document.getElementById('callnote');
+
+    Debug.ObjDump(data);
+
+    var text = data.name;
+    if (data.number != '0') text += ' (' + data.number + ')';
+    speaker.innerHTML = text;
+    date.innerHTML = data.date + ', ' + data.length;
+    note.innerHTML = data.note;
+}
+
+function play_message(event)
+{
+    Debug.write('Request ' + event.originalTarget.payload['fname'] + ' in ' + event.originalTarget.payload['dir']);
+
+    var frame = document.getElementById('phonecall');
+    var parms = 'dir='+event.originalTarget.payload['dir']+'&call='+event.originalTarget.payload['fname'];
+    ajax_request('callinfo', parms, play_message_callback);
+    // frame.src = 'index.php?'+parms;
+}
diff --git a/phone.php b/phone.php
new file mode 100644 (file)
index 0000000..c8f7381
--- /dev/null
+++ b/phone.php
@@ -0,0 +1,106 @@
+<?
+define('SPOOL_DIR', '/var/spool/vbox/ttyI6');
+
+function read_info($dir, $call)
+{
+  $info = array();
+  if (($f = fopen(SPOOL_DIR . '/' . $dir . '/' . $call . '.info', 'r')) !== false) {
+    $line = fgets($f, 1024);
+    fclose($f);
+    $info = unserialize($line);
+    if (empty($info['note'])) $info['note'] = '';
+  }
+  return $info;
+}
+
+function write_info($dir,$fname,$info)
+{
+  if (($f = fopen(SPOOL_DIR . '/' . $dir . '/' . $fname . '.info', 'w')) !== false) {
+    fwrite($f, serialize($info)."\n");
+    fclose($f);
+  }
+}
+
+function message_info($dir,$fname)
+{
+  $info = array();
+  $basename = SPOOL_DIR . '/' . $dir . '/' . $fname;
+
+  if (is_file($basename . '.vmsg')) {
+    if (!is_file($basename . '.info')) {
+      if (($p = popen('vboxmode ' . $basename . '.vmsg', 'r')) !== false) {
+       while (!feof($p)) {
+         $line = chop(fgets($p, 1024));
+         $pos = strpos($line, ':')+2;
+         if (strpos($line, 'Speaker name............: ') !== false) {
+           $info['name'] = utf8_encode(substr($line, $pos));
+         } elseif (strpos($line, 'Length..................: ') !== false) {
+           $info['length'] = substr($line, $pos);
+         } elseif (strpos($line, 'Speaker caller number...: ') !== false) {
+           $info['number'] = substr($line, $pos);
+         } elseif (strpos($line, 'Creation time...........: ') !== false) {
+           $info['date'] = substr($line, $pos);
+         }
+       }
+       pclose($p);
+       $s = stat($basename . '.vmsg');
+       $info['timestamp'] = $s['mtime'];
+       write_info($dir,$fname,$info);
+      }
+    }
+    $info = read_info($dir,$fname);
+  }
+
+  return $info;
+}
+
+function get_incoming()
+{
+  $result = array();
+
+  if ($dir = opendir(SPOOL_DIR . '/incoming')) {
+    while (($filename = readdir($dir)) !== false) {
+      if (($pos = strpos($filename, '.vmsg')) !== false) {
+       $fname = substr($filename,0,$pos);
+       $info = message_info('incoming', $fname);
+       $info['fname'] = $fname;
+       $result[] = $info;
+      }
+    }
+    closedir($dir);
+  }
+  return $result;
+}
+
+function callinfo($dir, $call)
+{
+  return read_info($dir, $call);
+}
+
+function send_call($dir, $call)
+{
+  $dir = str_replace('/','x',$dir);
+  $call = str_replace('/','x',$call);
+  $fname = SPOOL_DIR . '/' . $dir . '/' . $call . '.vmsg';
+
+  if (!is_file($fname)) {
+    printf("<html><body><h3>Anruf %s in %s nicht gefunden!</h3></body></html>", $call, $dir);
+    return;
+  }
+
+  if (($p = popen('vboxtoau < ' . $fname, 'r')) === false) {
+    printf("<html><body><h3>Anruf %s in %s konnte geoeffnet werden!</h3></body></html>", $call, $dir);
+    return;
+  }
+
+  header(sprintf('Content-disposition: inline; filename="%s.au"', $call));
+  header('Content-Type: audio/basic');
+  header("Cache-Control: ");
+  header("Pragma: ");
+  sleep(1);
+  fpassthru($p);
+
+  pclose($p);
+}
+
+?>
\ No newline at end of file