diff options
-rw-r--r-- | config/ampache.cfg.php.dist | 14 | ||||
-rwxr-xr-x | docs/CHANGELOG | 4 | ||||
-rw-r--r-- | lib/batch.lib.php | 18 | ||||
-rw-r--r-- | lib/class/access.class.php | 13 | ||||
-rw-r--r-- | lib/class/album.class.php | 3 | ||||
-rw-r--r-- | lib/class/api.class.php | 10 | ||||
-rw-r--r-- | lib/class/xmldata.class.php | 53 | ||||
-rw-r--r-- | modules/archive/archive.lib.php | 71 | ||||
-rw-r--r-- | server/xml.server.php | 21 | ||||
-rw-r--r-- | templates/show_add_access.inc.php | 4 |
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> |