mirror of
https://github.com/Yetangitu/ampache
synced 2025-10-05 19:41:55 +02:00
renamed xml-rpc acl to rpc, added default mime type of image/jpg and added config options for batch download to the fs, no garbage collection for non-completed downloads yet.
This commit is contained in:
parent
d5ae71f551
commit
67cbb218cd
10 changed files with 177 additions and 34 deletions
|
@ -141,6 +141,7 @@ require_session = "true"
|
|||
; DEFAULT: false
|
||||
;xml_rpc = "false"
|
||||
|
||||
; Allow Zip Download
|
||||
; This setting allows/disallows using zlib to zip up an entire
|
||||
; playlist/album for download. Even if this is turned on you will
|
||||
; still need to enabled downloading for the specific user you
|
||||
|
@ -148,6 +149,19 @@ require_session = "true"
|
|||
; DEFAULT: false
|
||||
;allow_zip_download = "false"
|
||||
|
||||
; File Zip Download
|
||||
; This settings tells Ampache to attempt to save the zip file
|
||||
; to the filesystem instead of creating it in memory, you must
|
||||
; also set file_zip_path in order for this to work
|
||||
; DEFAULT: false
|
||||
;file_zip_download = "false"
|
||||
|
||||
; File Zip Path
|
||||
; If File Zip Download is enabled this must be set to tell
|
||||
; Ampache which directory to save the file to
|
||||
; DEFAULT: false
|
||||
;file_zip_path= "false"
|
||||
|
||||
; This setting throttles a persons downloading to the specified
|
||||
; bytes per second. This is not a 100% guaranteed function, and
|
||||
; you should really use a server based rate limiter if you want
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
|
||||
--------------------------------------------------------------------------
|
||||
v.3.4-Alpha3
|
||||
- Added ability to do batch downloads on the FS failed downloads
|
||||
currently will not be garbage collected (Thx COF)
|
||||
- Added default mime type if none found (image/jpg)
|
||||
- Changed XML-RPC ACL type to RPC to reflect multiple uses
|
||||
- Tweaked catalog add function to improve speed (Thx Karl Hungus)
|
||||
- Added XML API borrows authentication style from Last.FM's
|
||||
scrobbling, allows query of Ampache DB, returns XML
|
||||
|
|
|
@ -50,11 +50,27 @@ function get_song_files($song_ids) {
|
|||
*/
|
||||
function send_zip( $name, $song_files ) {
|
||||
|
||||
// Check if they want to save it to a file, if so then make sure they've got
|
||||
// a defined path as well and that it's writeable
|
||||
if (Config::get('file_zip_download') && Config::get('file_zip_path')) {
|
||||
// Check writeable
|
||||
if (!is_writable(Config::get('file_zip_path'))) {
|
||||
$in_memory = '1';
|
||||
debug_event('Error','File Zip Path:' . Config::get('file_zip_path') . ' is not writeable','1');
|
||||
}
|
||||
else {
|
||||
$in_memory = '0';
|
||||
$basedir = Config::get('file_zip_path');
|
||||
}
|
||||
|
||||
} // if file downloads
|
||||
|
||||
/* Require needed library */
|
||||
require_once Config::get('prefix') . '/modules/archive/archive.lib.php';
|
||||
$arc = new zip_file( $name . ".zip" );
|
||||
$options = array(
|
||||
'inmemory' => 1, // create archive in memory
|
||||
'inmemory' => $in_memory, // create archive in memory
|
||||
'basedir' => $basedir,
|
||||
'storepaths' => 0, // only store file name, not full path
|
||||
'level' => 0 // no compression
|
||||
);
|
||||
|
|
|
@ -183,10 +183,11 @@ class Access {
|
|||
$sql = "SELECT `id` FROM `access_list`" .
|
||||
" WHERE `start` <= '$ip' AND `end` >= '$ip' AND `type`='xml-rpc' AND `level` >= '$level'";
|
||||
break;
|
||||
case 'rpc':
|
||||
case 'xml-rpc':
|
||||
$sql = "SELECT `id` FROM `access_list`" .
|
||||
" WHERE `start` <= '$ip' AND `end` >= '$ip'" .
|
||||
" AND `key` = '$key' AND `level` >= '$level' AND `type`='xml-rpc'";
|
||||
" AND `key` = '$key' AND `level` >= '$level' AND (`type`='xml-rpc' OR `type`='rpc')";
|
||||
break;
|
||||
case 'network':
|
||||
case 'interface':
|
||||
|
@ -221,11 +222,14 @@ class Access {
|
|||
public static function validate_type($type) {
|
||||
|
||||
switch($type) {
|
||||
case 'xml-rpc':
|
||||
case 'rpc':
|
||||
case 'interface':
|
||||
case 'network':
|
||||
return $type;
|
||||
break;
|
||||
case 'xml-rpc':
|
||||
return 'rpc';
|
||||
break;
|
||||
default:
|
||||
return 'stream';
|
||||
break;
|
||||
|
@ -298,7 +302,8 @@ class Access {
|
|||
|
||||
switch ($this->type) {
|
||||
case 'xml-rpc':
|
||||
return 'XML-RPC';
|
||||
case 'rpc':
|
||||
return 'RPC';
|
||||
break;
|
||||
case 'network':
|
||||
return 'Local Network Definition';
|
||||
|
|
|
@ -751,6 +751,9 @@ class Album {
|
|||
}
|
||||
} // if we have PHP:GD
|
||||
|
||||
// Default to image/jpg as a guess if there is no passed mime type
|
||||
$mime = $mime ? $mime : 'image/jpg';
|
||||
|
||||
// Push the image into the database
|
||||
$sql = "REPLACE INTO `album_data` SET `art` = '" . Dba::escape($image) . "'," .
|
||||
" `art_mime` = '" . Dba::escape($mime) . "'" .
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
*/
|
||||
class Api {
|
||||
|
||||
public static $version = '340001';
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* This really isn't anything to do here, so it's private
|
||||
|
@ -45,6 +47,11 @@ class Api {
|
|||
*/
|
||||
public static function handshake($timestamp,$passphrase,$ip,$username='') {
|
||||
|
||||
// If the timestamp is over 2hr old sucks to be them
|
||||
// if ($timestamp < (time() - 7200)) {
|
||||
// return 'Timestamp too old, try again';
|
||||
// }
|
||||
|
||||
// First we'll filter by username and IP
|
||||
if (!$username) {
|
||||
$user_id = '-1';
|
||||
|
@ -76,7 +83,8 @@ class Api {
|
|||
// Create the Session, in this class for now needs to be moved
|
||||
$token = self::create_session($row['level'],$ip,$user_id);
|
||||
debug_event('API','Login Success, passphrase matched','1');
|
||||
return $token;
|
||||
|
||||
return array('auth'=>$token,'api'=>self::$version);
|
||||
} // match
|
||||
|
||||
} // end while
|
||||
|
|
|
@ -27,10 +27,9 @@
|
|||
*/
|
||||
class xmlData {
|
||||
|
||||
public static $version = '340001';
|
||||
|
||||
// This is added so that we don't pop any webservers
|
||||
public static $limit = '5000';
|
||||
private static $offset = '0';
|
||||
|
||||
/**
|
||||
* constructor
|
||||
|
@ -42,6 +41,17 @@ class xmlData {
|
|||
|
||||
} // constructor
|
||||
|
||||
/**
|
||||
* set_offset
|
||||
* This takes an int and changes the offset
|
||||
*/
|
||||
public static function set_offset($offset) {
|
||||
|
||||
$offset = intval($offset);
|
||||
self::$offset = $offset;
|
||||
|
||||
} // set_offset
|
||||
|
||||
/**
|
||||
* error
|
||||
* This generates a standard XML Error message
|
||||
|
@ -66,6 +76,35 @@ class xmlData {
|
|||
|
||||
} // single_string
|
||||
|
||||
/**
|
||||
* keyed_array
|
||||
* This will build an xml document from a key'd array,
|
||||
*/
|
||||
public static function keyed_array($array,$callback='') {
|
||||
|
||||
$string = '';
|
||||
|
||||
// Foreach it
|
||||
foreach ($array as $key=>$value) {
|
||||
// If it's an array, run again
|
||||
if (is_array($value)) {
|
||||
$value = self::keyed_array($value,1);
|
||||
$string .= "\t<$key>$value</$key>\n";
|
||||
}
|
||||
else {
|
||||
$string .= "\t<$key><![CDATA[$value]]></$key>\n";
|
||||
}
|
||||
|
||||
} // end foreach
|
||||
|
||||
if (!$callback) {
|
||||
$string = self::_header() . $string . self::_footer();
|
||||
}
|
||||
|
||||
return $string;
|
||||
|
||||
} // keyed_array
|
||||
|
||||
/**
|
||||
* artists
|
||||
* This takes an array of artists and then returns a pretty xml document with the information
|
||||
|
@ -74,9 +113,11 @@ class xmlData {
|
|||
public static function artists($artists) {
|
||||
|
||||
if (count($artists) > self::$limit) {
|
||||
$artists = array_splice($artists,0,self::$limit);
|
||||
$artists = array_splice($artists,self::$offset,self::$limit);
|
||||
}
|
||||
|
||||
$string = '';
|
||||
|
||||
foreach ($artists as $artist_id) {
|
||||
$artist = new Artist($artist_id);
|
||||
$artist->format();
|
||||
|
@ -98,7 +139,7 @@ class xmlData {
|
|||
public static function albums($albums) {
|
||||
|
||||
if (count($albums) > self::$limit) {
|
||||
$albums = array_splice($albums,0,self::$limit);
|
||||
$albums = array_splice($albums,self::$offset,self::$limit);
|
||||
}
|
||||
|
||||
foreach ($albums as $album_id) {
|
||||
|
@ -139,7 +180,7 @@ class xmlData {
|
|||
public static function genres($genres) {
|
||||
|
||||
if (count($genres) > self::$limit) {
|
||||
$genres = array_slice($genres,0,self::$limit);
|
||||
$genres = array_slice($genres,self::$offset,self::$limit);
|
||||
}
|
||||
|
||||
// Foreach the ids
|
||||
|
@ -172,7 +213,7 @@ class xmlData {
|
|||
public static function songs($songs) {
|
||||
|
||||
if (count($songs) > self::$limit) {
|
||||
$songs = array_slice($songs,0,self::$limit);
|
||||
$songs = array_slice($songs,self::$offset,self::$limit);
|
||||
}
|
||||
|
||||
// Foreach the ids!
|
||||
|
|
|
@ -271,15 +271,14 @@ class archive
|
|||
return $files;
|
||||
}
|
||||
|
||||
function download_file()
|
||||
{
|
||||
if ($this->options['inmemory'] == 0)
|
||||
{
|
||||
$this->error[] = "Can only use download_file() if archive is in memory. Redirect to file otherwise, it is faster.";
|
||||
return;
|
||||
}
|
||||
switch ($this->options['type'])
|
||||
{
|
||||
/**
|
||||
* download_file
|
||||
* Modified by COF
|
||||
*/
|
||||
public function download_file() {
|
||||
|
||||
// Always send this header
|
||||
switch ($this->options['type']) {
|
||||
case "zip":
|
||||
header("Content-Type: application/zip");
|
||||
break;
|
||||
|
@ -291,7 +290,37 @@ class archive
|
|||
break;
|
||||
case "tar":
|
||||
header("Content-Type: application/x-tar");
|
||||
} // end switch
|
||||
|
||||
if ($this->options['inmemory'] == 0) {
|
||||
|
||||
$full_arc_name = $this->options['basedir']."/".$this->options['name'];
|
||||
if (file_exists($full_arc_name)) {
|
||||
$fsize = filesize($full_arc_name);
|
||||
|
||||
//Send some headers which can be useful...
|
||||
$header = "Content-Disposition: attachment; filename=\"";
|
||||
$header .= strstr($this->options['name'], "/") ? substr($this->options['name'], strrpos($this->options['name'], "/") + 1) : $this->options['name'];
|
||||
$header .= "\"";
|
||||
header($header);
|
||||
header("Content-Length: " . $fsize);
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
header("Cache-Control: no-cache, must-revalidate, max-age=60");
|
||||
header("Expires: Sat, 01 Jan 2000 12:00:00 GMT");
|
||||
|
||||
readfile($full_arc_name);
|
||||
|
||||
//Now delete tempory file
|
||||
unlink($full_arc_name);
|
||||
}
|
||||
else {
|
||||
debug_event('ERROR','Archive does not exist, unable to download','1');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// else if we're doing this baby in memory
|
||||
else {
|
||||
$header = "Content-Disposition: attachment; filename=\"";
|
||||
$header .= strstr($this->options['name'], "/") ? substr($this->options['name'], strrpos($this->options['name'], "/") + 1) : $this->options['name'];
|
||||
$header .= "\"";
|
||||
|
@ -302,7 +331,9 @@ class archive
|
|||
header("Expires: Sat, 01 Jan 2000 12:00:00 GMT");
|
||||
print($this->archive);
|
||||
}
|
||||
}
|
||||
} // download file
|
||||
|
||||
} // end zip_file class
|
||||
|
||||
class tar_file extends archive
|
||||
{
|
||||
|
|
|
@ -61,6 +61,10 @@ switch ($_REQUEST['action']) {
|
|||
if ($_REQUEST['filter']) {
|
||||
Browse::set_filter('alpha_match',$_REQUEST['filter']);
|
||||
}
|
||||
|
||||
// Set the offset
|
||||
xmlData::set_offset($_REQUEST['offset']);
|
||||
|
||||
$artists = Browse::get_objects();
|
||||
// echo out the resulting xml document
|
||||
echo xmlData::artists($artists);
|
||||
|
@ -69,6 +73,10 @@ switch ($_REQUEST['action']) {
|
|||
$artist = new Artist($_REQUEST['filter']);
|
||||
|
||||
$albums = $artist->get_albums();
|
||||
|
||||
// Set the offset
|
||||
xmlData::set_offset($_REQUEST['offset']);
|
||||
|
||||
echo xmlData::albums($albums);
|
||||
break;
|
||||
case 'albums':
|
||||
|
@ -80,12 +88,19 @@ switch ($_REQUEST['action']) {
|
|||
Browse::set_filter('alpha_match',$_REQUEST['filter']);
|
||||
}
|
||||
$albums = Browse::get_objects();
|
||||
|
||||
// Set the offset
|
||||
xmlData::set_offset($_REQUEST['offset']);
|
||||
|
||||
echo xmlData::albums($albums);
|
||||
break;
|
||||
case 'album_songs':
|
||||
$album = new Album($_REQUEST['filter']);
|
||||
$songs = $album->get_songs();
|
||||
|
||||
// Set the offset
|
||||
xmlData::set_offset($_REQUEST['offset']);
|
||||
|
||||
echo xmlData::songs($songs);
|
||||
break;
|
||||
case 'genres':
|
||||
|
@ -98,6 +113,9 @@ switch ($_REQUEST['action']) {
|
|||
}
|
||||
$genres = Browse::get_objects();
|
||||
|
||||
// Set the offset
|
||||
xmlData::set_offset($_REQUEST['offset']);
|
||||
|
||||
echo xmlData::genres($genres);
|
||||
break;
|
||||
case 'genre_artists':
|
||||
|
@ -128,6 +146,9 @@ switch ($_REQUEST['action']) {
|
|||
}
|
||||
$songs = Browse::get_objects();
|
||||
|
||||
// Set the offset
|
||||
xmlData::set_offset($_REQUEST['offset']);
|
||||
|
||||
echo xmlData::songs($songs);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -64,12 +64,12 @@
|
|||
<option selected="selected" value="stream"><?php echo _('Stream Access'); ?></option>
|
||||
<option value="interface"><?php echo _('Web Interface'); ?></option>
|
||||
<option value="network"><?php echo _('Local Network Definition'); ?></option>
|
||||
<option value="xml-rpc"><?php echo _('XML-RPC'); ?></option>
|
||||
<option value="rpc"><?php echo _('RPC'); ?></option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2"><h4><?php echo _('XML-RPC Options'); ?></h4></td>
|
||||
<td colspan="2"><h4><?php echo _('RPC Options'); ?></h4></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><?php echo _('Remote Key'); ?>:</td>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue