summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/ampache.cfg.php.dist14
-rwxr-xr-xdocs/CHANGELOG4
-rw-r--r--lib/batch.lib.php18
-rw-r--r--lib/class/access.class.php13
-rw-r--r--lib/class/album.class.php3
-rw-r--r--lib/class/api.class.php10
-rw-r--r--lib/class/xmldata.class.php53
-rw-r--r--modules/archive/archive.lib.php71
-rw-r--r--server/xml.server.php21
-rw-r--r--templates/show_add_access.inc.php4
10 files changed, 177 insertions, 34 deletions
diff --git a/config/ampache.cfg.php.dist b/config/ampache.cfg.php.dist
index ce70c9da..db13d68a 100644
--- a/config/ampache.cfg.php.dist
+++ b/config/ampache.cfg.php.dist
@@ -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
diff --git a/docs/CHANGELOG b/docs/CHANGELOG
index f3522b56..4131bb93 100755
--- a/docs/CHANGELOG
+++ b/docs/CHANGELOG
@@ -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
diff --git a/lib/batch.lib.php b/lib/batch.lib.php
index c49e04a4..ae919767 100644
--- a/lib/batch.lib.php
+++ b/lib/batch.lib.php
@@ -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
);
diff --git a/lib/class/access.class.php b/lib/class/access.class.php
index c9e41512..59289c7c 100644
--- a/lib/class/access.class.php
+++ b/lib/class/access.class.php
@@ -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;
@@ -297,8 +301,9 @@ class Access {
public function get_type_name() {
switch ($this->type) {
- case 'xml-rpc':
- return 'XML-RPC';
+ case 'xml-rpc':
+ case 'rpc':
+ return 'RPC';
break;
case 'network':
return 'Local Network Definition';
diff --git a/lib/class/album.class.php b/lib/class/album.class.php
index 601b1f9b..bbacf852 100644
--- a/lib/class/album.class.php
+++ b/lib/class/album.class.php
@@ -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) . "'" .
diff --git a/lib/class/api.class.php b/lib/class/api.class.php
index 1ebc86e8..592ae953 100644
--- a/lib/class/api.class.php
+++ b/lib/class/api.class.php
@@ -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
diff --git a/lib/class/xmldata.class.php b/lib/class/xmldata.class.php
index c9d49a3f..ac776635 100644
--- a/lib/class/xmldata.class.php
+++ b/lib/class/xmldata.class.php
@@ -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
@@ -43,6 +42,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
* nothing fancy here...
@@ -67,6 +77,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
* we want
@@ -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!
diff --git a/modules/archive/archive.lib.php b/modules/archive/archive.lib.php
index f6662c60..3e668a05 100644
--- a/modules/archive/archive.lib.php
+++ b/modules/archive/archive.lib.php
@@ -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,18 +290,50 @@ 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;
}
- $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: " . strlen($this->archive));
- 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");
- print($this->archive);
- }
-}
+ // 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 .= "\"";
+ header($header);
+ header("Content-Length: " . strlen($this->archive));
+ 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");
+ print($this->archive);
+ }
+ } // download file
+
+} // end zip_file class
class tar_file extends archive
{
diff --git a/server/xml.server.php b/server/xml.server.php
index 682b0d55..db966441 100644
--- a/server/xml.server.php
+++ b/server/xml.server.php
@@ -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:
diff --git a/templates/show_add_access.inc.php b/templates/show_add_access.inc.php
index 9b26d96e..8cea9ab6 100644
--- a/templates/show_add_access.inc.php
+++ b/templates/show_add_access.inc.php
@@ -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>