ajax.php
author Dan
Tue, 23 Dec 2008 20:20:35 -0500
changeset 64 ee64bb096f56
parent 55 b8a3c9c54fbe
permissions -rw-r--r--
A few miscellaneous fixes including modifying WebServer to write data in chunks (improved performance and reliability on a slow connection)

<?php

/**
 * Action servlet (play, pause, etc.)
 *
 * Greyhound - real web management for Amarok
 * Copyright (C) 2008 Dan Fuhry
 *
 * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
 */

status('initializing Services_JSON');
$json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);

// keep track of playlist refresh
$playlist_last_refresh = time();

/**
 * Terminate a request with an error string formatted as JSON.
 * @param string Error message
 */

function json_die($msg)
{
  global $json;
  echo $json->encode(array(
      'mode' => 'error',
      'error' => $msg
    ));
  return true;
}

function ajax_request_handler($httpd, $socket)
{
  global $playlist, $mime_types, $json, $allowcontrol;
  global $use_auth, $auth_data;
  
  if ( !session_check() )
    return true;
  
  // Set content type
  $httpd->header("Content-type: {$mime_types['js']}");
  
  // get PATH_INFO
  $pathinfo = @substr(@substr($_SERVER['REQUEST_URI'], 1), @strpos(@substr($_SERVER['REQUEST_URI'], 1), '/')+1);
  if ( empty($pathinfo) )
  {
    return json_die('No action specified on URI');
  }
  
  $params = explode('/', $pathinfo);
  $action =& $params[0];
  switch ( $action )
  {
    case 'stop':
    case 'next':
    case 'prev':
      if ( !$allowcontrol )
        return false;
      echo dcop_action('player', $action);
      break;
    case 'play':
      if ( !$allowcontrol )
        return false;
      echo dcop_action('player', 'playPause');
      break;
    case 'jump':
      if ( !$allowcontrol )
        return false;
      $tid =& $params[1];
      if ( !preg_match('/^[0-9]+$/', $tid) )
      {
        return json_die('Invalid track ID');
      }
      $tid = intval($tid);
      dcop_action('playlist', "playByIndex $tid");
      $return = array(
        'current_track_length' => $playlist[$tid]['length_int'],
        'current_track_pos' => 0,
        'current_track_title' => $playlist[$tid]['title'],
        'current_track_album' => $playlist[$tid]['album'],
        'current_track_artist' => $playlist[$tid]['artist']
      );
      echo $json->encode($return);
      break;
    case 'volume':
      if ( !$allowcontrol )
        return false;
      $volume =& $params[1];
      if ( !preg_match('/^[0-9]+$/', $volume) )
      {
        return json_die('Invalid track ID');
      }
      $volume = intval($volume);
      dcop_action('player', "setVolume $volume");
      $return = array(
        'volume' => $volume
        );
      echo $json->encode($return);
      break;
    case 'seek':
      if ( !$allowcontrol )
        return false;
      $pos =& $params[1];
      if ( !preg_match('/^[0-9]+$/', $pos) )
      {
        return json_die('Invalid track ID');
      }
      $pos = intval($pos);
      dcop_action('player', "seek $pos");
      
      break;
    case 'refresh':
      global $playlist_last_refresh, $playlist, $playlist_last_md5;
      if ( $playlist_last_refresh + 60 < time() )
      {
        rebuild_playlist();
      }
      $current_track = dcop_action('playlist', 'getActiveIndex');
      $current_time = dcop_action('player', 'trackCurrentTime');
      $is_playing = dcop_action('player', 'isPlaying');
      $return = array(
          'is_playing' => $is_playing,
          'is_paused' => $current_time > 0 && !$is_playing,
          'current_track' => $current_track,
          'volume' => dcop_action('player', 'getVolume'),
          // include the MD5 of the playlist so that if it changes, the
          // client can refresh (otherwise things get madly corrupted)
          'playlist_hash' => $playlist_last_md5,
          'current_track_title' => false,
          'current_track_album' => false,
          'current_track_artist' => false
        );
      if ( isset($playlist[$current_track]) )
      {
        $return['current_track_length'] = $playlist[$current_track]['length_int'];
        $return['current_track_pos'] = $current_time;
        $return['current_track_title'] = $playlist[$current_track]['title'];
        $return['current_track_artist'] = $playlist[$current_track]['artist'];
        $return['current_track_album'] = $playlist[$current_track]['album'];
      }
      echo $json->encode($return);
      break;
    default:
      return json_die("Undefined action: $action");
  }
}

function api_request_handler($httpd, $socket)
{
  global $json;
  $httpd->header('Content-type: text/javascript');
  if ( !isset($_POST['request']) )
  {
    return json_die("No request specified on POST.");
  }
  $req = $json->decode($_POST['request']);
  if ( !isset($req['action']) )
  {
    return json_die("No action specified.");
  }
  switch($req['action'])
  {
    case 'check_login':
      global $use_auth, $auth_data;
      if ( $use_auth )
      {
        $return = array(
          'need_login' => true
        );
        if ( isset($req['username']) && isset($req['password']) )
        {
          $return['auth_valid'] = ( isset($auth_data[$req['username']]) && $auth_data[$req['username']] === $req['password'] );
        }
      }
      else
      {
        $return = array(
          'need_login' => false,
          'auth_valid' => true
        );
      }
      break;
    case 'login':
      global $use_auth, $auth_data;
      if ( $use_auth )
      {
        if ( !isset($req['username']) || !isset($req['password']) )
        {
          return json_die("Username or password not provided");
        }
        if ( $session = login($req['username'], $req['password']) )
        {
          $return = array(
            'need_login' => true,
            'login_cookie' => $session
          );
        }
        else
        {
          $return = array(
            'need_login' => true,
            'login_cookie' => false
          );
        }
      }
      else
      {
        $return = array(
          'need_login' => false,
          'login_cookie' => false
        );
      }
      break;
    default:
      return json_die("Undefined action '{$req['action']}'.");
      break;
  }
  echo $json->encode($return);
}